逆向入门--第一次的HelloWorld

xiaoxiao2021-02-28  67

终于算是慢慢的爬入了逆向的大门,梦想虽远,坚持就好

记第一次简单的逆向过程

首先贴出CrackMe的源码,很简单的一个if而已

#include <stdio.h> #inclued <stdlib.h> int main(int argc, char **argv) { char passWord[8] = {"pass"}; char word[8] ; gets(word); if(strncmp(passWord, word, 8) == 0) { printf("authorized !\n"); } return 0; }

代码很简单,输对了就打印 (当然这个还存在缓冲区溢出,这个后面讲)

开始Crack

因为我们的EXE文件是标准的PE( Portable Executable ) 所以我们使用IDA(静态分析调试工具)对文件进行查看 IDA 相当与我们的地图一样的作用

这个就是我们的IDA 加载之后的程序 ,当然是汇编,的形式 第一行可以看到,是main的入口

很多人都是认为程序是从main函数开始 的,其实不然,程序真正的入口我们称之为OEP(original entry point)

然后我们向下读代码, 30 地址之前的就是我们的变量地址分配,

ebp,exp也就是我们常提起的bp 和 sp 的extend版本 31到36是我们的栈初始化

30 基址压栈31 基址赋值33 对栈指针做掩码??(没弄懂这个作用)36 对栈顶指针做减法,即分配栈空间 20*16 个字节39 call _main (这里才是真正的进入了main函数中去)

39往后main里

3E 就是变量赋值 可以看到 str1的值是 -8h (这里就很好解释了栈地址是如何向低地址增长的),后面的字符串当时我还没反应过来,其实是端序的问题,在Win里 都是大端格式,所以向下增长 的时候字符串要反过来46 这里就是对字符串后面添加 \0 作为结束符4E ~52 原理同上分配buffer(IDA已经自动注释,美哉)55 就是调用我们的gets函数5A~6E 就是strncmp的参数配置,str1 str2 maxcount这三个71 调用strncmp函数

76 这个比较重要 这里的显然是不改变eax的值的,那么他的作用是什么呢? 就是设置flag寄存器的状态

test 的作用不同于 cmp ,cmp 相当于算数相减,而test 是逻辑相与

所以这里只有eax为0h的时候 才会出现 设置Z位为1

78这里就是我们核心的一句! jnz就是不为零就调转,而下面就是我们的puts 得到的函数,所以要想成功破解,这里的就必须不能跳转!7A 字符串压栈,81 打印86~8B 就是我们的return 0了

eax 默认的就是传递的第一个参数

到此程序的静态解读告一段落
下面就是我们使用ollydbg进行动态调试,或者直接使用UE对pe文件进行修改(直接改jnz的汇编码即可) Ollydbg: ![这里写图片描述](https://img-blog.csdn.net/20170901001708367?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveno3MDkxOTY0ODQ=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast) (2333 ollydbg 看着还是挺帅的) 这里的地址,可以在ida里面找到; 下面就是修改那个jnz了,反正什么都行 jz 刚好相反nop 啥都不动向下执行

那就Nop吧 随便改一改

可见我们的authorized已经打印出来了


本次简单逆向也是告一段落了

附加

下面附件一点:

* 缓冲区溢出问题* 因为上面刚刚好有汇编的代码,这样解释起来就是变得简单了 可以看到,栈的空间分配是连续的,所以我的缓冲区给的大小是8 那么这样的话,他地址会基于栈地址来减去八个字节,然而,gets() 函数是不会判断缓冲区大小的,所以会把我们的输入直接写到地址。


所以,漏洞就产生了, str1,str2 是地址连续的两个8字节的空间,那么我们只要输入一个16字节对称的字符串,就可以完美绕过!

效果如上!

写在最后的话

送给大家一句话吧: 鸿鹄志高而难酬,终而还是妥协泯然众人 “”小镇青年何必远方?“” 于是我走出了这个熟悉的地方

转载请注明原文地址: https://www.6miu.com/read-60799.html

最新回复(0)