【攻防世界】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













