2016-03-19 13 views
1

Ich möchte ein Python-Skript schreiben, das eine Funktion Opcodes aus einer Elf-Binärdatei extrahiert, die ihre Adresse kennt, z. B. 0x437310 und die Größe. Wie kann ich diese Adresse dem entsprechenden Offset in der Binärdatei zuordnen, um davon zu lesen?Funktionsbytes aus der ELF-Binärdatei extrahieren

Mit einem Hex-Editor kann ich herausfinden, dass die Funktion bei 0x437310 bei Offset 0x37310 im Hexdump beginnt.

Wie kann ich dies auf generische Weise berechnen, da die Bilddatenbank einer Binärdatei nicht immer die gleiche ist.

wird jede mögliche Hilfe der

+0

Bitte fügen Sie eine (relevante) Probe ELF-Datei. – boardrider

Antwort

0

Lassen Sie sagen, dass ich den Anweisungen von maybe_make_export_env extrahieren möchten von bash geschätzt.

Das erste, was Sie tun möchten, ist dieses Symbol in der Symboltabelle finden:

$ readelf -s /bin/bash 
    Num: Value   Size Type Bind Vis  Ndx Name 
[...] 
    216: 000000000043ed80 18 FUNC GLOBAL DEFAULT 14 maybe_make_export_env 
[...] 

Diese uns die Adresse der Funktion im Speicher (0x43ed80) und seine Länge (18) gibt.

Wir haben die Adresse im (virtuellen) Speicher (im Prozessabbild). Wir wollen nun die relevante Adresse in der Datei finden. Um das zu tun, dass wir auf der Programmkopftabelle suchen müssen:

$ readelf -l /bin/bash 
Program Headers: 
    Type   Offset    VirtAddr   PhysAddr 
       FileSiz   MemSiz    Flags Align 
    PHDR   0x0000000000000040 0x0000000000400040 0x0000000000400040 
       0x00000000000001f8 0x00000000000001f8 R E 8 
    INTERP   0x0000000000000238 0x0000000000400238 0x0000000000400238 
       0x000000000000001c 0x000000000000001c R  1 
     [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2] 
    LOAD   0x0000000000000000 0x0000000000400000 0x0000000000400000 
       0x00000000000f3ad4 0x00000000000f3ad4 R E 200000 
    LOAD   0x00000000000f3de0 0x00000000006f3de0 0x00000000006f3de0 
       0x0000000000008ea8 0x000000000000ea78 RW  200000 
    DYNAMIC  0x00000000000f3df8 0x00000000006f3df8 0x00000000006f3df8 
       0x0000000000000200 0x0000000000000200 RW  8 
    NOTE   0x0000000000000254 0x0000000000400254 0x0000000000400254 
       0x0000000000000044 0x0000000000000044 R  4 
    GNU_EH_FRAME 0x00000000000d8ab0 0x00000000004d8ab0 0x00000000004d8ab0 
       0x0000000000004094 0x0000000000004094 R  4 
    GNU_STACK  0x0000000000000000 0x0000000000000000 0x0000000000000000 
       0x0000000000000000 0x0000000000000000 RW  10 
    GNU_RELRO  0x00000000000f3de0 0x00000000006f3de0 0x00000000006f3de0 
       0x0000000000000220 0x0000000000000220 R  1 

Wir in denen PT_LOAD Eintrag finden möchten diese Adresse (basierend auf VirtAddr und MemSize) gehört. Der erste PT_LOAD Eingabebereich von 0x400000 bis 0x400000 + 0xf3ad4 = 0x4f3ad4 (ausgeschlossen), so dass das Symbol zu diesem PT_LOAD Eintrag gehört.

Wir können den Offset in der Datei mit finden: symbol_value - VirtAddr + Offset = 0x3ed80.

Dies ist der relevante Teil der Datei:

0003ed80: 8b05 3260 2b00 85c0 7406 e911 feff ff90 ..2`+...t....... 
0003ed90: f3c3 0f1f 4000 662e 0f1f 8400 0000 0000 [email protected] 

wir in der Tat die gleichen Bytes wie die von objdump -d /bin/bash gegebenen haben:

000000000043ed80 <[email protected]@Base>: 
    43ed80:  8b 05 32 60 2b 00  mov 0x2b6032(%rip),%eax  # 6f4db8 <[email protected]@Base> 
    43ed86:  85 c0     test %eax,%eax 
    43ed88:  74 06     je  43ed90 <[email protected]@Base+0x10> 
    43ed8a:  e9 11 fe ff ff   jmpq 43eba0 <[email protected]@Base+0x60> 
    43ed8f:  90      nop 
    43ed90:  f3 c3     repz retq 
    43ed92:  0f 1f 40 00    nopl 0x0(%rax) 
    43ed96:  66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1) 
    43ed9d:  00 00 00