简单逆向

来源:互联网 发布:python eval() 编辑:程序博客网 时间:2024/05/17 23:30

转自:http://www.cnblogs.com/kakaxisir/p/4928022.html

之前大致了解过PE格式、ELF格式、COFF格式以及内存布局和栈的布局,这次直接实战反编译。

参考书籍:1.0day安全:软件漏洞分析技术
     2.IDA PRO 权威指南

首先搭建开发环境:虚拟机安装系统Windows XP SP2 ,安装VC++6.0,安装ollydbg和IDA PRO

      主机:Linux,安装dumpbin、objdump、nidisasm和ditorm(后三个暂时用不上)

一:开发一个简单的C语言程序,主要逻辑是简单验证(本次的目的就是突破这种验证限制)

复制代码
#include <string.h>#include <stdio.h>#define PASSWORD "123456"int verify_password(char *password){    int authenticated;    authenticated = strcmp(password,PASSWORD);    return authenticated;}int main(int argc, char* argv[]){    int valid_flag =0;    char password[1024];    while(1){        printf("please input password: ");        scanf("%s",password);        valid_flag = verify_password(password);        if(valid_flag){            printf("incorrect password!\n\n");        }else{            printf("Congratulation! you have passed the verification ");            break;        }    }    return 0;}
复制代码

二:先使用一些其他的深度探测工具来检查

  1.  strings (Linux下用于提取文件中的字符串内容)

        

        (由于内容太多,所以加了grep)可以看到,里面的字符串很多都被找到。但是要注意的是:

    • 这些字符串可能是函数名称或者库名,也由可能是程序输出,绝不能仅仅根据这些字符串来断定程序的功能
    • 默认情况下,strings 仅仅扫描文件中可加载的、经初始化的部分,使用-a命令可强制strings扫描整个文件
    • strings不会指出字符串在文件中的位置,使用命令行-t可令strings显示所发现的每一个字符串的文件偏移量信息。(结合之后的步骤进行操作效果更佳)
    • 许多文件使用了其他字符集。使用命令行-e可使strings搜索更广泛的字符
  2. IDA PRO反汇编

  

  可以通过F12来查看图形化的流程说明,如下图:    

        

同时,也可以在IDA中打开包含strings的视图,可以查看原来的字符串,如下图所示:

  (.rdata段表示只读的数据,比如字符串文字量、常量和调试目录信息。)

 继续,来看一个函数

复制代码
.text:00401020 _verify_password proc near              ; CODE XREF: j__verify_passwordj.text:00401020.text:00401020 var_44          = byte ptr -44h       ;编译器自动生成的记号.text:00401020 var_4           = dword ptr -4.text:00401020 Str1            = dword ptr  8.text:00401020 .text:00401020                 push    ebp                  ;从这里开始压入原来的ebp(函数栈帧).text:00401021                 mov     ebp, esp        ;新的ebp=esp(栈顶).text:00401023                 sub     esp, 44h        ;开辟44个空间.text:00401026                 push    ebx.text:00401027                 push    esi.text:00401028                 push    edi          ;保留调用的函数的一些数据.text:00401029                 lea     edi, [ebp+var_44]    .text:0040102C                 mov     ecx, 11h.text:00401031                 mov     eax, 0CCCCCCCCh.text:00401036                 rep stosd.text:00401038                 push    offset Str2     ; "123456".text:0040103D                 mov     eax, [ebp+Str1].text:00401040                 push    eax             ; Str1.text:00401041                 call    _strcmp.text:00401046                 add     esp, 8.text:00401049                 mov     [ebp+var_4], eax.text:0040104C                 mov     eax, [ebp+var_4]        .text:0040104F                 pop     edi.text:00401050                 pop     esi.text:00401051                 pop     ebx.text:00401052                 add     esp, 44h.text:00401055                 cmp     ebp, esp.text:00401057                 call    __chkesp.text:0040105C                 mov     esp, ebp           ;恢复ebp.text:0040105E                 pop     ebp.text:0040105F                 retn
复制代码

这个结合前一篇关于栈的分析,可以很清楚的看出来程序的执行流程。push offset Str2 这句就是要比较的内容,因此可以选择去读取.rdata段中的数据来get密码。

继续看主函数,call之后的结果保存在了eax中,通过和0比较来判断是否是正确的密码。为了改变流程,可以将jz变成jnz。(jz->0x74,jnz->0x75)

.text:004010C6                 call    j__verify_password.text:004010CB                 add     esp, 4.text:004010CE                 mov     [ebp+var_4], eax.text:004010D1                 cmp     [ebp+var_4], 0.text:004010D5                 jz      short loc_4010E6

接下来,还涉及到虚拟内存地址(VA)和文件偏移地址的转换

  文件偏移地址=虚拟内存地址(VA)-转载基址(Image Base)-节偏移=0x004010D5-0x00400000-(0x00001000-0x00001000)=0x10D5     

                 

利用Winhex来修改74为75,就可以达到目的。结果如图所示:输入之前正确的密码,反而不行,其他字符一律通过

  

0 0
原创粉丝点击