通过TopStack方法获取kernel基址简介

来源:互联网 发布:像素大逃杀制作软件 编辑:程序博客网 时间:2024/06/07 20:27

1、简介

      本地线程的堆栈里偏移1CH(或者18H)的指针指向kernel32.dll内部,而fs:[0x18]指向当前线程而且往里四个字节指向线程栈,
      结合堆栈的top pointer进行对齐遍历,找到PE文件头(DLL的文件格式)的“MZ”MSDOS标志,就拿到了kernel32.dll基址。
先从Windbg里查看一下:
0:000> dt -v -r _NT_TIB $teb
struct _NT_TIB, 8 elements, 0x1c bytes
         +0x000 ExceptionList          : 0x0013fd0c struct _EXCEPTION_REGISTRATION_RECORD, 2 elements, 0x8 bytes
            +0x000 Next                   : 0xffffffff struct _EXCEPTION_REGISTRATION_RECORD, 2 elements, 0x8 bytes
               +0x000 Next                   : ???? 
               +0x004 Handler                : ???? 
            +0x004 Handler                : 0x7c92ee18              _EXCEPTION_DISPOSITION        ntdll!_except_handler3+0
         +0x004 StackBase              : 0x00140000 
         +0x008 StackLimit             : 0x0013e000 
         +0x00c SubSystemTib           : (null) 
         +0x010 FiberData              : 0x00001e00 
         +0x010 Version                : 0x1e00
         +0x014 ArbitraryUserPointer : (null) 
         +0x018 Self                   : 0x7ffdf000 struct _NT_TIB, 8 elements, 0x1c bytes
            +0x000 ExceptionList          : 0x0013fd0c struct _EXCEPTION_REGISTRATION_RECORD, 2 elements, 0x8 bytes
               +0x000 Next                   : 0xffffffff struct _EXCEPTION_REGISTRATION_RECORD, 2 elements, 0x8 bytes
               +0x004 Handler                : 0x7c92ee18                 _EXCEPTION_DISPOSITION        ntdll!_except_handler3+0
            +0x004 StackBase              : 0x00140000 
            +0x008 StackLimit             : 0x0013e000 
            +0x00c SubSystemTib           : (null) 
            +0x010 FiberData              : 0x00001e00 
            +0x010 Version                : 0x1e00
            +0x014 ArbitraryUserPointer : (null) 
            +0x018 Self                   : 0x7ffdf000 struct _NT_TIB

      其中+0x018 Self是一个指向TEB自己的指针,StackBase指向本线程堆栈的原点,即地址最高处,这里是0x140000,
      而StackLimit则指向堆栈所在区间的下部边界,即地址最低处.
————————————————  
/*程序3                             */
xor esi, esi
mov esi, fs:[esi + 0x18]           //TEB 
mov eax, [esi+4]                   //这个是需要的栈顶StackBase,top of the stack
mov eax, [eax - 0x1c]              //指向Kernel32.dll内部 
           //mov eax, [eax - 0x18]
find_kernel32_base:
dec eax                            //开始遍历页
xor ax, ax        
cmp word ptr [eax], 0x5a4d         //"MZ"
jne find_kernel32_base             //循环遍历,找到则返回eax
————————————————  

为了方便测试,我写了一个PEB/TEB/SEH通用测试例程:

/*  
 *        程序4
 *        SEH method test for Windows 9x/NT/2k/XP 
 *        asm return eax contained kernel32.dll base address.
 *        print kernel base address in the console.
 */ 
__inline __declspec(naked) unsigned int GetKernel32()
{
        __asm
{
           push esi
 push ecx


/*        you should replace the follow section if you want to test the others */
 xor esi, esi
 mov esi, fs:[esi + 0x18]      
 mov eax, [esi+4]             
 mov eax, [eax - 0x1c]        
   
 find_kernel32_base:
 dec eax                     
 xor ax, ax        
 cmp word ptr [eax], 0x5a4d  
 jne find_kernel32_base      
/* Above is the section needed to replace */

 pop ecx
 pop esi
 ret
}
}

void main(void)
{
 printf("Kernel base is located at: 0x%0.8X\n",GetKernel32());
}

注意这几句:
1. mov eax, [eax - 0x1c]
      一般地,它将指向kernel32.dll内部,你可以在编译器里单步跟踪调试。其中,eax值为StackBase(0x140000),计算eax-0x1c可得0x0013FFE4;
      在我的机器上0x0013FFE4为0x7C839AA8,0x0013FFE8为7C816FE0。
      此时栈的分布大致如下:
        | ...            |
          0013FFE0          | FFFFFFFF | SEH链尾部          //哦?有疑问吗?SEH吗?
          0013FFE4 | 7C839AA8 | SEH处理程序
          0013FFE8          | 7C816FE0 | kernel32.7C816FE0
        | 00000000 |
        | ...            |


2. dec eax                      
         xor ax, ax 
      这两句的作用就是实现页遍历,单步跟踪结果如下:
      0x7C839AA8 -> 0x7C839AA7 -> 0x7C830000 -> 0x7C82FFFF -> 0x7C820000 -> ... -> 0x7C800000 
      但是,在不同环境下的堆栈不同,如果偏移1C(或18)不指向kernel32.dll内部,将导致获取地址失败,当然这种情况很少发生,
      至少我现在还没遇到过;另一个几率很小的失败现象是64K的页边界有"MZ"这样的特征字符出现,这样可能会误导得到错误的地址。


参考文献:http://www.nbjxzx.cn/E_ReadNews.asp?NewsID=1440

原创粉丝点击