-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathghidra_plugin_ioncube_decrypt.py
70 lines (55 loc) · 1.79 KB
/
ghidra_plugin_ioncube_decrypt.py
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
# Decrypts "encrypted" strings from ioncube's loaders
#@author ss23
#@category _NEW_
#@keybinding
#@menupath
#@toolbar
encryption_key = [0x25,0x68,0xd3,0xc2,0x28,0xf2,0x59,0x2e,0x94,0xee,0xf2,0x91,0xac,0x13,0x96,0x95]
def attemptDecrypt(addr):
tmplength = getByte(addr)
if tmplength < 0:
length = tmplength + 256
else:
length = tmplength
#print length
content = getBytes(addr.next(), length)
# Convert negatives into positives
# TODO: Surely there's an API call for this
new_content = []
for i in range(0, length):
# jython why
if content[i] < 0:
new_content.append(content[i] + 256)
else:
new_content.append(content[i])
decrypted_string = ""
# Decrypt the content
for i in range(0, length):
decrypted_string += chr(new_content[i] ^ encryption_key[(length + i) % len(encryption_key)])
return decrypted_string
funcs = getGlobalFunctions("ioncube_decrypt")
if len(funcs) < 1:
print "Could not identify ioncube_decrypt function"
exit()
elif len(funcs) > 1:
print "Too many ioncube_decrypt functions identified"
exit()
refs = getReferencesTo(funcs[0].getEntryPoint())
for ref in refs:
addr = ref.getFromAddress()
# instruction before should be the "push encrypted_string" we want
instr = getInstructionBefore(addr)
if (type(instr) == type(None)):
continue
possible_data_addr = instr.getOpObjects(0)[0]
# Java!
addr_factory = getAddressFactory()
# Get the assumed-length
possible_data_addr_str = possible_data_addr.toString()
possible_data_addr = addr_factory.getAddress(possible_data_addr_str)
decrypted_string = attemptDecrypt(possible_data_addr)
# TODO: Figure out how to set repeatable comments on a symbol / address
# TODO: Do not duplicate comments
setPreComment(possible_data_addr, "decrypted: " + decrypted_string)
#print possible_data_addr
print "Completed"