新手一枚,如有错误(不足)请指正,谢谢!!
题目链接: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 <stdio.h>
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为<mark>flag{Y0uaretheB3st!#@_VirtualCC}</mark>