-
Notifications
You must be signed in to change notification settings - Fork 561
Expand file tree
/
Copy pathGdaImport.py
More file actions
191 lines (183 loc) · 9.41 KB
/
GdaImport.py
File metadata and controls
191 lines (183 loc) · 9.41 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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# this file is just used for GDA python, cannot be modified, or some erro will occur
# author:gjden
# 2018.9.10
import ctypes
#define the Interface type
CALLFUNC_P = ctypes.CFUNCTYPE(ctypes.c_char_p)
CALLFUNC_IP = ctypes.CFUNCTYPE(ctypes.c_int,ctypes.c_char_p)
CALLFUNC_PI = ctypes.CFUNCTYPE(ctypes.c_char_p,ctypes.c_int)
CALLFUNC_IPI = ctypes.CFUNCTYPE(ctypes.c_int,ctypes.c_char_p,ctypes.c_int)
CALLFUNC_PII = ctypes.CFUNCTYPE(ctypes.c_char_p,ctypes.c_int,ctypes.c_int)
CALLFUNC_IIP = ctypes.CFUNCTYPE(ctypes.c_int,ctypes.c_int,ctypes.c_int)
CALLFUNC_IIPI = ctypes.CFUNCTYPE(ctypes.c_int,ctypes.c_int,ctypes.c_char_p,ctypes.c_int)
CALLFUNC_PIIII = ctypes.CFUNCTYPE(ctypes.c_char_p,ctypes.c_int,ctypes.c_int,ctypes.c_int,ctypes.c_int)
CALLFUNC_PIIIII = ctypes.CFUNCTYPE(ctypes.c_char_p,ctypes.c_int,ctypes.c_int,ctypes.c_int,ctypes.c_int,ctypes.c_int)
CALLFUNC_IIPI = ctypes.CFUNCTYPE(ctypes.c_int,ctypes.c_int,ctypes.c_char_p,ctypes.c_int)
CALLFUNC_IIPII = ctypes.CFUNCTYPE(ctypes.c_int,ctypes.c_int,ctypes.c_char_p,ctypes.c_int)
CALLFUNC_IPIII = ctypes.CFUNCTYPE(ctypes.c_int,ctypes.c_char_p,ctypes.c_int,ctypes.c_int,ctypes.c_int)
CALLFUNC_PPII = ctypes.CFUNCTYPE(ctypes.c_char_p,ctypes.c_char_p,ctypes.c_int,ctypes.c_int)
# Dex File Header
class DexHeader:
def __init__(self):
#dex header
self.magic= []
self.checksum= 0
self.signature= []
self.DexSize= 0
self.headerSize= 0
self.endianTag= 0
self.linkSize= 0
self.linkOff= 0
self.mapOff= 0
self.stringIdsSize= 0
self.stringIdsOff= 0
self.typeIdsSize= 0
self.typeIdsOff= 0
self.protoIdsSize= 0
self.protoIdsOff= 0
self.fieldIdsSize= 0
self.fieldIdsOff= 0
self.methodIdsSize= 0
self.methodIdsOff= 0
self.classDefsSize= 0
self.classDefsOff= 0
self.dataSize= 0
self.dataOff= 0
# android-method infomation Class
class MethodInfo:
def __init__(self):
idx = 0 #index to a method_id_item
methodName = "" #method name like OnCreate
modifiedMethodName = "" #the modified method name like OnCreate_
methodFullName = "" #method full name like com.gda.MyActivity.OnCreate
methodPackage = "" #package eg:com.gda.MyActivity
MethodSignature = "" #method signature eg:(IILandroid/sys/network;)I
offset = 0 #the method binary code offset which is equal to codeOff of DexMehtod
size = 0 #the size of DexCode(the members and binary instruction data)
regSize = 0 #the register size
permission = "" #method execute permisson
methodSmaliCode = "" #smail code text
methodJavaCode = "" #java code text
callorIdxList = [] #the callor list of the method
refMethodIdxList = [] #the callee list of the method
refStringIdxList = [] #the string list that is used of method
# refClassIdxList = []
# refFieldIdxList = []
#
# android-class infomation class
class ClassInfo:
def __init__(self):
idx = 0
className = ""
modifiedClassName = ""
classFullName = ""
sourceFileIdx = 0 #the source file string index
superclassIdx = 0 #the parent class index
classCode = "" #class code without method code
subClassList = [] #subClass List
# Gda-Dex interface Class
#
class GdaDex:
def __init__(self):
self.DexHeader = 0 #Class DexHeader instance
self.MethodTable = {} #Methods Hash Table (dictionary<idx,MethodInfo>)
self.ClassTable = {} #Classes Hash Table (dictionary<idx,ClassInfo>)
self.ClassList = []
self.MethodList = []
class GDAInterface:
def initInterface(self, InterfaceDic):
self.pInstance= 0 #Class instance,will be setup by GDA
#interface
self.InterfaceDic_= InterfaceDic
self.GetAppString_ = CALLFUNC_PI(InterfaceDic['GetAppString'])
self.log_ = CALLFUNC_IP(InterfaceDic['gprint'])
self.GetPermission_ = CALLFUNC_P(InterfaceDic['GetPermission'])
self.GetCert_ = CALLFUNC_P(InterfaceDic['GetCert'])
self.GetSupicous_ = CALLFUNC_PI(InterfaceDic['GetSupicous'])
self.GetStringById_ = CALLFUNC_PII(InterfaceDic['GetStringById'])
self.SetStringById_ = CALLFUNC_IIPI(InterfaceDic['SetStringById'])
self.SetMethodName_ = CALLFUNC_IIPI(InterfaceDic['SetMethodName'])
self.SetClassName_ = CALLFUNC_IIPI(InterfaceDic['SetClassName'])
self.GetClassCodeById_ = CALLFUNC_PII(InterfaceDic['GetClassCodeById'])
self.GetSmaliCodeById_ = CALLFUNC_PII(InterfaceDic['GetSmaliCodeById'])
self.GetJavaCodeById_ = CALLFUNC_PII(InterfaceDic['GetJavaCodeById'])
self.GetUrlString_ = CALLFUNC_PI(InterfaceDic['GetUrlString'])
self.FindClassId_ = CALLFUNC_IPI(InterfaceDic['FindClassId'])
self.GetMethodNameById_ = CALLFUNC_PII(InterfaceDic['GetMethodNameById'])
self.GetStringByTypeId_ = CALLFUNC_PII(InterfaceDic['GetStringByTypeId'])
self.DumpHexData_= CALLFUNC_PIIIII(InterfaceDic['DumpHexData'])
self.WriteBinaryToDex_= CALLFUNC_IIPII(InterfaceDic['WriteBinaryToDex'])
self.DumpBin_= CALLFUNC_IPIII(InterfaceDic['DumpBin'])
self.GetMethodDeclare_= CALLFUNC_PII(InterfaceDic['GetMethodDeclare'])
self.GetClassCodeById_Ex_= CALLFUNC_PII(InterfaceDic['GetClassCodeById_Ex'])
self.DisasmBinData_= CALLFUNC_PPII(InterfaceDic['DisasmBinData'])
self.DexList=[] # GdaDex List,for supporting multi-Dex,will be setup by GDA
# return the strings used by all methods, dexId is the index of GdaDex,
# default value is 0, most of apk only contains one Dex
def GetAppString(self,dexId=0):
return self.GetAppString_(dexId)
# GDA print, the string will be output in GDA tool
def log(self,str):
return self.log_(ctypes.c_char_p(str))
# return all Permissions string of apk file
def GetPermission(self):
return self.GetPermission_()
# return the certificate
def GetCert(self):
return self.GetCert_()
# return the Suspicious behavior
def GetSupicous(self,dexId=0):
return self.GetSupicous_(dexId)
# getting string by string index
def GetStringById(self,idx,dexId=0):
return self.GetStringById_(idx,dexId)
# setting string by string index
def SetStringById(self,idx,str,dexId=0):
return self.SetStringById_(idx,ctypes.c_char_p(str),dexId)
# getting method name by method index
def GetMethodNameById(self,idx,dexId=0):
return self.GetMethodNameById_(idx,dexId)
# updating the class name
def SetClassName(self,idx,name,dexId=0):
return self.SetClassName_(idx,ctypes.c_char_p(name),dexId)
# updating the method name
def SetMethodName(self,idx,name,dexId=0):
return self.SetMethodName_(idx,ctypes.c_char_p(name),dexId)
# getting the chass code by class index
def GetClassCodeById(self,idx,dexId=0):
return self.GetClassCodeById_(idx,dexId)
# getting the class code(all the methods of a class) by class index
def GetClassCodeById_Ex(self,idx,dexId=0):
return self.GetClassCodeById_Ex_(idx,dexId)
# getting the smali code for method by method index
def GetSmaliCodeById(self,idx,dexId=0):
return self.GetSmaliCodeById_(idx,dexId)
# getting the java code for method by method index
def GetJavaCodeById(self,idx,dexId=0):
return self.GetJavaCodeById_(idx,dexId)
# getting the all the strings like url
def GetUrlString(self,dexId=0):
return self.GetUrlString_(dexId)
# getting class idx by the class descriptor
def FindClassId(self,descriptor,dexId=0):
return self.FindClassId_(ctypes.c_char_p(descriptor),dexId)
# getting type string by type index
def GetStringByTypeId(self,idx,dexId=0):
return self.GetStringByTypeId_(idx,dexId)
# getting method by index, etc:setValue(Activity myActivity)
def GetMethodDeclare(self,idx,dexId=0):
return self.GetMethodDeclare_(idx,dexId)
# dump the binary data of dex file into file
def DumpBin(self,fileName,offset,size,dexId=0):
return self.DumpBin_(ctypes.c_char_p(fileName),offset,size,dexId)
# getting the binary data of dex file by hex formation
# width is the bytes of a line,eg:16
# mode=0(only hex),1(with offset),2(with blank between two hex),4(with chars),7(with all of features)
def DumpHexData(self,offset,size,width=16,mode=7,dexId=0):
return self.DumpHexData_(offset,size,width,mode,dexId)
# write binary data into dex file, note:probaly damage the Dex File
def WriteBinaryToDex(self,offset,bytes,buffLen,dexId=0):
return self.WriteBinaryToDex_(offset,ctypes.c_char_p(bytes),buffLen,dexId)
# write binary data into dex file, note:probaly damage the Dex File
def DisasmBinData(self,data,dataLen,dexId=0):
return self.DisasmBinData_(ctypes.c_char_p(data),dataLen,dexId)