amd64-darwin.dylib hacking

modified:   p_mach.cpp
	modified:   p_mach.h
	modified:   p_mach_enum.h
	modified:   stub/src/amd64-darwin.dylib-entry.S

	modified:   stub/amd64-darwin.dylib-entry.h
	modified:   stub/tmp/amd64-darwin.dylib-entry.bin.dump
This commit is contained in:
John Reiser
2017-05-17 15:50:34 -07:00
parent 8eabb9b02f
commit ce194fa5d8
6 changed files with 924 additions and 957 deletions
File diff suppressed because it is too large Load Diff
+104 -78
View File
@@ -37,9 +37,10 @@
/*************************************************************************
// We have been CALLed as a subroutine from dyld; C-language rules apply.
// init(%edi=argc, %rsi=argv, %rdx=envp, %rcx=apple, %r8=...)
// -4*4+_start: .int32 offset(user_init_function)
// -3*4+_start: .int32 offset(&b_info of compressed Mach_headers)
// -2*4+_start: .int32 length(compressed __TEXT)
// -2*4+_start: .int32 segTEXT.vmsize
// -1*4+_start: .int32 total_length # of preceding bytes in file
**************************************************************************/
@@ -47,10 +48,15 @@ section MACHMAINX
_start: .globl _start
L100: pause; jmp L100 // FIXME
int3 // FIXME
push %rax // space for &user_init function
push $~0 // space for &user_init function
push %rdi; push %rsi; push %rdx; push %rcx; push %r8 // args
push %rbp // callee-save registers
push %rbx
call main // push &decompress
call main // push &escape
escape:
syscall
pop %rcx; pop %rdx; pop %rsi; pop %rdi
ret
/* Returns 0 on success; non-zero on failure. */
decompress: // (uchar const *src, size_t lsrc, uchar *dst, u32 &ldst, uint method)
@@ -187,7 +193,9 @@ end_decompress: .globl end_decompress
/* IDENTSTR goes here */
section MACHMAINZ
SYS_mmap = 0x02000000 + 197
SYS_mmap = 0x2000000 + 197
SYS_mprotect = 0x2000000 + 0x4a
SYS_munmap = 0x2000000 + 73
PAGE_SIZE= ( 1<<12)
sz_Mach_header= 7*4
@@ -212,54 +220,69 @@ PROT_WRITE= 2
PROT_EXEC= 4
main:
pop %rbp # &escape
// Get temp pages for compressed __TEXT and this stub
lea -1*4 + _start - escape(%rbp),%rbx
mov (%rbx),%eax; sub %rax,%rbx # our &Mach_header
mov -4*4 + _start - escape(%rbp),%edx # offset(user_init_fn)
add %rbx,%rdx; mov %rdx,7*8(%rsp) # reloc(user_init_fn)
mov -3*4 + _start - escape(%rbp),%edx # offset(b_info)
sub %edx,%eax; add %rbx,%rdx
sub $-4+ _start,%eax
add $ dy_top,%eax; push %rax # P_02 length(tmppag)
push %rdx # P_01 &b_info
xchg %eax,%arg2l # length
xor %arg6,%arg6 # 0 offset
or $~0,%arg5l # -1 fd
mov $MAP_ANON|MAP_PRIVATE,%sys4l
push $PROT_READ|PROT_WRITE; pop %arg3
xor %arg1l,%arg1l # 0 addr
mov $SYS_mmap,%eax; syscall; jc bad_mmap
// Copy compressed__TEXT and this stub to temp pages
pop %rsi # P_01 &b_info src
pop %rcx; push %rcx # P_02 length(tmppag)
push %rax # P_03 addr(tmppag)
push %rax; pop %rdi # dst
add %rcx,%rax # reloc(dy_top)
sub %rsi,%rbp
add %rdi,%rbp # reloc(&escape)
push %rdi # P_05 reloc(&b_info)
add $7,%ecx; shr $3,%ecx; rep movsq
pop %rcx # P_05 reloc(&b_info)
// Make temp pages executable, and go there
pop %arg1 # P_03 src (tmppag)
pop %arg2 # P_02 length(tmppag)
push $PROT_READ|PROT_EXEC; pop %arg3
push %arg2 # P_02 length(tmppag)
push %arg1 # P_03 src(tmppag)
push %rcx # P_06 reloc(&b_info)
push %rax # P_04 reloc(dy_top)
mov $SYS_mprotect,%eax; syscall; jc bad_mmap
pop %rax # P_04 reloc(dy_top)
add $dy_reloc - dy_top,%rax
jmp *%rax
bad_mmap:
hlt
jmp bad_mmap
main:
pop %rbp # &decompress
lea -4+ _start - decompress(%rbp),%rbx # &total_length
mov -1*4(%rbx),%eax # length(compressed __TEXT)
add $dy_top,%eax
sub $decompress,%eax
push %rax # length for eventual munmap
mov $0,%arg6l # offset
mov $0,%arg5l # fd
mov $MAP_ANON|MAP_PRIVATE,%sys4l
mov $PROT_READ|PROT_WRITE,%arg3l
mov %eax,%arg2l # length
sub %arg1l,%arg1l # 0 addr
mov $SYS_mmap,%eax
syscall
jc bad_mmap
push %rax # addr for eventual munmap
// Copy interval [decompress, dy_top).
mov %rbp,%rsi # decompressor
mov %rax,%rbp # new location
mov %rax,%rdi # dst for decompressor
mov $dy_top,%ecx
sub $decompress,%ecx
cld; rep movsb
// Goto the copied dy_reloc.
lea -(dy_top - dy_reloc)(%rdi),%rax
jmp *%rax
dy_reloc:
// Copy compressed __TEXT.
push %rdi # remember start of compressed __TEXT
mov %rbx,%rdx # &total_length
mov -4*4(%rbx),%eax # offset(user_init_function)
sub (%rbx),%edx # runtime base address
add %rdx,%rax; mov %rax,(1+2+2)*4(%rsp) # relocate &user_init_function
mov -2*4(%rbx),%esi; add %rdx,%rsi
mov -1*4(%rbx),%ecx
rep movsb
pop %rsi # &b_info for Mach_header
mov %rdx,%rdi # runtime base address
// Make __TEXT writeable
push %rbx; pop %arg1 # our &Mach_header
mov -2*4 + _start - escape(%rbp),%arg2l
push $PROT_READ|PROT_WRITE; pop %arg3
mov $SYS_mprotect,%eax; syscall; jc bad_mmap
pop %rsi # P_06 reloc(&b_info)
push %rbx; pop %rdi # our &Mach_header
add $decompress - escape,%rbp
// Decompress __TEXT, but do not overwrite Mach_headers
// in order to maintain consistency with dyld partial caching of them.
@@ -271,44 +294,47 @@ dy_uncpr:
push %rsi; push %rdi # save in case unfilter
lodsl; test %eax,%eax; jz dy_done
push %rax // sz_uncompressed (maximum dstlen for lzma)
mov %rsp,%arg4 // &dstlen
mov %rdi,%arg3 // dst
add %rdi,%rax; push %rax // next dst
lodsl; mov %eax,%arg2l // sz_compressed (srclen)
mov %rax,%rcx
lodsl; mov %eax,%arg5l // last 4 bytes of b_info
mov %rsi,%arg1 // &compressed __TEXT
add %rsi,%rcx; push %rcx // next src
push %rax // P_09 sz_unc (maximum dstlen for lzma)
mov %rsp,%arg4 // &dstlen (%rcx)
add %rdi,%rax; push %rax // P_07 next dst
lodsl; xchg %eax,%edx // sz_cpr (srclen)
lodsl; xchg %eax,%arg5l // last 4 bytes of b_info
lea (%rsi,%rdx),%rax; push %rax // P_08 next src
push %rdx // P_10 sz_cpr
mov %rdi,%arg3 // %rdx dst
mov %rsi,%arg1 // %rdi &compressed __TEXT
pop %arg2 // P_10 sz_cpr (srclen)
call *%rbp // decompress(1=rdi=src, 2=rsi=srclen, 3=rdx=dst, 4=rcx=&dstlen, 5=r8=b_info.misc)
pop %rsi // next src
pop %rdi // next dst
pop %rcx // dstlen (junk)
pop %rsi // P_08 next src
pop %rdi // P_07 next dst
pop %rcx // P_09 dstlen (junk)
pop %rdx; pop %rax # rdx= old dst; rax= old &b_info
movzbl 1+ b_method(%rax),%arg4l # ftid
test %arg4l,%arg4l; je dy_uncpr # no filter
movzbl 2+ b_method(%rax),%arg3l # cto8
#if 0
mov sz_unc(%rax),%arg2l
#else
// sz_unc == 0
mov (%rax),%arg2l
#endif
mov %rdx,%arg1 # dst
pop %rdi; pop %rcx # rdi= old dst; rcx= old &b_info
mov (%rcx),%esi # sz_unc
movzbl 2+ b_method(%rcx),%edx # cto8
movzbl 1+ b_method(%rcx),%ecx # ftid
test %ecx,%ecx; je dy_done
call f_unfilter # f_unfilter(1=rdi=dst, 2=rsi=dstlen, 3=rdx=cto8, 4=rcx=ftid)
jmp dy_uncpr
jmp dy_done
SYS_munmap= 0x02000000 + 73
dy_done:
pop %rax; pop %rcx # discard
mov $PAGE_SIZE,%arg2l // length for munmap
pop %arg1 // addr for munmap
pop %rbx; pop %rbp // saved registers
sz_Mach_header64 = 0x20
// Make __TEXT executable
push %rbx; pop %arg1 # our &Mach_header
mov escape - decompress(%rbp),%rax # 8 bytes of instructions
add $8+ 2*4 + sz_Mach_header64,%rbx # &segname[8] after "__TEXT\0\0"
mov %rax,(%rbx)
mov -2*4 + _start - decompress(%rbp),%arg2l
push $PROT_READ|PROT_EXEC; pop %arg3
mov $SYS_mprotect,%eax; syscall; jc bad_mmap
pop %arg1 # P_03 tmppag
pop %arg2 # P_02 len(tmppag)
mov $SYS_munmap,%eax
lea -4(%rdi),%rdx # steal some space at high end of __TEXT
movl $0x90c3050f,(%rdx) # syscall; ret; nop
jmp *%rdx
push %rbx; pop %rcx
pop %rbx; pop %rbp // saved registers
pop %r8
jmp *%rcx
#undef off
#undef len
+16 -18
View File
@@ -2,24 +2,24 @@ file format elf64-x86-64
Sections:
Idx Name Size VMA LMA File off Algn Flags
0 MACHMAINX 00000015 0000000000000000 0000000000000000 00000040 2**0 CONTENTS, RELOC, READONLY
1 NRV_HEAD 00000066 0000000000000000 0000000000000000 00000055 2**0 CONTENTS, READONLY
2 NRV2E 000000b7 0000000000000000 0000000000000000 000000bb 2**0 CONTENTS, RELOC, READONLY
3 NRV2D 0000009e 0000000000000000 0000000000000000 00000172 2**0 CONTENTS, RELOC, READONLY
4 NRV2B 00000090 0000000000000000 0000000000000000 00000210 2**0 CONTENTS, RELOC, READONLY
5 LZMA_ELF00 00000064 0000000000000000 0000000000000000 000002a0 2**0 CONTENTS, RELOC, READONLY
6 LZMA_DEC10 000009f7 0000000000000000 0000000000000000 00000304 2**0 CONTENTS, READONLY
7 LZMA_DEC20 000009f7 0000000000000000 0000000000000000 00000cfb 2**0 CONTENTS, READONLY
8 LZMA_DEC30 00000014 0000000000000000 0000000000000000 000016f2 2**0 CONTENTS, READONLY
9 NRV_TAIL 00000000 0000000000000000 0000000000000000 00001706 2**0 CONTENTS, READONLY
10 MACHMAINY 00000011 0000000000000000 0000000000000000 00001706 2**0 CONTENTS, READONLY
11 MACHMAINZ 0000012e 0000000000000000 0000000000000000 00001717 2**0 CONTENTS, RELOC, READONLY
0 MACHMAINX 00000023 0000000000000000 0000000000000000 00000040 2**0 CONTENTS, RELOC, READONLY
1 NRV_HEAD 00000066 0000000000000000 0000000000000000 00000063 2**0 CONTENTS, READONLY
2 NRV2E 000000b7 0000000000000000 0000000000000000 000000c9 2**0 CONTENTS, RELOC, READONLY
3 NRV2D 0000009e 0000000000000000 0000000000000000 00000180 2**0 CONTENTS, RELOC, READONLY
4 NRV2B 00000090 0000000000000000 0000000000000000 0000021e 2**0 CONTENTS, RELOC, READONLY
5 LZMA_ELF00 00000064 0000000000000000 0000000000000000 000002ae 2**0 CONTENTS, RELOC, READONLY
6 LZMA_DEC10 000009f7 0000000000000000 0000000000000000 00000312 2**0 CONTENTS, READONLY
7 LZMA_DEC20 000009f7 0000000000000000 0000000000000000 00000d09 2**0 CONTENTS, READONLY
8 LZMA_DEC30 00000014 0000000000000000 0000000000000000 00001700 2**0 CONTENTS, READONLY
9 NRV_TAIL 00000000 0000000000000000 0000000000000000 00001714 2**0 CONTENTS, READONLY
10 MACHMAINY 00000011 0000000000000000 0000000000000000 00001714 2**0 CONTENTS, READONLY
11 MACHMAINZ 00000163 0000000000000000 0000000000000000 00001725 2**0 CONTENTS, RELOC, READONLY
SYMBOL TABLE:
0000000000000000 l d MACHMAINX 0000000000000000 MACHMAINX
0000000000000000 l d NRV_HEAD 0000000000000000 NRV_HEAD
0000000000000000 l d LZMA_DEC30 0000000000000000 LZMA_DEC30
0000000000000000 l d MACHMAINY 0000000000000000 MACHMAINY
0000000000000000 l d MACHMAINZ 0000000000000000 MACHMAINZ
0000000000000000 l d MACHMAINX 0000000000000000 MACHMAINX
0000000000000000 l d NRV2E 0000000000000000 NRV2E
0000000000000000 l d NRV2D 0000000000000000 NRV2D
0000000000000000 l d NRV2B 0000000000000000 NRV2B
@@ -32,7 +32,7 @@ SYMBOL TABLE:
RELOCATION RECORDS FOR [MACHMAINX]:
OFFSET TYPE VALUE
0000000000000009 R_X86_64_PC32 MACHMAINZ+0xffffffffffffffff
0000000000000010 R_X86_64_PC32 MACHMAINZ+0xfffffffffffffffc
RELOCATION RECORDS FOR [NRV2E]:
OFFSET TYPE VALUE
@@ -55,7 +55,5 @@ OFFSET TYPE VALUE
RELOCATION RECORDS FOR [MACHMAINZ]:
OFFSET TYPE VALUE
000000000000000f R_X86_64_32 MACHMAINZ+0x000000000000012e
0000000000000014 R_X86_64_32 MACHMAINX+0x000000000000000d
0000000000000048 R_X86_64_32 MACHMAINZ+0x000000000000012e
000000000000004e R_X86_64_32 MACHMAINX+0x000000000000000d
0000000000000027 R_X86_64_32 _start+0xfffffffffffffffc
000000000000002c R_X86_64_32 MACHMAINZ+0x0000000000000163