question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Loading external .so libraries

See original GitHub issue

Hi all, I’m having difficulty getting angr’s simulation manager to execute code in manually loaded libraries. Specifically, I am concolically executing a binary which makes a call to the memcmp libc function. I need angr to step over the supplied libc.so file I provide, but when jumping to a memcmp call, it does not link to my provided libc function.

My setup for the angr project is specified below:

p = Project(main_range.file,
            main_opts={'backend': 'elf',
                        'base_addr': main_range.address,
                        'entry_point': entry_address},
            use_system_libs=False,
            auto_load_libs=True,
            except_missing_libs=False,
            use_sim_procedures=False,
            force_load_libs=["./abcdef/libc.so.6",
                             "./abcdef/ld-linux-x86-64.so.2"],
            lib_opts={"libc.so.6":{"base_addr":0x7ffff6d06000},
                      "ld-linux-x86-64.so.2":{"base_addr":0x7ffff7dd9000}}
            )

Note that if I set auto_load_libs=True, then memcmp will be hooked to CLE’s externs. Also, I have offsetted the loaded libs to 0x7fff… addresses as this is needed for my concolic execution trace.

As you can see below here, the binary is loaded how I want it, and the memcmp symbol is located in the libary I provide.

In [2]: self.angr_project.is_symbol_hooked("memcmp")                                                                                                                                                                 
Out[2]: False

In [3]: self.angr_project.loader.find_symbol("memcmp")                                                                                                                                                               
Out[3]: <Symbol "memcmp" in libc.so.6 at 0x7ffff6d89940>

In [4]: self.angr_project.loader.all_objects                                                                                                                                                                         
Out[4]: 
[<ELF Object hostapd, maps [0x400000:0x6c595f]>,
 <ELFTLSObject Object cle##tls, maps [0x1000000:0x1015010]>,
 <ExternObject Object cle##externs, maps [0x2000000:0x2008000]>,
 <KernelObject Object cle##kernel, maps [0x3000000:0x3008000]>,
 <ELF Object libc.so.6, maps [0x7ffff6d06000:0x7ffff70a495f]>,
 <ELF Object ld-linux-x86-64.so.2, maps [0x7ffff7dd9000:0x7ffff7ffe16f]>]

However, if we take a look the IDA dissasembly of the call to memcp, it is linked via the Global Offset Table, not a symbol. Screenshot from 2019-05-17 19-48-56 And below is the corresponding angr disassembly of the same block:

0x407500:	jmp	qword ptr [rip + 0x2bd39a]

When, I step with the SimManager from the basic block at 0x407500, the active state of angr moves to address 0x20008e8, which falls in the cle###externs range, not libc.so.6!!

In [3]: sm.active[0]                                                                                                                                                                                                 
Out[3]: <SimState @ 0x407500>
In [4]: sm.step()   
In [5]: sm.active[0]                                                                                                                                                                                                
Out[5]: <SimState @ 0x20008e8>

Can anyone advise me as to whether I doing anything wrong with the loading of these external libs? Please let me know if you need anymore information from my set-up in order to help me. Thanks.

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:12 (7 by maintainers)

github_iconTop GitHub Comments

1reaction
rhelmotcommented, May 31, 2019

Yeah - this is not something I have the ability to intuit the cause of. You’ll have to either give me a full testcase for reproduction or root-cause it yourself. It could maybe be caused by having weird combinations of functions which are and aren’t hooked, it could be caused by not running all the initializers (but synced memory state should take care of that!) but it’s impossible to say for sure.

1reaction
rhelmotcommented, May 19, 2019

I think what you’re seeing is an ifunc, or a function whose implementation is chosen at runtime by checking e.g. cpuid. The ELF symbol for memcmp will not point to an actual implementation of memcmp, but a function which will return a pointer to whatever function should be used to implement memcmp. It is the dynamic loader’s (angr’s, in this case) job to deal with this. angr implements it by resolving the symbol to the externs space, hooking that with an “ifunc resolver” simprocedure, and then having that procedure run the resolver and then dump the result back into the GOT. iirc this is fairly close to how ld does it?

You could, theoretically, add an option to the SimOS code which sets this up to do eager evaluation of these, but I don’t know if they depend on initialization that doesn’t happen in libc until execution starts, so you might end up with crashes.

You are going to run into a lot more issues like this (auxv, precise stack layouts, cpuid, minutia of loader implementations and ELF features, thread-local storage) if you want to try to get angr to sync up with a recorded trace precisely. Believe me, I’ve been down that road.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Loading and using shared libraries - The Javascript Tools Guide
To load an external shared library into JavaScript, create a new ExternalObject object. The instance acts as a container and manager for the...
Read more >
How to dynamically load a native shared libraries (.so) for ...
You can try on your project to see how it goes. Step 1: Ensure that your app permission for external storage is configured...
Read more >
4. Dynamically Loaded (DL) Libraries
Dynamically loaded (DL) libraries are libraries that are loaded at times other than during the startup of a program. They're particularly useful for ......
Read more >
Loading a library from a script - ROOT Forum
Hi, Continuing along the lines of extending ROOT functionality with external libraries I have run into another issue that I am hoping ...
Read more >
Dynamically Loaded Libraries Outside the Standard - YouTube
https://cppcon.org/https://github.com/CppCon/CppCon2021---You must be aware of dynamically-link libraries, but have you tried using them ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found