庞大资源库的计算机教程网站!
设为首页
加入收藏
总编信箱
投稿或申请专栏请先 [登 陆]
首页 操作系统 程序设计 图形图像 媒体动画 机械电子 WEB开发 数 据 库 办公系列 路由技术 网络原理 网络应用
认证考试 安全技术
首页>安全技术>软件破解>原理分析>正文
资料搜索
Google搜索
Google
返回上级列表

推荐文章

快速保存网页中所有图片的方法
Windows中让光驱巧妙“隐身”技
防范非法用户入侵Win 2000/XP系
两款比较典型的ASP木马防范方法
有关表格边框的css语法整理
Windows XP中可以被禁用的服务
SQL Server导出导入数据方法
Javascript所有对象的属性的获
网页(HTML)中的特殊字符
与篮球共舞,尽显模式本色
QQ病毒的手工清除方法
Photoshop为极品美女打造性感睫
天衣无缝:IIS与PHP水火也相容
SQL Server存储过程编写和优化

动态分析技术-拆解教程 下

 作者:本站收集   日期:2005-5-28
字号选择〖 〗/ 双击滚屏 单击停止   
所以我们来看看EBP-34那里有什么:
        :d ebp-3
你应该能在数据窗中看到你输入的东西。下面我们得来找开始核对输入注册码的
地方。按F10一步一步地单步运行直到你发现与EBP-34有点关系的地方.... 你不
用单步运行多久,就会看到这些代码:
    >   LEA     EAX, [EBP+FFFFFF64]             ; EAX = EBP-9C
        LEA     ECX, [EBP-34]                   ; ECX = EBP-34
        PUSH    EAX                             ; 保存 EAX
        PUSH    ECX                             ; 保存 ECX
    >   CALL    00403DD0                        ; Call 一子程序
        ADD     ESP, 08                         ; 删除保存的信息
        TEST    EAX, EAX                        ; 检查返回值
        JNZ     00402BC0                        ; 如果不是零的话跳转
对我来说,马上就可以看出这象是一个字符比较程序。它们工作起来就是这样:
        * 输入两个字符串
          如果相同就返回零
          否则返回非零
那为什么程序要用一个字符串来和你输入的相比较呢?看它是不是合法的!(可
能你已经想到了)。那么是什么东西躲在 [EBP+FFFFFF64] ? SoftICE处理负数
还不是很好,所以得算算:
        100000000 - FFFFFF64 = 9C
在 SoftICE 用这样的命令:
        :? 0-FFFFFF64
100000000 对SoftICE来说太大了,但它还是给出了相同的结果。
现在是...来看看什么东西躲在EBP-9C那里的时候了...这样输入命令:
        :d ebp-9c
数据窗口会显示出一大排数字 ─ 注册码!但是记住我前面说过的...两种注册
方式对应两个注册码....所以你把这些注册码抄下来以后,继续用F10单步运行
....我们会遇到这些代码:
    >   LEA     EAX, [EBP-68]                   ; EAX = EBP-68
        LEA     ECX, [EBP-34]                   ; ECX = EBP-34
        PUSH    EAX                             ; 保存 EAX
        PUSH    ECX                             ; 保存 ECX
    >   CALL    00403DD0                        ; 再次调用子程序
        ADD     ESP, 08                         ; 删除保存的信息
        TEST    EAX, EAX                        ; 检查返回结果
        JNZ     00402BFF                        ; 如果非零跳转
你在EBP-68处找到了什么?不错吧...另一个注册码。
        :d ebp-68
我们的练习结束了,希望一切顺利。
3.2  Command Line 95 -容易的用户名/注册码方式的注册、注册器
=================================================================
这是一个非常好的例子,注册码的计算也很简单。
3.1.1 检查程序
===========================
检查程序以后你知道它是32位的应用程序,要求输入名字和注册码。 让我们开始!
3.1.2 捕捉代码
===========================
我们象拆解TaskLock那样 ─ 设置断点。我们可以在两个可能性最大的两个函数
都设上断点:GetWindowTextA 和 
GetDlgItemTextA. 按下Ctrl+D 进入SoftICE, 然后:
        :bpx getwindowtexta
        :bpx getdlgitemtexta
接下来进入注册对话框,输入一个名字和一些数字(多数情况下是一个整数),
我是这么写的,然后按OK....
        Name:   ED!SON '96
        Code:   12345
程序在 GetDlgItemTextA 处停住了,就象TaskLock一样。我们按F11回到调用它
的地方。用 Ctrl+Up卷动窗口直到看到这些:
        MOV     ESI, [ESP+0C]
        PUSH    1E                              ; 最大长度
        PUSH    0040A680                        ; 缓冲地址
        PUSH    000003ED                        ; 控制柄
        PUSH    ESI                             ; 对话柄
        CALL    [User32!GetDlgItemTextA]
数字40A680引起了我们的注意,看看那里有什么:
        :d 40a680
如果没有我们输入的名字,
数据窗口里有些什么呢?好了,我们来研究下面的一 段代码:
        PUSH    00
        PUSH    00
        PUSH    000003F6                        ; 控制柄
        MOV     EDI, 0040A680                   ; 保存缓冲区地址
        PUSH    ESI                             ; 对话柄
        CALL    [User32!GetDlgItemInt]
GetDlgItemInt 和 GetDlgItemText差不多,但它从文字框中返回一个整数。
它出在EAX中返回来的,所以单步运行通过这些代码,再来看看寄存器窗....
对我而言是:
        EAX=00003039
十六进制数3039是多少? 输入:
        :? 3039
我们得到:
        00003039  0000012345  "09"
        ^ 16进制  ^ 十进制     ^ ASCII
正如你看到(和已经猜到)的那样,它是你输入的注册码。OK,下面怎么办?让
我们来看下面的代码:
        MOV     [0040A548], EAX                 ; 返回注册码
        MOV     EDX, EAX                        ; 同时保存在DX中
3.1.3 计算注册码
==========================
这样注册码就算出来了
        MOV     ECX, FFFFFFFF                   ; 这几行计算字符长度
        SUB     EAX, EAX                        ; .
        REPNZ SCASB                             ; .
        NOT     ECX                             ; .
        DEC     ECX                             ; ECX <-- 长度
        MOVSX   EAX, BYTE PTR [0040A680]        ; 读入40A680处的一字节
        IMUL    ECX, EAX                        ; ECX = ECX * EAX
        SHL     ECX, 0A                         ; 左移 0A 次
        ADD     ECX, 0002F8CC                   ; 结果加上2F8CC
        MOV     [0040A664], ECX
验证合法性....
        CMP     ECX, EDX                        ; 比较
        JZ      00402DA6                        ; 如果相同就....
当你运行到比较这一步时,就可以得到你真正的注册码:
        :? ecx
对我而言它是:
        000DC0CC  0000901324
也就是说我的正确的注册码是901324.
按F5或者Ctrl+D让它运行,
然后用正确的注册码(十进制)再来一次。这一次 成功了!
4.  为COMMAND LINE 95制作注册器
=========================================
我们把上面计算注册码的代码翻译成C语言程序。 最明了的计算公式就是:
code=((uppercase_first_char * length_of_string) << 0x0A) + 0x2f8cc;
注(1): 别忘了一件事 就是把所有字符转成大写
  (2): "<< 0x0A" 实际上就是 "乘以 2^10"
完整的程序就是:
        #include <string.h>
        #include <stdio.h>
        int main()
        {
                unsigned long code;
                unsigned char buffer[0x1e];
                printf("CommandLine95 Keymaker by ED!SON '96\n");
                printf("Enter name:   ");
                gets(buffer);
                strupr(buffer);
                code = ( ((unsigned long)buffer[0] *
                        (unsigned long)strlen(buffer))
                        << 0x0A) + 0x2f8cc;
                printf("Your code is: %lu", code);
                return 0;
        }
爽吧?
4. 当程序调用一个函数时,PUSH和CALL这些指令是如何工作的
====================================================
我们重新来看看TaskLock中的这段代码:
        PUSH    32                        ; 字符串最大长度
        PUSH    EAX                       ; 字符缓冲区地址
        PUSH    000003F4                  ; 控制标识
        PUSH    DWORD PTR [ESI+1C]        ; 对话框柄
        CALL    [USER32!GetDlgItemTextA]  ; 获得字符
如果认为是C语言编译出来的话,这个CALL应该是这样:
  GetDlgItemTextA(hwndDlg, 0x3F4, buffer, 0x32);
                  ^ [ESI+1C]      ^ EAX
PUSH把数据保存在叫做堆栈的地方。每个PUSH把新的数据放在堆栈的顶部,被调
用的子程序就挨个地检查躺在堆栈中的数据,按照定义来使用它们。
附录
A. 让SoftICE载入符号
==============================
你可以用exp getwindowtext命令来检查SoftICE是否已经为GetWindowText装入
了符号,象这样:
       :exp getwindowtext
如果你没有得到所有GetWindowText函数的列表,你就得编辑\SIW95\WINICE.DAT,
在"Examples of export symbols that can be included for chicago"这段文字
以后的那些 'exp='的行首去掉';',为了节省内存,选择最重要的几个就可以了:
   kernel32.dll
   user32.dll
   gdi32.dll
编辑完后,重新起动计算机使其生效。
B. 函数语法
============================
如果你看看下面的函数声明,对我们上面讲到的函数调用就容易明白了:
int GetWindowText(int windowhandle, char *buffer, int maxlen); int
GetDlgItemText(int dialoghandle, int controlid, char *buffer,
                   int maxlen);
int GetDlgItemInt(int dialoghandle, 
int controlid, int *flag, int type);
这些函数的详细描述,可参考Windows/Win32编程手册
=====================================================
上一篇:动态分析技术-拆解教程 上    下一篇:静态分析技术-W32Dasm简介 上  
[发送给好友]  [关闭窗口]  [返回顶部]   转载请注明来源:www.it00.com   
特别声明: 本站除部分特别声明禁止转载的专稿外的其他文章可以自由转载,但请务必注明出处和原始作者。文章版权归文章原始作者所有。对于被本站转载文章的个人和网站,我们表示深深的谢意。如果本站转载的文章有版权问题请联系编辑人员,我们尽快予以更正。
责任编辑: 原点 投稿作者: 本站收集
信息来源: 网络 录入时间: 2005-5-28
关于我们 - 广告服务 - 版权申明 - 网站地图 - 联系方式 - 总编信箱 - 会员投稿