18 Commits
v0.3 ... v0.5

Author SHA1 Message Date
Karmaz95
d3b1e459ec 2024-02-18 22:34:40 +01:00
Karmaz95
d0d8b8a471 2024-02-18 22:32:36 +01:00
Karmaz95
13c8587f28 2024-02-18 21:58:01 +01:00
Karmaz95
ea0d485e57 2024-02-18 17:17:44 +01:00
Karmaz95
acaa13158b 2024-02-18 17:02:01 +01:00
Karmaz95
464f5317ae 2024-02-18 15:35:56 +01:00
Karmaz95
73bf3b3aa0 2024-02-18 13:25:12 +01:00
Karmaz95
ba7fdc92f2 2024-02-11 10:27:09 +01:00
Karmaz95
c8425c8430 2024-02-04 19:40:58 +01:00
Karmaz95
bf82224406 2024-02-04 19:39:27 +01:00
Karmaz95
c5c1aeef65 2024-02-03 09:24:09 +01:00
Karmaz95
6b614c778e 2024-01-18 13:44:03 +01:00
Karmaz95
c58ca4bed6 2024-01-18 13:12:03 +01:00
Karmaz95
9f67cfcf99 2024-01-18 13:10:23 +01:00
Karmaz95
61116a35ef 2024-01-17 13:46:14 +01:00
Karmaz95
367c1f3e21 2024-01-17 12:03:19 +01:00
Karmaz95
ada7094c2b 2024-01-17 12:00:56 +01:00
Karmaz95
3854f0f1b0 2024-01-07 14:16:20 +01:00
29 changed files with 18525 additions and 43 deletions

14
.gitignore vendored
View File

@@ -1,2 +1,14 @@
# Exclude .DS_Store files
**/.DS_Store
**/.vscode
# Exclude .vscode directory
**/.vscode/
# Exclude __pycache__ directories
__pycache__/
# Exclude pytest_cache directories
.pytest_cache/
# Exclude changes_release.md
changes_release.md

View File

@@ -1,3 +1,4 @@
// clang -fobjc-arc -framework Foundation example.m -o arc_example
#import <Foundation/Foundation.h>
@interface Person : NSObject

11
IV. Dylibs/custom/lib1.c Normal file
View File

@@ -0,0 +1,11 @@
//clang -dynamiclib lib1.c -o $PWD/lib1.dylib -L. -l2
#include <stdio.h>
#include "lib1.h"
#include "lib2.h"
void callLib1Function() {
printf("Now, wer are in lib1.dylib code.\n");
printf("Press enter to enter lib2.dylib function\n");
getchar();
callLib2Function();
}

7
IV. Dylibs/custom/lib1.h Normal file
View File

@@ -0,0 +1,7 @@
#ifndef LIB1_H
#define LIB1_H
void callLib1Function();
#endif

10
IV. Dylibs/custom/lib2.c Normal file
View File

@@ -0,0 +1,10 @@
//clang -dynamiclib lib2.c -o $PWD/lib2.dylib
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void callLib2Function() {
printf("Now we are in lib2.dylib.\n");
printf("Press enter to back to executable code...\n");
getchar();
}

7
IV. Dylibs/custom/lib2.h Normal file
View File

@@ -0,0 +1,7 @@
#ifndef LIB2_H
#define LIB2_H
void callLib2Function();
#endif

17
IV. Dylibs/custom/m.c Normal file
View File

@@ -0,0 +1,17 @@
// clang -dynamiclib m.c -o m.dylib //-o $PWD/TARGET_DYLIB
#include <syslog.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
__attribute__((constructor))
void myconstructor(int argc, const char **argv)
{
syslog(LOG_ERR, "[+] m.dylib injected in %s\n", argv[0]);
printf("[+] m.dylib injected in %s\n", argv[0]);
setuid(0);
system("id");
//system("/bin/sh");
}
void callLib1Function(void){}

15
IV. Dylibs/custom/main.c Normal file
View File

@@ -0,0 +1,15 @@
//clang main.c -o $PWD/executable -L. -l1
//codesign -s IDENTITY --option=runtime -f executable
#include <stdio.h>
#include "lib1.h"
int main() {
printf("Main program\n");
printf("Press enter to call lib1.dylib function...\n");
getchar();
callLib1Function();
printf("Press Enter to exit...\n");
getchar();
return 0;
}

View File

@@ -0,0 +1,6 @@
#include "mylib.h"
#include <stdio.h>
void myFunction() {
printf("Hello from mylib!\n");
}

View File

@@ -0,0 +1 @@
void my_function(); // Declare the function prototype

View File

@@ -0,0 +1,6 @@
#include "mylib.h"
int main() {
myFunction(); // Call the function from the library
return 0;
}

2537
IV. Dylibs/macos/Header.cpp Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

3250
IV. Dylibs/macos/Loader.cpp Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1590
IV. Dylibs/macos/loader.h Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,100 @@
#!/usr/bin/env python3
import os
import lief
class MachODylibLoadCommandsFinder:
'''
Recursively crawl the system and parse Mach-O files to find DYLIB related load commands.
1. Check if the file is a Mach-O.
2. List all Load Commands.
3. Check if any DYLIB-related LC exists.
LC_LOAD_DYLIB
LC_ID_DYLIB
LC_PREBOUND_DYLIB
LC_LOAD_WEAK_DYLIB
LC_REEXPORT_DYLIB
LC_LAZY_LOAD_DYLIB
LC_LOAD_UPWARD_DYLIB
LC_RPATH
4. Print the total Mach-O files analyzed and how many DYLIB-related LCs existed.
'''
def __init__(self):
self.total_files_analyzed = 0
self.binary_dylibs = {}
self.dylib_counts = {
"LC_LOAD_DYLIB" : 0,
"LC_ID_DYLIB": 0,
"LC_PREBOUND_DYLIB": 0,
"LC_LOAD_WEAK_DYLIB": 0,
"LC_REEXPORT_DYLIB": 0,
"LC_LAZY_LOAD_DYLIB": 0,
"LC_LOAD_UPWARD_DYLIB": 0,
"LC_RPATH": 0,
}
def parseDirectory(self, directory_path):
'''Recursively check if the path is a file. If it is, use checkIfMacho method.'''
for root, dirs, files in os.walk(directory_path):
for file in files:
file_path = os.path.join(root, file)
if os.path.isfile(file_path):
self.checkIfMacho(file_path)
def checkIfMacho(self, file_path):
binaries = lief.MachO.parse(file_path)
if binaries:
self.parseFatBinary(binaries, file_path)
def parseFatBinary(self, binaries, file_path):
for binary in binaries:
if binary.header.cpu_type == lief.MachO.CPU_TYPES.ARM64:
self.total_files_analyzed += 1
self.checkDylibLoadCommands(binary, file_path)
def checkDylibLoadCommands(self, binary, file_path):
dylib_related_lcs = {
lief.MachO.LOAD_COMMAND_TYPES.LOAD_DYLIB: "LC_LOAD_DYLIB",
lief.MachO.LOAD_COMMAND_TYPES.ID_DYLIB: "LC_ID_DYLIB",
lief.MachO.LOAD_COMMAND_TYPES.PREBOUND_DYLIB: "LC_PREBOUND_DYLIB",
lief.MachO.LOAD_COMMAND_TYPES.LOAD_WEAK_DYLIB: "LC_LOAD_WEAK_DYLIB",
lief.MachO.LOAD_COMMAND_TYPES.REEXPORT_DYLIB: "LC_REEXPORT_DYLIB",
lief.MachO.LOAD_COMMAND_TYPES.LAZY_LOAD_DYLIB: "LC_LAZY_LOAD_DYLIB",
lief.MachO.LOAD_COMMAND_TYPES.LOAD_UPWARD_DYLIB: "LC_LOAD_UPWARD_DYLIB",
lief.MachO.LOAD_COMMAND_TYPES.RPATH: "LC_RPATH",
}
binary_dylibs_set = set()
for cmd in binary.commands:
if cmd.command in dylib_related_lcs:
lc_name = dylib_related_lcs[cmd.command]
self.dylib_counts[lc_name] += 1
binary_dylibs_set.add(lc_name)
self.binary_dylibs[file_path] = binary_dylibs_set
def print_results(self):
print(f"Total Mach-O files analyzed: {self.total_files_analyzed}")
print("DYLIB-related LC counts:")
for lc, count in self.dylib_counts.items():
print(f"{lc}: {count}")
print("\nBinary Dylibs:")
for binary, dylibs in self.binary_dylibs.items():
print(f"{binary}: {dylibs}")
def save_results(self):
with open("MachODylibLoadCommandsFinder_results.txt", "a") as f:
f.write(f"Total Mach-O files analyzed: {self.total_files_analyzed}\n")
f.write("DYLIB-related LC counts:\n")
for lc, count in self.dylib_counts.items():
f.write(f"{lc}: {count}\n")
for binary, dylibs in self.binary_dylibs.items():
f.write(f"{binary}: {', '.join(dylibs)}\n")
macho_checker = MachODylibLoadCommandsFinder()
macho_checker.parseDirectory("/")
macho_checker.print_results()
macho_checker.save_results()

134
README.md
View File

@@ -1,4 +1,5 @@
# Snake & Apple
![alt](img/Snake_Apple.jpg)
The code repository for the `Snake&Apple` article series, which documents my research about macOS security.
Each article directory contains three subdirectories:
@@ -7,29 +8,34 @@ Each article directory contains three subdirectories:
* `python` - contains the latest CrimsonUroboros and other Python scripts created during research.
## ARTICLES
![alt](img/Snake_Apple.jpg)
* &#9745; [I. Mach-O](https://karol-mazurek95.medium.com/snake-apple-i-mach-o-a8eda4b87263?sk=v2%2Ffc1cbfa4-e2d4-4387-9a82-b27191978b5b)
* &#9745; [II. Code Signing](https://karol-mazurek95.medium.com/snake-apple-ii-code-signing-f0a9967b7f02?sk=v2%2Fbbc87007-89ca-4135-91d6-668b5d2fe9ae)
* &#9745; [III. Checksec](https://karol-mazurek95.medium.com/snake-apple-iii-checksec-ed64a4b766c1?sk=v2%2Fb4b8d637-e906-4b6b-8088-ca1f893cd787)
* &#9744; [IV. Dylibs]()
* &#9745; [IV. Dylibs](https://karol-mazurek.medium.com/snake-apple-iv-dylibs-2c955439b94e?sk=v2%2Fdef72b7a-121a-47a1-af89-7bf53aed1ea2)
* &#9744; [V. Dyld]()
* &#9745; [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)
* &#9745; [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)
* &#9745; [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)
* &#9745; [DYLD — Do You Like Death? (IV)](https://karol-mazurek.medium.com/dyld-do-you-like-death-iv-ede6b157752c?sk=v2%2F87ebe38d-004c-41a6-bc1f-43898494a512)
* &#9744; [DYLD — Do You Like Death? (V)]()
* &#9745; [V. Dyld](https://karol-mazurek.medium.com/snake-apple-v-dyld-8b36b674cc44?sk=v2%2F4acb16f8-fa88-41f0-8d7c-1362f4060010)
* &#9744; [VI. AMFI]()
## TOOLS
### [CrimsonUroboros](III.%20Checksec/python/CrimsonUroboros.py)
[CrimsonUroboros](#crimsonuroboros) • [MachOFileFinder](#machofilefinder) • [TrustCacheParser](#trustcacheparser) • [SignatureReader](#signaturereader) • [extract_cms.sh](#extract_cmssh) • [ModifyMachOFlags](#modifymachoflags) • [LCFinder](#lcfinder) • [MachODylibLoadCommandsFinder](#machodylibloadcommandsfinder)
***
### [CrimsonUroboros](tests/CrimsonUroboros.py)
![alt](img/CrimsonUroboros.jpg)
Core program resulting from the Snake&Apple article series for binary analysis. You may find older versions of this script in each article directory in this repository.
* Usage
```console
usage: CrimsonUroboros [-h] -p PATH [--file_type] [--header_flags] [--endian]
[--header] [--load_commands] [--segments] [--sections]
[--symbols] [--chained_fixups] [--exports_trie] [--uuid]
[--main] [--strings_section] [--all_strings]
[--save_strings all_strings.txt] [--info]
[--verify_signature] [--cd_info] [--cd_requirements]
[--entitlements [human|xml|var]]
[--extract_cms cms_signature.der]
[--extract_certificates certificate_name]
[--remove_sig unsigned_binary]
[--sign_binary [adhoc|identity_number]]
usage: CrimsonUroboros [-h] -p PATH [--file_type] [--header_flags] [--endian] [--header] [--load_commands] [--segments] [--sections] [--symbols] [--imported_symbols] [--chained_fixups] [--exports_trie] [--uuid] [--main] [--encryption_info [(optional) save_path.bytes]] [--strings_section] [--all_strings]
[--save_strings all_strings.txt] [--info] [--verify_signature] [--cd_info] [--cd_requirements] [--entitlements [human|xml|var]] [--extract_cms cms_signature.der] [--extract_certificates certificate_name] [--remove_sig unsigned_binary] [--sign_binary [adhoc|identity]] [--has_pie] [--has_arc]
[--is_stripped] [--has_canary] [--has_nx_stack] [--has_nx_heap] [--has_xn] [--is_notarized] [--is_encrypted] [--is_restricted] [--is_hr] [--is_as] [--is_fort] [--has_rpath] [--has_lv] [--checksec] [--dylibs] [--rpaths] [--rpaths_u] [--dylibs_paths] [--dylibs_paths_u]
[--broken_relative_paths] [--dylibtree [cache_path,output_path,is_extracted]] [--dylib_id] [--reexport_paths] [--hijack_sec] [--dylib_hijacking [(optional) cache_path]] [--dylib_hijacking_a [cache_path]] [--prepare_dylib [(optional) target_dylib_name]] [--is_built_for_sim] [--get_dyld_env]
[--compiled_with_dyld_env] [--has_interposing] [--interposing_symbols]
Mach-O files parser for binary analysis
@@ -46,40 +52,81 @@ MACH-O ARGS:
--segments Print binary segments in human-friendly form
--sections Print binary sections in human-friendly form
--symbols Print all binary symbols
--imported_symbols Print symbols imported from external libraries
--chained_fixups Print Chained Fixups information
--exports_trie Print Export Trie information
--uuid Print UUID
--main Print entry point and stack size
--encryption_info [(optional) save_path.bytes]
Print encryption info if any. Optionally specify an output path to dump the encrypted data (if cryptid=0, data will be in plain text)
--strings_section Print strings from __cstring section
--all_strings Print strings from all sections
--save_strings all_strings.txt
Parse all sections, detect strings, and save them to a
file
--info Print header, load commands, segments, sections,
symbols, and strings
Parse all sections, detect strings, and save them to a file
--info Print header, load commands, segments, sections, symbols, and strings
CODE SIGNING ARGS:
--verify_signature Code Signature verification (if the contents of the
binary have been modified)
--verify_signature Code Signature verification (if the contents of the binary have been modified)
--cd_info Print Code Signature information
--cd_requirements Print Code Signature Requirements
--entitlements [human|xml|var]
Print Entitlements in a human-readable, XML, or DER
format (default: human)
Print Entitlements in a human-readable, XML, or DER format (default: human)
--extract_cms cms_signature.der
Extract CMS Signature from the Code Signature and save
it to a given file
Extract CMS Signature from the Code Signature and save it to a given file
--extract_certificates certificate_name
Extract Certificates and save them to a given file. To
each filename will be added an index at the end: _0 for
signing, _1 for intermediate, and _2 for root CA
certificate
Extract Certificates and save them to a given file. To each filename will be added an index at the end: _0 for signing, _1 for intermediate, and _2 for root CA certificate
--remove_sig unsigned_binary
Save the new file on a disk with removed signature
--sign_binary [adhoc|identity_number]
Sign binary using specified identity - use : 'security
find-identity -v -p codesigning' to get the identity.
(default: adhoc)
--sign_binary [adhoc|identity]
Sign binary using specified identity - use : 'security find-identity -v -p codesigning' to get the identity (default: adhoc)
CHECKSEC ARGS:
--has_pie Check if Position-Independent Executable (PIE) is set
--has_arc Check if Automatic Reference Counting (ARC) is in use (can be false positive)
--is_stripped Check if binary is stripped
--has_canary Check if Stack Canary is in use (can be false positive)
--has_nx_stack Check if stack is non-executable (NX stack)
--has_nx_heap Check if heap is non-executable (NX heap)
--has_xn Check if binary is protected by eXecute Never (XN) ARM protection
--is_notarized Check if the application is notarized and can pass the Gatekeeper verification
--is_encrypted Check if the application is encrypted (has LC_ENCRYPTION_INFO(_64) and cryptid set to 1)
--is_restricted Check if binary has __RESTRICT segment or CS_RESTRICT flag set
--is_hr Check if the Hardened Runtime is in use
--is_as Check if the App Sandbox is in use
--is_fort Check if the binary is fortified
--has_rpath Check if the binary utilise any @rpath variables
--has_lv Check if the binary has Library Validation (protection against Dylib Hijacking)
--checksec Run all checksec module options on the binary
DYLIBS ARGS:
--dylibs Print shared libraries used by specified binary with compatibility and the current version (loading paths unresolved, like @rpath/example.dylib)
--rpaths Print all paths (resolved) that @rpath can be resolved to
--rpaths_u Print all paths (unresolved) that @rpath can be resolved to
--dylibs_paths Print absolute dylib loading paths (resolved @rpath|@executable_path|@loader_path) in order they are searched for
--dylibs_paths_u Print unresolved dylib loading paths.
--broken_relative_paths
Print 'broken' relative paths from the binary (cases where the dylib source is specified for an executable directory without @executable_path)
--dylibtree [cache_path,output_path,is_extracted]
Print the dynamic dependencies of a Mach-O binary recursively. You can specify the Dyld Shared Cache path in the first argument, the output directory as the 2nd argument, and if you have already extracted DSC in the 3rd argument (0 or 1). The output_path will be used as a base for
dylibtree. For example, to not extract DSC, use: --dylibs ",,1", or to extract from default to default use just --dylibs or --dylibs ",,0" which will extract DSC to extracted_dyld_share_cache/ in the current directory
--dylib_id Print path from LC_ID_DYLIB
--reexport_paths Print paths from LC_REEXPORT_DLIB
--hijack_sec Check if binary is protected against Dylib Hijacking
--dylib_hijacking [(optional) cache_path]
Check for possible Direct and Indirect Dylib Hijacking loading paths. The output is printed to console and saved in JSON format to /tmp/dylib_hijacking_log.json(append mode). Optionally, specify the path to the Dyld Shared Cache
--dylib_hijacking_a [cache_path]
Like --dylib_hijacking, but shows only possible vectors (without protected binaries)
--prepare_dylib [(optional) target_dylib_name]
Compile rogue dylib. Optionally, specify target_dylib_path, it will search for the imported symbols from it in the dylib specified in the --path argument and automatically add it to the source code of the rogue lib. Example: --path lib1.dylib --prepare_dylib /path/to/lib2.dylib
DYLD ARGS:
--is_built_for_sim Check if binary is built for simulator platform.
--get_dyld_env Extract Dyld environment variables from the loader binary.
--compiled_with_dyld_env
Check if binary was compiled with -dyld_env flag and print the environment variables and its values.
--has_interposing Check if binary has interposing sections.
--interposing_symbols
Print interposing symbols if any.
```
* Example:
```bash
@@ -212,17 +259,29 @@ LCFinder -l macho_paths.txt --lc SEGMENT_64 2>/dev/null
LCFinder -p hello --lc lc_segment_64 2>/dev/null
```
***
### [MachODylibLoadCommandsFinder](IV.%20Dylibs/python/MachODylibLoadCommandsFinder.py)
Designed to Recursively crawl the system and parse Mach-O files to find DYLIB related load commands.
Print the total Mach-O files analyzed and how many DYLIB-related LCs existed
* Usage:
```console
MachODylibLoadCommandsFinder 2>/dev/null
```
## INSTALL
```
pip -r requirements.txt
python3 -m pip install pyimg4
pip3 install -r requirements.txt
wget https://github.com/CRKatri/trustcache/releases/download/v2.0/trustcache_macos_arm64 -O /usr/local/bin/trustcache
chmod +x /usr/local/bin/trustcache
xattr -d com.apple.quarantine /usr/local/bin/trustcache
brew install keith/formulae/dyld-shared-cache-extractor
brew install blacktop/tap/ipsw
```
## LIMITATIONS
* Codesigning module(codesign wrapper) works only on macOS.
* `--dylib_hijacking` needs [ipsw](https://github.com/blacktop/ipsw) to be installed.
* `--dylibtree` needs the [dyld-shared-cache-extractor](https://github.com/keith/dyld-shared-cache-extractor) to be installed.
## WHY UROBOROS?
I will write the code for each article as a class SnakeX, where X will be the article number. To make it easier for the audience to follow. Each Snake class will be a child of the previous one and infinitely "eat itself" (inherit methods of the previous class), like Uroboros.
@@ -232,9 +291,12 @@ I will write the code for each article as a class SnakeX, where X will be the ar
* [XNU](https://github.com/apple-oss-distributions/xnu)
* [dyld](https://github.com/apple-oss-distributions/dyld)
## TODO
## TODO - IDEAS / IMPROVES
* DER Entitlements converter method - currently, only the `convert_xml_entitlements_to_dict()` method exists. I need to create a Python parser for DER-encoded entitlements.
* SuperBlob parser - to find other blobs in Code Signature.
* Entitlements Blob parser - to check if XML and DER blobs exist.
* Every method in the Snake class that use Entitlements should parse first XML > DER (currently, only XML parser exists)
* After making a SuperBlob parser and CodeDirectory blob parser, modify hasHardenedRuntime to check Runtime flag by using bitmask, instead of string.
* After making a SuperBlob parser and CodeDirectory blob parser, modify hasHardenedRuntime to check Runtime flag by using bitmask, instead of string.
* Build Dyld Shared Cache parser and extractor to make SnakeIV independant of dyld-shared-cache-extractor.
* Make testing branch and implement tests, before pushing new updates.
* Create `RottenApple.app` in another repository and use it for testing.

View File

@@ -0,0 +1,22 @@
#include <stdio.h>
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;
}

15
V. Dyld/custom/con_des.c Normal file
View File

@@ -0,0 +1,15 @@
#include <stdio.h>
#include <stdlib.h>
#include <syslog.h>
// Constructor
__attribute__((constructor)) void crimson_constructor() {
syslog(LOG_ERR, "[+] crimson_constructor called\n");
printf("[+] crimson_constructor called\n");
}
// Destructor
__attribute__((destructor)) void crimson_destructor() {
syslog(LOG_ERR, "[+] crimson_destructor called\n");
printf("[+] crimson_destructor called\n");
}

8
V. Dyld/custom/hello.c Normal file
View File

@@ -0,0 +1,8 @@
// clang -o hello hello.c
#include <stdio.h>
int main() {
printf("Hello!\n");
return 0;
}

View File

@@ -0,0 +1,22 @@
// clang -dynamiclib -o libinterpose.dylib interpose.c
#include <stdio.h>
// Define the interpose macro
#define DYLD_INTERPOSE(_replacement,_replacee) \
__attribute__((used)) static struct { \
const void* replacement; \
const void* replacee; \
} \
_interpose_##_replacee \
__attribute__ ((section ("__DATA,__interpose,interposing"))) = { \
(const void*)(unsigned long)&_replacement, \
(const void*)(unsigned long)&_replacee };
// Define the replacement function
int my_printf(const char *format, ...) {
int ret = printf("Hello from my_printf!\n");
return ret;
}
// Apply the interposing macro to replace printf with my_printf
DYLD_INTERPOSE(my_printf, printf)

View File

@@ -0,0 +1,63 @@
//g++ -std=c++11 lambda_capture_example.cpp -o lambda_capture_example
/*
This example demonstrates how lambda capture by reference [&] allows the lambda function to access and modify variables from the outer scope directly.
1. We have a function withWritableMemory that simulates the process of making memory writable, executing some work, and then restoring memory protection.
2. In the main function, we have variables x and y.
3. We define a lambda function lambda capturing all variables by reference [&]().
4. Inside the lambda, we modify the values of x and y.
5. We call withWritableMemory and pass the lambda as an argument.
6. The lambda is executed within the withWritableMemory function.
7. After the lambda execution, we print the values of x and y to see the changes made inside the lambda.
*/
#include <iostream>
void withWritableMemory(std::function<void()> work) {
std::cout << "Entering withWritableMemory function" << std::endl;
// Simulating the setup before making memory writable
std::cout << "Setting up memory..." << std::endl;
// Make memory writable
// Execute the provided work function
work();
// Restore memory protection
std::cout << "Restoring memory protection..." << std::endl;
std::cout << "Exiting withWritableMemory function" << std::endl;
}
int main() {
int x = 5;
int y = 3;
// Lambda function capturing all variables by reference
auto lambda = [&]() {
// Access and modify variables from the outer scope
x = x + 10;
y = y * 2;
std::cout << "Inside lambda: x = " << x << ", y = " << y << std::endl;
};
// Call the function with the lambda as an argument
withWritableMemory(lambda);
// After the lambda is executed
std::cout << "After lambda: x = " << x << ", y = " << y << std::endl;
return 0;
}
/*
./lambda_capture_example
Entering withWritableMemory function
Setting up memory...
Inside lambda: x = 15, y = 6
Restoring memory protection...
Exiting withWritableMemory function
After lambda: x = 15, y = 6
*/

View File

@@ -0,0 +1,26 @@
#include <stdbool.h>
#include <stdio.h>
int rosetta_dyld_is_translated(bool *is_translated);
// Pseudo implementation of SyscallDelegate::isTranslated
bool isTranslated() {
bool is_translated = false;
if (rosetta_dyld_is_translated(&is_translated) == 0) {
return is_translated;
}
return false;
}
// Mock implementation of rosetta_dyld_is_translated for demonstration purposes
// This function always sets is_translated to true using pointer - for the sake of the example
int rosetta_dyld_is_translated(bool *is_translated) {
*is_translated = true; // Simulated behavior: always set is_translated to true
return 0; // Return success
}
int main() {
bool translated = isTranslated();
printf("Is translated: %s\n", translated ? "true" : "false");
return 0;
}

1686
V. Dyld/python/CrimsonUroboros.py Executable file

File diff suppressed because it is too large Load Diff

View File

@@ -1,10 +1,7 @@
lief
uuid
argparse
subprocess
os
sys
asn1crypto
glob
shutil
pyimg4
pyimg4
treelib
xattr

1
tests/CrimsonUroboros.py Symbolic link
View File

@@ -0,0 +1 @@
../V. Dyld/python/CrimsonUroboros.py

File diff suppressed because it is too large Load Diff