-
Notifications
You must be signed in to change notification settings - Fork 36
/
Copy pathfix_extMethod.py
133 lines (103 loc) · 4.8 KB
/
fix_extMethod.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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# Fix IOExternalMethodDispatch for externalMethod()
#@author simo
#@category iOS.kernel
#@keybinding Meta Shift B
#@menupath
#@toolbar logos/ext.png
#@description test
# -*- coding: utf-8 -*-
from utils.helpers import *
from utils.methods import *
import json
logger = None
def fix_extMethod(class_struct ,func):
dtm = currentProgram.getDataTypeManager()
IOArgs_dt = find_struct("IOExternalMethodArguments")
assert(IOArgs_dt != None)
this = ParameterImpl("this",PointerDataType(class_struct),currentProgram)
reference = ParameterImpl("reference",PointerDataType(VoidDataType()),currentProgram)
IOArgs = ParameterImpl("args",PointerDataType(IOArgs_dt),currentProgram)
params = [this,reference,IOArgs]
func.replaceParameters(FunctionUpdateType.DYNAMIC_STORAGE_ALL_PARAMS,
True,
SourceType.USER_DEFINED,
params)
IOExternalMethodDispatch_size = 24
external_methods = {}
def fix_externalMethods(target,selectors,sMethods):
logger.info("target=%s selectors=%d ,sMethod=%s" %(target,selectors, sMethods))
_sMethods = sMethods
className = target
symbolTable = currentProgram.getSymbolTable()
listing = currentProgram.getListing()
namespace = symbolTable.getNamespace(className,None)
if namespace == None:
popup("[-] %s class not found " %(className))
exit(-1)
class_struct = find_struct(className)
em_infos = {}
for sel in range(selectors):
#off = sel * 24
function_off = int(sMethods,16)
checkScalarInputCount_off = function_off + 8
checkStructureInputSize_off = checkScalarInputCount_off + 4
checkScalarOutputCount_off = checkStructureInputSize_off + 4
checkStructureOutputSize_off = checkScalarOutputCount_off +4
smAddr = toAddr(sMethods)
function_ptr = toAddr(hex(function_off).replace("L",""))
function_end = toAddr(hex(function_off+25).replace("L",""))
scalarInput_addr = toAddr(hex(checkScalarInputCount_off).replace("L",""))
structureInput_addr = toAddr(hex(checkStructureInputSize_off).replace("L",""))
scalarOutput_addr = toAddr(hex(checkScalarOutputCount_off).replace("L",""))
structureOutput_addr = toAddr(hex(checkStructureOutputSize_off).replace("L",""))
listing.clearCodeUnits(function_ptr,function_end,False)
func = makeFunction(function_ptr)
func_addr = getDataAt(function_ptr).getValue()
func = getFunctionAt(func_addr)
if func != None:
symName = "extMethod_%d" %(sel)
fix_namespace(className,func,symName)
fix_extMethod(class_struct,func)
setEOLComment(function_ptr,"sel %d" %(sel))
makeUint(scalarInput_addr,"scalarInput")
makeUint(structureInput_addr,"structureInput")
makeUint(scalarOutput_addr,"scalarOutput")
makeUint(structureOutput_addr,"structureInput")
sMethods = hex(int(sMethods,16) + 24).replace("L","")
scalarInputCnt = getDataAt(scalarInput_addr).getValue()
structureInputCnt = getDataAt(structureInput_addr).getValue()
scalarOutputCnt = getDataAt(scalarOutput_addr).getValue()
structureOutputCnt = getDataAt(structureOutput_addr).getValue()
if func == None:
continue
function_name = func.getName(False)
call_info = {
"selector" : sel,
"scalarInputCnt" : scalarInputCnt.getValue(),
"structInputCnt" : structureInputCnt.getValue(),
"scalarOutputCnt" : scalarOutputCnt.getValue(),
"structOutputCnt" : structureOutputCnt.getValue(),
"async" : False,
"address": func_addr.toString()
}
if function_name in em_infos:
function_name = function_name + str(sel)
em_infos[function_name] = call_info
external_methods['externalMethods'] = em_infos # externalMethods
external_methods['target'] = className # userclient
external_methods['user_client_type'] = 0 # connection type (-1 means undefiend)
external_methods['sMethods'] = _sMethods
out_file = "/tmp/%s.json"%(className)
with open(out_file, 'w') as json_file:
json.dump(external_methods, json_file,indent=4, sort_keys=True)
logger.info("%s file created" %(out_file))
if __name__ == "__main__":
sMethods = currentAddress
if sMethods == None :
popup("Select a The first External Method address")
exit(-1)
logger = setup_logging("external_method")
addr_str = sMethods.toString()
target = askString("Namespace","Target name: ") # how to track the history of strings ?
selectors = askInt("sMethod " + addr_str,"Selector count: ")
fix_externalMethods(target,selectors,addr_str)