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;
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!