VIII. SANDBOX patch

This commit is contained in:
Karmaz95
2024-07-29 18:27:09 +02:00
parent 01721cfba4
commit d8038d85bb
7 changed files with 511 additions and 11 deletions
Binary file not shown.
+158
View File
@@ -0,0 +1,158 @@
_hook_iokit_check_get_property
_hook_iokit_check_filter_properties
_hook_vnode_notify_link
_hook_kext_check_unload
_hook_kext_check_load
_hook_pty_notify_close
_hook_pty_notify_grant
_hook_system_check_info
_hook_vnode_check_lookup_preflight
_hook_system_check_kas_info
_hook_vnode_notify_deleteextattr
_hook_vnode_check_setacl
_hook_vnode_notify_rename
_hook_vnode_notify_create
_hook_proc_check_ledger
_hook_iokit_check_open
_hook_vnode_check_fsgetpath
_hook_proc_check_map_anon
_hook_priv_grant
_hook_priv_check
_hook_vnode_check_searchfs
_hook_iokit_check_set_properties
___hook_iokit_check_set_properties_block_invoke
___hook_iokit_check_set_properties_block_invoke_2
_hook_thread_userret
_hook_proc_check_suspend_resume
_hook_vnode_check_uipc_connect
_hook_vnode_check_uipc_bind
_hook_vnode_label_recycle
_hook_vnode_label_destroy
_hook_vnode_label_copy
_hook_vnode_check_unlink
_hook_vnode_check_truncate
_hook_vnode_check_stat
_hook_vnode_check_setutimes
_hook_vnode_check_setowner
_hook_vnode_check_setmode
_hook_vnode_check_setflags
_hook_vnode_check_setextattr
_hook_vnode_check_setattrlist
_hook_vnode_check_revoke
_hook_vnode_check_readlink
_hook_vnode_check_open
_hook_vnode_check_listextattr
_hook_vnode_check_link
_hook_vnode_check_ioctl
_hook_vnode_check_getextattr
_hook_vnode_check_getattrlist
_hook_vnode_check_exchangedata
_hook_vnode_check_deleteextattr
_hook_vnode_check_create
_hook_vnode_check_chroot
_hook_vnode_check_access
_hook_iokit_check_hid_control
_hook_proc_check_set_cs_info
_hook_proc_check_get_cs_info
_hook_vnode_check_clone
_hook_mount_check_snapshot_delete
_hook_mount_check_snapshot_create
_hook_mount_check_snapshot_revert
_hook_proc_notify_exit
_hook_sysvshm_check_shmget
_hook_sysvshm_check_shmdt
_hook_sysvshm_check_shmctl
_hook_sysvshm_check_shmat
_hook_sysvsem_check_semop
_hook_sysvsem_check_semget
_hook_sysvsem_check_semctl
_hook_sysvmsq_check_msqsnd
_hook_sysvmsq_check_msqrcv
_hook_sysvmsq_check_msqget
_hook_sysvmsq_check_msqctl
_hook_sysvmsq_check_msgrmid
_hook_sysvmsq_check_msgrcv
_hook_sysvmsq_check_enqueue
_hook_socket_check_ioctl
_hook_system_check_swapon
_hook_system_check_swapoff
_hook_system_check_settime
_hook_system_check_reboot
_hook_system_check_nfsd
_hook_system_check_host_priv
_hook_system_check_auditon
_hook_system_check_auditctl
_hook_system_check_audit
_hook_system_check_acct
_hook_iokit_check_open_service
_hook_thread_microstackshot
_hook_proc_check_memorystatus_control
_hook_socket_check_getsockopt
_hook_socket_check_setsockopt
_hook_socket_check_send
_hook_socket_check_receive
_hook_socket_check_listen
_hook_socket_check_create
_hook_socket_check_connect
_hook_socket_check_bind
_hook_proc_check_signal
_hook_proc_check_setauid
_hook_proc_check_setaudit
_hook_proc_check_sched
_hook_proc_check_fork
_hook_proc_check_debug
_hook_posixshm_check_unlink
_hook_posixshm_check_open
_hook_posixshm_check_create
_hook_posixsem_check_wait
_hook_posixsem_check_unlink
_hook_posixsem_check_post
_hook_posixsem_check_open
_hook_posixsem_check_create
_hook_skywalk_flow_check_listen
_hook_skywalk_flow_check_connect
_hook_mount_check_snapshot_mount
_hook_mount_check_mount_late
_hook_vnode_check_trigger_resolve
_hook_proc_check_set_host_exception_port
_hook_proc_check_set_host_special_port
_hook_proc_check_syscall_unix
_hook_proc_notify_exec_complete
_hook_kext_check_query
_hook_vnode_check_rename
_hook_system_check_sysctlbyname
_hook_policy_syscall
_hook_policy_initbsd
_hook_policy_init
_hook_proc_check_migroutine_invoke
_hook_proc_check_syscall_mach
_hook_proc_check_syscall_mac
_hook_proc_check_get_task_with_flavor
_hook_proc_check_expose_task_with_flavor
_hook_mount_label_init
_hook_mount_label_destroy
_hook_mount_label_associate
_hook_mount_check_umount
_hook_mount_check_remount
_hook_mount_check_mount
_hook_mount_check_fsctl
_hook_mount_check_quotactl
_hook_vnode_check_copyfile
_hook_vnode_notify_unlink
_hook_proc_check_set_task_special_port
_hook_proc_check_get_task_special_port
_hook_vnode_notify_setflags
_hook_vnode_notify_setextattr
_hook_necp_check_client_action
_hook_necp_check_open
_hook_file_check_set
_hook_file_check_mmap
_hook_file_check_lock
_hook_file_check_fcntl
_hook_cred_label_update
_hook_cred_label_destroy
_hook_cred_label_associate
_hook_cred_check_label_update
_hook_vnode_check_exec
_hook_cred_check_label_update_execve
_hook_cred_label_update_execve
+333 -6
View File
@@ -97,7 +97,7 @@ class SnakeHatchery:
''' Initialize the binary object in global scope.'''
global binaries # It must be global, becuase after this object is destructed, the snake_instance would point to invalid memory ("binary" is dependant on "binaries").
if self.file_path_exists:
if self.file_path: # We cannot use here self.file_path_exists because at this point the file_path cpuld be set fron None to a valid path by filePathInit() method (when only -b specified)
adhoc_macho_processor = MachOProcessor() # Just for this limited scope
if adhoc_macho_processor.isFileMachO(self.file_path):
@@ -208,6 +208,14 @@ class BundleProcessor:
else:
return None
def getBundleId(self):
''' Return CFBundleIdentifier from Info.plist of the App Bundle. '''
if self.info_plist_exists:
with open(self.info_plist_path, 'rb') as f:
plist = plistlib.load(f)
return plist.get('CFBundleIdentifier')
return None
class SnakeAppBundleExtension:
def __init__(self, binaries, file_path):
''' It stores only logic for CrimsonUroboros flags. Most of the code related to parsing and extracting data from App Bundle is in BundleProcessor class.
@@ -248,6 +256,14 @@ class SnakeAppBundleExtension:
else:
print("No plugins found.")
def printBundleId(self):
''' Print the CFBundleIdentifier from Info.plist of the App Bundle. '''
bundle_id = bundle_processor.getBundleId()
if bundle_id:
print(bundle_id)
else:
print("No bundle id found.")
### --- I. MACH-O --- ###
class MachOProcessor:
def __init__(self):
@@ -384,6 +400,9 @@ class MachOProcessor:
if args.dump_section: # Dump section to a stdout
snake_instance.dumpSectionToStdout(args.dump_section)
if args.dump_binary: # Dump binary to a given file
snake_instance.dumpBinaryToFile(args.dump_binary)
def isFileMachO(self, file_path):
'''Check if file is Mach-O. '''
try:
@@ -695,12 +714,12 @@ class SnakeI(SnakeAppBundleExtension):
def getStringSection(self):
'''Return strings from the __cstring (string table).'''
extracted_strings = set()
extracted_strings = []
for section in self.binary.sections:
if section.type == lief.MachO.SECTION_TYPES.CSTRING_LITERALS:
strings_bytes = section.content.tobytes()
strings = strings_bytes.decode('utf-8', errors='ignore') # Adjust the encoding as per your requirements
extracted_strings.update(strings.split('\x00'))
strings = strings_bytes.decode('utf-8', errors='ignore')
extracted_strings.extend(strings.split('\x00'))
return extracted_strings
def findAllStringsInBinary(self):
@@ -914,7 +933,15 @@ class SnakeI(SnakeAppBundleExtension):
segment_name = segment_section[0]
section_name = segment_section[1]
extracted_bytes = self.extractSection(segment_name, section_name)
print(extracted_bytes)
sys.stdout.buffer.write(extracted_bytes)
def dumpBinaryToFile(self, output_path):
''' Dump ARM64 binary from FAT binary and save to a given file. '''
if binaries is not None:
if self.binary is not None:
if not output_path.startswith('/'):
output_path = os.path.join(os.getcwd(), output_path)
self.binary.write(output_path)
### --- II. CODE SIGNING --- ###
class CodeSigningProcessor:
@@ -2809,6 +2836,281 @@ class SnakeVII(SnakeVI):
value_as_bytes = value.encode()
xattr.setxattr(self.file_path, 'com.apple.quarantine', value_as_bytes)
### ---- VIII. SANDBOX --- ###
class SandboxProcessor:
def __init__(self):
'''This class contains part of the code from the main() for the SnakeVIII: Sandbox.'''
pass
def process(self, args):
if args.sandbox_container_path: # Print the sandbox container path
snake_instance.printSandboxContainerPath()
if args.sandbox_container_metadata: # Print the sandbox container metadata
snake_instance.printSandboxContainerMetadata()
if args.sandbox_redirectable_paths: # Print the sandbox redirectable paths
snake_instance.printSandboxRedirectablePaths()
if args.sandbox_parameters: # Print the sandbox parameters
snake_instance.printSandboxParameters()
if args.sandbox_entitlements: # Print the sandbox entitlements
snake_instance.printSandboxEntitlements()
if args.sandbox_build_uuid: # Print the sandbox build UUID
snake_instance.printSandboxBuildUUID()
if args.sandbox_redirected_paths: # Print the sandbox redirected paths
snake_instance.printSandboxRedirectedPaths()
if args.sandbox_system_images: # Print the sandbox system images
snake_instance.printSandboxSystemImages()
if args.sandbox_system_profiles: # Print the sandbox system profiles
snake_instance.printSandboxSystemProfiles()
if args.sandbox_content_protection: # Print the sandbox com.apple.MobileInstallation.ContentProtectionClass value
snake_instance.printContentProtectionClass()
if args.sandbox_profile_data: # Print the sandbox profile data
snake_instance.printSandboxProfileData()
if args.dump_kext: # Dump the kernel extension binary from the kernelcache.decompressed file
snake_instance.dumpKernelExtensionBinary(args.dump_kext)
if args.extract_sandbox_operations: # Extract sandbox operations from the kernelcache.decompressed file
snake_instance.printSandboxOperations()
class SnakeVIII(SnakeVII):
def __init__(self, binaries, file_path):
super().__init__(binaries, file_path)
self.kext_map.update({
'com.apple.security.sandbox' : 'sandbox',
'sandbox.kext' : 'sandbox',
})
self.container_metadata_file = ".com.apple.containermanagerd.metadata.plist"
def getSandboxContainerPath(self):
''' Check if sandbox container exists for the given App Bundle and if it exists, return the path to the container. '''
bundle_id = bundle_processor.getBundleId()
if bundle_id:
container_path = os.path.join(os.path.expanduser('~'), 'Library', 'Containers', bundle_id)
if os.path.exists(container_path):
return container_path
else:
print("Bundle id is not set in Info.plist for the given App Bundle.")
return None
def printSandboxContainerPath(self):
''' Print the sandbox container path. '''
container_path = self.getSandboxContainerPath()
if container_path:
print(f'APP BUNDLE SANDBOX CONTAINER: {container_path}')
else:
print("No sandbox container found for the given App Bundle.")
def getSandboxContainerMetadata(self):
''' Return the sandbox container metadata in XML format. '''
container_path = self.getSandboxContainerPath()
if container_path:
container_metadata_path = os.path.join(container_path, self.container_metadata_file)
if os.path.exists(container_metadata_path):
with open(container_metadata_path, 'rb') as f:
container_metadata = plistlib.load(f)
return container_metadata
return None
def printSandboxContainerMetadata(self):
''' Print the sandbox container metadata in XML format. '''
container_metadata = self.getSandboxContainerMetadata()
if container_metadata is None:
print("No sandbox container found for the given App Bundle.")
else:
container_metadata_xml = (plistlib.dumps(container_metadata, fmt=plistlib.FMT_XML).decode('utf-8'))
print(container_metadata_xml)
def getSandboxRedirectablePaths(self):
''' Return the redirectable paths as array. '''
container_metadata = self.getSandboxContainerMetadata()
if container_metadata:
redirectable_paths = container_metadata.get('MCMMetadataInfo', {}).get('SandboxProfileDataValidationInfo', {}).get('RedirectablePaths', [])
return redirectable_paths
return None
def printSandboxRedirectablePaths(self):
''' Print the redirectable paths. '''
redirectable_paths = self.getSandboxRedirectablePaths()
if redirectable_paths:
for path in redirectable_paths:
print(path)
else:
print("No redirectable paths found for the given App Bundle.")
def getSandboxParameters(self):
''' Return the sandbox parameters as dictionary. '''
container_metadata = self.getSandboxContainerMetadata()
if container_metadata:
parameters = container_metadata.get('MCMMetadataInfo', {}).get('SandboxProfileDataValidationInfo', {}).get('Parameters', {})
return parameters
return None
def printSandboxParameters(self):
''' Print the sandbox parameters as key-value pairs. '''
parameters = self.getSandboxParameters()
if parameters:
for parameter_key, parameter_value in parameters.items():
print(f"{parameter_key}: {parameter_value}")
else:
print("No sandbox parameters found for the given App Bundle.")
def getSandboxEntitlements(self):
''' Return the sandbox entitlements as dictionary. '''
container_metadata = self.getSandboxContainerMetadata()
if container_metadata:
entitlements = container_metadata.get('MCMMetadataInfo', {}).get('SandboxProfileDataValidationInfo', {}).get('Entitlements', {})
return entitlements
return None
def printSandboxEntitlements(self):
''' Print the sandbox entitlements as JSON. '''
entitlements = self.getSandboxEntitlements()
if entitlements:
print(json.dumps(entitlements, indent=4))
else:
print("No sandbox entitlements found for the given App Bundle.")
def getSandboxBuildUUID(self):
''' Return the sandbox build UUID as string. '''
container_metadata = self.getSandboxContainerMetadata()
if container_metadata:
build_uuid = container_metadata.get('MCMMetadataInfo', {}).get('SandboxProfileDataValidationInfo', {}).get('Sandbox_Build_UUID', '')
return build_uuid
return None
def printSandboxBuildUUID(self):
''' Print the sandbox build UUID as string. '''
build_uuid = self.getSandboxBuildUUID()
if build_uuid:
print(f"Build UUID: {build_uuid}")
else:
print("No sandbox build UUID found for the given App Bundle.")
def getSandboxRedirectedPaths(self):
''' Return the redirected paths as list. '''
container_metadata = self.getSandboxContainerMetadata()
if container_metadata:
redirected_paths = container_metadata.get('MCMMetadataInfo', {}).get('SandboxProfileDataValidationInfo', {}).get('RedirectedPaths', [])
return redirected_paths
return None
def printSandboxRedirectedPaths(self):
''' Print the redirected paths as dictionary. '''
redirected_paths = self.getRedirectedPaths()
if redirected_paths:
for path in redirected_paths:
print(path)
else:
print("No redirected paths found for the given App Bundle.")
def getSandboxSystemImages(self):
''' Return the system images as list. '''
container_metadata = self.getSandboxContainerMetadata()
if container_metadata:
system_images = container_metadata.get('MCMMetadataInfo', {}).get('SandboxProfileDataValidationInfo', {}).get('SystemImages', [])
return system_images
return None
def printSandboxSystemImages(self):
''' Print the system images as dictionary. '''
system_images = self.getSandboxSystemImages()
if system_images:
for path in system_images:
print(path)
else:
print("No system images found for the given App Bundle.")
def getSandboxSystemProfiles(self):
''' Return the system profiles as dict. '''
container_metadata = self.getSandboxContainerMetadata()
if container_metadata:
system_profiles = container_metadata.get('MCMMetadataInfo', {}).get('SandboxProfileDataValidationInfo', {}).get('SystemProfiles', {})
return system_profiles
return None
def printSandboxSystemProfiles(self):
''' Print the system profiles as JSON. '''
system_profiles = self.getSandboxSystemProfiles()
if system_profiles:
# Convert datetime to string for all profiles
for profile in system_profiles:
if 'AppSandboxProfileSnippetModificationDateKey' in profile:
profile['AppSandboxProfileSnippetModificationDateKey'] = profile['AppSandboxProfileSnippetModificationDateKey'].isoformat()
# Print all profiles as a single JSON object
print(json.dumps(system_profiles, indent=4))
else:
print("No system profiles found for the given App Bundle.")
def getContentProtectionClass(self):
'''Return the com.apple.MobileInstallation.ContentProtectionClass value'''
container_metadata = self.getSandboxContainerMetadata()
if container_metadata:
content_protection = container_metadata.get('MCMMetadataInfo', {}).get('com.apple.MobileInstallation.ContentProtectionClass')
return content_protection
return None
def printContentProtectionClass(self):
'''Print the com.apple.MobileInstallation.ContentProtectionClass value'''
content_protection = self.getContentProtectionClass()
if content_protection is not None:
print(f"com.apple.MobileInstallation.ContentProtectionClass: {content_protection}")
else:
print("No com.apple.MobileInstallation.ContentProtectionClass found for the given App Bundle.")
def getSandboxProfileData(self):
''' Return the sandbox profile data as bytes. '''
container_metadata = self.getSandboxContainerMetadata()
if container_metadata:
sandbox_profile_data = container_metadata.get('MCMMetadataInfo', {}).get('SandboxProfileData', None)
return sandbox_profile_data
return None
def printSandboxProfileData(self):
''' Print the sandbox profile data as bytes. '''
sandbox_profile_data = self.getSandboxProfileData()
if sandbox_profile_data:
sys.stdout.buffer.write(sandbox_profile_data)
else:
print("No SandboxProfileData found for the given App Bundle.")
def dumpKernelExtensionBinary(self, kext_name):
''' Dump the kernel extension binary from the kernelcache.decompressed file.
For now it is only wrapper arround ipsw'''
os.system(f"ipsw kernel extract {self.file_path} {kext_name}")
def extractSandboxOperations(self):
''' Extract sandbox operations from the Sandbox.kext file. '''
all_strings = self.getStringSection()
operations = []
capture = False
for string in all_strings:
if string == 'default':
capture = True
if capture:
operations.append(string)
if string == 'xpc-message-send':
capture = False
return operations
def printSandboxOperations(self):
'''Print the sandbox operations.'''
operations = self.extractSandboxOperations()
for operation in operations:
print(operation)
### --- ARGUMENT PARSER --- ###
class ArgumentParser:
@@ -2824,6 +3126,7 @@ class ArgumentParser:
self.addDyldArgs()
self.addAMFIArgs()
self.addAntivirusArgs()
self.addSandboxArgs()
def addGeneralArgs(self):
general_group = self.parser.add_argument_group('GENERAL ARGS')
@@ -2837,6 +3140,7 @@ class ArgumentParser:
bundle_group.add_argument('--bundle_info_syntax_check', action='store_true', help="Check if bundle info syntax is valid")
bundle_group.add_argument('--bundle_frameworks', action='store_true', help="Print the list of frameworks in the bundle")
bundle_group.add_argument('--bundle_plugins', action='store_true', help="Print the list of plugins in the bundle")
bundle_group.add_argument('--bundle_id', action='store_true', help="Print the CFBundleIdentifier value from the Info.plist file if it exists")
def addMachOArgs(self):
macho_group = self.parser.add_argument_group('MACH-O ARGS')
@@ -2867,6 +3171,7 @@ class ArgumentParser:
macho_group.add_argument('--calc_offset', help="Calculate the real address (file on disk) of the given Virtual Memory {vm_offset} (e.g. 0xfffffe000748f580)", metavar='vm_offset')
macho_group.add_argument('--constructors', action='store_true', help="Print binary constructors")
macho_group.add_argument('--dump_section', help="Dump '__SEGMENT,__section' to standard output as a raw bytes", metavar='__SEGMENT,__section')
macho_group.add_argument('--dump_binary', help="Dump arm64 binary to a given file", metavar='output_path')
def addCodeSignArgs(self):
codesign_group = self.parser.add_argument_group('CODE SIGNING ARGS')
@@ -2954,6 +3259,24 @@ class ArgumentParser:
antivirus_group.add_argument('--remove_quarantine', action='store_true', help="Remove com.apple.quarantine extended attribute from the file")
antivirus_group.add_argument('--add_quarantine', action='store_true', help="Add com.apple.quarantine extended attribute to the file")
def addSandboxArgs(self):
sandbox_group = self.parser.add_argument_group('SANDBOX ARGS')
sandbox_group.add_argument('--sandbox_container_path', action='store_true', help="todo")
sandbox_group.add_argument('--sandbox_container_metadata', action='store_true', help="Print the .com.apple.containermanagerd.metadata.plist contents for the given bundlein XML format")
sandbox_group.add_argument('--sandbox_redirectable_paths', action='store_true', help="Print the redirectable paths from the sandbox container metadata as list")
sandbox_group.add_argument('--sandbox_parameters', action='store_true', help="Print the parameters from the sandbox container metadata as key-value pairs")
sandbox_group.add_argument('--sandbox_entitlements', action='store_true', help="Print the entitlements from the sandbox container metadata in JSON format")
sandbox_group.add_argument('--sandbox_build_uuid', action='store_true', help="Print the sandbox build UUID from the sandbox container metadata")
sandbox_group.add_argument('--sandbox_redirected_paths', action='store_true', help="Print the redirected paths from the sandbox container metadata as list")
sandbox_group.add_argument('--sandbox_system_images', action='store_true', help="Print the system images from the sandbox container metadata as key-value pairs")
sandbox_group.add_argument('--sandbox_system_profiles', action='store_true', help="Print the system profile from the sandbox container metadata in JSON format")
sandbox_group.add_argument('--sandbox_content_protection', action='store_true', help="Print the content protection from the sandbox container metadata")
sandbox_group.add_argument('--sandbox_profile_data', action='store_true', help="Print raw bytes ofthe sandbox profile data from the sandbox container metadata")
sandbox_group.add_argument('--dump_kext', help="Dump the kernel extension binary from the kernelcache.decompressed file", metavar='kext_name')
sandbox_group.add_argument('--extract_sandbox_operations', action='store_true', help="Extract sandbox operations from the kernelcache.decompressed file")
def parseArgs(self):
args = self.parser.parse_args()
@@ -3324,7 +3647,7 @@ if __name__ == "__main__":
args = arg_parser.parseArgs()
### --- APP BUNDLE EXTENSION --- ###
snake_hatchery = SnakeHatchery(args, SnakeVII)
snake_hatchery = SnakeHatchery(args, SnakeVIII)
snake_hatchery.hatch()
### --- I. MACH-O --- ###
@@ -3354,3 +3677,7 @@ if __name__ == "__main__":
### --- VII. ANTIVIRUS --- ###
antivirus_processor = AntivirusProcessor()
antivirus_processor.process(args)
### --- VIII. SANDBOX --- ###
sandbox_processor = SandboxProcessor()
sandbox_processor.process(args)
+4 -2
View File
@@ -1,6 +1,7 @@
import os
import plistlib
import argparse
import base64
class SandboxInspector:
def __init__(self, home_dir):
@@ -71,7 +72,7 @@ def main():
parser.add_argument('-p', '--path', type=str, required=True, help="Path to the application (e.g., /Applications/Notes.app)")
parser.add_argument('-m', '--metadata', action='store_true', help="Print the .com.apple.containermanagerd.metadata.plist contents")
parser.add_argument('-r', '--redirectable', action='store_true', help="Print the redirectable paths")
parser.add_argument('-s', '--sandbox_profile_data', action='store_true', help="Print the SandboxProfileData bytes")
parser.add_argument('-s', '--sandbox_profile_data', action='store_true', help="Print the SandboxProfileData as base64-encoded bytes")
args = parser.parse_args()
app_path = args.path
@@ -103,7 +104,8 @@ def main():
sandbox_profile_data = inspector.get_sandbox_profile_data(bundle_id)
if sandbox_profile_data:
parsed_data = inspector.parse_sandbox_profile_data(sandbox_profile_data)
print(f"SandboxProfileData for {bundle_id}:\n{parsed_data}")
encoded_data = base64.b64encode(parsed_data).decode('utf-8')
print(f"SandboxProfileData for {bundle_id} (base64-encoded):\n{encoded_data}")
else:
print(f"No SandboxProfileData found for {bundle_id}.")
else:
+1 -1
View File
@@ -1 +1 @@
../App Bundle Extension/python/CrimsonUroboros.py
../VIII. Sandbox/python/CrimsonUroboros.py
+15 -2
View File
@@ -306,6 +306,9 @@ class TestSnakeI():
# Purge the compiled files
cls.compiler.purgeCompiledFiles()
assert not os.path.exists("hello_1") # Check if the file is removed after purging
os.remove("test_bin")
assert not os.path.exists("test_bin") # Check if the file is removed after purging
def test_MachOProcessor(self):
'''Test the initialization of MachOProcessor.
@@ -769,7 +772,15 @@ class TestSnakeI():
def test_dump_section(self):
'''Test the --dump_section flag of SnakeI.'''
args_list = ['-p', 'hello_1', '--dump_section', '__TEXT,__cstring']
uroboros_output = run_and_get_stdout('python3 CrimsonUroboros.py -p hello_1 --dump_section "__TEXT,__cstring"')
print(uroboros_output)
expected_output = 'Hello, World!'
assert expected_output in uroboros_output
def test_dump_binary(self):
'''Test the --dump_binary flag of SnakeI.'''
args_list = ['-p', 'hello_1', '--dump_binary', 'test_bin']
args = argumentWrapper(args_list)
snake_hatchery = SnakeHatchery(args, snake_class)
snake_hatchery.hatch()
@@ -779,9 +790,11 @@ class TestSnakeI():
macho_processor.process(args)
uroboros_output = executeCodeBlock(code_block)
expected_output = 'Hello, World!'
expected_output = ''
assert expected_output in uroboros_output
assert os.path.exists('test_bin')
assert run_and_get_stdout('file test_bin') == 'test_bin: Mach-O 64-bit executable arm64'
class TestSnakeII():
'''Testing II. CODE SIGNING'''