2025tx游戏安全PC初赛
Table of Contents
前期分析 #
拖进ida发现会对加载sys文件并运行,sys驱动里面有反调一直监控,所以ida attach上去 会自动退出
把加载驱动的部分全部patch掉可以直接attach上去
Attach上去后又有一个线程触发反调试,我们把它手动挂起不管直接看main进程都有啥
在sub_1400020D0之前不涉及flag直接不管 sub_1400020D0里面是一个变表base58
调进去找到base58的表
然后是一个异或
再到到check处进入vtable的方法
看到FilterSendMessage的v12变量里面装的是一个154004操作码+长度+一串数组
然后对sys展开逆向 一上来发现一个很多异或的函数,交叉引用回溯到父函数发现很多花,去花得到函数原型
处理后的flag传入了tea加密,tea加密去花发现密文位置,密文长度42 但解密发现明文并不是0-256范围内的数,盲猜要么密文被hook要么tea被hook 通过查看tea引用进入一个加了花的函数000000014000A35B 去花后发现对tea进行的写入
观察tea函数0x56偏移刚好和140004001处汇编对得上
调驱动看看效果
kuku一顿配环境终于把VirtualKD驸上去了
查看驱动加载地址对一下入口的汇编对不对
打断点发现tea处的代码果然变了,跳过去可以看到xxtea的加密
所以总的是一个tea+xxtea的轻度魔改
脚本 #
def tea_decrypt_deepseek(encrypted_data, key):
v7, v9 = encrypted_data
k0, k1, k2, k3 = key
sum_val = (-0x61C88647 * 32) & 0xFFFFFFFF # 初始sum为加密后的sum值
for _ in range(32):
# 处理v9的恢复
term1 = (sum_val + v7) & 0xFFFFFFFF
# 计算16*v7,使用左移4位,并确保32位无符号
term2 = (k2 + ((v7 << 4) & 0xFFFFFFFF)) & 0xFFFFFFFF
# 计算v7 >> 5(无符号右移)
term3 = (k3 + ((v7 & 0xFFFFFFFF) >> 5)) & 0xFFFFFFFF
combined = (term1 ^ term2 ^ term3) & 0xFFFFFFFF
v9 = (v9 - combined) & 0xFFFFFFFF
# 处理v7的恢复
term1_v7 = (sum_val + v9) & 0xFFFFFFFF
term2_v7 = (k0 + ((v9 << 4) & 0xFFFFFFFF)) & 0xFFFFFFFF
term3_v7 = (k1 + ((v9 & 0xFFFFFFFF) >> 5)) & 0xFFFFFFFF
combined_v7 = (term1_v7 ^ term2_v7 ^ term3_v7) & 0xFFFFFFFF
v7 = (v7 - combined_v7) & 0xFFFFFFFF
# 更新sum_val,恢复到上一轮的值
sum_val = (sum_val + 0x61C88647) & 0xFFFFFFFF
return (v7, v9)
def tea_decrypt(v0, v1, key):
"""
TEA解密函数
:param v0: 密文的左32位 (unsigned int)
:param v1: 密文的右32位 (unsigned int)
:param key: 128位密钥,包含4个32位整数 [k0, k1, k2, k3]
:return: 解密后的两个32位整数元组
"""
delta = 0x61C88647
sum_val = (-delta * 32) & 0xFFFFFFFF
k0, k1, k2, k3 = key
for _ in range(32):
v1 = (v1 - ((sum_val + v0) ^ ((v0 << 4) + k2) ^ ((v0 >> 5) + k3)) & 0xFFFFFFFF)
v0 = (v0 - ((sum_val + v1) ^ ((v1 << 4) + k0) ^ ((v1 >> 5) + k1)) & 0xFFFFFFFF)
sum_val = (sum_val + delta) & 0xFFFFFFFF
return (v0, v1)
def tea_decrypt_XXXTEA(v0, v1, key):
delta = 0x61C88647
sum_val = (-delta * 32) & 0xFFFFFFFF
k0, k1, k2, k3 = key
for _ in range(32):
# 逆向处理v1的更新
u_v0 = v0 & 0xFFFFFFFF
term1 = (u_v0 << 4) & 0xFFFFFFFF
term2 = (u_v0 >> 5) # 无符号右移
combined = ((term1 ^ term2) + u_v0) & 0xFFFFFFFF
key_index = (sum_val >> 11) & 3
key_part = key[key_index]
key_sum = (key_part + sum_val) & 0xFFFFFFFF
increment_v1 = (combined ^ key_sum) & 0xFFFFFFFF
v1 = (v1 - increment_v1) & 0xFFFFFFFF
# 逆向处理v0的更新
u_v1 = v1 & 0xFFFFFFFF
sum_v1 = (sum_val + u_v1) & 0xFFFFFFFF
term3 = ((u_v1 << 4) + k0) & 0xFFFFFFFF
term4 = ((u_v1 >> 5) + k1) # 无符号右移
term4 = term4 & 0xFFFFFFFF # 确保在32位范围内
increment_v0 = (sum_v1 ^ term3 ^ term4) & 0xFFFFFFFF
v0 = (v0 - increment_v0) & 0xFFFFFFFF
# 更新sum_val到上一轮的值
sum_val = (sum_val + delta) & 0xFFFFFFFF
return (v0, v1)
enc = [ 0xEC367B8,0x0C9DA9044, 0x0DA6C2DEB, 0x88DDC9C3, 0x32A01575, 0x231DD0B4,
0x4B9E8A74, 0x0D75D3E74, 0x0EAAB8712, 0x0E704E888, 0x0E01A31AC,
0x0ECAE205C, 0x0A7BE7467, 0x0C6252A3, 0x1AEFEC4E, 0x0C40DED44,
0x0C3C842CC, 0x0DE4A0C0E, 0x7C24F3FC, 0x8FB8D001, 0x11153E6E,
0x530ED15C, 0x0F4214811, 0x0BEB517E0, 0x63F91634, 0x4D96F8A5,
0x0FE23EAC8, 0x2C607ADF, 0x0CC43D85C, 0x0FF186C5B, 0x8763E1A5,
0x9187BD58, 0x87D1069B, 0x0D7878D7B, 0x836E6B68, 0x55A0C63F,
0x0D979FDB3, 0x3E524DEE, 0x7AB35C82, 0x0A2F4DA8D, 0x1708BA4C,
0x710653E6]
key = b'0ECA'
key = [65, 67, 69, 54]
# 48
key = [65, 67, 69, 48]
key = b'0ECA'
key = b'ACE6'
ans = []
for i in range(0,len(enc),2):
# print(i)
c1,c2=enc[i],enc[i+1]
m1,m2 = tea_decrypt_deepseek([c1,c2],key)
m1,m2 = tea_decrypt_XXXTEA(c1,c2,key)
# print(m1,m2)
ans.append(m1)
ans.append(m2)
# print(bytes(ans))
print(len(ans))
print(ans)
# key1 = b'sxx'
# ans2=[]
# for i in range(len(ans)):
# ans2.append(ans[i]^key1[i%len(key1)])
# print(ans2)
# ans2 = bytes(ans2)
# from base58 import b58encode
def base58_decode(encoded: str) -> bytes:
"""
将变种Base58字符串解码为原始字节数据
:param encoded: Base58编码的字符串
:return: 解码后的字节数据
"""
ALPHABET = 'abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ1234567890!@+/'
char_to_value = {char: idx for idx, char in enumerate(ALPHABET)}
if not isinstance(encoded, str):
raise TypeError("Input must be a string")
# 处理前导零字符(ALPHABET[0])
leading_zeros = 0
for char in encoded:
if char != ALPHABET[0]:
break
leading_zeros += 1
# 转换剩余字符为数值
n = 0
for char in encoded[leading_zeros:]:
if char not in char_to_value:
raise ValueError(f"Invalid character found: {char}")
n = n * 58 + char_to_value[char]
# 转换为字节数据
try:
# 处理全零的特殊情况
if n == 0:
return b'\x00' * leading_zeros
# 计算字节长度(需要向上取整)
byte_length = (n.bit_length() + 7) // 8
decoded = n.to_bytes(byte_length, 'big')
except OverflowError:
decoded = b''
# 添加前导零字节
return b'\x00' * leading_zeros + decoded
str1 = [51, 40, 19, 0, 45, 22, 64, 65, 19, 42, 18, 79, 69, 75, 31, 20, 57, 73, 59, 52, 58, 38, 59, 25, 36, 43, 34, 5, 76, 14, 0, 76, 59, 4, 43, 29, 5, 57, 22, 34, 61, 11]
# str1 = enc.encode()
key1 = b'sxx'
ans=[]
for i in range(len(str1)):
ans.append(str1[i]^key1[i%len(key1)])
# print(ans)
print(bytes(ans))
enc = 'PksUn39kYj763ggA1HLBUCaWSZv4vs4CwSevAnQEs'
flag = base58_decode(enc[::-1])
print(flag)
# ACE_We1C0me!T0Z0Z5GamESecur1t9*CTf