Skip to content

Instantly share code, notes, and snippets.

@trickster0
Forked from Cracked5pider/ReflectedDll.c
Created December 15, 2021 11:30
Show Gist options
  • Select an option

  • Save trickster0/c224cc2fa0c2c7a0a4c29cca084e46a9 to your computer and use it in GitHub Desktop.

Select an option

Save trickster0/c224cc2fa0c2c7a0a4c29cca084e46a9 to your computer and use it in GitHub Desktop.

Revisions

  1. @Cracked5pider Cracked5pider revised this gist Dec 15, 2021. No changes.
  2. @Cracked5pider Cracked5pider created this gist Dec 15, 2021.
    40 changes: 40 additions & 0 deletions ReflectedDll.c
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,40 @@
    //===============================================================================================//
    // This is a stub for the actuall functionality of the DLL.
    //===============================================================================================//
    #include "ReflectiveLoader.h"
    #include <stdio.h>

    // Note: REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR and REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN are
    // defined in the project properties (Properties->C++->Preprocessor) so as we can specify our own
    // DllMain and use the LoadRemoteLibraryR() API to inject this DLL.

    // You can use this value as a pseudo hinstDLL value (defined and set via ReflectiveLoader.c)
    extern HINSTANCE hAppInstance;

    BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpReserved )
    {
    BOOL bReturnValue = TRUE;
    switch( dwReason )
    {
    case DLL_QUERY_HMODULE:
    if( lpReserved != NULL )
    *(HMODULE *)lpReserved = hAppInstance;
    break;
    case DLL_PROCESS_ATTACH:
    {
    hAppInstance = hinstDLL;

    printf("[^] Hello from Reflective loaded dll ==> %d\n", GetCurrentProcessId());
    fflush(stdout);

    ExitProcess( 0 );
    break;
    }

    case DLL_PROCESS_DETACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    break;
    }
    return bReturnValue;
    }
    208 changes: 208 additions & 0 deletions inject.c
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,208 @@
    //===============================================================================================//
    // Copyright (c) 2012, Stephen Fewer of Harmony Security (www.harmonysecurity.com)
    // All rights reserved.
    //
    // Redistribution and use in source and binary forms, with or without modification, are permitted
    // provided that the following conditions are met:
    //
    // * Redistributions of source code must retain the above copyright notice, this list of
    // conditions and the following disclaimer.
    //
    // * Redistributions in binary form must reproduce the above copyright notice, this list of
    // conditions and the following disclaimer in the documentation and/or other materials provided
    // with the distribution.
    //
    // * Neither the name of Harmony Security nor the names of its contributors may be used to
    // endorse or promote products derived from this software without specific prior written permission.
    //
    // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
    // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
    // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
    // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
    // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
    // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    // POSSIBILITY OF SUCH DAMAGE.
    //===============================================================================================//
    #define WIN32_LEAN_AND_MEAN
    #include <windows.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include "LoadLibraryR.h"
    #include "GetProcAddressR.h"

    #pragma comment(lib,"Advapi32.lib")

    #define BREAK_WITH_ERROR( e ) { printf( "[-] %s. Error=%d", e, GetLastError() ); break; }

    void ReadFromPipe(HANDLE hSTD_OUT_Read)
    {
    puts("[*] Started reading");
    BOOL ok = FALSE;
    LPVOID pOutputBuffer = NULL;
    UCHAR buf[1025] = { 0 };
    DWORD dwBufferSize = 0,
    dwRead = 0;

    pOutputBuffer = LocalAlloc(LPTR, 1024);

    do
    {
    ok = ReadFile(hSTD_OUT_Read, buf, 1024, &dwRead, NULL);

    if (dwRead == 0)
    break;

    pOutputBuffer = LocalReAlloc(
    pOutputBuffer,
    dwBufferSize + dwRead,
    LMEM_MOVEABLE | LMEM_ZEROINIT
    );

    dwBufferSize += dwRead;

    memcpy( (char*)pOutputBuffer + (dwBufferSize - dwRead), buf, dwRead);
    memset(buf, 0, dwRead);

    } while (ok == TRUE);

    printf("[+] Output:\n%s\n", pOutputBuffer);

    memset(pOutputBuffer, 0, dwBufferSize);
    LocalFree(pOutputBuffer);
    pOutputBuffer = NULL;
    }

    // Simple app to inject a reflective DLL into a process vis its process ID.
    int main( int argc, char * argv[] )
    {
    HANDLE hFile = NULL;
    LPVOID lpBuffer = NULL;
    DWORD dwLength = 0;
    DWORD dwBytesRead = 0;
    HANDLE hToken;
    TOKEN_PRIVILEGES priv = {0};

    #ifdef WIN_X64
    char * cpDllFile = "reflective_dll.x64.dll";
    #else
    #ifdef WIN_X86
    char * cpDllFile = "reflective_dll.dll";
    #else WIN_ARM
    char * cpDllFile = "reflective_dll.arm.dll";
    #endif
    #endif

    HANDLE hProcess = NULL;

    if (argc < 2)
    {
    printf("[x] Please specify child process path: inject.x64.exe c:\\windows\\system32\\rundll32.exe\n");
    return 0;
    }

    do
    {

    LPCSTR cpCommandLine = "hello from injector";

    hFile = CreateFileA( cpDllFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
    if( hFile == INVALID_HANDLE_VALUE )
    BREAK_WITH_ERROR( "Failed to open the DLL file" );

    dwLength = GetFileSize( hFile, NULL );
    if( dwLength == INVALID_FILE_SIZE || dwLength == 0 )
    BREAK_WITH_ERROR( "Failed to get the DLL file size" );

    lpBuffer = HeapAlloc( GetProcessHeap(), 0, dwLength );
    if( !lpBuffer )
    BREAK_WITH_ERROR( "Failed to get the DLL file size" );

    if( ReadFile( hFile, lpBuffer, dwLength, &dwBytesRead, NULL ) == FALSE )
    BREAK_WITH_ERROR( "Failed to alloc a buffer!" );

    if( OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken ) )
    {
    priv.PrivilegeCount = 1;
    priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

    if( LookupPrivilegeValue( NULL, SE_DEBUG_NAME, &priv.Privileges[0].Luid ) )
    AdjustTokenPrivileges( hToken, FALSE, &priv, 0, NULL, NULL );

    CloseHandle( hToken );
    }

    // Child Process
    puts("[*] Setup for child process");
    HANDLE hStdInPipeRead = NULL;
    HANDLE hStdInPipeWrite = NULL;
    HANDLE hStdOutPipeRead = NULL;
    HANDLE hStdOutPipeWrite = NULL;

    SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };

    if ( !CreatePipe(&hStdInPipeRead, &hStdInPipeWrite, &sa, 0) )
    {
    printf("[-] Failed Input pipe: %d\n", GetLastError());
    return -1;
    }

    if ( !CreatePipe(&hStdOutPipeRead, &hStdOutPipeWrite, &sa, 0) )
    {
    printf("[-] Failed Output pipe: %d\n", GetLastError());
    return -1;
    }

    STARTUPINFOA si = { 0 };
    si.cb = sizeof(STARTUPINFOA);
    si.dwFlags = STARTF_USESTDHANDLES;
    si.hStdError = hStdOutPipeWrite;
    si.hStdOutput = hStdOutPipeWrite;
    si.hStdInput = hStdInPipeRead;
    PROCESS_INFORMATION pi = { 0 };

    if ( !CreateProcessA(NULL, argv[1], NULL, NULL, TRUE, CREATE_NO_WINDOW | CREATE_SUSPENDED, NULL, NULL, &si, &pi) )
    {
    return -1;
    }

    printf("[*] Created child process in suspended state: %d\n", pi.dwProcessId);

    /*LPVOID lpRemoteCommandLine = VirtualAllocEx(hProcess, NULL, strlen(cpCommandLine) + 1, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
    if (!lpRemoteCommandLine)
    BREAK_WITH_ERROR("[INJECT] inject_dll. VirtualAllocEx 1 failed");
    if (!WriteProcessMemory(hProcess, lpRemoteCommandLine, cpCommandLine, strlen(cpCommandLine) + 1, NULL))
    BREAK_WITH_ERROR("[INJECT] inject_dll. WriteProcessMemory 1 failed");*/

    puts("[*] Press enter to inject...");
    getchar();

    HANDLE hModule = LoadRemoteLibraryR( pi.hProcess, lpBuffer, dwLength, NULL );

    printf("[*] Resumed process thread: %d\n", ResumeThread(pi.hThread));

    WaitForSingleObject(hModule, -1);

    // Handling output from process

    CloseHandle(hStdOutPipeWrite);
    CloseHandle(hStdInPipeRead);

    ReadFromPipe(hStdOutPipeRead);

    CloseHandle(hStdOutPipeRead);
    CloseHandle(hStdInPipeWrite);

    DWORD ExitCode = 0;
    GetExitCodeProcess(pi.hProcess, &ExitCode);

    printf("[*] Process Exit code: %d\n", ExitCode);
    } while( 0 );

    if( lpBuffer )
    HeapFree( GetProcessHeap(), 0, lpBuffer );

    return 0;
    }