Replace
题目链接:https://pan.baidu.com/s/1kASjMHQYrQsHCYPEAIyk9w
提取码:f5j9
我们首先用IDA打开,发现没有多少东西,可以猜到是加了壳的。
使用Peid进行查壳,发现是UPX壳。
Upx壳比较简单,我们之间使用esp定律壳轻松找到OEP。
我们使用x32dbg来分析这个程序,x32dbg反编译功能,这样我们不必脱壳,在进行分析核心算法的时候够使用反编译功能即可得到伪代码。
等壳加载完后到了继续单步跟踪,即可找到程序的核心部分,可以看到成功与失败的字符串“Well Done”和“Your Wrong”。
我们对这片汇编代码进行反编译。
可以看出程序的功能是获取输入35个字符,然后再核心函数里对输入进行验证,若输入正确,则输出成功,若输入错误,则输出错误。
下面我们跟进核心函数进行分析,汇编代码比较复杂,我们仍使用x32dbg的反编译功能。
反汇编后
经分析我们可以看到有一个do-while循环来处理输入的35个字符,进行循环35次,每次处理一个字符。
循环中首先根据输入的一个字符进行运算得到两个值esi6和ed7
接着根据程序中的一个地址保存的数组(我们称为data数组)中的值生成eax8和ecx9
我们动态调试一下可得到data数组中的值。
然后就是进行比较,我们来看最后进行的比较
分析知道是比较的是,由edi7和esi6进行运算得到一个数当下标,然后在一个数组中(我们称为arr数组)进行查找,然后和ecx9与eax8进行运算的值比较。
也就是说,比较的两个值,一个是根据输入的字符生成下标,然后在arr数组中进行寻值,另一个值呢,是根据程序中的data数组生成的。
并且可以知道,data数组是固定的,所以等式右边比较的36个值都是固定的。我们在比较的地方设下动态断点,不必运算,通过调试即可得到右边的cmp2数组36个值。
得到
cmp2[35]={0x33,0x50,0xef,0x85,0x21,0x20,0x45,0xc7,0x8f,0xcf,0xc7,0x8f,0xcf,0xed,0xf9,0x3c,0x51,0x50,0x4d,0xcf,0x0,0x4d,0x51,0xc7,0xef,0xfb,0xc3,0xcf,0x6e,0x9f,0xfb,0x4,0x43,0xc3,0xff}
即cmp2数组的值都能在arr数组找到,只要满足输入的字符生成的下标正确即可。然后我们知道循环每次都处理一个字符,产生一个下标,有一个对应的arr数组的值,然后和cmp2数组进行比较。
所以我们选择输入常见的字符然后进行调试,在比较的地方设下断点,然后运行查看寄存器eax,(将下面比较不相等的跳转指令nop掉),就是这个字符在arr数组中对应的值,然后我们能够得到常见字符对应的arr数组中的值。
常见字符对应的arr数组中的值如下(为了节省时间不全部列出,列出比较值主要对应的):
0-0x4 1-0xc7 2-0x23 3-0xc3 4-0x18 5-0x96 6-0x5 7-0x9a 8-0x7 9-0x12
a-0xef b-0xaa c-0xfb d-0x43 e-0x4d f-0x33 g-0x85 h-0x45 i-0xf9 j-0x2
... l-0x50 m-0x3c n-0x9f ... p-0x51 ... s-0x8f ....
... R-0x0 T-0x20 S-0xed ... E-0x6E ... {-0x21 ... }-0xff ... _-0xcf ...
然后我们只要将cmp2数组的中的值进行匹配相应的字符即可。