1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| ; find_function 60 pusha 8B 6C 24 24 mov ebp, [esp+24h] ; 将要加载模块的基地址放入EBP 8B 45 3C mov eax, [ebp+3Ch] ; 跳过 DOS 头 8B 54 28 78 mov edx, [eax+ebp+78h] ; 找到导出表, 并将其相对地址放入EDX 01 EA add edx, ebp ; 将相对地址(EDX)与基地址(EBP)相加, 得到导出表的绝对地址, 存入 EDX 8B 4A 18 mov ecx, [edx+18h] ; 设置计数器 ECX 8B 5A 20 mov ebx, [edx+20h] ; 将 名称表 的相对偏移存入 EBX 01 EB add ebx, ebp ; 得到 名称表 的绝对地址, 存入EBX fund_function_l oop: E3 34 jecxz short loc_75 ; find_function_finished, 如果 ECX 为 0, 并且最后一个函数被验证过了 ; 正常情况下不应执行这个跳转 ; 执行这个跳转说明函数没找到 49 dec ecx ; ECX - 1 8B 34 8B mov esi, [ebx+ecx*4] ; 获取当前函数的名称的相对偏移, 并存入 ESI 01 EE add esi, ebp ; 相对地址 + 基地址 获得 绝对地址 ; compute_hash : 31 FF xor edi, edi ; EDI 清零 31 C0 xor eax, eax ; EAX 清零 FC cld ; 清空标志位 compute_hash_again: AC lodsb ; 获取当前的函数名(ESI 中存储地址处的字符串) 84 C0 test al, al ; 检查是否为所要找的函数名 74 07 jz short compute_hash_finished ; 找到了执行该跳转 C1 CF 0D ror edi, 0Dh ; 把 hash 循环右移13位 01 C7 add edi, eax ; 把当前函数名的 Character 加入到 hash EB F4 jmp short compute_hash_again ; 继续找
compute_hash_finished: 3B 7C 24 28 cmp edi, [esp+28h] ; 检查当前hash是否匹配所要找的函数的hash 75 E1 jnz short fund_function_loop ; 不匹配, 继续找 8B 5A 24 mov ebx, [edx+24h] ; 取出序号表的相对地址,放入 EBX 01 EB add ebx, ebp ; 得到绝对地址 66 8B 0C 4B mov cx, [ebx+ecx*2] ; 获取当前符号序号 8B 5A 1C mov ebx, [edx+1Ch] ; 获取相对地址放入EBX 01 EB add ebx, ebp ; 获取绝对地址 8B 04 8B mov eax, [ebx+ecx*4] ; 获取函数偏移 01 E8 add eax, ebp ; 得到函数的实际地址 89 44 24 1C mov [esp+1Ch], eax ; 把函数地址存入 esp+1Ch
popa: 61 popa C3 retn ; find_function endp
|