原理:读取系统DLL到分配的内存里面去,然后定位到相关的API的代码。
FARPROC GetApiAddr(BYTE *Base,DWORD Api)
参数一:我们分配的内存基址
参数二:函数地址减去模块基址的差值
返回值:返回内存中得API的函数的地址
作用:对原来的系统API函数下断点无效,因为我们已经吧全部系统DLL读取到内存中定位到相关的代码了,调用的是内存中得API函数
代码:
#include <windows.h> char Caption[]="Test"; char Text[]="MessageBoxA"; FARPROC GetApiAddr(BYTE *Base,DWORD Api) { DWORD VirtualSize; DWORD PhysicalAddr; DWORD RawSize; FARPROC RET=NULL; PIMAGE_DOS_HEADER DosHeader=(PIMAGE_DOS_HEADER)Base; PIMAGE_NT_HEADERS NtHeader=(PIMAGE_NT_HEADERS)((DWORD)DosHeader+(DWORD)DosHeader->e_lfanew); PIMAGE_SECTION_HEADER SecHeader=(PIMAGE_SECTION_HEADER)((DWORD)NtHeader+sizeof(IMAGE_FILE_HEADER)+ NtHeader->FileHeader.SizeOfOptionalHeader+4); BYTE SecSum=NtHeader->FileHeader.NumberOfSections; while(SecSum) { PhysicalAddr=(DWORD)SecHeader->Misc.PhysicalAddress; VirtualSize=(DWORD)SecHeader->VirtualAddress;//>Misc.VirtualSize; PhysicalAddr+=VirtualSize; if(Api>=VirtualSize&&Api<=PhysicalAddr) { RawSize=SecHeader->PointerToRawData; RawSize-=VirtualSize; Base+=RawSize; Base+=Api; } SecHeader++; SecSum--; } RET=(FARPROC)Base; return RET; } int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow) { DWORD dwRead; char SystemPath[MAX_PATH]={0}; HMODULE hMod=GetModuleHandleA("USER32.DLL"); if(!hMod) hMod=LoadLibraryA("USER32.DLL"); GetSystemDirectoryA(SystemPath,MAX_PATH); lstrcat(SystemPath,"\\user32.dll"); HANDLE Handle=CreateFileA(SystemPath,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); DWORD Size=GetFileSize(Handle,NULL); BYTE *Virtual=VirtualAlloc(NULL,Size,MEM_COMMIT,PAGE_READWRITE); VirtualLock(Virtual,Size); ReadFile(Handle,Virtual,Size,&dwRead,NULL); DWORD MeAddr=(DWORD)GetProcAddress(hMod,"MessageBoxA"); MeAddr=MeAddr-(DWORD)hMod; DWORD Api=(DWORD)GetApiAddr(Virtual,MeAddr); _asm{ push 0 lea eax,Caption push eax lea eax,Text push eax push 0 call Api } return FALSE; }