按照您的方式调用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;
}
这是从我拥有的旧项目中提取的所有代码。欢迎您使用代码并做任何您想做的事情,但我知道如果我现在要重写代码,我会做很多不同的事情。