Skip to content

Instantly share code, notes, and snippets.

@hyuunnn
Last active September 17, 2018 16:55
Show Gist options
  • Save hyuunnn/a5a601b5bdae1504b4434f5ea7076f3f to your computer and use it in GitHub Desktop.
Save hyuunnn/a5a601b5bdae1504b4434f5ea7076f3f to your computer and use it in GitHub Desktop.
import struct
import sys
import hexdump
import csv
import os
import argparse
# https://gist.github.com/skochinsky/07c8e95e33d9429d81a75622b5d24c8b
PRODID_MAP = {
0: "Unknown",
1: "Import0",
2: "Linker510",
3: "Cvtomf510",
4: "Linker600",
5: "Cvtomf600",
6: "Cvtres500",
7: "Utc11_Basic",
8: "Utc11_C",
9: "Utc12_Basic",
10: "Utc12_C",
11: "Utc12_CPP",
12: "AliasObj60",
13: "VisualBasic60",
14: "Masm613",
15: "Masm710",
16: "Linker511",
17: "Cvtomf511",
18: "Masm614",
19: "Linker512",
20: "Cvtomf512",
21: "Utc12_C_Std",
22: "Utc12_CPP_Std",
23: "Utc12_C_Book",
24: "Utc12_CPP_Book",
25: "Implib700",
26: "Cvtomf700",
27: "Utc13_Basic",
28: "Utc13_C",
29: "Utc13_CPP",
30: "Linker610",
31: "Cvtomf610",
32: "Linker601",
33: "Cvtomf601",
34: "Utc12_1_Basic",
35: "Utc12_1_C",
36: "Utc12_1_CPP",
37: "Linker620",
38: "Cvtomf620",
39: "AliasObj70",
40: "Linker621",
41: "Cvtomf621",
42: "Masm615",
43: "Utc13_LTCG_C",
44: "Utc13_LTCG_CPP",
45: "Masm620",
46: "ILAsm100",
47: "Utc12_2_Basic",
48: "Utc12_2_C",
49: "Utc12_2_CPP",
50: "Utc12_2_C_Std",
51: "Utc12_2_CPP_Std",
52: "Utc12_2_C_Book",
53: "Utc12_2_CPP_Book",
54: "Implib622",
55: "Cvtomf622",
56: "Cvtres501",
57: "Utc13_C_Std",
58: "Utc13_CPP_Std",
59: "Cvtpgd1300",
60: "Linker622",
61: "Linker700",
62: "Export622",
63: "Export700",
64: "Masm700",
65: "Utc13_POGO_I_C",
66: "Utc13_POGO_I_CPP",
67: "Utc13_POGO_O_C",
68: "Utc13_POGO_O_CPP",
69: "Cvtres700",
70: "Cvtres710p",
71: "Linker710p",
72: "Cvtomf710p",
73: "Export710p",
74: "Implib710p",
75: "Masm710p",
76: "Utc1310p_C",
77: "Utc1310p_CPP",
78: "Utc1310p_C_Std",
79: "Utc1310p_CPP_Std",
80: "Utc1310p_LTCG_C",
81: "Utc1310p_LTCG_CPP",
82: "Utc1310p_POGO_I_C",
83: "Utc1310p_POGO_I_CPP",
84: "Utc1310p_POGO_O_C",
85: "Utc1310p_POGO_O_CPP",
86: "Linker624",
87: "Cvtomf624",
88: "Export624",
89: "Implib624",
90: "Linker710",
91: "Cvtomf710",
92: "Export710",
93: "Implib710",
94: "Cvtres710",
95: "Utc1310_C",
96: "Utc1310_CPP",
97: "Utc1310_C_Std",
98: "Utc1310_CPP_Std",
99: "Utc1310_LTCG_C",
100: "Utc1310_LTCG_CPP",
101: "Utc1310_POGO_I_C",
102: "Utc1310_POGO_I_CPP",
103: "Utc1310_POGO_O_C",
104: "Utc1310_POGO_O_CPP",
105: "AliasObj710",
106: "AliasObj710p",
107: "Cvtpgd1310",
108: "Cvtpgd1310p",
109: "Utc1400_C",
110: "Utc1400_CPP",
111: "Utc1400_C_Std",
112: "Utc1400_CPP_Std",
113: "Utc1400_LTCG_C",
114: "Utc1400_LTCG_CPP",
115: "Utc1400_POGO_I_C",
116: "Utc1400_POGO_I_CPP",
117: "Utc1400_POGO_O_C",
118: "Utc1400_POGO_O_CPP",
119: "Cvtpgd1400",
120: "Linker800",
121: "Cvtomf800",
122: "Export800",
123: "Implib800",
124: "Cvtres800",
125: "Masm800",
126: "AliasObj800",
127: "PhoenixPrerelease",
128: "Utc1400_CVTCIL_C",
129: "Utc1400_CVTCIL_CPP",
130: "Utc1400_LTCG_MSIL",
131: "Utc1500_C",
132: "Utc1500_CPP",
133: "Utc1500_C_Std",
134: "Utc1500_CPP_Std",
135: "Utc1500_CVTCIL_C",
136: "Utc1500_CVTCIL_CPP",
137: "Utc1500_LTCG_C",
138: "Utc1500_LTCG_CPP",
139: "Utc1500_LTCG_MSIL",
140: "Utc1500_POGO_I_C",
141: "Utc1500_POGO_I_CPP",
142: "Utc1500_POGO_O_C",
143: "Utc1500_POGO_O_CPP",
144: "Cvtpgd1500",
145: "Linker900",
146: "Export900",
147: "Implib900",
148: "Cvtres900",
149: "Masm900",
150: "AliasObj900",
151: "Resource900",
152: "AliasObj1000",
154: "Cvtres1000",
155: "Export1000",
156: "Implib1000",
157: "Linker1000",
158: "Masm1000",
170: "Utc1600_C",
171: "Utc1600_CPP",
172: "Utc1600_CVTCIL_C",
173: "Utc1600_CVTCIL_CPP",
174: "Utc1600_LTCG_C ",
175: "Utc1600_LTCG_CPP",
176: "Utc1600_LTCG_MSIL",
177: "Utc1600_POGO_I_C",
178: "Utc1600_POGO_I_CPP",
179: "Utc1600_POGO_O_C",
180: "Utc1600_POGO_O_CPP",
# vvv
183: "Linker1010",
184: "Export1010",
185: "Implib1010",
186: "Cvtres1010",
187: "Masm1010",
188: "AliasObj1010",
# ^^^
199: "AliasObj1100",
201: "Cvtres1100",
202: "Export1100",
203: "Implib1100",
204: "Linker1100",
205: "Masm1100",
206: "Utc1700_C",
207: "Utc1700_CPP",
208: "Utc1700_CVTCIL_C",
209: "Utc1700_CVTCIL_CPP",
210: "Utc1700_LTCG_C ",
211: "Utc1700_LTCG_CPP",
212: "Utc1700_LTCG_MSIL",
213: "Utc1700_POGO_I_C",
214: "Utc1700_POGO_I_CPP",
215: "Utc1700_POGO_O_C",
216: "Utc1700_POGO_O_CPP",
}
class rich_header():
def __init__(self, path):
self.path = path
self.start_offset = 0x3c
self.output = {}
self.f = open("result.csv", 'w', encoding='euc-kr', newline='')
self.wr = csv.writer(self.f)
def run(self):
if os.path.isfile(self.path):
f = open(self.path, "rb")
self.data = f.read()
f.close()
self.parse(os.path.basename(self.path))
elif os.path.isdir(self.path):
file_list = os.listdir(self.path)
for i in file_list:
f = open(self.path + "\\" + i, "rb")
self.data = f.read()
f.close()
self.parse(i)
def parse(self, name):
MZ_check = self.data[:2]
if MZ_check == b"MZ":
self.wr.writerow([name,"key", "prodid", "name", "build", "count"])
size = self.data[self.start_offset:self.start_offset+4]
size = struct.unpack("<L", size)[0]
print("[*]Path : " + name)
print("[*]Size : " + str(size))
if self.data[:size].find(b"Rich") != -1:
self.data = self.data[0x80:size]
xor_key = struct.unpack("<L", self.data[:0x4])[0] ^ 0x536e6144 # DanS
find_Rich_string = self.data.find(b"Rich")
check_Rich_signature = struct.unpack("<L", self.data[find_Rich_string+4:find_Rich_string+8])[0]
if xor_key == check_Rich_signature:
print("[*]Vaild signature")
print("[*]XOR KEY : " + hex(xor_key) + "\n")
else:
print("[*]Not Vaild signature")
print("[*]Calculate 'DanS' XOR KEY: " + hex(xor_key))
print("[*]Rich + 4bytes XOR KEY : " + hex(check_Rich_signature) + "\n")
print("[*]Rich Header Hexdump")
hexdump.hexdump(self.data)
print("\n[*]PRODID_List")
print("{:10} | {:10} | {:20} | {:10} | {:10} |".format("key","PRODID", "name", "build", "count"))
for i in range(16, find_Rich_string, 8): # pass DanS Signature, 0000 padding
key = struct.unpack("<L", self.data[i:i+4])[0] ^ xor_key
count = struct.unpack("<L", self.data[i+4:i+8])[0] ^ xor_key
prodid = key >> 16
build = key & 0xFFFF
try:
prodid_data = PRODID_MAP[prodid]
except KeyError:
prodid_data = "UNKNOWN"
self.wr.writerow(["", hex(key), prodid, prodid_data, build, count])
print("{:10} | {:10} | {:20} | {:10} | {:10} |".format(hex(key), prodid, prodid_data, build, count))
print("")
else:
print("Not Found Rich Signature : " + name)
self.wr.writerow(["Not Found Rich Signature", name])
else:
print("Not Found MZ Signature : " +name)
self.wr.writerow(["Not Found MZ Signature", name])
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument("--path", help="path")
args = parser.parse_args()
a = rich_header(args.path)
a.run()
import struct
import sys
import csv
import os
import argparse
import hashlib
class rich_header():
def __init__(self, path):
self.path = path
self.start_offset = 0x3c
self.output = {}
self.f = open("result.csv", 'w', encoding='euc-kr', newline='')
self.wr = csv.writer(self.f)
self.wr.writerow(["filename","xorkey", "ClearData MD5"])
def run(self):
if os.path.isfile(self.path):
f = open(self.path, "rb")
self.data = f.read()
f.close()
self.parse(os.path.basename(self.path))
elif os.path.isdir(self.path):
file_list = os.listdir(self.path)
for i in file_list:
f = open(self.path + "\\" + i, "rb")
self.data = f.read()
f.close()
self.parse(i)
def parse(self, name):
MZ_check = self.data[:2]
if MZ_check == b"MZ":
size = self.data[self.start_offset:self.start_offset+4]
size = struct.unpack("<L", size)[0]
print("[*]Path : " + name)
if self.data[:size].find(b"Rich") != -1:
self.data = self.data[0x80:size]
xor_key = (struct.unpack(">L", self.data[:0x4])[0] ^ 0x44616e53).to_bytes(4, byteorder="big") # DanS
find_Rich_string = self.data.find(b"Rich")
check_Rich_signature = struct.unpack(">L", self.data[find_Rich_string+4:find_Rich_string+8])[0].to_bytes(4, byteorder="big")
if xor_key == check_Rich_signature:
print("[*]Vaild signature\n")
cleardata = b""
for i in range(0, find_Rich_string):
cleardata += struct.pack("B", self.data[i] ^ xor_key[i%4])
self.wr.writerow([name, xor_key.hex(), hashlib.md5(cleardata).hexdigest()])
else:
print("[*]Not Vaild signature")
print("[*]Calculate 'DanS' XOR KEY: " + xor_key.hex())
print("[*]Rich + 4bytes XOR KEY : " + check_Rich_signature.hex() + "\n")
else:
print("Not Found Rich Signature : " + name + "\n")
self.wr.writerow([name, "Not Found Rich Signature"])
else:
print("Not Found MZ Signature : " +name + "\n")
self.wr.writerow([name, "Not Found MZ Signature"])
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument("--path", help="path")
args = parser.parse_args()
a = rich_header(args.path)
a.run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment