Skip to main content

2025tx游戏安全PC初赛

·716 words·4 mins
Table of Contents

前期分析 #

拖进ida发现会对加载sys文件并运行,sys驱动里面有反调一直监控,所以ida attach上去 会自动退出

把加载驱动的部分全部patch掉可以直接attach上去

Alt text

Attach上去后又有一个线程触发反调试,我们把它手动挂起不管直接看main进程都有啥

Alt text

在sub_1400020D0之前不涉及flag直接不管 sub_1400020D0里面是一个变表base58

调进去找到base58的表

然后是一个异或

再到到check处进入vtable的方法

看到FilterSendMessage的v12变量里面装的是一个154004操作码+长度+一串数组

Alt text

然后对sys展开逆向 一上来发现一个很多异或的函数,交叉引用回溯到父函数发现很多花,去花得到函数原型

Alt text

处理后的flag传入了tea加密,tea加密去花发现密文位置,密文长度42 但解密发现明文并不是0-256范围内的数,盲猜要么密文被hook要么tea被hook 通过查看tea引用进入一个加了花的函数000000014000A35B 去花后发现对tea进行的写入

Alt text

观察tea函数0x56偏移刚好和140004001处汇编对得上

Alt text

调驱动看看效果

kuku一顿配环境终于把VirtualKD驸上去了

Alt text

查看驱动加载地址对一下入口的汇编对不对

Alt text

打断点发现tea处的代码果然变了,跳过去可以看到xxtea的加密

所以总的是一个tea+xxtea的轻度魔改

Alt text

Alt text

脚本 #

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