From ba7fdc92f2c354e3aac35c01d2c85237b04ab2e1 Mon Sep 17 00:00:00 2001 From: Karmaz95 Date: Sun, 11 Feb 2024 10:27:09 +0100 Subject: [PATCH] --- README.md | 1 + V. Dyld/custom/arg_printer.c | 22 +++++++++++++++++++ V. Dyld/python/CrimsonUroboros.py | 35 ++++++++++++++++++++++++++++--- tests/test_CrimsonUroboros.py | 4 +++- 4 files changed, 58 insertions(+), 4 deletions(-) create mode 100644 V. Dyld/custom/arg_printer.c diff --git a/README.md b/README.md index 4cb24dd..8c6d815 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ Each article directory contains three subdirectories: * ☐ [V. Dyld]() * ☑ [DYLD — Do You Like Death? (I)](https://karol-mazurek.medium.com/dyld-do-you-like-death-i-8199faad040e?sk=v2%2F359b081f-d944-409b-9e7c-95f7c171b969) * ☑ [DYLD — Do You Like Death? (II)](https://karol-mazurek.medium.com/dyld-do-you-like-death-ii-b74360b8af47?sk=v2%2Ff0cff71c-5345-4228-a639-653325fc979d) + * ☑ [DYLD — Do You Like Death? (III)](https://karol-mazurek.medium.com/dyld-do-you-like-death-iii-af77701a3034?sk=v2%2F06c92503-2db9-40e2-b139-c9ae0a35e7b3) ## TOOLS [CrimsonUroboros](#crimsonuroboros) • [MachOFileFinder](#machofilefinder) • [TrustCacheParser](#trustcacheparser) • [SignatureReader](#signaturereader) • [extract_cms.sh](#extract_cmssh) • [ModifyMachOFlags](#modifymachoflags) • [LCFinder](#lcfinder) • [MachODylibLoadCommandsFinder](#machodylibloadcommandsfinder) diff --git a/V. Dyld/custom/arg_printer.c b/V. Dyld/custom/arg_printer.c new file mode 100644 index 0000000..fd0ca3d --- /dev/null +++ b/V. Dyld/custom/arg_printer.c @@ -0,0 +1,22 @@ +#include + +int main(int argc, char *argv[], char *envp[], char *apple[]) { + printf("Argument count: %d\n", argc); + + printf("Standard arguments:\n"); + for (int i = 0; i < argc; i++) { + printf("Argument %d: %s\n", i, argv[i]); + } + + printf("Environment variables:\n"); + for (int i = 0; envp[i] != NULL; i++) { + printf("Environment Variable %d: %s\n", i, envp[i]); + } + + printf("Apple-specific arguments:\n"); + for (int i = 0; apple[i] != NULL; i++) { + printf("Apple Argument %d: %s\n", i, apple[i]); + } + + return 0; +} \ No newline at end of file diff --git a/V. Dyld/python/CrimsonUroboros.py b/V. Dyld/python/CrimsonUroboros.py index 2665f65..c34e790 100755 --- a/V. Dyld/python/CrimsonUroboros.py +++ b/V. Dyld/python/CrimsonUroboros.py @@ -64,7 +64,7 @@ class MachOProcessor: if args.symbols: # Print symbols for symbol in snake_instance.getSymbols(): - print(symbol.name) + print(f"0x{symbol.value:016X} {symbol.name}") if args.imported_symbols: snake_instance.printImportedSymbols() @@ -114,7 +114,7 @@ class MachOProcessor: print(section) print('\n<=== SYMBOLS ===>') for symbol in snake_instance.getSymbols(): - print(symbol.name) + print(f"{(symbol.name).ljust(32)} {hex(symbol.value)}") print('\n<=== STRINGS ===>') print('Strings from __cstring section:') print('-------------------------------') @@ -286,7 +286,9 @@ class SnakeI: extracted_strings = set() for section in self.binary.sections: if section.type == lief.MachO.SECTION_TYPES.CSTRING_LITERALS: - extracted_strings.update(section.content.tobytes().split(b'\x00')) + 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')) return extracted_strings def findAllStringsInBinary(self): @@ -1380,6 +1382,9 @@ class DyldProcessor: def process(self, args): if args.is_built_for_sim: # Check if binary is build for a simulator snake_instance.printIsBuiltForSimulator() + + if args.get_dyld_env: # Extract DYLD environment variables from the binary + snake_instance.printDyldEnv() class SnakeV(SnakeIV): def __init__(self, binaries, file_path): @@ -1431,6 +1436,29 @@ class SnakeV(SnakeIV): else: print(f'{name} platform is \033[94m{self.platforms[platform_value]}\033[0m\033[92m -> not built for simulator\033[0m') + def getDyldEnv(self): + '''Return a list of DYLD environment variables from the binary.''' + dyld_env = [] + strings_from_CSTRING = self.getStringSection() + for s in strings_from_CSTRING: + if s.startswith('DYLD_') and '/' not in s: + # Exclude DYLD_$ paths (that starts and ends with DYLD_) + if s.endswith('DYLD_'): + continue + # Remove spaces and all after the first occurrence of space + s = s.split(' ')[0].strip() + if s not in dyld_env: + dyld_env.append(s) + return dyld_env + + def printDyldEnv(self): + '''Print DYLD environment variables from the binary.''' + dyld_env = self.getDyldEnv() + if dyld_env: + print(*dyld_env, sep='\n') + else: + print("No DYLD environment variables found.") + ### --- ARGUMENT PARSER --- ### class ArgumentParser: def __init__(self): @@ -1516,6 +1544,7 @@ class ArgumentParser: def addDyldArgs(self): dyld_group = self.parser.add_argument_group('DYLD ARGS') dyld_group.add_argument('--is_built_for_sim', action='store_true', default=False, help="Check if binary is built for simulator platform.") + dyld_group.add_argument('--get_dyld_env', action='store_true', default=False, help="Extract Dyld-specific environment variables from the binary.") def parseArgs(self): diff --git a/tests/test_CrimsonUroboros.py b/tests/test_CrimsonUroboros.py index a3435eb..2879c77 100644 --- a/tests/test_CrimsonUroboros.py +++ b/tests/test_CrimsonUroboros.py @@ -465,9 +465,11 @@ class TestSnakeI(): macho_processor.process(args) uroboros_output = executeCodeBlock(code_block) - expected_output_1 = 'b\'Hello, World!' + expected_output_1 = 'Hello, World!' + expected_output_2 = '__cstring' assert expected_output_1 in uroboros_output + assert expected_output_2 in uroboros_output def test_all_strings(self): '''Test the --all_strings flag of SnakeI.'''