FUNCTION GetKernel32Module(): Cardinal; assembler
asm
mov eax, fs:$30
mov eax, [eax+$0c]
mov eax, [eax+$1c] // 相当于 mov esi, [eax+$1c]
mov eax, [eax] // 相当于 lodsd (mov eax, [esi])
mov eax, [eax+$08] // 返回k32的基址
end;
FUNCTION LStrLengthA(const lpStr: PAnsiChar): Cardinal; assembler;
asm
push edi
push ebx
mov edi, eax
mov ebx, eax
xor al, al
@@lstrscan:
scas byte ptr es:[edi] //字符扫描法检查字符串指针长度
jnz @@lstrscan
dec edi
sub edi, ebx
mov eax, edi
pop ebx
pop edi
end;
FUNCTION CalcBufferCRC(lpBuffer:PAnsiChar): Cardinal; assembler;
asm
push ebx
push edi
push ecx
mov ebx, eax
call LStrLengthA
mov edi, eax
shr edi, 2
xor ecx, ecx
@@loopBegin:
dec edi
jl @@loopOver
xor ecx, dword ptr ds:[ebx]
add ebx, 4
jmp @@loopBegin
@@loopOver:
mov eax, ecx
pop ecx
pop edi
pop ebx
end;
function GetProcAddressA(hModule:Cardinal; dwExportCRC: Cardinal) : Pointer; assembler;
var
lpProcNameCRC, dwProcNumber: Cardinal;
pProcAddress, pProcNameAddress, pProcIndexAddress: Pointer;
asm
push ebx
push esi
mov lpProcNameCRC, edx // edx=函数名CRC32
mov ebx, eax // ebx=基址
mov eax, [ebx+$3c] // eax=文件头偏移
mov esi, [ebx+eax+$78] // esi=输出表偏移,文件头+可选头的长度=$78
lea esi, [ebx+esi+$18] // 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=遍历函数名
call CalcBufferCRC
cmp eax, lpProcNameCRC // 对比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
end;
先用
LoadLibraryCRC32:= CalcBufferCRC('LoadLibraryA')
计算出 LoadLibraryA 的 CRC32 通常常用的API 应该事先计算好放在程序内, 以便查找, 不要在程序调用时出现, 杀毒软件对某些API名称会敏感 所以才有 CRC32 匹配法, 网上的代码基本都是传遍了大江南北, 杀软都做了特征, 其实你自己可以用很多种方法来计算API的加密算法, 用我的汇编进行匹配查询.
然后
GetProcAddressA(GetKernel32Module, LoadLibraryCRC32)
就可以得到 LoadLibraryA 的函数地址了
效率绝对一流, 用KOL 编译出的 3.5k 程序 优化后可以在 2k 以内, 极端情况不做代表
本人不提倡到处复制黏贴, 但是若要复制, 请说明作者和出处!
“没有分享就没有进步的精神永在”!!!
[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法