orhun / binsider

Analyze ELF binaries like a boss πŸ˜ΌπŸ•΅οΈβ€β™‚οΈ
https://binsider.dev/
Apache License 2.0
2.76k stars 61 forks source link

Consider supporting symbolic relocation names #72

Open HadrienG2 opened 1 month ago

HadrienG2 commented 1 month ago

Is your feature request related to a problem? Please describe.

Relocation types are currently given as integer codes. To interpret these, one must look up the ELF ABI supplement for the relevant CPU architecture (or a third-party account thereof) and search it via a number, which is a poor search key because numbers are everywhere in technical documents, or go through the summary to look up the right section.

Describe the solution you'd like

I'd like binsider to use symbolic relocation names like R_X86_64_RELATIVE, which are both easier to remember and easier to search on the internet. To save up precious screen estate and make the display clearer, it might be a good idea to only keep the differentiating suffix i.e. "RELATIVE", since this is not ambiguous when the CPU architecture of the binary is known.

Describe alternatives you've considered

The tricky part about this feature proposal is that unless you can find an ELF parser that already does the work for you, it requires digging up lots of SysV ABI supplements to build lots of tables, which is time-consuming. This might be a selection criterion for your future binary parser, as discussed in #26 .

orhun commented 1 month ago

Thanks for the suggestion! As of now, I'm not sure how to achieve this with elf, which is the library that I'm using to parse the ELF format. I guess I need to read more up on symbolic relocation names and where they come from.

I guess we can't simply slap a lookup table somewhere and simply use the values from there πŸ’€

HadrienG2 commented 1 month ago

It can be done with a lookup table, but you need a 2D lookup table because relocation type numbers are reused across CPU architectures with different meanings on each architecture. Needless to say, filling up the lookup table will also be a little boring as you need to check the SysV ABI supplements for each CPU architecture of interest.

FWIW, all the multi-format binary parsers that we discussed in #67 have something to bring here:

orhun commented 1 month ago

LIEF seems like to have the most straightforward approach to it, so I gave it a try:

diff --git a/src/elf/relocations.rs b/src/elf/relocations.rs
index 8bfaed2..052c1ae 100644
--- a/src/elf/relocations.rs
+++ b/src/elf/relocations.rs
@@ -4,6 +4,7 @@ use elf::{
     relocation::{Rel, Rela},
     ElfBytes, ParseError,
 };
+use lief::elf::relocation::Type;
 use std::io::{Error as IoError, ErrorKind as IoErrorKind};

 /// ELF relocations wrapper.
@@ -52,7 +53,7 @@ impl<'a> Property<'a> for Relocations {
         let mut relocations = Vec::new();
         self.rels.iter().for_each(|v| {
             relocations.push(vec![
-                format!("{:#X?}", v.r_type),
+                format!("{:?}", Type::from_value(v.r_type)),
                 format!("{:#X?}", v.r_sym),
                 format!("{:#X?}", v.r_offset),
                 String::from("-"),
@@ -60,7 +61,7 @@ impl<'a> Property<'a> for Relocations {
         });
         self.relas.iter().for_each(|v| {
             relocations.push(vec![
-                format!("{:#X?}", v.r_type),
+                format!("{:?}", Type::from_value(v.r_type)),
                 format!("{:#X?}", v.r_sym),
                 format!("{:#X?}", v.r_offset),
                 format!("{:#X?}", v.r_addend),

But I'm getting for all the types. Any idea what's going wrong there?

HadrienG2 commented 1 month ago

Notice how the from_value function does not ask you for the CPU arch, which is required information for disambiguating reuse of ELF relocation type codes across CPU arches.

This suggests that something fishy is going on, and the "type value" exposed by LIEF is not a pure ELF relocation type code.

In the LIEF source code, you can see that indeed they tag relocation types with CPU arch codes : https://github.com/lief-project/LIEF/blob/main/include/LIEF/ELF/Relocation.hpp