【攻防世界】Reversing-x64Elf-100
收获
- 要能看出 v3 是一个二维字符数组,根据代码:
__int64 v3[4]; // [rsp+18h] [rbp-20h]
v3[0] = "Dufhbmf";
v3[1] = "pG`imos";
v3[2] = "ewUglpt";
要能读懂
*(v3[i % 3] + 2 * (i / 3))
表示的意思:
对于二维数组v3
来说,v3[]
实际代表的也是一个首地址:v3[][0]
的地址,所以2 * (i / 3)
其实是首地址的偏移,因此v3[i % 3] + 2 * (i / 3)
代表的是v3[][]
的地址,所以*(v3[i % 3] + 2 * (i / 3))
代表的是v3[][]
的值,即:字符串(字符数组)v3[]
中的一个字符在 Python 中,整数类型除法,如果除不断,结果会转化为浮点型,所以在 Python 中数组下标的
2 * (i / 3)
要写成2 * int (i / 3)
找准 flag 的表示,本题循环中用
*(i + a1)
代表 flag 中的每一个字符,直接根据条件表示出*(i + a1)
即可
思路
IDA 查看 main
输入的字符串 s 经过 sub_4006FD(s)
处理后若返回 0,则破解成功
查看 sub_4006FD(s)
输入的字符串 s 中的每一个字符经过 for 循环处理后,均必须满足 *(v3[i % 3] + 2 * (i / 3)) - *(i + a1) == 1
,否则返回1,破解失败
根据代码:
__int64 v3[4]; // [rsp+18h] [rbp-20h]
v3[0] = "Dufhbmf";
v3[1] = "pG\`imos";
v3[2] = "ewUglpt";
可以判断,v3 是一个二维数组【v3 是一个数组,而 v3 的每一个元素又都是一个字符串(char 数组)】
注意这里条件语句的写法:*(v3[i % 3] + 2 * (i / 3))
,* 是加在整体上的,所以 * 表示取 v3[i % 3] + 2 * (i / 3)
这个地址上的值,而 v3 是一个二维数组,所以 v3[i % 3]
代表的其实是一个首地址,即 v3[i % 3][0]
的地址,后面的 2 * (i / 3)
其实是一个偏移量,所以 *(v3[i % 3] + 2 * (i / 3))
指的是 v3[i % 3][2 * (i / 3)]
的值
a1 是输入的字符串 s 的首地址,每一轮循环中的 *(i + a1)
其实就是 s 中的每一个对应元素,因此求出每一轮 *(i + a1)
的值就是 s 中的每一个元素的值,而 v3 中的值并未发生修改,所以根据 *(v3[i % 3] + 2 * (i / 3)) - *(i + a1) == 1
的条件可得:*(i + a1) = *(v3[i % 3] + 2 * (i / 3)) - 1,即: *(i + a1) = v3[i % 3][2 * (i / 3)] - 1
脚本
C++
#include <iostream>
using namespace std;
int main(){
string v3[4];
v3[0] = "Dufhbmf";
v3[1] = "pG`imos";
v3[2] = "ewUglpt";
string flag = "";
for ( int i = 0; i <= 11; ++i )
{
flag += v3[i % 3][2*(i/3)] - 1;
}
cout<<flag;
return 0;
}
Python
checker = ["Dufhbmf", "pG`imos", "ewUglpt"]
flag = ""
for i in range(0, 12):
flag += chr(ord(checker[i % 3][2 * int(i/3)]) - 1)
print(flag)
结果
Code_Talkers