我正在使用高級代碼注入代碼在遠程進程上啓動.dll。 你可以在這裏找到,例如如何工作/一小段代碼片段:使用代碼注入在遠程進程中執行功能
https://sourceforge.net/p/diagnostic/svn/HEAD/tree/src/RemoteInit.cpp
我注意到一些應用中,這種方法是行不通的 - 它崩潰主機應用程序。主要問題似乎是特殊的3-第三方軟件,如ConEmuHk64.dll
,通過提供它攔截kernel32.dll GetProcAddress
自己的鉤子函數 - 那我得到的函數指針像這樣經過:
*((FARPROC*) &info.pfuncGetProcAddress) = GetProcAddress(hKernel32, "GetProcAddress");
但不是我越來越指針功能位於ConEmuHk64.dll中。
在我自己的進程中調用該函數是可以接受的,但是當嘗試在遠程進程中執行相同的操作時 - 它崩潰,因爲ConEmuHk64.dll
不一定在那裏可用。
我已經弄清楚機制如何通過手動走在DOS/NE其他標頭功能的自動探測正確的地址 - 這裏是代碼片段:
//
// We use GetProcAddress as a base function, with exception to when GetProcAddress itself is hooked by 3-rd party
// software and pointer to function returned to us is incorrect - then we try to locate function manually by
// ourselfes.
//
FARPROC GetProcAddress2(HMODULE hDll, char* funcName)
{
FARPROC p = GetProcAddress(hDll, funcName);
if(!p)
return NULL;
IMAGE_DOS_HEADER* pDosHeader = (IMAGE_DOS_HEADER *) hDll;
if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
return p;
IMAGE_NT_HEADERS* pNtHeaders = (IMAGE_NT_HEADERS *) (((char*) pDosHeader) + pDosHeader->e_lfanew);
if (pNtHeaders->Signature != IMAGE_NT_SIGNATURE)
return p;
IMAGE_OPTIONAL_HEADER* pOptionalHeader = &pNtHeaders->OptionalHeader;
if((char*) p >= (char*)hDll && (char*) p <= ((char*)hDll) + pOptionalHeader->SizeOfCode)
// Sounds like valid address.
return p;
// Does not sounds right, may be someone hooked given function ? (ConEmuHk64.dll or ConEmuHk.dll)
IMAGE_DATA_DIRECTORY* pDataDirectory = &pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
IMAGE_EXPORT_DIRECTORY* pExp = (IMAGE_EXPORT_DIRECTORY *) ((size_t) pDosHeader + pDataDirectory->VirtualAddress);
ULONG* addrofnames = (ULONG *) ((BYTE*) hDll + pExp->AddressOfNames);
ULONG* funcaddr = (ULONG*) ((BYTE*) hDll + pExp->AddressOfFunctions);
for (DWORD i = 0; i < pExp->NumberOfNames; i++)
{
char* funcname = (char*) ((BYTE*) hDll + addrofnames[i]);
if (strcmp(funcname, funcName) == 0)
{
void* p2 = (void*) ((BYTE*) hDll + funcaddr[i]);
return (FARPROC) p2;
}
} //for
return p;
} //GetProcAddress2
這似乎是工作GetProcAddress
- 我可以檢測鉤住的函數並覆蓋它的行爲。但是 - 這種方法不是通用的。我嘗試了其他方法的類似函數調用,例如FreeLibrary/AddDllDirectory/RemoveDllDirectory
- 這些函數指針指出dll邊界 - GetProcAddress
返回DOS標頭之前的地址。
我懷疑是由DLL /代碼大小範圍比較是不正確的一個:
if((char*) p >= (char*)hDll && (char*) p <= ((char*)hDll) + pOptionalHeader->SizeOfCode)
,但沒有線索公式可以如何改進。
你能否推薦我如何完全修復這個問題 - 所以任何第三方軟件都可以攔截任何功能,而且我可以在沒有崩潰的情況下繼續使用它?