代码:
assume fs:nothing mov eax,fs:[30h] test eax,eax js os_9x os_nt: mov eax,[eax+0ch] mov esi,[eax+1ch] lodsd mov eax,[eax+8] jmp k_finished os_9x: mov eax,[eax+34h] mov eax,[eax+7ch] mov eax,[eax+3ch] k_finished: sub esp,200 mov edi,esp mov [edi+8],eax ;获取kernel32地址
xor ebx, ebx ; clear ebx
mov ebx, [fs: 0x30 ] ; get a pointer to the PEB
mov ebx, [ ebx + 0x0C ] ; get PEB->Ldr
mov ebx, [ ebx + 0x14 ] ; get PEB->Ldr.InMemoryOrderModuleList.Flink (1st entry)
mov ebx, [ ebx ] ; get the next entry (2nd entry)
mov ebx, [ ebx ] ; get the next entry (3rd entry)
mov ebx, [ ebx + 0x10 ] ; get the 3rd entries base address (kernel32.dll)
这个代码利用了kernel32.dll 是在InMemoryOrderModuleList 中的第三个的事实。(因此它是
一个和前面代码稍微不同的方法,前面是查找InitializationOrder。
(2) 查找API函数地址
通过上面找到了kernel32的基址,但是我们如何得到具体的api函数地址呢?这里就需要涉及到pe文件格式了。这里我只讲解如何从dll文件中找出其函数引出表中的函数地址的方法:(班门弄斧了,见笑~)
a.在kernel32基址+0x3c处获取e_lfanewc地址,即可以得到PE头
b.在PE头偏移的0x78处得到函数引出表地址
c.在引出表的0x1c偏移处获取AddressOfFunctions、AddressOfNames、AddressOfNameOrdinalse
d. AddressOfFunctions和 AddressOfNames是函数地址和函数名通过AddressOfNameOrdinalse一一对应的两个数组
e.是这样计算的:
搜索AddressOfNames,确定“GetProcAddress”所对应的index;
index = AddressOfNameOrdinalse [ index ];
函数地址 = AddressOfFunctions [ index ];
一个和前面代码稍微不同的方法,前面是查找InitializationOrder。
(2) 查找API函数地址
通过上面找到了kernel32的基址,但是我们如何得到具体的api函数地址呢?这里就需要涉及到pe文件格式了。这里我只讲解如何从dll文件中找出其函数引出表中的函数地址的方法:(班门弄斧了,见笑~)
a.在kernel32基址+0x3c处获取e_lfanewc地址,即可以得到PE头
b.在PE头偏移的0x78处得到函数引出表地址
c.在引出表的0x1c偏移处获取AddressOfFunctions、AddressOfNames、AddressOfNameOrdinalse
d. AddressOfFunctions和 AddressOfNames是函数地址和函数名通过AddressOfNameOrdinalse一一对应的两个数组
e.是这样计算的:
搜索AddressOfNames,确定“GetProcAddress”所对应的index;
index = AddressOfNameOrdinalse [ index ];
函数地址 = AddressOfFunctions [ index ];
代码:
FindApi: ;获取API函数地址子过程 push ebp push edi mov ebp,edi mov ebx,esp add ebx,8 xor edx,edx mov eax,[ebp+8] add eax,3ch ;指向PE头部偏移值e_lfanew mov eax,[eax] ;取得e_lfanew值 add eax,[ebp+8] ;指向PE header cmp dword ptr[eax],4550h ;判断是否为'PE' jne NotFound ;kernel32基址错误 mov [ebp+0ch],eax ;保存PE文件头 mov eax,[eax+78h] add eax,[ebp+8] mov [ebp+0ch],eax ;指向IMAGE_EXPORT_DIRECTORY mov eax,[eax+20h] add eax,[ebp+8] mov [ebp+4],eax ;保存函数名指针数组的指针值 mov ecx,[ebp+0ch] mov ecx,[ecx+14h] FindLoop: push ecx mov eax,[eax] add eax,[ebp+8] mov esi,ebx add esi,8 mov edi,eax mov ecx,[ebx+4] cld repe cmpsb jne FindNext add esp,4 mov eax,[ebp+0ch] mov eax,[eax+1ch] add eax,[ebp+8] shl edx,2 add eax,edx mov eax,[eax] add eax,[ebp+8] jmp Found FindNext: inc edx add dword ptr[ebp+4],4 mov eax,[ebp+4] pop ecx loop FindLoop NotFound: xor eax,eax Found: pop edi pop ebp ret