这道题小小花指令不咋难,但是代码的逆写让我止步了一会儿,64位程序,丢进ida64中
这边按tap键,进入汇编代码
可以看到在jump那一行出问题了,如下操作,打开栈选项
打开stack pointer 并将bytes设置为5
在回到汇编代码界面,选中那一行,右击如图操作,将第一位改为90
再ok即可,然后回到汇编代码界面,选中红色区域如图操作
这边选择force,然后再yes即可,最后选中这些代码按p生成函数,最后再选中这些代码,f5反编译即可得到如下代码
当然了,这道题的难点在于逆写代码,我是用爆破写的,首先我们理一下思路先,这是一个从0开始的循环,这边有一个重要的点,str[i]和str[(i*i+123)%21] 这边的i是和(i*i+123)%21 对应住的,什么意思呢,比如我现在i==0,那么str[0]就一直和str[(i*i+123)%21] 一起相加,然后再和96进行取模操作,简而言之,i定则(i*i+123)%21定,懂了这个之后,那就可以逆了,我先简化一下,
Str1[i] -32 = (Str1[i] + Str1[(i * i + 123) % 21]) % 96 ; 此时我的左侧是已知数,右边我们不懂%96的逆运算,那就爆破,代码如下
#include<iostream>
using namespace std;
int main()
{
char str[] = "~4G~M:=WV7iX,zlViGmu4?hJ0H-Q*";
char flag[30] = {0};
int i;
for ( i = 28; i >=0 ; i--)
{
str[i] -= 32;
for (int k = 32; k < 127; k++)
{
if ((k + str[(i * i + 123) % 21]) % 96 == str[i])
{
flag[i] = k;
str[i] = k;
break;
}
}
}
for (int l = 0; l < 29; l++)
{
printf("%c", flag[l]);
}
return 0;
}
这边有两个注意点,一个是for循环要逆过来写,还有一个就是要将已经爆破出来的数赋值给str[i],
因为他是一环套一环,前面的数会影响到后面的数,还有就是一个break,其他的没啥,取模一般
都是爆破,注意找里面的对应量,不变量