Skip to content
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

When computing relocations, use DYNAMIC segment if available #16419

Merged
merged 21 commits into from Apr 8, 2020
Merged

When computing relocations, use DYNAMIC segment if available #16419

merged 21 commits into from Apr 8, 2020

Conversation

ghost
Copy link

@ghost ghost commented Apr 5, 2020

Your checklist for this pull request

  • I've read the guidelines for contributing to this repository
  • I made sure to follow the project's coding style
  • I've added tests that prove my fix is effective or that my feature works (if possible)
  • I've updated the documentation and the radare2 book with the relevant information (if needed)

Detailed description
I start working on the dynamic section, the ir command found all the relocations. I don't know why the pd 15 command doesn't use all the relocs (new/db/formats/elf/reloc). I used readelf to test the relocation. Maybe later we could move the struct dynamic_relocation_section in the struct ELFOBJ?

Test plan

ir

Closing issues

#12732

@ret2libc ret2libc self-assigned this Apr 6, 2020
@ret2libc ret2libc added the ELF label Apr 6, 2020
Copy link
Contributor

@ret2libc ret2libc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are many errors in the tests. I will review after those are fixed, unless you have particular questions for me ;)

libr/bin/format/elf/elf.c Outdated Show resolved Hide resolved
@ghost
Copy link
Author

ghost commented Apr 6, 2020

I am testing to see why it failed, and i was wandering if one test could be wrong?

file: ./test/new/db/cmd/cmd_i

3182 NAME=ir (file x86_64, ifunc)
3183 FILE=../bins/elf/ifunc_rel64
3184 EXPECT=<<EOF
3185 [Relocations]
3186
3187 vaddr      paddr      type   name
3188 ---------------------------------
3189 0x006b17d0 0x000b17d0 SET_64 ifunc_416530 0x00416530 (ifunc)
3190 0x006b17d8 0x000b17d8 SET_64 ifunc_4193a0 0x004193a0 (ifunc)
3191 0x006b17e0 0x000b17e0 SET_64 ifunc_4199b0 0x004199b0 (ifunc)
3192 0x006b17e8 0x000b17e8 SET_64 ifunc_418a50 0x00418a50 (ifunc)
3193 0x006b17f0 0x000b17f0 SET_64 ifunc_418de0 0x00418de0 (ifunc)
3194 0x006b17f8 0x000b17f8 SET_64 ifunc_419ad0 0x00419ad0 (ifunc)
3195 0x006b1800 0x000b1800 SET_64 ifunc_4193f0 0x004193f0 (ifunc)
3196 0x006b1808 0x000b1808 SET_64 ifunc_414300 0x00414300 (ifunc)
3197 0x006b1810 0x000b1810 SET_64 ifunc_479800 0x00479800 (ifunc)
3198 0x006b1818 0x000b1818 SET_64 ifunc_4140b0 0x004140b0 (ifunc)

../bins/elf/ifunc_rel64 hasn't any .dynamic section.

❯ readelf -d ./test/bins/elf/ifunc_rel64

There is no dynamic section in this file.

Readelf believe that there are some relocations, but the ld don't do any relocation on this file.

@ghost
Copy link
Author

ghost commented Apr 6, 2020

And there is the problem of the .obj file...
There is no relocation, but in the future if the file is linked there will be some relocation.

@ghost
Copy link
Author

ghost commented Apr 6, 2020

In the case of ./test/bins/elf/radare2.c.obj which relocations r2 need?
'readelf -r' list a great number of relocations.

@ret2libc
Copy link
Contributor

ret2libc commented Apr 6, 2020

I think what happens in this case is that the function is statically linked (as file can confirm) so there is no dynamic segment as the executable doesn't need to pass any info to the dynamic loader. However the compiler still included those additional information.

The thing is that we still want the information provided by the sections because, as you said, in some cases they are the only information we have and in other cases they may enhance what we already have. However, I think care must be taken to ensure that first we load info from the dynamic segment and only later we enhance those info with the section information (if there are conflicts between info provided by DYNAMIC segment and .rel sections, DYNAMIC should win).

Does that make sense? What do you think?

@ghost
Copy link
Author

ghost commented Apr 6, 2020

Okay, that doesn't seems to be to complicated but how could we detect collision?
We could ignore sections with the same offset than informations inside the .dynamic.

The second problem is detecting valid rel or rela section. If a section use 'rel' or 'rela' in his name it doesn't guarantee that the section hold relocation entries. Maybe we could list all the section's names with a special meaning?

@ret2libc
Copy link
Contributor

ret2libc commented Apr 6, 2020

Okay, that doesn't seems to be too complicated but how could we detect collision?
We could ignore sections with the same offset than informations inside the .dynamic.

I think you can first get relocations from DYNAMIC (like what you are doing right now), then extract them from sections (just get the old code before your change, it should work well enough). While getting relocations from sections, check if there is already one at the same vaddr. If there is, ignore the one from sections and trust the one in DYNAMIC. If there isn't, add the new relocation to the list of relocations.

The second problem is detecting valid rel or rela section. If a section use 'rel' or 'rela' in his name it doesn't guarantee that the section hold relocation entries. Maybe we could list all the section's names with a special meaning?

There is nothing you can do about this. The only way to differentiate sections is with their names AFAIK.

@ghost
Copy link
Author

ghost commented Apr 6, 2020

The problem with the vaddr is that some debug reloc could have the same addr than .dynamic reloc.
We could check that the entrie's offset is not inside the range of a previous relocation entries?

@ghost
Copy link
Author

ghost commented Apr 6, 2020

There is two similar function 'Elf_(r_bin_elf_get_relocs)' and 'rel_cache_new'. Should i merge them?

@ghost
Copy link
Author

ghost commented Apr 6, 2020

We could use the new array of reloc to generate the hash map.

@lgtm-com
Copy link

lgtm-com bot commented Apr 6, 2020

This pull request fixes 1 alert when merging 357ce4d into e484762 - view on LGTM.com

fixed alerts:

  • 1 for FIXME comment

@codecov-io
Copy link

codecov-io commented Apr 7, 2020

Codecov Report

Merging #16419 into master will increase coverage by 0.24%.
The diff coverage is 46.12%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master   #16419      +/-   ##
==========================================
+ Coverage   38.79%   39.04%   +0.24%     
==========================================
  Files         994      994              
  Lines      324022   324528     +506     
==========================================
+ Hits       125697   126696     +999     
+ Misses     198325   197832     -493     
Impacted Files Coverage Δ
binr/r2r/load.c 70.17% <0.00%> (-8.47%) ⬇️
binr/radare2/radare2.c 7.89% <ø> (ø)
libr/bin/bin.c 71.14% <ø> (ø)
libr/core/cio.c 69.11% <ø> (-0.10%) ⬇️
libr/core/cmd.c 45.84% <0.00%> (+0.02%) ⬆️
libr/core/cmd_anal.c 49.71% <0.00%> (+0.03%) ⬆️
libr/core/panels.c 0.00% <0.00%> (ø)
libr/core/visual.c 12.05% <0.00%> (+<0.01%) ⬆️
libr/core/vmenus.c 2.24% <0.00%> (-0.11%) ⬇️
libr/include/r_util/r_buf.h 66.66% <ø> (ø)
... and 97 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update ec49299...5be706a. Read the comment docs.

@ret2libc
Copy link
Contributor

ret2libc commented Apr 7, 2020

@08a I think this is not working as expected. I tried the tests in https://github.com/radareorg/radare2-regressions/commit/19ccc45154ca69041b8432147197738a453419e5 and it is still failing. Are you using the info from dynamic?

@radare
Copy link
Collaborator

radare commented Apr 7, 2020

can you add a test?

@ghost
Copy link
Author

ghost commented Apr 7, 2020

The https://github.com/radareorg/radare2-regressions/commit/19ccc45154ca69041b8432147197738a453419e5 can't work on __libc_start_main because there is no relocation related to this symbol.

@ghost
Copy link
Author

ghost commented Apr 7, 2020

import sys
import lief

def rename_section_rela(filename, output):
    binary = lief.parse(filename)
    for i, section in enumerate(binary.sections):
        if ("rel" in section.name):
            section.name = f"section_number_{i}"
    binary.write(output);

if __name__ == "__main__":
    if len(sys.argv) != 3:
        print("Usage: {} <elf binary> <output>".format(sys.argv[0]))
        sys.exit(1)

    rename_section_rela(sys.argv[1], sys.argv[2])

I used this small script on this simple binary

#include <stdio.h>

int main(void) {
    printf("Hello World!!!");
    return 0;
}

I will send a pr on https://github.com/radareorg/radare2-testbins

@lgtm-com
Copy link

lgtm-com bot commented Apr 7, 2020

This pull request fixes 1 alert when merging c3a6e7a into 6d633a9 - view on LGTM.com

fixed alerts:

  • 1 for FIXME comment

@ret2libc
Copy link
Contributor

ret2libc commented Apr 7, 2020

The radareorg/radare2-regressions@19ccc45 can't work on __libc_start_main because there is no relocation related to this symbol.

Somehow I uploaded a wrong binary in that commit :/ As you say, that bin does not work, sorry about that. Could you please update it so that it works or just remove it if you already have added another test for this behaviour? I will review your code today/tomorrow, but the results look good! Thanks :)

@ghost
Copy link
Author

ghost commented Apr 7, 2020

I need some advice for this pr. I believe some refacto can be done.

  • rel_cache_new and Elf_(r_bin_elf_get_relocs) (same behaviour different data structure, maybe replace by the new implementation or reused inside rel_cache_new)
  • move struct dynamic_relocation_section inside ELFOBJ
  • move the function get_dynamic_info inside init_dynamic_section
  • remove the is_rela inside ELFOBJ

@lgtm-com
Copy link

lgtm-com bot commented Apr 7, 2020

This pull request fixes 1 alert when merging 5be706a into 38fa548 - view on LGTM.com

fixed alerts:

  • 1 for FIXME comment

Copy link
Contributor

@ret2libc ret2libc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot! I had a look at the code, overall it looks very good. I added comments here and there. Tell me what you think.

About the refactoring you mentioned, I think they are valid points, but I would do those things after merging this PR, to avoid changing too many things at the same time with the risk of breaking and never merging the change. Ok?

libr/bin/format/elf/elf.c Outdated Show resolved Hide resolved
libr/bin/format/elf/elf.c Outdated Show resolved Hide resolved
libr/bin/format/elf/elf.c Outdated Show resolved Hide resolved
libr/bin/format/elf/elf.c Outdated Show resolved Hide resolved
libr/bin/format/elf/elf.c Outdated Show resolved Hide resolved
libr/bin/format/elf/elf.c Outdated Show resolved Hide resolved
return bin->g_sections[pos].info < bin->ehdr.e_shnum && bin->shdr;
}

static size_t get_next_not_analysed_offset(size_t section_offset, size_t offset,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i have an hard time following this function :(

can it be simplified a bit? also, i'm not sure it's right that we check for all the if cases when we are really working only with one type of rel (e.g. if i'm iterating over rela entries, this function may still check info->addr_jmprel - base_addr <= g_offset && g_offset < info->addr_jmprel + info->jmprel_size - base_addr.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The main problem is that we could have obfuscated binary like that

section: rel.plt
false_relocation | real rela table | jmprel table | false rel table

We can't trust the type of relocation in the name.
Maybe we could had an option to load or not the relocations record from section?
It could be an start's option.

libr/bin/format/elf/elf.c Outdated Show resolved Hide resolved
libr/bin/format/elf/elf.c Outdated Show resolved Hide resolved
libr/bin/format/elf/elf.c Show resolved Hide resolved
@ghost ghost requested a review from ret2libc April 8, 2020 13:24
Copy link
Contributor

@ret2libc ret2libc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just fix the last few things and I think we can remove the WIP status and merge it. Are you ok with the current state of things? As you said, it's not only about this because there are other parts of the code that still use section names, but those can be done separately. Great work btw :)

libr/bin/format/elf/elf.c Outdated Show resolved Hide resolved
libr/bin/format/elf/elf.c Outdated Show resolved Hide resolved
libr/bin/format/elf/elf.c Show resolved Hide resolved
@ghost
Copy link
Author

ghost commented Apr 8, 2020

I am satisfied with the state of the PR, later today or tomorrow i will send an other PR to add some re-factorization.

@ret2libc ret2libc marked this pull request as ready for review April 8, 2020 14:13
@ret2libc ret2libc changed the title WIP - Work on dt dynamic When computing relocations, use DYNAMIC segment if available Apr 8, 2020
@lgtm-com
Copy link

lgtm-com bot commented Apr 8, 2020

This pull request fixes 1 alert when merging 4c3918f into a52506a - view on LGTM.com

fixed alerts:

  • 1 for FIXME comment

@radare radare merged commit 1c29509 into radareorg:master Apr 8, 2020
@ghost ghost deleted the work_on_DT_DYNAMIC branch April 8, 2020 18:32
Emi1305 pushed a commit to Emi1305/radare2 that referenced this pull request Jul 12, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants