API内存搜索引擎(C语言内嵌汇编)
// apisearchEngine.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <Windows.h> DWORD __stdcall GetStrLengthA(char* szName) { _asm { push edi push ebx mov eax, szName mov edi, eax mov ebx, eax xor al, al lstrscan: scas byte ptr [edi] //字符扫描法检查字符串指针长度 jnz lstrscan dec edi sub edi, ebx mov eax, edi pop ebx pop edi } } DWORD __stdcall CalcBufferCRC(char* lpBuffer) { _asm { push ebx push edi push ecx push ebp mov ebx, lpBuffer push ebx call GetStrLengthA mov edi, eax shr edi, 2 xor ecx, ecx loopBegin: dec edi jl loopOver xor ecx, dword ptr [ebx] add ebx, 4 jmp loopBegin loopOver: mov eax, ecx pop ebp pop ecx pop edi pop ebx } } DWORD __stdcall GetProcAddressA(HANDLE hModule, DWORD dwExportCRC) { //DWORD lpProcNameCRC = ; DWORD dwProcNumber; LPVOID pProcAddress, pProcNameAddress, pProcIndexAddress; _asm { push ebx push esi mov eax, hModule mov edx,dwExportCRC // edx=函数名CRC32 mov ebx, eax // ebx=基址 mov eax, [ebx+0x3c] // eax=文件头偏移 mov esi, [ebx+eax+0x78] // esi=输出表偏移,文件头+可选头的长度=$78 lea esi, [ebx+esi+0x18] // esi=函数名数量 = 函数数量 [ebx+esi+$14] lods dword ptr ds:[esi] mov dwProcNumber, eax // eax=函数名数量 lods dword ptr ds:[esi] mov pProcAddress, eax // eax=函数偏移量 lods dword ptr ds:[esi] mov pProcNameAddress, eax // eax=函数名偏移量 lods dword ptr ds:[esi] mov pProcIndexAddress, eax // eax=序列号偏移量 mov edx, dwProcNumber // edx=遍历次数 LoopBegin: xor eax, eax // Result = 0 dec edx jl LoopEnd mov eax, pProcNameAddress add eax, ebx // eax=函数名基地址 mov eax, dword ptr ds:[eax+edx*4] add eax, ebx // eax=遍历函数名 push eax call CalcBufferCRC cmp eax, dwExportCRC // 对比CRC32 jnz LoopBegin shl edx, 1 add edx, pProcIndexAddress // 函数基序列 movzx eax, word ptr ss:[edx+ebx] shl eax, 2 add eax, pProcAddress // 函数基地址 mov eax, [eax+ebx] add eax, ebx // Result = 函数地址 LoopEnd: pop esi pop ebx } } DWORD __stdcall GetKernel32Module() { _asm { PUSH EBP XOR ECX, ECX //MOV ESI, [FS:ECX + 0x30] ; ESI = &(PEB) ([FS:0x30]) MOV ESI, FS:[0X30] MOV ESI, [ESI + 0x0C] ; ESI = PEB->Ldr MOV ESI, [ESI + 0x1C] ; ESI = PEB->Ldr.InInitOrder next_module: MOV EBP, [ESI + 0x08] ; EBP = InInitOrder[X].base_address MOV EDI, [ESI + 0x20] ; EBP = InInitOrder[X].module_name (unicode) MOV ESI, [ESI] ; ESI = InInitOrder[X].flink (next module) CMP [EDI + 12*2], CL ; modulename[12] == 0 ? JNE next_module ; No: try next module. MOV EAX, EBP POP EBP } } int main(int argc, char* argv[]) { printf("write by xiaoju !\n"); printf("*****************\n"); DWORD dwBaseKernel32 = GetKernel32Module(); printf("Kernel32的模块地址:%08x\n",dwBaseKernel32); DWORD LoadLibraryCRC32= CalcBufferCRC("LoadLibraryA") ; printf("LoadLibraryA的CRC值(静态写到程序中):%08x\n\n", LoadLibraryCRC32); DWORD dwAddrLoadLibrary = GetProcAddressA((HANDLE)dwBaseKernel32, 0x577a7461); printf("在程序中动态得到的LoadLibraryA的地址:%08x\n", dwAddrLoadLibrary); getchar(); return 0; }