您现在的位置: 捷凌网安 >> 编程语言 >> VCC >> 正文
dll反汇编初步

作者:佚名 责任编辑:左决 点击数: 更新时间:2008-2-15 6:26:41

没有什么特别有效的方法,靠的就是耐心和经验,反复验证,直到调用成功。 
 有个dll2lib的工具,不知道是我不会使用还是怎么的,反正我是没有使用成功过,所以我只能靠自己

来分析了。

 首先是使用的工具,ida/win32dasm/ollydbg

 win32dasm分析的速度快一些,但是智能程度不如ida,ida这个2001开发工具亚军绝对不是浪得虚名的

,它的智能程度非常高,可是识别出常用的函数,这两个都是静态反汇编的工具,必须配以动态分析的工具,

毕竟你很难一下子就分析对(至少我是这样),当然你可以使用s-ice或者trw,但是这些工具都有限制,trw不支

持2000,s-ice一旦装载只能reboot才能取消装载,还有其工作在ring0,所以你只能对者黑乎乎的屏幕,很痛

苦,这里选用的ollydbg是最新版本,支持dll的跟踪。

 下面列出win32dasm反汇编的结果:

 Exported fn(): GetUserNumber - Ord:0004h
:0040C1B0 55                      push ebp
:0040C1B1 8BEC                    mov ebp, esp
:0040C1B3 53                      push ebx
:0040C1B4 56                      push esi
:0040C1B5 57                      push edi
:0040C1B6 8B5D08                  mov ebx, dword ptr [ebp+08]
:0040C1B9 33F6                    xor esi, esi
:0040C1BB 8BC3                    mov eax, ebx
:0040C1BD E846A5FFFF              call 00406708
:0040C1C2 6685C0                  test ax, ax
:0040C1C5 7212                    jb 0040C1D9
:0040C1C7 40                      inc eax
:0040C1C8 33D2                    xor edx, edx

* Referenced by a (U)nconditional or (C)ondITional Jump at Address:
|:0040C1D7(C)
|
:0040C1CA 0FB7CA                  movzx ecx, dx
:0040C1CD 0FB60C0B                movzx ecx, byte ptr [ebx+ecx]
:0040C1D1 03F1                    add esi, ecx
:0040C1D3 42                      inc edx
:0040C1D4 66FFC8                  dec ax
:0040C1D7 75F1                    jne 0040C1CA

* Referenced by a (U)nconditional or (C)ondITional Jump at Address:
|:0040C1C5(C)
|
:0040C1D9 8B450C                  mov eax, dword ptr [ebp+0C]
:0040C1DC 8A4012                  mov al, byte ptr [eax+12]
:0040C1DF 3C61                    cmp al, 61
:0040C1E1 720B                    jb 0040C1EE
:0040C1E3 25FF000000              and eax, 000000FF
:0040C1E8 6683E861                sub ax, 0061
:0040C1EC EB09                    jmp 0040C1F7

* Referenced by a (U)nconditional or (C)ondITional Jump at Address:
|:0040C1E1(C)
|
:0040C1EE 25FF000000              and eax, 000000FF
:0040C1F3 6683E841                sub ax, 0041

* Referenced by a (U)nconditional or (C)ondITional Jump at Address:
|:0040C1EC(U)
|
:0040C1F7 8B550C                  mov edx, dword ptr [ebp+0C]
:0040C1FA 8A5213                  mov dl, byte ptr [edx+13]
:0040C1FD 80FA61                  cmp dl, 61
:0040C200 720C                    jb 0040C20E
:0040C202 81E2FF000000            and edx, 000000FF
:0040C208 6683EA61                sub dx, 0061
:0040C20C EB0A                    jmp 0040C218

* Referenced by a (U)nconditional or (C)ondITional Jump at Address:
|:0040C200(C)
|
:0040C20E 81E2FF000000            and edx, 000000FF
:0040C214 6683EA41                sub dx, 0041

* Referenced by a (U)nconditional or (C)ondITional Jump at Address:
|:0040C20C(U)
|
:0040C218 0FB7C0                  movzx eax, ax
:0040C21B 6BF81A                  imul edi, eax, 0000001A
:0040C21E 0FB7C2                  movzx eax, dx
:0040C221 03F8                    add edi, eax
:0040C223 81F74D010000            xor edi, 0000014D
:0040C229 83F701                  xor edi, 00000001
:0040C22C 8BC3                    mov eax, ebx
:0040C22E E8D5A4FFFF              call 00406708
:0040C233 2BF8                    sub edi, eax
:0040C235 8BC6                    mov eax, esi
:0040C237 B91A000000              mov ecx, 0000001A
:0040C23C 99                      cdq
:0040C23D F7F9                    idiv ecx
:0040C23F 2BFA                    sub edi, edx
:0040C241 8BC7                    mov eax, edi
:0040C243 5F                      pop edi
:0040C244 5E                      pop esi
:0040C245 5B                      pop ebx
:0040C246 5D                      pop ebp
:0040C247 C20800                  ret 0008

 通过ret 008我们可以知道这个函数需要两个参数,通过mov eax, esi,我们可以知道这个函数有反回

值(这是因为在高级语言里面一般通过eax设置函数返回值)具体返回什么类型现在还没办法知道,但是不管这么

多,我们假设此函数是这样的:

 int GetUserNumber(int a1,int a2)

我们会在后续分析后,慢慢修正他,现在我们开始一点点分析。

:0040C1B0 55                      push ebp
:0040C1B1 8BEC                    mov ebp, esp
:0040C1B3 53                      push ebx
:0040C1B4 56                      push esi
:0040C1B5 57                      push edi
这个是function prolog,建立堆栈和寄存器的保存,没什么可多说的。
:0040C1B6 8B5D08                  mov ebx, dword ptr [ebp+08]
:0040C1B9 33F6                    xor esi, esi
:0040C1BB 8BC3                    mov eax, ebx
:0040C1BD E846A5FFFF              call 00406708

这里你需要知道函数调用过程的参数传递,可以到asm.yeah.net看看罗云彬那篇很好的关于参数传递和堆栈修

复的文章,这里简单说一下,调用函数的时候如果通过堆栈来传递参数的话,那么对于我们讨论的函数可能是

这样的:

  push a2
  push a1
  call GetUserNumber

此时堆栈看起来是这样的

  -----a2
  -----a1
 esp-> -----returnaddress
这时候进入函数内部push ebp后
 esp+c -----a2
 esp+8 -----a1
 esp+4 -----returnaddress
 esp-> -----ebp

 mov ebp,esp

 此时要寻址a1可以通过ebp+8

:0040C1B6 8B5D08                  mov ebx, dword ptr [ebp+08]; ebx保存第一个参数
:0040C1B9 33F6                    xor esi, esi
:0040C1BB 8BC3                    mov eax, ebx
:0040C1BD E846A5FFFF              call 00406708

这个很简单esi清零,把第一个参数传递给eax,然后调用00406708

所以我们接下来就是要到00406708里面去看看
:00406708 89FA                    mov edx, edi
:0040670A 89C7                    mov edi, eax
:0040670C B9FFFFFFFF              mov ecx, FFFFFFFF
:00406711 30C0                    xor al, al
:00406713 F2                      repnz
:00406714 AE                      scasb
:00406715 B8FEFFFFFF              mov eax, FFFFFFFE
:0040671A 29C8                    sub eax, ecx
:0040671C 89D7                    mov edi, edx
:0040671E C3                      ret

这个是很典型的求字符串长度的代码
:00406708 89FA                    mov edx, edi    ;保存edi
:0040670A 89C7                    mov edi, eax   ;eax是我们调用前的a1
:0040670C B9FFFFFFFF              mov ecx, FFFFFFFF ecx设置成最大32数
:00406711 30C0                    xor al, al   ;al清零

我们知道汇编指令的字符串操作一般通过esi和edi,上面的过程在注释里给出解释
:00406713 F2                      repnz
:00406714 AE                      scasb   ;判断字符串是否结束
:00406715 B8FEFFFFFF              mov eax, FFFFFFFE
:0040671A 29C8                    sub eax, ecx  ;eax保存了字符串长度
:0040671C 89D7                    mov edi, edx  ;恢复edi
:0040671E C3                      ret

上面分析我们知道参数a1是一个字符串,现在把我们的函数修正如下
 int GetUserNumber(char * a1,int a2)


继续我们的分析:

:0040C1C2 6685C0                  test ax, ax   ;长度是否为零
:0040C1C5 7212                    jb 0040C1D9 ;为零则跳转
:0040C1C7 40                      inc eax ;eax加一
:0040C1C8 33D2                    xor edx, edx ;edx清零

我们用c语言写出等价程序如下:
int GetUserNumber(char * strUserName,test * pt)
{
 
 esi = 0;

 int len = strlen(strUserName);
 if(len <= 0)
  goto _SKIP_USERNAME;

_SKIP_USERNAME:

}

继续分析并且进一步修正我们的代码

[1] [2] [3] 下一页

  • 上一篇文章:

  • 下一篇文章:
  •  
    最进更新
    普通文章VC++设计超强仿QQ自动伸缩窗04-17
    推荐文章基于HOOK和MMF的Win密码渗透04-17
    推荐文章几种VC++数据库开发技术的相04-17
    普通文章多线程、Socket技术及委托技04-11
    推荐文章VB.Net连接各种数据库的几种04-11
    普通文章VB.NET中的多窗体编程:升级04-11
    普通文章用VB.NET定制Windows控件04-11
    普通文章VB.NET中监视文件夹的变化04-11
    普通文章VB.NET中对象的克隆04-11
    推荐文章VB.NET中的TextBox控件详解04-11
     
    推荐文章
    推荐文章基于HOOK和MMF的Win密码渗透04-17
    推荐文章几种VC++数据库开发技术的相04-17
    推荐文章VB.Net连接各种数据库的几种04-11
    推荐文章VB.NET中的TextBox控件详解04-11
    推荐文章在VB.NET中进行抓屏04-11
    推荐文章VB.Net开发的长内容自动分页04-11
    推荐文章VB.NET中快速访问注册表技巧04-11
    推荐文章PHP5手动最简安装方法03-07
    推荐文章完全讲解PHP+MySQL的分页显示03-07
    推荐文章Linux Shell元字符知识笔记02-21
     
    热点文章 
    普通文章VC++设计超强仿QQ自动伸缩窗04-17
    推荐文章基于HOOK和MMF的Win密码渗透04-17
    推荐文章几种VC++数据库开发技术的相04-17
    普通文章VB.NET中的多窗体编程:升级04-11
    普通文章用VB.NET定制Windows控件04-11
    普通文章VB.NET中对象的克隆04-11
    推荐文章VB.NET中的TextBox控件详解04-11
    普通文章VB/VB.NET/C#导出到Excel的方04-11
    普通文章如何通过VB.NET获取网卡地址04-11
    普通文章VB.NET中使用ListView控件的04-11

    | 设为首页 | 加入收藏 | 联系站长 | 广告服务 | 友情链接 | 版权申明 | 网站地图 |

    在线交流 捷凌网安主群:51649627
    Copyright 2007-2008 © 捷凌网安. All rights reserved.
    备案序号:蜀ICP备08001812号