あなたが持っているように呼び出すGetModuleHandle
と、プロセスにマップされているため、DLL のベースが取得されます (存在する場合)。したがって、最初に行う必要があるのは、DLL で関数をエクスポートすることです。行ったように行うか、ここ.def
に示すようにファイルを作成できます。その後:
理論的には
- ターゲット プロセスに DLL を挿入し、ロードされたベース アドレスを取得します。
- 現在のプロセスに DLL を挿入します。
GetProcAddress
エクスポートされた関数と DLL のベースの間のオフセットを見つけるために使用します。
- ステップ 1 で取得したベース アドレスにこのオフセットを追加し
CreateRemoteThread
ます。
実際には
DLL インジェクションを実行すると、DLL がターゲットにロードされているというベースを取得することができます。
HMODULE hInjected;
hThread = CreateRemoteThread( hProcess, NULL, 0,
(LPTHREAD_START_ROUTINE)( GetProcAddress( hMod,
"LoadLibraryW" ) ), lpAddress, 0, NULL );
// Locate address our payload was loaded
if( hThread != 0 ) {
WaitForSingleObject( hThread, INFINITE );
GetExitCodeThread( hThread, ( LPDWORD )&hInjected );
CloseHandle( hThread );
}
hInjected
挿入された DLL のベースになります。次に、別の機能があります。
void* GetPayloadExportAddr( LPCWSTR lpPath, HMODULE hPayloadBase, LPCSTR lpFunctionName ) {
// Load payload in our own virtual address space
HMODULE hLoaded = LoadLibrary( lpPath );
if( hLoaded == NULL ) {
return NULL;
} else {
void* lpFunc = GetProcAddress( hLoaded, lpFunctionName );
DWORD dwOffset = (char*)lpFunc - (char*)hLoaded;
FreeLibrary( hLoaded );
return (DWORD)hPayloadBase + dwOffset;
}
}
これが行うことは、最初にペイロードを独自の仮想アドレス空間にロードすることです。その後、GetProcAddress
エクスポートされた関数のアドレスを取得するために使用できます。これから、DLL のベースから関数のオフセットを取得できます。このオフセットをhInjected
以前に取得した に追加すると、CreateRemoteThread
呼び出しを行う必要がある場所がわかります。したがって、次のように電話をかけることができます。
BOOL InitPayload( HANDLE hProcess, LPCWSTR lpPath, HMODULE hPayloadBase, HWND hwndDlg ) {
void* lpInit = GetPayloadExportAddr( lpPath, hPayloadBase, "Init" );
if( lpInit == NULL ) {
return FALSE;
} else {
HANDLE hThread = CreateRemoteThread( hProcess, NULL, 0,
lpInit, hwndDlg, 0, NULL );
if( hThread == NULL ) {
return FALSE;
} else {
CloseHandle( hThread );
}
}
return TRUE;
}
これはすべて、私が持っている古いプロジェクトから切り取ったコードです。コードを手に入れて、それを使って好きなことをするのは大歓迎ですが、今コードを書き直すとしたら、多くのことを別の方法で行うことになることはわかっています。