【CTF-RE】[攻防世界]Reversing-x64Elf-100
直接拖到ida64里,再直接定位到主要函数里:
__int64 __fastcall check(__int64 a1)
{
int i; // [rsp+14h] [rbp-24h]
__int64 v3[4]; // [rsp+18h] [rbp-20h]
v3[0] = (__int64)"Dufhbmf";
v3[1] = (__int64)"pG`imos";
v3[2] = (__int64)"ewUglpt";
for ( i = 0; i <= 11; ++i )
{
if ( *(char *)(v3[i % 3] + 2 * (i / 3)) - *(char *)(i + a1) != 1 )
return 1LL;
}
return 0LL;
}
首先需要明白,在c语言中,char* 表示字符串,如char* string=“abc”
或char string[3]="abc";
char** 就是字符串数组,string[0]="abc"; sring[1]="cde";
而char string[0][0]='a'
代码里的v3就是一个字符串数组,v3[0][0]就是Dufhbmf里的第一个D。
*(char *)(v3[i % 3] + 2 * (i / 3)) - *(char *)(i + a1)
这行if里的意思是:
先看后面,a1是输入的字符串,如
char * a1 = ”abc"
,a1的地址即为a1[0],是第一个“a”;再加i就是第几个字符,如i=2时,a1[2]="c"。(这是计算地址的方式)v3这个字符串数组里的第
i%3
项中2 * (i / 3)
个(char)【起作用的是char *】上的内容【起作用的是开头的 *】,即v3[i%3][2(i/3)]
字符
两者相减(ASCII码计算)不为1时退出,在主函数报错。
所以用暴力求得a1:
import string
v3 = ["Dufhbmf", "pG`imos", "ewUglpt"]
res = string.ascii_letters+string.digits+string.punctuation
print(res)
flag = ""
for i in range(0, 12):
for j in res:
if ord(v3[i % 3][2 * (i // 3)]) - ord(j) == 1:
flag += j
break
elif j == "~":
print("!")
print(len(flag))
print(flag)
得到flag为Code_Talkers
或直接反向推出flag:
v3 = ["Dufhbmf", "pG`imos", "ewUglpt"]
flag = []
for i in range(12):
# 选择字符串和字符位置
s = v3[i % 3] # i%3 → 0,1,2 循环
idx = 2 * (i // 3) # 偏移量 0,0,0,2,2,2,4,4,4,6,6,6
target_char = s[idx] # 取目标字符
# 计算输入字符(ASCII 码减 1)
input_char = chr(ord(target_char) - 1)
flag.append(input_char)
print(''.join(flag)) # 输出:Code_Talkers