从零开始的程序逆向之路基础篇 第二章——用OllyDbg(OD)分析一个简单的软件

作者:Crazyman_Army

原文来自:https://bbs.ichunqiu.com/thread-43469-1-1.html

 

0x00知识回顾 (由于笔者省事,没开XP虚拟机,而且没关闭ASLR,所以每次重载的内存地址会不一样)

在第一章的内容中,笔者已经讲了OllyDbg(简称OD)的界面介绍以及基础的操作,普及了常用的汇编指令


上次课在底下的附件中,我留下了一个演示样例,大家载入OD后搜索到字符串点击跟踪到反汇编窗口的时候会发现与第一章所讲的程序的框架不太一样.

 

从零开始的程序逆向之路基础篇 第二章——用OllyDbg(OD)分析一个简单的软件_第1张图片


尤其可见多出了很多的call指令,call指令在汇编中就是调用子程序,下面放出代码,各位同学可以比对一下与上篇文件所贴出代码的不同

代码如下:

 

#include

#include    

#include

BOOL getProcess(const char *procressName);

BOOL getProcess(const char *procressName)

{

        char pName[MAX_PATH];                                

        strcpy(pName, procressName);                            

        CharLowerBuff(pName, MAX_PATH);                       

        PROCESSENTRY32 currentProcess;                       

        currentProcess.dwSize = sizeof(currentProcess);        

        HANDLE hProcess = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

        if (hProcess == INVALID_HANDLE_VALUE)

        {

                printf("CreateToolhelp32Snapshot()调用失败!\n");

                return FALSE;

        }

        _asm NOP;

        BOOL bMore = Process32First(hProcess, ¤tProcess);        

        while (bMore)

        {

                CharLowerBuff(currentProcess.szExeFile, MAX_PATH);        

                if (strcmp(currentProcess.szExeFile, pName) == 0)            

                {

                        CloseHandle(hProcess);                                

                        return TRUE;

                }

                bMore = Process32Next(hProcess, ¤tProcess);           

        }

        CloseHandle(hProcess);    

        return FALSE;

}

int main()

{

        char* process = "explorer.exe";

        if (getProcess(process))

        {

                printf("发现explorer.exe\n");

                system("pause");

                exit(0);

        }

        else

        {

                printf("没有发现explorer.exe\n");

                printf("Cracke Success!");

        }

        getchar();

        return 0;

}

 

从代码角度来看,很明显,这次笔者讲判断进程封装成一个返回布尔值的函数,所以才会在核心判断部分出现如此多的调用,那这当然不能像上次一样改一步简单的跳转就解决问题,如果改得不对就会造成程序的崩溃。

下面笔者通过三种方法来绕过这个检验explorer.exe进程的小程序

 

方法一:修改判断进程的变量名称


在只能搜索中,我们看到了explorer.exe这个进程的字符串,我们用鼠标选中后,双击,在反汇编窗口中跟随

 

从零开始的程序逆向之路基础篇 第二章——用OllyDbg(OD)分析一个简单的软件_第2张图片


反汇编窗口显示的如下:

 

从零开始的程序逆向之路基础篇 第二章——用OllyDbg(OD)分析一个简单的软件_第3张图片


用鼠标选中这条代码右键 -> 数据窗口中跟随–> 内存地址

 

从零开始的程序逆向之路基础篇 第二章——用OllyDbg(OD)分析一个简单的软件_第4张图片


数据窗口随之发生了变化,在数据窗口上选中一部分数据右键

 

从零开始的程序逆向之路基础篇 第二章——用OllyDbg(OD)分析一个简单的软件_第5张图片


右键 –> 复制到可执行文件

 

从零开始的程序逆向之路基础篇 第二章——用OllyDbg(OD)分析一个简单的软件_第6张图片


点击放大键放大该窗口

 

从零开始的程序逆向之路基础篇 第二章——用OllyDbg(OD)分析一个简单的软件_第7张图片

 


然后就可以胡乱修改explorer.exe这个字符串

 

从零开始的程序逆向之路基础篇 第二章——用OllyDbg(OD)分析一个简单的软件_第8张图片


笔者这里就随便修改了

 

从零开始的程序逆向之路基础篇 第二章——用OllyDbg(OD)分析一个简单的软件_第9张图片


修改如下:

 

从零开始的程序逆向之路基础篇 第二章——用OllyDbg(OD)分析一个简单的软件_第10张图片


在窗口上右键,保存文件

 

从零开始的程序逆向之路基础篇 第二章——用OllyDbg(OD)分析一个简单的软件_第11张图片


文件保存成功

 

从零开始的程序逆向之路基础篇 第二章——用OllyDbg(OD)分析一个简单的软件_第12张图片


点击运行

 

从零开始的程序逆向之路基础篇 第二章——用OllyDbg(OD)分析一个简单的软件_第13张图片


第一种方法破解成功

 

方法二:确认过眼神,你不是我们的人

 

回到判断的核心代码,这里面是jnz来进行进程的判断

那jnz 的全拼写是 jump not zero 那其的反义词即为 jump


Zero,即为jz 或者 je (jump equal),那这样原来的判断explorer.exe就改为了不判断explorer.exe,这样就绕过了检测进程.

 

从零开始的程序逆向之路基础篇 第二章——用OllyDbg(OD)分析一个简单的软件_第14张图片


下面我们来实际操作,用鼠标选中后

 


从零开始的程序逆向之路基础篇 第二章——用OllyDbg(OD)分析一个简单的软件_第15张图片


双击

 

从零开始的程序逆向之路基础篇 第二章——用OllyDbg(OD)分析一个简单的软件_第16张图片


将jnz short 00291158改为 jz short 00291158或者 je short 00291158,将使用nop填充勾掉

 

 


点击汇编

 

从零开始的程序逆向之路基础篇 第二章——用OllyDbg(OD)分析一个简单的软件_第17张图片


然后再保存文件,保存后运行

 

从零开始的程序逆向之路基础篇 第二章——用OllyDbg(OD)分析一个简单的软件_第18张图片


第二种破解方法成功

 

方法三:条件改强制

 

如下图,这个jnz short 00101158是如果zf=0时就会跳转


而jnz所在代码的地址为00101137,我们尝试让其无条件跳转到00101137下面一个地址,也就是00101139(下图红框锁标注的区域)

 

从零开始的程序逆向之路基础篇 第二章——用OllyDbg(OD)分析一个简单的软件_第19张图片


双击地址为00101137的那条代码,如下图所示 将jnz short 00101158改为jmp short 00101139,点击汇编

 

 

从零开始的程序逆向之路基础篇 第二章——用OllyDbg(OD)分析一个简单的软件_第20张图片


点击运行按钮

 

从零开始的程序逆向之路基础篇 第二章——用OllyDbg(OD)分析一个简单的软件_第21张图片


程序运行截图:

从零开始的程序逆向之路基础篇 第二章——用OllyDbg(OD)分析一个简单的软件_第22张图片


很显然破解成功了,那具体是怎么个原理呢,我们这里留个悬念,等用od能分析一个简单程序后,我们回过头来解释这个问题

 

00x01 用OllyDbg分析一个简单的程序

下面,笔者将带领同学去用OllyDbg来分析一个简单的程序


笔者为了方便写了一个简单的判断输入数字的程序,代码如下:

 

从零开始的程序逆向之路基础篇 第二章——用OllyDbg(OD)分析一个简单的软件_第23张图片


载入OD

 

从零开始的程序逆向之路基础篇 第二章——用OllyDbg(OD)分析一个简单的软件_第24张图片


反汇编窗口上右键中文搜搜引擎 -> 智能搜索

 

从零开始的程序逆向之路基础篇 第二章——用OllyDbg(OD)分析一个简单的软件_第25张图片


跟踪后的代码可以看到:

 

从零开始的程序逆向之路基础篇 第二章——用OllyDbg(OD)分析一个简单的软件_第26张图片


在有程序保护的情况下,你可能无法搜索到字符串,这里先不讨论,笔者将带领同学一步一步分析这个简单的程序


这里面push ebp movebp,esp push ecx可以简单的理解为源码中的int main()后的{   (这里为了方便于理解)

 

从零开始的程序逆向之路基础篇 第二章——用OllyDbg(OD)分析一个简单的软件_第27张图片


push Text.013E3E34,push的意思自然是压栈

这里就不得不要说说C语言中的printf


下面是printf的函数声明

int printf(const char *format, ...);


那在默认的情况下,printf函数应该有一个const char*型的参数,而这一行就是把“Please Input Flag Number:”这个字符串指针当成参数1,压入栈中

 

从零开始的程序逆向之路基础篇 第二章——用OllyDbg(OD)分析一个简单的软件_第28张图片


mov [local.1],0x0

那究竟这个[local.1]是何方神圣呢?


我们选中这段代码

 

image.png


右键 -> 分析 –> 从模块中删除分析

 

从零开始的程序逆向之路基础篇 第二章——用OllyDbg(OD)分析一个简单的软件_第29张图片


此时[local.1]就露出了他真面目[ebp-4]

第一章的时候我们讲到了,mov(move)数据传送指令

mov a,b 把b的值传给a

当然mov也可以对内存中的数据进行赋值

这里面 mov [ebp-4],0x0 就是把0赋值给内存中所设置的变量,其中[]操作符可以引用内存中的数据

类似于源码中

 

image.png

 

从零开始的程序逆向之路基础篇 第二章——用OllyDbg(OD)分析一个简单的软件_第30张图片

 

call指令就是调用,那就是调用printf函数输出”PleaseInput Flag Number”这个字符串指针

 

 

从零开始的程序逆向之路基础篇 第二章——用OllyDbg(OD)分析一个简单的软件_第31张图片


lea eax,dword ptrss:[ebp-0x4]

LEA指令是一个计算机指令,可以将有效地址传送到指定的的寄存器。


按道理来说就把变量1的地址传递给了eax寄存器

 

从零开始的程序逆向之路基础篇 第二章——用OllyDbg(OD)分析一个简单的软件_第32张图片


push eax

push Text.00EE3E50

现在的eax其实被传递了变量1的地址

往下面一瞥会发现scanf函数


下面是scanf函数的定义

int scanf(const char * restrict format,...);


一般代码中都是scanf(“格式说明符”,&变量地址)

这里面格式说明符是函数的参数1,变量地址是函数的参数2

而这个变量地址就类似于图中的push eax-> 参数2

而格式说明符就类似于图中的pushText.00EE3E50 ->参数1

那为何是先把参数2推入,再把参数1推入呢?

比如 int Text(a,b,c)这个函数Text参数为a,b,c

在Windows调用规定中

这个函数在汇编中会

Push c

Push b

Push a

Call Text函数的地址


在此你应该能发现参数啊a,b,c却被反向以c,b,a的顺序压入栈中,然后再callText函数的地址

 

从零开始的程序逆向之路基础篇 第二章——用OllyDbg(OD)分析一个简单的软件_第33张图片


Call指令当然就是调用scanf函数读取输入flag的值

 

从零开始的程序逆向之路基础篇 第二章——用OllyDbg(OD)分析一个简单的软件_第34张图片


Add esp,0xc

由于_cdcel调用约定,故需要进行堆栈平衡


cmp dword ptrss:[ebp-0x4],0x2F59

cmp是比较指令 而这里面比较的两个对象是变量1与0x2F9(12121)


故cmp指令可以影响标志寄存器

 

从零开始的程序逆向之路基础篇 第二章——用OllyDbg(OD)分析一个简单的软件_第35张图片


Jnz short Text.009E1036

Jnz跳转指令,由于前面的cmp指令

若变量1-12121=0         Z位=1    jnz不跳转


若变量1-12121!=0        Z位=0    jnz跳转到009E1036

 

从零开始的程序逆向之路基础篇 第二章——用OllyDbg(OD)分析一个简单的软件_第36张图片


那这个程序的大致流程就是输入变量1的数以后与12121做比较,如果两个数相等,Z位=1 ,jnz不跳转,输入Right!;如果两个数不相等,Z位=0,jnz跳转到009E1036上,输出Error!


然后剩下的代码分析和前面所讲的差不多,大家可以自己写一下注释

 

 

从零开始的程序逆向之路基础篇 第二章——用OllyDbg(OD)分析一个简单的软件_第37张图片


00x02总结

 

本篇我们介绍如何用OD来分析一个简单的程序,同学可以在事后自己用OD跑一下,这样会理解的更加深刻

下一章 如何用OD(OllyDbg)动态调试程序

 

点击“阅读原文”即可下载本次文章所用到的几个程序的例子哦~

你可能感兴趣的:(web安全)