- UID
 - 66114
 
 注册时间2010-4-1
阅读权限30
最后登录1970-1-1
龙战于野 
  
 
 
 
TA的每日心情  | 慵懒 2019-3-12 17:25 | 
|---|
 
  签到天数: 3 天 [LV.2]偶尔看看I  
 | 
 
相信各位读者随着上一节学习已经可以顺利找出程序的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) 交给各位完成(提示:与本小节所讲内容相关)【注:谢绝各位大牛们公布答案-_-!】。 
 
      我将在发布下一节教程时公布答案…… |   
 
 
 
 |