c语言 内存搜索,API内存搜索引擎(C语言内嵌汇编)

这篇博客介绍了如何使用C语言内嵌汇编来实现API的搜索,包括计算字符串长度、CRC校验以及获取指定CRC值的函数地址。通过示例代码展示了获取Kernel32模块地址、LoadLibraryA函数CRC值以及动态获取其地址的过程。
摘要由CSDN通过智能技术生成

API内存搜索引擎(C语言内嵌汇编)

// apisearchEngine.cpp : Defines the entry point for the console application.

//

#include "stdafx.h"

#include

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

{

PUSHEBP

XOR ECX, ECX

//MOV ESI, [FS:ECX + 0x30] ; ESI = &(PEB) ([FS:0x30])

MOVESI, 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.

MOVEAX, EBP

POPEBP

}

}

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;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值