File size: 4,325 Bytes
ce847d4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
"""Walk ALL payload chunks in the .onemodel file and decrypt them statically.
Full cross-platform static decryptor - no DLL or Windows APIs needed.
"""
import struct
import hashlib
from Crypto.Cipher import AES

MASTER_KEY = b'kj)TGtrK>f]b[Piow.gU+nC@s""""""4'
IV = b"Copyright @ OneO"
CONTAINER_MAGIC = bytes.fromhex("4a1a082b25000000")

def aes_cfb128_decrypt(key: bytes, iv: bytes, data: bytes) -> bytes:
    cipher = AES.new(key, AES.MODE_CFB, iv=iv, segment_size=128)
    return cipher.decrypt(data)

with open("ocr_data/oneocr.onemodel", "rb") as f:
    fdata = f.read()

# Parse file header
H = struct.unpack_from("<Q", fdata, 0)[0]
file_hash = fdata[8:24]
print(f"File size: {len(fdata):,} bytes")
print(f"Header value H: {H}")
print(f"DX encrypted size: {H-12}")
print(f"Payload start: {H+16}")

# Decrypt DX index
dx_key = hashlib.sha256(MASTER_KEY + file_hash).digest()
dx_enc = fdata[24:H+12]
dx = aes_cfb128_decrypt(dx_key, IV, dx_enc)

valid_size = struct.unpack_from("<Q", dx, 8)[0]
print(f"DX magic: {dx[:8]}")
print(f"DX valid size: {valid_size}")

# Decrypt config from DX
config_sha_input = dx[48:64] + dx[32:48]  # sizes + checksum
config_key = hashlib.sha256(config_sha_input).digest()
config_s1 = struct.unpack_from("<Q", dx, 48)[0]
config_enc = dx[64:64+config_s1+8]
config_dec = aes_cfb128_decrypt(config_key, IV, config_enc)
print(f"Config decrypted: {len(config_dec)} bytes, magic match: {config_dec[:8] == CONTAINER_MAGIC}")

# Walk payload chunks
off = H + 16
chunk_idx = 0
chunks = []

while off + 32 <= len(fdata):
    chk = fdata[off:off+16]
    s1, s2 = struct.unpack_from("<QQ", fdata, off+16)
    
    if s2 != s1 + 24 or s1 == 0 or s1 > len(fdata):
        break
    
    enc_size = s1 + 8
    data_off = off + 32
    
    if data_off + enc_size > len(fdata):
        print(f"WARNING: chunk#{chunk_idx} extends past file end!")
        break
    
    # Derive per-chunk key
    sha_input = fdata[off+16:off+32] + fdata[off:off+16]  # sizes + checksum
    chunk_key = hashlib.sha256(sha_input).digest()
    
    # Decrypt
    dec_data = aes_cfb128_decrypt(chunk_key, IV, fdata[data_off:data_off+enc_size])
    
    magic_ok = dec_data[:8] == CONTAINER_MAGIC
    payload = dec_data[8:]  # strip container header
    
    chunks.append({
        "idx": chunk_idx,
        "file_offset": off,
        "data_offset": data_off,
        "size1": s1,
        "enc_size": enc_size,
        "magic_ok": magic_ok,
        "payload": payload,
    })
    
    print(f"  chunk#{chunk_idx:02d}: off={off:>10} s1={s1:>10} magic={'OK' if magic_ok else 'FAIL'} payload_start={payload[:8].hex()}")
    
    off = data_off + enc_size
    chunk_idx += 1

print(f"\nTotal chunks: {chunk_idx}")
print(f"File bytes remaining: {len(fdata) - off}")
print(f"All magic OK: {all(c['magic_ok'] for c in chunks)}")

# Identify ONNX models (start with protobuf field tags typical for ONNX ModelProto)
print("\n=== ONNX model identification ===")
onnx_count = 0
for c in chunks:
    payload = c["payload"]
    # ONNX ModelProto fields: 1(ir_version), 2(opset_import), 3(producer_name), etc.
    # Field 1 varint starts with 0x08
    # Actually check for ONNX-specific protobuf pattern
    is_onnx = False
    if len(payload) > 100:
        # Check for typical ONNX patterns
        if payload[0] == 0x08 and payload[1] in (0x06, 0x07):  # ir_version 6 or 7
            is_onnx = True
    
    if is_onnx:
        onnx_count += 1
        print(f"  chunk#{c['idx']:02d}: ONNX model, size={len(payload):,} bytes")

print(f"\nTotal ONNX models found: {onnx_count}")
print(f"Total non-ONNX chunks: {chunk_idx - onnx_count}")

# Show what non-ONNX chunks look like
print("\n=== Non-ONNX chunk types ===")
for c in chunks:
    payload = c["payload"]
    if len(payload) < 100 or payload[0] != 0x08 or payload[1] not in (0x06, 0x07):
        # Try ASCII
        try:
            s = payload[:40].decode('ascii')
            readable = all(ch.isprintable() or ch in '\n\r\t' for ch in s)
        except:
            readable = False
        
        if readable:
            preview = payload[:60].decode('ascii', errors='replace').replace('\n', '\\n')
        else:
            preview = payload[:32].hex()
        print(f"  chunk#{c['idx']:02d}: size={len(payload):>8,} type={'text' if readable else 'binary'} preview={preview}")