PE加載器:將PE文件在內存中加載,此加載方式,進程的模塊列表中無法查看到模塊名。Procmon中監視,堆棧,堆棧中顯示<未知>,彙編跟蹤時也沒有模塊名。
替換方法:找到模塊所在的內存塊,對內存塊中的PE文件進行解析,定位到導入表處,再替換導入表。
方法詳見代碼
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,true,m_Pid);
char str[315392];
memset(str,0,315392);
DWORD lread;
BOOL bSuccess = ReadProcessMemory(hProcess,(LPCVOID)0x01ae0000,str,315392,&lread);
//判斷PE文件
PIMAGE_DOS_HEADER PE_Head; //DOS頭
PE_Head = (PIMAGE_DOS_HEADER)str;
if (PE_Head->e_magic != IMAGE_DOS_SIGNATURE)
{
AfxMessageBox("錯誤的MS_DOS頭!");
return;
}
PIMAGE_NT_HEADERS PE_NtHead; //NT頭
PE_NtHead = (PIMAGE_NT_HEADERS)(str+PE_Head->e_lfanew);
if (PE_NtHead->Signature != IMAGE_NT_SIGNATURE)
{
AfxMessageBox("錯誤的PE頭!");
return;
}
//獲取頭的地址
PIMAGE_FILE_HEADER PE_FileHead; //文件頭
PIMAGE_OPTIONAL_HEADER PE_OptionHead; //可選頭
PE_FileHead = &PE_NtHead->FileHeader;
PE_OptionHead = &PE_NtHead->OptionalHeader;
//獲取導入表的地址
PIMAGE_DATA_DIRECTORY PE_ImportDirectory;
//由於輸入表爲第二項,獲取輸入表的目錄表的信息。
PE_ImportDirectory = &PE_OptionHead->DataDirectory[1];
//獲取輸入表前先獲取輸入表的偏移地址
DWORD PE_ImportOffset;
PE_ImportOffset = PE_ImportDirectory->VirtualAddress;
//輸入表是以IMAGE_IMPORT_DESCRIPTOR爲結構,以空爲結尾
//先獲得輸入表的指針
PIMAGE_IMPORT_DESCRIPTOR pImportDesc;
pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)(str + PE_ImportOffset);
while (pImportDesc->FirstThunk)
{
char szName[1024];
memset(szName,0,1024);
strcpy(szName,str+pImportDesc->Name);
PIMAGE_THUNK_DATA PE_INT;
PE_INT = (PIMAGE_THUNK_DATA)(str+pImportDesc->OriginalFirstThunk);
PIMAGE_THUNK_DATA PE_IAT;
PE_IAT = (PIMAGE_THUNK_DATA)(str+pImportDesc->FirstThunk);
char *pszFunName = NULL;
while(PE_IAT->u1.Function)
{
if (PE_IAT->u1.Function == 0x7C801A28)
{
PE_IAT->u1.Function = 0x3449068;
}
// if (PE_IAT->u1.Function == 0x7C809BE7)
// {
// PE_IAT->u1.Function = 0x33C9068;
// }
//PDWORD lpAddr = str + PE_IAT->u1.Function
PE_IAT++;
}
pImportDesc++;
}
bSuccess = WriteProcessMemory(hProcess,(LPVOID)0x01ae0000,str,315392,&lread);
int x = 01;