这段代码演示了如何让你的程序要保护的API函数不被下断。
这段代码显示一个对话框,但Cracker在OD中是无法下MessageBoxA断点的。因为程序将要用到的MessageBoxA函数的DLL文件拷贝到了自己新申请的空间内,并执行的是新空间中MessageBoxA的代码。而Cracker下的断是系统DLL文件的断点,显然是无法拦截到我们的函数的。
#include <windows.h>
#include <stdio.h>
DWORD RvaToOffset(LPVOID lpBase,DWORD VirtualAddress)
{
IMAGE_DOS_HEADER *dosHeader = (IMAGE_DOS_HEADER*)lpBase;
IMAGE_NT_HEADERS *NtHeader = (IMAGE_NT_HEADERS*)((BYTE*)lpBase + dosHeader->e_lfanew);
int NumberOfSection = NtHeader->FileHeader.NumberOfSections;
IMAGE_SECTION_HEADER *SectionHeader;
for (int i=0;i<NumberOfSection;i++)
{
SectionHeader = IMAGE_FIRST_SECTION(NtHeader)+i;
if(VirtualAddress>SectionHeader->VirtualAddress&&VirtualAddress<SectionHeader->VirtualAddress+SectionHeader->SizeOfRawData)
{
DWORD AposRVA = VirtualAddress - SectionHeader->VirtualAddress;
DWORD offset = SectionHeader->PointerToRawData + AposRVA;
return offset;
}
}
return 0;
}
int main(int argc,char *argv[])
{
char szDllPath[MAX_PATH];
DWORD dwRead;
char *szTitle="Tilte";
char *szMessage="Message";
GetSystemDirectory(szDllPath,MAX_PATH);
strcat(szDllPath,"");
HANDLE hFile = CreateFile(szDllPath,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,NULL,NULL);
DWORD dwSize = GetFileSize(hFile,NULL);
LPVOID lpBase = VirtualAlloc(NULL,dwSize,MEM_COMMIT,PAGE_READWRITE);
ReadFile(hFile,lpBase,dwSize,&dwRead,NULL);
//申请user32.dll文件大小空间,并将user32.dll文件写入
HMODULE lpMod = LoadLibrary(szDllPath); //得到user32.dll的HMODULE
LPVOID lpOldMessageBox = GetProcAddress(lpMod,"MessageBoxA");//得到MessageBoxA函数地址
DWORD dwRVA = (DWORD)lpOldMessageBox - (DWORD)lpMod;//计算MessageBoxA在内存中的偏移地址
DWORD lpNewMessageBox = RvaToOffset(lpBase,dwRVA);//将内存地址转换成文件地址,即找到MessageBoxA在文件中的地址
lpNewMessageBox += (DWORD)lpBase;//计算MessageBoxA在新内存中的地址
__asm
{
mov eax,lpNewMessageBox
push 0
push szTitle
push szMessage
push 0
call eax
}
FreeLibrary(lpMod);
CloseHandle(hFile);
return 0;
}