飘云阁

 找回密码
 加入我们

QQ登录

只需一步,快速开始

查看: 3692|回复: 0

一个简单的小例子

[复制链接]
  • TA的每日心情
    慵懒
    2019-3-12 17:25
  • 签到天数: 3 天

    [LV.2]偶尔看看I

    发表于 2010-5-28 16:29:31 | 显示全部楼层 |阅读模式
    相信各位读者随着上一节学习已经可以顺利找出程序的main函数了,既然如此,那么接下来我们是不是应该做点什么呢?嗯,让我好好想想,我们一起来玩一个小游戏吧,看看我们是否可以让目标程序显示“Hello everybody”,而不是毫无个性的“Hello World”。

          这里我先放出源代码:

    int _tmain(int argc, _TCHAR* argv[])
    {
        if (argc)
        {
            printf("Hello world!\r\n");
        }
        else
        {
            printf("Hello everybody!\r\n");
        }
      return 0;
    }

          各位读者应该都知道程序在执行时会将自己的路径保存到argv字符数组里的,因此argc的值肯定都是始终大于1的,所以程序如果未经处理总是会显示“Hello world!”,现在就让我们给他做一个微型外科手术吧。

          为了更接近实战,所以这次我们要分析Release版的,找到main函数后其内容如下:

    00401000  CMP DWORD PTR SS:[ESP+4], 0
    00401005  JE SHORT Test_0.00401018
    00401007  PUSH Test_0.004020F4                     ; /format = "Hello world!
    0040100C  CALL DWORD PTR DS:[<&MSVCR90.printf>]    ; \printf
    00401012  ADD ESP, 4
    00401015  XOR EAX, EAX
    00401017  RETN
    00401018  PUSH Test_0.00402104                     ; /format = "Hello everybody!
    0040101D  CALL DWORD PTR DS:[<&MSVCR90.printf>]    ; \printf
    00401023  ADD ESP, 4
    00401026  XOR EAX, EAX
    00401028  RETN

          看到这些有些读者应该已经快大叫起来了“这个我知道,改关键跳!”但是请注意,我们现在不是在学爆破,而是在学习逆向,因此
    还请各位读者静下心来好好看看这段代码的意思。

          由于ESP是栈指针,ESP的值也就是当前栈的所在位置,而[ESP+4]的意思就是在当前堆栈+4的地方取其内容,那么这句话的意思也就是在当前堆栈+4的地方取其内容,然后与0比较。
          第二句话的意思是检查其比较结果,我们都知道其实cmp指令的作用其实就是对着两个操作数做减法操作,只不过不保存操作结果,仅影响标志位。因此结合起来看可以用C语言描述为如下形式:

        if([ESP+4]!=0)
        { …… }
        else
        { …… }

          但是[ESP+4]我们又怎样理解呢?下面我就带领大家顺便再温习一下栈的结构,先看图:

            ESP = 0012FFE0
          栈地址    栈内容
        ┏━━━━┳━━━━┓
        ┃0012FFE8┃00000000┃▲
        ┣━━━━╋━━━━┫┃
        ┃0012FFEC┃00000000┃┃由
        ┣━━━━╋━━━━┫┃高
      ->┃0012FFF0┃00000000┃┃向
        ┣━━━━╋━━━━┫┃低
        ┃0012FFF4┃00000000┃┃增
        ┣━━━━╋━━━━┫┃长
        ┃0012FFF8┃00000000┃┃
        ┣━━━━╋━━━━┫┃
        ┃0012FFFC┃00000000┃┃
        ┗━━━━┻━━━━┛


        我们应该还记得在进入一个CALL后,其ESP指向的地址为这个CALL的返回地址,如果在调用这个CALL之前压入了一个参数,那么要找到它的方法很定是将当前ESP加上4在取内容,为了更利于各位读者理解这里我为各位举一个比较典型的例子:

    …………  …………
    00400010  jmp 00400200h
    …………  …………
    00400100  mov eax,[esp+4]
    00400104  mov [esp-4],eax  ; 将参数2的值传给局部变量1
    00400108  mov eax,[esp+8]
    0040010C  mov [esp-8],eax  ; 将参数1的值传给局部变量2
    00400110  retn             ; 假如我们此时停到这里!EIP = 00400110
    …………  …………
    00400200  push 11          ; 参数1
    00400202  push 22          ; 参数2
    00400204  call 00400100
    00400209  …………

        它的栈结构大致如下:

            ESP = 0012FFE4
          栈地址    栈内容
        ┏━━━━┳━━━━┓
        ┃0012FFE8┃00000000┃▲
        ┣━━━━╋━━━━┫┃
        ┃0012FFEC┃00000011┃┃由  <- 局部变量2
        ┣━━━━╋━━━━┫┃高
        ┃0012FFF0┃00000022┃┃向  <- 局部变量1
        ┣━━━━╋━━━━┫┃低
      ->┃0012FFF4┃00400209┃┃增  <- 返回地址
        ┣━━━━╋━━━━┫┃长
        ┃0012FFF8┃00000022┃┃    <- 参数2
        ┣━━━━╋━━━━┫┃
        ┃0012FFFC┃00000011┃┃    <- 参数1
        ┗━━━━┻━━━━┛

          本小节就算是又带领大家又大致温习了一下一些基础知识,现在我们回到主题,看看怎样达到我们的目的,我想这应该是很简单的事情了,我目前想出了以下方案:

    (1) 将00401005处的JZ改为JMP
    (2) 将004020F4处的文本信息改为Hello everybody!
    (3) 交给各位完成(提示:与本小节所讲内容相关)【注:谢绝各位大牛们公布答案-_-!】。

          我将在发布下一节教程时公布答案……
    PYG19周年生日快乐!
    您需要登录后才可以回帖 登录 | 加入我们

    本版积分规则

    快速回复 返回顶部 返回列表