jc021227 发表于 2022-2-26 21:14

学校寒假考核作业之入门级逆向

1.起因
这是学校的寒假作业,难度入门级,然而我也是菜鸟,所以看看到底谁更菜吧。分析过程很简单,大神请略过……
下载地址:https://wwe.lanzouy.com/iQm4H00mv4zi


2.查壳
破解好习惯先查壳,使用Die发现是无壳VC++程序。

3.静态分析
拖进IDA,查看伪代码,容易发现有反调试。输入为一个字符串和一个长整数,有三个判断条件。简单修改名称并添加注释,如图:

观察三个判断条件:
((int (__cdecl **)(int *))dword_404380)(&int1)
((int (__cdecl **)(char *))dword_404380)((char *)&int1 + 5)
((int (__cdecl **)(char *))dword_404380)((char *)&int1 + 9)
前面的括号里应该是一个数组,下标0,1,2的元素是三个函数,后面的括号是函数的参数。至于函数到底在哪里,因为我实在不太会用IDA,所以用OD进行动态调试。
4.动态调试
拖进OD开始分析,刚才已经看到有反调试,代码位置如图:

而起始位置是00401000,相减算出偏移量是0x45C。OD的起始位置是01081000,加上偏移量,前往0108145C处,将je改为jmp,即可跳过反调试。

再回头看IDA的流程图,发现函数地址就储存在eax。

用同样的方法找到这一行代码在OD中的地址,F2下断点,运行程序,在断点停下然后F7步入,找到函数位置01081080,偏移量为0x80。然后继续寻找另外两个函数的偏移量,分别是0x130和0x230。5.分析算法每个函数的位置都找到了,下一步就是逐个分析算法。
函数1
回到IDA,先看第一个函数,在00401080处。F5看伪代码,发现循环和字符串比较。

我选择逆向分析,这个函数结束后的跳转是jz,而且跳转未实现才能进入下一个判断,所以eax等于1,即函数返回1。再看函数的返回值,v2 == 0必须为真,即v2等于0。那么if (v2)会被跳过。再往前看,v2是字符串比较的结果,搜索一下strcmp这个函数,得知字符串相同返回0,因此a1="pvlg`"。从前面的循环可以发现,a1的长度为5,每一位都和下标i进行异或运算。根据异或运算的性质,a^b^a=b,所以把字符串"pvlg`"的每一位与下标进行异或运算的结果就是a1。计算出结果是"pwndd"。
函数2
继续分析第二个函数,还是从返回值入手,过程跟上一个一样,就知道了a1这个字符串经过循环处理的结果是"evoL"。

分析这个循环,i的取值是
a=a^b
b=a^b
a=a^b
相当于
b=a^b^b=a
a=a^b^a=b
也就是a和b的值互换,而不借助中间变量。其实我以前看到过这种方法,所以马上想到答案是"Love"。
函数3
来到00401230处,发现这个函数稍显复杂:

跟之前的思路一样,a1经过处理与"ZELDA"相同。分析这个循环,首先把int0向右移位,int0是什么?通过交叉引用,发现它就是输入的长整数。

第一次循环,v4=4,int0向右移动32位,也就是v2=int0/2^32;然后a1=v2;最后v2左移32位,相当于int0=int0-v2*2^32。这时注意到输入的字符串应该长度为5,但循环只有4次,也就得到了a1='A'。而循环中对字符串a1只有赋值操作,不依赖它原本的值,因此字符串的前4位可以是任意值,记作"????A"。所以我接下来的目的是找到长整数的值。继续逆向分析,从第四次循环开始,已知v2=(int)'D'=68,而每次循环v4自减,第四次循环时v4=1。那么68=int0/2^8,得出int0=17408。再依次分析第3,2,1次循环,最终得到int0=387709682688。其实可以写个循环来计算,不过次数很少,按计算器也方便。
总结
算法分析到这里就结束了。flag的字符串部分应该是"pwndd""Love""????A"(最后一个不唯一),而长整数就是387709682688。
6.未完待续
分析已经结束了,那么flag是不是"pwnddLoveZELDA 387709682688"呢?当然不是。因为每个函数都要求两个字符串完全相同,所以不能连在一起输入。如果分开输入,程序接受的第二个参数是长整型而不是字符串,也不能通过,于是陷入了两难的境地。但我觉得这就是正确答案,所以接下来用动态调试验证一下:
进入第一个函数,发现整个字符串都被传入了:

字符串比较不通过,但可以看到前5位是正确的:

为了继续验证,将此跳转改为nop,进入下一个函数:


可以看到字符串从第六位开始传入,依然是运行到比较处,发现前四位相同:

还是把下方的跳转改为nop,进入最后一个函数:

这时传入的字符串就满足条件了,因此只要我给出的长整数正确,那么第三个验证就能直接通过。F4直接来到验证处,查看结果:

完全正确!最后证明一下,返回之后的这个跳转我没有修改,可以直接来到成功提示:

程序运行效果如下:



最后
虽然无法直接运行程序得到成功提示,但通过最后的动态调试和分析,可以确定我的思路是正确的,对算法的分析也是正确的。尤其是第三个函数的验证能直接通过,有力证明了答案的正确性。现在我很好奇作者是如何用flag得到成功提示的,那实在太神奇了。感兴趣的小伙伴也可以动手尝试一下,看看能不能解决这个疑惑。

n92738 发表于 2022-2-26 21:49

学习了 学习

降龙18掌 发表于 2022-2-26 22:55


https://v.youku.com/v_show/id_XNTgwNzM5Nzg4NA==.html

wo452323123 发表于 2022-2-27 04:10

厉害了,膜拜学习

Fxhlt 发表于 2022-2-27 08:16

这作业可兴做呢

SuperGround 发表于 2022-2-27 09:03

节假日进行逆向学习,楼主看来是个热爱电脑的好学生呀,可别忘了寒假作业哦,哈哈哈

HardenL 发表于 2022-2-27 10:57

谢谢分享一起学习

allycn 发表于 2022-2-27 13:08

正在学习中,谢谢分享

zhengxinjun 发表于 2022-2-27 14:22

不明觉厉,顶一下

qrrc124 发表于 2022-2-27 15:54

学习了学习了学习了
页: [1] 2 3 4
查看完整版本: 学校寒假考核作业之入门级逆向