Page 1 of 1

Usage examples of jtool

PostPosted: Sat Apr 13, 2013 9:11 pm
by Guest

I downloaded the jtool package, and would like some more information on how to use it, particularly the disassembly method?


Re: Usage examples of jtool

PostPosted: Sat Apr 13, 2013 9:27 pm
by morpheus
Absolutely. I've tried to make jtool as compatible as possible with the otool(1) use cases, though with different switches (e.g. -d disassembles, instead of -tV for otool). Additionally, there are many cases where jtool has options otool doesn't - naturally this means more switches. The jtool downloadable also contains a jtool.1, which is the (partial) man page explaining usage. As for your specific questions, i.e. disassembly:

Jtool contains its own disassembler - i.e. it doesn't use libopcodes, like gdb does. This is both good and bad. Bad, because I had to code everything from scratch, so not all opcodes are supported - yet. Good, because by doing so I also implemented a virtual machine for those opcodes which I do support. Including, to an extent, "decompilation", when it comes to function calls. Jtool traces the values of registers throughout instructions whenever possible, and recreates the C-style function call for known functions. These known functions are currently (but not for long) hard coded, and include kernel functions such as kernel_debug, panic, and PE_parse_boot_argn.

For example, with panic:

Code: Select all
Erudite:JTool morpheus$ ./jtool -d 0x80002000,10000000 ~/Documents/iOS/kernel.iOS6.0.1.iPod4 | grep "_panic" | more
Processing /Users/morpheus/Documents/iOS/kernel.iOS6.0.1.iPod4:
;  _panic(""%s[KERNEL]: %s"","(default pager): ","alloc pager thread");
800020b8        f015fdaa        BL    0x15b54           ; 0x80017c10 _panic
;  _panic(""%s[KERNEL]: %s"","(default pager): ","alloc thread buffer");
800020e8        f015fd92        BL    0x15b24           ; 0x80017c10 _panic
;  _panic(""%s[KERNEL]: %s"","(default pager): ","wire thread buffer");
80002120        f015fd76        BL    0x15aec           ; 0x80017c10 _panic
;  _panic(""can't start backing store monitor thread"");
800022f8        f015fc8a        BL    0x15914           ; 0x80017c10 _panic
;  _panic(""%s[KERNEL]: %s"","(default pager): ","default memory manager");
80002418        f015fbfa        BL    0x157f4           ; 0x80017c10 _panic
;  _panic(""bs_no_paging_space: NOT ENOUGH PAGING SPACE"");
80002618        f015fafa        BL    0x155f4           ; 0x80017c10 _panic
;  _panic(""backing_store_alloc: no memory"");
800028f8        f015f98a        BL    0x15314           ; 0x80017c10 _panic
;  _panic(""bs_get_global_cl_size:host_default_memory_manager"");
80002a96        f015f8bb        BL    0x15176           ; 0x80017c10 _panic
;  _panic(""bs_get_global_cl_size:there is another default pager"");
80002aac        f015f8b0        BL    0x15160           ; 0x80017c10 _panic
;  _panic(""backing_store_alloc: no memory"");

This is SUPER useful for reverse-engineering the kernel and symbolicating it, because you can quickly find notable functions by "grepping" their names - most of these functions panic at some point, with their name:

Code: Select all
Erudite:JTool morpheus$ ./jtool -d 0x800b2000,40000000 ~/Documents/iOS/kernel.iOS6.0.1.iPod4   | grep bsd_init
Processing /Users/morpheus/Documents/iOS/kernel.iOS6.0.1.iPod4:
-- 802b9656   4478       ADD   R0, PC            ; R0 += 802b965a = 0x802a55b1 "bsd_init: Failed to allocate kernel funnel"
;  _panic(""bsd_init: Failed to allocate kernel funnel"");
-- 802b9cc0   4478       ADD   R0, PC            ; R0 += 802b9cc4 = 0x802a55ef "bsd_init: Failed to allocate bsd pageable map"
;  _panic(""bsd_init: Failed to allocate bsd pageable map"");
-- 802b9cd2   4478       ADD   R0, PC            ; R0 += 802b9cd6 = 0x802a561f "bsd_init: Failed to create execve semaphore"
;  _panic(""bsd_init: Failed to create execve semaphore"");
-- 802b9ec2   4478       ADD   R0, PC            ; R0 += 802b9ec6 = 0x802a564d "bsd_init: cannot find root vnode: %s"
;  _panic(""bsd_init: cannot find root vnode: %s"","(null)");

So now you know the address range of 802b9xxx is part of bsd_init. This is where you'd probably use IDA to rename the subrountine, though Im hoping a future version of joker will do that, too, and automatically inject symbols.

Another example: If you're familiar with the pod2g boot-args script,for example, which takes the hard coded argument names and displays them - the same can be done with jtool like so:

Code: Select all
Erudite:JTool morpheus$ ./jtool -d 0x800b2000,40000000 ~/Documents/iOS/kernel.iOS6.0.1.iPod4   | grep PE_pa
Processing /Users/morpheus/Documents/iOS/kernel.iOS6.0.1.iPod4:
; R0 =  _PE_parse_boot_argn("ifa_debug",0x803195a0,4);
800d588a   f1a3fe8f   BL    0x1a3d1e          ; 0x802795ac _PE_parse_boot_argn
; R0 =  _PE_parse_boot_argn("net_affinity",0x802dddd4,4);
800d98ac   f19ffe7e   BL    0x19fcfc          ; 0x802795ac _PE_parse_boot_argn
; R0 =  _PE_parse_boot_argn("net_rxpoll",0x802dddd0,4);
800d98c6   f19ffe71   BL    0x19fce2          ; 0x802795ac _PE_parse_boot_argn
; R0 =  _PE_parse_boot_argn("net_rtref",0x802de1d0,4);
800d98e4   f19ffe62   BL    0x19fcc4          ; 0x802795ac _PE_parse_boot_argn
; R0 =  _PE_parse_boot_argn("ifnet_debug",0x802de650,4);
800d98f8   f19ffe58   BL    0x19fcb0          ; 0x802795ac _PE_parse_boot_argn

Which is way more useful, because it A) gives you the address where the boot_arg is in memory and B) where PE_parse_boot_argn was called from (again, leaking the function's true name when correlated with the open source version of XNU)