新手一枚,如有错误(不足)请指正,谢谢!!
题目链接:BUUCTF-re-[SWPU2019]ReverseMe
题目下载:点击下载
OD内存断点
OD载入
右键→中文搜索引擎→智能搜索,找到“Please input your flag”,双击进入
在此函数的头部下断点,F9运行程序
F8单步,到输入call程序运行起来
随便输入flag,回车,程序暂停
这里进行了一个比较,将栈中ss:[ebp-0x90]的值与0x20也就是32进行比较。并改变标志位影响下面的je跳转,je跳转如果未实现的话,则走向了失败,如果要je跳转实现,则需要z标志位为1,z标志位如果为1,则cmp的运算结果需要为0,也就是[ebp-0x90]-0x20=0 ,也就是[ebp-0x90]需要等于0x20
而此时[ebp-0x90]的值为0xD也就是13恰好就是输入字符的个数。
因此可以知道输入字符个数为32
重新载入,输入32个字符
继续F8单步,来到这个循环,
每次从[SWPU_2019_CTF]取一位,与输入的字符串进行异或,,EDI寄存器做计数器。循环32次,
程序肯定还会对字符串进行其他处理,右键数据窗口跟随输入字符串的堆栈地址,下内存断点
先F4跳出此循环,然后下内存断点
运行程序,程序被断下来。
这里将数据转移到栈的另一位置,然后删除此内存断点,跟随到另一位置继续下内存断点查看进行了什么操作。
继续F9运行程序
这里将字符串与栈中[esi+eax]的值进行了异或
也就是这块数据
然后再在写入异或结果的栈[ebx+eax-0x4]下内存断点,F9运行程序
通过一个循环将eax的值与栈[edx]中的值进行比对,而eax的值来自于[ecx],数据窗口跟随,与这块数据进行比较
通过修改Z标志位可以使之运行到congratulations
分析好开始写脚本
最后比较的数据,与第二次异或的数据进行异或,再与第一次异或的数据进行异或,得到flag
#include
int main(void)
{
char str0[] = {0xB3,0x37,0x0F,0xF8,0xBC,0xBC,0xAE,0x5D,0xBA,0x5A,0x4D,0x86,0x44,0x97,0x62,0xD3,0x4F,0xBA,0x24,0x16,0x0B,0x9F,0x72,0x1A,0x65,0x68,0x6D,0x26,0xBA,0x6B,0xC8,0x67,0};
char str1[] = {0x86,0x0C,0x3E,0xCA,0x98,0xD7,0xAE,0x19,0xE2,0x77,0x6B,0xA6,0x6A,0xA1,0x77,0xB0,0x69,0x91,0x37,0x05,0x7A,0xF9,0x7B,0x30,0x43,0x5A,0x4B,0x10,0x86,0x7D,0xD4,0x28,0};
char str2[] = "SWPU_2019_CTF";
char flag[33] = {0};
int i;
for(i=0;i<32;i++)
flag[i] = str0[i]^str1[i]^str2[i%13];
puts(flag);
return 0;
}
最终flag为flag{Y0uaretheB3st!#@_VirtualCC}