int __fastcall main(int argc, const char **argv, const char **envp)
{
_QWORD *v4; // rcx
__int64 v5; // rdx
__int64 v6; // rdx
_QWORD *v7; // rcx
__int64 v8; // rdx
__int64 v9; // rdx
_QWORD *v10; // rcx
__int64 v11; // rdx
__int64 v12; // rdx
int v13; // eax
int i; // [rsp+0h] [rbp-30A0h]
int v15; // [rsp+4h] [rbp-309Ch]
int j; // [rsp+8h] [rbp-3098h]
int k; // [rsp+Ch] [rbp-3094h]
int v18; // [rsp+10h] [rbp-3090h]
int m; // [rsp+14h] [rbp-308Ch]
int v20; // [rsp+18h] [rbp-3088h]
int ii; // [rsp+1Ch] [rbp-3084h]
int c; // [rsp+20h] [rbp-3080h]
int v23; // [rsp+24h] [rbp-307Ch]
size_t v24; // [rsp+28h] [rbp-3078h] BYREF
size_t n; // [rsp+30h] [rbp-3070h] BYREF
size_t v26; // [rsp+38h] [rbp-3068h] BYREF
size_t v27; // [rsp+40h] [rbp-3060h] BYREF
size_t v28; // [rsp+48h] [rbp-3058h] BYREF
FILE *stream; // [rsp+50h] [rbp-3050h]
FILE *v30; // [rsp+58h] [rbp-3048h]
__int64 v31; // [rsp+60h] [rbp-3040h]
size_t v32; // [rsp+68h] [rbp-3038h]
size_t v33; // [rsp+70h] [rbp-3030h]
size_t v34; // [rsp+78h] [rbp-3028h]
__int64 v35; // [rsp+80h] [rbp-3020h] BYREF
__int64 v36; // [rsp+88h] [rbp-3018h]
__int64 v37; // [rsp+90h] [rbp-3010h]
__int64 v38; // [rsp+98h] [rbp-3008h] BYREF
__int64 s1; // [rsp+A0h] [rbp-3000h] BYREF
__int64 v40; // [rsp+A8h] [rbp-2FF8h]
__int64 v41; // [rsp+B0h] [rbp-2FF0h]
__int64 v42; // [rsp+B8h] [rbp-2FE8h] BYREF
__int64 s2; // [rsp+C0h] [rbp-2FE0h] BYREF
__int64 v44; // [rsp+C8h] [rbp-2FD8h]
__int64 v45; // [rsp+D0h] [rbp-2FD0h]
__int64 v46; // [rsp+D8h] [rbp-2FC8h] BYREF
_QWORD v47[4]; // [rsp+E0h] [rbp-2FC0h] BYREF
__int64 v48; // [rsp+100h] [rbp-2FA0h] BYREF
__int64 v49; // [rsp+108h] [rbp-2F98h]
__int64 v50; // [rsp+110h] [rbp-2F90h]
__int64 v51; // [rsp+118h] [rbp-2F88h]
_BYTE v52[1008]; // [rsp+120h] [rbp-2F80h] BYREF
_BYTE src[1008]; // [rsp+510h] [rbp-2B90h] BYREF
_BYTE v54[1008]; // [rsp+900h] [rbp-27A0h] BYREF
char v55[944]; // [rsp+CF0h] [rbp-23B0h] BYREF
char s[2016]; // [rsp+10E0h] [rbp-1FC0h] BYREF
_BYTE dest[2016]; // [rsp+18C0h] [rbp-17E0h] BYREF
_BYTE v58[2032]; // [rsp+20B0h] [rbp-FF0h] BYREF
_BYTE v59[2040]; // [rsp+28A0h] [rbp-800h] BYREF
unsigned __int64 v60; // [rsp+3098h] [rbp-8h]
v60 = __readfsqword(0x28u);
setvbuf(_bss_start, 0LL, 2, 0LL);
setvbuf(stdout, 0LL, 2, 0LL);
setvbuf(stderr, 0LL, 2, 0LL);
printf("Initial data: ");
if ( !fgets(s, 2002, _bss_start) )
{
fwrite("Invalid input\n", 1uLL, 0xEuLL, stderr);
return 1;
}
trim_newline(s);
if ( (unsigned int)hex_to_bin(s, (__int64)v52, &v24) )
goto LABEL_47;
SHA256(v52, v24, &v35);
s1 = v35;
v40 = v36;
v41 = v37;
v42 = v38;
s2 = v35;
v44 = v36;
v45 = v37;
v46 = v38;
for ( i = 0; i <= 99; ++i )
{
printf("Round %d\n", i + 1);
printf("Salt 1: ");
if ( !fgets(s, 2002, _bss_start) )
goto LABEL_47;
trim_newline(s);
if ( (unsigned int)hex_to_bin(s, (__int64)src, &n) )
goto LABEL_47;
printf("Salt 2: ");
if ( !fgets(s, 2002, _bss_start) )
goto LABEL_47;
trim_newline(s);
if ( (unsigned int)hex_to_bin(s, (__int64)v54, &v26) )
goto LABEL_47;
printf("Salt 3: ");
if ( !fgets(s, 2002, _bss_start) )
goto LABEL_47;
trim_newline(s);
if ( (unsigned int)hex_to_bin(s, (__int64)v55, &v27) )
goto LABEL_47;
printf("Salt 4: ");
if ( !fgets(s, 2002, _bss_start) )
goto LABEL_47;
trim_newline(s);
if ( (unsigned int)hex_to_bin(s, (__int64)v59, &v28) )
goto LABEL_47;
if ( n != v27 || v26 != v28 )
{
fwrite("Length should be equal\n", 1uLL, 0x17uLL, stderr);
return 1;
}
v33 = n + v26 + 32;
memcpy(dest, src, n);
v4 = &dest[n];
v5 = v40;
*v4 = s1;
v4[1] = v5;
v6 = v42;
v4[2] = v41;
v4[3] = v6;
memcpy(&dest[n + 32], v54, v26);
SHA256(dest, v33, &s1);
v34 = v27 + v28 + 32;
memcpy(v58, v55, v27);
v7 = &v58[v27];
v8 = v44;
*v7 = s2;
v7[1] = v8;
v9 = v46;
v7[2] = v45;
v7[3] = v9;
memcpy(&v58[v27 + 32], v59, v28);
SHA256(v58, v34, &s2);
if ( !memcmp(&s1, &s2, 0x20uLL) )
{
fwrite("Hash should be different\n", 1uLL, 0x19uLL, stderr);
return 1;
}
}
if ( memcmp(&v42, &v46, 8uLL) || memcmp(&v42, &v38, 8uLL) )
{
puts("Wrong answer");
return 1;
}
stream = fopen("flag2", "r");
if ( !stream )
goto LABEL_27;
while ( 1 )
{
c = fgetc(stream);
if ( c == -1 )
break;
putchar(c);
}
fclose(stream);
printf("Magic data: ");
if ( !fgets(s, 2002, _bss_start) || (trim_newline(s), (unsigned int)hex_to_bin(s, (__int64)src, &n)) )
{
LABEL_47:
fwrite("Invalid input\n", 1uLL, 0xEuLL, stderr);
return 1;
}
SHA256(src, n, v47);
v15 = 0;
for ( j = 0; j <= 99; ++j )
{
printf("How many rounds for path %d: ", j + 1);
if ( !fgets(s, 2002, _bss_start) )
goto LABEL_47;
trim_newline(s);
v31 = strtol(s, (char **)&v26, 10);
if ( *(_BYTE *)v26 || v31 <= 0 || v31 > 100 )
{
fwrite("Invalid number of rounds\n", 1uLL, 0x19uLL, stderr);
return 1;
}
v48 = v47[0];
v49 = v47[1];
v50 = v47[2];
v51 = v47[3];
dword_1370500 = v31;
for ( k = 0; v31 > k; ++k )
{
printf("Round %d\n", k + 1);
printf("Salt 1: ");
if ( !fgets(s, 2002, _bss_start) )
goto LABEL_47;
trim_newline(s);
if ( (unsigned int)hex_to_bin(s, (__int64)v54, &v27) )
goto LABEL_47;
printf("Salt 2: ");
if ( !fgets(s, 2002, _bss_start) )
goto LABEL_47;
trim_newline(s);
if ( (unsigned int)hex_to_bin(s, (__int64)v55, &v28) )
goto LABEL_47;
memcpy((char *)&path + 2016 * k, v54, v27);
*((_QWORD *)&unk_133F568 + 252 * k) = v27;
memcpy((char *)&path + 2016 * k + 1008, v55, v28);
qword_133F958[252 * k] = v28;
v32 = v27 + v28 + 32;
memcpy(v59, v54, v27);
v10 = &v59[v27];
v11 = v49;
*v10 = v48;
v10[1] = v11;
v12 = v51;
v10[2] = v50;
v10[3] = v12;
memcpy(&v59[v27 + 32], v55, v28);
SHA256(v59, v32, &v48);
}
if ( memcmp(&v48, &v35, 0x20uLL) )
{
fwrite("Hash does not match\n", 1uLL, 0x14uLL, stderr);
return 1;
}
v18 = 0;
for ( m = 0; m < v15; ++m )
{
if ( dword_363E0[50402 * m] == dword_1370500 )
{
v20 = 1;
for ( ii = 0; ii < dword_1370500; ++ii )
{
if ( *((_QWORD *)&unk_5448 + 25201 * m + 252 * ii) != *((_QWORD *)&unk_133F568 + 252 * ii)
|| memcmp(
(char *)&paths + 201608 * m + 2016 * ii,
(char *)&path + 2016 * ii,
*((_QWORD *)&unk_133F568 + 252 * ii))
|| *((_QWORD *)&unk_5838 + 25201 * m + 252 * ii) != qword_133F958[252 * ii]
|| memcmp(
(char *)&paths + 201608 * m + 2016 * ii + 1008,
(char *)&path + 2016 * ii + 1008,
qword_133F958[252 * ii]) )
{
v20 = 0;
break;
}
}
if ( v20 )
{
v18 = 1;
break;
}
}
}
if ( v18 )
{
fwrite("Duplicate path\n", 1uLL, 0xFuLL, stderr);
return 1;
}
v13 = v15++;
memcpy((char *)&paths + 201608 * v13, &path, (size_t)&unk_31388);
}
v30 = fopen("flag3", "r");
if ( !v30 )
{
LABEL_27:
fwrite("Can't open file\n", 1uLL, 0x10uLL, stderr);
return 1;
}
while ( 1 )
{
v23 = fgetc(v30);
if ( v23 == -1 )
break;
putchar(v23);
}
fclose(v30);
return 0;
}
请把这段反编译得到的程序写成等价的 Python 代码
Below is the equivalent Python code for the decompiled C program:
import sys
import hashlib
def hex_to_bin(s):
try:
data = bytes.fromhex(s)
return data
except ValueError:
return None
def read_salt(n):
print("Salt %d: " % n, end='')
s = sys.stdin.readline()
if not s:
print("Invalid input", file=sys.stderr)
exit(1)
s = s.strip('\n')
data = hex_to_bin(s)
if data is None:
print("Invalid input", file=sys.stderr)
exit(1)
return data
def main():
# Initial data
print("Initial data: ", end='')
s = sys.stdin.readline()
if not s:
print("Invalid input", file=sys.stderr)
return 1
s = s.strip('\n')
data = hex_to_bin(s)
if data is None:
print("Invalid input", file=sys.stderr)
return 1
hash1 = hashlib.sha256(data).digest()
hash_s1 = hash1
hash_s2 = hash1
# First loop of 100 rounds
for i in range(100):
print("Round %d" % (i+1))
Salt1 = read_salt(1)
Salt2 = read_salt(2)
Salt3 = read_salt(3)
Salt4 = read_salt(4)
if len(Salt1) != len(Salt3) or len(Salt2) != len(Salt4):
print("Length should be equal", file=sys.stderr)
return 1
data1 = Salt1 + hash_s1 + Salt2
hash_s1 = hashlib.sha256(data1).digest()
data2 = Salt3 + hash_s2 + Salt4
hash_s2 = hashlib.sha256(data2).digest()
if hash_s1 == hash_s2:
print("Hash should be different", file=sys.stderr)
return 1
# After 100 rounds, check the last 8 bytes
if hash_s1[24:32] != hash_s2[24:32] or hash_s1[24:32] != hash1[24:32]:
print("Wrong answer")
return 1
# Open and print 'flag2'
try:
with open('flag2', 'r') as f:
for line in f:
print(line, end='')
except FileNotFoundError:
print("Can't open file", file=sys.stderr)
return 1
# Magic data
print("Magic data: ", end='')
s = sys.stdin.readline()
if not s:
print("Invalid input", file=sys.stderr)
return 1
s = s.strip('\n')
data = hex_to_bin(s)
if data is None:
print("Invalid input", file=sys.stderr)
return 1
temp_hash = hashlib.sha256(data).digest()
paths = []
# Second loop of 100 paths
for j in range(100):
print("How many rounds for path %d: " % (j+1), end='')
s = sys.stdin.readline()
if not s:
print("Invalid input", file=sys.stderr)
return 1
s = s.strip('\n')
try:
num_rounds = int(s)
if num_rounds <= 0 or num_rounds > 100:
raise ValueError
except ValueError:
print("Invalid number of rounds", file=sys.stderr)
return 1
path_salts = []
temp_temp_hash = temp_hash
for k in range(num_rounds):
print("Round %d" % (k+1))
Salt1 = read_salt(1)
Salt2 = read_salt(2)
path_salts.append( (Salt1, Salt2) )
data = Salt1 + temp_temp_hash + Salt2
temp_temp_hash = hashlib.sha256(data).digest()
if temp_temp_hash != hash1:
print("Hash does not match", file=sys.stderr)
return 1
# Check for duplicates
duplicate = False
for previous_path in paths:
if len(previous_path) != len(path_salts):
continue
is_same = True
for (prev_salt1, prev_salt2), (salt1, salt2) in zip(previous_path, path_salts):
if prev_salt1 != salt1 or prev_salt2 != salt2:
is_same = False
break
if is_same:
duplicate = True
break
if duplicate:
print("Duplicate path", file=sys.stderr)
return 1
paths.append(path_salts)
# Open and print 'flag3'
try:
with open('flag3', 'r') as f:
for line in f:
print(line, end='')
except FileNotFoundError:
print("Can't open file", file=sys.stderr)
return 1
if __name__ == '__main__':
main()
This Python script performs the same operations as the provided C code. Here's a brief explanation:
- It reads an initial hex-encoded input and computes its SHA256 hash.
- It then goes through 100 rounds where it reads four salts per round, performs checks, and updates the hash values.
- After the rounds, it checks certain conditions on the hashes.
- It opens and prints the contents of
flag2
. - It reads a magic data input, computes its hash, and then processes 100 paths. Each path consists of multiple rounds where salts are read and hashes are computed.
- It checks for duplicate paths and hash mismatches.
- Finally, it opens and prints the contents of
flag3
.
Please ensure you have the flag2
and flag3
files in the same directory as the script for it to work correctly.
请写得尽可能简洁,错误处理可以直接忽略,写成 assert 即可。
以下是简化后的 Python 代码:
import sys
import hashlib
def hex_to_bin(s):
return bytes.fromhex(s.strip())
def read_input(prompt):
print(prompt, end='')
return sys.stdin.readline().strip()
def read_salt(n):
s = read_input(f"Salt {n}: ")
return hex_to_bin(s)
def main():
# 初始数据
s = read_input("Initial data: ")
data = hex_to_bin(s)
hash1 = hashlib.sha256(data).digest()
hash_s1 = hash_s2 = hash1
# 第一部分,100轮迭代
for i in range(100):
print(f"Round {i+1}")
Salt1 = read_salt(1)
Salt2 = read_salt(2)
Salt3 = read_salt(3)
Salt4 = read_salt(4)
assert len(Salt1) == len(Salt3) and len(Salt2) == len(Salt4), "Length should be equal"
data1 = Salt1 + hash_s1 + Salt2
hash_s1 = hashlib.sha256(data1).digest()
data2 = Salt3 + hash_s2 + Salt4
hash_s2 = hashlib.sha256(data2).digest()
assert hash_s1 != hash_s2, "Hash should be different"
# 检查最后的8字节
assert hash_s1[-8:] == hash_s2[-8:] == hash1[-8:], "Wrong answer"
# 输出 flag2 文件内容
with open('flag2', 'r') as f:
print(f.read(), end='')
# Magic data
s = read_input("Magic data: ")
data = hex_to_bin(s)
temp_hash = hashlib.sha256(data).digest()
paths = []
# 第二部分,100个路径
for j in range(100):
num_rounds = int(read_input(f"How many rounds for path {j+1}: "))
assert 0 < num_rounds <= 100, "Invalid number of rounds"
path_salts = []
temp_temp_hash = temp_hash
for k in range(num_rounds):
print(f"Round {k+1}")
Salt1 = read_salt(1)
Salt2 = read_salt(2)
path_salts.append( (Salt1, Salt2) )
data = Salt1 + temp_temp_hash + Salt2
temp_temp_hash = hashlib.sha256(data).digest()
assert temp_temp_hash == hash1, "Hash does not match"
assert path_salts not in paths, "Duplicate path"
paths.append(path_salts)
# 输出 flag3 文件内容
with open('flag3', 'r') as f:
print(f.read(), end='')
if __name__ == '__main__':
main()
这个简化的 Python 脚本按照以下步骤执行:
- 从标准输入读取初始数据,转换为二进制,并计算其 SHA256 哈希值,得到
hash1
。 - 初始化
hash_s1
和hash_s2
为hash1
。 - 进行第一部分的 100 轮迭代,每轮:
- 读取 4 个盐值(Salt 1 到 Salt 4),并转换为二进制。
- 确保
Salt1
与Salt3
的长度相等,Salt2
与Salt4
的长度相等。 - 使用
Salt1
、hash_s1
、Salt2
计算新的hash_s1
。 - 使用
Salt3
、hash_s2
、Salt4
计算新的hash_s2
。 - 确保新的
hash_s1
与hash_s2
不相等。
- 在完成第一部分后,检查
hash_s1
、hash_s2
、hash1
的最后 8 个字节是否相等。 - 打开并输出名为
flag2
的文件内容。 - 读取 Magic data,计算其 SHA256 哈希值,得到
temp_hash
。 - 进行第二部分的 100 条路径处理,每条路径:
- 读取该路径的轮数
num_rounds
。 - 进行
num_rounds
轮迭代,每轮:- 读取 2 个盐值(Salt 1 和 Salt 2),并转换为二进制。
- 使用
Salt1
、temp_temp_hash
、Salt2
计算新的temp_temp_hash
。
- 确保最终的
temp_temp_hash
与hash1
相等。 - 确保路径不重复。
- 读取该路径的轮数
- 打开并输出名为
flag3
的文件内容。
注意:
- 所有的错误处理都使用
assert
,以简化代码。 - 输入和输出均通过标准输入/输出完成。
- 请确保在运行脚本的目录下存在
flag2
和flag3
文件。
希望这段代码能够满足您的需求。