一个简单的弹出对话框的shellcode(取自0day2一书)

来源:互联网 发布:js字符串实例 编辑:程序博客网 时间:2024/05/29 02:05
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,sysdef 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 resmain()
1 0