---
# System prepended metadata

title: Confuser EX
tags: [分析筆記]

---

# Confuser EX 解密腳本

```python=
import pefile
import argparse

def ror(value : int, shift : int, bit_size : int = 32) -> int:
    shift %= bit_size  
    return ((value >> shift) | (value << (bit_size - shift))) & ((1 << bit_size) - 1)

def decrypt_confuser_ex(file_path : str, section_magic : int, key: list):
    pe = pefile.PE(file_path)
    f = open(file_path, 'rb')
    f_data = f.read()
    f.close()
    crypt_section_addr = 0
    crypt_len = 0
    for section in pe.sections:
        #print(f"section name: {section.Name.decode('utf-8')}, size: {section.SizeOfRawData}, pointer: {section.PointerToRawData}")
        num1 = int.from_bytes(section.Name[:4], 'little')
        num2 = int.from_bytes(section.Name[4:8], 'little')
        magic_num = (num1 * num2) & 0xffffffff
        if magic_num == section_magic:
            crypt_section_addr = section.PointerToRawData
            crypt_len = section.SizeOfRawData
        elif magic_num != 0:
            section_size = section.SizeOfRawData
            sectin_addr = section.PointerToRawData
            section_data = f_data[sectin_addr : sectin_addr + section_size]
            for i in range(0, section_size, 4):
                key_tmp = int.from_bytes(section_data[i:i+4], 'little')
                tmp = (key[2] * key[3]) & 0xffffffff
                key_tmp = ((key[0] ^ key_tmp) + key[1] + tmp) & 0xffffffff
                key[0] = key[1]
                key[1] = key[3]
                key[3] = key_tmp
    xor_key = []
    for i in range(16):
        if i % 3 == 0:
            xor_key.append((key[3] ^ key[1]) & 0xffffffff)
        elif i % 3 == 1:
            xor_key.append((key[3] * key[1]) & 0xffffffff)
        elif i % 3 == 2:
            xor_key.append((key[3] + key[1]) & 0xffffffff)
        key[0] = ror(key[1], 5)
        key[1] = ror(key[2], 3)
        key[2] = ror(key[3], 7)
        key[3] = ror(key[0], 11)
    f_data = bytearray(f_data)
    for i in range(0, crypt_len, 4):
        cur_addr = crypt_section_addr + i
        tmp = int.from_bytes(f_data[cur_addr:cur_addr+4], 'little') ^ xor_key[(i >> 2) & 15]
        tmp = tmp & 0xffffffff
        xor_key[(i >> 2) & 15] = ((xor_key[(i >> 2) & 15] ^ tmp) + 1035675673) & 0xffffffff
        f_data[cur_addr:cur_addr+4] = tmp.to_bytes(4, 'little')
    
    f = open(file_path + ".dec", "wb")
    f.write(bytes(f_data))
    f.close()

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description="decrypt ConfuserEX")
    parser.add_argument('--file', required=True, help='file path')
    parser.add_argument('--magic', required=True, type=int, help='section magic')
    parser.add_argument('--key', required=True, type=int, nargs='+', help='decrypt key')
    args = parser.parse_args()
    try:
        #key = [840982363, 396845039, 3595245228, 3416868873]
        decrypt_confuser_ex(args.file, args.magic, args.key)
    except pefile.PEFormatError as e:
        print(f"Wrong PE File {args.file}: {e}")
    except FileNotFoundError:
        print(f"File not exist: {args.file}")
```