3

RunPEとして知られている「Win32EXEの動的フォーク」の既知の方法を実装しようとしています。私の問題は、http://www.security.org.sg/code/loadexe.htmlの3番目のポイントで述べたように、「ベースアドレス」の正しい結果を取得できないことです。

これは私のコードです:

DWORD* peb;
DWORD* baseAddress;
...snip...

GetThreadContext(hTarget, &contx)

peb = (DWORD *) contx.Ebx;
baseAddress = (DWORD *) contx.Ebx+8;

_tprintf(_T("The EBX [PEB] is: 0x%08X\nThe base address is: 0x%08X\nThe Entry Point is: 0x%08X\n"), peb, baseAddress, contx.Eax);

出力は次のようになります。

EBX [PEB]は次のとおりです:0x7FFD4000

ベースアドレスは次のとおりです:0x7FFD4020

エントリポイントは次のとおりです:0x00401000

私の問題はbaseAddressポインターの実装にあると思いますが、何が問題なのか正確にはわかりません。または、上記の記事を正しく理解しておらず、baseAddressがImageBaseではない可能性があります。そうであれば、baseAddressとは何ですか?

Win 7 64bとWin-XPで実行しようとしましたが、どちらでも同じ誤った結果が得られます。

4

3 に答える 3

2

次の行では、ポインタ演算を実行しているだけで、実際にはメモリを逆参照していません。

baseAddress = (DWORD *) contx.Ebx+8;

8*sizeof(DWORD) = 32の値に追加しているだけですcontx.Ebx。本当にやりたいのcontx.Ebx+8 は、新しいプロセスのアドレス空間ののアドレスにあるデータを読み取ることです。これを行うには、を使用する必要があり、ReadProcessMemoryキャストする必要はありません。値sizeof(DWORD)を使用してポインター演算を行う場合に発生する、オフセットに乗算を掛けたものではなく、生のオフセットを使用する必要がありDWORD*ます。

ただし、このような実装の詳細を掘り下げないように強く注意してください。このような実装の詳細は、異なるバージョンのWindows間で変更される可能性があります。リンクした記事は2004年に作成されたものであり、概念実証にすぎないため、Vista、Windows 7、Windows 8、および将来のバージョンでは、多くの隠れた落とし穴や予期しない問題が発生する可能性があります。 。

Windows APIには、Unixのfork(2)関数のように動作する関数がないため、フォークする必要がないようにできるだけ努力する必要がありCreateProcessますfork+exec。たとえば、 Cygwinの実装forkは醜くて遅いので、 DLLメモリマッピングの問題が原因で予期せず失敗します。

于 2012-10-09T21:27:54.817 に答える
2

指示には「[EBX+8]で」と書かれていることに注意してください。角かっこは、そのアドレス位置の値を意味します。にはいくつかの問題があります

baseAddress = (DWORD *) contx.Ebx+8;

まず、コンパイラは間隔に注意を払わず、括弧だけに注意を払うため、これは

baseAddress = ((DWORD *)contx.Ebx) + 8;

8はバイトではなくDWORDをカウントしているため、これは間違っています。あなたが欲しい

baseAddress = (DWORD *)(contx.Ebx + 8);

ただし、これにより、baseAddressの値ではなく、baseAddressが格納されているアドレスが取得されます。そのためにあなたは必要です

baseAddress = *(DWORD *)(contx.Ebx + 8);

ただし、これはcontx.Ebxがプロセス内のアドレスを参照している場合にのみ機能しますが、すべてのプロセスには独自のアドレススペースがあり、中断されたプロセスのアドレススペースにアクセスする必要があります。そのためには、ReadProcessMemory( http://msdn.microsoft.com/en-us/library/windows/desktop/ms680553%28v=vs.85%29.aspx)を使用する必要があります。

ok = ReadProcessMemory(hTarget, (LPCVOID)(contx.Ebx + 8), (LPVOID)&baseAddress, sizeof baseAddress, NULL);
于 2012-10-09T22:05:20.587 に答える
2

他の人が言ったことに加えて、プロセスのPEB構造のベースアドレスを取得するためのはるかに簡単な方法があります。NtQueryInformationProcess()代わりに、ProcessInformationClassパラメータセットをに設定して使用してくださいProcessBasicInformation。出力はPROCESS_BASIC_INFORMATION構造になります:

typedef struct _PROCESS_BASIC_INFORMATION {
    PVOID Reserved1;
    PPEB PebBaseAddress;
    PVOID Reserved2[2];
    ULONG_PTR UniqueProcessId;
    PVOID Reserved3;
} PROCESS_BASIC_INFORMATION;

2番目のメンバーはあなたが探しているものです。

于 2012-10-09T23:42:35.633 に答える