mirror of
https://github.com/Karmaz95/Snake_Apple.git
synced 2026-08-17 21:47:10 +02:00
This commit is contained in:
@@ -34,11 +34,11 @@ class MachOProcessor:
|
|||||||
|
|
||||||
global binaries # It must be global, becuase after the MachOProcessor object is destructed, the snake_instance would point to invalid memory ("binary" is dependant on "binaries").
|
global binaries # It must be global, becuase after the MachOProcessor object is destructed, the snake_instance would point to invalid memory ("binary" is dependant on "binaries").
|
||||||
global snake_instance # Must be global for further processors classes.
|
global snake_instance # Must be global for further processors classes.
|
||||||
|
|
||||||
binaries = self.parseFatBinary()
|
binaries = self.parseFatBinary()
|
||||||
|
|
||||||
if binaries == None:
|
if binaries is None:
|
||||||
exit() # Exit if not
|
exit() # Exit if the file is not valid macho
|
||||||
|
|
||||||
snake_instance = SnakeVI(binaries, self.file_path) # Initialize the latest Snake class
|
snake_instance = SnakeVI(binaries, self.file_path) # Initialize the latest Snake class
|
||||||
|
|
||||||
@@ -47,7 +47,7 @@ class MachOProcessor:
|
|||||||
|
|
||||||
if args.header_flags: # Print binary header flags
|
if args.header_flags: # Print binary header flags
|
||||||
header_flag_list = snake_instance.getHeaderFlags()
|
header_flag_list = snake_instance.getHeaderFlags()
|
||||||
print("Header flags:", " ".join(header_flag.name for header_flag in header_flag_list))
|
print("Header flags:", " ".join(header_flag.__name__ for header_flag in header_flag_list))
|
||||||
|
|
||||||
if args.endian: # Print binary endianess
|
if args.endian: # Print binary endianess
|
||||||
print(f'Endianess: {snake_instance.getEndianess()}')
|
print(f'Endianess: {snake_instance.getEndianess()}')
|
||||||
@@ -57,7 +57,7 @@ class MachOProcessor:
|
|||||||
|
|
||||||
if args.load_commands: # Print binary load commands
|
if args.load_commands: # Print binary load commands
|
||||||
load_commands_list = snake_instance.getLoadCommands()
|
load_commands_list = snake_instance.getLoadCommands()
|
||||||
print("Load Commands:", " ".join(load_command.command.name for load_command in load_commands_list))
|
print("Load Commands:", " ".join(load_command.command.__name__ for load_command in load_commands_list))
|
||||||
|
|
||||||
if args.has_cmd: # Check if LC exist
|
if args.has_cmd: # Check if LC exist
|
||||||
snake_instance.printHasLoadCommand(args.has_cmd)
|
snake_instance.printHasLoadCommand(args.has_cmd)
|
||||||
@@ -239,15 +239,14 @@ class SnakeI:
|
|||||||
'''
|
'''
|
||||||
for binary in binaries:
|
for binary in binaries:
|
||||||
if binary.header.cpu_type == lief.MachO.CPU_TYPES.ARM64:
|
if binary.header.cpu_type == lief.MachO.CPU_TYPES.ARM64:
|
||||||
arm64_bin = binary
|
return binary
|
||||||
if arm64_bin == None:
|
|
||||||
print('The specified Mach-O file is not in ARM64 architecture.')
|
print('The specified Mach-O file is not in ARM64 architecture.')
|
||||||
exit()
|
exit()
|
||||||
return arm64_bin
|
|
||||||
|
|
||||||
def getFileType(self):
|
def getFileType(self):
|
||||||
'''Extract and return the file type from a binary object's header.'''
|
'''Extract and return the file type from a binary object's header.'''
|
||||||
return self.binary.header.file_type.name
|
return self.binary.header.file_type.__name__
|
||||||
|
|
||||||
def getHeaderFlags(self):
|
def getHeaderFlags(self):
|
||||||
'''Return binary header flags.'''
|
'''Return binary header flags.'''
|
||||||
@@ -255,7 +254,7 @@ class SnakeI:
|
|||||||
|
|
||||||
def getEndianess(self):
|
def getEndianess(self):
|
||||||
'''Check the endianness of a binary based on the system and binary's magic number.'''
|
'''Check the endianness of a binary based on the system and binary's magic number.'''
|
||||||
magic = self.binary.header.magic.name
|
magic = self.binary.header.magic.__name__
|
||||||
endianness = sys.byteorder
|
endianness = sys.byteorder
|
||||||
if endianness == 'little' and (magic == 'MAGIC_64' or magic == 'MAGIC' or magic == 'FAT_MAGIC'):
|
if endianness == 'little' and (magic == 'MAGIC_64' or magic == 'MAGIC' or magic == 'FAT_MAGIC'):
|
||||||
return 'little'
|
return 'little'
|
||||||
@@ -327,7 +326,7 @@ class SnakeI:
|
|||||||
'''
|
'''
|
||||||
for section in self.binary.sections:
|
for section in self.binary.sections:
|
||||||
if segment_name == section.segment_name:
|
if segment_name == section.segment_name:
|
||||||
if section_name == section.fullname:
|
if section_name == section.fullname.decode():
|
||||||
section_offset_start, section_offset_end = self.calcSectionRange(section)
|
section_offset_start, section_offset_end = self.calcSectionRange(section)
|
||||||
return section_offset_start, section_offset_end
|
return section_offset_start, section_offset_end
|
||||||
return False, False
|
return False, False
|
||||||
@@ -351,15 +350,15 @@ class SnakeI:
|
|||||||
sections_info.append(len(sections_info[0])*"=")
|
sections_info.append(len(sections_info[0])*"=")
|
||||||
for section in self.binary.sections:
|
for section in self.binary.sections:
|
||||||
segment_name = section.segment_name
|
segment_name = section.segment_name
|
||||||
section_name = section.fullname
|
section_name = section.fullname.decode()
|
||||||
section_type = section.type.name
|
section_type = section.type.__name__
|
||||||
section_va_start = hex(section.virtual_address)
|
section_va_start = hex(section.virtual_address)
|
||||||
section_va_end = hex(section.virtual_address + section.offset)
|
section_va_end = hex(section.virtual_address + section.offset)
|
||||||
section_size_start, section_size_end = self.calcSectionRange(section)
|
section_size_start, section_size_end = self.calcSectionRange(section)
|
||||||
section_size_start = hex(section_size_start)
|
section_size_start = hex(section_size_start)
|
||||||
section_size_end = hex(section_size_end)
|
section_size_end = hex(section_size_end)
|
||||||
section_flags_list = section.flags_list
|
section_flags_list = section.flags_list
|
||||||
flags_strings = [flag.name for flag in section_flags_list]
|
flags_strings = [flag.__name__ for flag in section_flags_list]
|
||||||
flags = " ".join(flags_strings)
|
flags = " ".join(flags_strings)
|
||||||
sections_info.append((f'{segment_name.ljust(14)}{section_name.ljust(20)}{section_type.ljust(28)}{section_va_start}-{section_va_end.ljust(20)}{section_size_start}-{section_size_end}\t\t({flags})'))
|
sections_info.append((f'{segment_name.ljust(14)}{section_name.ljust(20)}{section_type.ljust(28)}{section_va_start}-{section_va_end.ljust(20)}{section_size_start}-{section_size_end}\t\t({flags})'))
|
||||||
return sections_info
|
return sections_info
|
||||||
@@ -609,7 +608,7 @@ class SnakeI:
|
|||||||
load_command = load_command.lower()
|
load_command = load_command.lower()
|
||||||
|
|
||||||
for cmd in self.load_commands:
|
for cmd in self.load_commands:
|
||||||
cmd = str(cmd.command.name).lower()
|
cmd = str(cmd.command.__name__).lower()
|
||||||
if load_command == cmd:
|
if load_command == cmd:
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
@@ -1174,7 +1173,7 @@ class SnakeIV(SnakeIII):
|
|||||||
dylib_loading_commands_names = []
|
dylib_loading_commands_names = []
|
||||||
|
|
||||||
for cmd in self.load_commands:
|
for cmd in self.load_commands:
|
||||||
cmd_name = cmd.command.name
|
cmd_name = cmd.command.__name__
|
||||||
if cmd_name in self.dylib_load_commands_names:
|
if cmd_name in self.dylib_load_commands_names:
|
||||||
dylib_loading_commands.append(cmd)
|
dylib_loading_commands.append(cmd)
|
||||||
dylib_loading_commands_names.append(cmd_name)
|
dylib_loading_commands_names.append(cmd_name)
|
||||||
@@ -1186,7 +1185,7 @@ class SnakeIV(SnakeIII):
|
|||||||
Return a list of unresolved paths (like @executable_path/Frameworks) from LC_RPATH load commands. Example return:
|
Return a list of unresolved paths (like @executable_path/Frameworks) from LC_RPATH load commands. Example return:
|
||||||
['/usr/lib/swift', '@executable_path/Frameworks', '@loader_path/Frameworks']
|
['/usr/lib/swift', '@executable_path/Frameworks', '@loader_path/Frameworks']
|
||||||
'''
|
'''
|
||||||
return [cmd.path for cmd in self.load_commands if cmd.command.name == 'RPATH']
|
return [cmd.path for cmd in self.load_commands if cmd.command.__name__ == 'RPATH']
|
||||||
|
|
||||||
def resolveRunPathLoadCommands(self):
|
def resolveRunPathLoadCommands(self):
|
||||||
'''
|
'''
|
||||||
@@ -1363,7 +1362,7 @@ class SnakeIV(SnakeIII):
|
|||||||
I intentionally omit this step to always extract ID.
|
I intentionally omit this step to always extract ID.
|
||||||
'''
|
'''
|
||||||
for cmd in self.load_commands:
|
for cmd in self.load_commands:
|
||||||
if cmd.command.name == 'ID_DYLIB':
|
if cmd.command.__name__ == 'ID_DYLIB':
|
||||||
return cmd
|
return cmd
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@@ -1641,7 +1640,7 @@ class SnakeIV(SnakeIII):
|
|||||||
'''
|
'''
|
||||||
reexport_load_commands = []
|
reexport_load_commands = []
|
||||||
for cmd in self.load_commands:
|
for cmd in self.load_commands:
|
||||||
if cmd.command.name == 'REEXPORT_DYLIB':
|
if cmd.command.__name__ == 'REEXPORT_DYLIB':
|
||||||
reexport_load_commands.append(cmd)
|
reexport_load_commands.append(cmd)
|
||||||
return reexport_load_commands
|
return reexport_load_commands
|
||||||
|
|
||||||
@@ -1834,7 +1833,7 @@ class SnakeV(SnakeIV):
|
|||||||
all_dyld_env = []
|
all_dyld_env = []
|
||||||
|
|
||||||
for cmd in self.load_commands:
|
for cmd in self.load_commands:
|
||||||
if cmd.command.name == 'DYLD_ENVIRONMENT':
|
if cmd.command.__name__ == 'DYLD_ENVIRONMENT':
|
||||||
all_dyld_env.append(cmd)
|
all_dyld_env.append(cmd)
|
||||||
|
|
||||||
return all_dyld_env
|
return all_dyld_env
|
||||||
@@ -1988,13 +1987,15 @@ class SnakeVI(SnakeV):
|
|||||||
''' Dump '__PRELINK_INFO,__info' to a given file (default: 'PRELINK_info.txt') '''
|
''' Dump '__PRELINK_INFO,__info' to a given file (default: 'PRELINK_info.txt') '''
|
||||||
segment_name = '__PRELINK_INFO'
|
segment_name = '__PRELINK_INFO'
|
||||||
section_name = '__info'
|
section_name = '__info'
|
||||||
self.dumpSection(segment_name, section_name, filename)
|
if self.dumpSection(segment_name, section_name, filename):
|
||||||
|
print("SUCCESS: __PRELINK_INFO,__info dump")
|
||||||
|
|
||||||
def dumpPrelink_text(self, filename):
|
def dumpPrelink_text(self, filename):
|
||||||
''' Dump '__PRELINK_TEXT,__text' to a given file (default: 'PRELINK_text.txt') '''
|
''' Dump '__PRELINK_TEXT,__text' to a given file (default: 'PRELINK_text.txt') '''
|
||||||
segment_name = '__PRELINK_TEXT'
|
segment_name = '__PRELINK_TEXT'
|
||||||
section_name = '__text'
|
section_name = '__text'
|
||||||
self.dumpSection(segment_name, section_name, filename)
|
if self.dumpSection(segment_name, section_name, filename):
|
||||||
|
print("SUCCESS: __PRELINK_TEXT,__text dump")
|
||||||
|
|
||||||
def extractPRELINK_INFO_plist(self):
|
def extractPRELINK_INFO_plist(self):
|
||||||
''' Extract '__PRELINK_INFO,__info' and return it. '''
|
''' Extract '__PRELINK_INFO,__info' and return it. '''
|
||||||
|
|||||||
@@ -1738,16 +1738,25 @@ class TestSnakeVI():
|
|||||||
amfi_processor.process(args)
|
amfi_processor.process(args)
|
||||||
|
|
||||||
uroboros_output = executeCodeBlock(code_block)
|
uroboros_output = executeCodeBlock(code_block)
|
||||||
expected_output = '''MIG_subsystem_1000:
|
expected_output_1 = 'MIG_subsystem_1000:'
|
||||||
- MIG_msg_1000: 0x100007ea8
|
expected_output_2 = 'MIG_msg_1000'
|
||||||
- MIG_msg_1001: 0x1000080dc
|
expected_output_3 = 'MIG_msg_1001'
|
||||||
- MIG_msg_1002: 0x0
|
expected_output_4 = 'MIG_msg_1002'
|
||||||
- MIG_msg_1003: 0x1000081dc
|
expected_output_5 = 'MIG_msg_1003'
|
||||||
- MIG_msg_1004: 0x100008300
|
expected_output_6 = 'MIG_msg_1004'
|
||||||
- MIG_msg_1005: 0x100008448
|
expected_output_7 = 'MIG_msg_1005'
|
||||||
- MIG_msg_1006: 0x1000084e8
|
expected_output_8 = 'MIG_msg_1006'
|
||||||
- MIG_msg_1007: 0x100008588'''
|
expected_output_9 = 'MIG_msg_1007'
|
||||||
assert expected_output in uroboros_output
|
|
||||||
|
assert expected_output_1 in uroboros_output
|
||||||
|
assert expected_output_2 in uroboros_output
|
||||||
|
assert expected_output_3 in uroboros_output
|
||||||
|
assert expected_output_4 in uroboros_output
|
||||||
|
assert expected_output_5 in uroboros_output
|
||||||
|
assert expected_output_6 in uroboros_output
|
||||||
|
assert expected_output_7 in uroboros_output
|
||||||
|
assert expected_output_8 in uroboros_output
|
||||||
|
assert expected_output_9 in uroboros_output
|
||||||
|
|
||||||
def test_has_suid(self):
|
def test_has_suid(self):
|
||||||
'''Test the --has_suid flag of SnakeVI.'''
|
'''Test the --has_suid flag of SnakeVI.'''
|
||||||
|
|||||||
Reference in New Issue
Block a user