iniwf

风是温柔的,雨是伤心的,云是快乐的,月是多情的,爱是迷失的,恋是醉人的,情是难忘的,天是长久的,地是永恒的

内核反编译学习笔记2

内核反编译学习笔记2(上)

 

本节任务:通过具有不同数量参数的函数调用,看其中区别
所用程序bz3
需要掌握:
windbg命令:
uf 反汇编
dd 查看内容

调用的时候:
mov     给参数赋值
push   eax 供函数使用的参数
被调用函数内部
push    ebp         保存ebp,用来保存调用前运行的代码地址
mov     ebp,esp     将esp赋值给ebp,现在有新的ebp指针了,指向栈顶

pop     ebp         恢复ebp,取得地址,准备跳到那地址的代码,继续运行程序


需要了解
JMP    无条件跳转,去运行跳转后地址的代码
ret              返回,注意,调用前每push一个参数,esp就-4,两个参数就-8,ret的时候,需要+8返回

无需了解:
call=push+JMP
ret = pop+JMP      将在后面继续说明


//先贴代码,仔细看其实很简单


VOID MyP0()
{
 DbgPrint("no arg...\r\n");
}

VOID MyP1(ULONG u1)
{
 DbgPrint("One arg:%d\n!",u1);
}

VOID MyP2(ULONG u1,ULONG u2)
{
   ULONG u3;
   u3 = u1+u2;
   DbgPrint("two arg:%d\n!",u3);

}
 

VOID DriverUnload(PDRIVER_OBJECT driver)
{
 
 DbgPrint("unload…\r\n");
}


NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path)
{
 ULONG x1 = 5;
 ULONG x2 = 8;
 
 
 
#if DBG
       _asm int 3
#endif
 
 MyP0();
 MyP1(x1);
 MyP2(x1,x2);
 

 
 driver->DriverUnload = DriverUnload;
 return STATUS_SUCCESS;
}

//////代码结束


以下分别为Entry主函数和3个自定义函数的反汇编。
汇编完了先放那,具体解析在下面。


kd> uf bz3!driverentry
bz3!DriverEntry [d:\mydriver\bz3\bz3.c @ 31]:
   31 f8451520 8bff            mov     edi,edi
   31 f8451522 55              push    ebp
   31 f8451523 8bec            mov     ebp,esp
   31 f8451525 83ec08          sub     esp,8
   32 f8451528 c745f805000000  mov     dword ptr [ebp-8],5
   33 f845152f c745fc08000000  mov     dword ptr [ebp-4],8
   38 f8451536 cc              int     3
   41 f8451537 e854ffffff      call    bz3!MyP0 (f8451490)
   42 f845153c 8b45f8          mov     eax,dword ptr [ebp-8]
   42 f845153f 50              push    eax
   42 f8451540 e86bffffff      call    bz3!MyP1 (f84514b0)
   43 f8451545 8b4dfc          mov     ecx,dword ptr [ebp-4]
   43 f8451548 51              push    ecx
   43 f8451549 8b55f8          mov     edx,dword ptr [ebp-8]
   43 f845154c 52              push    edx
   43 f845154d e87effffff      call    bz3!MyP2 (f84514d0)
   47 f8451552 8b4508          mov     eax,dword ptr [ebp+8]
   47 f8451555 c74034001545f8  mov     dword ptr [eax+34h],offset bz3!DriverUnload (f8451500)
   48 f845155c 33c0            xor     eax,eax
   49 f845155e 8be5            mov     esp,ebp
   49 f8451560 5d              pop     ebp
   49 f8451561 c20800          ret     8
  

内核反编译学习笔记2(下)

 

三个自定义:
kd> uf bz3!myp0
bz3!MyP0 [d:\mydriver\bz3\bz3.c @ 5]:
    5 f8451490 8bff            mov     edi,edi
    5 f8451492 55              push    ebp
    5 f8451493 8bec            mov     ebp,esp
    6 f8451495 68701545f8      push    offset bz3! ?? ::FNODOBFM::`string' (f8451570)
    6 f845149a e8cb000000      call    bz3!DbgPrint (f845156a)
    6 f845149f 83c404          add     esp,4
    7 f84514a2 5d              pop     ebp
    7 f84514a3 c3              ret
kd> uf bz3!myp1
bz3!MyP1 [d:\mydriver\bz3\bz3.c @ 10]:
   10 f84514b0 8bff            mov     edi,edi
   10 f84514b2 55              push    ebp
   10 f84514b3 8bec            mov     ebp,esp
   11 f84514b5 8b4508          mov     eax,dword ptr [ebp+8]
   11 f84514b8 50              push    eax
   11 f84514b9 68801545f8      push    offset bz3! ?? ::FNODOBFM::`string' (f8451580)
   11 f84514be e8a7000000      call    bz3!DbgPrint (f845156a)
   11 f84514c3 83c408          add     esp,8
   12 f84514c6 5d              pop     ebp
   12 f84514c7 c20400          ret     4
kd> uf bz3!myp2
bz3!MyP2 [d:\mydriver\bz3\bz3.c @ 15]:
   15 f84514d0 8bff            mov     edi,edi
   15 f84514d2 55              push    ebp
   15 f84514d3 8bec            mov     ebp,esp
   15 f84514d5 51              push    ecx
   17 f84514d6 8b4508          mov     eax,dword ptr [ebp+8]
   17 f84514d9 03450c          add     eax,dword ptr [ebp+0Ch]
   17 f84514dc 8945fc          mov     dword ptr [ebp-4],eax
   18 f84514df 8b4dfc          mov     ecx,dword ptr [ebp-4]
   18 f84514e2 51              push    ecx
   18 f84514e3 68901545f8      push    offset bz3! ?? ::FNODOBFM::`string' (f8451590)
   18 f84514e8 e87d000000      call    bz3!DbgPrint (f845156a)
   18 f84514ed 83c408          add     esp,8
   20 f84514f0 8be5            mov     esp,ebp
   20 f84514f2 5d              pop     ebp
   20 f84514f3 c20800          ret     8
  
  
   正式开始我们的任务
   ////////////
   以下为Entry中调用函数的反汇编代码
  
         call    bz3!MyP0 (f8451490)     ;无参数
        
         mov     eax,dword ptr [ebp-8]   ;1个参数
         push    eax
         call    bz3!MyP1 (f84514b0)    
        
         mov     ecx,dword ptr [ebp-4]   ;2个参数
         push    ecx
         mov     edx,dword ptr [ebp-8]
         push    edx
         call    bz3!MyP2 (f84514d0)   

   显然我们可以得出结论:
   在调用函数的时候,无参数,直接call,
   有参数,有几个要push几个,把eax等寄存器内的数据入栈:push exx
   eax,edx等寄存器内的数据哪里来的呢?通过mov,从存放地点移动过来赋值。
  
  
  //接下来我们进入函数内部,要动态追踪下面代码。以后每次看见这样代码,明白道理,就直接忽略:
  push    ebp         保存ebp
  mov     ebp,esp     保存esp

  pop     ebp         获得ebp
  ret              返回,注意,后面为什么是8
 
  我们先看一下Entry调用MyP0处的地址:
   38 f8451536 cc              int     3
   41 f8451537 e854ffffff      call    bz3!MyP0 (f8451490)
   42 f845153c 8b45f8          mov     eax,dword ptr [ebp-8]
  
   显然调用MyP0后,要运行f845153c的代码。然后我们到函数内部看
     push    ebp         中ebp的内容,是不是f845153c
    
  进入windbg:
//////////////////////////
  kd> t
bz3!DriverEntry+0x17:
f8451537 e854ffffff      call    bz3!MyP0 (f8451490)
kd> t
bz3!MyP0:
f8451490 8bff            mov     edi,edi
kd> p
bz3!MyP0+0x5:
f8451495 68701545f8      push    offset bz3! ?? ::FNODOBFM::`string' (f8451570)
kd> dd ebp
f8282c6c  f8282c7c f845153c 00000005 00000008
//////////////////
呵呵,没错,f845153c,5,8,都是要用的。
下面两个地址也应该出现在下面两个函数的ebp中,不然程序返回后不知道继续运行哪里的代码。
 f8451545 f8451552
 
 顺便看下类似下面命令是什么意思
 mov     eax,dword ptr [ebp+8]
 
我们要知道 ebp+8,要先看下ebp:
 
kd> dd ebp
f8282c64:  f8282c7c f8451552 00000005 00000008

可以看到,ebp+4就是f8451552,返回后继续运行的地址,ebp+8当然是5了,ebp+12(哦,要16进制:ebp+c)是8。
那我们直接看下dd ebp+8:
kd> dd ebp+8
f8282c6c:   00000005 00000008 00000005 00000008
kd> dd ebp+c
f8282c70:  00000008 00000005 00000008 f8282d4c

应该没疑问了。
 
//////////////
以后看汇编代码的时候,可以忽略:
  push    ebp         保存返回地址
  mov     ebp,esp     设置新的ebp指针,指向栈顶
中间是具体实现
  pop     ebp         获得返回地址
  ret              返回

只看这些代码中间的代码就可以了,以后直接贴这些代码中间的实现。

posted on 2010-04-18 19:02 iniwf 阅读(460) 评论(0)  编辑 收藏 引用 所属分类: 驱动反汇编


只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


导航

统计

常用链接

留言簿(2)

随笔分类

随笔档案

收藏夹

IT技术

积分与排名

最新评论

阅读排行榜

评论排行榜