forked from iGio90/GDumper
-
Notifications
You must be signed in to change notification settings - Fork 2
/
crcsploiter.py
111 lines (85 loc) · 2.98 KB
/
crcsploiter.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
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
import argparse
import binascii
import capstone
import keystone
import os
import sys
def main(args):
parser = argparse.ArgumentParser(description='Exploit Supercell CRC protection.')
parser.add_argument('-o', '--offset', help="Offset", required=True)
parser.add_argument('-c', '--count', help="Count")
parser.add_argument('-pH', '--payloadH', help="Attempt to find a valid spot for given payload in hex string format")
parser.add_argument('-pI', '--payloadI', help="Attempt to find a valid spot for given instruction")
parser.add_argument('-e', '--extract', help="Extract library")
args = parser.parse_args()
offset = args.offset
count = args.count
extract = args.extract
payloadH = args.payloadH
payloadI = args.payloadI
if not count:
count = 8
if extract:
print("Extracting libg\n")
runCmd("adb shell su -c cp /data/data/com.supercell.boombeach/lib/libg.so /sdcard/libg.so")
runCmd("adb pull /sdcard/libg.so .")
if str.startswith(offset, "0x"):
offset = int(offset, 16)
else:
offset = int(offset)
lib = open("libg.so", "rb")
data = lib.read()
lib.close()
target = data[offset:offset + int(count)]
hex_bytes = binascii.hexlify(target)
hex_str = hex_bytes.decode("ascii")
print("CALCULATING CRC FOR: " + str.upper(hex_str) + "\n")
print("ASSEMBLY CODE:")
md = capstone.Cs(capstone.CS_ARCH_ARM, capstone.CS_MODE_THUMB)
for (address, size, mnemonic, op_str) in md.disasm_lite(target, 0x0000):
print("0x%x:\t%s\t%s" % (address, mnemonic, op_str))
print("")
calculateCrc(hex_str)
if payloadI:
print("ASSEMBLING INSTRUCTION: %s" % payloadI)
try:
payloadI = payloadI.encode()
ks = keystone.Ks(keystone.KS_ARCH_ARM, keystone.KS_MODE_THUMB)
encoding, count = ks.asm(payloadI)
payloadH = binascii.hexlify(bytearray(encoding)).decode("ascii")
print(payloadH + "\n")
except keystone.KsError as e:
print("ERROR: %s" % e)
if payloadH:
print("CALCULATING CRC FOR %s:" % str.upper(payloadH))
calculateCrc(payloadH)
def runCmd(cmd):
os.system(cmd)
def calculateCrc(payload):
k = 0
crc = 0
block = ""
plen = len(payload)
for i in range(plen):
if i % 2 != 0:
if (k != 4 and k > 0) and (i + 1 == plen):
print("CRC for block %s: %d" % (str.upper(block), crc))
continue
if i + 2 <= len(payload):
block += payload[i:i + 2]
crc += parseInt(payload[i:i + 2])
k = k + 1
if k == 4:
k = 0
print("CRC for block %s: %d" % (str.upper(block), crc))
crc = 0
block = ""
print("")
def parseInt(str):
hex = {'A', 'B', 'C', 'D', 'E', 'F'}
for hChar in hex:
if hChar in str.upper():
return int(str, 16)
return int(str, 10)
if __name__ == '__main__':
main(sys.argv)