diff options
-rw-r--r-- | Makefile | 24 | ||||
-rw-r--r-- | generated/darwin-inject-asm.S | 8 | ||||
-rw-r--r-- | generated/manual-mach.inc.h | 565 | ||||
-rw-r--r-- | lib/darwin/execmem.c | 108 | ||||
-rw-r--r-- | lib/darwin/inject-asm-raw.c | 14 | ||||
-rw-r--r-- | lib/darwin/inject-asm-raw.order | 1 | ||||
-rw-r--r-- | lib/darwin/manual-syscall.h | 75 | ||||
-rwxr-xr-x | script/gen-manual-mach.sh | 13 |
8 files changed, 711 insertions, 97 deletions
@@ -86,20 +86,26 @@ out/libsubstitute.dylib: $(LIB_OBJS) # Did you know? With -Oz + -marm, Apple clang-600.0.56 actually generated # wrong code for the ARM version. It works with -Os and with newer clang. IACLANG := clang -Os -fno-stack-protector -dynamiclib -nostartfiles -nodefaultlibs -isysroot /dev/null -Ilib -fPIC -out/inject-asm-raw-x86_64.o: lib/darwin/inject-asm-raw.c Makefile - $(IACLANG) -arch x86_64 -o $@ $< -out/inject-asm-raw-i386.o: lib/darwin/inject-asm-raw.c Makefile - $(IACLANG) -arch i386 -o $@ $< -out/inject-asm-raw-arm.o: lib/darwin/inject-asm-raw.c Makefile - $(IACLANG) -arch armv7 -marm -o $@ $< -out/inject-asm-raw-arm64.o: lib/darwin/inject-asm-raw.c Makefile - $(IACLANG) -arch arm64 -o $@ $< +define define_iar +out/inject-asm-raw-$(1).o: lib/darwin/inject-asm-raw.c Makefile lib/darwin/manual-syscall.h lib/darwin/inject-asm-raw.order + $(IACLANG) -arch $(2) -Wl,-order_file,lib/darwin/inject-asm-raw.order -o $$@ $$< +endef +$(eval $(call define_iar,x86_64,x86_64)) +$(eval $(call define_iar,i386,i386)) +$(eval $(call define_iar,arm,armv7 -marm)) +$(eval $(call define_iar,arm64,arm64)) + IAR_BINS := out/inject-asm-raw-x86_64.bin out/inject-asm-raw-i386.bin out/inject-asm-raw-arm.bin out/inject-asm-raw-arm64.bin out/darwin-inject-asm.S: $(IAR_BINS) Makefile script/gen-inject-asm.sh ./script/gen-inject-asm.sh > $@ || rm -f $@ -generateds: out/darwin-inject-asm.S +generateds: generated/darwin-inject-asm.S +generated/darwin-inject-asm.S: out/darwin-inject-asm.S cp $< generated/ +generateds: generated/manual-mach.inc.h +generated/manual-mach.inc.h: ./script/gen-manual-mach.sh + ./script/gen-manual-mach.sh + out/%.bin: out/%.o Makefile segedit -extract __TEXT __text $@ $< diff --git a/generated/darwin-inject-asm.S b/generated/darwin-inject-asm.S index 34691f1..d710a3e 100644 --- a/generated/darwin-inject-asm.S +++ b/generated/darwin-inject-asm.S @@ -13,16 +13,16 @@ _inject_page_start: .align 2 .globl _inject_start_x86_64 _inject_start_x86_64: -.byte 0x55, 0x48, 0x89, 0xe5, 0x53, 0x50, 0x48, 0x89, 0xfb, 0xc7, 0x45, 0xf4, 0x00, 0x00, 0x00, 0x00, 0x48, 0x8d, 0x15, 0x32, 0x00, 0x00, 0x00, 0x48, 0x8d, 0x7d, 0xf4, 0x31, 0xf6, 0x48, 0x89, 0xd9, 0xff, 0x13, 0x8b, 0x7d, 0xf4, 0xff, 0x53, 0x08, 0x48, 0x8b, 0x4b, 0x30, 0xb8, 0x69, 0x01, 0x00, 0x02, 0x31, 0xff, 0x31, 0xf6, 0x31, 0xd2, 0x0f, 0x05, 0xb9, 0xad, 0x0b, 0x00, 0x00, 0x31, 0xc0, 0xff, 0xd1, 0x48, 0x83, 0xc4, 0x08, 0x5b, 0x5d, 0xc3, 0x55, 0x48, 0x89, 0xe5, 0x53, 0x50, 0x48, 0x89, 0xfb, 0x48, 0x8b, 0x7b, 0x28, 0x31, 0xf6, 0xff, 0x53, 0x10, 0x48, 0x85, 0xc0, 0x74, 0x1c, 0x48, 0x8d, 0x35, 0x49, 0x00, 0x00, 0x00, 0x48, 0x89, 0xc7, 0xff, 0x53, 0x18, 0x48, 0x85, 0xc0, 0x74, 0x0a, 0x48, 0x8d, 0x7b, 0x40, 0x48, 0x8b, 0x73, 0x38, 0xff, 0xd0, 0xb8, 0x24, 0x00, 0x00, 0x01, 0x31, 0xd2, 0x31, 0xc9, 0x48, 0x8b, 0x7b, 0x30, 0x31, 0xf6, 0x0f, 0x05, 0x48, 0x8b, 0x43, 0x20, 0x48, 0x81, 0xe3, 0x00, 0xf0, 0xff, 0xff, 0xbe, 0x00, 0x20, 0x00, 0x00, 0x48, 0x89, 0xdf, 0x48, 0x83, 0xc4, 0x08, 0x5b, 0x5d, 0xff, 0xe0, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x75, 0x62, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x69, 0x74, 0x00 +.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x48, 0x89, 0xe5, 0x53, 0x50, 0x48, 0x89, 0xfb, 0xc7, 0x45, 0xf4, 0x00, 0x00, 0x00, 0x00, 0x48, 0x8d, 0x15, 0x4f, 0x00, 0x00, 0x00, 0x48, 0x8d, 0x7d, 0xf4, 0x31, 0xf6, 0x48, 0x89, 0xd9, 0xff, 0x13, 0x8b, 0x7d, 0xf4, 0xff, 0x53, 0x08, 0x8b, 0x4b, 0x30, 0x31, 0xff, 0x31, 0xf6, 0x31, 0xd2, 0xe8, 0x14, 0x00, 0x00, 0x00, 0xb9, 0xad, 0x0b, 0x00, 0x00, 0x31, 0xc0, 0xff, 0xd1, 0x48, 0x83, 0xc4, 0x08, 0x5b, 0x5d, 0xc3, 0x90, 0x90, 0x90, 0x90, 0xb8, 0x69, 0x01, 0x00, 0x02, 0x49, 0x89, 0xca, 0x0f, 0x05, 0xc3, 0xb8, 0x24, 0x00, 0x00, 0x01, 0x49, 0x89, 0xca, 0x0f, 0x05, 0xc3, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x55, 0x48, 0x89, 0xe5, 0x53, 0x50, 0x48, 0x89, 0xfb, 0x48, 0x8b, 0x7b, 0x28, 0x31, 0xf6, 0xff, 0x53, 0x10, 0x48, 0x85, 0xc0, 0x74, 0x1c, 0x48, 0x8d, 0x35, 0x46, 0x00, 0x00, 0x00, 0x48, 0x89, 0xc7, 0xff, 0x53, 0x18, 0x48, 0x85, 0xc0, 0x74, 0x0a, 0x48, 0x8d, 0x7b, 0x40, 0x48, 0x8b, 0x73, 0x38, 0xff, 0xd0, 0x8b, 0x7b, 0x30, 0xe8, 0xb4, 0xff, 0xff, 0xff, 0x48, 0x8b, 0x43, 0x20, 0x48, 0x81, 0xe3, 0x00, 0xf0, 0xff, 0xff, 0xbe, 0x00, 0x20, 0x00, 0x00, 0x48, 0x89, 0xdf, 0x48, 0x83, 0xc4, 0x08, 0x5b, 0x5d, 0xff, 0xe0, 0x66, 0x66, 0x66, 0x66, 0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x75, 0x62, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x69, 0x74, 0x00 .align 2 .globl _inject_start_i386 _inject_start_i386: -.byte 0xe9, 0x25, 0x00, 0x00, 0x00, 0x55, 0x89, 0xe5, 0x81, 0xed, 0x00, 0x04, 0x00, 0x00, 0x8b, 0x54, 0x24, 0x08, 0x8b, 0x42, 0x10, 0x81, 0xe2, 0x00, 0xf0, 0xff, 0xff, 0x89, 0x55, 0x08, 0xc7, 0x45, 0x0c, 0x00, 0x20, 0x00, 0x00, 0x83, 0xc0, 0x03, 0xff, 0xe0, 0x55, 0x89, 0xe5, 0x56, 0x83, 0xec, 0x24, 0x89, 0xce, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x58, 0xc7, 0x45, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x89, 0x74, 0x24, 0x0c, 0x8d, 0x80, 0x65, 0x00, 0x00, 0x00, 0x89, 0x44, 0x24, 0x08, 0x8d, 0x45, 0xf8, 0x89, 0x04, 0x24, 0xc7, 0x44, 0x24, 0x04, 0x00, 0x00, 0x00, 0x00, 0xff, 0x16, 0x8b, 0x45, 0xf8, 0x89, 0x04, 0x24, 0xff, 0x56, 0x04, 0x8b, 0x46, 0x18, 0x89, 0x45, 0xf4, 0xb8, 0x69, 0x01, 0x00, 0x00, 0xff, 0x75, 0xf4, 0x6a, 0x00, 0x6a, 0x00, 0x6a, 0x00, 0x6a, 0x00, 0x89, 0xe1, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x81, 0xc2, 0x09, 0x00, 0x00, 0x00, 0x0f, 0x34, 0x83, 0xc4, 0x14, 0xb8, 0xad, 0x0b, 0x00, 0x00, 0xff, 0xd0, 0x83, 0xc4, 0x24, 0x5e, 0x5d, 0xc3, 0x55, 0x89, 0xe5, 0x57, 0x56, 0x83, 0xec, 0x10, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x8b, 0x75, 0x08, 0x8b, 0x46, 0x14, 0x89, 0x04, 0x24, 0xc7, 0x44, 0x24, 0x04, 0x00, 0x00, 0x00, 0x00, 0xff, 0x56, 0x08, 0x85, 0xc0, 0x74, 0x23, 0x8d, 0x8f, 0x70, 0x00, 0x00, 0x00, 0x89, 0x4c, 0x24, 0x04, 0x89, 0x04, 0x24, 0xff, 0x56, 0x0c, 0x85, 0xc0, 0x74, 0x0f, 0x8d, 0x4e, 0x20, 0x8b, 0x56, 0x1c, 0x89, 0x54, 0x24, 0x04, 0x89, 0x0c, 0x24, 0xff, 0xd0, 0x8b, 0x46, 0x18, 0x89, 0x45, 0xf4, 0xb8, 0xdc, 0xff, 0xff, 0xff, 0x6a, 0x00, 0x6a, 0x00, 0x6a, 0x00, 0xff, 0x75, 0xf4, 0x6a, 0x00, 0x89, 0xe1, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x81, 0xc2, 0x09, 0x00, 0x00, 0x00, 0x0f, 0x34, 0x83, 0xc4, 0x14, 0x83, 0xc4, 0x10, 0x5e, 0x5f, 0x5d, 0xe9, 0xeb, 0xfe, 0xff, 0xff, 0x73, 0x75, 0x62, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x69, 0x74, 0x00 +.byte 0x55, 0x89, 0xe5, 0x56, 0x83, 0xec, 0x14, 0x89, 0xce, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x58, 0xc7, 0x45, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x89, 0x74, 0x24, 0x0c, 0x8d, 0x80, 0x98, 0x00, 0x00, 0x00, 0x89, 0x44, 0x24, 0x08, 0x8d, 0x45, 0xf8, 0x89, 0x04, 0x24, 0xc7, 0x44, 0x24, 0x04, 0x00, 0x00, 0x00, 0x00, 0xff, 0x16, 0x8b, 0x45, 0xf8, 0x89, 0x04, 0x24, 0xff, 0x56, 0x04, 0x8b, 0x46, 0x18, 0x89, 0x44, 0x24, 0x0c, 0xc7, 0x44, 0x24, 0x08, 0x00, 0x00, 0x00, 0x00, 0xc7, 0x44, 0x24, 0x04, 0x00, 0x00, 0x00, 0x00, 0xc7, 0x04, 0x24, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x00, 0x00, 0xb8, 0xad, 0x0b, 0x00, 0x00, 0xff, 0xd0, 0x83, 0xc4, 0x14, 0x5e, 0x5d, 0xc3, 0xb8, 0x69, 0x01, 0x00, 0x00, 0x5a, 0x89, 0xe1, 0x0f, 0x34, 0xb8, 0xdc, 0xff, 0xff, 0xff, 0x5a, 0x89, 0xe1, 0x0f, 0x34, 0x55, 0x89, 0xe5, 0x81, 0xed, 0x00, 0x04, 0x00, 0x00, 0x8b, 0x54, 0x24, 0x08, 0x8b, 0x42, 0x10, 0x81, 0xe2, 0x00, 0xf0, 0xff, 0xff, 0x89, 0x55, 0x08, 0xc7, 0x45, 0x0c, 0x00, 0x20, 0x00, 0x00, 0x83, 0xc0, 0x03, 0xff, 0xe0, 0x55, 0x89, 0xe5, 0x57, 0x56, 0x83, 0xec, 0x10, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x8b, 0x75, 0x08, 0x8b, 0x46, 0x14, 0x89, 0x04, 0x24, 0xc7, 0x44, 0x24, 0x04, 0x00, 0x00, 0x00, 0x00, 0xff, 0x56, 0x08, 0x85, 0xc0, 0x74, 0x23, 0x8d, 0x8f, 0x52, 0x00, 0x00, 0x00, 0x89, 0x4c, 0x24, 0x04, 0x89, 0x04, 0x24, 0xff, 0x56, 0x0c, 0x85, 0xc0, 0x74, 0x0f, 0x8d, 0x4e, 0x20, 0x8b, 0x56, 0x1c, 0x89, 0x54, 0x24, 0x04, 0x89, 0x0c, 0x24, 0xff, 0xd0, 0x8b, 0x46, 0x18, 0x89, 0x04, 0x24, 0xe8, 0x7d, 0xff, 0xff, 0xff, 0x83, 0xc4, 0x10, 0x5e, 0x5f, 0x5d, 0xe9, 0x7c, 0xff, 0xff, 0xff, 0x73, 0x75, 0x62, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x69, 0x74, 0x00 .align 2 .globl _inject_start_arm _inject_start_arm: -.byte 0x90, 0x40, 0x2d, 0xe9, 0x04, 0x70, 0x8d, 0xe2, 0x04, 0xd0, 0x4d, 0xe2, 0x44, 0x20, 0x00, 0xe3, 0x00, 0x40, 0xa0, 0xe1, 0x00, 0x00, 0xa0, 0xe3, 0x00, 0x20, 0x40, 0xe3, 0x00, 0x00, 0x8d, 0xe5, 0x02, 0x20, 0x8f, 0xe0, 0x00, 0x90, 0x94, 0xe5, 0x0d, 0x00, 0xa0, 0xe1, 0x00, 0x10, 0xa0, 0xe3, 0x04, 0x30, 0xa0, 0xe1, 0x39, 0xff, 0x2f, 0xe1, 0x04, 0x10, 0x94, 0xe5, 0x00, 0x00, 0x9d, 0xe5, 0x31, 0xff, 0x2f, 0xe1, 0x18, 0x30, 0x94, 0xe5, 0x69, 0xc1, 0x00, 0xe3, 0x00, 0x00, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3, 0x00, 0x20, 0xa0, 0xe3, 0x80, 0x00, 0x00, 0xef, 0xad, 0x0b, 0x00, 0xe3, 0x30, 0xff, 0x2f, 0xe1, 0x04, 0xd0, 0x47, 0xe2, 0x90, 0x80, 0xbd, 0xe8, 0x90, 0x40, 0x2d, 0xe9, 0x00, 0x40, 0xa0, 0xe1, 0x00, 0x10, 0xa0, 0xe3, 0x08, 0x20, 0x94, 0xe5, 0x04, 0x70, 0x8d, 0xe2, 0x14, 0x00, 0x94, 0xe5, 0x32, 0xff, 0x2f, 0xe1, 0x00, 0x00, 0x50, 0xe3, 0x0a, 0x00, 0x00, 0x0a, 0x0c, 0x20, 0x94, 0xe5, 0x48, 0x10, 0x00, 0xe3, 0x00, 0x10, 0x40, 0xe3, 0x01, 0x10, 0x8f, 0xe0, 0x32, 0xff, 0x2f, 0xe1, 0x00, 0x20, 0xa0, 0xe1, 0x00, 0x00, 0x52, 0xe3, 0x02, 0x00, 0x00, 0x0a, 0x1c, 0x10, 0x94, 0xe5, 0x20, 0x00, 0x84, 0xe2, 0x32, 0xff, 0x2f, 0xe1, 0x18, 0x00, 0x94, 0xe5, 0x23, 0xc0, 0xe0, 0xe3, 0x00, 0x10, 0xa0, 0xe3, 0x00, 0x20, 0xa0, 0xe3, 0x00, 0x30, 0xa0, 0xe3, 0x80, 0x00, 0x00, 0xef, 0x10, 0x20, 0x94, 0xe5, 0x1f, 0x40, 0xcb, 0xe7, 0x02, 0x1a, 0xa0, 0xe3, 0x04, 0x00, 0xa0, 0xe1, 0x90, 0x40, 0xbd, 0xe8, 0x12, 0xff, 0x2f, 0xe1, 0x73, 0x75, 0x62, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x69, 0x74, 0x00 +.byte 0x90, 0x40, 0x2d, 0xe9, 0x04, 0x70, 0x8d, 0xe2, 0x04, 0xd0, 0x4d, 0xe2, 0x58, 0x20, 0x00, 0xe3, 0x00, 0x40, 0xa0, 0xe1, 0x00, 0x00, 0xa0, 0xe3, 0x00, 0x20, 0x40, 0xe3, 0x00, 0x00, 0x8d, 0xe5, 0x02, 0x20, 0x8f, 0xe0, 0x00, 0x90, 0x94, 0xe5, 0x0d, 0x00, 0xa0, 0xe1, 0x00, 0x10, 0xa0, 0xe3, 0x04, 0x30, 0xa0, 0xe1, 0x39, 0xff, 0x2f, 0xe1, 0x04, 0x10, 0x94, 0xe5, 0x00, 0x00, 0x9d, 0xe5, 0x31, 0xff, 0x2f, 0xe1, 0x18, 0x30, 0x94, 0xe5, 0x00, 0x00, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3, 0x00, 0x20, 0xa0, 0xe3, 0x03, 0x00, 0x00, 0xeb, 0xad, 0x0b, 0x00, 0xe3, 0x30, 0xff, 0x2f, 0xe1, 0x04, 0xd0, 0x47, 0xe2, 0x90, 0x80, 0xbd, 0xe8, 0x69, 0xc1, 0x00, 0xe3, 0x80, 0x00, 0x00, 0xef, 0x1e, 0xff, 0x2f, 0xe1, 0x23, 0xc0, 0xe0, 0xe3, 0x80, 0x00, 0x00, 0xef, 0x1e, 0xff, 0x2f, 0xe1, 0x90, 0x40, 0x2d, 0xe9, 0x00, 0x40, 0xa0, 0xe1, 0x00, 0x10, 0xa0, 0xe3, 0x08, 0x20, 0x94, 0xe5, 0x04, 0x70, 0x8d, 0xe2, 0x14, 0x00, 0x94, 0xe5, 0x32, 0xff, 0x2f, 0xe1, 0x00, 0x00, 0x50, 0xe3, 0x0a, 0x00, 0x00, 0x0a, 0x0c, 0x20, 0x94, 0xe5, 0x38, 0x10, 0x00, 0xe3, 0x00, 0x10, 0x40, 0xe3, 0x01, 0x10, 0x8f, 0xe0, 0x32, 0xff, 0x2f, 0xe1, 0x00, 0x20, 0xa0, 0xe1, 0x00, 0x00, 0x52, 0xe3, 0x02, 0x00, 0x00, 0x0a, 0x1c, 0x10, 0x94, 0xe5, 0x20, 0x00, 0x84, 0xe2, 0x32, 0xff, 0x2f, 0xe1, 0x18, 0x00, 0x94, 0xe5, 0xe6, 0xff, 0xff, 0xeb, 0x10, 0x20, 0x94, 0xe5, 0x1f, 0x40, 0xcb, 0xe7, 0x02, 0x1a, 0xa0, 0xe3, 0x04, 0x00, 0xa0, 0xe1, 0x90, 0x40, 0xbd, 0xe8, 0x12, 0xff, 0x2f, 0xe1, 0x73, 0x75, 0x62, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x69, 0x74, 0x00 .align 2 .globl _inject_start_arm64 _inject_start_arm64: -.byte 0xf4, 0x4f, 0xbe, 0xa9, 0xfd, 0x7b, 0x01, 0xa9, 0xfd, 0x43, 0x00, 0x91, 0xff, 0x43, 0x00, 0xd1, 0xf3, 0x03, 0x00, 0xaa, 0xff, 0x0f, 0x00, 0xb9, 0x68, 0x02, 0x40, 0xf9, 0x01, 0x00, 0x80, 0xd2, 0x82, 0x02, 0x00, 0x10, 0x1f, 0x20, 0x03, 0xd5, 0xe0, 0x33, 0x00, 0x91, 0xe3, 0x03, 0x13, 0xaa, 0x00, 0x01, 0x3f, 0xd6, 0x68, 0x06, 0x40, 0xf9, 0xe0, 0x0f, 0x40, 0xb9, 0x00, 0x01, 0x3f, 0xd6, 0x63, 0x1a, 0x40, 0xf9, 0x30, 0x2d, 0x80, 0xd2, 0x00, 0x00, 0x80, 0xd2, 0x01, 0x00, 0x80, 0xd2, 0x02, 0x00, 0x80, 0xd2, 0x01, 0x10, 0x00, 0xd4, 0xa8, 0x75, 0x81, 0xd2, 0x00, 0x01, 0x3f, 0xd6, 0xbf, 0x43, 0x00, 0xd1, 0xfd, 0x7b, 0x41, 0xa9, 0xf4, 0x4f, 0xc2, 0xa8, 0xc0, 0x03, 0x5f, 0xd6, 0xf4, 0x4f, 0xbe, 0xa9, 0xfd, 0x7b, 0x01, 0xa9, 0xfd, 0x43, 0x00, 0x91, 0xf3, 0x03, 0x00, 0xaa, 0x68, 0x0a, 0x40, 0xf9, 0x60, 0x16, 0x40, 0xf9, 0x01, 0x00, 0x80, 0x52, 0x00, 0x01, 0x3f, 0xd6, 0x40, 0x01, 0x00, 0xb4, 0x68, 0x0e, 0x40, 0xf9, 0x81, 0x02, 0x00, 0x10, 0x1f, 0x20, 0x03, 0xd5, 0x00, 0x01, 0x3f, 0xd6, 0xe8, 0x03, 0x00, 0xaa, 0x88, 0x00, 0x00, 0xb4, 0x60, 0x02, 0x01, 0x91, 0x61, 0x1e, 0x40, 0xf9, 0x00, 0x01, 0x3f, 0xd6, 0x01, 0x00, 0x80, 0xd2, 0x02, 0x00, 0x80, 0xd2, 0x03, 0x00, 0x80, 0xd2, 0x60, 0x1a, 0x40, 0xf9, 0x70, 0x04, 0x80, 0x92, 0x01, 0x10, 0x00, 0xd4, 0x60, 0xc6, 0x72, 0x92, 0x62, 0x12, 0x40, 0xf9, 0xe1, 0x03, 0x73, 0xb2, 0xfd, 0x7b, 0x41, 0xa9, 0xf4, 0x4f, 0xc2, 0xa8, 0x40, 0x00, 0x1f, 0xd6, 0x73, 0x75, 0x62, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x69, 0x74, 0x00 +.byte 0xf4, 0x4f, 0xbe, 0xa9, 0xfd, 0x7b, 0x01, 0xa9, 0xfd, 0x43, 0x00, 0x91, 0xff, 0x43, 0x00, 0xd1, 0xf3, 0x03, 0x00, 0xaa, 0xff, 0x0f, 0x00, 0xb9, 0x68, 0x02, 0x40, 0xf9, 0x01, 0x00, 0x80, 0xd2, 0x22, 0x03, 0x00, 0x10, 0x1f, 0x20, 0x03, 0xd5, 0xe0, 0x33, 0x00, 0x91, 0xe3, 0x03, 0x13, 0xaa, 0x00, 0x01, 0x3f, 0xd6, 0x68, 0x06, 0x40, 0xf9, 0xe0, 0x0f, 0x40, 0xb9, 0x00, 0x01, 0x3f, 0xd6, 0x63, 0x32, 0x40, 0xb9, 0x00, 0x00, 0x80, 0xd2, 0x01, 0x00, 0x80, 0xd2, 0x02, 0x00, 0x80, 0x52, 0x07, 0x00, 0x00, 0x94, 0xa8, 0x75, 0x81, 0xd2, 0x00, 0x01, 0x3f, 0xd6, 0xbf, 0x43, 0x00, 0xd1, 0xfd, 0x7b, 0x41, 0xa9, 0xf4, 0x4f, 0xc2, 0xa8, 0xc0, 0x03, 0x5f, 0xd6, 0x2c, 0x2d, 0x80, 0xd2, 0x01, 0x10, 0x00, 0xd4, 0xc0, 0x03, 0x5f, 0xd6, 0x6c, 0x04, 0x80, 0x92, 0x01, 0x10, 0x00, 0xd4, 0xc0, 0x03, 0x5f, 0xd6, 0xf4, 0x4f, 0xbe, 0xa9, 0xfd, 0x7b, 0x01, 0xa9, 0xfd, 0x43, 0x00, 0x91, 0xf3, 0x03, 0x00, 0xaa, 0x68, 0x0a, 0x40, 0xf9, 0x60, 0x16, 0x40, 0xf9, 0x01, 0x00, 0x80, 0x52, 0x00, 0x01, 0x3f, 0xd6, 0x40, 0x01, 0x00, 0xb4, 0x68, 0x0e, 0x40, 0xf9, 0x01, 0x02, 0x00, 0x10, 0x1f, 0x20, 0x03, 0xd5, 0x00, 0x01, 0x3f, 0xd6, 0xe8, 0x03, 0x00, 0xaa, 0x88, 0x00, 0x00, 0xb4, 0x60, 0x02, 0x01, 0x91, 0x61, 0x1e, 0x40, 0xf9, 0x00, 0x01, 0x3f, 0xd6, 0x60, 0x32, 0x40, 0xb9, 0xea, 0xff, 0xff, 0x97, 0x60, 0xc6, 0x72, 0x92, 0x62, 0x12, 0x40, 0xf9, 0xe1, 0x03, 0x73, 0xb2, 0xfd, 0x7b, 0x41, 0xa9, 0xf4, 0x4f, 0xc2, 0xa8, 0x40, 0x00, 0x1f, 0xd6, 0x73, 0x75, 0x62, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x69, 0x74, 0x00 diff --git a/generated/manual-mach.inc.h b/generated/manual-mach.inc.h new file mode 100644 index 0000000..ddf31bc --- /dev/null +++ b/generated/manual-mach.inc.h @@ -0,0 +1,565 @@ +/* + * IDENTIFICATION: + * stub generated Sun Feb 22 22:43:07 2015 + * with a MiG generated by bootstrap_cmds-91 + * OPTIONS: + */ +#define __MIG_check__Reply__thread_act_subsystem__ 1 + +#include <string.h> +#include <mach/ndr.h> +#include <mach/boolean.h> +#include <mach/kern_return.h> +#include <mach/notify.h> +#include <mach/mach_types.h> +#include <mach/message.h> +#include <mach/mig_errors.h> +#include <mach/port.h> + +/* BEGIN VOUCHER CODE */ + +#ifndef KERNEL +#if defined(__has_include) +#if __has_include(<mach/mig_voucher_support.h>) +#ifndef USING_VOUCHERS +#endif +#ifndef __VOUCHER_FORWARD_TYPE_DECLS__ +#define __VOUCHER_FORWARD_TYPE_DECLS__ +#ifdef __cplusplus +extern "C" { +#endif + extern boolean_t voucher_mach_msg_set(mach_msg_header_t *msg) __attribute__((weak_import)); +#ifdef __cplusplus +} +#endif +#endif // __VOUCHER_FORWARD_TYPE_DECLS__ +#endif // __has_include(<mach/mach_voucher_types.h>) +#endif // __has_include +#endif // !KERNEL + +/* END VOUCHER CODE */ + + + + +#ifndef mig_internal +#define mig_internal static __inline__ +#endif /* mig_internal */ + +#ifndef mig_external +#define mig_external +#endif /* mig_external */ + +#if !defined(__MigTypeCheck) && defined(TypeCheck) +#define __MigTypeCheck TypeCheck /* Legacy setting */ +#endif /* !defined(__MigTypeCheck) */ + +#if !defined(__MigKernelSpecificCode) && defined(_MIG_KERNEL_SPECIFIC_CODE_) +#define __MigKernelSpecificCode _MIG_KERNEL_SPECIFIC_CODE_ /* Legacy setting */ +#endif /* !defined(__MigKernelSpecificCode) */ + +#ifndef LimitCheck +#define LimitCheck 0 +#endif /* LimitCheck */ + +#ifndef min +#define min(a,b) ( ((a) < (b))? (a): (b) ) +#endif /* min */ + +#if !defined(_WALIGN_) +#define _WALIGN_(x) (((x) + 3) & ~3) +#endif /* !defined(_WALIGN_) */ + +#if !defined(_WALIGNSZ_) +#define _WALIGNSZ_(x) _WALIGN_(sizeof(x)) +#endif /* !defined(_WALIGNSZ_) */ + +#ifndef UseStaticTemplates +#define UseStaticTemplates 0 +#endif /* UseStaticTemplates */ + +#ifndef __MachMsgErrorWithTimeout +#define __MachMsgErrorWithTimeout(_R_) { \ + switch (_R_) { \ + case MACH_SEND_INVALID_DATA: \ + case MACH_SEND_INVALID_DEST: \ + case MACH_SEND_INVALID_HEADER: \ + mig_put_reply_port(InP->Head.msgh_reply_port); \ + break; \ + case MACH_SEND_TIMED_OUT: \ + case MACH_RCV_TIMED_OUT: \ + default: \ + mig_dealloc_reply_port(InP->Head.msgh_reply_port); \ + } \ +} +#endif /* __MachMsgErrorWithTimeout */ + +#ifndef __MachMsgErrorWithoutTimeout +#define __MachMsgErrorWithoutTimeout(_R_) { \ + switch (_R_) { \ + case MACH_SEND_INVALID_DATA: \ + case MACH_SEND_INVALID_DEST: \ + case MACH_SEND_INVALID_HEADER: \ + mig_put_reply_port(InP->Head.msgh_reply_port); \ + break; \ + default: \ + mig_dealloc_reply_port(InP->Head.msgh_reply_port); \ + } \ +} +#endif /* __MachMsgErrorWithoutTimeout */ + +#ifndef __DeclareSendRpc +#define __DeclareSendRpc(_NUM_, _NAME_) +#endif /* __DeclareSendRpc */ + +#ifndef __BeforeSendRpc +#define __BeforeSendRpc(_NUM_, _NAME_) +#endif /* __BeforeSendRpc */ + +#ifndef __AfterSendRpc +#define __AfterSendRpc(_NUM_, _NAME_) +#endif /* __AfterSendRpc */ + +#ifndef __DeclareSendSimple +#define __DeclareSendSimple(_NUM_, _NAME_) +#endif /* __DeclareSendSimple */ + +#ifndef __BeforeSendSimple +#define __BeforeSendSimple(_NUM_, _NAME_) +#endif /* __BeforeSendSimple */ + +#ifndef __AfterSendSimple +#define __AfterSendSimple(_NUM_, _NAME_) +#endif /* __AfterSendSimple */ + +#define msgh_request_port msgh_remote_port +#define msgh_reply_port msgh_local_port + + + + + +/* Routine thread_get_state */ +static kern_return_t manual_thread_get_state +( + thread_act_t target_act, + thread_state_flavor_t flavor, + thread_state_t old_state, + mach_msg_type_number_t *old_stateCnt +, mach_port_t reply_port) +{ + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + thread_state_flavor_t flavor; + mach_msg_type_number_t old_stateCnt; + } Request; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_msg_type_number_t old_stateCnt; + natural_t old_state[224]; + mach_msg_trailer_t trailer; + } Reply; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_msg_type_number_t old_stateCnt; + natural_t old_state[224]; + } __Reply; +#ifdef __MigPackStructs +#pragma pack() +#endif + /* + * typedef struct { + * mach_msg_header_t Head; + * NDR_record_t NDR; + * kern_return_t RetCode; + * } mig_reply_error_t; + */ + + union { + Request In; + Reply Out; + } Mess; + + Request *InP = &Mess.In; + Reply *Out0P = &Mess.Out; + + mach_msg_return_t msg_result; + +#ifdef __MIG_check__Reply__thread_get_state_t__defined + kern_return_t check_result; +#endif /* __MIG_check__Reply__thread_get_state_t__defined */ + + __DeclareSendRpc(3603, "thread_get_state") + + InP->NDR = NDR_record; + + InP->flavor = flavor; + + if (*old_stateCnt < 224) + InP->old_stateCnt = *old_stateCnt; + else + InP->old_stateCnt = 224; + + InP->Head.msgh_bits = + MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE); + /* msgh_size passed as argument */ + InP->Head.msgh_request_port = target_act; + InP->Head.msgh_reply_port = reply_port; + InP->Head.msgh_id = 3603; + +/* BEGIN VOUCHER CODE */ + +#ifdef USING_VOUCHERS + if (voucher_mach_msg_set != NULL) { + voucher_mach_msg_set(&InP->Head); + } +#endif // USING_VOUCHERS + +/* END VOUCHER CODE */ + + __BeforeSendRpc(3603, "thread_get_state") + msg_result = manual_mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, (mach_msg_size_t)sizeof(Request), (mach_msg_size_t)sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); + __AfterSendRpc(3603, "thread_get_state") + if (msg_result != MACH_MSG_SUCCESS) { + __MachMsgErrorWithoutTimeout(msg_result); + { return msg_result; } + } + + +#if defined(__MIG_check__Reply__thread_get_state_t__defined) + check_result = __MIG_check__Reply__thread_get_state_t((__Reply__thread_get_state_t *)Out0P); + if (check_result != MACH_MSG_SUCCESS) + { return check_result; } +#endif /* defined(__MIG_check__Reply__thread_get_state_t__defined) */ + + if (Out0P->old_stateCnt > *old_stateCnt) { + (void)manual_memcpy((char *) old_state, (const char *) Out0P->old_state, 4 * *old_stateCnt); + *old_stateCnt = Out0P->old_stateCnt; + { return MIG_ARRAY_TOO_LARGE; } + } + (void)manual_memcpy((char *) old_state, (const char *) Out0P->old_state, 4 * Out0P->old_stateCnt); + + *old_stateCnt = Out0P->old_stateCnt; + + return KERN_SUCCESS; +} + + + +/* Routine thread_set_state */ +static kern_return_t manual_thread_set_state +( + thread_act_t target_act, + thread_state_flavor_t flavor, + thread_state_t new_state, + mach_msg_type_number_t new_stateCnt +, mach_port_t reply_port) +{ + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + thread_state_flavor_t flavor; + mach_msg_type_number_t new_stateCnt; + natural_t new_state[224]; + } Request; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_msg_trailer_t trailer; + } Reply; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply; +#ifdef __MigPackStructs +#pragma pack() +#endif + /* + * typedef struct { + * mach_msg_header_t Head; + * NDR_record_t NDR; + * kern_return_t RetCode; + * } mig_reply_error_t; + */ + + union { + Request In; + Reply Out; + } Mess; + + Request *InP = &Mess.In; + Reply *Out0P = &Mess.Out; + + mach_msg_return_t msg_result; + unsigned int msgh_size; + +#ifdef __MIG_check__Reply__thread_set_state_t__defined + kern_return_t check_result; +#endif /* __MIG_check__Reply__thread_set_state_t__defined */ + + __DeclareSendRpc(3604, "thread_set_state") + + InP->NDR = NDR_record; + + InP->flavor = flavor; + + if (new_stateCnt > 224) { + { return MIG_ARRAY_TOO_LARGE; } + } + (void)manual_memcpy((char *) InP->new_state, (const char *) new_state, 4 * new_stateCnt); + + InP->new_stateCnt = new_stateCnt; + + msgh_size = (mach_msg_size_t)(sizeof(Request) - 896) + ((4 * new_stateCnt)); + InP->Head.msgh_bits = + MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE); + /* msgh_size passed as argument */ + InP->Head.msgh_request_port = target_act; + InP->Head.msgh_reply_port = reply_port; + InP->Head.msgh_id = 3604; + +/* BEGIN VOUCHER CODE */ + +#ifdef USING_VOUCHERS + if (voucher_mach_msg_set != NULL) { + voucher_mach_msg_set(&InP->Head); + } +#endif // USING_VOUCHERS + +/* END VOUCHER CODE */ + + __BeforeSendRpc(3604, "thread_set_state") + msg_result = manual_mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, msgh_size, (mach_msg_size_t)sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); + __AfterSendRpc(3604, "thread_set_state") + if (msg_result != MACH_MSG_SUCCESS) { + __MachMsgErrorWithoutTimeout(msg_result); + { return msg_result; } + } + + +#if defined(__MIG_check__Reply__thread_set_state_t__defined) + check_result = __MIG_check__Reply__thread_set_state_t((__Reply__thread_set_state_t *)Out0P); + if (check_result != MACH_MSG_SUCCESS) + { return check_result; } +#endif /* defined(__MIG_check__Reply__thread_set_state_t__defined) */ + + return KERN_SUCCESS; +} + + + +/* Routine mach_vm_remap */ +static kern_return_t manual_mach_vm_remap +( + vm_map_t target_task, + mach_vm_address_t *target_address, + mach_vm_size_t size, + mach_vm_offset_t mask, + int flags, + vm_map_t src_task, + mach_vm_address_t src_address, + boolean_t copy, + vm_prot_t *cur_protection, + vm_prot_t *max_protection, + vm_inherit_t inheritance +, mach_port_t reply_port) +{ + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t src_task; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_vm_address_t target_address; + mach_vm_size_t size; + mach_vm_offset_t mask; + int flags; + mach_vm_address_t src_address; + boolean_t copy; + vm_inherit_t inheritance; + } Request; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_vm_address_t target_address; + vm_prot_t cur_protection; + vm_prot_t max_protection; + mach_msg_trailer_t trailer; + } Reply; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_vm_address_t target_address; + vm_prot_t cur_protection; + vm_prot_t max_protection; + } __Reply; +#ifdef __MigPackStructs +#pragma pack() +#endif + /* + * typedef struct { + * mach_msg_header_t Head; + * NDR_record_t NDR; + * kern_return_t RetCode; + * } mig_reply_error_t; + */ + + union { + Request In; + Reply Out; + } Mess; + + Request *InP = &Mess.In; + Reply *Out0P = &Mess.Out; + + mach_msg_return_t msg_result; + +#ifdef __MIG_check__Reply__mach_vm_remap_t__defined + kern_return_t check_result; +#endif /* __MIG_check__Reply__mach_vm_remap_t__defined */ + + __DeclareSendRpc(4813, "mach_vm_remap") + +#if UseStaticTemplates + const static mach_msg_port_descriptor_t src_taskTemplate = { + /* name = */ MACH_PORT_NULL, + /* pad1 = */ 0, + /* pad2 = */ 0, + /* disp = */ 19, + /* type = */ MACH_MSG_PORT_DESCRIPTOR, + }; +#endif /* UseStaticTemplates */ + + InP->msgh_body.msgh_descriptor_count = 1; +#if UseStaticTemplates + InP->src_task = src_taskTemplate; + InP->src_task.name = src_task; +#else /* UseStaticTemplates */ + InP->src_task.name = src_task; + InP->src_task.disposition = 19; + InP->src_task.type = MACH_MSG_PORT_DESCRIPTOR; +#endif /* UseStaticTemplates */ + + InP->NDR = NDR_record; + + InP->target_address = *target_address; + + InP->size = size; + + InP->mask = mask; + + InP->flags = flags; + + InP->src_address = src_address; + + InP->copy = copy; + + InP->inheritance = inheritance; + + InP->Head.msgh_bits = MACH_MSGH_BITS_COMPLEX| + MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE); + /* msgh_size passed as argument */ + InP->Head.msgh_request_port = target_task; + InP->Head.msgh_reply_port = reply_port; + InP->Head.msgh_id = 4813; + +/* BEGIN VOUCHER CODE */ + +#ifdef USING_VOUCHERS + if (voucher_mach_msg_set != NULL) { + voucher_mach_msg_set(&InP->Head); + } +#endif // USING_VOUCHERS + +/* END VOUCHER CODE */ + + __BeforeSendRpc(4813, "mach_vm_remap") + msg_result = manual_mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, (mach_msg_size_t)sizeof(Request), (mach_msg_size_t)sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); + __AfterSendRpc(4813, "mach_vm_remap") + if (msg_result != MACH_MSG_SUCCESS) { + __MachMsgErrorWithoutTimeout(msg_result); + { return msg_result; } + } + + +#if defined(__MIG_check__Reply__mach_vm_remap_t__defined) + check_result = __MIG_check__Reply__mach_vm_remap_t((__Reply___kernelrpc_mach_vm_remap_t *)Out0P); + if (check_result != MACH_MSG_SUCCESS) + { return check_result; } +#endif /* defined(__MIG_check__Reply__mach_vm_remap_t__defined) */ + + *target_address = Out0P->target_address; + + *cur_protection = Out0P->cur_protection; + + *max_protection = Out0P->max_protection; + + return KERN_SUCCESS; +} + + + diff --git a/lib/darwin/execmem.c b/lib/darwin/execmem.c index d99e947..13c9ac5 100644 --- a/lib/darwin/execmem.c +++ b/lib/darwin/execmem.c @@ -4,11 +4,15 @@ #define _DARWIN_C_SOURCE #include "cbit/htab.h" #include "execmem.h" -/* #include "darwin/manual-syscall.h" */ +#include "darwin/manual-syscall.h" #include "darwin/mach-decls.h" #include "substitute.h" #include "substitute-internal.h" #include <mach/mach.h> +#ifndef __MigPackStructs +#error wtf +#endif +#include <mach/mig.h> #include <sys/mman.h> #include <sys/syscall.h> #include <errno.h> @@ -18,6 +22,30 @@ #include <signal.h> #include <pthread.h> +int manual_sigreturn(void *, int); +GEN_SYSCALL(sigreturn, 184); +__typeof__(mmap) manual_mmap; +GEN_SYSCALL(mmap, 197); +__typeof__(mprotect) manual_mprotect; +GEN_SYSCALL(mprotect, 74); +__typeof__(mach_msg) manual_mach_msg; +GEN_SYSCALL(mach_msg, -31); + +extern int __sigaction(int, struct __sigaction * __restrict, struct sigaction * __restrict); + +static void manual_memcpy(void *restrict dest, const void *src, size_t len) { + /* volatile to avoid compiler transformation to call to memcpy */ + volatile uint8_t *d8 = dest; + const uint8_t *s8 = src; + while (len--) + *d8++ = *s8++; +} + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-variable" +#include "../generated/manual-mach.inc.h" +#pragma GCC diagnostic pop + #define port_hash(portp) (*(portp)) #define port_eq(port1p, port2p) (*(port1p) == *(port2p)) #define port_null(portp) (*(portp) == MACH_PORT_NULL) @@ -101,20 +129,22 @@ static bool apply_one_pcp_with_state(native_thread_state *state, } static int apply_one_pcp(mach_port_t thread, execmem_pc_patch_callback callback, - void *ctx) { + void *ctx, mach_port_t reply_port) { native_thread_state state; mach_msg_type_number_t real_cnt = sizeof(state) / sizeof(int); mach_msg_type_number_t cnt = real_cnt; - kern_return_t kr = thread_get_state(thread, NATIVE_THREAD_STATE_FLAVOR, - (thread_state_t) &state, &cnt); + kern_return_t kr = manual_thread_get_state(thread, NATIVE_THREAD_STATE_FLAVOR, + (thread_state_t) &state, &cnt, + reply_port); if (kr == KERN_TERMINATED) return SUBSTITUTE_OK; if (kr || cnt != real_cnt) return SUBSTITUTE_ERR_ADJUSTING_THREADS;; if (apply_one_pcp_with_state(&state, callback, ctx)) { - kr = thread_set_state(thread, NATIVE_THREAD_STATE_FLAVOR, - (thread_state_t) &state, real_cnt); + kr = manual_thread_set_state(thread, NATIVE_THREAD_STATE_FLAVOR, + (thread_state_t) &state, real_cnt, + reply_port); if (kr) return SUBSTITUTE_ERR_ADJUSTING_THREADS; } @@ -197,19 +227,23 @@ static void resume_other_threads() { htab_free_storage_mach_port_set(suspended_set); } -static void segfault_handler(UNUSED int sig, UNUSED siginfo_t *info, - void *uap_) { +/* note: unusual prototype since we are avoiding _sigtramp */ +static void segfault_handler(UNUSED void *func, int style, int sig, + UNUSED siginfo_t *sinfo, void *uap_) { + ucontext_t *uap = uap_; if (pthread_main_np()) { /* The patcher itself segfaulted. Oops. Reset the signal so the * process exits rather than going into an infinite loop. */ signal(sig, SIG_DFL); - return; + goto sigreturn; } /* We didn't catch it before it segfaulted so have to fix it up here. */ - ucontext_t *uap = uap_; apply_one_pcp_with_state(&uap->uc_mcontext->__ss, g_pc_patch_callback, g_pc_patch_callback_ctx); /* just let it continue, whatever */ +sigreturn: + if (manual_sigreturn(uap, style)) + abort(); } static int init_pc_patch(execmem_pc_patch_callback callback, void *ctx) { @@ -219,22 +253,23 @@ static int init_pc_patch(execmem_pc_patch_callback callback, void *ctx) { if ((ret = stop_other_threads())) return ret; - struct sigaction sa; + struct __sigaction sa; memset(&sa, 0, sizeof(sa)); - sa.sa_sigaction = segfault_handler; + sa.sa_sigaction = (void *) 0xdeadbeef; + sa.sa_tramp = segfault_handler; sigfillset(&sa.sa_mask); sa.sa_flags = SA_RESTART | SA_NODEFER | SA_SIGINFO; - if (sigaction(SIGSEGV, &sa, &old_segv)) + if (__sigaction(SIGSEGV, &sa, &old_segv)) return SUBSTITUTE_ERR_ADJUSTING_THREADS; - if (sigaction(SIGBUS, &sa, &old_bus)) { + if (__sigaction(SIGBUS, &sa, &old_bus)) { sigaction(SIGSEGV, &old_segv, NULL); return SUBSTITUTE_ERR_ADJUSTING_THREADS; } return SUBSTITUTE_OK; } -static int run_pc_patch() { +static int run_pc_patch(mach_port_t reply_port) { int ret; struct htab_mach_port_set *suspended_set = &g_suspended_ports.h; @@ -242,7 +277,7 @@ static int run_pc_patch() { UNUSED struct empty *_, mach_port_set) { if ((ret = apply_one_pcp(*threadp, g_pc_patch_callback, - g_pc_patch_callback_ctx))) + g_pc_patch_callback_ctx, reply_port))) return ret; } @@ -281,14 +316,6 @@ static kern_return_t get_page_prot(uintptr_t ptr, vm_prot_t *prot, return kr; } -static void manual_memcpy(void *restrict dest, const void *src, size_t len) { - /* volatile to avoid compiler transformation to call to memcpy */ - volatile uint8_t *d8 = dest; - const uint8_t *s8 = src; - while (len--) - *d8++ = *s8++; -} - int execmem_foreign_write_with_pc_patch(struct execmem_foreign_write *writes, size_t nwrites, execmem_pc_patch_callback callback, @@ -297,6 +324,9 @@ int execmem_foreign_write_with_pc_patch(struct execmem_foreign_write *writes, qsort(writes, nwrites, sizeof(*writes), compare_dsts); + mach_port_t task_self = mach_task_self(); + mach_port_t reply_port = mig_get_reply_port(); + if (callback) { /* Set the segfault handler - stopping all other threads before * doing so in case they were using it for something (this @@ -361,14 +391,18 @@ int execmem_foreign_write_with_pc_patch(struct execmem_foreign_write *writes, * new becomes the sole owner before actually writing. Though, for all * I know, these trips through the VM system could be slower than just * memcpying a page or two... */ - kr = vm_copy(mach_task_self(), page_start, len, (vm_address_t) new); + kr = vm_copy(task_self, page_start, len, (vm_address_t) new); if (kr) { ret = SUBSTITUTE_ERR_VM; goto fail_unmap; } - /* Disable access to the page so anyone trying to execute there - * will segfault. */ - if (mmap(NULL, len, PROT_NONE, MAP_ANON | MAP_SHARED, -1, 0) + /* Start of danger zone: between the mmap PROT_NONE and remap, we avoid + * using any standard library functions in case the user is trying to + * hook one of them. (This includes the mmap, since there's an epilog + * after the actual syscall instruction.) + * This includes the signal handler! */ + if (manual_mmap((void *) page_start, len, PROT_NONE, + MAP_ANON | MAP_SHARED | MAP_FIXED, -1, 0) == MAP_FAILED) { ret = SUBSTITUTE_ERR_VM; goto fail_unmap; @@ -389,25 +423,26 @@ int execmem_foreign_write_with_pc_patch(struct execmem_foreign_write *writes, * patched. (A call instruction within the affected region would * break this assumption, as then a thread could move to an * affected PC by returning. */ - if ((ret = run_pc_patch())) + if ((ret = run_pc_patch(reply_port))) goto fail_unmap; } /* Protect new like the original, and move it into place. */ vm_address_t target = page_start; - if (mprotect(new, len, prot)) { + if (manual_mprotect(new, len, prot)) { ret = SUBSTITUTE_ERR_VM; goto fail_unmap; } vm_prot_t c, m; - kr = vm_remap(mach_task_self(), &target, len, 0, VM_FLAGS_OVERWRITE, - mach_task_self(), (vm_address_t) new, /*copy*/ FALSE, - &c, &m, inherit); + printf("new=%p\n", new); + kr = manual_vm_remap(task_self, &target, len, 0, VM_FLAGS_OVERWRITE, + task_self, (vm_address_t) new, /*copy*/ FALSE, + &c, &m, inherit, reply_port); if (kr) { ret = SUBSTITUTE_ERR_VM; goto fail_unmap; } - /* ignore errors... */ + /* Danger zone over. Ignore errors when unmapping the temporary buffer. */ munmap(new, len); continue; @@ -426,8 +461,9 @@ fail: if (callback) { /* Other threads are no longer in danger of segfaulting, so put * back the old segfault handler. */ - if ((ret = finish_pc_patch())) - return ret; + int ret2; + if ((ret2 = finish_pc_patch())) + return ret2; } return ret; diff --git a/lib/darwin/inject-asm-raw.c b/lib/darwin/inject-asm-raw.c index ca316f1..55dab5f 100644 --- a/lib/darwin/inject-asm-raw.c +++ b/lib/darwin/inject-asm-raw.c @@ -1,3 +1,5 @@ +#define WANT_BSDTHREAD_TERMINATE +#define WANT_SEMAPHORE_WAIT_TRAP #include "darwin/manual-syscall.h" #ifdef __arm64__ @@ -6,6 +8,11 @@ #define _PAGE_SIZE 0x1000 #endif +int manual_bsdthread_terminate(void *, unsigned long, unsigned, unsigned); +GEN_SYSCALL(bsdthread_terminate, 361); +int manual_semaphore_wait_trap(int); +GEN_SYSCALL(semaphore_wait_trap, -36); + /* This is somewhat more complicated than it has to be because it does not use * pthread_join, which depends on pthread_self, which would need to be * initialized manually; the format of this has changed in the past, and could @@ -31,7 +38,7 @@ void entry(struct baton *baton) { int pt = 0; baton->pthread_create(&pt, 0, (void *) bsd_thread_func, baton); baton->pthread_detach(pt); - manual_syscall(361 /* bsdthread_terminate */, 0, 0, 0, baton->sem_port); + manual_bsdthread_terminate(0, 0, 0, baton->sem_port); ((void (*)()) 0xbad)(); } static int bsd_thread_func(void *arg) { @@ -45,7 +52,7 @@ static int bsd_thread_func(void *arg) { init(baton->shuttle, baton->nshuttle); } - manual_syscall(-36 /* semaphore_wait_trap */, baton->sem_port, 0, 0, 0); + manual_semaphore_wait_trap(baton->sem_port); #ifndef __i386__ /* since we're munmapping our own code, this must be optimized into a jump * (taill call elimination) */ @@ -61,8 +68,7 @@ static int bsd_thread_func(void *arg) { } #ifdef __i386__ /* yuck */ -asm("jmp _entry;" - ".globl _jump_to_munmap;" +asm(".globl _jump_to_munmap;" "_jump_to_munmap:" "push %ebp;" "mov %esp, %ebp;" diff --git a/lib/darwin/inject-asm-raw.order b/lib/darwin/inject-asm-raw.order new file mode 100644 index 0000000..faafe03 --- /dev/null +++ b/lib/darwin/inject-asm-raw.order @@ -0,0 +1 @@ +_entry diff --git a/lib/darwin/manual-syscall.h b/lib/darwin/manual-syscall.h index 9f04d2b..b1bac7e 100644 --- a/lib/darwin/manual-syscall.h +++ b/lib/darwin/manual-syscall.h @@ -1,54 +1,41 @@ #pragma once -#define REG(var, reg) register long _##var __asm__(#reg) = var -#define OREG(var, reg) register long var __asm__(#reg) +#define GEN_SYSCALL(name, num) \ + __asm__(".globl _manual_" #name "\n" \ + ".pushsection __TEXT,__text,regular,pure_instructions\n" \ + "_manual_" #name ":\n" \ + ".set num, " #num "\n" \ + GEN_SYSCALL_INNER() \ + ".popsection\n") -__attribute__((always_inline)) #if defined(__x86_64__) -static int manual_syscall(long s, long a, long b, long c, long d) { - if (s < 0) - s = -s | 1 << 24; - else - s |= 2 << 24; - REG(s, rax); REG(a, rdi); REG(b, rsi); REG(c, rdx); REG(d, rcx); - OREG(out, rax); - __asm__ volatile("syscall" - : "=r"(out) - : "r"(_s), "r"(_a), "r"(_b), "r"(_c), "r"(_d)); - return out; -} +/* Look at me, I'm different! */ +#define GEN_SYSCALL_INNER() \ + ".if num < 0\n" \ + "mov $(-num | 1 << 24), %eax\n" \ + ".else\n" \ + "mov $( num | 2 << 24), %eax\n" \ + ".endif\n" \ + "mov %rcx, %r10\n" \ + "syscall\n" \ + "ret\n" + #elif defined(__i386__) -static int manual_syscall(long s, long a, long b, long c, long d) { - REG(s, eax); - OREG(out, eax); - __asm__ volatile("push %5; push %4; push %3; push %2; push $0;" - "mov %%esp, %%ecx;" - "call 1f; 1: pop %%edx; add $(2f-1b), %%edx;" - "sysenter;" - "2: add $(5 * 4), %%esp" - : "=r"(out) - : "r"(_s), "g"(a), "g"(b), "g"(c), "g"(d) - : "edx", "ecx"); - return out; -} +#define GEN_SYSCALL_INNER() \ + "mov $num, %eax\n" \ + "pop %edx\n" \ + "mov %esp, %ecx\n" \ + "sysenter\n" #elif defined(__arm__) -static int manual_syscall(long s, long a, long b, long c, long d) { - REG(s, r12); REG(a, r0); REG(b, r1); REG(c, r2); REG(d, r3); - OREG(out, r0); - __asm__ volatile("svc #0x80" - : "=r"(out) - : "r"(_s), "r"(_a), "r"(_b), "r"(_c), "r"(_d)); - return out; -} +#define GEN_SYSCALL_INNER() \ + "mov r12, #num\n" \ + "svc #0x80\n" \ + "bx lr\n" #elif defined(__arm64__) -static int manual_syscall(long s, long a, long b, long c, long d) { - REG(s, x16); REG(a, x0); REG(b, x1); REG(c, x2); REG(d, x3); - OREG(out, x0); - __asm__ volatile("svc #0x80" - : "=r"(out) - : "r"(_s), "r"(_a), "r"(_b), "r"(_c), "r"(_d)); - return out; -} +#define GEN_SYSCALL_INNER() \ + "mov x12, #num\n" \ + "svc #0x80\n" \ + "ret\n" #else #error ? #endif diff --git a/script/gen-manual-mach.sh b/script/gen-manual-mach.sh new file mode 100755 index 0000000..02f7eda --- /dev/null +++ b/script/gen-manual-mach.sh @@ -0,0 +1,13 @@ +#!/bin/bash +out=generated/manual-mach.inc.h +(mig -user /dev/stdout -server /dev/null -header /dev/null /usr/include/mach/{thread_act,vm_map}.defs | + unifdef -U__MigTypeCheck | + grep -v '#define USING_VOUCHERS' | + sed -E 's/(mach_msg|memcpy)\(/manual_\1(/g; + s/^\)/, mach_port_t reply_port)/; + s/mig_external kern_return_t /static kern_return_t manual_/; + s/_kernelrpc_//; + s/mig_get_reply_port\(\)/reply_port/g' | + awk 'BEGIN { on = 1 } + /^\/\* Routine / { on = /thread_[gs]et_state|vm_remap/; } + on { print }' > $out) || rm -f $out |