{"id":2808,"date":"2021-02-19T17:19:50","date_gmt":"2021-02-19T16:19:50","guid":{"rendered":"https:\/\/andreas-klingler.de\/infosec\/?p=2808"},"modified":"2023-12-24T12:37:18","modified_gmt":"2023-12-24T11:37:18","slug":"the-linux-executable-and-linking-format-elf","status":"publish","type":"post","link":"https:\/\/infosec.andreas-klingler.de\/?p=2808","title":{"rendered":"The Linux Executable and Linking Format (<span class=\"caps\">ELF<\/span>)"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Concepts<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A <strong>seg\u00adment<\/strong> is a piece of a infor\u00adma\u00adtion which is mapped into the mem\u00ado\u00adry (of a process). A <span class=\"caps\">ELF<\/span> bina\u00adry can have zero or mul\u00adti\u00adple seg\u00adments. It defines also where the <span class=\"caps\">OS<\/span> should put it into the mem\u00ado\u00adry. Each seg\u00adment has a Pro\u00adgram Head\u00ader which describes the <em>sec\u00adtions<\/em> within.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A <strong>sec\u00adtion<\/strong> is a dis\u00adtinc\u00adtive part of a seg\u00adment with a defined pur\u00adpose. A seg\u00adment can have zero or mul\u00adti\u00adple sections.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The <span class=\"caps\">ELF<\/span> header<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The <span class=\"caps\">ELF<\/span> file head\u00ader looks like&nbsp;this:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># hexdump \/bin\/ls -C | head\n00000000  7f 45 4c 46 02 01 01 00  00 00 00 00 00 00 00 00\n00000010  03 00 3e 00 01 00 00 00  60 61 00 00 00 00 00 00\n00000020  40 00 00 00 00 00 00 00  68 37 02 00 00 00 00 00\n00000030  00 00 00 00 40 00 38 00  0b 00 40 00 1e 00 1d 00<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Expla\u00adna\u00adtion:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th class=\"has-text-align-right\" data-align=\"right\">Byte#<\/th><th>Byte<\/th><th>Con\u00adtent<\/th><\/tr><\/thead><tbody><tr><td class=\"has-text-align-right\" data-align=\"right\">1<\/td><td><span class=\"caps\">7F<\/span><\/td><td><\/td><\/tr><tr><td class=\"has-text-align-right\" data-align=\"right\">2<\/td><td>45<\/td><td>E<\/td><\/tr><tr><td class=\"has-text-align-right\" data-align=\"right\">3<\/td><td><span class=\"caps\">4C<\/span><\/td><td>L<\/td><\/tr><tr><td class=\"has-text-align-right\" data-align=\"right\">4<\/td><td>46<\/td><td>F<\/td><\/tr><tr><td class=\"has-text-align-right\" data-align=\"right\">5<\/td><td>02<\/td><td>Class:<br>0 = None<br>1 = 32 Bit object<br>2 = 64 Bit object<\/td><\/tr><tr><td class=\"has-text-align-right\" data-align=\"right\">6<\/td><td>01<\/td><td>Data encod\u00ading:<br>0 = None<br>1 = <span class=\"caps\">LSB<\/span><br>2 =&nbsp;<span class=\"caps\">MSB<\/span><\/td><\/tr><tr><td class=\"has-text-align-right\" data-align=\"right\">7<\/td><td>01<\/td><td>Ver\u00adsion. There is only ver\u00adsion&nbsp;1.<\/td><\/tr><tr><td class=\"has-text-align-right\" data-align=\"right\">8<\/td><td>00<\/td><td><span class=\"caps\">ABI<\/span> Appli\u00adca\u00adtion Bina\u00adry Inter\u00adface:<br>0 = None\/System V (most\u00adly used)<br>1 = <span class=\"caps\">HP-UX<\/span><br>2 = NetB\u00adSD<br>3 =&nbsp;Linux<\/td><\/tr><tr><td class=\"has-text-align-right\" data-align=\"right\">9<\/td><td>00<\/td><td><span class=\"caps\">ABI<\/span> ver\u00adsion. Nor\u00admal\u00adly&nbsp;0.<\/td><\/tr><tr><td class=\"has-text-align-right\" data-align=\"right\">10<\/td><td>00<\/td><td><em>Padding<\/em><\/td><\/tr><tr><td class=\"has-text-align-right\" data-align=\"right\">11<\/td><td>00<\/td><td><em>Padding<\/em><\/td><\/tr><tr><td class=\"has-text-align-right\" data-align=\"right\">12<\/td><td>00<\/td><td><em>Padding<\/em><\/td><\/tr><tr><td class=\"has-text-align-right\" data-align=\"right\">13<\/td><td>00<\/td><td><em>Padding<\/em><\/td><\/tr><tr><td class=\"has-text-align-right\" data-align=\"right\">14<\/td><td>00<\/td><td><em>Padding<\/em><\/td><\/tr><tr><td class=\"has-text-align-right\" data-align=\"right\">15<\/td><td>00<\/td><td><em>Padding<\/em><\/td><\/tr><tr><td class=\"has-text-align-right\" data-align=\"right\">16<\/td><td>00<\/td><td><em>Padding<\/em><\/td><\/tr><tr><td class=\"has-text-align-right\" data-align=\"right\">17 18<\/td><td>03 00<\/td><td>File Type:<br>0 <span class=\"caps\">ET_NONE<\/span> = None<br>1 <span class=\"caps\">ET_REL<\/span> = Relo\u00adcat\u00adable file (.o)<br>2 <span class=\"caps\">ET_EXEC<\/span> = Exe\u00adcutable file<br>3 <span class=\"caps\">ET_DYN<\/span> = Shared object file (.so)<br>4 <span class=\"caps\">ET_CORE<\/span> = Core file (mem\u00ado\u00adry dump&nbsp;file)<\/td><\/tr><tr><td class=\"has-text-align-right\" data-align=\"right\">19 20<\/td><td>3e 00<\/td><td>Machine Type:<br>0x03 = x86<br>0x28 = <span class=\"caps\">ARM<\/span><br>0x3E =&nbsp;amd64&nbsp;<\/td><\/tr><tr><td class=\"has-text-align-right\" data-align=\"right\">21 22 23&nbsp;24<\/td><td>01 00 00&nbsp;00<\/td><td>Ver\u00adsion. Always 1.<\/td><\/tr><tr><td class=\"has-text-align-right\" data-align=\"right\">25 26 27 28 29 30 31&nbsp;32<\/td><td>60 61 00 00 00 00 00&nbsp;00<\/td><td>Rel\u00ada\u00adtive address of the main func\u00adtion: <code>0x6160<\/code> (or 0 for libraries)<\/td><\/tr><tr><td class=\"has-text-align-right\" data-align=\"right\">33 34 35 36 37 38 39&nbsp;40<\/td><td>40 00 00 00 00 00 00&nbsp;00<\/td><td>Start of the pro\u00adgram head\u00aders (from byte 64 on rel\u00ada\u00adtive to the begin\u00adning of the&nbsp;file.)<\/td><\/tr><tr><td class=\"has-text-align-right\" data-align=\"right\">41 42 43 44 45 46 47&nbsp;48<\/td><td>68 37 02 00 00 00 00&nbsp;00<\/td><td>Start of the sec\u00adtion head\u00aders (from byte  <code>0x023768 = 145256<\/code> on rel\u00ada\u00adtive to the begin\u00adning of the&nbsp;file.)<\/td><\/tr><tr><td class=\"has-text-align-right\" data-align=\"right\">49 50 51&nbsp;52<\/td><td>00 00 00&nbsp;00<\/td><td>Proces\u00adsor&nbsp;flags<\/td><\/tr><tr><td class=\"has-text-align-right\" data-align=\"right\">53 54<\/td><td>40 00<\/td><td>Size of this head\u00ader head\u00ader (until byte 64; kind of use\u00adless&nbsp;here)<\/td><\/tr><tr><td class=\"has-text-align-right\" data-align=\"right\">55 56<\/td><td>38 00<\/td><td>Size of the pro\u00adgram head\u00aders: <code>0x38 = 56<\/code> byte.<\/td><\/tr><tr><td class=\"has-text-align-right\" data-align=\"right\">57 58<\/td><td>0b 00<\/td><td>Num\u00adber of pro\u00adgram head\u00aders: <code>11<\/code><\/td><\/tr><tr><td class=\"has-text-align-right\" data-align=\"right\">59 60<\/td><td>40 00<\/td><td>Size of sec\u00adtion head\u00aders: <code>0x40 = 64 <\/code>byte.<\/td><\/tr><tr><td class=\"has-text-align-right\" data-align=\"right\">61 62<\/td><td>1e 00<\/td><td>Num\u00adber of sec\u00adtion head\u00aders: <code>30<\/code><\/td><\/tr><tr><td class=\"has-text-align-right\" data-align=\"right\">63 64<\/td><td>1d 00<\/td><td>Index of sec\u00adtion head\u00ader string table: <code>29<\/code><\/td><\/tr><\/tbody><\/table><figcaption><span class=\"caps\">ELF<\/span> head\u00ader explained<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">This infor\u00adma\u00adtion can also be obtained with <code>readelf -h \/bin\/ls<\/code>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"caps\">ELF<\/span> symbols<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A <em>sym\u00adbol<\/em> is a ref\u00ader\u00adence to code or data like a vari\u00adable or func\u00adtion. There are usu\u00adal\u00adly two sec\u00adtions with sym\u00adbol tables:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><code>.symtab<\/code> con\u00adtains all sym\u00adbols&nbsp;and<\/li><li><code>.dynsym<\/code> con\u00adtains only the dynam\u00adic \/ glob\u00adal symbols.<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Note that <code>.symtab<\/code> con\u00adtains also all sym\u00adbols from<code> .dynsym<\/code>. The sym\u00adbols in <code>.dynsym<\/code> are all sym\u00adbols need\u00aded at run\u00adtimes. Sym\u00adbols in <code>.symtab<\/code> can also be sym\u00adbols from func\u00adtions which were nev\u00ader called (e.g. from a library). There\u00adfore, some bina\u00adries strip the <code>.symtab<\/code> sec\u00adtion alto\u00adgeth\u00ader, which makes debug\u00adging hard\u00ader but does\u00adn\u2019t affect execution.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"caps\">ELF<\/span> relocation<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Relo\u00adca\u00adtion is a tech\u00adnique to resolve sym\u00adbol ref\u00ader\u00adences. If a <span class=\"caps\">ELF<\/span> object ref\u00ader\u00adences a func\u00adtion in anoth\u00ader library, the ref\u00ader\u00adence is com\u00adpiled with a place\u00adhold\u00ader. As soon as it is com\u00adpiled into an exe\u00adcutable bina\u00adry, the link\u00ader resolves the place\u00adhold\u00aders and ref\u00ader\u00adences the address\u00ades where the shared library is placed in the pro\u00adgram\u2019s memory.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Exam\u00adple: Com\u00adpile the fol\u00adlow\u00ading C&nbsp;code<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme data-enlighter-highlight data-enlighter-linenumbers data-enlighter-lineoffset data-enlighter-title data-enlighter-group>_start() {\nfoo();\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">with <code>gcc -nostdlib -shared ref1.c -o ref1<\/code> and dis\u00adsas\u00adsem\u00adble the binary:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Disassembly of section .plt:\n\n0000000000001000 &lt;.plt&gt;:\n    1000:\tff 35 02 30 00 00    \tpushq  0x3002(%rip)        # 4008 &lt;_GLOBAL_OFFSET_TABLE_+0x8&gt;\n    1006:\tff 25 04 30 00 00    \tjmpq   *0x3004(%rip)        # 4010 &lt;_GLOBAL_OFFSET_TABLE_+0x10&gt;\n    100c:\t0f 1f 40 00          \tnopl   0x0(%rax)\n\n0000000000001010 &lt;foo@plt&gt;:\n    1010:\tff 25 02 30 00 00    \tjmpq   *0x3002(%rip)        # 4018 &lt;foo&gt;\n    1016:\t68 00 00 00 00       \tpushq  $0x0\n    101b:\te9 e0 ff ff ff       \tjmpq   1000 &lt;.plt&gt;\n\nDisassembly of section .text:\n\n0000000000001020 &lt;_start&gt;:\n    1020:\t55                   \tpush   %rbp\n    1021:\t48 89 e5             \tmov    %rsp,%rbp\n    1024:\tb8 00 00 00 00       \tmov    $0x0,%eax\n    1029:\te8 e2 ff ff ff       \tcallq  1010 &lt;foo@plt&gt;\n    102e:\t90                   \tnop\n    102f:\t5d                   \tpop    %rbp\n    1030:\tc3                   \tretq<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">See also<\/h2>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/andreas-klingler.de\/infosec\/?p=2793\" data-type=\"post\" data-id=\"2793\">Reverse Engi\u00adneer\u00ading tools for the Lin\u00adux&nbsp;<span class=\"caps\">ELF<\/span><\/a><\/li><li><a href=\"https:\/\/andreas-klingler.de\/infosec\/?p=2806\" data-type=\"post\" data-id=\"2806\">Bina\u00adry patching<\/a><\/li><li><a href=\"http:\/\/Binary injection\">Bina\u00adry injection<\/a><\/li><\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Con\u00adcepts A seg\u00adment is a piece of a infor\u00adma\u00adtion which is mapped into the mem\u00ado\u00adry (of a process). A <span class=\"caps\">ELF<\/span> bina\u00adry can have zero or mul\u00adti\u00adple seg\u00adments. It defines also where the <span class=\"caps\">OS<\/span> should put it into the mem\u00ado\u00adry. Each seg\u00adment has a Pro\u00adgram Head\u00ader which describes the sec\u00adtions with\u00adin. A sec\u00adtion is a distinctive&nbsp;[\u2026]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"wp_typography_post_enhancements_disabled":false,"footnotes":""},"categories":[355],"tags":[356],"class_list":["post-2808","post","type-post","status-publish","format-standard","hentry","category-reverse-engineering","tag-elf"],"_links":{"self":[{"href":"https:\/\/infosec.andreas-klingler.de\/index.php?rest_route=\/wp\/v2\/posts\/2808","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/infosec.andreas-klingler.de\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/infosec.andreas-klingler.de\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/infosec.andreas-klingler.de\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/infosec.andreas-klingler.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2808"}],"version-history":[{"count":11,"href":"https:\/\/infosec.andreas-klingler.de\/index.php?rest_route=\/wp\/v2\/posts\/2808\/revisions"}],"predecessor-version":[{"id":2829,"href":"https:\/\/infosec.andreas-klingler.de\/index.php?rest_route=\/wp\/v2\/posts\/2808\/revisions\/2829"}],"wp:attachment":[{"href":"https:\/\/infosec.andreas-klingler.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2808"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/infosec.andreas-klingler.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2808"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/infosec.andreas-klingler.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2808"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}