ULONG rip=0xffffffff;
__asm
{
push eax
mov eax,[ebp+04h]
mov rip,eax
pop eax
}
DebugString("the module from ebp+04h:%s/n",GetWhoIsCalling(rip));
char * __stdcall GetWhoIsCalling(DWORD apiAddr,DWORD pPEB=0) { LDR_MODULE *ldr, *headLdr; LDR_MODULE *result = NULL; if(pPEB==0) { __asm { mov eax, fs:[30h]; // get pointer to PEB from offset 30h into TEB } } else { __asm { mov eax, pPEB; // get pointer to PEB from arg pPEB } } __asm { mov eax, [eax+0ch]; // retrive value from offset 0ch into PEB //mov esi, [eax+1ch]; // get the head pointer to InInitializationOrderModuleList //一般"按初始化顺序"前向遍历链表时,第一个节点对应ntdll.dll,第二个结点对应 //kernel32.dll,我们不太关心其它模块。如果按加载顺序前向遍历,第一个节点对应 //EXE文件本身,第二个节点才对应ntdll.dll。 mov esi, [eax+0ch]; // get the head pointer to InLoadOrderModuleList mov headLdr, esi; } ldr = headLdr; while(true) { if(!IsBadReadPtr(ldr->BaseAddress, 4) && !IsBadReadPtr(ldr->BaseDllName.Buffer, 4)) { //printf("BaseDllName: %ws/n",ldr->BaseDllName.Buffer); //printf("FullDllName: %ws/n",ldr->FullDllName.Buffer); DWORD dllEnd = (DWORD)ldr->BaseAddress + ldr->SizeOfImage; if(apiAddr > (DWORD)ldr->BaseAddress && apiAddr < dllEnd) { DWORD nameLen = WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, ldr->BaseDllName.Buffer, -1, NULL, 0, NULL, NULL); if(nameLen) { LPSTR buffer = (LPSTR)malloc(nameLen + 1); if(buffer) { WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, ldr->BaseDllName.Buffer, -1, buffer, nameLen + 1, NULL, NULL); return buffer; } } } } // get the head pointer to InLoadOrderModuleList ldr = (LDR_MODULE *)ldr->InLoadOrderModuleList.Flink; if(ldr == headLdr) break; } return NULL; } |
一般在HOOK的函数头部CALL GetWhoIsCalling,就能得到调用的模块