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了:

结果:

posted @ 2024-03-09 11:18  robot__i  阅读(35)  评论(0)    收藏  举报