[Help] Unknown function addresses in disassembly

Questions and Answers about all things *OS (macOS, iOS, tvOS, watchOS)

[Help] Unknown function addresses in disassembly

Postby acheronfail » Thu Jun 07, 2018 10:37 am

Hi all,

I'm just having an issue deciphering some disassembly I've found in a MachO binary, I have come across some procedures that just seem to be calling addresses that don't point to anything.
I feel like this place might be a good place to ask, since users here seem to have some experience disassembling macOS binaries.
I think some examples would help:

(Unfortunately, I can't use jtool for this since this is an Intel binary)

In the following examples, I want to know what the 0x1001d7ed0 is, namely what's being called at the address: 0x0000000100027e2d

Disassembly with otool:
Code: Select all
0000000100027e0e   movq   %rdi, %r14
0000000100027e11   xorl   %ebx, %ebx
0000000100027e13   leaq   -0x24(%rbp), %r15
0000000100027e17   movl   %ebx, (%r15)
0000000100027e1a   leaq   0x1b00af(%rip), %rax
0000000100027e21   movq   (%rax), %r12
0000000100027e24   leaq   0x1aff45(%rip), %rcx
0000000100027e2b   xorl   %eax, %eax
0000000100027e2d   callq   *(%rcx)                         ; <--- trying to find out what's called here


The same procedure, but using radare2 instead:
Code: Select all
0x100027e0e      4989fe         mov r14, rdi               ; moves data from src to dst
0x100027e11      31db           xor ebx, ebx               ; logical exclusive or
0x100027e13      4c8d7ddc       lea r15, [local_24h]       ; load effective address
0x100027e17      41891f         mov dword [r15], ebx       ; moves data from src to dst
0x100027e1a      488d05af001b.  lea rax, [0x1001d7ed0]     ; load effective address                              ; <-- what are these values? nothing at the address
0x100027e21      4c8b20         mov r12, qword [rax]       ; moves data from src to dst
0x100027e24      488d0d45ff1a.  lea rcx, [0x1001d7d70]     ; section.32.__DATA.__common ; load effective address ; <-- what are these values? nothing at the address
0x100027e2b      31c0           xor eax, eax               ; logical exclusive or
0x100027e2d      ff11           call qword [rcx]           ; calls a subroutine, push eip into the stack (esp)


If I seek to the address with Radare2, it seems that there's nothing there:
Code: Select all
[0x1001d7ed0]> pv
0x0000000000000000
[0x1001d7ed0]> pdf
p: Cannot find function at 0x1001d7ed0


And finally, a screenshot using Hopper Disassembler:
The same procedure as above (click on it to reveal the whole screenshot):
Screen Shot 2018-06-07 at 20.08.55.png
Hopper (procedure)
Screen Shot 2018-06-07 at 20.08.55.png (248.56 KiB) Viewed 279 times


If I seek to the address it points to, all Hopper shows me is:
Screen Shot 2018-06-07 at 20.09.20.png
Hopper (destination address)
Screen Shot 2018-06-07 at 20.09.20.png (84.17 KiB) Viewed 279 times


Some more information:

- This is a macOS application, ie the binary is found at: /path/to/application.app/Contents/MacOS/binary
- This app it written in Objective-C (I can tell from the disassembly)

My thoughts:

From what I can tell, I'm thinking this might be some sort of macOS private API? This app seems to use some private APIs for undocumented functionality, and that's what I'm looking for. Maybe this is the result of one of those calls? I'm not sure.
Whatever I do, I can't seem to find out what exactly is happening here, but it's definitely (maybe?) some sort of function, as you can see by Hopper's generated psuedocode:
Screen Shot 2018-06-07 at 20.16.42.png
Hopper (psuedo)
Screen Shot 2018-06-07 at 20.16.42.png (60.08 KiB) Viewed 279 times


If you need anymore information, let me know.
Appreciate any sort of response!
Thanks.
acheronfail
 
Posts: 9
Joined: Wed Jan 03, 2018 1:12 am

Re: [Help] Unknown function addresses in disassembly

Postby Siguza » Thu Jun 07, 2018 2:24 pm

Code: Select all
lea rcx, [0x1001d7d70]
call qword [rcx]


This loads the address 0x1001d7d70 into a register, then dereferences it and jumps to the resulting address. In other words, the memory at 0x1001d7d70 holds a function pointer. Since it's in the __DATA.__common segment though, that value is not static in the binary, but assigned at runtime. So you'll either have to take a look at a running binary, or find the code that's responsible for writing to 0x1001d7d70.
User avatar
Siguza
Unicorn
 
Posts: 200
Joined: Thu Jan 28, 2016 10:38 am

Re: [Help] Unknown function addresses in disassembly

Postby acheronfail » Thu Jun 07, 2018 9:43 pm

Ahhh I see, that would also make sense!
I'll see if I can debug it, or find where it sets that address.

Appreciate the reply! :D
acheronfail
 
Posts: 9
Joined: Wed Jan 03, 2018 1:12 am

Re: [Help] Unknown function addresses in disassembly

Postby acheronfail » Fri Jun 08, 2018 2:14 pm

Okay, after Siguza's helpful tips, I was able to find out what the function calls were :)

I attached Hopper's debugger to the process, and set a breakpoint at those addresses, and then inspected the registers using the debugger's console (lldb):
By stepping through the instructions, I found that the destination register was:
Screen Shot 2018-06-08 at 23.54.04.png
register value
Screen Shot 2018-06-08 at 23.54.04.png (28.11 KiB) Viewed 246 times


Which, when you inspect it shows the actual function:
Screen Shot 2018-06-08 at 23.53.47.png
actual address
Screen Shot 2018-06-08 at 23.53.47.png (220.51 KiB) Viewed 246 times



This works for the other parts in the file - thanks again Siguza!!
:mrgreen:
acheronfail
 
Posts: 9
Joined: Wed Jan 03, 2018 1:12 am

Re: [Help] Unknown function addresses in disassembly

Postby morpheus » Sat Jun 09, 2018 12:25 am

Siguza beat me to it but..

A) use ojtool because it is a wrapper over otool which resolves ip relative addresses. It would have given you the address
B) The address is bound by dyld at runtime. degenerate radare2 can't handle binding opcodes - but jtool can -
jtool -d on the address will show you immediately where it is bound, as will jtool -bind or jtool -lazy_bind. That's faster and safer than using a debugger..

J
morpheus
Site Admin
 
Posts: 650
Joined: Thu Apr 11, 2013 6:24 pm

Re: [Help] Unknown function addresses in disassembly

Postby acheronfail » Sat Jun 09, 2018 9:57 am

use ojtool because it is a wrapper over otool which resolves ip relative addresses. It would have given you the address


Do you mean this tool: http://newosxbook.com/src.jl?tree=listi ... toolfilt.c ?
If so, the output I get from using that is basically the same as plain ol' `otool` (although, I'm probably using it incorrectly if I understand what you're saying).
How could I achieve the same result as I did before (when I debugged it and inspected the memory live)?

The address is bound by dyld at runtime. degenerate radare2 can't handle binding opcodes - but jtool can -
jtool -d on the address will show you immediately where it is bound, as will jtool -bind or jtool -lazy_bind. That's faster and safer than using a debugger..


This is a x86_64 intel binary (macOS), IIUC `jtool -d` doesn't work with this kind of binary?

I have been using these other tools since I was under the impression jtool wouldn't be of much help in my case here.. If it can though, please point me in the right direction! (:
I'm all about not using the debugger - that took a lot more effort that I wanted just to discover what function ended up being called.
acheronfail
 
Posts: 9
Joined: Wed Jan 03, 2018 1:12 am

Re: [Help] Unknown function addresses in disassembly

Postby morpheus » Sun Jun 10, 2018 2:00 am

attach the binary here and I'll gladly walk you through it.
morpheus
Site Admin
 
Posts: 650
Joined: Thu Apr 11, 2013 6:24 pm

Re: [Help] Unknown function addresses in disassembly

Postby acheronfail » Sun Jun 10, 2018 6:51 am

attach the binary here and I'll gladly walk you through it.


I can't attach it here since the max file size is 256 KiB, but here's a link to it in my Dropbox: https://www.dropbox.com/s/t10jk0errn5iw ... t.zip?dl=0

I wrote a short explanation of what my goal is in reverse engineering this binary to give you some context :)
acheronfail
 
Posts: 9
Joined: Wed Jan 03, 2018 1:12 am

Re: [Help] Unknown function addresses in disassembly

Postby morpheus » Sun Jun 10, 2018 2:20 pm

So, using ojtool on the same file, we get:

Code: Select all
morpheus@Zephyr (~/Downloads/attachment) %ojtool HyperDock_Helper| grep -A 10 0100027e0e                                                9:51
Trying companion file : ./HyperDock_Helper.x86_64.D3E7CF69-2497-3E6B-B275-5C0DACC53330
Tip: Consider creating a companion file using jtool --jtooldir . -d __DATA.__const > /dev/null
0000000100027e0e   movq   %rdi, %r14
0000000100027e11   xorl   %ebx, %ebx
0000000100027e13   leaq   -0x24(%rbp), %r15
0000000100027e17   movl   %ebx, (%r15)
0000000100027e1a   leaq   0x1001d7ed0, %rax
0000000100027e21   movq   (%rax), %r12
0000000100027e24   leaq   0x1001d7d70, %rcx
0000000100027e2b   xorl   %eax, %eax
0000000100027e2d   callq   *(%rcx)
0000000100027e2f   movq   0x1001cf570, %rcx
0000000100027e36   movl   (%r14,%rcx), %esi


(note I had to rename to HyperDock_Helper, with an '_', so as to get around a command line argument bug)

As you can see the value of Rex is immediately recognizable as 0x1001d7d70. But note that is in the zero filled section. So as Siguza said, we need to find
who's writing to it:

Code: Select all
morpheus@Zephyr (~/Downloads/attachment) %ojtool HyperDock_Helper| grep 0x1001d7d70 | more
... (all leaq, which read, so not interesting)
00000001000552ca   leaq   0x1001d7d70, %rcx
0000000100055d0d   leaq   0x1001d7d70, %rcx
0000000100068ad1   movq   %rax, 0x1001d7d70
0000000100079280   leaq   0x1001d7d70, %rcx
0000000100079332   leaq   0x1001d7d70, %rcx
0000000100079398   leaq   0x1001d7d70, %rcx


And then:
Code: Select all
morpheus@Zephyr (~/Downloads/attachment) %ojtool HyperDock_Helper| grep -B 15 100068ad1                                                  9:55
Trying companion file : ./HyperDock_Helper.x86_64.D3E7CF69-2497-3E6B-B275-5C0DACC53330
Tip: Consider creating a companion file using jtool --jtooldir . -d __DATA.__const > /dev/null
0000000100068aa6   leaq   0x100137d91, %rsi ## literal pool for: "_DIVHjlh}u~N{{|ts\205{\202\202"
0000000100068aad   xorl   %edx, %edx
0000000100068aaf   movb   (%rdx,%rsi), %cl
0000000100068ab2   addb   %al, %cl
0000000100068ab4   movb   %cl, (%rbx,%rdx)
0000000100068ab7   incq   %rdx
0000000100068aba   decb   %al
0000000100068abc   cmpq   $0x15, %rdx
0000000100068ac0   jne   0x100068aaf
0000000100068ac2   movq   $-0x2, %rdi
0000000100068ac9   movq   %rbx, %rsi
0000000100068acc   callq   0x100125414 ## symbol stub for: _dlsym



So it's the return value of dlsym. Note that this is an obvious attempt at obfuscation. In this particular case, you're better off with the debugger approach, admittedly, since you'd need the value of rsi, meaning rbx (rdi is just RTLD_DEFAULT, or -2). The value of the symbol is obtained from "decrypting" the string ("_DIVHjlh}u~N{{|ts\205{\202\202"), so a breakpoint at 0x100068acc indeed does it.

I therefore was too eager in saying jtool alone will do - most often the anti-reversing is feeble, and merely refers to a direct call to a value populated by lazy_bind . This one is fully dynamic. Still, a debugger will fail even the best of attempts.
morpheus
Site Admin
 
Posts: 650
Joined: Thu Apr 11, 2013 6:24 pm

Re: [Help] Unknown function addresses in disassembly

Postby acheronfail » Sun Jun 10, 2018 6:26 pm

Wow thanks for that explanation, I can't believe it was that easy for you to find that section! haha
TBH, I had no idea that this binary had any form of obfuscation in it - I'll see what I can figure out with this combination of methods.
(If I discover anything noteworthy/potentially useful I'll be sure to post back again here).

Really appreciate the assistance and direction you've both given me, thank you. :)
acheronfail
 
Posts: 9
Joined: Wed Jan 03, 2018 1:12 am

Next

Return to Questions and Answers

Who is online

Users browsing this forum: No registered users and 1 guest