0

私は単純なdllコードを持っています:

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
      if(ul_reason_for_call == DLL_PROCESS_ATTACH) 
      {
            MessageBox(0, L"Hello!", L"Hello!", 0);          

      }

return TRUE;
}

そして、dll を別のプロセスに注入するための python コード:

import ctypes

PAGE_READWRITE = 0x04
PROCESS_ALL_ACCESS = (0x000F0000 | 0x00100000 | 0xFFF)
VIRTUAL_MEM = (0x1000 | 0x2000)

def InjectDLL(DLLPath, PID):

    kernel = ctypes.windll.kernel32
    dllLen = len(DLLPath)

    hProcs  = ctypes.windll.kernel32.OpenProcess(PROCESS_ALL_ACCESS, False, PID)
    if not hProcs:
        print 'OpenProcess failed.'
        return None


    argAddy = ctypes.windll.kernel32.VirtualAllocEx(hProcs, 0, dllLen, VIRTUAL_MEM, PAGE_READWRITE)
    if not argAddy:
        print 'VirtualAllocEx failed.'
        return None

    wrote = ctypes.c_int(0)
    kernel.WriteProcessMemory(hProcs, argAddy, DLLPath, dllLen, ctypes.byref(wrote))

    hKernel = kernel.GetModuleHandleA("kernel32.dll")
    hLib = kernel.GetProcAddress(hKernel, "LoadLibraryA")
    t_Id = ctypes.c_ulong(0)
    kernel.CreateRemoteThread(hProcs, None, 0, hLib, argAddy, 0, ctypes.byref(t_Id))
    return t_Id

result = InjectDLL("injdll.dll", 564)
print result

一部のプロセスでは、注入が機能します。たとえば、gvim で動作します。メッセージボックスが見えます。しかし、C# で簡単なアプリケーションを作成しました。そして、私のdllをこのアプリケーションに注入しようとした後、何も起こりません。

OpenProcessPython インジェクターは、 orCirtualAllocExおよび returnでエラーを報告しませんc_ulong(3968L)。では、なぜメッセージボックスが表示されないのでしょうか?

編集:

私のオペレーティング システム: Windows XP Professional SP3 32 ビット。

編集2:

Cコードで同じことをしたところ、同じ結果が得られました。インジェクションは、たとえば gvim で機能します。しかし、C# での私のプロセスではありません。デバッガーで確認したところ、DllMain 関数が実行されていないようです。

DWORD pid;
cout << "PID: ";
cin >> pid;


HANDLE hproc = OpenProcess(PROCESS_ALL_ACCESS,0,pid);

LPVOID adr = 
VirtualAllocEx (
                hproc,
               (LPVOID)0,
               (SIZE_T)0x1000,
               MEM_COMMIT | MEM_RESERVE,
               PAGE_EXECUTE_READWRITE
               );

WriteProcessMemory (hproc, adr, "injdll.dll", 256, NULL);

HANDLE hthread = CreateRemoteThread 
(hproc,
 NULL,
 0,
 (LPTHREAD_START_ROUTINE)
 GetProcAddress(GetModuleHandle(L"kernel32"),"LoadLibraryA"),
 adr,
 0,
 NULL);

CloseHandle(hthread);
CloseHandle(hproc);

return 0;
4

1 に答える 1

2

まだコメントを残すことはできません。使用している OS のバージョンを教えてください。

ほとんどの場合、64 ビット OS の .net アプリケーションの場合、DLL は 64 ビットである必要があります。

pyton ではわかりませんが、LoadLibrary には AsciiZ 文字列が必要です。では、安全上の理由から、「dllLen = len(DLLPath)+1」を使用できますか?

また、デフォルトのスタックサイズを変更してみてください

kernel.CreateRemoteThread(hProcs, None, 4096*16, hLib, argAddy, 0, ctypes.byref(t_Id))

あるいは、DllMain で例外が発生している可能性があります (何らかの理由で?)。CreateRemoteThread を実行する前に、ターゲット プロセスにデバッガーをアタッチします。

于 2012-06-06T22:16:26.823 に答える