-
Notifications
You must be signed in to change notification settings - Fork 115
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Loader: ELF non-zero based PIC binaries support #65
Comments
You are wrong about the correct behavior of However, there is definitely a bug. I think the issue is just that our rebase granularity is too large. Can you try loading the binary with |
Thought about granularity and tried it already with
In my case As I understand |
Are your shared libraries not position-independent? I'm having a hard time understanding the situation you're describing. Can you send me the binaries to reproduce this? |
Unfortunately, I can't because of NDA.
No. They are all PICs except the main binary as usual. I found that the problem has occurred because CLE can't correctly load prelinked binaries. self.requested_base = self._pe.OPTIONAL_HEADER.ImageBase and this one is from the basic Backend class Backend(object):
"""
Main base class for CLE binary objects.
...
:ivar requested_base: The base address this object requests to be loaded at, or None
...
self.requested_base = None and from loader def add_object(self, obj, base_addr=None):
...
elif obj.requested_base is not None and self._is_range_free(obj.requested_base + obj_offset, obj_size):
base_addr = obj.requested_base so generally it supports the concept of image base, but the usage I think is wrong.
Is that correct? |
I think your diagnosis is correct, and the solution you propose is also good. An easy fix might be to just use min_addr as the other base. On the other hand, I've never encountered a "prelinked" binary before. Can you compile one for me or find me an example not covered by your NDA? |
I've tried such fast fix at first, but the issue touches several more files and many regression tests failed as a result. Is it possible that an assertion is wrong in this case index bf60598..09c782e 100644
--- a/tests/test_overlap.py
+++ b/tests/test_overlap.py
@@ -14,7 +14,7 @@ class MockBackend(cle.backends.Backend):
def test_overlap():
filename = os.path.join(os.path.dirname(os.path.realpath(__file__)), '../../binaries/tests/i386/manysum')
ld = cle.Loader(filename, auto_load_libs=False)
- nose.tools.assert_equal(ld.main_bin.rebase_addr, 0)
+ nose.tools.assert_equal(ld.main_bin.rebase_addr, 0x8048000)
nose.tools.assert_equal(ld.main_bin.get_min_addr(), 0x8048000)
obj1 = MockBackend(0x8047000, 0x2000, custom_arch=ld.main_bin.arch) Any image is actually rebasing each time it is loading: def add_object(self, obj, base_addr=None):
...
l.info("Rebasing %s at %#x", obj.binary, base_addr) The new base should stay the same (
I'll attach them here a bit later. |
It looks like angr project itself also suffers from this issue. |
The semantics of
Yes. I honestly didn't know that such binaries could exist before this issue was opened, so who knows where else the problem could be lurking... My hope is that except for the testcases, the rest of angr will only use the CLE interfaces instead of the direct addresses, so making the interface consistent will fix problems elsewhere. |
Thanks for the support.
If these assumptions are correct, it seems that addressing in the second case should be also absolute, and also because of rebasing. But are they correct? |
The top level clemory,
|
@rhelmot I think this is the problem that we've discussed before. CLE respects the "ideal" base address specified by the library being loaded into the memory, and it always uses the previously maximum address as the new minimum base address for future libraries to be loaded. Hence, when libraries with large default base addresses are loaded, some large holes will be created between their memory spaces, which in the end leads to the issue above. The fix, as I proposed before, was to change how |
@ltfish
will not help too much. As an example, |
@amttr My understanding is that the original issue was because that the maximum address (rebased) is too large due to loading some libraries with very high default base addresses, apart from several other less obvious bugs you and @rhelmot mentioned in this issue. |
@ltfish it just a result of incorrect usage of addresses types. The reason is there are many places inside CLE where VA(MVA/LVA)/RVA were misused. angr and angrop also suffer from the same issue. |
I still don't understand what the semantics of those three acronyms are supposed to refer to. Is there somewhere where all this is written down? For CLE we couldn't find anything of the sort so we sort of... made up our own classification. |
Regardless, we do have test cases now, so I can and will make it all work. I think we could even do it before the hell refactor over in angr is over, since this should just touch CLE if my understanding of the problem is right. (From rereading my last post last month on this issue I think I know what I'm talking about? probably? and I know where to start working on a solution) |
@rhelmot sorry, I mean Relative Virtual Address and Virtual Address (using Linked or Mapped image base). As we've talked earlier CLE consist code which sometimes uses address with two bases applied. |
@amttr Don't get me wrong, I'm not saying the misuses do not exist. In fact, they have always been a big problem in CLE. I'm sure we got a lot of things wrong due to our ignorance. However, the current logic in I'm not saying you should address it. If it is a real issue (which I believe it is), it can be a separate issue anyway. |
@ltfish I agree. This is definitely a separate issue. |
Is this now resolved with the merging of those PRs? :) |
I think prelinked binaries from should be merged too, or you can add rebased versions of those by yourself with prelink rebase angr/binaries#13 $ prelink --help | grep -A1 Relocate
-r, --reloc-only=BASE_ADDRESS Relocate library to given address, don't
prelink |
It is may be not a real issue but a lack of understanding.
I am trying to load some 32bit ARM binary with dependencies resolution enabled
the result is
The virtual address 0x1 9200 0000 is not of 32 bit length.
The problem, as I understood, arise from method Loader._get_safe_rebase_addr
and located inside Loader.max_addr→backends.get_max_addr
The line I am interested in is the last one
it should return new rebased image base address (the one inside Clemory map), but in my case it instead returns
(old image base + maximum rva from ELF objects) out + self.rebase_addr (new image base)
Does this logic correct? Maybe out should be normalized (- old image base)...
Please correct me if I am wrong.
The text was updated successfully, but these errors were encountered: