The most up to date fork I have found of otx
is Cai's. I have tried the CLI interface of his v1.7: Build 566 release on macOS 10.11.6 and it runs fine for basic disassembly, albeit on invoking it using -o
to 'check the executable for obfuscation' against a little test code I wrote, it terminates with a
Terminating app due to uncaught exception
'NSInvalidArgumentException', reason: '-[X8664Processor
verifyNops:numFound:]: unrecognized selector sent to instance
0x7fb7e5806200'
In my opinion there are better suited tools available today to disassemble binaries on OSX, among which even otool
nowadays does not seem like it lacks functionality compared to otx
for ad-hoc disassembly.
Let's have a quick look by disassembling the section of a code which reads (essentially the 32bit version of 32-__builtin_clz(n)
):
static uint8_t f1_u32(uint32_t n) {
return n ? 1 + f1_u32(n/2) : 0;
}
Using otool -t -d -vV -j -q -H -P ./kk 2>/dev/null | grep -A24 "^_f1_u32:"
we get:
_f1_u32:
0000000100000de0 55 pushq %rbp
0000000100000de1 48 89 e5 movq %rsp, %rbp
0000000100000de4 48 83 ec 10 subq $0x10, %rsp
0000000100000de8 89 7d fc movl %edi, -0x4(%rbp)
0000000100000deb 83 7d fc 00 cmpl $0x0, -0x4(%rbp)
0000000100000def 0f 84 1b 00 00 00 je 0x100000e10
0000000100000df5 8b 45 fc movl -0x4(%rbp), %eax
0000000100000df8 c1 e8 01 shrl $0x1, %eax
0000000100000dfb 89 c7 movl %eax, %edi
0000000100000dfd e8 de ff ff ff callq _f1_u32
0000000100000e02 0f b6 f8 movzbl %al, %edi
0000000100000e05 83 c7 01 addl $0x1, %edi
0000000100000e08 89 7d f8 movl %edi, -0x8(%rbp)
0000000100000e0b e9 0a 00 00 00 jmp 0x100000e1a
0000000100000e10 31 c0 xorl %eax, %eax
0000000100000e12 89 45 f8 movl %eax, -0x8(%rbp)
0000000100000e15 e9 00 00 00 00 jmp 0x100000e1a
0000000100000e1a 8b 45 f8 movl -0x8(%rbp), %eax
0000000100000e1d 88 c1 movb %al, %cl
0000000100000e1f 0f b6 c1 movzbl %cl, %eax
0000000100000e22 48 83 c4 10 addq $0x10, %rsp
0000000100000e26 5d popq %rbp
0000000100000e27 c3 retq
0000000100000e28 0f 1f 84 00 00 00 00 00 nopl (%rax,%rax)
Using ./otx -d ./kk 2>/dev/null | grep -A26 "^_f1_u32:"
, this is the result:
_f1_u32:
+0 0000000100000de0 55 pushq %rbp
+1 0000000100000de1 4889e5 movq %rsp, %rbp
+4 0000000100000de4 4883ec10 subq $0x10, %rsp
+8 0000000100000de8 897dfc movl %edi, -0x4(%rbp)
+11 0000000100000deb 837dfc00 cmpl $0x0, -0x4(%rbp)
+15 0000000100000def 0f841b000000 je 0x100000e10
+21 0000000100000df5 8b45fc movl -0x4(%rbp), %eax
+24 0000000100000df8 c1e801 shrl $0x1, %eax
+27 0000000100000dfb 89c7 movl %eax, %edi
+29 0000000100000dfd e8deffffff callq _f1_u32
+34 0000000100000e02 0fb6f8 movzbl %al, %edi
+37 0000000100000e05 83c701 addl $0x1, %edi
+40 0000000100000e08 897df8 movl %edi, -0x8(%rbp)
+43 0000000100000e0b e90a000000 jmp 0x100000e1a Anon4
+48 0000000100000e10 31c0 xorl %eax, %eax
+50 0000000100000e12 8945f8 movl %eax, -0x8(%rbp)
+53 0000000100000e15 e900000000 jmp 0x100000e1a Anon4
Anon4:
+0 0000000100000e1a 8b45f8 movl -0x8(%rbp), %eax
+3 0000000100000e1d 88c1 movb %al, %cl
+5 0000000100000e1f 0fb6c1 movzbl %cl, %eax
+8 0000000100000e22 4883c410 addq $0x10, %rsp
+12 0000000100000e26 5d popq %rbp
+13 0000000100000e27 c3 retq
+14 0000000100000e28 0f1f840000000000 nopl (%rax,%rax)
Besides cosmetic differences, we actually get (and expect) very similar output.
Unbeknownst of your agenda, in recent times I have found myself using radare2 or the hopper GUI tool rather than fiddling with otool
or otx
when it comes to disassembly.
In hopper, you even get a decent pseudo code out of the disassembly (could be even better if hopper interpreted the & 0xff
as a hint towards an unsigned variable in this case):
int _f1_u32(int arg0) {
var_4 = arg0;
if (var_4 != 0x0) {
var_8 = (_f1_u32(var_4 >> 0x1) & 0xff) + 0x1;
} else {
var_8 = 0x0;
}
rax = var_8 & 0xff;
return rax;
}