Skip to content

Instantly share code, notes, and snippets.

@saagarjha
Created October 17, 2022 18:57
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save saagarjha/eab91784174cfb469f16618cd53c2876 to your computer and use it in GitHub Desktop.
Save saagarjha/eab91784174cfb469f16618cd53c2876 to your computer and use it in GitHub Desktop.
Some code I used to help write FB11698739. Very rough and posted as-is: don't copy things blindly from the internet, but that applies doubly so here!
// clang path_hook.mm -shared -ldl -g -framework Foundation path_hook.o -L/usr/lib/swift
#include <cassert>
#include <cstdint>
#include <dlfcn.h>
#include <mach/arm/vm_param.h>
#include <mach/kern_return.h>
#include <mach/mach_init.h>
#include <mach/vm_map.h>
#include <mach/vm_prot.h>
#include <sys/mman.h>
#include <os/log.h>
#include <Foundation/Foundation.h>
#include <unistd.h>
extern "C" {
extern const struct mach_header *_dyld_get_dlopen_image_header(void *handle);
[[noreturn]]
extern void *trampoline();
void logger(uint64_t tag, id string);
void setup();
};
__asm__ (
"_trampoline:\n"
"sub sp, sp, #0x20\n"
"stp x29, x30, [sp, #0x0]\n"
"stp x0, x1, [sp, #0x10]\n"
"bl _logger\n"
"ldp x29, x30, [sp, #0x0]\n"
"ldp x0, x1, [sp, #0x10]\n"
"add sp, sp, #0x20\n"
"sub sp, sp, #0x70\n"
"stp x28, x27, [sp, #0x10]\n"
"stp x26, x25, [sp, #0x20]\n"
"stp x24, x23, [sp, #0x30]\n"
"adrp x9, _function@PAGE\n"
"add x9, x9, _function@PAGEOFF\n"
"ldr x9, [x9]\n"
"br x9\n"
);
uintptr_t function;
__attribute__((constructor)) static void init() {
sleep(1);
setup();
auto handle = dlopen("/Applications/Xcode-beta.app/Contents/SharedFrameworks/XCBuild.framework/Versions/A/PlugIns/XCBBuildService.bundle/Contents/Frameworks/XCBUtil.framework/XCBUtil", RTLD_LAZY);
auto base = _dyld_get_dlopen_image_header(handle);
function = (uintptr_t)base + 0x0007e7fc;
os_log(OS_LOG_DEFAULT, "asdf done 1");
assert(vm_protect(mach_task_self(), function, PAGE_SIZE, false, VM_PROT_READ | VM_PROT_WRITE | VM_PROT_COPY) == KERN_SUCCESS);
memcpy((void *)function, "\x49\x00\xc0\xd2\x29\x01\x40\xf9\x20\x01\x1f\xd6", 12);
assert(vm_protect(mach_task_self(), function, PAGE_SIZE, false, VM_PROT_READ | VM_PROT_EXECUTE) == KERN_SUCCESS);
os_log(OS_LOG_DEFAULT, "asdf done 2");
auto ptr = mmap((void *)0x200000000, 0x4000, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0);
*(uintptr_t *)ptr = (uintptr_t)trampoline;
assert(ptr);
function += 12;
// assert(mprotect((void *)(function & ~0x4000), 0x400, PROT_READ | PROT_WRITE) == 0);
os_log(OS_LOG_DEFAULT, "asdf done 3");
}
// swiftc path_hook.swift -emit-object -g
import Foundation
import os
var counts: UnsafeMutablePointer<[String: Int]>!
var lock: UnsafeMutablePointer<os_unfair_lock>!
@_cdecl("setup")
func setup() {
counts = .allocate(capacity: 1)
counts.pointee = [:]
NSLog("asdf \(counts)")
lock = .allocate(capacity: 1)
}
@_silgen_name("logger")
func log(_ string: String) {
os_unfair_lock_lock(lock)
counts.pointee[string, default: 0] += 1
os_unfair_lock_unlock(lock)
// NSLog("asdf \(string)")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment