原理很简单,对于已经加载的pe,可以在firstthunk中保存了导入函数的地址。因此,这里找到相对应导入函数保存的地址,然后进行修改就ok了。
void ShowAddr(PCHAR pStr,PVOID pAddr)
{
cout<<pStr<<hex<<pAddr<<endl;
}
typedef HMODULE (WINAPI* pfGetModuleHandle)( __in_opt LPCSTR lpModuleName );
pfGetModuleHandle pOldApi = NULL;
HMODULE WINAPI MyGetModuleHandle( __in_opt LPCSTR lpModuleName )
{
cout<<"yes intercept api!!!"<<endl;
if (pOldApi)
{
return pOldApi(lpModuleName);
}
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hProcess = GetModuleHandle(NULL);
PBYTE pImageBaseAddr = (PBYTE)hProcess;
//HANDLE hProcess2 = GetCurrentProcess();
cout<<"current module image base address:0x"<<hex<<hProcess<<endl;
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pImageBaseAddr;
PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)(pImageBaseAddr + pDosHeader->e_lfanew);
PIMAGE_OPTIONAL_HEADER pOptionalHeader = NULL;
PIMAGE_FILE_HEADER pFileHeader = NULL;
pOptionalHeader = &(pNtHeader->OptionalHeader);
pFileHeader = &(pNtHeader->FileHeader);
ShowAddr("OEP:0x",(pOptionalHeader->AddressOfEntryPoint + pImageBaseAddr));
cout<<"import dir rva:0x"<<pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
cout<<" size:0x"<<pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size<<endl;
PIMAGE_IMPORT_DESCRIPTOR pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)(pImageBaseAddr + pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
for (int i = 0;; i++)
{
if (pImportDesc->Name==NULL&&pImportDesc->TimeDateStamp==NULL)
{
break;
}
PIMAGE_THUNK_DATA pThunkData = NULL,pThunkData2 = NULL;
PIMAGE_IMPORT_BY_NAME pFuncName = NULL;
cout<<endl<<pImportDesc->Name+pImageBaseAddr<<endl;
if(pImportDesc->OriginalFirstThunk)
{
pThunkData = (PIMAGE_THUNK_DATA)(pImportDesc->OriginalFirstThunk + pImageBaseAddr);
pThunkData2 = (PIMAGE_THUNK_DATA)(pImportDesc->FirstThunk + pImageBaseAddr);
while(pThunkData->u1.Function)
{
if((pThunkData->u1.Function&IMAGE_ORDINAL_FLAG32) == IMAGE_ORDINAL_FLAG32)
{
//here just conside x86 pe
DWORD dwId = pThunkData->u1.Function & ~IMAGE_ORDINAL_FLAG32;
cout<<" ID:0x"<<dwId<<" addr:0x"<<pThunkData2->u1.AddressOfData<<endl;
}
else
{
pFuncName = (PIMAGE_IMPORT_BY_NAME)(pThunkData->u1.Function+pImageBaseAddr);
cout<<" 0x"<<pFuncName->Hint<<" "<<pFuncName->Name<<" addr:0x"<<pThunkData2->u1.AddressOfData<<endl;
if (stricmp((PCHAR)pFuncName->Name,"GetModuleHandleW")==0)
{
//here can intercept api
pThunkData2->u1.AddressOfData = (DWORD)MyGetModuleHandle;
cout<<"MyGetModuleHandle Addr:0x"<<pThunkData2->u1.AddressOfData<<endl;
}
}
pThunkData++;
}
}
else
{
pImportDesc->FirstThunk;
}
pImportDesc++;
}
//test intercept
hProcess = GetModuleHandle(NULL);
getchar();
return 0;
}