一、工具:
1、IDA(32位)
二、解题思路:
①、运行程序,发现窗口会出现一段字符串
我们在字符串窗口尝试找一下这串字符
双击定位到关键位置,双击选中这段字符串,交叉引用显示图表视图,会发现无法生成伪代码,那就分析汇编代码
②、
由mov al,[edx] 可知 al 保存着 edx 的值,inc edx 表示edx自增 1 ,cmp edx,1Bh 是 edx 的值与 1Bh(十进制:27) 进行比较,若 edx 的值大于 27 则执行 wrong 那一块的代码。反之,cl 与 al(edx) 的值异或再保存回 cl 中,最终得到:MSAWB~FXZ:J:`tQJ"N@ bpdd}8g
大致过程弄清楚就可以解密了
由于和同一个数异或两次等于没异或,所以只需要把最终的字符串的每个字符再和 1~27 一 一对应的异或一次就可以得到 flag
③、脚本编写:
#include
#include
int main()
{
char ch[] = {
'M',
'S',
'A',
'W',
'B',
'~',
'F',
'X',
'Z',
':',
'J',
':',
'`',
't',
'Q',
'J',
'"',
'N',
'@',
' ',
'b',
'p',
'd',
'd',
'}',
'8',
'g'
};
for(int i = 0;i < strlen(ch);i++)
{
ch[i] = ch[i] ^ i;
printf("%c",ch[i]);
}
return 0;
}
写代码出现的错误:我开始把空格给删掉了,还有 8 也没有加单引号,导致一直得不到正确的 flag ,所以写代码的时候,数字也要加上单引号;空格不能删除,用单引号把空格括起来。
结果:
MRCTF{@_R3@1ly_E2_R3verse!}
三、收获
db指令的作用:声明并初始化数据。声明数据的本质就是:在内存中占用一块空间 ;初始化数据的本质就是:给这个空间赋予一个值 。
举例:db 0,0,0,0,0
,在内存中占用了5个字节的空间,这5个字节的值都是0 。
INC是加一指令,就是自加一的一次每次触发进行加1操作。 对应的DEC是减一指令。 加1指令INC是将操作数 [D]的内容进行加1,运算结果仍存入 [D]中。 平时使用定时器设定值就要用INC加1指令或DEC减1指令来改变寄存器的常数。
对 edx 进行清零操作,两个相同的数异或结果为 0 ;两个不同的数异或结果为1;和mov edx,0 结果一样,不过 xor edx,edx 的效率更高一些。