-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfix_extMethod.py
More file actions
135 lines (105 loc) · 5.08 KB
/
fix_extMethod.py
File metadata and controls
135 lines (105 loc) · 5.08 KB
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
134
135
# 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) # make function
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)
#if func.getSymbol().getSource() != SourceType.USER_DEFINED:
#func.setName(symName,SourceType.USER_DEFINED)
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()
#print "SCALAR COUNT", scalarInputCnt
#print "SCALAR COUNT", structureInputCnt
#print "SCALAR COUNT", scalarOutputCnt
#print "SCALAR COUNT", structureOutputCnt
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()
}
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)