Skip to content

Instantly share code, notes, and snippets.

@ry0kvn
Last active December 6, 2019 23:17
Show Gist options
  • Save ry0kvn/16c38132350c6559cbac228213cba7ac to your computer and use it in GitHub Desktop.
Save ry0kvn/16c38132350c6559cbac228213cba7ac to your computer and use it in GitHub Desktop.

LoadLibrary()を使ったDLLInjection

Injector

参考サイト: http://furuya02.hatenablog.com/entry/20120114/1326484897

Windowsにおいて、各プロセスはユニークな仮想メモリ空間の中で動作する。 そのため通常は、プロセスがプロセスを操作する状況において、引数として自プロセス内で取得したアドレスを他プロセスに渡してもうまく動作しない。 しかしある種のDLLはすべてのプロセス空間で同一のアドレスにロードされるため、そのDLLからエクスポートされている関数へのアドレスはすべてのプロセスで共通の値をとる。 Loadlibrary()を使ったDLLインジェクションはこの仕組みに着目し、Kernel32.dllからエクスポートされるLoadlibrary()へのアドレスをそのまま他プロセスに渡すことで任意のDLLを読み込ませる手法である。

主な手順は以下である。

  1. リモートプロセスにオープンまたはアタッチ
  2. WriteProcessMemoryでリモートプロセスに読み込ませたいDLLのパスを書き込む
  3. Loadlibrary()へのアドレスを引数としてリモートプロセスに対してCreateRemoteThreadする
  4. この際、Loadlibrary()の引数に、先ほど書き込んだDLLのパスへのアドレスを指定することで、任意のDLLを読み込ませることが可能

通常プロセス間に限っての話で、システムプロセスなどでは当然アドレスは異なることに留意。

// usage
// ./remote_loadlib.exe [DLLPath] [ProcessID to insert DLL]

#include <windows.h>

int main(int argc, char *argv[])
{
    DWORD pid;
    HANDLE proc;
    LPSTR libPath;
    LPSTR remoteLibPath;
    DWORD pathSize;
    libPath = argv[1];

    // 文字列を数値に変換
    pid = strtoul(argv[2], NULL, 0);

    proc = OpenProcess(
        PROCESS_CREATE_THREAD      //create remote  thread
            | PROCESS_VM_OPERATION //VirtualAllocEX
            | PROCESS_VM_WRITE,    //WriteProcessMemory
        FALSE,                     //InheritHandle
        pid);

    pathSize = strlen(libPath) + 1;
    remoteLibPath = VirtualAllocEx(
        proc,
        NULL,
        pathSize,
        MEM_COMMIT,
        PAGE_READWRITE);
    
    // リモートプロセスへ読み込ませたいDLLのパスを書き込む
    WriteProcessMemory(
        proc,
        remoteLibPath,
        libPath,
        pathSize,
        NULL);

    // 自プロセス内のLoadlibrary()へのアドレスを引数として渡す 
    CreateRemoteThread(
        proc,
        NULL,
        0,
        (LPTHREAD_START_ROUTINE)LoadLibrary,
        remoteLibPath,
        0,
        NULL);

    return 0;
}

読み込ませるDLL

このDLLがリモートプロセスに読み込まれ、デバッグウィンドウに文字列が出力される。

#include <Windows.h>
int evilcode(void);

int evilCode()
{
    char *buf = "Injected!";
    OutputDebugString(buf);
}

BOOL WINAPI
DllMain(HMODULE hModule,
        DWORD ul_reason_for_call,
        LPVOID lpReserved)
{
    if (ul_reason_for_call == DLL_PROCESS_ATTACH)
    {
        evilCode();
    }
    return TRUE;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment