拿到程序是一个MFC程序,使用IDA打开程序。搜索GetDlgItem使用crtl+x查看调用,发现了很多这个函数,查找输入错误信息得到的字符串error!,一瞬间有点迷茫,找不到关键入口。
使用工具xspy对button按钮进行检测,检测出id为03e9之后对整个MFC窗口进行检测
注意最后一行
OnCommand: notifycode=0000 id=03e9,func= 0x00A42420(Junk_Instruction.exe+ 0x002420 )
这里有id=03e9!!跟上面的按钮的id一样
也就是说,点击那个铵钮的时候,mfc 会跳到0xA42420处执行而IDA中在402420
使用OD调试在A42420处下断点向下运行几步,此时寄存器中出现输入字符的uncoide类型,在该内存处下内存断点
F9运行后删除,来到一处地方,发现是计算输入数据长度,继续向下走,运行至此处上方函数WideCharToMuliByte将输入的uncoide类型字符转换成ASCII码。此时新生成ASCII码的地方下内存断点。
F9运行,继续向下调试,晕了又是计算长度,再次按F9运行,来到此处,将字符串拷贝到一个地址处,拷贝完之后对其下内存访问断点,并且删除上个断点
F9运行,又到了计算长度,继续F9,又把地址给其他的地址,在该地址处下内存断点,且删除上一个内存访问断点
F9运行,又是计算长度,但这次有了比较,先将长度减去6再判断是否等于0x20,即输入长度等于38.
重新输入后38个字符后来到此处,继续对地址下内存访问断点,数据再次转移,再对转移的数据下内存访问断点,F9运行之后将数据删除,分析到此处借助IDA的静态分析,一步步向下分析。到了这一步原先被删除的字符又回来了,并且去除了前5个字符和最后一个字符再逆序放置,在新字符处下内存访问断点
继续运行结果又到了计算长度内容必然是0x20,再次F9,出现了异或运算,不同的值异或运算的值相同。记录一下这些异或运算的值。记录一下这些异或运算的值
3D E4 E5 16 AD EE 7D 49 5B 06 F9 26 A9 49 C8 CB
E9 44 53 D6 C4 84 EF 66 B3 FE 3B 38 AD E3 72 C3
异或运算结束出来后便进行了比较判断,比较也是从最后一个字符进行比较,dump出比较的字符串
5B D6 D0 26 C8 DD 19 7E 6E 3E CB 16 91 7D FF AF
DD 76 64 B0 F7 E5 89 57 82 9F 0C 00 9E D0 45 FA
最后写脚本解密
#include
#include
int main()
{
BYTE x[32] = { 0x3D, 0xE4, 0xE5, 0x16, 0xAD, 0xEE, 0x7D, 0x49, 0x5B, 0x06, 0xF9, 0x26, 0xA9, 0x49, 0xC8, 0xCB,
0xE9, 0x44, 0x53, 0xD6, 0xC4, 0x84, 0xEF, 0x66, 0xB3, 0xFE, 0x3B, 0x38, 0xAD, 0xE3, 0x72, 0xC3
};
BYTE result[32] = { 0x5B, 0xD6, 0xD0, 0x26, 0xC8, 0xDD, 0x19, 0x7E, 0x6E, 0x3E, 0xCB, 0x16, 0x91, 0x7D, 0xFF, 0xAF,
0xDD, 0x76, 0x64, 0xB0, 0xF7, 0xE5, 0x89, 0x57, 0x82, 0x9F, 0x0C, 0x00, 0x9E, 0xD0, 0x45, 0xFA
};
for (int i = 0; i < 32; i++)
{
result[i] ^= x[i];
}
for (int i = 31; i >= 0; i--)
{
printf("%c", result[i]);
}
system("pause");
}
输出结果973387a11fa3f724d74802857d3e052f最后包裹flag