int main()
{
_asm{
nop
nop
nop
nop
nop
CLD ; clear flag DF
;store hash
push 0x1e380a6a ;hash of MessageBoxA
push 0x4fd18963 ;hash of ExitProcess
push 0x0c917432 ;hash of LoadLibraryA
mov esi,esp ; esi = addr of first function hash
;esi 指向第一个function的hash
lea edi,[esi-0xc] ; edi = addr to start writing function
;edi
; make some stack space
xor ebx,ebx
mov bh, 0x04
sub esp, ebx ;esp-=0x0400
; push a pointer to "user32" onto stack
mov bx, 0x3233 ; rest of ebx is null
push ebx
push 0x72657375
push esp
;push "user32"
xor edx,edx
; find base addr of kernel32.dll
mov ebx, fs:[edx + 0x30] ; ebx = address of PEB
mov ecx, [ebx + 0x0c] ; ecx = pointer to loader data
mov ecx, [ecx + 0x1c] ; ecx = first entry in initialisation order list
mov ecx, [ecx] ; ecx = second entry in list (kernel32.dll)
mov ecx,[ecx]
mov ebp, [ecx + 0x08] ; ebp = base address of kernel32.dll
;ebp 指向kernel32基址
;
find_lib_functions:
lodsd ; load next hash into al and increment esi
;从esi 指向的源地址中逐一读取一个双字,送入eax 中
;并且esi+4
cmp eax, 0x1e380a6a ; hash of MessageBoxA - trigger
; LoadLibrary("user32")
jne find_functions ;一开始eax是 LoadLibrary,所以转去执行find_functions
xchg eax, ebp ; save current hash ;一开始保存当前MessageBox Hash到ebp中
call [edi - 0x8] ; LoadLibraryA
xchg eax, ebp ; restore current hash, and update ebp
; with base address of user32.dll
find_functions:
pushad ; preserve registers
mov eax, [ebp + 0x3c] ; eax = start of PE header
mov ecx, [ebp + eax + 0x78] ; ecx = relative offset of export table
add ecx, ebp ; ecx = absolute addr of export table
mov ebx, [ecx + 0x20] ; ebx = relative offset of names table
add ebx, ebp ; ebx = absolute addr of names table
xor edi, edi ; edi will count through the functions
next_function_loop:
inc edi ; increment function counter
mov esi, [ebx + edi * 4] ; esi = relative offset of current function name
add esi, ebp ; esi = absolute addr of current function name
cdq ; dl will hold hash (we know eax is small)
hash_loop: ;计算hash
movsx eax, byte ptr[esi]
cmp al,ah
jz compare_hash ;计算完了之后比较hash
ror edx,7
add edx,eax
inc esi
jmp hash_loop
compare_hash:
cmp edx, [esp + 0x1c] ; compare to the requested hash (saved on stack from pushad)
jnz next_function_loop ;不是我们的目标函数就继续查看下一个导出函数
;如果是的 话
mov ebx, [ecx + 0x24] ; ebx = relative offset of ordinals table
add ebx, ebp ; ebx = absolute addr of ordinals table
mov di, [ebx + 2 * edi] ; di = ordinal number of matched function
mov ebx, [ecx + 0x1c] ; ebx = relative offset of address table
add ebx, ebp ; ebx = absolute addr of address table
add ebp, [ebx + 4 * edi] ; add to ebp (base addr of module) the
; relative offset of matched function
xchg eax, ebp ; move func addr into eax
pop edi ; edi is last onto stack in pushad
stosd ; write function addr to [edi] and increment edi
push edi
popad ; restore registers
; loop until we reach end of last hash
cmp eax,0x1e380a6a 如果不是MessageBox就回到find_lib_functions
jne find_lib_functions
;至此 已经找到了所有的函数地址 并且存入栈中
function_call:
xor ebx,ebx
push ebx // cut string
push 0x74736577
push 0x6C696166 //push failwest
mov eax,esp //load address of failwest
push ebx
push eax
push eax
push ebx
call [edi - 0x04] ; //call MessageboxA
push ebx
call [edi - 0x08] ; // call ExitProcess
nop
nop
nop
nop
}
}
使用IDA提取出十六进制字节码
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
unsigned char shellcode[]=
"\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\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(*)())shellcode)();
__asm{
lea eax,shellcode
push eax
ret
}
return 0;
}
附带一个从IDA中提取十六进制字节码转换为\xaa的的脚本
import os,sys
def main():
if len(sys.argv)==1:
print 'input the target hex filename'
file=sys.argv[1]
print 'target filename:',file
hexcode=open(file,'r').read()
res=''
c=0
for i in hexcode:
res+='\\x%02x'%ord(i)
c+=1
if c==16:
c=0
res+='\n'
print res
main()