Created
May 28, 2018 07:25
-
-
Save kam800/e1f1fa143257c733a20aea2974929ab8 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# This snippet shows how to enable dyld `closured` and how to fix `read` implementation in dyld using lldb. | |
# Following text is a bash/lldb command mix and it contains the relevant stdout content and my comments. | |
// `DYLD_PRINT_WARNINGS=1` environment variable will print dyld logs | |
$ DYLD_PRINT_WARNINGS=1 lldb /Users/kamil.borzym/tmp/TestMacApp.app/Contents/MacOS/TestMacApp | |
(lldb) process launch --stop-at-entry | |
(lldb) image list | |
[ 0] D355CCB5-8584-33E3-8DF7-7BA95BAD41AF 0x0000000100000000 /Users/kamil.borzym/tmp/TestMacApp.app/Contents/MacOS/TestMacApp | |
[ 1] AFAB4EFA-7020-34B1-BBEF-0F26C6D3CA36 0x000000010070d000 /usr/lib/dyld | |
// see the dyld base address -> 0x000000010070d000 | |
(lldb) image lookup -s dyld::sEnableClosures | |
1 symbols match 'dyld::sEnableClosures' in /usr/lib/dyld: | |
Address: dyld[0x000000000004dde8] (dyld.__DATA.__bss + 88) | |
Summary: dyld`dyld::sEnableClosures | |
// write '1' to dyld base address + dyld::sEnableClosures offset | |
(lldb) memory write --size 1 0x000000010070d000+0x000000000004dde8 1 | |
// now dyld::sEnableClosures == 1 | |
(lldb) breakpoint set --shlib dyld --name read --auto-continue true | |
Breakpoint 1: where = dyld`read, address = 0x000000010073e890 | |
// use `read` address -> 0x000000010073e890 to see assembly | |
(lldb) dis --address 0x000000010073e890 | |
dyld`read: | |
0x10073e890 <+0>: movl $0x2000003, %eax ; imm = 0x2000003 | |
0x10073e895 <+5>: movq %rcx, %r10 | |
0x10073e898 <+8>: syscall | |
0x10073e89a <+10>: jae 0x10073e8a4 ; <+20> | |
0x10073e89c <+12>: movq %rax, %rdi | |
0x10073e89f <+15>: jmp 0x10073da6d ; cerror | |
0x10073e8a4 <+20>: retq | |
0x10073e8a5 <+21>: nop | |
0x10073e8a6 <+22>: nop | |
0x10073e8a7 <+23>: nop | |
// `retq` instruction address -> 0x10073e8a4 | |
// declare variables used in breakpoint command script | |
(lldb) expr int $fd; | |
(lldb) expr unsigned long $buf; | |
(lldb) expr ssize_t $count; | |
(lldb) expr ssize_t $ret; | |
(lldb) expr ssize_t $partial; | |
(lldb) expr int $guard; | |
(lldb) breakpoint command add 1 | |
> expr $fd = $arg1 | |
> expr $buf = $arg2 | |
> expr $count = $arg3 | |
> expr $ret = 0 | |
> expr $guard = 4 | |
// invoke `read` in loop until all expected bytes are read or error occured too many times | |
> expr do { $partial = (ssize_t)read($fd, $buf, $count); if ($partial <= 0) { $guard -= 1; } else { $buf += $partial; $count -= $partial; $ret += $partial; } } while ($count > 0 && $guard >= 0) | |
> expr if ($guard <= 0) { $ret = -1 } | |
// set `read` return value as a sum off all nested `read` return values | |
> register write rax `$ret` | |
// quit from current `read` – jump to the `retq` instruction at the end of the `read` function | |
> register write rip 0x10073e8a4 | |
> DONE | |
(lldb) c | |
Process 86647 resuming | |
dyld: found closure 0x7fffd35c3d20 in dyld shared cache | |
dyld: closure 0x7fffd35c3d20 not used because current cache on disk and in memory cache have UUID mismatches | |
// voilà, all closured output has been read | |
dyld: closured return 0x10082e000 for /Users/kamil.borzym/tmp/TestMacApp.app/Contents/MacOS/TestMacApp |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment