题目链接:https://pan.baidu.com/s/1p3s_RpW_fO_CUWXriFGuAQ
提取码:4lvd
(提示:给出的这道题是我脱壳后的,因为没有及时保存原题,抱歉,不过是简单的UXP壳,大家直接用工具去脱也是可以的,所以相信大家没毛病)
这题是当时打南宁杯时的题目,拿到题目一起分析下:
1、首先用PEID查壳,发现是UXP壳,直接用工具脱壳,我的工具如下(这一步相信都没问题的):
2、脱完壳,拖进OD,看看情况:
要求输入flag
3、接着拖进ida看看,F5大法:
看的出来v3是输入,然后是29位的长度,最后一位是125(字符是“}”)修改化简下:
这是第一关
从逻辑上看可以知道,do里面的就是检验的过程,是简单的异或加密,就是把输入的字符的前八位与dword_40803里面的东西异或,和右边的比较,相同则v7加一,然后继续下一位,直到v7 = 8,就是说验证前8位都是正确的后,才进入下一层sub_401170(第二关),否则肯定是报错啦。
那么逻辑就是A^B=C,则C^B=A;我们要求input1,也就是要把dword_40803的东西与input[aMwwCTw-input]里面的东西进行异或才能得到input,下面去看看汇编:
先异或EBX和EBP结果存在EBX,再执行指令把数放到EBP中,比较EBX和EBP是否相等
这里无法直接看到,于是可以使用动态调试,地址是00401268,然后重点关注EBX和EBP寄存器的内容,运行OD:
分析逻辑,在00401253(循环开始的上方)在00401258和00401282这3个地方都下个断点
然后挂完断点跑程序,随便输入29位的字符,记住最后一位是},如下:
在XOR指令那里记录EBX寄存器的值,即dword_40803里面的东西,在CMP指令那里记录EBP寄存器的值,即右边的input[aMwwCTw-input]里面的东西
认准寄存器!提取出来后写个python脚本吧:
到这里第一关闯过去了,字符的前8位是gxnnctf{,卧槽,这不是南宁杯的flag格式吗,一口老血吐出来......不过学到的东西是自己的(强行安慰自己)
接着继续第二关:
do那里可以看到又是异或操作,是紧接着的后5位验证,所以直接110异或*v3就可以得到那5位了,v3是由v5得到的,猜测v5是数组,转一下:
也就是V5的每一位异或110得到那5位:
其实大家想说那是不是在动态调试时也可以看到?答案是肯定的!所以如果没有给出的话,加大难度,那我们就动态调试出来,这里啰嗦下:
看栈里面的东西,一个一个地调出来,再来个脚本:
答案是一样的,但是我们更熟悉查看栈内容的技巧啦
接下来继续闯关!
这里第一个do的分析有些复杂,由于while里面是小于9,所以是把接下来的9位字符串处理,处理得到的12位的字符串存到v11中,看第二个do比较了12次,于是再次动态调试:
汇编地址是00401127,下断点跑程序,每次循环记录EDX寄存器的内容,也是DL的内容,写个脚本跑出来
由经验可知,是base64加密,于是在线解码
第三关结束!(其实本轮算法是base64加密算法需要经验.........可能这里有些难)
最后再进入sub_401000(也是最后一关)
由前面的可以知道,总共破解了8+5+9=22位字符,总长度29位,所以这是对接下来的6位字符(因为最后一位是“}”)的操作,分析逻辑可以知道,看do里面的if,右边的内容减2就是左边的,所以得先知道右边是什么,看汇编,再次动态调试:
地址是00401036,关注寄存器EBX的内容,
写个python脚本:
整合下代码,最终的flag就是gxnnctf{Se1f-M0difying_c0de!},我们去提交下吧!
总结技巧经验:本题学习动态调试查看栈里面的内容,以及异或加密操作,经历过后,我们的动态调试能力有所提升,汇编语言也学习到了一些,对于学习逆向的帮助还是很大的,希望能对大家有用,我也在学习的过程中,一起加油吧!