-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsearch.xml
97 lines (50 loc) · 48.3 KB
/
search.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title>Relocation Table in ELF</title>
<link href="/2019/06/12/Relocation-Table-in-ELF/"/>
<url>/2019/06/12/Relocation-Table-in-ELF/</url>
<content type="html"><![CDATA[<p><strong><em>Have you ever wondered how <code>Type</code> and <code>Sym. Name</code> get calculated in the Relocation Table</em>?</strong></p><p>Using the classic <code>helloworld.c</code> program as an example again,</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><stdio.h></span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"Hello world!\n"</span>);</span><br><span class="line"> getchar();</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p><code>$ gcc -o helloworld helloworld.c</code></p><p>Let’s print out its relocation table.</p><p><code>$ readelf -r helloworld</code></p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">Relocation section '.rela.dyn' at offset 0x410 contains 8 entries:</span><br><span class="line"> Offset Info Type Sym. Value Sym. Name + Addend</span><br><span class="line">000000200db8 000000000008 R_X86_64_RELATIVE 630</span><br><span class="line">000000200dc0 000000000008 R_X86_64_RELATIVE 5f0</span><br><span class="line">000000201008 000000000008 R_X86_64_RELATIVE 201008</span><br><span class="line">000000200fd8 000100000006 R_X86_64_GLOB_DAT 0000000000000000 _ITM_deregisterTMClone + 0</span><br><span class="line">000000200fe0 000300000006 R_X86_64_GLOB_DAT 0000000000000000 __libc_start_main@GLIBC_2.2.5 + 0</span><br><span class="line">000000200fe8 000400000006 R_X86_64_GLOB_DAT 0000000000000000 __gmon_start__ + 0</span><br><span class="line">000000200ff0 000500000006 R_X86_64_GLOB_DAT 0000000000000000 _ITM_registerTMCloneTa + 0</span><br><span class="line">000000200ff8 000600000006 R_X86_64_GLOB_DAT 0000000000000000 __cxa_finalize@GLIBC_2.2.5 + 0</span><br><span class="line"></span><br><span class="line">Relocation section '.rela.plt' at offset 0x4d0 contains 1 entry:</span><br><span class="line"> Offset Info Type Sym. Value Sym. Name + Addend</span><br><span class="line">000000200fd0 000200000007 R_X86_64_JUMP_SLO 0000000000000000 puts@GLIBC_2.2.5 + 0</span><br></pre></td></tr></table></figure><p>Looking at the <a href="http://man7.org/linux/man-pages/man5/elf.5.html" target="_blank" rel="noopener">struct</a> for the Relocation entry, <code>Type</code> and <code>Sym. value</code>/<code>Sym. Name</code> aren’t amongst its attributes.</p><p>However, the man page for elf left a hint as to where we can find them,</p><blockquote><p>When the text refers to a relocation entry’s relocation type or symbol table index, it means the result of applying <code>ELF[32|64]_R_TYPE</code> or <code>ELF[32|64]_R_SYM</code>, respectively, to the entry’s <code>r_info</code> member.</p></blockquote><p><strong><em>What does it mean exactly?</em></strong></p><p>So basically <code>ELF[32|64]_R_TYPE</code> and <code>ELF[32|64]_R_SYM</code> are defined as macros, which take <code>r_info</code> as a parameter, and the result from each marco is the <code>Type</code> and <code>Sym. Name</code> respectively.</p><p>Below are the definition of both macros, we will pick the 64-bit version since this <code>helloworld</code> program is in 64-bit.</p><p><strong><em>elf.h</em></strong></p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">define</span> ELF64_R_SYM(i)((i) >> 32)</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> ELF64_R_TYPE(i)((i) & 0xffffffff)</span></span><br></pre></td></tr></table></figure><p>Take the reloation entry for <code>puts</code> for example, put <code>000200000007</code> in place of <code>i</code> in <code>((i) >> 32)</code>, the result is <code>2</code>. This is an index into the symbol table below. <code>puts</code> right sitting at the second index there, and its value can be retrieved as well in one go.</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">readelf -s helloworld</span><br><span class="line"></span><br><span class="line">Symbol table '.dynsym' contains 7 entries:</span><br><span class="line"> Num: Value Size Type Bind Vis Ndx Name</span><br><span class="line"> 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND</span><br><span class="line"> 1: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterTMCloneTab</span><br><span class="line"> 2: 0000000000000000 0 FUNC GLOBAL DEFAULT UND puts@GLIBC_2.2.5 (2)</span><br><span class="line"> 3: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.2.5 (2)</span><br><span class="line"> 4: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__</span><br><span class="line"> 5: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_registerTMCloneTable</span><br><span class="line"> 6: 0000000000000000 0 FUNC WEAK DEFAULT UND __cxa_finalize@GLIBC_2.2.5 (2)</span><br></pre></td></tr></table></figure><p>Next, the <code>Type</code>.</p><p>Put <code>000200000007</code> in place of <code>i</code> in the second macro <code>((i) & 0xffffffff)</code>, the result is <code>7</code>.</p><p>Look up this number in the following table, the type is <code>R_X86_64_JUMP_SLOT</code>.</p><p><strong><em>elf.h</em></strong></p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* AMD x86-64 relocations. */</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> R_X86_64_NONE0<span class="comment">/* No reloc */</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> R_X86_64_641<span class="comment">/* Direct 64 bit */</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> R_X86_64_PC322<span class="comment">/* PC relative 32 bit signed */</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> R_X86_64_GOT323<span class="comment">/* 32 bit GOT entry */</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> R_X86_64_PLT324<span class="comment">/* 32 bit PLT address */</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> R_X86_64_COPY5<span class="comment">/* Copy symbol at runtime */</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> R_X86_64_GLOB_DAT6<span class="comment">/* Create GOT entry */</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> R_X86_64_JUMP_SLOT7<span class="comment">/* Create PLT entry */</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> R_X86_64_RELATIVE8<span class="comment">/* Adjust by program base */</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> R_X86_64_GOTPCREL9<span class="comment">/* 32 bit signed PC relative</span></span></span><br></pre></td></tr></table></figure><p>Hope you enjoyed.</p><p><br></p><blockquote><p><strong><em>What is a symbol?</em></strong> </p><p>A symbol is a name assigned to an entity in your code.<br>A variable name is a symbol, a function name is a symbol, it is basically a tag to a thing.</p><p><strong><em>What is a Relocation Table?</em></strong> </p><p>A Relocation Table is a table that tells a linker which location in the code needs to be patched with the symbol’s real memory address. So in the final machine code, when the CPU needs to access the value of a symbol, it just go to that memory address. This is the only thing it cares about.</p><p>Put it in the real world, it is not possible to find Sam Smith’s home by just saying <em>“Sending this letter to Sam’s house”</em>. The address has to be physical. </p><p>Same story for programming. You got the point.</p></blockquote>]]></content>
<tags>
<tag> ELF </tag>
<tag> Relocation Table </tag>
</tags>
</entry>
<entry>
<title>A Guide to hexdump</title>
<link href="/2019/06/06/A-Guide-to-hexdump/"/>
<url>/2019/06/06/A-Guide-to-hexdump/</url>
<content type="html"><![CDATA[<p>hexdump is a fantastic tool when one needs to dump information from a Linux binary file.</p><p>In my case, it helps me to see how the symbol table (<code>.symtab</code>) is organized in the binary form, so that various tools like <code>readelf</code> can make sense of the raw bytes stored there, and present them in a human readable form to the end users according to some predefined rules. </p><h2 id="Intro"><a href="#Intro" class="headerlink" title="Intro"></a>Intro</h2><p>First of all, instead of jumping directly to hexdump, I would like to spend some words on the context that <code>hexdump</code> is going to deal with.</p><p>Since this post is a demonstration on analysing symbol table using <code>hexdump</code>, let’s first take a look at what a symbol table is, and where we can find it and how to make sense of the information in it.</p><p><strong>Let’s get started!</strong></p><p>Given a classic helloworld.c, let’s compile it and use the <code>helloworld</code> binary produced for this demo.</p><p><code>$ gcc -o helloworld helloworld.c</code></p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta"># <span class="meta-keyword">include</span> <span class="meta-string"><stdio.h></span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"Hello world!"</span>);</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>Let’s print out its sections using <code>readelf</code>.</p><p><code>$ readelf -s helloworld</code></p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">Symbol table '.dynsym' contains 7 entries:</span><br><span class="line"> Num: Value Size Type Bind Vis Ndx Name</span><br><span class="line">[...]</span><br><span class="line"></span><br><span class="line">Symbol table '.symtab' contains 63 entries:</span><br><span class="line"> Num: Value Size Type Bind Vis Ndx Name</span><br><span class="line"> 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND</span><br><span class="line"> 1: 0000000000000238 0 SECTION LOCAL DEFAULT 1</span><br><span class="line">[...]</span><br><span class="line"> 26: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c</span><br><span class="line"> 27: 0000000000000560 0 FUNC LOCAL DEFAULT 14 deregister_tm_clones</span><br><span class="line">[...]</span><br></pre></td></tr></table></figure><p><strong><em>Figure 1.</em></strong></p><p><code>readelf -s</code> prints out all the sections of a ELF file, symbol table is one of them.</p><p>Looking at above output, one thing confuses me though is the <code>Name</code> column - there isn’t an attribute in the symbol struct that says <code>Name</code> (see symbol struct below).</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> {</span></span><br><span class="line"> <span class="keyword">uint32_t</span> st_name;</span><br><span class="line"> <span class="keyword">unsigned</span> <span class="keyword">char</span> st_info;</span><br><span class="line"> <span class="keyword">unsigned</span> <span class="keyword">char</span> st_other;</span><br><span class="line"> <span class="keyword">uint16_t</span> st_shndx;</span><br><span class="line"> Elf64_Addr st_value;</span><br><span class="line"> <span class="keyword">uint64_t</span> st_size;</span><br><span class="line">} Elf64_Sym;</span><br></pre></td></tr></table></figure><p><strong><em>Figure 2.</em></strong></p><p>Some would argue that the first element <code>st_name</code> is the symbol name. However, that’s not true.</p><blockquote><p><code>man elf.h</code> - This member (st_name) holds an index into the object file’s symbol string table, which holds character representations of the symbol names.</p></blockquote><p>Let’s put it another way. Basically this member is an integer, which is acting as an index into the <code>.strtab</code> section, that contains all the symbols used in this binary.</p><p>So the <code>readelf</code> command might have taken a step further for us, which is to find the symbol name using the <code>st_name</code> index in the <code>.strtab</code>, and display it in the <code>Name</code> coloumn.</p><p>To prove our speculation, we need a way to dump the symbol table to see what’s actually stored there. This is where <code>hexdump</code> comes in. </p><h2 id="Hexdump"><a href="#Hexdump" class="headerlink" title="Hexdump"></a>Hexdump</h2><p>First of all, let’s see where the symbol table resides in the binary file.</p><p><code>$ readelf -S helloworld</code></p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">There are 29 section headers, starting at offset 0x1930:</span><br><span class="line"></span><br><span class="line">Section Headers:</span><br><span class="line"> [Nr] Name Type Address Offset</span><br><span class="line"> Size EntSize Flags Link Info Align</span><br><span class="line"> [ 0] NULL 0000000000000000 00000000</span><br><span class="line"> 0000000000000000 0000000000000000 0 0 0</span><br><span class="line"> [...]</span><br><span class="line"> [26] .symtab SYMTAB 0000000000000000 00001040</span><br><span class="line"> 00000000000005e8 0000000000000018 27 43 8</span><br><span class="line"> [27] .strtab STRTAB 0000000000000000 00001628</span><br><span class="line"> 0000000000000208 0000000000000000 0 0 1</span><br></pre></td></tr></table></figure><p><strong><em>Figure 3</em></strong></p><p>It is located at offset <code>0x1040</code> in the file, with a size of <code>0x5e8</code> bytes. Let’s dump them out for further inspection.</p><p>But wait! I wanted more than just dump them as is to the console, I want them to be tailored.</p><p>Here is the plan.</p><p>As just mentioned, the symbol table has <code>0x5e8</code> bytes of data, and that essentially is comprised of a group of elements, each representing a symbol (per the symbol struct in <strong><em>Figure 2.</em></strong>). So ideally each and every element should be on its own line, with attributes of each element separated from each other by spaces for clarity.</p><p>After hours of experimenting, below is the command to achieve that,</p><p><code>$ hexdump -s 0x1040 -n 1512 -v -e '"%_ax# " 4/1 "%02x" " " /1 "%02x " /1 "%02x " 2/1 "%02x" " " 8/1 "%02x" " " 8/1 "%02x""\n"' helloworld</code></p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">1040# 00000000 00 00 0000 0000000000000000 0000000000000000</span><br><span class="line">1058# 00000000 03 00 0100 3802000000000000 0000000000000000</span><br><span class="line">1070# 00000000 03 00 0200 5402000000000000 0000000000000000</span><br><span class="line">[...]</span><br><span class="line">12b0# 01000000 04 00 f1ff 0000000000000000 0000000000000000</span><br><span class="line">12c8# 0c000000 02 00 0e00 6005000000000000 0000000000000000</span><br><span class="line">[...]</span><br><span class="line">1610# af010000 12 00 0b00 e804000000000000 0000000000000000</span><br></pre></td></tr></table></figure><p><strong><em>Figure 4</em></strong></p><p>Let’s look at line <code>12b0#</code>. This line should represents one of the symbols in the symbol table. Let’s see which one it is.</p><p>The data <code>01000000</code> in the second column corresponds to the <code>st_name</code> field. As we’ve already knew that this is an index into the string table <code>strtab</code>. So let’s check out the string table to see what is at index 1 there. We need to dump the string table (<code>.strtab</code>) the same way as we did on the symbol table.</p><p>From <strong><em>Figure 3</em></strong> we can see that the string table <code>.strtab</code> starts at <code>0x1628</code> and is <code>0x208</code> bytes long, let’s dump them out,</p><p><code>$ hexdump -C -s 0x1628 -n 520 helloworld</code></p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">00001628 00 63 72 74 73 74 75 66 66 2e 63 00 64 65 72 65 |.crtstuff.c.dere|</span><br><span class="line">00001638 67 69 73 74 65 72 5f 74 6d 5f 63 6c 6f 6e 65 73 |gister_tm_clones|</span><br><span class="line">00001648 00 5f 5f 64 6f 5f 67 6c 6f 62 61 6c 5f 64 74 6f |.__do_global_dto|</span><br><span class="line">00001658 72 73 5f 61 75 78 00 63 6f 6d 70 6c 65 74 65 64 |rs_aux.completed|</span><br></pre></td></tr></table></figure><p>It is very clear that the string that starts at index 1 is <code>crtstuff.c</code> (null-terminated), which matches the same in the <code>Name</code> column in <strong><em>Figure 1.</em></strong></p><p><strong>Bingo!</strong></p><p>Job well done <code>hexdump</code>! </p><h2 id="Further-Readings"><a href="#Further-Readings" class="headerlink" title="Further Readings"></a>Further Readings</h2><p>What we’ve gone through just now does seem to be a trivial utilization of <code>hexdump</code>. However, there still some pieces that were intentionally left out for the sake of continuity that need to be cleared (at least for someone new to <code>hexdump</code>).</p><p>The following content elaborates everything that I felt were obsured to me when attempting above task. So it will be a mixture of explaination to various <code>hexdump</code> options, as well as the intepretations of the attributes in the symbol table. It is not a required but highly recommanded section that will save you enormous effort experimenting each option, as well as going through all the examples in the man page.</p><ul><li><p>First of all, an explanation of all the options used in <strong><em>Figure 4</em></strong>.</p><blockquote><p><strong>_a[dox]</strong>: display offset culmutively. <code>[dox]</code> is to format the offset into decimal, octal, hex respectively. <code>#</code> is printed literaly.</p><p><strong>-s</strong>: Skip offset bytes from the beginning of the input. Accepts decimal/octal/hex number.</p><p><strong>-n</strong>: Interpret only length bytes of input (only accepts decimal number).</p><p><strong>-v</strong>: Without the -v option, any number of groups of output lines, which would be identical to the immediately preceding group of output lines (except for the input offsets), are replaced with a line comprised of a single asterisk.</p><p><strong>-e</strong>: Flag for format string.</p><p>The whole fomrat string following <code>-e</code> should be quoted in a pair of single quote(‘ ‘). A format string contains any number of format units, separated by whitespace. A format unit contains up to <strong>three</strong> items: an <strong>iteration count</strong>(ptional), a <strong>byte count</strong>(optional), and a <strong>format</strong>(required, must be surrounded by double quote (“ “).</p><p>Sometimes we will see a couple of <code>-e</code> flags in a row, that indicates the same byte will be applied with multiple format strings.</p><p>Check out this example.</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">>% echo hello | hexdump -e '8/1 "%02X ""\t"" "' -e '8/1 "%c""\n"'</span><br><span class="line">>68 65 6C 6C 6F 0A hello</span><br><span class="line">></span><br></pre></td></tr></table></figure></blockquote><blockquote><p><code>hello</code> will first be applied with format string <code>8/1 "%02X "</code> and then <code>8/1 "%c"</code>.</p><p>The first format string outputs <code>68 65 6C 6C 6F 0A</code> and the second outputs <code>hello</code>, with a tab (“\t”) in between.</p></blockquote></li><li><p>Now let’s move on to see how <code>iteration_count/byte_count format</code> collaborates together to produce the final result.</p><p> The original form of the binary data at offset <code>12b0#</code> is,</p><p> <code>010000000400f1ff00000000000000000000000000000000</code></p><p> When above is sent to the command in <strong><em>Figure 4</em></strong>,</p><ul><li><p>The first format string <code>"%_ax#"</code> outputs the offset <code>12b0#</code>.</p></li><li><p><code>4/1 "%02x"</code> applies format <code>"%02x"</code> on <code>1</code> byte <code>4</code> times. So basically it takes one byte at a time, apply the format, and repeat this 4 times. <code>02</code> dictates the minimum number of characters to be printed. If the value to be printed is shorter than this number, the result is padded with leading 0s.</p></li><li><p><code>" "</code> appends a space to above result.</p></li><li><p><code>/1</code> is equivalent to <code>1/1</code>, this is to apply the format once on a single byte.</p></li><li><p><code>\n</code> signifies the end of the format string(s). The remaining bytes will be processed starting from the 1st format string.</p><p>The original data will be eventually formatted into,</p><p><code>12b0# 01000000 04 00 f1ff 0000000000000000 0000000000000000</code></p><p>Per the symbol struct, the 2nd field is <code>st_name</code> which is 4 bytes long(<code>uint32_t</code>). It has the value <code>01000000</code> which basically is <code>1</code>. It is represented as little-endian, so the most significant byte is the right-most byte, and the least significant byte left-most. So the correct order to put it is: <code>00000001</code>, that’s the value of <code>1</code>. This <code>1</code> is an index into <code>.strtab</code>, that is the first character into this table.</p><p>The 3rd field is <code>st_info</code>, 1 byte, which specifies the symbol’s type and binding attributes. It has a value of <code>04</code>, so it is of type <code>FILE</code> and it binds to <code>LOCAL</code>.</p><p>The 4th field is <code>st_shndx</code>. Every symbol table entry is “defined” in relation to some section. This member holds the relevant section header table index. So basically it tells which section this symbol belongs to.</p><p>The 5th field is <code>st_value</code>, that is the address of the symbol in the binary file. If we look at line <code>27</code> (28th) line in <strong>Figure 2</strong>, the <code>deregister_tm_clones</code> symbol is located at address <code>560</code>, that is the offet where it can found in the file. </p></li></ul></li></ul><h2 id="Conclusion"><a href="#Conclusion" class="headerlink" title="Conclusion"></a>Conclusion</h2><p>As you get to know more and more about <code>hexdump</code>, you will find its power is not only limited to dealing with ELF binaries, but also in literally any tasks relating to binary files, for instance, <a href="https://www.suse.com/c/making-sense-hexdump/" target="_blank" rel="noopener">extracting partition table from a disk dump</a>.</p><p>I hope you will find this article helpful. Any comment is welcomed via email (before the comment function is sorted out in my blog).</p><p>GL & HF!</p><p><strong><em>References</em></strong></p><p><em><a href="http://man7.org/linux/man-pages/man5/elf.5.html" target="_blank" rel="noopener">http://man7.org/linux/man-pages/man5/elf.5.html</a></em></p><p><em><a href="http://man7.org/linux/man-pages/man1/hexdump.1.html" target="_blank" rel="noopener">http://man7.org/linux/man-pages/man1/hexdump.1.html</a></em></p>]]></content>
<tags>
<tag> hexdump </tag>
<tag> elf </tag>
<tag> reverse engineering </tag>
</tags>
</entry>
<entry>
<title>Facebook CTF 2019</title>
<link href="/2019/06/04/Facebook-CTF-2019/"/>
<url>/2019/06/04/Facebook-CTF-2019/</url>
<content type="html"><![CDATA[<p>Well, I’d admit this is kinda clickbait.</p><p>I have to say I laughed for 10 minutes when I spotted the following on the scoreboard in 2019 Facebook CTF.</p><p>I’d be very interested to see how dramatic it would be in June during Google CTF 2019.</p><p><em>“Google ranked 1st in Facebook CTF, just to advertise its coming CTF.”</em></p><p><br></p><img src="/2019/06/04/Facebook-CTF-2019/Googlewin.png">]]></content>
<categories>
<category> ctf </category>
</categories>
<tags>
<tag> ctf </tag>
</tags>
</entry>
<entry>
<title>hackme: Deconstructing an ELF File</title>
<link href="/2019/06/03/deconstructing-an-elf-file/"/>
<url>/2019/06/03/deconstructing-an-elf-file/</url>
<content type="html"><![CDATA[<p>This write-up complements the analysis of</p><blockquote><p><a href="http://manoharvanga.com/hackme/" target="_blank" rel="noopener">hackme: Deconstructing an ELF File</a></p></blockquote><p>There are a couple of reasons behind this,</p><ul><li>This is by far the most difficult ELF32 binary I’ve analysed, primarily because the symbols are stripped, making commands like <code>diassemble main</code> in gdb impossible.</li><li>The share library funcitons in libc.so referenced in this program are shwon as <code>ds:0xnnnnnnn</code>, which involves some work to guess who is who.</li><li>The original article does not show the correct password (however, works with some alternatives) in the first place, which will be worked out in this write-up.</li></ul><p>I’ve learned a lot when trying to analyse this binary, therefore, I wanted to note down the parts I think is important for future reference and help other people.</p><p>If you would like to give the binary a try, feel free to download it from the original webiste above.</p><p>In this write-up, I will give more words on analysing the logic of the binary pertaining to revealing the password.</p><p>Let’s get started!</p><p><strong>(BIG THANKS TO THE AUTHOR OF THE ORIGINAL ARTICLE! BTW)</strong></p><h2 id="The-Start"><a href="#The-Start" class="headerlink" title="The Start"></a>The Start</h2><p>Since the program has anit-debugger built-in, we need to preload a fake ptrace() function from our custom library to get around it, the steps are well-documented there, which won’t repeat there.</p><p>One thing I’d like to add though, is if we need to load it up in gdb for dynamic analysis, we can use the following command to set the <code>LD_PRELOAD</code> environment variable.</p><p><code>gdb-peda$ set environment LD_PRELOAD=./fake.so</code></p><p><code>gdb-peda$ run</code></p><p>Above assumes <code>gdb-peda</code> is used, and the custom <code>fake.so</code> share library is in the same directory as the <code>hackme</code> binary.</p><h2 id="Reversing-the-logic"><a href="#Reversing-the-logic" class="headerlink" title="Reversing the logic"></a>Reversing the logic</h2><p>As explained in the original write-up, the code that is pertaining to the password authentication can be narrowed down to the following snippet, which instead, will be annotated thoroughly in this post,</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br></pre></td><td class="code"><pre><span class="line"> 8048591:55 push ebp</span><br><span class="line"> 8048592:89 e5 mov ebp,esp</span><br><span class="line"> 8048594:57 push edi</span><br><span class="line"> 8048595:56 push esi</span><br><span class="line"> 8048596:53 push ebx</span><br><span class="line"> 8048597:81 ec 98 00 00 00 sub esp,0x98</span><br><span class="line"></span><br><span class="line"> ;Password, please?</span><br><span class="line"> 804859d:68 99 87 04 08 push 0x8048799</span><br><span class="line"></span><br><span class="line"> ;printf()</span><br><span class="line"> 80485a2:ff 15 94 99 04 08 call DWORD PTR ds:0x8049994</span><br><span class="line"></span><br><span class="line"> ;user input stored at [ebp-0x7c]</span><br><span class="line"> 80485a8:8d 45 84 lea eax,[ebp-0x7c]</span><br><span class="line"></span><br><span class="line"> ;0x8048799 stored in ebx</span><br><span class="line"> 80485ab:5b pop ebx</span><br><span class="line"> 80485ac:5e pop esi</span><br><span class="line"> 80485ad:50 push eax</span><br><span class="line"></span><br><span class="line"> ;%s</span><br><span class="line"> 80485ae:68 ac 87 04 08 push 0x80487ac</span><br><span class="line"></span><br><span class="line"> ;scanf()</span><br><span class="line"> 80485b3:ff 15 90 99 04 08 call DWORD PTR ds:0x8049990</span><br><span class="line"> 80485b9:83 c4 10 add esp,0x10</span><br><span class="line"></span><br><span class="line"> ;set eax to 0 to prepare for 80485c1</span><br><span class="line"> 80485bc:31 c0 xor eax,eax</span><br><span class="line"></span><br><span class="line"> ;dlopen@plt is used as a base addr for jmp, dlopen@plt+0x1f1 = 80485c1</span><br><span class="line"> 80485be:eb 01 jmp 80485c1 <dlopen@plt+0x1f1></span><br><span class="line"></span><br><span class="line"> 80485c0:40 inc eax</span><br><span class="line"></span><br><span class="line"> ;user input stored at [ebp+eax*1-0x7c], increment eax to loop thru the string until the end ('\0')</span><br><span class="line"> 80485c1:80 7c 05 84 00 cmp BYTE PTR [ebp+eax*1-0x7c],0x0</span><br><span class="line"></span><br><span class="line"> 80485c6:75 f8 jne 80485c0 <dlopen@plt+0x1f0></span><br><span class="line"></span><br><span class="line"> ;after the end of user input is reached, proceed to the next</span><br><span class="line"> 80485c8:31 db xor ebx,ebx</span><br><span class="line"> </span><br><span class="line"> ;password should be 19 chars long</span><br><span class="line"> 80485ca:83 f8 13 cmp eax,0x13</span><br><span class="line"> 80485cd:0f 94 c3 sete bl;sete set if equal</span><br><span class="line"></span><br><span class="line"> ;esi=10</span><br><span class="line"> 80485d0:be 0a 00 00 00 mov esi,0xa</span><br><span class="line"></span><br><span class="line"> ; random() returns a random number (random#), which makes the remainder of random#/0x13 random.</span><br><span class="line"> ; it then picks the (remainder+1)th char in user input, and the 1-byte hex code positioned the same in the predefined sequence.</span><br><span class="line"> ; remainder decides the # of times eax will be applied with the loop (add + multiply itself)</span><br><span class="line"> ; user input will be xor'ed with the least 1-byte of the product of above step, to see if the result equals to predefined hex code in the same position.</span><br><span class="line"> ; above process is repeated 10 times, since the position picked in the user input is random, we need to make sure every char in user input satisfy above xor'ed check.</span><br><span class="line"> 80485d5:e8 b6 fd ff ff call 8048390 <random@plt></span><br><span class="line"> 80485da:b9 13 00 00 00 mov ecx,0x13</span><br><span class="line"></span><br><span class="line"> ;extend sign bit of eax to edx</span><br><span class="line"> 80485df:99 cdq </span><br><span class="line"></span><br><span class="line"> ;(edx:eax) / ecx, eax:quotient, edx:remainder</span><br><span class="line"> 80485e:f7 f9 idiv ecx</span><br><span class="line"> 80485e2:31 c0 xor eax,eax</span><br><span class="line"></span><br><span class="line"> ;take the remainder as an index, store the [remainder+1]th char from user input in edi,</span><br><span class="line"> ;and from the same poistion from predefined hex sequence at base addr 0x804869c, store it in cl</span><br><span class="line"> 80485e4:8a 8a 9c 86 04 08 mov cl,BYTE PTR [edx+0x804869c]</span><br><span class="line"> 80485ea:0f b6 7c 15 84 movzx edi,BYTE PTR [ebp+edx*1-0x7c]</span><br><span class="line"> 80485ef:42 inc edx</span><br><span class="line"></span><br><span class="line"> ;put edx+1 at ebp-0x8c</span><br><span class="line"> 80485f0:89 95 74 ff ff ff mov DWORD PTR [ebp-0x8c],edx</span><br><span class="line"> </span><br><span class="line"> ;set edx = 0</span><br><span class="line"> 80485f6:31 d2 xor edx,edx</span><br><span class="line"> 80485f8:eb 0c jmp 8048606 <dlopen@plt+0x236></span><br><span class="line"></span><br><span class="line">;eax starts from 0 here, eax *= 0x6d01788d, overflow might occur</span><br><span class="line"> 80485fa:69 c0 8d 78 01 6d imul eax,eax,0x6d01788d</span><br><span class="line"> 8048600:42 inc edx</span><br><span class="line"></span><br><span class="line">;eax += 12345</span><br><span class="line"> 8048601:05 39 30 00 00 add eax,0x3039</span><br><span class="line"> 8048606:3b 95 74 ff ff ff cmp edx,DWORD PTR [ebp-0x8c]</span><br><span class="line"> 804860c:7c ec jl 80485fa <dlopen@plt+0x22a></span><br><span class="line"></span><br><span class="line">;edi = one char in user input, eax is the final number</span><br><span class="line"> 804860e:31 f8 xor eax,edi</span><br><span class="line"></span><br><span class="line">;cl is the predefined hex sequence \xnn</span><br><span class="line"> 8048610:38 c1 cmp cl,al</span><br><span class="line"> 8048612:b8 00 00 00 00 mov eax,0x0</span><br><span class="line"></span><br><span class="line">;move eax to ebx if cl != al</span><br><span class="line"> 8048617:0f 45 d8 cmovne ebx,eax</span><br><span class="line"> 804861a:4e dec esi</span><br><span class="line"></span><br><span class="line">;jump back to random() to generate another random number if esi != 0</span><br><span class="line">;dec affects ZF flag</span><br><span class="line"> 804861b:75 b8 jne 80485d5 <dlopen@plt+0x205></span><br><span class="line"></span><br><span class="line"> 804861d:85 db test ebx,ebx</span><br><span class="line"> 804861f:a1 94 99 04 08 mov eax,ds:0x8049994</span><br><span class="line"></span><br><span class="line"> ;jump to Oops if ebx is 0</span><br><span class="line"> 8048624:74 0a je 8048630 <dlopen@plt+0x260></span><br><span class="line"> 8048626:83 ec 0c sub esp,0xc</span><br><span class="line"></span><br><span class="line"> ;Congratulations!</span><br><span class="line"> 8048629:68 af 87 04 08 push 0x80487af</span><br><span class="line"> 804862e:eb 08 jmp 8048638 <dlopen@plt+0x268></span><br><span class="line"> 8048630:83 ec 0c sub esp,0xc</span><br><span class="line"></span><br><span class="line"> ;Oops!</span><br><span class="line"> 8048633:68 c1 87 04 08 push 0x80487c1</span><br><span class="line"></span><br><span class="line"> ;address of printf() is moved into eax at 804861f</span><br><span class="line"> 8048638:ff d0 call eax</span><br><span class="line"> 804863a:83 c4 10 add esp,0x10</span><br><span class="line"> 804863d:8d 65 f4 lea esp,[ebp-0xc]</span><br><span class="line"> 8048640:5b pop ebx</span><br><span class="line"> 8048641:5e pop esi</span><br><span class="line"> 8048642:5f pop edi</span><br><span class="line"> 8048643:5d pop ebp</span><br><span class="line"> 8048644:c3 ret</span><br></pre></td></tr></table></figure><h2 id="Reversing-the-password"><a href="#Reversing-the-password" class="headerlink" title="Reversing the password"></a>Reversing the password</h2><p>The logic is clear now, let’s write a python script to do the reverse to reveal the password.</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#/usr/bin/env python3</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">reversing_password</span><span class="params">()</span>:</span></span><br><span class="line"></span><br><span class="line"> <span class="comment"># hex sequence stored between 0x804869c - 0x80486ae (19 bytes)</span></span><br><span class="line"> predefval = [<span class="string">'0x6a'</span>, <span class="string">'0xfb'</span>, <span class="string">'0x4c'</span>, <span class="string">'0x8d'</span>, <span class="string">'0x58'</span>, <span class="string">'0x0f'</span>, <span class="string">'0xd4'</span>, <span class="string">'0xe8'</span>, <span class="string">'0x94'</span>,</span><br><span class="line"> <span class="string">'0x98'</span>, <span class="string">'0xee'</span>, <span class="string">'0x6b'</span>, <span class="string">'0x18'</span>,<span class="string">'0x30'</span>, <span class="string">'0xe0'</span>, <span class="string">'0x55'</span>, <span class="string">'0xc5'</span>, <span class="string">'0x28'</span>, <span class="string">'0x0e'</span>]</span><br><span class="line"></span><br><span class="line"> m = <span class="number">0</span></span><br><span class="line"> password = []</span><br><span class="line"></span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">0</span>, <span class="number">19</span>):</span><br><span class="line"> m *= int(<span class="string">'0x6d01788d'</span>, <span class="number">16</span>)</span><br><span class="line"> m += int(<span class="string">'0x3039'</span>, <span class="number">16</span>)</span><br><span class="line"></span><br><span class="line"> password.append(chr(int(hex(m)[<span class="number">-2</span>:], <span class="number">16</span>) ^ int(predefval[i][<span class="number">-2</span>:], <span class="number">16</span>)))</span><br><span class="line"></span><br><span class="line"> print(<span class="string">''</span>.join(password))</span><br><span class="line"></span><br><span class="line">reversing_password()</span><br></pre></td></tr></table></figure><p>Executing this script produces the following result,</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">$</span> hackme.py</span><br><span class="line">SesameOpenYourself!</span><br><span class="line"></span><br><span class="line"><span class="meta">$</span> ./hackme</span><br><span class="line">Password, please? SesameOpenYourself!</span><br><span class="line">Congratulations!</span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category> cyber_security </category>
<category> reverse_engineering </category>
</categories>
<tags>
<tag> reverse engineering </tag>
<tag> c </tag>
</tags>
</entry>
</search>