Skip to content

Commit

Permalink
support 32-bit static-analysis
Browse files Browse the repository at this point in the history
  • Loading branch information
CloneVsObf committed Feb 15, 2019
1 parent d1ba092 commit 336e1b9
Show file tree
Hide file tree
Showing 9 changed files with 1,160 additions and 361 deletions.
60 changes: 42 additions & 18 deletions basic_analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,52 @@
import shutil
import zipfile
import plistlib
from static_analysis import static_analysis

if len(sys.argv) < 2:
print('[Error] Usage: python basic_analysis.py [Target IPA file]')
exit(-1)

target_ipa_path = sys.argv[1]
if not os.path.exists(target_ipa_path):
print('[Error] File \'%s\' is not exists' % (target_ipa_path))
exit(-1)
def extract_app_path_from_ipa(ipa_path):
_, file_type = os.path.splitext(ipa_path)
if file_type == '.ipa':
target_ipa_file = zipfile.ZipFile(ipa_path)
if os.path.isdir('.tmp'):
shutil.rmtree('.tmp')
os.mkdir('.tmp')
target_ipa_file.extractall('.tmp')
target_ipa_file.close()
tmp_file = os.listdir('.tmp/Payload')[0]
return '.tmp/Payload/' + tmp_file
return None

target_ipa_file = zipfile.ZipFile(target_ipa_path)

if os.path.isdir('.tmp'):
shutil.rmtree('.tmp')
os.mkdir('.tmp')
if __name__ == '__main__':

target_ipa_file.extract('iTunesMetadata.plist', '.tmp')
target_ipa_file.close()
if len(sys.argv) < 2:
print('[Error] Usage: python basic_analysis.py [Target IPA file/Target APP file]')
exit(-1)

itunes_meta_file = open('.tmp/iTunesMetadata.plist', 'rb+')
itunes_meta_file.seek(-1, os.SEEK_END)
itunes_meta_file.truncate()
itunes_meta_file.close()
target_file_path = sys.argv[1]
if not os.path.exists(target_file_path):
print('[Error] File \'%s\' is not exists' % target_file_path)
exit(-1)

print(type(plistlib.readPlist('.tmp/iTunesMetadata.plist')))
_, file_type = os.path.splitext(target_file_path)

target_app_path = None
if file_type == '.ipa':
target_app_path = extract_app_path_from_ipa(target_file_path)
elif file_type == '.app':
target_app_path = target_file_path

if target_app_path is None:
print('[Error] File \'%s\' is not IPA file or APP file' % target_file_path)
exit(-1)

execute_file = None
os.chdir(target_app_path)
app_info_plist_path = 'Info.plist'
with open(app_info_plist_path, 'rb') as app_info_plist:
plist_content = plistlib.load(app_info_plist)
execute_file = plist_content['CFBundleExecutable']

if execute_file is not None:
static_analysis(execute_file)
7 changes: 6 additions & 1 deletion interpreters/inner_Interpreter.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,15 @@ def __init__(self, memory_provider=None, handle_strange_add=None):
self.wsp = Register(-1)
self.sp = Register(-1)
self.pc = Register(-1)
self.memory = {hex(0-0x30):SUPER_POINTER}
self.memory = {hex(0-0x30): SUPER_POINTER}
self.memory_provider = memory_provider
self.handle_strange_add = handle_strange_add

# Jump related
self.compare_flag = 0 # 0 is equal and -1 is small and 1 is bigger
self.should_jump = False
self.jump_address = 0x0

def modify_regs(self, reg, value):
if not type(value) == int:
return False
Expand Down
7 changes: 6 additions & 1 deletion models/class_storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,15 @@ def __init__(self, name):
self.arguments_type = [] # empty means no argument


MethodDataTypeClass = 0
MethodDataTypeInstance = 1


class MethodData:

def __init__(self, _class, name):
def __init__(self, _class, name, type=MethodDataTypeInstance):
self._class = _class
self.type = type
self.name = name
self.return_type = 'id' # guess default return_type should be 'id'
self.arguments_type = [] # empty means no argument
Expand Down
14 changes: 8 additions & 6 deletions models/mach_o/fat.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,10 @@ def __init__(self):

@classmethod
def parse_from_bytes(cls, _bytes):
print(_bytes)
fh = cls()
fh.magic = parse_int(_bytes[0:4])
fh.nfat_arch = parse_int(_bytes[4:8])
fh.nfat_arch = parse_int(_bytes[4:8], False)
return fh

def get_size(self):
Expand All @@ -57,11 +58,12 @@ def __init__(self):
@classmethod
def parse_from_bytes(cls, _bytes):
fa = cls()
fa.cputype = parse_int(_bytes[0:4])
fa.cpusubtype = parse_int(_bytes[4:8])
fa.offset = parse_int(_bytes[8:12])
fa.size = parse_int(_bytes[12:16])
fa.size = parse_int(_bytes[16:20])
# 这里是大端,其他地方是小端......
fa.cputype = parse_int(_bytes[0:4], False)
fa.cpusubtype = parse_int(_bytes[4:8], False)
fa.offset = parse_int(_bytes[8:12], False)
fa.size = parse_int(_bytes[12:16], False)
fa.align = parse_int(_bytes[16:20], False)
return fa

def get_size(self):
Expand Down
26 changes: 23 additions & 3 deletions models/mach_o/loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB = 0xC0



class MachBase:

def __init__(self):
Expand Down Expand Up @@ -126,6 +125,9 @@ class LoadCommand(MachBase):
LC_DYLD_INFO = 0x22
LC_DYLD_INFO_ONLY = (0x22 | LC_REQ_DYLD)

LC_LOAD_WEAK_DYLIB = (0x18 | LC_REQ_DYLD)
LC_RPATH = (0x1c | LC_REQ_DYLD)

def __init__(self):
self.cmd = 0
self.cmdsize = 0
Expand All @@ -141,11 +143,29 @@ def get_size(self):
return LoadCommand.LC_TOTAL_SIZE


class RpathCommand(LoadCommand):
RC_TOTAL_SIZE = 16
RC_PATH_RANGE = (8, 8)

def __init__(self):
super(RpathCommand, self).__init__()
self.path = 0

@classmethod
def parse_from_bytes(cls, _bytes):
rc = cls()
rc.cmd = parse_int(_bytes[0:4])
rc.cmdsize = parse_int(_bytes[4:8])
rc.path = parse_int(_bytes[8:16])
return rc

def get_size(self):
return RpathCommand.RC_TOTAL_SIZE


class DyldInfoCommand(LoadCommand):

DIC_TOTAL_SIZE = 48
DIC_CMD_RANGE = (0, 4)
DIC_CMDSIZE_RANGE = (4, 4)
DIC_REBASE_OFF_RANGE = (8, 4)
DIC_REBASE_SIZE_RANGE = (12, 4)
DIC_BIND_OFF_RANGE = (16, 4)
Expand Down
Loading

0 comments on commit 336e1b9

Please sign in to comment.