1

While working on this kernel module, I noticed IDA somehow resolves some ELF relocations statically. Consider the symbol sys_renameat, which, according to IDA, resides at 0x8000720 in .bss segment.

enter image description here

The raw hex bytes corresponding to the mov instruction at 0x800328 are A3 20 07 00 08

However, looking at bytes at that specific offset with a hex-editor reveals A3 00 00 00 00. Clearly, there is a relocation which IDA is resolving somehow.

enter image description here

readelf -r rootkit confirms this.

Relocation section '.rel.init.text' at offset 0x119c contains 26 entries:
 Offset     Info    Type            Sym.Value  Sym. Name
.
00000059  00001701 R_386_32          00000000   sys_renameat
.

The symbol information as returned by readelf -s rootkit

Symbol table '.symtab' contains 44 entries:
Num:    Value  Size Type    Bind   Vis      Ndx Name
.
23: 00000000     4 OBJECT  GLOBAL DEFAULT   15 sys_renameat
.

However, if I strip the binary, suddenly IDA fails to resolve (mov instruction at 0x800328) the relocations any more.

enter image description here

My understanding is, resolving dynamic relocations never depends on symbol information which strip removes. I tried to compute how IDA was computing R_386_32 type relocation for sys_renameat according to ELF specification, but couldn't figure out what's going on.

Is IDA resolving relocation correctly in this case/ If so, can someone please explain this behavior?

  • Hi. Two things. Could you please - either in addition or as replacement -copy&paste the actual textual contents of the disassembly instead of the screenshots. And then, what was the output for the various places that ELF has to store symbols after you stripped the binary? – 0xC0000022L Jun 7 '18 at 18:40
  • I don't know if IDA allows us to copy raw disassembly. I have linked the original binary in my post though. – Holmes.Sherlock Jun 7 '18 at 20:52
  • yep, IDA can easily do that. The point behind this request is that this makes your question easier to index for search engines. They won't recognize keywords from the screenshots. – 0xC0000022L Jun 7 '18 at 21:13
4

Linux kernel modules are not shared objects and don't use dynamic relocations, although they may look a little similar.

file:

rootkit: ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), BuildID[sha1 ]=5552f893cf02ce13e9a183af3b6717e884493ead, not stripped

readelf -h:

Type: REL (Relocatable file)

So it's a relocatable object, and by stripping it you remove information necessary for its functioning.

From the Linux Loadable Kernel Module HOWTO:

How that relocation happens is fundamentally different between Linux 2.4 and Linux 2.6. In 2.6, insmod pretty much just passes the verbatim contents of the LKM file (.ko file) to the kernel and the kernel does the relocation.

About relocation resolution by IDA:

Since the real address of the symbols is not known until runtime but the user expects to see nice names in the disassembly, IDA's ELF loader creates a fake segment ("extern") and fills it with placeholders for the external symbols. The relocatable bytes are then patched to point to those fake symbols.

  • Does it essentially mean that the address 0x080000720 (as the destination of mov instruction at 0x08000328) I am seeing in the first disassembly is plain wrong, and no way the real one? – Holmes.Sherlock Jun 8 '18 at 4:15
  • Also the symbol sys_renameat lands in .bss, not in .extern – Holmes.Sherlock Jun 8 '18 at 4:17
  • well, local symbols are obviously resolved locally. as for the addresses, “wrong” depends on your point of view. they probably don’t match the real addresses at runtime but the logical connections should be the same. – Igor Skochinsky Jun 8 '18 at 10:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.