kenkeiras http://codigoparallevar.com/blog/ me@codigoparallevar.com Código para llevar tag:codigoparallevar.com/blog,2011-06-11:/atom/ http://codigoparallevar.com/blog/favicon.ico http://codigoparallevar.com/blog/feed-logo.png 2018-02-07T00:00:00Z acrylamid Clone this wiki tag:codigoparallevar.com/blog,2018-02-07:/2018/clone-this-wiki 2018-02-07T00:00:00Z kenkeiras http://codigoparallevar.com/blog/ me@codigoparallevar.com <p>Wow, a post after almost two years!</p> <p>I'm going to be brief to avoid taking hours to make a single post and going back to not writing.</p> <p>First things first, I setup <a href="https://wiki.codigoparallevar.com/">a wiki for personal references/notes</a> it's not thought to have refined or complete content, just fast tips to solve situations I encountered. It might be handy, it might not, it's your decision.</p> <p>I had a bit of fun making it as minimalistic as possible, and now it should run with only <code>sh</code> and a <code>markdown</code> to html compiler. All of this while being fully version-controlled by <code>git</code>. You can take a look at it on <a href="https://code.codigoparallevar.com/kenkeiras/clone-this-wiki">my gitea</a> or on <a href="https://github.com/kenkeiras/clone-this-wiki">github</a>. (Yep, content and "code" shares version control as there's really little code)</p> <p>Ok, with that out of the way...</p> <p>Lots of things happened lately, but in summary</p> <ul> <li> <p>I'll start writting back, now in english. It's not harder and saves me the effort of translating every post, which was what made me stop in the first place.</p> </li> <li> <p>Posts will get smaller, and i'll cover mostly my own projects. Doing comprehensive writeups take a loooong time so (unless something is <em>very</em> interesting) I won't be doing more. Also, tips and how-to's will go to the wiki but i'll try to add an entry here just to link back.</p> </li> </ul> <p>That is the plan anyway ¯\_(ツ)_/¯</p> <p>Saw that? A post written in ~30 minutes, that's much better that 2 days for a writeup :D!</p> Primer batch de tweetcodes (1 - 10) tag:codigoparallevar.com/blog,2016-03-13:/2016/primer-batch-de-tweetcodes-1-10 2016-03-13T20:45:00Z kenkeiras http://codigoparallevar.com/blog/ me@codigoparallevar.com <p>Desde finales de enero estoy publicando un <code>tweetcode</code> al día en <a href="https://gnusocial.net/oneliners/all">gnusocial (@oneliners)</a>, y en <a href="https://twitter.com/twtcodes">twitter (@twtcodes)</a>. El concepto viene de una idea que tuvo <a href="https://twitter.com/hacklego">@hacklego</a> para <a href="http://hackliza.blogspot.com.es/">hackliza</a>: <a href="http://hackliza.blogspot.com.es/p/twitcodes-que-son.html">un twitcode sería</a> un pequeño codigo, de no más de 140 caracteres, que tenga alguna utilidad. Parte de la idea, era también dar una explicación de como funciona, así que ahora que va más de un mes de estos <code>twitcodes</code>, toca empezar a explicarlos. Veamos...</p> <h3>1. Colorear 0s y 1s</h3> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1</pre></div></td><td class="code"><div class="highlight"><pre>sed <span class="s1">&#39;s/1/\x1b\[1;32m1/g&#39;</span><span class="p">|</span>sed <span class="s1">&#39;s/0/\x1b\[1;31m0/g&#39;</span><span class="p">|</span>sed <span class="s1">&#39;s/\x1b\[1;3[12]m[01]/&amp;\x1b\[0m/g&#39;</span> </pre></div> </td></tr></table> <p><img alt="" src="https://codigoparallevar.com/files/tweetcodes/1.png"/><br /> En <a href="https://gnusocial.net/notice/342827">gnusocial</a>, <a href="https://twitter.com/twtcodes/status/691538925823856640">twitter</a>.</p> <p><strong>Desglose:</strong> </p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1 2 3</pre></div></td><td class="code"><div class="highlight"><pre>sed <span class="s1">&#39;s/1/\x1b\[1;32m1/g&#39;</span> <span class="p">|</span> <span class="c"># Colorea los 1s de verde</span> sed <span class="s1">&#39;s/0/\x1b\[1;31m0/g&#39;</span> <span class="p">|</span> <span class="c"># Colorea los 0s de rojo</span> sed <span class="s1">&#39;s/\x1b\[1;3[12]m[01]/&amp;\x1b\[0m/g&#39;</span> <span class="c"># A los 0 o 1 coloreados les añade un &quot;fin de color&quot;</span> </pre></div> </td></tr></table> <p>Ojo con el orden! la primera regexp no crea ningún 0 que la segunda pueda pisar.</p> <h3>2. Ordenar filas y mostrar el total</h3> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1</pre></div></td><td class="code"><div class="highlight"><pre>sort -rn<span class="p">|</span>awk <span class="s1">&#39;{ c+=1;t+=$1; print } END { print &quot;\nTotal of &quot; c &quot; = &quot; t }&#39;</span> </pre></div> </td></tr></table> <p><img alt="" src="https://codigoparallevar.com/files/tweetcodes/2.1.png"/><br /> En <a href="https://gnusocial.net/notice/345968">gnusocial</a>, <a href="https://twitter.com/twtcodes/status/691899325228699649">twitter</a>.</p> <p><strong>Desglose:</strong></p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1 2 3 4</pre></div></td><td class="code"><div class="highlight"><pre>sort -rn <span class="p">|</span> <span class="c"># Ordena los resultados numéricos de forma descendente</span> awk <span class="s1">&#39;{ c+=1;t+=$1; print }</span> <span class="s1"> END </span> <span class="s1"> { print &quot;\nTotal of &quot; c &quot; = &quot; t }&#39;</span> </pre></div> </td></tr></table> <p>El truco, claro, está en el awk</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1 2 3 4 5 6 7 8</pre></div></td><td class="code"><div class="highlight"><pre><span class="c1"># Por cada fila</span> <span class="p">{</span> <span class="nx">c</span><span class="o">+=</span><span class="mi">1</span><span class="p">;</span> <span class="c1"># Incrementa un contador de líneas</span> <span class="nx">t</span><span class="o">+=$</span><span class="mi">1</span><span class="p">;</span> <span class="c1"># Suma el valor de la primera fila al total</span> <span class="kr">print</span> <span class="c1"># Imprime la línea</span> <span class="p">}</span> <span class="nb">END</span> <span class="c1"># Después de haber procesado todas las líneas</span> <span class="p">{</span> <span class="kr">print</span> <span class="s2">&quot;\nTotal of &quot;</span> <span class="nx">c</span> <span class="s2">&quot; = &quot;</span> <span class="nx">t</span> <span class="p">}</span> <span class="c1"># Muestra el número de líneas y la suma total</span> </pre></div> </td></tr></table> <h3>3. Mostrar el espacio que ocupa cada directorio, gráficamente</h3> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1</pre></div></td><td class="code"><div class="highlight"><pre>du -d0 * 2&gt;/dev/null<span class="p">|</span>gnuplot -p -e <span class="s1">&#39;set xtics nomirror ro by -45; plot &quot;/dev/stdin&quot; u 1:xticlabels(2) w boxes ti &quot;&quot;&#39;</span> </pre></div> </td></tr></table> <p><img alt="" src="https://codigoparallevar.com/files/tweetcodes/3.png"/><br /> En <a href="https://gnusocial.net/notice/349406">gnusocial</a>, <a href="https://twitter.com/twtcodes/status/692262875608539137">twitter</a>.</p> <p><strong>Desglose:</strong> </p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1 2</pre></div></td><td class="code"><div class="highlight"><pre>du -d0 * 2&gt;/dev/null <span class="p">|</span> <span class="c"># Extrae el peso de cada directorio a partir del actual</span> gnuplot -p -e <span class="s1">&#39;set xtics nomirror ro by -45; plot &quot;/dev/stdin&quot; u 1:xticlabels(2) w boxes ti &quot;&quot;&#39;</span> </pre></div> </td></tr></table> <p>El script de gnuplot para generar la gráfica hace así:</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1 2 3 4 5</pre></div></td><td class="code"><div class="highlight"><pre><span class="k">set</span> <span class="nb">xtics</span> <span class="n">nomirror</span> <span class="n">ro</span> <span class="n">by</span> <span class="mi">-45</span> <span class="c"># Inclina las etiquetas del eje X (los directorios)</span> <span class="c"># (plot &quot;/dev/stdin&quot;) Get the data from stdin</span> <span class="c"># (u 1:xticlabels(2)) Use first column as the value and the second as the labels in X axis</span> <span class="c"># (w boxes) Plot the data as a barchart</span> <span class="c"># (ti &quot;&quot;) Set an empty title</span> </pre></div> </td></tr></table> <h3>4. Mostrar las IPs de un log</h3> <p><strong>Apache:</strong></p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1</pre></div></td><td class="code"><div class="highlight"><pre>sudo sh -c <span class="s1">&#39;for i in /var/log/apache2/acc*;do if echo $i|grep -q gz$;then zcat $i;else cat $i;fi;done&#39;</span><span class="p">|</span>cut -d<span class="se">\ </span> -f1<span class="p">|</span>sort<span class="p">|</span>uniq -c<span class="p">|</span>sort -rn </pre></div> </td></tr></table> <p><strong>Nginx:</strong></p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1</pre></div></td><td class="code"><div class="highlight"><pre>sudo sh -c <span class="s1">&#39;for i in /var/log/nginx/acc*;do if echo $i|grep -q gz$;then zcat $i;else cat $i;fi;done&#39;</span><span class="p">|</span>cut -d<span class="se">\ </span> -f1<span class="p">|</span>sort<span class="p">|</span>uniq -c<span class="p">|</span>sort -rn </pre></div> </td></tr></table> <p><img alt="" src="https://codigoparallevar.com/files/tweetcodes/4-apache.png"/><br /> En <a href="https://gnusocial.net/notice/352843">gnusocial</a>, <a href="https://twitter.com/twtcodes/status/692624721049948160">twitter</a>.</p> <p><strong>Desglose:</strong> </p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16</pre></div></td><td class="code"><div class="highlight"><pre>sudo sh -c <span class="c"># Pide permisos de root</span> <span class="k">for</span> i in /var/log/apache2/acc*<span class="p">;</span><span class="k">do</span> <span class="c"># Itera sobre los logs de acceso</span> <span class="c"># Usa `zcat` con los archivos comprimidos</span> <span class="k">if</span> <span class="nb">echo</span> <span class="nv">$i</span><span class="p">|</span>grep -q gz<span class="nv">$;</span><span class="k">then</span> zcat <span class="nv">$i</span> <span class="c"># y solo `cat` para archivos en texto plano</span> <span class="k">else</span> cat <span class="nv">$i</span> <span class="k">fi</span> <span class="k">done</span> <span class="p">|</span> cut -d<span class="se">\ </span> -f1 <span class="p">|</span> <span class="c"># Corta la primera columna (la IP)</span> sort <span class="p">|</span> <span class="c"># Ordena las entradas</span> uniq -c <span class="p">|</span> <span class="c"># Cuenta las entradas únicas</span> sort -rn <span class="c"># Ordena los resultados desendentemente</span> </pre></div> </td></tr></table> <h3>5. Sniffar a que host se connecta un cliente SSL</h3> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1</pre></div></td><td class="code"><div class="highlight"><pre><span class="nv">f</span><span class="o">=</span><span class="s1">&#39;ssl.handshake.extensions_server_name&#39;</span><span class="p">;</span> tshark -Y <span class="nv">$f</span> -Tfields -e <span class="nv">$f</span> </pre></div> </td></tr></table> <p><img alt="" src="https://codigoparallevar.com/files/tweetcodes/5.png"/><br /> En <a href="https://gnusocial.net/notice/356834">gnusocial</a>, <a href="https://twitter.com/twtcodes/status/693003044011773953">twitter</a>.</p> <p><strong>Desglose:</strong></p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1 2 3</pre></div></td><td class="code"><div class="highlight"><pre><span class="nv">f</span><span class="o">=</span><span class="s1">&#39;ssl.handshake.extensions_server_name&#39;</span> <span class="c"># El campo con la información</span> <span class="c"># Elimina los paquetes que no contienen el campo y lo imprimen</span> tshark -Y <span class="nv">$f</span> -Tfields -e <span class="nv">$f</span> </pre></div> </td></tr></table> <h3>6. Encontrar los paquetes necesarios para ejecutar un binario</h3> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1</pre></div></td><td class="code"><div class="highlight"><pre>deps<span class="o">()</span> <span class="o">{</span> <span class="k">for</span> i in <span class="sb">`</span>ldd <span class="s2">&quot;</span><span class="nv">$1</span><span class="s2">&quot;</span><span class="p">|</span>awk <span class="s1">&#39;{print $1}&#39;</span><span class="sb">`</span><span class="p">;</span><span class="k">do</span> apt-file -l search <span class="s2">&quot;</span><span class="nv">$i</span><span class="s2">&quot;</span> <span class="p">|</span> head -1<span class="p">;</span><span class="k">done</span> <span class="p">|</span> sort <span class="p">|</span> uniq<span class="p">;</span> <span class="o">}</span> </pre></div> </td></tr></table> <p><img alt="" src="https://codigoparallevar.com/files/tweetcodes/6.png"/><br /> En <a href="https://gnusocial.net/notice/365163">gnusocial</a>, <a href="https://twitter.com/twtcodes/status/694075687850893313">twitter</a>.</p> <p><strong>Desglose:</strong></p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1 2 3 4 5 6 7 8 9 10 11</pre></div></td><td class="code"><div class="highlight"><pre>deps<span class="o">()</span> <span class="o">{</span> <span class="k">for</span> i in <span class="sb">`</span>ldd <span class="s2">&quot;</span><span class="nv">$1</span><span class="s2">&quot;</span> <span class="p">|</span> <span class="c"># Itera sobre la lista de dependencias de librerías compartidas</span> awk <span class="s1">&#39;{print $1}&#39;</span> <span class="c"># se queda con el nombre del archivo</span> <span class="sb">`</span><span class="p">;</span><span class="k">do</span> apt-file -l search <span class="s2">&quot;</span><span class="nv">$i</span><span class="s2">&quot;</span> <span class="p">|</span> <span class="c"># Busca el archivo por nombre en APT-file</span> head -1<span class="p">;</span> <span class="c"># mantiene el primer resultado</span> <span class="k">done</span> <span class="p">|</span> sort <span class="p">|</span> <span class="c"># Ordena los resultados</span> uniq<span class="p">;</span> <span class="c"># filtra los repetidos</span> <span class="o">}</span> </pre></div> </td></tr></table> <h3>7. Descargar metadatos de un stream de radio</h3> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1</pre></div></td><td class="code"><div class="highlight"><pre><span class="n">r</span><span class="o">=</span><span class="n">get</span><span class="p">(</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span><span class="n">headers</span><span class="o">=</span><span class="p">{</span><span class="s">&#39;Icy-MetaData&#39;</span><span class="p">:</span><span class="mi">1</span><span class="p">},</span><span class="n">stream</span><span class="o">=</span><span class="bp">True</span><span class="p">);</span><span class="n">m</span><span class="o">=</span><span class="nb">int</span><span class="p">(</span><span class="n">r</span><span class="o">.</span><span class="n">headers</span><span class="p">[</span><span class="s">&#39;icy-metaint&#39;</span><span class="p">]);</span><span class="n">r</span><span class="o">.</span><span class="n">raw</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="n">m</span><span class="p">);</span><span class="k">print</span> <span class="n">r</span><span class="o">.</span><span class="n">raw</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="nb">ord</span><span class="p">(</span><span class="n">r</span><span class="o">.</span><span class="n">raw</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mi">1</span><span class="p">))</span><span class="o">*</span><span class="mi">16</span><span class="p">)</span> </pre></div> </td></tr></table> <p><img alt="" src="https://codigoparallevar.com/files/tweetcodes/7.png"/><br /> En <a href="https://gnusocial.net/notice/368341">gnusocial</a>, <a href="https://twitter.com/twtcodes/status/694437830442008576">twitter</a>.</p> <p><strong>Desglose:</strong> </p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1 2 3 4 5 6 7 8 9 10</pre></div></td><td class="code"><div class="highlight"><pre><span class="c">#!/usr/bin/env python</span> <span class="kn">from</span> <span class="nn">sys</span> <span class="kn">import</span> <span class="o">*</span> <span class="kn">from</span> <span class="nn">requests</span> <span class="kn">import</span> <span class="o">*</span> <span class="n">r</span> <span class="o">=</span> <span class="n">get</span><span class="p">(</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">headers</span><span class="o">=</span><span class="p">{</span><span class="s">&#39;Icy-MetaData&#39;</span><span class="p">:</span><span class="mi">1</span><span class="p">},</span> <span class="n">stream</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span> <span class="c"># Pide el stream, con los metadatos</span> <span class="n">m</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">r</span><span class="o">.</span><span class="n">headers</span><span class="p">[</span><span class="s">&#39;icy-metaint&#39;</span><span class="p">])</span> <span class="c"># icy-metaint indica cada cuantos elementos hay metadatos</span> <span class="n">r</span><span class="o">.</span><span class="n">raw</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="n">m</span><span class="p">)</span> <span class="c"># Se salta los `m` primeros bytes de no-metadatos</span> <span class="n">metalength</span> <span class="o">=</span> <span class="nb">ord</span><span class="p">(</span><span class="n">r</span><span class="o">.</span><span class="n">raw</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mi">1</span><span class="p">))</span><span class="o">*</span><span class="mi">16</span> <span class="c"># El primer byte indica la longitud, dividida entre 16</span> <span class="k">print</span> <span class="n">r</span><span class="o">.</span><span class="n">raw</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="n">metalength</span><span class="p">)</span> <span class="c"># Lee los metadatas, con la longitud indicada</span> </pre></div> </td></tr></table> <p><strong>Referencia:</strong> <a href="http://www.smackfu.com/stuff/programming/shoutcast.html">SmackFu: Shoutcast Metadata Protocol</a></p> <h3>8. Extraer el nombre de un volumen FAT</h3> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1 2 3 4 5 6 7 8 9 10</pre></div></td><td class="code"><div class="highlight"><pre><span class="k">def</span> <span class="nf">get</span><span class="p">(</span><span class="n">f</span><span class="p">):</span> <span class="c"># El byte 38 indica el tipo de partición FAT, 0x28 o 0x29 para FAT12 y FAT16</span> <span class="n">f</span><span class="o">.</span><span class="n">seek</span><span class="p">(</span><span class="mi">38</span><span class="p">)</span> <span class="n">sig</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="k">if</span> <span class="n">sig</span> <span class="ow">in</span> <span class="s">&#39;()&#39;</span><span class="p">:</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">43</span> <span class="c"># En FAT12/16, la etiqueta está en el offset 43</span> <span class="k">else</span><span class="p">:</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">71</span> <span class="c"># En FAT32, en el 71</span> <span class="n">f</span><span class="o">.</span><span class="n">seek</span><span class="p">(</span><span class="n">i</span><span class="p">)</span> <span class="k">return</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mi">11</span><span class="p">)</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span> <span class="c"># Lee 11 bytes a partir del offset</span> </pre></div> </td></tr></table> <p><img alt="" src="https://codigoparallevar.com/files/tweetcodes/8.png"/><br /> En <a href="https://gnusocial.net/notice/371296">gnusocial</a>, <a href="https://twitter.com/twtcodes/status/694804720871985152">twitter</a>.</p> <p><strong>Referencia:</strong> <a href="http://wiki.osdev.org/FAT#FAT_12_and_FAT_16">FAT - OSDev Wiki</a></p> <h3>9. Bencodear un objeto python</h3> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1</pre></div></td><td class="code"><div class="highlight"><pre><span class="n">j</span><span class="o">=</span><span class="s">&#39;&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">;</span><span class="n">e</span><span class="o">=</span><span class="k">lambda</span> <span class="n">x</span><span class="p">:</span><span class="nb">eval</span><span class="p">({</span><span class="mi">46</span><span class="p">:</span><span class="s">&quot;&#39;d</span><span class="si">%s</span><span class="s">e&#39;%j([e(k)+e(x[k])for k in x])&quot;</span><span class="p">,</span><span class="mi">45</span><span class="p">:</span><span class="s">&quot;&#39;l</span><span class="si">%s</span><span class="s">e&#39;%j(map(e,x))&quot;</span><span class="p">,</span><span class="mi">64</span><span class="p">:</span><span class="s">&quot;&#39;i</span><span class="si">%s</span><span class="s">e&#39;</span><span class="si">%x</span><span class="s">&quot;</span><span class="p">,</span><span class="mi">71</span><span class="p">:</span><span class="s">&quot;&#39;</span><span class="si">%s</span><span class="s">:&#39;</span><span class="si">%le</span><span class="s">n(x)+x&quot;</span><span class="p">}[</span><span class="nb">len</span><span class="p">(</span><span class="nb">dir</span><span class="p">(</span><span class="n">x</span><span class="p">))])</span> </pre></div> </td></tr></table> <p><img alt="" src="https://codigoparallevar.com/files/tweetcodes/9.png"/><br /> En <a href="https://gnusocial.net/notice/374683">gnusocial</a>, <a href="https://twitter.com/twtcodes/status/695163964142018560">twitter</a>.</p> <p><strong>Desglose:</strong> </p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1 2 3 4 5 6 7 8 9 10 11 12</pre></div></td><td class="code"><div class="highlight"><pre><span class="n">j</span><span class="o">=</span><span class="s">&#39;&#39;</span><span class="o">.</span><span class="n">join</span> <span class="n">e</span><span class="o">=</span><span class="k">lambda</span> <span class="n">x</span><span class="p">:</span><span class="nb">eval</span><span class="p">(</span> <span class="c"># Por cada elemento</span> <span class="p">{</span><span class="mi">46</span><span class="p">:</span> <span class="c"># Si es un diccionario (len(dir(dict)) == 46)</span> <span class="s">&quot;&#39;d</span><span class="si">%s</span><span class="s">e&#39;%j([e(k)+e(x[k])for k in x])&quot;</span><span class="p">,</span> <span class="c"># Concatena &quot;d&quot;, el bencode de claves, el de los valores y &quot;e&quot;</span> <span class="mi">45</span><span class="p">:</span> <span class="c"># Si es una lista (len(dir(list)) == 45)</span> <span class="s">&quot;&#39;l</span><span class="si">%s</span><span class="s">e&#39;%j(map(e,x))&quot;</span><span class="p">,</span> <span class="c"># Concatena &quot;l&quot;, el bencode de cada elemento y &quot;e&quot;</span> <span class="mi">64</span><span class="p">:</span> <span class="c"># Si es un entero (len(dir(list)) == 64)</span> <span class="s">&quot;&#39;i</span><span class="si">%s</span><span class="s">e&#39;</span><span class="si">%x</span><span class="s">&quot;</span><span class="p">,</span> <span class="c"># Concatena &quot;i&quot;, el número y &quot;e&quot;</span> <span class="mi">71</span><span class="p">:</span> <span class="c"># Si es un string (len(dir(list)) == 71)</span> <span class="s">&quot;&#39;</span><span class="si">%s</span><span class="s">:&#39;</span><span class="si">%le</span><span class="s">n(x)+x&quot;</span> <span class="c"># Concatena la lontigud de la cadena, &quot;:&quot; y la cadena</span> <span class="p">}[</span><span class="nb">len</span><span class="p">(</span><span class="nb">dir</span><span class="p">(</span><span class="n">x</span><span class="p">))])</span> <span class="c"># Los tipos se distinguen por el número de métodos a los que dan acceso (depende de la versión de python)</span> </pre></div> </td></tr></table> <p>Lo de utilizar el número de métodos es bastante sucio, pero sin eso resultaba imposible bajar de los 141, la otra versión era esta:</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1</pre></div></td><td class="code"><div class="highlight"><pre><span class="n">j</span><span class="o">=</span><span class="s">&#39;&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">;</span><span class="n">e</span><span class="o">=</span><span class="k">lambda</span> <span class="n">x</span><span class="p">:</span><span class="nb">eval</span><span class="p">({</span><span class="nb">dict</span><span class="p">:</span><span class="s">&quot;&#39;d</span><span class="si">%s</span><span class="s">e&#39;%j([e(k)+e(x[k])for k in x])&quot;</span><span class="p">,</span><span class="nb">list</span><span class="p">:</span><span class="s">&quot;&#39;l</span><span class="si">%s</span><span class="s">e&#39;%j(map(e,x))&quot;</span><span class="p">,</span><span class="nb">int</span><span class="p">:</span><span class="s">&quot;&#39;i</span><span class="si">%s</span><span class="s">e&#39;</span><span class="si">%x</span><span class="s">&quot;</span><span class="p">,</span><span class="nb">str</span><span class="p">:</span><span class="s">&quot;&#39;</span><span class="si">%s</span><span class="s">:&#39;</span><span class="si">%le</span><span class="s">n(x)+x&quot;</span><span class="p">}[</span><span class="nb">type</span><span class="p">(</span><span class="n">x</span><span class="p">)])</span> </pre></div> </td></tr></table> <p>Desglosado, lo unico que cambia es la forma de acceder a diccionario de strings a evaluar...</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1 2 3 4 5 6 7</pre></div></td><td class="code"><div class="highlight"><pre><span class="n">j</span><span class="o">=</span><span class="s">&#39;&#39;</span><span class="o">.</span><span class="n">join</span> <span class="n">e</span><span class="o">=</span><span class="k">lambda</span> <span class="n">x</span><span class="p">:</span><span class="nb">eval</span><span class="p">({</span> <span class="nb">dict</span><span class="p">:</span><span class="s">&quot;&#39;d</span><span class="si">%s</span><span class="s">e&#39;%j([e(k)+e(x[k])for k in x])&quot;</span><span class="p">,</span> <span class="nb">list</span><span class="p">:</span><span class="s">&quot;&#39;l</span><span class="si">%s</span><span class="s">e&#39;%j(map(e,x))&quot;</span><span class="p">,</span> <span class="nb">int</span><span class="p">:</span><span class="s">&quot;&#39;i</span><span class="si">%s</span><span class="s">e&#39;</span><span class="si">%x</span><span class="s">&quot;</span><span class="p">,</span> <span class="nb">str</span><span class="p">:</span><span class="s">&quot;&#39;</span><span class="si">%s</span><span class="s">:&#39;</span><span class="si">%le</span><span class="s">n(x)+x&quot;</span> <span class="p">}[</span><span class="nb">type</span><span class="p">(</span><span class="n">x</span><span class="p">)])</span> </pre></div> </td></tr></table> <h3>10. Mostrar un JSON de forma amigable</h3> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1</pre></div></td><td class="code"><div class="highlight"><pre><span class="n">python</span> <span class="o">-</span><span class="n">m</span> <span class="n">json</span><span class="o">.</span><span class="n">tool</span> </pre></div> </td></tr></table> <p><img alt="" src="https://codigoparallevar.com/files/tweetcodes/10.png"/><br /> En <a href="https://gnusocial.net/notice/377785">gnusocial</a>, <a href="https://twitter.com/twtcodes/status/695523026201419777">twitter</a>.</p> <p>Que simplemente funciona :p</p> Ajustando el brillo de la pantalla en Awesome tag:codigoparallevar.com/blog,2016-01-23:/2016/ajustando-el-brillo-de-la-pantalla-en-awesome 2016-01-23T21:31:00Z kenkeiras http://codigoparallevar.com/blog/ me@codigoparallevar.com <p>Poder cambiar la luminosidad de una pantalla siempre es algo práctico, para ajustarla cuando hay más o menos luz, o incluso apagarla para que un portatil siga procesando sin la pantalla encendida. Esto suele funcionar solo cuando utilizamos un entorno como KDE o Gnome, pero puede que no sea así si no utilizamos ciertos drivers o si preferimos entornos más configurables (como <a href="http://awesome.naquadah.org/">awesome</a>).</p> <p>Si preferimos hacerlo a mano, podemos desde la línea de comandos en <strong><code>/sys/class/backlight/</code></strong>, en el directorio de cada dispositivo hay un archivo <strong><code>brightness</code></strong> que marca el brillo actual (y que acepta cambios) y otro, <strong><code>max_brightness</code></strong>, donde indica el valor máximo que acepta, por ejemplo. <!-- more --></p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15</pre></div></td><td class="code"><div class="highlight"><pre><span class="c"># Buscamos el dispositivo disponible</span> <span class="nv">$ </span>ls /sys/class/backlight/ radeon_bl0 <span class="c"># Brillo actual</span> <span class="nv">$ </span>cat /sys/class/backlight/radeon_bl0/brightness 100 <span class="c"># Brillo máximo</span> <span class="nv">$ </span>cat /sys/class/backlight/radeon_bl0/max_brightness 255 <span class="c"># Ponemos el brillo al máximo. Ojo! hace falta root</span> <span class="nv">$ </span><span class="nb">echo </span><span class="m">255</span> <span class="p">|</span> sudo tee /sys/class/backlight/radeon_bl0/brightness 255 </pre></div> </td></tr></table> <p>Sabiendo esto, podemos montar un scriptillo para que lo haga automáticamente, tendría que poder...</p> <p><strong>Listar los dispositivos</strong>:</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1 2</pre></div></td><td class="code"><div class="highlight"><pre><span class="k">def</span> <span class="nf">get_device_list</span><span class="p">():</span> <span class="k">return</span> <span class="n">os</span><span class="o">.</span><span class="n">listdir</span><span class="p">(</span><span class="s">&#39;/sys/class/backlight/&#39;</span><span class="p">)</span> </pre></div> </td></tr></table> <p><strong>Mostrar el brillo actual y el máximo</strong>:</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1 2 3 4 5 6 7</pre></div></td><td class="code"><div class="highlight"><pre><span class="k">def</span> <span class="nf">get_brightness</span><span class="p">(</span><span class="n">backlight</span><span class="p">):</span> <span class="k">return</span> <span class="nb">int</span><span class="p">(</span><span class="nb">open</span><span class="p">(</span><span class="s">&#39;/sys/class/backlight/{backlight}/brightness&#39;</span> <span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">backlight</span><span class="o">=</span><span class="n">backlight</span><span class="p">),</span> <span class="s">&#39;rt&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">read</span><span class="p">())</span> <span class="k">def</span> <span class="nf">get_max_brightness</span><span class="p">(</span><span class="n">backlight</span><span class="p">):</span> <span class="k">return</span> <span class="nb">int</span><span class="p">(</span><span class="nb">open</span><span class="p">(</span><span class="s">&#39;/sys/class/backlight/{backlight}/max_brightness&#39;</span> <span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">backlight</span><span class="o">=</span><span class="n">backlight</span><span class="p">),</span> <span class="s">&#39;rt&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">read</span><span class="p">())</span> </pre></div> </td></tr></table> <p><strong>Cambiar el brillo</strong>:</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1 2 3</pre></div></td><td class="code"><div class="highlight"><pre><span class="k">def</span> <span class="nf">set_brightness</span><span class="p">(</span><span class="n">backlight</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span> <span class="k">return</span> <span class="nb">open</span><span class="p">(</span><span class="s">&#39;/sys/class/backlight/{backlight}/brightness&#39;</span> <span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">backlight</span><span class="o">=</span><span class="n">backlight</span><span class="p">),</span> <span class="s">&#39;wt&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">value</span><span class="p">))</span> </pre></div> </td></tr></table> <p>Con esto ya podemos hacer un par de funciones para <strong>aumentar y disminuir el brillo</strong>:</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1 2 3 4 5 6 7 8 9 10 11 12</pre></div></td><td class="code"><div class="highlight"><pre><span class="k">def</span> <span class="nf">less</span><span class="p">(</span><span class="n">backlight</span><span class="p">):</span> <span class="n">brightness</span> <span class="o">=</span> <span class="n">get_brightness</span><span class="p">(</span><span class="n">backlight</span><span class="p">)</span> <span class="n">max_brightness</span> <span class="o">=</span> <span class="n">get_max_brightness</span><span class="p">(</span><span class="n">backlight</span><span class="p">)</span> <span class="n">set_brightness</span><span class="p">(</span><span class="n">backlight</span><span class="p">,</span> <span class="nb">max</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">brightness</span> <span class="o">-</span> <span class="nb">max</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">max_brightness</span> <span class="o">/</span> <span class="mi">10</span><span class="p">)))</span> <span class="k">def</span> <span class="nf">more</span><span class="p">(</span><span class="n">backlight</span><span class="p">):</span> <span class="n">brightness</span> <span class="o">=</span> <span class="n">get_brightness</span><span class="p">(</span><span class="n">backlight</span><span class="p">)</span> <span class="n">max_brightness</span> <span class="o">=</span> <span class="n">get_max_brightness</span><span class="p">(</span><span class="n">backlight</span><span class="p">)</span> <span class="n">set_brightness</span><span class="p">(</span><span class="n">backlight</span><span class="p">,</span> <span class="nb">max</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">brightness</span> <span class="o">+</span> <span class="nb">max</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">max_brightness</span> <span class="o">/</span> <span class="mi">10</span><span class="p">)))</span> </pre></div> </td></tr></table> <p>Le añadimos una función de ayuda y un main y está listo:</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18</pre></div></td><td class="code"><div class="highlight"><pre><span class="k">def</span> <span class="nf">show_help</span><span class="p">():</span> <span class="k">print</span><span class="p">(</span><span class="s">&#39;&#39;&#39;brightness.py (less|more) device</span> <span class="s">Devices:</span> <span class="s"> {}&#39;&#39;&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="s">&#39;</span><span class="se">\n</span><span class="s"> &#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">get_device_list</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="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">)</span> <span class="o">==</span> <span class="mi">3</span> <span class="ow">and</span> <span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="ow">in</span> <span class="p">(</span><span class="s">&#39;less&#39;</span><span class="p">,</span> <span class="s">&#39;more&#39;</span><span class="p">):</span> <span class="k">if</span> <span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">get_device_list</span><span class="p">():</span> <span class="k">print</span><span class="p">(</span><span class="s">&#39;Device {} not found&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">2</span><span class="p">]))</span> <span class="k">elif</span> <span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="s">&#39;less&#39;</span><span class="p">:</span> <span class="n">less</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">2</span><span class="p">])</span> <span class="k">elif</span> <span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="s">&#39;more&#39;</span><span class="p">:</span> <span class="n">more</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</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="n">show_help</span><span class="p">()</span> </pre></div> </td></tr></table> <p>Y el script está listo [ <a href="https://gitlab.com/kenkeiras/codigo-para-llevar/blob/master/python/brightness/brightness.py">brightness.py</a> ], pero hay un problema... para cambiar el brillo hacen falta permisos de root. Podemos ejecutar el script con <strong><code>sudo</code></strong>, pero podemos hacer que no sea necesario con <a href="https://en.wikipedia.org/wiki/Setuid">setuid</a>.</p> <p>El tema de usar <strong><code>setuid</code></strong> con python tiene truco, resulta que usarlo en scripts que indiquen el intérprete con <strong><code>#!</code></strong> <a href="https://en.wikipedia.org/wiki/Shebang_%28Unix%29#Security_issues">implica problemas de seguridad</a> y está desactivado en sistemas modernos. La solución es compilar el script, por ejemplo con <strong><code>cython</code></strong>.</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1 2 3 4 5 6 7 8</pre></div></td><td class="code"><div class="highlight"><pre><span class="c"># Compilamos el script a un .c</span> <span class="nv">$ </span>cython --embed brightness.py <span class="c"># Compilamos el brightness.c a un .o</span> <span class="nv">$ </span>gcc -c brightness.c -I/usr/include/python2.7 <span class="c"># Compilamos el brightness.o a un ejecutable</span> <span class="nv">$ </span>gcc -o brightness brightness.o -lpython2.7 </pre></div> </td></tr></table> <p><strong>OJO</strong>: gcc no require demasiados parámetros por que es un script sencillo, pero no tiene por que ser así, hay por ahí <a href="https://gitlab.com/kenkeiras/codigo-para-llevar/blob/master/python/brightness/Makefile">Makefiles más completos</a></p> <p>Una vez compilado ya podemos hacerlo <strong><code>setuid</code></strong> como root:</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1 2 3 4 5</pre></div></td><td class="code"><div class="highlight"><pre><span class="c"># Cambiamos el usuario a root</span> <span class="nv">$ </span>sudo chown root brightness <span class="c"># Activamos setuid</span> <span class="nv">$ </span>sudo chmod +s brightness </pre></div> </td></tr></table> <p>Así que con esto ya debería bastar:</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1 2 3 4 5 6 7 8 9 10 11 12</pre></div></td><td class="code"><div class="highlight"><pre><span class="c"># Listamos los dispositivos</span> <span class="nv">$ </span>./brightness brightness.py <span class="o">(</span>less<span class="p">|</span>more<span class="o">)</span> device Devices: radeon_bl0 <span class="c"># Aumentamos el brillo</span> <span class="nv">$ </span>./brightness more radeon_bl0 <span class="c"># Reducimos el brillo</span> <span class="nv">$ </span>./brightness less radeon_bl0 </pre></div> </td></tr></table> <p>Y ya podemos modificarlo con cualquier usuario desde la consola!</p> <p>Pero, y si tenemos un entorno de escritorio Awesome y queremos que funcionen las teclas de brillo? Pues eso es bastante sencillo, en el <strong><code>rc.lua</code></strong> hay una sección, <strong><code>clientkeys</code></strong>, donde podemos configurarlo:</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1 2 3 4 5</pre></div></td><td class="code"><div class="highlight"><pre><span class="n">clientkeys</span> <span class="o">=</span> <span class="n">awful</span><span class="p">.</span><span class="n">util</span><span class="p">.</span><span class="n">table</span><span class="p">.</span><span class="n">join</span><span class="p">(</span> <span class="n">awful</span><span class="p">.</span><span class="n">key</span><span class="p">({</span> <span class="p">},</span> <span class="s2">&quot;</span><span class="s">XF86MonBrightnessDown&quot;</span><span class="p">,</span> <span class="k">function</span> <span class="p">()</span> <span class="n">awful</span><span class="p">.</span><span class="n">util</span><span class="p">.</span><span class="n">spawn</span><span class="p">(</span><span class="s1">&#39;</span><span class="s">RUTA/AL/EJECUTABLE/brightness less DISPOSITIVO&#39;</span><span class="p">)</span> <span class="k">end</span><span class="p">),</span> <span class="n">awful</span><span class="p">.</span><span class="n">key</span><span class="p">({</span> <span class="p">},</span> <span class="s2">&quot;</span><span class="s">XF86MonBrightnessUp&quot;</span><span class="p">,</span> <span class="k">function</span> <span class="p">()</span> <span class="n">awful</span><span class="p">.</span><span class="n">util</span><span class="p">.</span><span class="n">spawn</span><span class="p">(</span><span class="s1">&#39;</span><span class="s">RUTA/AL/EJECUTABLE/brightness more DISPOSITIVO&#39;</span><span class="p">)</span> <span class="k">end</span><span class="p">),</span> </pre></div> </td></tr></table> <p>Y con esto ya estaría completo y podremos ajustar el brillo sin necesidad de ningún extra (más... :P).</p> <p>PD: el código, para hacer <strong><code>make</code></strong> y tirar millas está en <a href="https://gitlab.com/kenkeiras/codigo-para-llevar/tree/master/python/brightness">GitLab</a>.</p> Subuser: un Docker para el escritorio tag:codigoparallevar.com/blog,2015-12-30:/2015/subuser-un-docker-para-el-escritorio 2015-12-30T00:53:00Z kenkeiras http://codigoparallevar.com/blog/ me@codigoparallevar.com <p>Hoy andaba trasteando con <a href="https://www.docker.com/">Docker</a> e intentando hacer que corriera una aplicación de escritorio, <a href="https://stackoverflow.com/questions/16296753/can-you-run-gui-apps-in-a-docker-container">algo que no se puede hacer</a> sin salirse del flujo que se espera de esta herramienta.</p> <p>Docker es una plataforma que permite gestionar “contenedores”, algo similar a las máquinas virtuales de toda la vida, pero sin la sobrecarga de tener que simular otro sistema completo con su kernel y sus cosillas... Estos contenedores encontraron un entorno perfecto en los servidores, donde permiten montar más <a href="https://es.wikipedia.org/wiki/Servidor_virtual">VPS</a>, o donde permiten que cada <a href="https://en.wikipedia.org/wiki/Microservices">micro-servicio</a> corra de forma aislada sin necesidad de varias máquinas.</p> <p>Sin embargo estos sistemas no estan orientados a las máquinas de “escritorio”, y se portan especialmente mal con X11. Esto es así poque para que un programa funcione sobre X11 sería necesario levantar un socket desde el anfitrion, es decir, desde fuera del contenedor, algo que no se puede automatizar a través de estas herramientas (aunque si con un shell script). Otra solución es levantar un servidor VNC dentro del contenedor, pero podemos intuir que el rendimiento es “limitado” :P.</p> <p>Pues bien, hay un proyecto que pretende solventar este problema, este es <a href="http://subuser.org/">Subuser</a>. Podríamos decir, y ellos lo hacen, que Subuser es un <a href="https://www.qubes-os.org/">Qubes OS</a> ligero, simplemente da una capa de abstracción sobre Docker para permitir que aplicaciones de escritorio funcionen de forma transparente (o casi). Para ello implementaron <a href="http://subuser.org/news/0.3.html#the-xpra-x11-bridge">un puente para la interfaz gráfica</a>, y <a href="http://subuser.org/subuser-standard/permissions-dot-json-file-format.html#permissions">un sistema de gestión de permisos</a>.</p> <p>Podemos ver rápidamente como funciona, <a href="https://github.com/subuser-security/subuser#installation">la instalación</a> es muy sencilla, pero si usamos la rama <code>master</code> del git puede dar problemas, así que probablemente sea buena idea hacer checkout de <a href="https://github.com/subuser-security/subuser/releases">la última release</a></p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1</pre></div></td><td class="code"><div class="highlight"><pre><span class="nv">$ </span>git checkout 0.4 <span class="c"># Desde dentro del clon local, claro</span> </pre></div> </td></tr></table> <p>Una vez instalado el resto es bastante sencillo, por ejemplo, si queremos levantar una instancia de xterm</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37</pre></div></td><td class="code"><div class="highlight"><pre><span class="c"># Creamos un entorno para el contenedor </span> <span class="nv">$ </span>subuser subuser add sample-term xterm Adding subuser sample-term xterm Verifying subuser configuration. Verifying registry consistency... Unregistering any non-existant installed images. sample-term would like to have the following permissions: Description: A trivial terminal emulator Maintainer: Timothy Hobbs &lt;timothyhobbs <span class="o">(</span>at<span class="o">)</span> seznam dot cz&gt; Executable: /usr/bin/xterm Conservative permissions<span class="o">(</span>These are safe<span class="o">)</span>: - stateful-home: To have its own home directory where it can save files and settings. - inherit-locale: To find out language you speak and what region you live in. - inherit-timezone: To find out your current timezone. Moderate permissions<span class="o">(</span>These are probably safe<span class="o">)</span>: - gui: * To be able to display windows. * Is able to access the host<span class="s1">&#39;s clipboard.</span> <span class="s1"> * Is able to change the mouse&#39;</span>s cursor icon. - access-working-directory: To access the directory from which it was launched. - allow-network-access: To access the network/internet. A - Accept and apply changes E - Apply changes and edit result Please <span class="k">select</span> an option:A <span class="c"># Aquí aceptamos los permisos</span> Checking <span class="k">if</span> images need to be updated or installed... Checking <span class="k">if</span> subuser sample-term is up to date. Installing xterm ... Step <span class="m">0</span> : FROM bbbb9023163704cee9c1fcb403f74098c409f9103d0c54f6eda309c54f70a355 <span class="c"># Y se pone a montar el contenedor...</span> <span class="c"># este proceso puede ser lento la primera vez ya que tiene que</span> <span class="c"># montar las imágenes intermedias</span> <span class="c"># Una vez acaba, solo queda lanzar el contenedor</span> <span class="nv">$ </span>subuser run sample-term <span class="c"># Y en poco tiempo ya debería aparecer un xterm</span> </pre></div> </td></tr></table> <p>Pero claro, no solo vamos a utilizar imágenes que vengan por defecto, montar las nuestras es bastante sencillo. Yo buscaba como meter aplicaciones gráficas en containers para poder ejecutar juegos de forma segura, hacer una imágen para esto se reduce a:</p> <p>Crear un repositorio (un directorio donde meteremos todas las imágenes) y añadirlo as Subuser con</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1</pre></div></td><td class="code"><div class="highlight"><pre><span class="nv">$ </span>subuser repository add <span class="nb">local</span> ~/ruta/al/repositorio </pre></div> </td></tr></table> <p>Dentro del repositorio, creamos un directorio con el nombre que tendrá nuestra imágen, en el introduciremos un archivo <strong><code>permissions.json</code></strong> con la descripción del contenedor.</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1 2 3 4 5 6 7 8</pre></div></td><td class="code"><div class="highlight"><pre><span class="p">{</span> <span class="nt">&quot;description&quot;</span> <span class="p">:</span> <span class="s2">&quot;Graphic and sound enabled games.&quot;</span> <span class="p">,</span><span class="nt">&quot;maintainer&quot;</span> <span class="p">:</span> <span class="s2">&quot;kenkeiras &lt;kenkeiras (at) codigoparallevar dot com&gt;&quot;</span> <span class="p">,</span><span class="nt">&quot;executable&quot;</span> <span class="p">:</span> <span class="s2">&quot;/bin/bash&quot;</span> <span class="p">,</span><span class="nt">&quot;gui&quot;</span> <span class="p">:</span> <span class="p">{</span><span class="nt">&quot;cursors&quot;</span><span class="p">:</span><span class="kc">true</span><span class="p">}</span> <span class="p">,</span><span class="nt">&quot;sound-card&quot;</span> <span class="p">:</span> <span class="kc">true</span> <span class="p">,</span><span class="nt">&quot;basic-common-permissions&quot;</span> <span class="p">:</span> <span class="kc">true</span> <span class="p">}</span> </pre></div> </td></tr></table> <p>Nos interesa tener interfaz gráfica, sonido, el control del cursor y los <a href="http://subuser.org/subuser-standard/permissions-dot-json-file-format.html#conservative-permissions">permisos básicos</a>, estos últimos bastante “light”. Todos los permisos están explicados en <a href="http://subuser.org/subuser-standard/permissions-dot-json-file-format.html#permissions">la documentación</a>.</p> <p>Se puede observar que el ejecutable que se indica es <code>bash</code>, esto es así para poder instalar algo a posteriori, de forma manual, no es óptimo, pero en mi caso era necesario, en caso de preparar una imágen para un juego en concreto podríamos indicar ahí el comando a ejecutar.</p> <p>Y por último solo tendríamos que declarar en <strong><code>docker-image/SubuserImagefile</code></strong> como se generará el sistema de archivos del contenedor, en este caso sería suficiente con </p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1</pre></div></td><td class="code"><div class="highlight"><pre><span class="k">FROM</span><span class="s">-SUBUSER-IMAGE libx11@default</span> </pre></div> </td></tr></table> <p>Pero podría hacer cualquier cosa, es un <a href="https://docs.docker.com/engine/reference/builder/">Dockerfile</a>. Además: <strong>ojo</strong> con el <strong><code>@default</code></strong>, indica que deriva de una de las imágenes que vienen por defecto, es necesario ponerlo si no pertenecen al mismo repositorio.</p> <p>Y eso sería todo, ya podríamos lanzar nuestra imágen de la misma forma que hacemos con la de xterm, creando un entorno y después lanzandolo (pero añadiendo <strong><code>@local</code></strong> al nombre para indicar el repositorio).</p> TensorFlow con Python3 tag:codigoparallevar.com/blog,2015-11-29:/2015/tensorflow-con-python3 2015-11-29T20:30:00Z kenkeiras http://codigoparallevar.com/blog/ me@codigoparallevar.com <p><a href="https://tensorflow.org/">TensorFlow</a> es una librería Open Source que Google ha liberado a principios de este mes. Permite de forma sencilla montar flujos de procesado y entrenamiento con elementos como <a href="https://www.tensorflow.org/tutorials/mnist/beginners/index.html">redes neuronales</a>, e incluso implementar nuevas operaciones sobre su arquitectura (<a href="https://www.tensorflow.org/tutorials/index.html">tutorial</a> y <a href="https://github.com/aymericdamien/TensorFlow-Examples">ejemplos</a>).</p> <p>Esta librería está escrita en C++, pero la arquitectura, los datos a tratar y las operaciones se declaran en Python. Esto está genial, ya que da un gran rendimiento sin tener que pelearse con <code>Segmentation Faults</code>, pero si pensabas utilizar Python3 para esto... quizá tengas que esperar un poco, resulta que aún no está soportado [<a href="https://github.com/tensorflow/tensorflow/issues/1">issue #1 en el GitHub</a>], aunque tienen intención de hacerlo en algún momento.</p> <p>Mientras tanto, en <a href="https://github.com/kenkeiras/tensorflow/">este repo</a>, en la rama <a href="https://github.com/kenkeiras/tensorflow/tree/python3">python3</a> tenéis una forma de poder ir usándolo... no está totalmente actualizado y quedan cosas sin afinar, por ejemplo los checkpoints. Además hay que compilarlo a mano (no hay un paquete de pip ya preparado), pero ahora veremos que se puede hacer fácilmente.</p> <h3><strong>Bazel</strong></h3> <p>Bien, resulta que para compilar TensorFlow no basta con un <code>make</code> de toda la vida, sino que está preparado para hacerse con <a href="http://bazel.io/">bazel</a>. Instalar este es bastante sencillo, las instrucciones están en <a href="http://bazel.io/docs/install.html">bazel.io</a>. Una vez instaladas las dependencias, Bazel tiene un instalador que se puede ejecutar pipeando un <code>curl</code> de su script a una shell (ugh...) o clonando el repo, como pone en la web para esto último solo hace falta hacer</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1 2 3</pre></div></td><td class="code"><div class="highlight"><pre><span class="nv">$ </span>git clone https://github.com/bazelbuild/bazel.git <span class="nv">$ </span><span class="nb">cd </span>bazel <span class="nv">$ </span>./compile.sh </pre></div> </td></tr></table> <p>Esto generará el binario de Bazel en <code>bazel-bin/src/bazel</code>, que podemos mover al $PATH que queramos. Además tendremos un archivo para ayudar al autocompletado en <code>scripts/bazel-complete-template.bash</code>, que podemos añadir al <code>.bashrc</code> con una línea como esta</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1</pre></div></td><td class="code"><div class="highlight"><pre><span class="nv">$ </span><span class="nb">source</span> &lt;RUTA AL CÓDIGO DE BAZEL&gt;/scripts/bazel-complete-template.bash </pre></div> </td></tr></table> <h3><strong>Virtual environment</strong></h3> <p>Una vez tenemos preparado Bazel, tendremos que preparar el entorno virtual donde alojaremos todos los paquetes de los que depende TensorFlow, para esto solo hay que hacer</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15</pre></div></td><td class="code"><div class="highlight"><pre><span class="c"># Creamos el entorno virtual, por ejemplo en la ruta “tensorflow3-env”</span> <span class="c"># No tiene por que ser 3.4, otra versión de python3 puede funcionar</span> <span class="nv">$ </span>virtualenv-3.4 --system-site-packages tensorflow3-env Using base prefix <span class="s1">&#39;/usr&#39;</span> New python executable in tensorflow3-env/bin/python3 Not overwriting existing python script tensorflow3-env/bin/python <span class="o">(</span>you must use tensorflow3-env/bin/python3<span class="o">)</span> Installing setuptools, pip, wheel...done. <span class="c"># Lo activamos</span> <span class="nv">$ </span><span class="nb">source </span>tensorflow3-env/bin/activate <span class="c">#v-------------v podemos ver cuando estamos dentro del entorno virtual del python</span> <span class="o">(</span>tensorflow3-env<span class="o">)</span><span class="err">$</span> <span class="c"># Instalamos las dependencias de TensorFlow</span> <span class="o">(</span>tensorflow3-env<span class="o">)</span><span class="nv">$ </span>apt-get install python3-numpy swig python3-dev </pre></div> </td></tr></table> <h3><strong>TensorFlow</strong></h3> <p>Cuando el entorno ya está completamente listo, solo queda generar el paquete <a href="https://pip.pypa.io/en/stable/">pip</a>, <strong>pero ojo con este tema</strong>: parece que con GCC-5 el proceso consume demasiada memoria, así que hay que evitar paralelizarlo para que no atasque el PC. Así que si la versión de GCC es <strong>inferior a la 5</strong>, las órden será</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1 2</pre></div></td><td class="code"><div class="highlight"><pre><span class="c"># Preparar lo necesario para construír el paquete pip</span> <span class="o">(</span>tensorflow3-env<span class="o">)</span><span class="nv">$ </span>bazel build -c opt //tensorflow/tools/pip_package:build_pip_package </pre></div> </td></tr></table> <p>Para (<strong>en GCC 5</strong>), limitar la concurrencia del compilador, haremos</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1 2</pre></div></td><td class="code"><div class="highlight"><pre><span class="c"># Preparar lo necesario para construír el paquete pip</span> <span class="o">(</span>tensorflow3-env<span class="o">)</span><span class="nv">$ </span>bazel build --ram_utilization_factor<span class="o">=</span><span class="m">1</span> -c opt //tensorflow/tools/pip_package:build_pip_package </pre></div> </td></tr></table> <p>Una vez que esto acabó, podemos generar el paquete con</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1</pre></div></td><td class="code"><div class="highlight"><pre><span class="o">(</span>tensorflow3-env<span class="o">)</span><span class="nv">$ </span>bazel-bin/tensorflow/tools/pip_package/build_pip_package /tmp/tensorflow_pkg </pre></div> </td></tr></table> <p>El segundo parámetro especifica donde se dejará el paquete compilado (<code>/tmp/tensorflow_pkg</code>), podemos usar el que queramos (también borrarlo una vez esté instalado). Con todo ya listo y el paquete generado solo queda instalarlo con</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1</pre></div></td><td class="code"><div class="highlight"><pre><span class="o">(</span>tensorflow3-env<span class="o">)</span><span class="nv">$ </span>pip install /tmp/tensorflow_pkg/tensorflow-*.whl <span class="c"># El nombre del archivo puede cambiar</span> </pre></div> </td></tr></table> <p>Y listo, ya podemos utilizar esta librería</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1 2 3 4 5 6</pre></div></td><td class="code"><div class="highlight"><pre><span class="p">(</span><span class="n">tensorflow3</span><span class="o">-</span><span class="n">env</span><span class="p">)</span><span class="err">$</span> <span class="n">python3</span> <span class="n">Python</span> <span class="mf">3.4</span><span class="o">.</span><span class="mi">3</span><span class="o">+</span> <span class="p">(</span><span class="n">default</span><span class="p">,</span> <span class="n">Oct</span> <span class="mi">10</span> <span class="mi">2015</span><span class="p">,</span> <span class="mi">09</span><span class="p">:</span><span class="mi">15</span><span class="p">:</span><span class="mi">38</span><span class="p">)</span> <span class="p">[</span><span class="n">GCC</span> <span class="mf">5.2</span><span class="o">.</span><span class="mi">1</span> <span class="mi">20151028</span><span class="p">]</span> <span class="n">on</span> <span class="n">linux</span> <span class="n">Type</span> <span class="s">&quot;help&quot;</span><span class="p">,</span> <span class="s">&quot;copyright&quot;</span><span class="p">,</span> <span class="s">&quot;credits&quot;</span> <span class="ow">or</span> <span class="s">&quot;license&quot;</span> <span class="k">for</span> <span class="n">more</span> <span class="n">information</span><span class="o">.</span> <span class="o">&gt;&gt;&gt;</span> <span class="kn">import</span> <span class="nn">tensorflow</span> <span class="k">as</span> <span class="nn">tf</span> <span class="o">&gt;&gt;&gt;</span> <span class="c"># No hay problema!</span> </pre></div> </td></tr></table> El Julia set en un shader tag:codigoparallevar.com/blog,2015-11-16:/2015/el-julia-set-en-un-shader 2015-11-16T21:40:00Z kenkeiras http://codigoparallevar.com/blog/ me@codigoparallevar.com <p>Desde que empezó el tema de los smartphone, siempre sonó interesante la idea de programar desde el propio cacharro. Si bien ya se podía desde (casi?) el principio con <a href="https://github.com/damonkohler/sl4a">SL4A</a>, nunca fué algo demasiado cómodo.</p> <p>Pues bien, resulta que en <a href="https://f-droid.org/">F-Droid</a> (market de aplicaciones libres) tienen un entorno que permite programar <a href="https://es.wikipedia.org/wiki/Shader">Shaders</a> en <a href="https://en.wikipedia.org/wiki/GLSL">GLSL</a>, programas que permiten generar gráficos desde la GPU, e incluso utilizarlos como fondo de pantalla, <a href="https://f-droid.org/repository/browse/?fdfilter=shader+editor&amp;fdid=de.markusfisch.android.shadereditor">Shader Editor</a>.</p> <p>El programilla es bastante sencillo, y parece un buen método para aprender a hacer shaders, sabiendo por ejemplo C, y a partir de los ejemplos que incluye.</p> <p>Pues bien, ahí va algo programado cacharreando con esto en el tren, dibuja el <a href="https://en.wikipedia.org/wiki/Julia_set">conjunto de Julia</a>, moviendose en un par de dimensiones para que quede algo dinámico.</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72</pre></div></td><td class="code"><div class="highlight"><pre><span class="k">precision</span> <span class="k">mediump</span> <span class="k">float</span><span class="p">;</span> <span class="c1">// Time in ms</span> <span class="k">uniform</span> <span class="k">float</span> <span class="n">time</span><span class="p">;</span> <span class="c1">// Resolution in pixels</span> <span class="k">uniform</span> <span class="k">vec2</span> <span class="n">resolution</span><span class="p">;</span> <span class="c1">// Max number of iterations for scape alg.</span> <span class="k">const</span> <span class="k">int</span> <span class="n">max_its</span> <span class="o">=</span> <span class="mi">100</span><span class="p">;</span> <span class="c1">// Speed of the animation</span> <span class="k">const</span> <span class="k">float</span> <span class="n">sp</span> <span class="o">=</span> <span class="mf">20.</span><span class="p">;</span> <span class="cm">/* Match the number of iterations needed to scape</span> <span class="cm"> * to a color.</span> <span class="cm"> */</span> <span class="k">vec3</span> <span class="n">color</span><span class="p">(</span><span class="k">int</span> <span class="n">i</span><span class="p">){</span> <span class="k">float</span> <span class="n">f</span> <span class="o">=</span> <span class="k">float</span><span class="p">(</span><span class="n">max_its</span> <span class="o">-</span> <span class="n">i</span><span class="p">)</span> <span class="o">/</span> <span class="k">float</span><span class="p">(</span><span class="n">max_its</span><span class="p">);</span> <span class="k">return</span> <span class="k">vec3</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">f</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span> <span class="p">}</span> <span class="c1">// Escape time algorithm</span> <span class="k">int</span> <span class="n">iterations</span><span class="p">(</span><span class="k">float</span> <span class="n">x0</span><span class="p">,</span> <span class="k">float</span> <span class="n">x</span><span class="p">,</span> <span class="k">float</span> <span class="n">y0</span><span class="p">,</span> <span class="k">float</span> <span class="n">y</span><span class="p">){</span> <span class="k">int</span> <span class="n">i</span><span class="p">;</span> <span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mo">0</span><span class="p">;</span><span class="n">i</span> <span class="o">&lt;</span> <span class="n">max_its</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">){</span> <span class="k">float</span> <span class="n">x2</span> <span class="o">=</span> <span class="n">x</span> <span class="o">*</span> <span class="n">x</span><span class="p">;</span> <span class="k">float</span> <span class="n">y2</span> <span class="o">=</span> <span class="n">y</span> <span class="o">*</span> <span class="n">y</span><span class="p">;</span> <span class="k">if</span><span class="p">((</span><span class="n">x2</span> <span class="o">+</span> <span class="n">y2</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mf">4.</span><span class="p">){</span> <span class="k">return</span> <span class="n">i</span><span class="p">;</span> <span class="p">}</span> <span class="c1">// Yep, no complex numbers for us</span> <span class="k">float</span> <span class="n">tmp</span> <span class="o">=</span> <span class="n">x2</span> <span class="o">-</span> <span class="n">y2</span> <span class="o">+</span> <span class="n">x0</span><span class="p">;</span> <span class="n">y</span> <span class="o">=</span> <span class="mf">2.</span> <span class="o">*</span> <span class="n">x</span> <span class="o">*</span> <span class="n">y</span> <span class="o">+</span> <span class="n">y0</span><span class="p">;</span> <span class="n">x</span> <span class="o">=</span> <span class="n">tmp</span><span class="p">;</span> <span class="p">}</span> <span class="k">return</span> <span class="n">i</span><span class="p">;</span> <span class="p">}</span> <span class="k">void</span> <span class="n">main</span><span class="p">(</span> <span class="k">void</span> <span class="p">){</span> <span class="k">vec2</span> <span class="n">rs</span> <span class="o">=</span> <span class="n">resolution</span><span class="p">;</span> <span class="c1">// Size of the screen</span> <span class="c1">// Relevant for pixel-to-point mapping</span> <span class="k">vec2</span> <span class="n">xy</span> <span class="o">=</span> <span class="n">gl_FragCoord</span><span class="p">.</span><span class="n">xy</span><span class="p">;</span> <span class="c1">// Position of the pixel</span> <span class="c1">// Walk around the curve</span> <span class="k">float</span> <span class="n">x0</span> <span class="o">=</span> <span class="n">cos</span><span class="p">(</span><span class="n">time</span> <span class="o">/</span> <span class="n">sp</span><span class="p">)</span> <span class="o">*</span> <span class="mf">.70</span><span class="p">;</span> <span class="k">float</span> <span class="n">y0</span> <span class="o">=</span> <span class="n">sin</span><span class="p">(</span><span class="n">time</span> <span class="o">/</span> <span class="n">sp</span><span class="p">)</span> <span class="o">*</span> <span class="mf">.70</span><span class="p">;</span> <span class="c1">// Map pixels in the screen to points in the curve</span> <span class="k">float</span> <span class="n">x</span> <span class="o">=</span> <span class="p">(</span><span class="n">xy</span><span class="p">.</span><span class="n">x</span> <span class="o">/</span> <span class="n">rs</span><span class="p">.</span><span class="n">x</span><span class="p">)</span> <span class="o">*</span> <span class="mf">4.</span> <span class="o">-</span> <span class="mf">2.</span><span class="p">;</span> <span class="k">float</span> <span class="n">y</span> <span class="o">=</span> <span class="p">(</span><span class="n">xy</span><span class="p">.</span><span class="n">y</span> <span class="o">/</span> <span class="n">rs</span><span class="p">.</span><span class="n">y</span><span class="p">)</span> <span class="o">*</span> <span class="mf">4.</span> <span class="o">-</span> <span class="mf">2.</span><span class="p">;</span> <span class="k">int</span> <span class="n">i</span> <span class="o">=</span> <span class="n">iterations</span><span class="p">(</span><span class="n">x0</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y0</span><span class="p">,</span> <span class="n">y</span><span class="p">);</span> <span class="c1">// Color the interior parts</span> <span class="k">if</span> <span class="p">(</span><span class="n">i</span> <span class="o">&gt;=</span> <span class="n">max_its</span><span class="p">){</span> <span class="n">gl_FragColor</span> <span class="o">=</span> <span class="k">vec4</span><span class="p">(</span> <span class="k">vec3</span><span class="p">(</span><span class="mf">0.1</span><span class="p">,</span> <span class="mf">0.1</span><span class="p">,</span> <span class="mf">0.1</span><span class="p">),</span> <span class="mf">1.0</span><span class="p">);</span> <span class="p">}</span> <span class="c1">// The escaping ones too</span> <span class="k">else</span> <span class="p">{</span> <span class="n">gl_FragColor</span> <span class="o">=</span> <span class="k">vec4</span><span class="p">(</span> <span class="n">color</span><span class="p">(</span><span class="n">i</span><span class="p">),</span> <span class="mf">1.0</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> </pre></div> </td></tr></table> <p>Je, por cierto, bebe bastante batería, claro :P</p> <p><img alt="" src="http://codigoparallevar.com/files/2015/11/julia-set-shader.png"/></p> Un algoritmo de búsqueda de elementos similares tag:codigoparallevar.com/blog,2015-10-26:/2015/un-algoritmo-de-busqueda-de-elementos-similares 2015-10-26T21:00:00Z kenkeiras http://codigoparallevar.com/blog/ me@codigoparallevar.com <p>Es curioso, hay momentos en los que uno tiene que buscar una solución a un problema sencillo, por ejemplo, dadas varias listas de elementos, buscar la más parecida a otra nueva, y encontrar una solución (muy simple!). Pero esta solución no aparece en ningún otro sitio, a alguien se le tuvo que ocurrir! será tan simple (y tan inferior a otras), que no merece la pena documentarla?, simplemente uno no es capaz de encontrarla?... es probable :P...</p> <p><em>Después de hacer alguna prueba más... resulta que no escala bien, y con grandes datos pierde ventaja rápidamente xD</em></p> <p>Bueno, siendo como fuere, ahí va un algoritmo para buscar la lista (o listas), mas cercana a una dada, sin tener que comparar todos los elementos de todas.</p> <p>La utilidad es bastante directa, en el campo de la IA (Inteligencia Artificial) hay una serie de algoritmos para hacer clasificación, dado un conjunto de entrenamiento etiquetado (con cada elemento asignado a una categoría) encuentra al conjunto al que pertenece un nuevo elemento.</p> <h3>El acercamiento simplista</h3> <p>Uno de estos algoritmos de clasificación es el <strong>KNN</strong> (<a href="https://en.wikipedia.org/wiki/K-nearest_neighbors_algorithm">K-Nearest Neighbours</a>, los <em>K</em> vecinos más cercanos). El algoritmo es bastante simple, tenemos una lista de elementos con N características, por ejemplo, la longitud y anchura de el śepalo y pétalo de una serie de flores, y asociado el tipo de flor que es, para saber de que tipo es una nueva flor (conociendo estas 4 características), podemos computar su distancia al resto (como la suma de las diferencias de cada característica).</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1 2 3 4 5 6 7 8 9 10</pre></div></td><td class="code"><div class="highlight"><pre><span class="k">def</span> <span class="nf">distance</span><span class="p">(</span><span class="n">element1</span><span class="p">,</span> <span class="n">element2</span><span class="p">):</span> <span class="sd">&#39;&#39;&#39;Compute the distance between two elements.&#39;&#39;&#39;</span> <span class="n">distance_sum</span> <span class="o">=</span> <span class="mi">0</span> <span class="k">for</span> <span class="n">dimension</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">element1</span><span class="p">[</span><span class="s">&#39;features&#39;</span><span class="p">])):</span> <span class="n">feature1</span> <span class="o">=</span> <span class="n">element1</span><span class="p">[</span><span class="s">&#39;features&#39;</span><span class="p">][</span><span class="n">dimension</span><span class="p">]</span> <span class="n">feature2</span> <span class="o">=</span> <span class="n">element2</span><span class="p">[</span><span class="s">&#39;features&#39;</span><span class="p">][</span><span class="n">dimension</span><span class="p">]</span> <span class="n">distance_sum</span> <span class="o">+=</span> <span class="nb">pow</span><span class="p">(</span><span class="n">feature1</span> <span class="o">-</span> <span class="n">feature2</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span> <span class="k">return</span> <span class="n">distance_sum</span> </pre></div> </td></tr></table> <p>Sabiendo las distancias, podemos tomar los K elementos más cercanos y entre ellos escoger la "etiqueta" más común.</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21</pre></div></td><td class="code"><div class="highlight"><pre><span class="k">def</span> <span class="nf">get_more_represented</span><span class="p">(</span><span class="n">near_elements</span><span class="p">):</span> <span class="sd">&#39;&#39;&#39;Get the label found in more elements.&#39;&#39;&#39;</span> <span class="c"># Group by label</span> <span class="n">counts</span> <span class="o">=</span> <span class="p">{}</span> <span class="k">for</span> <span class="n">element</span> <span class="ow">in</span> <span class="n">near_elements</span><span class="p">:</span> <span class="n">label</span> <span class="o">=</span> <span class="n">element</span><span class="p">[</span><span class="s">&#39;label&#39;</span><span class="p">]</span> <span class="k">if</span> <span class="n">label</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">counts</span><span class="p">:</span> <span class="n">counts</span><span class="p">[</span><span class="n">label</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span> <span class="n">counts</span><span class="p">[</span><span class="n">label</span><span class="p">]</span> <span class="o">+=</span> <span class="mi">1</span> <span class="c"># Find the one with more elements</span> <span class="n">max_count</span> <span class="o">=</span> <span class="mi">0</span> <span class="n">max_label</span> <span class="o">=</span> <span class="k">None</span> <span class="k">for</span> <span class="n">label</span> <span class="ow">in</span> <span class="n">counts</span><span class="p">:</span> <span class="n">count</span> <span class="o">=</span> <span class="n">counts</span><span class="p">[</span><span class="n">label</span><span class="p">]</span> <span class="k">if</span> <span class="n">count</span> <span class="o">&gt;</span> <span class="n">max_count</span><span class="p">:</span> <span class="n">max_count</span> <span class="o">=</span> <span class="n">count</span> <span class="n">max_label</span> <span class="o">=</span> <span class="n">label</span> <span class="k">return</span> <span class="n">max_label</span> </pre></div> </td></tr></table> <p>El número que será K se define por ensayo y error, aunque suele ser uno pequeño como 3 podría ser cualquiera.</p> <p>Para encontrar los valores mas próximos entonces hay que evaluar la distancia desde el punto a clasificar a todos los ejemplos, y ordenarlos según este criterio. El problema, claro, es que el numero de cálculos <strong>para cada dato que se quiera clasificar</strong> es proporcional al (<strong>número de puntos</strong> * <strong>número de dimensiones</strong>, o características)</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18</pre></div></td><td class="code"><div class="highlight"><pre><span class="k">def</span> <span class="nf">naive_knn</span><span class="p">(</span><span class="n">training</span><span class="p">,</span> <span class="n">target</span><span class="p">,</span> <span class="n">k</span><span class="o">=</span><span class="mi">1</span><span class="p">):</span> <span class="sd">&#39;&#39;&#39;Classify an element based on training data.</span> <span class="sd"> :param training: The training set.</span> <span class="sd"> :param target: The element to classify.</span> <span class="sd"> &#39;&#39;&#39;</span> <span class="c"># Compute all distances</span> <span class="n">distances</span> <span class="o">=</span> <span class="p">[]</span> <span class="k">for</span> <span class="n">element</span> <span class="ow">in</span> <span class="n">training</span><span class="p">:</span> <span class="n">distances</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">element</span><span class="p">,</span> <span class="n">distance</span><span class="p">(</span><span class="n">element</span><span class="p">,</span> <span class="n">target</span><span class="p">)))</span> <span class="c"># Sort by distance</span> <span class="n">distances</span> <span class="o">=</span> <span class="p">[</span><span class="n">element</span> <span class="k">for</span> <span class="n">element</span><span class="p">,</span> <span class="n">dist</span> <span class="ow">in</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">distances</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">x</span><span class="p">:</span> <span class="n">x</span><span class="p">[</span><span class="mi">1</span><span class="p">])]</span> <span class="c"># Return the more represented</span> <span class="k">return</span> <span class="n">get_more_represented</span><span class="p">(</span><span class="n">distances</span><span class="p">[:</span><span class="n">k</span><span class="p">])</span> </pre></div> </td></tr></table> <p>Podemos probar el algoritmo contra este <a href="http://sci2s.ugr.es/keel/dataset/data/classification/iris.zip">dataset</a>. Después de descomprimirlo lo primero será cargarlo:</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1 2 3 4 5 6 7 8 9 10 11 12</pre></div></td><td class="code"><div class="highlight"><pre><span class="k">def</span> <span class="nf">to_element</span><span class="p">(</span><span class="n">parts</span><span class="p">):</span> <span class="sd">&#39;&#39;&#39;Convert the comma separated fields into an element.&#39;&#39;&#39;</span> <span class="k">return</span> <span class="p">{</span><span class="s">&#39;features&#39;</span><span class="p">:</span> <span class="p">[</span><span class="nb">float</span><span class="p">(</span><span class="n">part</span><span class="o">.</span><span class="n">strip</span><span class="p">())</span> <span class="k">for</span> <span class="n">part</span> <span class="ow">in</span> <span class="n">parts</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">]],</span> <span class="s">&#39;label&#39;</span><span class="p">:</span> <span class="n">parts</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]}</span> <span class="k">def</span> <span class="nf">load</span><span class="p">(</span><span class="n">fname</span><span class="o">=</span><span class="s">&#39;iris.dat&#39;</span><span class="p">):</span> <span class="sd">&#39;&#39;&#39;Load the Iris dataset from a CSV file.&#39;&#39;&#39;</span> <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">fname</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span> <span class="n">lines</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">()</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">&quot;</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">)</span> <span class="k">return</span> <span class="p">[</span><span class="n">to_element</span><span class="p">(</span><span class="n">line</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">&#39;,&#39;</span><span class="p">))</span> <span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">lines</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">line</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s">&#39;@&#39;</span><span class="p">)]</span> </pre></div> </td></tr></table> <p>Después tendremos que encontrar una forma de evaluarlo. Una simple y útil es <a href="https://en.wikipedia.org/wiki/Cross-validation_%28statistics%29#Leave-one-out_cross-validation"><em>one-out</em></a>, consiste en lo siguiente: cogemos los datos etiquetados de los que disponemos y por cada uno, lo intentamos clasificar utilizando el resto de la lista. De esta forma sabremos como de bien se hubiera clasificado ese. Cuantos más resultados correctos, mejor, claro.</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23</pre></div></td><td class="code"><div class="highlight"><pre><span class="k">def</span> <span class="nf">one_out</span><span class="p">(</span><span class="n">elements</span><span class="p">,</span> <span class="n">out_index</span><span class="p">):</span> <span class="sd">&#39;&#39;&#39;Separate one element from the list.</span> <span class="sd"> :param elements: The list of elements.</span> <span class="sd"> :param out_index: The position of the element to extract. </span> <span class="sd"> &#39;&#39;&#39;</span> <span class="k">if</span> <span class="p">(</span><span class="n">out_index</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="nb">len</span><span class="p">(</span><span class="n">elements</span><span class="p">):</span> <span class="c"># Last element is out</span> <span class="k">return</span> <span class="p">(</span><span class="n">elements</span><span class="p">[:</span><span class="n">out_index</span><span class="p">],</span> <span class="n">elements</span><span class="p">[</span><span class="n">out_index</span><span class="p">])</span> <span class="k">else</span><span class="p">:</span> <span class="k">return</span> <span class="p">(</span><span class="n">elements</span><span class="p">[:</span><span class="n">out_index</span><span class="p">]</span> <span class="o">+</span> <span class="n">elements</span><span class="p">[</span><span class="n">out_index</span> <span class="o">+</span> <span class="mi">1</span><span class="p">:],</span> <span class="n">elements</span><span class="p">[</span><span class="n">out_index</span><span class="p">])</span> <span class="k">def</span> <span class="nf">naive_knn_cross_validation</span><span class="p">(</span><span class="n">elements</span><span class="p">,</span> <span class="n">k</span><span class="o">=</span><span class="mi">1</span><span class="p">):</span> <span class="sd">&#39;&#39;&#39;Simple one-out cross validation.&#39;&#39;&#39;</span> <span class="n">failed</span> <span class="o">=</span> <span class="mi">0</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">elements</span><span class="p">)):</span> <span class="n">training</span><span class="p">,</span> <span class="n">out</span> <span class="o">=</span> <span class="n">one_out</span><span class="p">(</span><span class="n">elements</span><span class="p">,</span> <span class="n">i</span><span class="p">)</span> <span class="k">if</span> <span class="n">naive_knn</span><span class="p">(</span><span class="n">training</span><span class="p">,</span> <span class="n">out</span><span class="p">,</span> <span class="n">k</span><span class="p">)</span> <span class="o">!=</span> <span class="n">out</span><span class="p">[</span><span class="s">&#39;label&#39;</span><span class="p">]:</span> <span class="n">failed</span> <span class="o">+=</span> <span class="mi">1</span> <span class="k">return</span> <span class="n">failed</span> </pre></div> </td></tr></table> <p>Con esto ya podemos ir haciendonos una idea de que tal funciona.</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1 2 3 4 5 6 7 8 9 10</pre></div></td><td class="code"><div class="highlight"><pre><span class="c"># Load the training set </span> <span class="n">elements</span> <span class="o">=</span> <span class="n">load</span><span class="p">(</span><span class="s">&#39;iris.dat&#39;</span><span class="p">)</span> <span class="c"># Cross validate each element with the rest of the dataset</span> <span class="n">failed</span> <span class="o">=</span> <span class="n">naive_knn_cross_validation</span><span class="p">(</span><span class="n">elements</span><span class="p">)</span> <span class="nb">print</span><span class="p">(</span><span class="s">&quot;Failed {} of {} ({:.3f}%)&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span> <span class="n">failed</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">elements</span><span class="p">),</span> <span class="p">(</span><span class="n">failed</span> <span class="o">*</span> <span class="mi">100</span><span class="p">)</span> <span class="o">/</span> <span class="nb">len</span><span class="p">(</span><span class="n">elements</span><span class="p">)))</span> <span class="c"># Failed 6 of 150 (4.000%)</span> </pre></div> </td></tr></table> <p>De 150 elementos sólo 6 fallan (el 4%). Está bastante bien teniendo en cuenta lo simple e intuitivo del algoritmo, verdad? Veamos entonces la forma de hacer esta búsqueda de elementos más rápida (esto fué sobre 150 elementos en 4 dimensiones, es un caso muy limitado).</p> <h3>El algoritmo</h3> <p>Esta idea surgió intentando que la búsqueda sobre ~8000 elementos con más de 20 dimensiones fuese algo más... ligera ante la preocupación de que hubiera problemas cuando el conjunto de datos siguiera creciendo. Está pensado para evitar tener que comprobar todas las dimensiones de todos los elementos, y aún así garantizar que los elementos son los más cercanos, la idea es bastante simple.</p> <p>Por ejemplo, supongamos que tenemos 3 elementos en 2 dimensiones, y queremos encontrar el más cercano a un punto (0).</p> <p>Las distancias en cada dimensión a tres puntos (<code>A</code>, <code>B</code>, <code>C</code>) podrían ser:</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1 2</pre></div></td><td class="code"><div class="highlight"><pre>D1: (punto=A, distancia=1), (punto=B, distancia=2), (punto=C, distancia=3) D2: (punto=B, distancia=1), (punto=C, distancia=2), (punto=A, distancia=3) </pre></div> </td></tr></table> <p>Calculamos las distancias en la primera dimensión, y las introducimos en una lista ordenada por la distancia en esa dimensión, junto con el punto al que pertenecen y el número de dimensiones que ha sido computado hasta el momento.</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1</pre></div></td><td class="code"><div class="highlight"><pre>(punto=A, dist=1, dim_comp=1), (punto=B, dist=2, dim_comp=1), (punto=C, dist=3, dim_comp=1) </pre></div> </td></tr></table> <p>Tomamos el primer punto de la lista (el más cercano hasta ahora)</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1</pre></div></td><td class="code"><div class="highlight"><pre>(punto=A, dist=1, dim_comp=1) </pre></div> </td></tr></table> <p>Sumamos a la distancia de la primera dimensión la de la segunda (<code>1 + 3</code>) y la introducimos en la lista de acuerdo a la posición que le corresponde por su nueva distancia (sin olvidar cambiar el número de dimensiones computadas).</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1</pre></div></td><td class="code"><div class="highlight"><pre>(punto=B, dist=2, dim_comp=1), (punto=C, dist=3, dim_comp=1), (punto=A, dist=4, dim_comp=2) </pre></div> </td></tr></table> <p>Repetimos el paso con el siguiente elemento más cercano:</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1</pre></div></td><td class="code"><div class="highlight"><pre>(punto=B, dist=2, dim_comp=1) </pre></div> </td></tr></table> <p>La nueva distancia será <code>2 + 1</code> (la distancia hasta el momento, más el de la siguiente dimensión), así que al añadirlo a la lista se quedará así:</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1</pre></div></td><td class="code"><div class="highlight"><pre>(punto=B, dist=3, dim_comp=2), (punto=C, dist=3, dim_comp=1), (punto=A, dist=4, dim_comp=2) </pre></div> </td></tr></table> <p><em>(En este momento tanto el punto B como el C podrían ser el primero, da igual, pero si como desempate se hace que el elemento con más número de dimensiónes quede antes nos podemos ahorrar alguna iteración)</em></p> <p>Sacamos de nuevo el primer elemento:</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1</pre></div></td><td class="code"><div class="highlight"><pre>(punto=B, dist=3, dim_comp=2) </pre></div> </td></tr></table> <p>Y como ya hemos computado todas las dimensiones de este elemento y aún así sigue siendo elmás cercano, no hace falta seguir con el resto de puntos, sabemos seguro que es el más cercano.</p> <p>Si generalizamos el algoritmo para <strong><code>K</code></strong> vecinos, quedaría algo así:</p> <div class="highlight"><pre>1. Crear una lista vacía “vecinos”. 2. Calcular la distancia en la primera dimensión de cada elemento hasta el nuevo punto. 3. Organizarlas en una lista de tuplas (distancia, número de dimensiones hasta el momento, punto) 4. Ordenar la lista según la distancia, de forma ascendente 5. Tomar el menor elemento 6. Si se han tomado en cuenta todas las dimensiones para ese punto: 6.1 Pasarlo a la lista de “vecinos” como el siguiente más cercano. 6.2 Si la longitud de la lista de vecinos ya es `K`, ya se ha acabado. 7. Si aún queda alguna dimensión: 7.1 Calcular la nueva distancia sumándole la de la siguiente dimensión a la ya acumulada. 7.2 Introducir en la lista ordenada de acuerdo a la nueva distancia computada, con el nuevo número de dimensiones. 8. Volver al paso `5` </pre></div> <p>&nbsp;</p> <p>Así de simple, o, en python:</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52</pre></div></td><td class="code"><div class="highlight"><pre><span class="c"># Allows to maintain a sorted list</span> <span class="kn">from</span> <span class="nn">heapq</span> <span class="kn">import</span> <span class="n">heappush</span><span class="p">,</span> <span class="n">heappop</span> <span class="c"># Make elements sortable (dicts() are not)</span> <span class="k">class</span> <span class="nc">Element</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">element</span><span class="p">):</span> <span class="bp">self</span><span class="o">.</span><span class="n">e</span> <span class="o">=</span> <span class="n">element</span> <span class="k">def</span> <span class="nf">__lt__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span> <span class="k">return</span> <span class="bp">False</span> <span class="k">def</span> <span class="nf">sorted_knn</span><span class="p">(</span><span class="n">training</span><span class="p">,</span> <span class="n">target</span><span class="p">,</span> <span class="n">k</span><span class="o">=</span><span class="mi">1</span><span class="p">):</span> <span class="sd">&#39;&#39;&#39;Classify an element based on training data.</span> <span class="sd"> :param training: The training set.</span> <span class="sd"> :param target: The element to classify.</span> <span class="sd"> &#39;&#39;&#39;</span> <span class="c"># Compute all distances for the first feature</span> <span class="n">distances</span> <span class="o">=</span> <span class="p">[]</span> <span class="n">num_features</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">target</span><span class="p">[</span><span class="s">&#39;features&#39;</span><span class="p">])</span> <span class="k">for</span> <span class="n">element</span> <span class="ow">in</span> <span class="n">training</span><span class="p">:</span> <span class="c"># Elements are entered in the list in tuples</span> <span class="c"># (distance, last_dimension_computed, element)</span> <span class="n">heappush</span><span class="p">(</span><span class="n">distances</span><span class="p">,</span> <span class="p">(</span><span class="nb">pow</span><span class="p">(</span><span class="n">element</span><span class="p">[</span><span class="s">&#39;features&#39;</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="o">-</span> <span class="n">target</span><span class="p">[</span><span class="s">&#39;features&#39;</span><span class="p">][</span><span class="mi">0</span><span class="p">],</span> <span class="mi">2</span><span class="p">),</span> <span class="mi">1</span><span class="p">,</span> <span class="n">Element</span><span class="p">(</span><span class="n">element</span><span class="p">)))</span> <span class="n">nearest</span> <span class="o">=</span> <span class="p">[]</span> <span class="k">while</span> <span class="bp">True</span><span class="p">:</span> <span class="c"># Get the nearest element yet</span> <span class="n">distance</span><span class="p">,</span> <span class="n">next_feature</span><span class="p">,</span> <span class="n">element</span> <span class="o">=</span> <span class="n">heappop</span><span class="p">(</span><span class="n">distances</span><span class="p">)</span> <span class="c"># If all features are computated, it&#39;s the next on the nearest list</span> <span class="k">if</span> <span class="n">next_feature</span> <span class="o">==</span> <span class="n">num_features</span><span class="p">:</span> <span class="n">nearest</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">element</span><span class="p">)</span> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">nearest</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="n">k</span><span class="p">:</span> <span class="k">break</span> <span class="c"># Else, add it back to the heap</span> <span class="k">else</span><span class="p">:</span> <span class="n">new_distance</span> <span class="o">=</span> <span class="n">distance</span> <span class="o">+</span> <span class="nb">pow</span><span class="p">(</span><span class="n">element</span><span class="o">.</span><span class="n">e</span><span class="p">[</span><span class="s">&#39;features&#39;</span><span class="p">][</span><span class="n">next_feature</span><span class="p">]</span> <span class="o">-</span> <span class="n">target</span><span class="p">[</span><span class="s">&#39;features&#39;</span><span class="p">][</span><span class="n">next_feature</span><span class="p">],</span> <span class="mi">2</span><span class="p">)</span> <span class="n">heappush</span><span class="p">(</span><span class="n">distances</span><span class="p">,</span> <span class="p">(</span><span class="n">new_distance</span><span class="p">,</span> <span class="n">next_feature</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="n">element</span><span class="p">))</span> <span class="c"># Return the more represented</span> <span class="k">return</span> <span class="n">get_more_represented</span><span class="p">([</span><span class="n">element</span><span class="o">.</span><span class="n">e</span> <span class="k">for</span> <span class="n">element</span> <span class="ow">in</span> <span class="n">nearest</span><span class="p">])</span> </pre></div> </td></tr></table> <p>Y eso es todo lo necesario, si repetimos la validación, veremos que el ratio de acierto es el mismo.</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17</pre></div></td><td class="code"><div class="highlight"><pre><span class="k">def</span> <span class="nf">sorted_knn_cross_validation</span><span class="p">(</span><span class="n">elements</span><span class="p">,</span> <span class="n">k</span><span class="o">=</span><span class="mi">1</span><span class="p">):</span> <span class="sd">&#39;&#39;&#39;Simple one-out cross validation.&#39;&#39;&#39;</span> <span class="n">failed</span> <span class="o">=</span> <span class="mi">0</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">elements</span><span class="p">)):</span> <span class="n">training</span><span class="p">,</span> <span class="n">out</span> <span class="o">=</span> <span class="n">one_out</span><span class="p">(</span><span class="n">elements</span><span class="p">,</span> <span class="n">i</span><span class="p">)</span> <span class="k">if</span> <span class="n">sorted_knn</span><span class="p">(</span><span class="n">training</span><span class="p">,</span> <span class="n">out</span><span class="p">,</span> <span class="n">k</span><span class="p">)</span> <span class="o">!=</span> <span class="n">out</span><span class="p">[</span><span class="s">&#39;label&#39;</span><span class="p">]:</span> <span class="n">failed</span> <span class="o">+=</span> <span class="mi">1</span> <span class="k">return</span> <span class="n">failed</span> <span class="c"># Cross validate each element with the rest of the dataset</span> <span class="n">failed</span> <span class="o">=</span> <span class="n">sorted_knn_cross_validation</span><span class="p">(</span><span class="n">elements</span><span class="p">)</span> <span class="nb">print</span><span class="p">(</span><span class="s">&quot;Failed {} of {} ({:.3f}%)&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span> <span class="n">failed</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">elements</span><span class="p">),</span> <span class="p">(</span><span class="n">failed</span> <span class="o">*</span> <span class="mi">100</span><span class="p">)</span> <span class="o">/</span> <span class="nb">len</span><span class="p">(</span><span class="n">elements</span><span class="p">)))</span> <span class="c"># Failed 6 of 150 (4.000%)</span> </pre></div> </td></tr></table> <p>Pero si comparamos velocidades, para distintas <strong><code>K</code></strong>, vemos que no se comportan igual.</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53</pre></div></td><td class="code"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">time</span> <span class="k">import</span> <span class="n">time</span> <span class="k">def</span> <span class="nf">benchmark</span><span class="p">(</span><span class="n">elements</span><span class="p">,</span><span class="n">times</span><span class="o">=</span><span class="mi">100</span><span class="p">,</span> <span class="n">k</span><span class="o">=</span><span class="mi">3</span><span class="p">):</span> <span class="nb">print</span><span class="p">(</span><span class="s">&quot;Naive KNN&quot;</span><span class="p">)</span> <span class="n">t1</span> <span class="o">=</span> <span class="n">time</span><span class="p">()</span> <span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">times</span><span class="p">):</span> <span class="n">naive_knn_cross_validation</span><span class="p">(</span><span class="n">elements</span><span class="o">=</span><span class="n">elements</span><span class="p">,</span> <span class="n">k</span><span class="o">=</span><span class="n">k</span><span class="p">)</span> <span class="n">t2</span> <span class="o">=</span> <span class="n">time</span><span class="p">()</span> <span class="n">t</span> <span class="o">=</span> <span class="n">t2</span> <span class="o">-</span> <span class="n">t1</span> <span class="nb">print</span><span class="p">(</span><span class="s">&quot;{:.3f}s, {:.3f}s/iteration&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">t</span><span class="p">,</span> <span class="n">t</span> <span class="o">/</span> <span class="n">times</span><span class="p">))</span> <span class="nb">print</span><span class="p">(</span><span class="s">&quot;Sorted KNN&quot;</span><span class="p">)</span> <span class="n">t1</span> <span class="o">=</span> <span class="n">time</span><span class="p">()</span> <span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">times</span><span class="p">):</span> <span class="n">sorted_knn_cross_validation</span><span class="p">(</span><span class="n">elements</span><span class="o">=</span><span class="n">elements</span><span class="p">,</span> <span class="n">k</span><span class="o">=</span><span class="n">k</span><span class="p">)</span> <span class="n">t2</span> <span class="o">=</span> <span class="n">time</span><span class="p">()</span> <span class="n">t</span> <span class="o">=</span> <span class="n">t2</span> <span class="o">-</span> <span class="n">t1</span> <span class="nb">print</span><span class="p">(</span><span class="s">&quot;{:.3f}s, {:.3f}s/iteration&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">t</span><span class="p">,</span> <span class="n">t</span> <span class="o">/</span> <span class="n">times</span><span class="p">))</span> <span class="k">for</span> <span class="n">k</span> <span class="ow">in</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">9</span><span class="p">):</span> <span class="nb">print</span><span class="p">(</span><span class="s">&quot;K={}&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">k</span><span class="p">))</span> <span class="n">benchmark</span><span class="p">(</span><span class="n">elements</span><span class="p">,</span> <span class="n">k</span><span class="o">=</span><span class="n">k</span><span class="p">)</span> <span class="nb">print</span><span class="p">()</span> <span class="c"># K=1</span> <span class="c"># Naive KNN</span> <span class="c"># 9.514s, 0.095s/iteration</span> <span class="c"># Sorted KNN</span> <span class="c"># 6.763s, 0.067s/iteration</span> <span class="c"># K=3</span> <span class="c"># Naive KNN</span> <span class="c"># 9.467s, 0.094s/iteration</span> <span class="c"># Sorted KNN</span> <span class="c"># 7.837s, 0.078s/iteration</span> <span class="c"># K=5</span> <span class="c"># Naive KNN</span> <span class="c"># 9.472s, 0.094s/iteration</span> <span class="c"># Sorted KNN</span> <span class="c"># 8.512s, 0.085s/iteration</span> <span class="c"># K=7</span> <span class="c"># Naive KNN</span> <span class="c"># 9.426s, 0.094s/iteration</span> <span class="c"># Sorted KNN</span> <span class="c"># 9.094s, 0.090s/iteration</span> <span class="c"># K=9</span> <span class="c"># Naive KNN</span> <span class="c"># 9.481s, 0.094s/iteration</span> <span class="c"># Sorted KNN</span> <span class="c"># 9.809s, 0.098s/iteration</span> </pre></div> </td></tr></table> <p>En resumen, que al principio mantener la lista ordenada es más eficiente, pero a medida que aumenta la <strong><code>K</code></strong>, se pierde la ventaja y se empieza a notar el coste de <code>O(log N)</code> por inserción (en vez de uno constante en una lista normal) que implica mantener la lista ordenada.</p> <p><img alt="" src="http://codigoparallevar.com/files/2015/10/algorithm-plot.png"/></p> <p>Así que como curiosidad está bien, pero para cosas reales parece que no :P</p> Evolucionando decoders [1]: Brainfuck tag:codigoparallevar.com/blog,2015-08-26:/2015/evolucionando-decoders-1-brainfuck 2015-08-26T18:08:00Z kenkeiras http://codigoparallevar.com/blog/ me@codigoparallevar.com <p>Ya va casi un año desde el último post, como pasa el tiempo...</p> <p>Esta época he estado liado con varios proyectos, he acabado mi <a href="https://github.com/GII/ROBOBO/tree/develop">Trabajo de Fin de Grado</a>, del que intentaré hablar más adelante, y he participado en algún CTF. Algo que he notado es que en lo que se refiere a pruebas criptográficas suele haber dos tipos, en las que el algoritmo está claro desde el principio y hay que atacarlo. Y en las que se da un texto <em>cifrado</em> y se plantea el reto de obtener el <em>flag</em> que hay en el.</p> <p>La idea detrás de este segundo tipo de pruebas (supongo) es determinar la capacidad de reconocer similitudes con cifrados ya existentes, de realizar un análisis de los datos (entropía, ...) y extraer conclusiones a partir de ahí. Hay gente que es muy buena haciendo esto...</p> <p>Yo no.</p> <p>Otra opción es hacer pruebas hasta que vaya apareciendo algo interesante, pero es un proceso largo y que no necesariamente da frutos, sería interesante poder automatizarlo, verdad?</p> <p>Habría dos formas de atacar este problema, la primera es aplicar muchos filtros ya conocidos, todos los que se nos ocurran, y buscar en los resultados la respuesta, es muy realizable y probablemente encuentre las preguntas para retos simples, pero se atasque cuando encuentre algo nuevo (te esperarías algo en <a href="https://en.wikipedia.org/wiki/Ascii85">base 85</a>?).</p> <p>La segunda forma es evolucionar un decoder especifico para la cadena a "descifrar", las ventajas serían que <em>con un poco de suerte</em> se podría enfrentarse a problemas completamente nuevos. Como desventajas sería <strong>mucho</strong> más lento, más complejo y más dado a fallar que su contraparte no evolutiva.</p> <p>En adelante intentaré desarrollar esta segunda opción, por ahora no da buenos resultados pero espero que las pruebas puedan resultar interesantes, la criatura está en <a href="https://gitlab.com/kenkeiras/happy">este repositorio</a></p> <h4>El concepto</h4> <p>Bueno, deamos un paso atrás, está claro por que optamos por un acercamiento de IA (inteligencia artificial) para esto, hay una cantidad muy grande de formas en las que codificar algo, demasiado como para atacarlo con métodos más tradicionales. Así que, por cual optar? por que algoritmos evolutivos?</p> <p>Por lo general las técnicas de IA parten de un conjunto de entrenamiento (<a href="https://es.wikipedia.org/wiki/Aprendizaje_autom%C3%A1tico">machine learning</a>), reglas predefinidas (<a href="https://es.wikipedia.org/wiki/Sistema_experto">sistemas expertos</a>) o algún tipo de conocimiento previo del dominio. En el caso de pruebas de criptografía, no disponemos de datos de entrenamiento útiles o no serían útiles, ya que probablemente se haya usado un encoding diferente al de pruebas anteriores. Y también debemos descartar la idea de desarrollar alguna tabla de reglas, de nuevo por que no podríamos enfrentarnos a casos nuevos.</p> <p>Lo que nos queda es utilizar el conocimiento específico del que dispongamos. Cuando se trata de codificación de información podemos saber como de posible es que una cierta cadena sea la respuesta, de la misma forma que lo haría una persona si la cadena es una frase coherente probablemente hayamos tenido éxito.</p> <p>Esto lo podemos explotar de la siguiente forma: podemos construir un <strong>modelo de lenguaje</strong> que nos indique como de <em>coherente</em> es un texto.</p> <p>Bien, decidido este punto queda decidir como llegar a este texto que calificaremos, podríamos</p> <ul> <li>Generar textos al azar.</li> <li>"Mutar" el texto que nos proporciona el reto hasta llegar a algo coherente.</li> </ul> <p>Esto daría lugar a frases tan <em>buenas</em> como lo fuera modelo de lenguaje permita, pero es muy probable que no guarden ninguna relación con el texto <em>cifrado</em>. Una tercera aproximación más complicada sería buscar algún algoritmo que dado el texto <em>cifrado</em> como entrada produjese como salida el texto <em>claro</em>, la idea es el paso intermedio de evolucionar un programa en vez de la cadena en sí evite que se rompa el vínculo entre las dos cadenas, haciendo que el que el resultado sea coherente dependa de que el algoritmo sea el correcto para la <em>entrada</em>.</p> <p>Así, el programa tendría 3 componentes principales, el <em>modelo de lenguaje</em> que sirve para puntuar, el intérprete del programa a evolucionar y los algoritmos de cruce.</p> <h4>El modelo de lenguaje</h4> <p>Es el componente encargado de decidir como de cercano a una frase <em>normal</em> es un texto. Los problemas que tendrá esto son bastante claros de entrada, y es que es algo extremadamente complejo, hay una disciplina de IA dedicada exclusivamente a la interpretación de lenguajes naturales (<a href="https://es.wikipedia.org/wiki/Procesamiento_de_lenguajes_naturales">NLP</a>) y si bien va avanzando, los resultados varían mucho según el lenguaje utilizado, y aún en los casos ideales, queda mucho por recorrer.</p> <p>Para este caso en concreto además tendremos que dar una puntuación que indíque la <strong>cercanía</strong>, para dirigir la evolución de los programas. Como construir a mano un modelo para cada lenguaje que vayamos a utilizar y actualizarlo cada vez que queramos modificar cosas es <em>bastante incómodo</em> lo que haremos será calcularlo al vuelo a partir de un conjunto de textos que proporcione el usuario.</p> <p>En este momento el modelo depende de 5 parametros, una lista de bigramas (la probabilidad de que después de que un caracter vaya otro dado), trigramas (lo mismo para grupos de 3), palabras completas, la cantidad de <em>basura</em> (caracteres no printables o que no se corresponden a una palabra), y una medida de la entropía del lenguaje.</p> <p>El modelo esperado se calcula al arrancar el programa a partir de un texto de <em>diccionario</em>, los resultados son suficientes para realizar pruebas pero mejorables.</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1 2 3 4 5 6 7 8 9 10 11 12</pre></div></td><td class="code"><div class="highlight"><pre>happy score /usr/share/dict/american-english-large <span class="s1">&#39;Hello world&#39;</span> 286892 happy score /usr/share/dict/american-english-large <span class="s1">&#39;Hello warld&#39;</span> 1142 happy score /usr/share/dict/american-english-large <span class="s1">&#39;Hellox warld&#39;</span> 1465 happy score /usr/share/dict/american-english-large <span class="s1">&#39;Hellox warld&#39;</span> 1465 happy score /usr/share/dict/american-english-large <span class="s1">&#39;Hellox world&#39;</span> 322647 happy score /usr/share/dict/american-english-large <span class="s1">&#39;Hello world&#39;</span> 286892 </pre></div> </td></tr></table> <p>La cadena "Hello world" tiene una puntuación muy alta con respecto a la mayoría, pero es menor que la de "Hellox world", que dificilmente es la que buscamos. De todas formas esto probablemente sea un bug, más que un problema de concepto.</p> <p>El modelo de lenguajes se encuentra en el directorio <a href="https://gitlab.com/kenkeiras/happy/tree/master/src/lang-model">src/lang-model/</a>.</p> <h4>Intérprete y cruce</h4> <p>Aquí no hay mucho que decir, el intérprete es simplemente uno de brainfuck (por simplicidad) y <a href="https://gitlab.com/kenkeiras/happy/blob/05084af1e5a8bc8b1c7209d711fe2f6cc6d33064/src/transform-model/transform.c#L291">los cruces...</a> son mediocres, simplemente muta todos menos el mejor, la cantidad de mutaciones depende de la puntuación obtenida, a mejor puntuación menos mutaciones. Después itera sobre la <em>peor</em> mitad de programas y los cruza aleatoriamente, alternando un símbolo de cada uno de los dos individuos a cruzar.</p> <h4>Resultados</h4> <p>Lo cierto es que esperaba que no funcionara en absoluto y se quedara como un experimento con el que refrescar conceptos, pero es capaz de encontrar soluciones a problemas... ridículamente sencillos, eso sí</p> <p><strong>Copiar la entrada en la salida</strong> (solo son necesarios los 14 primeros caracteres, y de ellos 10 sobran)</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1 2 3 4 5 6 7 8 9 10</pre></div></td><td class="code"><div class="highlight"><pre><span class="nv">$ </span><span class="nb">time </span>bin/happy evolve dictionary <span class="s1">$&#39;flag stars are made of weird stuff&#39;</span> Seed: 0x55DE237F Iteration <span class="o">(</span> 0<span class="o">)</span> <span class="o">[</span><span class="m">1770572</span> <span class="p">|</span> 37<span class="o">]</span>: <span class="p">|</span>kg stars are made of weird stuffk...<span class="p">|</span> Found on iteration 5! <span class="o">[</span>Sc: <span class="m">5206406</span> <span class="p">|</span>Sz: 35<span class="o">]</span> -++&gt;+<span class="o">[</span>&lt;+<span class="o">[</span>-+,.<span class="o">][</span>&lt;-,,&gt;.+-<span class="o">[</span>--<span class="o">]</span>,,&lt;&lt;,<span class="o">[</span>&gt;,+<span class="o">[[</span>,&lt;<span class="o">[</span>--<span class="o">&lt;&lt;&lt;</span>..<span class="o">]</span>&gt;.-&gt;,<span class="o">[</span>-&lt;++-<span class="o">]]</span>&lt;<span class="o">[</span>&gt;&gt;&lt;&lt;,<span class="o">]</span>+&gt;,&gt;<span class="o">[</span>-.<span class="o">[</span>+,.&lt;<span class="o">[</span>&gt;<span class="o">[]</span>.<span class="o">]</span>&lt;&gt;<span class="o">[</span>.---&lt;+.,.+,&lt;&lt;&gt;+++,++.<span class="o">[</span>&gt;&gt;.&lt;+,..+<span class="o">[]</span>+&lt;<span class="o">]</span>.&lt;&gt;+,<span class="o">[]</span>+<span class="o">]</span>-&lt;<span class="o">[</span>.&lt;&lt;.,+<span class="o">[</span>&lt;--+-.-<span class="o">]</span>.,&lt;.,,..<span class="o">[[[</span>.+<span class="o">]</span>&gt;<span class="o">[[</span>-&lt;<span class="o">[</span>&gt;,<span class="o">[</span>,&gt;<span class="o">]</span>.&gt;<span class="o">]</span>.--<span class="o">[</span>-,,,-<span class="o">&lt;&lt;&lt;</span>&lt;+<span class="o">][]]</span>+..<span class="o">[</span>.&lt;<span class="o">]</span>.,<span class="o">]</span>.<span class="o">]</span>-.<span class="o">[</span>&lt;&lt;&gt;<span class="o">[[</span>-,+&gt;&gt;,<span class="o">[[</span>&gt;&lt;&gt;-&gt;<span class="o">[</span>-,<span class="o">]</span>.&lt;&gt;+<span class="o">][</span>+-<span class="o">[[</span>+,<span class="o">[</span>&gt;-+<span class="o">]</span>+<span class="o">]</span>-&gt;&lt;&gt;&gt;.&gt;<span class="o">]</span>--&gt;&gt;-&gt;,,-&gt;&gt;.<span class="o">[[</span>-,+<span class="o">[</span>&lt;<span class="o">[</span>.&lt;.&gt;&lt;-&gt;&lt;&lt;<span class="o">[]</span>&gt;&gt;,<span class="o">]</span>.-,,<span class="o">[</span>+<span class="o">]</span>&gt;-&gt;.,&gt;,<span class="o">][</span>.-&lt;,+&lt;+&lt;-<span class="o">]</span>&gt;,<span class="o">]</span>,-<span class="o">[</span>.&gt;<span class="o">[]</span>,+&gt;,.&gt;,,,<span class="o">[</span>+<span class="o">][]</span>-&gt;,,<span class="o">]</span>.-&gt;-&lt;,.<span class="o">]</span>&gt;&gt;,+&gt;<span class="o">]</span>-,&gt;..,.<span class="o">[</span>&gt;.+<span class="o">][</span>-<span class="o">[</span>+.&lt;<span class="o">]</span>.<span class="o">]</span>-&lt;.<span class="o">]</span>&gt;<span class="o">[</span>&gt;<span class="o">[]</span>+&gt;&lt;.&gt;++&lt;<span class="o">]</span>,&gt;<span class="o">]</span>+<span class="o">]</span>&gt;&gt;.+&lt;.-<span class="o">]</span>.&lt;.&gt;-.,<span class="o">]</span>&gt;<span class="o">]]</span>+&lt;<span class="o">[</span>&lt;&lt;.-<span class="o">[</span>&gt;&gt;.&lt;&gt;-<span class="o">][]</span>-,+&lt;<span class="o">[</span>-.<span class="o">][</span>&lt;<span class="o">[</span>&lt;<span class="o">[</span>&lt;&gt;<span class="o">[</span>.,&lt;&gt;&gt;..-<span class="o">[</span>,,&gt;,-&gt;...<span class="o">[]</span>&gt;+<span class="o">[</span>&lt;&gt;.-&gt;.-,-&lt;&gt;,<span class="o">]</span>&lt;&gt;<span class="o">[]]</span>,<span class="o">[[[</span>-&gt;.-&gt;--&gt;++<span class="o">]</span> real 0m0.863s user 0m0.760s sys 0m0.100s </pre></div> </td></tr></table> <p>&nbsp;</p> <p><strong>Sumar 1 a todas las entradas</strong> (solo los primeros 10, de los que vuelven a sobrar 4)</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1 2 3 4 5 6 7 8 9 10</pre></div></td><td class="code"><div class="highlight"><pre><span class="nv">$ </span><span class="nb">time </span>bin/happy evolve dictionary <span class="s1">$&#39;ek`f\x1frs`qr\x1f`qd\x1fl`cd\x1fne\x1fvdhqc\x1frstee&#39;</span> Seed: 0x55DE23A2 Iteration <span class="o">(</span> 0<span class="o">)</span> <span class="o">[</span><span class="m">15827</span> <span class="p">|</span> 199997<span class="o">]</span>: <span class="p">|</span>.ag stars are made of weird stuff.......%<span class="p">|</span> Found on iteration 10! <span class="o">[</span>Sc: <span class="m">5206406</span> <span class="p">|</span>Sz: 35<span class="o">]</span> ,<span class="o">[[</span>+.&gt;,-+<span class="o">]</span>+&gt;,.<span class="o">]]</span>&lt;<span class="o">][</span>..<span class="o">[</span>+-&lt;,.,+&gt;&gt;--&lt;<span class="o">[</span>-,<span class="o">][</span>&lt;<span class="o">[</span>,,.,.<span class="o">][][[</span>.&lt;,-,+-+&lt;,<span class="o">]]</span>&lt;-&gt;.&gt;&gt;<span class="o">[</span>,-<span class="o">]</span>+-,+-<span class="o">]</span>+,&gt;+&gt;<span class="o">[</span>&gt;<span class="o">[</span>.,.&lt;+.&lt;<span class="o">[</span>-,<span class="o">[</span>.<span class="o">[</span>&gt;,+&lt;-&gt;&gt;<span class="o">[</span>.&lt;.,++<span class="o">]</span>.<span class="o">]</span>&gt;,.<span class="o">[</span>&gt;+<span class="o">[</span>,,,-<span class="o">]</span>+,&lt;--,<span class="o">]</span>,<span class="o">[</span>&gt;,-&gt;-&gt;<span class="o">]</span>+&gt;<span class="o">[][]</span>&gt;&lt;,-&gt;+&gt;.+<span class="o">]</span>+<span class="o">[</span>+&gt;<span class="o">]</span>,<span class="o">[[[</span>.,--<span class="o">[</span>+&gt;-,&lt;+.+<span class="o">[</span>,&gt;-&lt;+&lt;<span class="o">[</span>,<span class="o">[</span>&lt;&lt;-&lt;&gt;++&lt;+-<span class="o">]</span>&gt;,++&lt;-<span class="o">[[</span>-.&lt;&lt;<span class="o">[</span>...&lt;<span class="o">[</span>++-<span class="o">[</span>&gt;<span class="o">]</span>-<span class="o">]</span>,<span class="o">]</span>,&lt;<span class="o">][</span>&gt;,.,&lt;<span class="o">]</span>.<span class="o">]]</span>&lt;-&gt;&lt;&lt;<span class="o">[</span>.+.+&gt;<span class="o">[</span>.&lt;,<span class="o">]</span>&gt;,,,.<span class="o">][</span>,..&gt;<span class="o">]</span>.&lt;<span class="o">[</span>&lt;<span class="o">]</span>&lt;,-+,<span class="o">[</span>+&lt;-.&lt;.,-&gt;+&lt;<span class="o">]</span>+&lt;&gt;-&lt;&gt;.-&gt;&lt;,+&lt;&gt;-<span class="o">]]</span>&lt;&gt;,.,,&lt;,-.<span class="o">[</span>&gt;&lt;&gt;..--&lt;.&lt;<span class="o">][</span>.,.&lt;<span class="o">[</span>-&lt;<span class="o">[]</span>,<span class="o">]</span>.+,&lt;-&lt;&lt;+,,<span class="o">]</span>,,+&gt;<span class="o">[</span>-,&gt;,,<span class="o">[</span>,<span class="o">[</span>&gt;&lt;+---+-<span class="o">[</span>-.,<span class="o">]</span>&lt;-,&gt;-+<span class="o">]</span>&gt;<span class="o">]</span>&gt;..+,+,+.<span class="o">[[</span>+,+&gt;-&gt;-<span class="o">]</span>&gt;&gt;<span class="o">[</span>+.<span class="o">]]</span>-+<span class="o">[</span>,,-,+<span class="o">[</span>-&lt;<span class="o">]</span>&gt;&lt;&gt;&lt;<span class="o">[[[</span>-,-<span class="o">]</span>.,&lt;<span class="o">]</span>-&lt;<span class="o">[</span>+..,,+&lt;+&lt;+&gt;.,-&lt;<span class="o">[]</span>+&lt;&gt;&gt;<span class="o">[</span>.&lt;<span class="o">[</span>,.&gt;&lt;&gt;&lt;<span class="o">]</span>&gt;&lt;.<span class="o">[[</span>&lt;.+<span class="o">][</span>+.,<span class="o">[]</span>..-&gt;<span class="o">[</span>,&gt;+.<span class="o">]</span>-&gt;-.,+&gt;<span class="o">[</span>+- real 0m1.236s user 0m1.108s sys 0m0.124s </pre></div> </td></tr></table> <p>&nbsp;</p> <p>Sin embargo si pasamos a algo más <em>complejo</em> (sumar a todo 5) ya hay problemas.</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31</pre></div></td><td class="code"><div class="highlight"><pre><span class="nv">$ </span>bin/happy evolve dictionary <span class="s1">$&#39;ag\\b\x1bno\\mn\x1b\\m`\x1bh\\_`\x1bja\x1br`dm_\x1bnopaa&#39;</span> Seed: 0x55DE2499 Iteration <span class="o">(</span> 0<span class="o">)</span> <span class="o">[</span> <span class="m">7085</span> <span class="p">|</span> 499997<span class="o">]</span>: <span class="p">|</span>ghhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh%<span class="p">|</span> Iteration <span class="o">(</span> 20<span class="o">)</span> <span class="o">[</span><span class="m">36208</span> <span class="p">|</span> 320<span class="o">]</span>: <span class="p">|</span>bee.....................................%<span class="p">|</span> Iteration <span class="o">(</span> 40<span class="o">)</span> <span class="o">[</span><span class="m">36208</span> <span class="p">|</span> 320<span class="o">]</span>: <span class="p">|</span>bee.....................................%<span class="p">|</span> Iteration <span class="o">(</span> 60<span class="o">)</span> <span class="o">[</span><span class="m">36208</span> <span class="p">|</span> 320<span class="o">]</span>: <span class="p">|</span>bee.....................................%<span class="p">|</span> Iteration <span class="o">(</span> 80<span class="o">)</span> <span class="o">[</span><span class="m">36208</span> <span class="p">|</span> 320<span class="o">]</span>: <span class="p">|</span>bee.....................................%<span class="p">|</span> Iteration <span class="o">(</span> 100<span class="o">)</span> <span class="o">[</span><span class="m">77392</span> <span class="p">|</span> 293<span class="o">]</span>: <span class="p">|</span>baba<span class="sb">`</span>a<span class="sb">`</span>_<span class="sb">`</span>_^_^<span class="o">]</span>^<span class="o">]</span><span class="se">\]\[\[</span>Z<span class="o">[</span>ZYZYXYXWXWVWVUVU%<span class="p">|</span> Iteration <span class="o">(</span> 120<span class="o">)</span> <span class="o">[</span><span class="m">162373</span> <span class="p">|</span> 10<span class="o">]</span>: <span class="p">|</span>.gf<span class="sb">`</span>__fee<span class="p">|</span> Iteration <span class="o">(</span> 140<span class="o">)</span> <span class="o">[</span><span class="m">162373</span> <span class="p">|</span> 10<span class="o">]</span>: <span class="p">|</span>.gf<span class="sb">`</span>__fee<span class="p">|</span> Iteration <span class="o">(</span> 160<span class="o">)</span> <span class="o">[</span><span class="m">162373</span> <span class="p">|</span> 10<span class="o">]</span>: <span class="p">|</span>.gf<span class="sb">`</span>__fee<span class="p">|</span> Iteration <span class="o">(</span> 180<span class="o">)</span> <span class="o">[</span><span class="m">162373</span> <span class="p">|</span> 10<span class="o">]</span>: <span class="p">|</span>.gf<span class="sb">`</span>__fee<span class="p">|</span> Iteration <span class="o">(</span> 200<span class="o">)</span> <span class="o">[</span><span class="m">162373</span> <span class="p">|</span> 10<span class="o">]</span>: <span class="p">|</span>.gf<span class="sb">`</span>__fee<span class="p">|</span> Iteration <span class="o">(</span> 220<span class="o">)</span> <span class="o">[</span><span class="m">162373</span> <span class="p">|</span> 10<span class="o">]</span>: <span class="p">|</span>.gf<span class="sb">`</span>__fee<span class="p">|</span> Iteration <span class="o">(</span> 240<span class="o">)</span> <span class="o">[</span><span class="m">162373</span> <span class="p">|</span> 10<span class="o">]</span>: <span class="p">|</span>.gf<span class="sb">`</span>__fee<span class="p">|</span> Iteration <span class="o">(</span> 260<span class="o">)</span> <span class="o">[</span><span class="m">241766</span> <span class="p">|</span> 23<span class="o">]</span>: <span class="p">|</span>noon..<span class="sb">`</span>.._<span class="sb">``</span>a..dmmnooa<span class="p">|</span> Iteration <span class="o">(</span> 280<span class="o">)</span> <span class="o">[</span><span class="m">241766</span> <span class="p">|</span> 23<span class="o">]</span>: <span class="p">|</span>noon..<span class="sb">`</span>.._<span class="sb">``</span>a..dmmnooa<span class="p">|</span> ... Iteration <span class="o">(</span> 300<span class="o">)</span> <span class="o">[</span><span class="m">241766</span> <span class="p">|</span> 23<span class="o">]</span>: <span class="p">|</span>noon..<span class="sb">`</span>.._<span class="sb">``</span>a..dmmnooa<span class="p">|</span> Iteration <span class="o">(</span> 600<span class="o">)</span> <span class="o">[</span><span class="m">241766</span> <span class="p">|</span> 23<span class="o">]</span>: <span class="p">|</span>noon..<span class="sb">`</span>.._<span class="sb">``</span>a..dmmnooa<span class="p">|</span> Iteration <span class="o">(</span> 620<span class="o">)</span> <span class="o">[</span><span class="m">266050</span> <span class="p">|</span> 333332<span class="o">]</span>: <span class="p">|</span>ggghghghghghghghghghghghghghghghghghghgh%<span class="p">|</span> Iteration <span class="o">(</span> 640<span class="o">)</span> <span class="o">[</span><span class="m">266050</span> <span class="p">|</span> 333332<span class="o">]</span>: <span class="p">|</span>ggghghghghghghghghghghghghghghghghghghgh%<span class="p">|</span> ... Iteration <span class="o">(</span> 760<span class="o">)</span> <span class="o">[</span><span class="m">266050</span> <span class="p">|</span> 333332<span class="o">]</span>: <span class="p">|</span>ggghghghghghghghghghghghghghghghghghghgh%<span class="p">|</span> Iteration <span class="o">(</span> 780<span class="o">)</span> <span class="o">[</span><span class="m">266050</span> <span class="p">|</span> 333332<span class="o">]</span>: <span class="p">|</span>ggghghghghghghghghghghghghghghghghghghgh%<span class="p">|</span> Iteration <span class="o">(</span> 800<span class="o">)</span> <span class="o">[</span><span class="m">526316</span> <span class="p">|</span> 333332<span class="o">]</span>: <span class="p">|</span>agfefefefefefefefefefefefefefefefefefefe%<span class="p">|</span> Iteration <span class="o">(</span> 820<span class="o">)</span> <span class="o">[</span><span class="m">526316</span> <span class="p">|</span> 333332<span class="o">]</span>: <span class="p">|</span>agfefefefefefefefefefefefefefefefefefefe%<span class="p">|</span> ... Iteration <span class="o">(</span> 1300<span class="o">)</span> <span class="o">[</span><span class="m">526316</span> <span class="p">|</span> 333332<span class="o">]</span>: <span class="p">|</span>agfefefefefefefefefefefefefefefefefefefe%<span class="p">|</span> Iteration <span class="o">(</span> 1320<span class="o">)</span> <span class="o">[</span><span class="m">526316</span> <span class="p">|</span> 333332<span class="o">]</span>: <span class="p">|</span>agfefefefefefefefefefefefefefefefefefefe%<span class="p">|</span> ... </pre></div> </td></tr></table> <p>Esto es problema tanto del modelo de lenguaje, que da puntuaciones muy altas a cadenas poco coherentes y del lenguaje a evolucionar, ya que para cosas muy simples requiere combinaciones complejas de operaciones.</p> <blockquote> <p>&nbsp;54. Beware of the Turing tar-pit in which everything is possible but nothing of interest is easy.<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -- Alan Perlis. Epigrams on Programming.</p> </blockquote> <h4>Siguientes pasos</h4> <p>Por supuesto esto no quedará ahí, lo próximo sería afinar la puntuación que se le asigna a las cadenas y reemplazar el uso de brainfuck por otro lenguaje más expresivo, espero que los resultados vayan mejorando a medida que se implementan estas mejoras.</p> <p>Hasta la próxima.</p> Writeup de inBINcible [NcN CTF Quals] tag:codigoparallevar.com/blog,2014-09-16:/2014/writeup-de-inbincible-ncn-ctf-quals 2014-09-16T00:36:00Z kenkeiras http://codigoparallevar.com/blog/ me@codigoparallevar.com <p>Lleva un tiempo el blog parado, pero traigo algo interesante, veamos como reversear un binario de los presentados en las quals del <a href="https://ctf.noconname.org/">CTF de la No Con Name</a>.</p> <p><strong>Aviso</strong>: Soy bastante novato en esto, así que seguro que se podrían obviar muchos pasos o hacer más sencillo con los conocimientos y herramientas adecuadas. Si sabes algo de esto, mejor ve ya a <a href="http://codigoparallevar.com/blog/blog/2014/writeup-de-inbincible-ncn-ctf-quals/#python">la parte curiosa</a> ;).</p> <p>El binario en cuestión es “<a href="http://codigoparallevar.com/files/2014/09/inbincible">inbincible</a>”, si lo ejecutamos produce el siguiente resultado:</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1 2 3</pre></div></td><td class="code"><div class="highlight"><pre><span class="nv">$ </span>./inbincible Nope! <span class="err">$</span> </pre></div> </td></tr></table> <p>Obviamente no es el que nos interesa, así que veamos lo que hace, abrimos con <a href="https://www.gnu.org/software/gdb/">gdb</a> y buscamos una función desde la que empezar <!-- more --></p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1 2 3 4 5</pre></div></td><td class="code"><div class="highlight"><pre><span class="nf">$</span> <span class="no">gdb</span> <span class="p">-</span><span class="no">q</span> <span class="p">.</span><span class="err">/</span><span class="no">inbincible</span> <span class="nf">Reading</span> <span class="no">symbols</span> <span class="no">from</span> <span class="p">.</span><span class="err">/</span><span class="no">inbincible...</span><span class="p">(</span><span class="no">no</span> <span class="no">debugging</span> <span class="no">symbols</span> <span class="no">found</span><span class="p">)...</span><span class="no">done.</span> <span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> <span class="no">break</span> <span class="no">main</span><span class="err">&lt;</span><span class="no">tab</span><span class="err">&gt;&lt;</span><span class="no">tab</span><span class="err">&gt;</span> <span class="nf">main</span> <span class="no">main.init</span> <span class="no">main.main</span> <span class="no">main.statictmp_0022</span> <span class="no">main.statictmp_0027</span> <span class="nf">main.func</span> <span class="no">main.initdone.</span> <span class="no">main.statictmp_0019</span> <span class="no">main.statictmp_0024</span> <span class="no">main.statictmp_0030</span> </pre></div> </td></tr></table> <p>Hay un main, así que empecemos por ahí </p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1 2 3 4 5 6 7</pre></div></td><td class="code"><div class="highlight"><pre><span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> <span class="no">break</span> <span class="no">main</span> <span class="nf">Breakpoint</span> <span class="mi">1</span> <span class="no">at</span> <span class="mi">0x806dc20</span> <span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> <span class="no">run</span> <span class="nf">Starting</span> <span class="no">program</span><span class="p">:</span> <span class="err">/</span><span class="no">home</span><span class="err">/</span><span class="no">kenkeiras</span><span class="err">/</span><span class="no">ctf</span><span class="err">/</span><span class="mi">2014</span><span class="err">/</span><span class="no">ncn</span><span class="err">/</span><span class="no">quals</span><span class="err">/</span><span class="no">inbincible</span><span class="err">/</span><span class="no">inbincible</span> <span class="nf">Breakpoint</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0x0806dc20</span> <span class="no">in</span> <span class="no">main</span> <span class="p">()</span> <span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> </pre></div> </td></tr></table> <p>Veamos que hay por ahí...</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1 2 3 4 5 6 7 8 9 10 11</pre></div></td><td class="code"><div class="highlight"><pre><span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> <span class="no">disassemble</span> <span class="nf">Dump</span> <span class="no">of</span> <span class="no">assembler</span> <span class="no">code</span> <span class="no">for</span> <span class="no">function</span> <span class="no">main</span><span class="p">:</span> <span class="err">=&gt;</span> <span class="err">0</span><span class="nf">x0806dc20</span> <span class="err">&lt;+</span><span class="mi">0</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">jmp</span> <span class="mh">0x806b890</span> <span class="p">&lt;</span><span class="no">_rt0_go</span><span class="p">&gt;</span> <span class="err">0</span><span class="nf">x0806dc25</span> <span class="err">&lt;+</span><span class="mi">5</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">add</span> <span class="nv">%al</span><span class="p">,(</span><span class="nv">%eax</span><span class="p">)</span> <span class="err">0</span><span class="nf">x0806dc27</span> <span class="err">&lt;+</span><span class="mi">7</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">add</span> <span class="nv">%al</span><span class="p">,(</span><span class="nv">%eax</span><span class="p">)</span> <span class="err">0</span><span class="nf">x0806dc29</span> <span class="err">&lt;+</span><span class="mi">9</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">add</span> <span class="nv">%al</span><span class="p">,(</span><span class="nv">%eax</span><span class="p">)</span> <span class="err">0</span><span class="nf">x0806dc2b</span> <span class="err">&lt;+</span><span class="mi">11</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">add</span> <span class="nv">%al</span><span class="p">,(</span><span class="nv">%eax</span><span class="p">)</span> <span class="err">0</span><span class="nf">x0806dc2d</span> <span class="err">&lt;+</span><span class="mi">13</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">add</span> <span class="nv">%al</span><span class="p">,(</span><span class="nv">%eax</span><span class="p">)</span> <span class="err">0</span><span class="nf">x0806dc2f</span> <span class="err">&lt;+</span><span class="mi">15</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">add</span> <span class="nv">%cl</span><span class="p">,</span><span class="nv">%ch</span> <span class="nf">End</span> <span class="no">of</span> <span class="no">assembler</span> <span class="no">dump.</span> <span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> </pre></div> </td></tr></table> <p>Parece que sigue por <code>_rt0_go</code> (y nunca vuelve), podemos cambiar el breakpoint a esa función</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1 2 3 4 5 6 7 8</pre></div></td><td class="code"><div class="highlight"><pre><span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> <span class="no">delete</span> <span class="mi">1</span> <span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> <span class="no">break</span> <span class="no">_rt0_go</span> <span class="nf">Breakpoint</span> <span class="mi">2</span> <span class="no">at</span> <span class="mi">0x806b890</span> <span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> <span class="no">continue</span> <span class="nf">Continuing.</span> <span class="nf">Breakpoint</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">0x0806b890</span> <span class="no">in</span> <span class="no">_rt0_go</span> <span class="p">()</span> <span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> </pre></div> </td></tr></table> <p>Y el código que contiene es: </p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25</pre></div></td><td class="code"><div class="highlight"><pre><span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> <span class="no">disassemble</span> <span class="nf">Dump</span> <span class="no">of</span> <span class="no">assembler</span> <span class="no">code</span> <span class="no">for</span> <span class="no">function</span> <span class="no">_rt0_go</span><span class="p">:</span> <span class="err">=&gt;</span> <span class="err">0</span><span class="nf">x0806b890</span> <span class="err">&lt;+</span><span class="mi">0</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0x4</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%eax</span> <span class="err">0</span><span class="nf">x0806b894</span> <span class="err">&lt;+</span><span class="mi">4</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0x8</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%ebx</span> <span class="err">0</span><span class="nf">x0806b898</span> <span class="err">&lt;+</span><span class="mi">8</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">sub</span> <span class="no">$0x80</span><span class="p">,</span><span class="nv">%esp</span> <span class="err">0</span><span class="nf">x0806b89e</span> <span class="err">&lt;+</span><span class="mi">14</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">and</span> <span class="no">$0xfffffff0</span><span class="p">,</span><span class="nv">%esp</span> <span class="err">0</span><span class="nf">x0806b8a1</span> <span class="err">&lt;+</span><span class="mi">17</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%eax</span><span class="p">,</span><span class="mi">0x78</span><span class="p">(</span><span class="nv">%esp</span><span class="p">)</span> <span class="err">0</span><span class="nf">x0806b8a5</span> <span class="err">&lt;+</span><span class="mi">21</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%ebx</span><span class="p">,</span><span class="mi">0x7c</span><span class="p">(</span><span class="nv">%esp</span><span class="p">)</span> <span class="err">0</span><span class="nf">x0806b8a9</span> <span class="err">&lt;+</span><span class="mi">25</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="no">$0x814e460</span><span class="p">,</span><span class="nv">%ebp</span> <span class="err">0</span><span class="nf">x0806b8ae</span> <span class="err">&lt;+</span><span class="mi">30</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">lea</span> <span class="p">-</span><span class="mi">0xff98</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%ebx</span> <span class="err">0</span><span class="nf">x0806b8b5</span> <span class="err">&lt;+</span><span class="mi">37</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%ebx</span><span class="p">,</span><span class="mi">0x3c</span><span class="p">(</span><span class="nv">%ebp</span><span class="p">)</span> <span class="err">0</span><span class="nf">x0806b8b8</span> <span class="err">&lt;+</span><span class="mi">40</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%ebx</span><span class="p">,</span><span class="mi">0x0</span><span class="p">(</span><span class="nv">%ebp</span><span class="p">)</span> <span class="err">0</span><span class="nf">x0806b8bb</span> <span class="err">&lt;+</span><span class="mi">43</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%esp</span><span class="p">,</span><span class="mi">0x4</span><span class="p">(</span><span class="nv">%ebp</span><span class="p">)</span> <span class="err">0</span><span class="nf">x0806b8be</span> <span class="err">&lt;+</span><span class="mi">46</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">xor</span> <span class="nv">%eax</span><span class="p">,</span><span class="nv">%eax</span> <span class="err">0</span><span class="nf">x0806b8c0</span> <span class="err">&lt;+</span><span class="mi">48</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">cpuid</span> <span class="err">0</span><span class="nf">x0806b8c2</span> <span class="err">&lt;+</span><span class="mi">50</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">cmp</span> <span class="no">$0x0</span><span class="p">,</span><span class="nv">%eax</span> <span class="err">0</span><span class="nf">x0806b8c5</span> <span class="err">&lt;+</span><span class="mi">53</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">je</span> <span class="mh">0x806b8da</span> <span class="p">&lt;</span><span class="no">_rt0_go</span><span class="p">+</span><span class="mi">74</span><span class="p">&gt;</span> <span class="err">0</span><span class="nf">x0806b8c7</span> <span class="err">&lt;+</span><span class="mi">55</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="no">$0x1</span><span class="p">,</span><span class="nv">%eax</span> <span class="err">0</span><span class="nf">x0806b8cc</span> <span class="err">&lt;+</span><span class="mi">60</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">cpuid</span> <span class="err">0</span><span class="nf">x0806b8ce</span> <span class="err">&lt;+</span><span class="mi">62</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%ecx</span><span class="p">,</span><span class="mi">0x814e008</span> <span class="err">0</span><span class="nf">x0806b8d4</span> <span class="err">&lt;+</span><span class="mi">68</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%edx</span><span class="p">,</span><span class="mi">0x814e00c</span> <span class="err">0</span><span class="nf">x0806b8da</span> <span class="err">&lt;+</span><span class="mi">74</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0x814df28</span><span class="p">,</span><span class="nv">%eax</span> <span class="err">0</span><span class="nf">x0806b8e0</span> <span class="err">&lt;+</span><span class="mi">80</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">test</span> <span class="nv">%eax</span><span class="p">,</span><span class="nv">%eax</span> <span class="err">0</span><span class="nf">x0806b8e2</span> <span class="err">&lt;+</span><span class="mi">82</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">je</span> <span class="mh">0x806b905</span> <span class="p">&lt;</span><span class="no">_rt0_go</span><span class="p">+</span><span class="mi">117</span><span class="p">&gt;</span> <span class="err">0</span><span class="nf">x0806b8e4</span> <span class="err">&lt;+</span><span class="mi">84</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="no">$0x806cfe0</span><span class="p">,</span><span class="nv">%ebx</span> </pre></div> </td></tr></table> <p>Y sigue hasta +270, pero aceleremos las cosas, no queremos que nos muestre ese mensaje, no? que la función se llame <code>_rt0_go</code> <a href="https://duckduckgo.com/?q=_rt0_go">nos indica</a> que es un programa hecho en <a href="https://duckduckgo.com/l/?kh=-1&amp;uddg=http%3A%2F%2Fgolang.org%2F">golang</a>, en ese lenguaje la función para printear es <code>fmt.Print</code>, esperemos por el programa ahí</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1 2 3 4 5 6 7 8 9 10</pre></div></td><td class="code"><div class="highlight"><pre><span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> <span class="no">break</span> <span class="no">fmt.Print</span> <span class="nf">Breakpoint</span> <span class="mi">3</span> <span class="no">at</span> <span class="mi">0x8071720</span> <span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> <span class="no">continue</span> <span class="nf">Continuing.</span> <span class="nf">Breakpoint</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">0x08071720</span> <span class="no">in</span> <span class="no">fmt.Print</span> <span class="p">()</span> <span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> <span class="no">bt</span> <span class="c">#0 0x08071720 in fmt.Print ()</span> <span class="c">#1 0x08048ebd in main.main ()</span> <span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> </pre></div> </td></tr></table> <p>Volvemos a empezar, ahora esperando en la dirección que llama a <code>fmt.Print</code></p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1 2 3 4 5 6 7 8 9 10</pre></div></td><td class="code"><div class="highlight"><pre><span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> <span class="no">break</span> <span class="p">*</span><span class="mi">0x08048ebd</span> <span class="nf">Breakpoint</span> <span class="mi">4</span> <span class="no">at</span> <span class="mi">0x8048ebd</span> <span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> <span class="no">delete</span> <span class="mi">2</span><span class="p">-</span><span class="mi">3</span> <span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> <span class="no">run</span> <span class="nf">The</span> <span class="no">program</span> <span class="no">being</span> <span class="no">debugged</span> <span class="no">has</span> <span class="no">been</span> <span class="no">started</span> <span class="no">already.</span> <span class="nf">Start</span> <span class="no">it</span> <span class="no">from</span> <span class="no">the</span> <span class="no">beginning</span><span class="err">?</span> <span class="p">(</span><span class="no">y</span> <span class="no">or</span> <span class="no">n</span><span class="p">)</span> <span class="no">y</span> <span class="nf">Starting</span> <span class="no">program</span><span class="p">:</span> <span class="err">/</span><span class="no">home</span><span class="err">/</span><span class="no">kenkeiras</span><span class="err">/</span><span class="no">ctf</span><span class="err">/</span><span class="mi">2014</span><span class="err">/</span><span class="no">ncn</span><span class="err">/</span><span class="no">quals</span><span class="err">/</span><span class="no">inbincible</span><span class="err">/</span><span class="no">inbincible</span> <span class="nf">N</span> <span class="nf">Breakpoint</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">0x08048ebd</span> <span class="no">in</span> <span class="no">main.main</span> <span class="p">()</span> <span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> </pre></div> </td></tr></table> <p>Ahora tenemos que buscar que nos lleva ahí para poder evitarlo... el desensamblado es grande, haciendo zoom en la parte donde quedó el programa</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102</pre></div></td><td class="code"><div class="highlight"><pre><span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> <span class="no">disassemble</span> <span class="na">...</span> <span class="err">0</span><span class="nf">x08048d9d</span> <span class="err">&lt;+</span><span class="mi">413</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">movl</span> <span class="no">$0x6</span><span class="p">,</span><span class="mi">0x88</span><span class="p">(</span><span class="nv">%esp</span><span class="p">)</span> <span class="err">0</span><span class="nf">x08048da8</span> <span class="err">&lt;+</span><span class="mi">424</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">movl</span> <span class="no">$0x6</span><span class="p">,</span><span class="mi">0x8c</span><span class="p">(</span><span class="nv">%esp</span><span class="p">)</span> <span class="err">0</span><span class="nf">x08048db3</span> <span class="err">&lt;+</span><span class="mi">435</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0x814e17c</span><span class="p">,</span><span class="nv">%ebx</span> <span class="err">0</span><span class="nf">x08048db9</span> <span class="err">&lt;+</span><span class="mi">441</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">cmp</span> <span class="no">$0x2</span><span class="p">,</span><span class="nv">%ebx</span> <span class="err">0</span><span class="nf">x08048dbc</span> <span class="err">&lt;+</span><span class="mi">444</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">je</span> <span class="mh">0x8048ef1</span> <span class="p">&lt;</span><span class="no">main.main</span><span class="p">+</span><span class="mi">753</span><span class="p">&gt;</span> <span class="err">0</span><span class="nf">x08048dc2</span> <span class="err">&lt;+</span><span class="mi">450</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">xor</span> <span class="nv">%ecx</span><span class="p">,</span><span class="nv">%ecx</span> <span class="err">0</span><span class="nf">x08048dc4</span> <span class="err">&lt;+</span><span class="mi">452</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0x88</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%ebp</span> <span class="err">0</span><span class="nf">x08048dcb</span> <span class="err">&lt;+</span><span class="mi">459</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">cmp</span> <span class="nv">%ecx</span><span class="p">,</span><span class="nv">%ebp</span> <span class="err">0</span><span class="nf">x08048dcd</span> <span class="err">&lt;+</span><span class="mi">461</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">jle</span> <span class="mh">0x8048ed1</span> <span class="p">&lt;</span><span class="no">main.main</span><span class="p">+</span><span class="mi">721</span><span class="p">&gt;</span> <span class="err">0</span><span class="nf">x08048dd3</span> <span class="err">&lt;+</span><span class="mi">467</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%ecx</span><span class="p">,</span><span class="nv">%edx</span> <span class="err">0</span><span class="nf">x08048dd5</span> <span class="err">&lt;+</span><span class="mi">469</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0xa0</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%ebx</span> <span class="err">0</span><span class="nf">x08048ddc</span> <span class="err">&lt;+</span><span class="mi">476</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%ecx</span><span class="p">,</span><span class="nv">%eax</span> <span class="err">0</span><span class="nf">x08048dde</span> <span class="err">&lt;+</span><span class="mi">478</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">cmp</span> <span class="no">$0xffffffff</span><span class="p">,</span><span class="nv">%ebx</span> <span class="err">0</span><span class="nf">x08048de1</span> <span class="err">&lt;+</span><span class="mi">481</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">je</span> <span class="mh">0x8048eea</span> <span class="p">&lt;</span><span class="no">main.main</span><span class="p">+</span><span class="mi">746</span><span class="p">&gt;</span> <span class="err">0</span><span class="nf">x08048de7</span> <span class="err">&lt;+</span><span class="mi">487</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">cltd</span> <span class="mi">0x08048de8</span> <span class="err">&lt;+</span><span class="mi">488</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">idiv</span> <span class="nv">%ebx</span> <span class="err">0</span><span class="nf">x08048dea</span> <span class="err">&lt;+</span><span class="mi">490</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%edx</span><span class="p">,</span><span class="nv">%ebp</span> <span class="err">0</span><span class="nf">x08048dec</span> <span class="err">&lt;+</span><span class="mi">492</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">cmp</span> <span class="mi">0xa0</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%ebp</span> <span class="err">0</span><span class="nf">x08048df3</span> <span class="err">&lt;+</span><span class="mi">499</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">jae</span> <span class="mh">0x8048ee3</span> <span class="p">&lt;</span><span class="no">main.main</span><span class="p">+</span><span class="mi">739</span><span class="p">&gt;</span> <span class="err">0</span><span class="nf">x08048df9</span> <span class="err">&lt;+</span><span class="mi">505</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0x9c</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%edx</span> <span class="err">0</span><span class="nf">x08048e00</span> <span class="err">&lt;+</span><span class="mi">512</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">lea</span> <span class="p">(</span><span class="nv">%edx</span><span class="p">,</span><span class="nv">%ebp</span><span class="p">,</span><span class="mi">1</span><span class="p">),</span><span class="nv">%edx</span> <span class="err">0</span><span class="nf">x08048e03</span> <span class="err">&lt;+</span><span class="mi">515</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">movzbl</span> <span class="p">(</span><span class="nv">%edx</span><span class="p">),</span><span class="nv">%edx</span> <span class="err">0</span><span class="nf">x08048e06</span> <span class="err">&lt;+</span><span class="mi">518</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%ecx</span><span class="p">,</span><span class="mi">0x28</span><span class="p">(</span><span class="nv">%esp</span><span class="p">)</span> <span class="err">0</span><span class="nf">x08048e0a</span> <span class="err">&lt;+</span><span class="mi">522</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">cmp</span> <span class="mi">0x88</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%ecx</span> <span class="err">0</span><span class="nf">x08048e11</span> <span class="err">&lt;+</span><span class="mi">529</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">jae</span> <span class="mh">0x8048edc</span> <span class="p">&lt;</span><span class="no">main.main</span><span class="p">+</span><span class="mi">732</span><span class="p">&gt;</span> <span class="err">0</span><span class="nf">x08048e17</span> <span class="err">&lt;+</span><span class="mi">535</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0x84</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%ebx</span> <span class="err">0</span><span class="nf">x08048e1e</span> <span class="err">&lt;+</span><span class="mi">542</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">lea</span> <span class="p">(</span><span class="nv">%ebx</span><span class="p">,</span><span class="nv">%ecx</span><span class="p">,</span><span class="mi">1</span><span class="p">),</span><span class="nv">%ebx</span> <span class="err">0</span><span class="nf">x08048e21</span> <span class="err">&lt;+</span><span class="mi">545</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">movzbl</span> <span class="p">(</span><span class="nv">%ebx</span><span class="p">),</span><span class="nv">%ebx</span> <span class="err">0</span><span class="nf">x08048e24</span> <span class="err">&lt;+</span><span class="mi">548</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%edx</span><span class="p">,</span><span class="nv">%ebp</span> <span class="err">0</span><span class="nf">x08048e26</span> <span class="err">&lt;+</span><span class="mi">550</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">xor</span> <span class="nv">%ebx</span><span class="p">,</span><span class="nv">%ebp</span> <span class="err">0</span><span class="nf">x08048e28</span> <span class="err">&lt;+</span><span class="mi">552</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">xchg</span> <span class="nv">%eax</span><span class="p">,</span><span class="nv">%ebp</span> <span class="err">0</span><span class="nf">x08048e29</span> <span class="err">&lt;+</span><span class="mi">553</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">movzbl</span> <span class="nv">%al</span><span class="p">,</span><span class="nv">%eax</span> <span class="err">0</span><span class="nf">x08048e2c</span> <span class="err">&lt;+</span><span class="mi">556</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">xchg</span> <span class="nv">%eax</span><span class="p">,</span><span class="nv">%ebp</span> <span class="err">0</span><span class="nf">x08048e2d</span> <span class="err">&lt;+</span><span class="mi">557</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">xor</span> <span class="nv">%ecx</span><span class="p">,</span><span class="nv">%ecx</span> <span class="err">0</span><span class="nf">x08048e2f</span> <span class="err">&lt;+</span><span class="mi">559</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%ebp</span><span class="p">,(</span><span class="nv">%esp</span><span class="p">)</span> <span class="err">0</span><span class="nf">x08048e32</span> <span class="err">&lt;+</span><span class="mi">562</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%ecx</span><span class="p">,</span><span class="mi">0x4</span><span class="p">(</span><span class="nv">%esp</span><span class="p">)</span> <span class="err">0</span><span class="nf">x08048e36</span> <span class="err">&lt;+</span><span class="mi">566</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">call</span> <span class="mh">0x806a6b0</span> <span class="p">&lt;</span><span class="no">runtime.intstring</span><span class="p">&gt;</span> <span class="err">0</span><span class="nf">x08048e3b</span> <span class="err">&lt;+</span><span class="mi">571</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0x8</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%ebx</span> <span class="err">0</span><span class="nf">x08048e3f</span> <span class="err">&lt;+</span><span class="mi">575</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%ebx</span><span class="p">,</span><span class="mi">0x74</span><span class="p">(</span><span class="nv">%esp</span><span class="p">)</span> <span class="err">0</span><span class="nf">x08048e43</span> <span class="err">&lt;+</span><span class="mi">579</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0xc</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%ebx</span> <span class="err">0</span><span class="nf">x08048e47</span> <span class="err">&lt;+</span><span class="mi">583</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%ebx</span><span class="p">,</span><span class="mi">0x78</span><span class="p">(</span><span class="nv">%esp</span><span class="p">)</span> <span class="err">0</span><span class="nf">x08048e4b</span> <span class="err">&lt;+</span><span class="mi">587</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">lea</span> <span class="mi">0x7c</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%edi</span> <span class="err">0</span><span class="nf">x08048e4f</span> <span class="err">&lt;+</span><span class="mi">591</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">xor</span> <span class="nv">%eax</span><span class="p">,</span><span class="nv">%eax</span> <span class="err">0</span><span class="nf">x08048e51</span> <span class="err">&lt;+</span><span class="mi">593</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">stos</span> <span class="nv">%eax</span><span class="p">,</span><span class="nv">%es</span><span class="p">:(</span><span class="nv">%edi</span><span class="p">)</span> <span class="err">0</span><span class="nf">x08048e52</span> <span class="err">&lt;+</span><span class="mi">594</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">stos</span> <span class="nv">%eax</span><span class="p">,</span><span class="nv">%es</span><span class="p">:(</span><span class="nv">%edi</span><span class="p">)</span> <span class="err">0</span><span class="nf">x08048e53</span> <span class="err">&lt;+</span><span class="mi">595</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">lea</span> <span class="mi">0x7c</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%ebx</span> <span class="err">0</span><span class="nf">x08048e57</span> <span class="err">&lt;+</span><span class="mi">599</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">cmp</span> <span class="no">$0x0</span><span class="p">,</span><span class="nv">%ebx</span> <span class="err">0</span><span class="nf">x08048e5a</span> <span class="err">&lt;+</span><span class="mi">602</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">je</span> <span class="mh">0x8048ed8</span> <span class="p">&lt;</span><span class="no">main.main</span><span class="p">+</span><span class="mi">728</span><span class="p">&gt;</span> <span class="err">0</span><span class="nf">x08048e5c</span> <span class="err">&lt;+</span><span class="mi">604</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%ebx</span><span class="p">,</span><span class="mi">0xa8</span><span class="p">(</span><span class="nv">%esp</span><span class="p">)</span> <span class="err">0</span><span class="nf">x08048e63</span> <span class="err">&lt;+</span><span class="mi">611</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">movl</span> <span class="no">$0x1</span><span class="p">,</span><span class="mi">0xac</span><span class="p">(</span><span class="nv">%esp</span><span class="p">)</span> <span class="err">0</span><span class="nf">x08048e6e</span> <span class="err">&lt;+</span><span class="mi">622</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">movl</span> <span class="no">$0x1</span><span class="p">,</span><span class="mi">0xb0</span><span class="p">(</span><span class="nv">%esp</span><span class="p">)</span> <span class="err">0</span><span class="nf">x08048e79</span> <span class="err">&lt;+</span><span class="mi">633</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">movl</span> <span class="no">$0x80cc440</span><span class="p">,(</span><span class="nv">%esp</span><span class="p">)</span> <span class="err">0</span><span class="nf">x08048e80</span> <span class="err">&lt;+</span><span class="mi">640</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">lea</span> <span class="mi">0x74</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%ebx</span> <span class="err">0</span><span class="nf">x08048e84</span> <span class="err">&lt;+</span><span class="mi">644</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%ebx</span><span class="p">,</span><span class="mi">0x4</span><span class="p">(</span><span class="nv">%esp</span><span class="p">)</span> <span class="err">0</span><span class="nf">x08048e88</span> <span class="err">&lt;+</span><span class="mi">648</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">call</span> <span class="mh">0x8065ed0</span> <span class="p">&lt;</span><span class="no">runtime.convT2E</span><span class="p">&gt;</span> <span class="err">0</span><span class="nf">x08048e8d</span> <span class="err">&lt;+</span><span class="mi">653</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0xa8</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%edi</span> <span class="err">0</span><span class="nf">x08048e94</span> <span class="err">&lt;+</span><span class="mi">660</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">lea</span> <span class="mi">0x8</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%ebx</span> <span class="err">0</span><span class="nf">x08048e98</span> <span class="err">&lt;+</span><span class="mi">664</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%ebx</span><span class="p">,</span><span class="nv">%esi</span> <span class="err">0</span><span class="nf">x08048e9a</span> <span class="err">&lt;+</span><span class="mi">666</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%edi</span><span class="p">,</span><span class="nv">%edx</span> <span class="err">0</span><span class="nf">x08048e9c</span> <span class="err">&lt;+</span><span class="mi">668</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">cld</span> <span class="mi">0x08048e9d</span> <span class="err">&lt;+</span><span class="mi">669</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">movsl</span> <span class="nv">%ds</span><span class="p">:(</span><span class="nv">%esi</span><span class="p">),</span><span class="nv">%es</span><span class="p">:(</span><span class="nv">%edi</span><span class="p">)</span> <span class="err">0</span><span class="nf">x08048e9e</span> <span class="err">&lt;+</span><span class="mi">670</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">movsl</span> <span class="nv">%ds</span><span class="p">:(</span><span class="nv">%esi</span><span class="p">),</span><span class="nv">%es</span><span class="p">:(</span><span class="nv">%edi</span><span class="p">)</span> <span class="err">0</span><span class="nf">x08048e9f</span> <span class="err">&lt;+</span><span class="mi">671</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%edx</span><span class="p">,(</span><span class="nv">%esp</span><span class="p">)</span> <span class="err">0</span><span class="nf">x08048ea2</span> <span class="err">&lt;+</span><span class="mi">674</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0xac</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%ebx</span> <span class="err">0</span><span class="nf">x08048ea9</span> <span class="err">&lt;+</span><span class="mi">681</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%ebx</span><span class="p">,</span><span class="mi">0x4</span><span class="p">(</span><span class="nv">%esp</span><span class="p">)</span> <span class="err">0</span><span class="nf">x08048ead</span> <span class="err">&lt;+</span><span class="mi">685</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0xb0</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%ebx</span> <span class="err">0</span><span class="nf">x08048eb4</span> <span class="err">&lt;+</span><span class="mi">692</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%ebx</span><span class="p">,</span><span class="mi">0x8</span><span class="p">(</span><span class="nv">%esp</span><span class="p">)</span> <span class="err">0</span><span class="nf">x08048eb8</span> <span class="err">&lt;+</span><span class="mi">696</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">call</span> <span class="mh">0x8071720</span> <span class="p">&lt;</span><span class="no">fmt.Print</span><span class="p">&gt;</span> <span class="err">=&gt;</span> <span class="err">0</span><span class="nf">x08048ebd</span> <span class="err">&lt;+</span><span class="mi">701</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0x28</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%ecx</span> <span class="err">0</span><span class="nf">x08048ec1</span> <span class="err">&lt;+</span><span class="mi">705</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">inc</span> <span class="nv">%ecx</span> <span class="err">0</span><span class="nf">x08048ec2</span> <span class="err">&lt;+</span><span class="mi">706</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0x88</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%ebp</span> <span class="err">0</span><span class="nf">x08048ec9</span> <span class="err">&lt;+</span><span class="mi">713</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">cmp</span> <span class="nv">%ecx</span><span class="p">,</span><span class="nv">%ebp</span> <span class="err">0</span><span class="nf">x08048ecb</span> <span class="err">&lt;+</span><span class="mi">715</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">jg</span> <span class="mh">0x8048dd3</span> <span class="p">&lt;</span><span class="no">main.main</span><span class="p">+</span><span class="mi">467</span><span class="p">&gt;</span> <span class="err">0</span><span class="nf">x08048ed1</span> <span class="err">&lt;+</span><span class="mi">721</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">add</span> <span class="no">$0xc0</span><span class="p">,</span><span class="nv">%esp</span> <span class="err">0</span><span class="nf">x08048ed7</span> <span class="err">&lt;+</span><span class="mi">727</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">ret</span> <span class="mi">0x08048ed8</span> <span class="err">&lt;+</span><span class="mi">728</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%eax</span><span class="p">,(</span><span class="nv">%ebx</span><span class="p">)</span> <span class="err">0</span><span class="nf">x08048eda</span> <span class="err">&lt;+</span><span class="mi">730</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">jmp</span> <span class="mh">0x8048e5c</span> <span class="p">&lt;</span><span class="no">main.main</span><span class="p">+</span><span class="mi">604</span><span class="p">&gt;</span> <span class="err">0</span><span class="nf">x08048edc</span> <span class="err">&lt;+</span><span class="mi">732</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">call</span> <span class="mh">0x8055f40</span> <span class="p">&lt;</span><span class="no">runtime.panicindex</span><span class="p">&gt;</span> <span class="err">0</span><span class="nf">x08048ee1</span> <span class="err">&lt;+</span><span class="mi">737</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">ud2</span> <span class="mi">0x08048ee3</span> <span class="err">&lt;+</span><span class="mi">739</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">call</span> <span class="mh">0x8055f40</span> <span class="p">&lt;</span><span class="no">runtime.panicindex</span><span class="p">&gt;</span> <span class="err">0</span><span class="nf">x08048ee8</span> <span class="err">&lt;+</span><span class="mi">744</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">ud2</span> <span class="mi">0x08048eea</span> <span class="err">&lt;+</span><span class="mi">746</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">xor</span> <span class="nv">%ebp</span><span class="p">,</span><span class="nv">%ebp</span> <span class="err">0</span><span class="nf">x08048eec</span> <span class="err">&lt;+</span><span class="mi">748</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">jmp</span> <span class="mh">0x8048dec</span> <span class="p">&lt;</span><span class="no">main.main</span><span class="p">+</span><span class="mi">492</span><span class="p">&gt;</span> <span class="err">0</span><span class="nf">x08048ef1</span> <span class="err">&lt;+</span><span class="mi">753</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">cmpl</span> <span class="no">$0x1</span><span class="p">,</span><span class="mi">0x814e17c</span> <span class="err">0</span><span class="nf">x08048ef8</span> <span class="err">&lt;+</span><span class="mi">760</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">jbe</span> <span class="mh">0x804937d</span> <span class="p">&lt;</span><span class="no">main.main</span><span class="p">+</span><span class="mi">1917</span><span class="p">&gt;</span> <span class="err">0</span><span class="nf">x08048efe</span> <span class="err">&lt;+</span><span class="mi">766</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0x814e178</span><span class="p">,</span><span class="nv">%ebx</span> <span class="err">0</span><span class="nf">x08048f04</span> <span class="err">&lt;+</span><span class="mi">772</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">add</span> <span class="no">$0x8</span><span class="p">,</span><span class="nv">%ebx</span> <span class="err">0</span><span class="nf">x08048f07</span> <span class="err">&lt;+</span><span class="mi">775</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0x4</span><span class="p">(</span><span class="nv">%ebx</span><span class="p">),</span><span class="nv">%esi</span> <span class="err">0</span><span class="nf">x08048f0a</span> <span class="err">&lt;+</span><span class="mi">778</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0x6c</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%ebx</span> <span class="err">0</span><span class="nf">x08048f0e</span> <span class="err">&lt;+</span><span class="mi">782</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0x4</span><span class="p">(</span><span class="nv">%ebx</span><span class="p">),</span><span class="nv">%ebp</span> <span class="err">0</span><span class="nf">x08048f11</span> <span class="err">&lt;+</span><span class="mi">785</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">cmp</span> <span class="nv">%ebp</span><span class="p">,</span><span class="nv">%esi</span> <span class="err">0</span><span class="nf">x08048f13</span> <span class="err">&lt;+</span><span class="mi">787</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">je</span> <span class="mh">0x8049048</span> <span class="p">&lt;</span><span class="no">main.main</span><span class="p">+</span><span class="mi">1096</span><span class="p">&gt;</span> <span class="err">0</span><span class="nf">x08048f19</span> <span class="err">&lt;+</span><span class="mi">793</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">xor</span> <span class="nv">%ecx</span><span class="p">,</span><span class="nv">%ecx</span> <span class="err">0</span><span class="nf">x08048f1b</span> <span class="err">&lt;+</span><span class="mi">795</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0x88</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%ebp</span> <span class="err">0</span><span class="nf">x08048f22</span> <span class="err">&lt;+</span><span class="mi">802</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">cmp</span> <span class="nv">%ecx</span><span class="p">,</span><span class="nv">%ebp</span> <span class="err">0</span><span class="nf">x08048f24</span> <span class="err">&lt;+</span><span class="mi">804</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">jle</span> <span class="mh">0x8049028</span> <span class="p">&lt;</span><span class="no">main.main</span><span class="p">+</span><span class="mi">1064</span><span class="p">&gt;</span> <span class="err">---</span><span class="nf">Type</span> <span class="err">&lt;</span><span class="no">return</span><span class="err">&gt;</span> <span class="no">to</span> <span class="no">continue</span><span class="p">,</span> <span class="no">or</span> <span class="mh">q</span> <span class="p">&lt;</span><span class="no">return</span><span class="p">&gt;</span> <span class="no">to</span> <span class="no">quit---q</span> <span class="nf">Quit</span> <span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> </pre></div> </td></tr></table> <p>Podemos ver que por lo menos hasta <strong>+467</strong> es parte del bucle, ¿que jump se pudo tomar o evitar antes?</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1 2 3 4 5 6 7 8 9</pre></div></td><td class="code"><div class="highlight"><pre> <span class="err">0</span><span class="nf">x08048d9d</span> <span class="err">&lt;+</span><span class="mi">413</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">movl</span> <span class="no">$0x6</span><span class="p">,</span><span class="mi">0x88</span><span class="p">(</span><span class="nv">%esp</span><span class="p">)</span> <span class="err">0</span><span class="nf">x08048da8</span> <span class="err">&lt;+</span><span class="mi">424</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">movl</span> <span class="no">$0x6</span><span class="p">,</span><span class="mi">0x8c</span><span class="p">(</span><span class="nv">%esp</span><span class="p">)</span> <span class="err">0</span><span class="nf">x08048db3</span> <span class="err">&lt;+</span><span class="mi">435</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0x814e17c</span><span class="p">,</span><span class="nv">%ebx</span> <span class="err">0</span><span class="nf">x08048db9</span> <span class="err">&lt;+</span><span class="mi">441</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">cmp</span> <span class="no">$0x2</span><span class="p">,</span><span class="nv">%ebx</span> <span class="err">0</span><span class="nf">x08048dbc</span> <span class="err">&lt;+</span><span class="mi">444</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">je</span> <span class="mh">0x8048ef1</span> <span class="p">&lt;</span><span class="no">main.main</span><span class="p">+</span><span class="mi">753</span><span class="p">&gt;</span> <span class="err">0</span><span class="nf">x08048dc2</span> <span class="err">&lt;+</span><span class="mi">450</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">xor</span> <span class="nv">%ecx</span><span class="p">,</span><span class="nv">%ecx</span> <span class="err">0</span><span class="nf">x08048dc4</span> <span class="err">&lt;+</span><span class="mi">452</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0x88</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%ebp</span> <span class="err">0</span><span class="nf">x08048dcb</span> <span class="err">&lt;+</span><span class="mi">459</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">cmp</span> <span class="nv">%ecx</span><span class="p">,</span><span class="nv">%ebp</span> <span class="err">0</span><span class="nf">x08048dcd</span> <span class="err">&lt;+</span><span class="mi">461</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">jle</span> <span class="mh">0x8048ed1</span> <span class="p">&lt;</span><span class="no">main.main</span><span class="p">+</span><span class="mi">721</span><span class="p">&gt;</span> </pre></div> </td></tr></table> <p>El más cercano, que nos lleva a <strong>+721</strong> provocará un <code>ret</code>, que no es lo que queremos</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1 2</pre></div></td><td class="code"><div class="highlight"><pre> <span class="err">0</span><span class="nf">x08048ed1</span> <span class="err">&lt;+</span><span class="mi">721</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">add</span> <span class="no">$0xc0</span><span class="p">,</span><span class="nv">%esp</span> <span class="err">0</span><span class="nf">x08048ed7</span> <span class="err">&lt;+</span><span class="mi">727</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">ret</span> </pre></div> </td></tr></table> <p>El siguiente, un <code>je</code> nos lleva a <strong>+753</strong> que parece que tiene más recorrido, veamos el <code>cmp</code> que lo precede</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1 2 3 4 5 6 7 8 9 10 11 12</pre></div></td><td class="code"><div class="highlight"><pre><span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> <span class="no">break</span> <span class="p">*</span><span class="mi">0x08048db9</span> <span class="nf">Breakpoint</span> <span class="mi">5</span> <span class="no">at</span> <span class="mi">0x8048db9</span> <span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> <span class="no">delete</span> <span class="mi">4</span> <span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> <span class="no">run</span> <span class="nf">The</span> <span class="no">program</span> <span class="no">being</span> <span class="no">debugged</span> <span class="no">has</span> <span class="no">been</span> <span class="no">started</span> <span class="no">already.</span> <span class="nf">Start</span> <span class="no">it</span> <span class="no">from</span> <span class="no">the</span> <span class="no">beginning</span><span class="err">?</span> <span class="p">(</span><span class="no">y</span> <span class="no">or</span> <span class="no">n</span><span class="p">)</span> <span class="no">y</span> <span class="nf">Starting</span> <span class="no">program</span><span class="p">:</span> <span class="err">/</span><span class="no">home</span><span class="err">/</span><span class="no">kenkeiras</span><span class="err">/</span><span class="no">ctf</span><span class="err">/</span><span class="mi">2014</span><span class="err">/</span><span class="no">ncn</span><span class="err">/</span><span class="no">quals</span><span class="err">/</span><span class="no">inbincible</span><span class="err">/</span><span class="no">inbincible</span> <span class="nf">Breakpoint</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">0x08048db9</span> <span class="no">in</span> <span class="no">main.main</span> <span class="p">()</span> <span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> <span class="no">x</span><span class="err">/</span><span class="no">i</span> <span class="no">$eip</span> <span class="err">=&gt;</span> <span class="err">0</span><span class="nf">x8048db9</span> <span class="err">&lt;</span><span class="no">main.main</span><span class="err">+</span><span class="mi">441</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">cmp</span> <span class="no">$0x2</span><span class="p">,</span><span class="nv">%ebx</span> <span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> </pre></div> </td></tr></table> <p>Se supone que debería dar true, y el valor de <code>%ebx</code> es...</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1 2 3</pre></div></td><td class="code"><div class="highlight"><pre><span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> <span class="no">print</span> <span class="no">$ebx</span> <span class="nf">$1</span> <span class="err">=</span> <span class="mi">1</span> <span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> </pre></div> </td></tr></table> <p>Así que no, ahora, ¿cúal es el 1 que podemos haber metido en el programa?</p> <p>¿El número de parámetros?</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1 2 3 4 5 6 7 8 9</pre></div></td><td class="code"><div class="highlight"><pre><span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> <span class="no">run</span> <span class="no">test</span> <span class="nf">The</span> <span class="no">program</span> <span class="no">being</span> <span class="no">debugged</span> <span class="no">has</span> <span class="no">been</span> <span class="no">started</span> <span class="no">already.</span> <span class="nf">Start</span> <span class="no">it</span> <span class="no">from</span> <span class="no">the</span> <span class="no">beginning</span><span class="err">?</span> <span class="p">(</span><span class="no">y</span> <span class="no">or</span> <span class="no">n</span><span class="p">)</span> <span class="no">y</span> <span class="nf">Starting</span> <span class="no">program</span><span class="p">:</span> <span class="err">/</span><span class="no">home</span><span class="err">/</span><span class="no">kenkeiras</span><span class="err">/</span><span class="no">ctf</span><span class="err">/</span><span class="mi">2014</span><span class="err">/</span><span class="no">ncn</span><span class="err">/</span><span class="no">quals</span><span class="err">/</span><span class="no">inbincible</span><span class="err">/</span><span class="no">inbincible</span> <span class="no">test</span> <span class="nf">Breakpoint</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">0x08048db9</span> <span class="no">in</span> <span class="no">main.main</span> <span class="p">()</span> <span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> <span class="no">print</span> <span class="no">$ebx</span> <span class="nf">$2</span> <span class="err">=</span> <span class="mi">2</span> <span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> </pre></div> </td></tr></table> <p>Parece que sí, por supuesto no es suficiente :P</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1 2 3 4 5</pre></div></td><td class="code"><div class="highlight"><pre><span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> <span class="no">continue</span> <span class="nf">Continuing.</span> <span class="nf">Nope</span><span class="err">!</span> <span class="err">[</span><span class="nf">Inferior</span> <span class="mi">1</span> <span class="p">(</span><span class="no">process</span> <span class="mi">16416</span><span class="p">)</span> <span class="no">exited</span> <span class="no">normally</span><span class="err">]</span> <span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> </pre></div> </td></tr></table> <p>Repetimos...</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20</pre></div></td><td class="code"><div class="highlight"><pre><span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> <span class="no">delete</span> <span class="mi">5</span> <span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> <span class="no">break</span> <span class="no">fmt.Print</span> <span class="nf">Breakpoint</span> <span class="mi">6</span> <span class="no">at</span> <span class="mi">0x8071720</span> <span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> <span class="no">run</span> <span class="nf">Starting</span> <span class="no">program</span><span class="p">:</span> <span class="err">/</span><span class="no">home</span><span class="err">/</span><span class="no">kenkeiras</span><span class="err">/</span><span class="no">ctf</span><span class="err">/</span><span class="mi">2014</span><span class="err">/</span><span class="no">ncn</span><span class="err">/</span><span class="no">quals</span><span class="err">/</span><span class="no">inbincible</span><span class="err">/</span><span class="no">inbincible</span> <span class="no">test</span> <span class="nf">Breakpoint</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">0x08071720</span> <span class="no">in</span> <span class="no">fmt.Print</span> <span class="p">()</span> <span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> <span class="no">bt</span> <span class="c">#0 0x08071720 in fmt.Print ()</span> <span class="c">#1 0x08049014 in main.main ()</span> <span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> <span class="no">break</span> <span class="p">*</span><span class="mi">0x08049014</span> <span class="nf">Breakpoint</span> <span class="mi">7</span> <span class="no">at</span> <span class="mi">0x8049014</span> <span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> <span class="no">delete</span> <span class="mi">6</span> <span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> <span class="no">run</span> <span class="no">The</span> <span class="no">program</span> <span class="no">being</span> <span class="no">debugged</span> <span class="no">has</span> <span class="no">been</span> <span class="no">started</span> <span class="no">already.</span> <span class="nf">Start</span> <span class="no">it</span> <span class="no">from</span> <span class="no">the</span> <span class="no">beginning</span><span class="err">?</span> <span class="p">(</span><span class="no">y</span> <span class="no">or</span> <span class="no">n</span><span class="p">)</span> <span class="no">y</span> <span class="nf">Starting</span> <span class="no">program</span><span class="p">:</span> <span class="err">/</span><span class="no">home</span><span class="err">/</span><span class="no">kenkeiras</span><span class="err">/</span><span class="no">ctf</span><span class="err">/</span><span class="mi">2014</span><span class="err">/</span><span class="no">ncn</span><span class="err">/</span><span class="no">quals</span><span class="err">/</span><span class="no">inbincible</span><span class="err">/</span><span class="no">inbincible</span> <span class="no">test</span> <span class="nf">N</span> <span class="nf">Breakpoint</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">0x08049014</span> <span class="no">in</span> <span class="no">main.main</span> <span class="p">()</span> <span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> </pre></div> </td></tr></table> <p>Ahora nos quedamos aquí</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90</pre></div></td><td class="code"><div class="highlight"><pre><span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> <span class="no">disassemble</span> <span class="na">...</span> <span class="err">0</span><span class="nf">x08048f07</span> <span class="err">&lt;+</span><span class="mi">775</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0x4</span><span class="p">(</span><span class="nv">%ebx</span><span class="p">),</span><span class="nv">%esi</span> <span class="err">0</span><span class="nf">x08048f0a</span> <span class="err">&lt;+</span><span class="mi">778</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0x6c</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%ebx</span> <span class="err">0</span><span class="nf">x08048f0e</span> <span class="err">&lt;+</span><span class="mi">782</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0x4</span><span class="p">(</span><span class="nv">%ebx</span><span class="p">),</span><span class="nv">%ebp</span> <span class="err">0</span><span class="nf">x08048f11</span> <span class="err">&lt;+</span><span class="mi">785</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">cmp</span> <span class="nv">%ebp</span><span class="p">,</span><span class="nv">%esi</span> <span class="err">0</span><span class="nf">x08048f13</span> <span class="err">&lt;+</span><span class="mi">787</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">je</span> <span class="mh">0x8049048</span> <span class="p">&lt;</span><span class="no">main.main</span><span class="p">+</span><span class="mi">1096</span><span class="p">&gt;</span> <span class="err">0</span><span class="nf">x08048f19</span> <span class="err">&lt;+</span><span class="mi">793</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">xor</span> <span class="nv">%ecx</span><span class="p">,</span><span class="nv">%ecx</span> <span class="err">0</span><span class="nf">x08048f1b</span> <span class="err">&lt;+</span><span class="mi">795</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0x88</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%ebp</span> <span class="err">0</span><span class="nf">x08048f22</span> <span class="err">&lt;+</span><span class="mi">802</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">cmp</span> <span class="nv">%ecx</span><span class="p">,</span><span class="nv">%ebp</span> <span class="err">0</span><span class="nf">x08048f24</span> <span class="err">&lt;+</span><span class="mi">804</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">jle</span> <span class="mh">0x8049028</span> <span class="p">&lt;</span><span class="no">main.main</span><span class="p">+</span><span class="mi">1064</span><span class="p">&gt;</span> <span class="err">0</span><span class="nf">x08048f2a</span> <span class="err">&lt;+</span><span class="mi">810</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%ecx</span><span class="p">,</span><span class="nv">%edx</span> <span class="err">0</span><span class="nf">x08048f2c</span> <span class="err">&lt;+</span><span class="mi">812</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0xa0</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%ebx</span> <span class="err">0</span><span class="nf">x08048f33</span> <span class="err">&lt;+</span><span class="mi">819</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%ecx</span><span class="p">,</span><span class="nv">%eax</span> <span class="err">0</span><span class="nf">x08048f35</span> <span class="err">&lt;+</span><span class="mi">821</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">cmp</span> <span class="no">$0xffffffff</span><span class="p">,</span><span class="nv">%ebx</span> <span class="err">0</span><span class="nf">x08048f38</span> <span class="err">&lt;+</span><span class="mi">824</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">je</span> <span class="mh">0x8049041</span> <span class="p">&lt;</span><span class="no">main.main</span><span class="p">+</span><span class="mi">1089</span><span class="p">&gt;</span> <span class="err">0</span><span class="nf">x08048f3e</span> <span class="err">&lt;+</span><span class="mi">830</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">cltd</span> <span class="mi">0x08048f3f</span> <span class="err">&lt;+</span><span class="mi">831</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">idiv</span> <span class="nv">%ebx</span> <span class="err">0</span><span class="nf">x08048f41</span> <span class="err">&lt;+</span><span class="mi">833</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%edx</span><span class="p">,</span><span class="nv">%ebp</span> <span class="err">0</span><span class="nf">x08048f43</span> <span class="err">&lt;+</span><span class="mi">835</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">cmp</span> <span class="mi">0xa0</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%ebp</span> <span class="err">0</span><span class="nf">x08048f4a</span> <span class="err">&lt;+</span><span class="mi">842</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">jae</span> <span class="mh">0x804903a</span> <span class="p">&lt;</span><span class="no">main.main</span><span class="p">+</span><span class="mi">1082</span><span class="p">&gt;</span> <span class="err">0</span><span class="nf">x08048f50</span> <span class="err">&lt;+</span><span class="mi">848</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0x9c</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%edx</span> <span class="err">0</span><span class="nf">x08048f57</span> <span class="err">&lt;+</span><span class="mi">855</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">lea</span> <span class="p">(</span><span class="nv">%edx</span><span class="p">,</span><span class="nv">%ebp</span><span class="p">,</span><span class="mi">1</span><span class="p">),</span><span class="nv">%edx</span> <span class="err">0</span><span class="nf">x08048f5a</span> <span class="err">&lt;+</span><span class="mi">858</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">movzbl</span> <span class="p">(</span><span class="nv">%edx</span><span class="p">),</span><span class="nv">%edx</span> <span class="err">0</span><span class="nf">x08048f5d</span> <span class="err">&lt;+</span><span class="mi">861</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%ecx</span><span class="p">,</span><span class="mi">0x1c</span><span class="p">(</span><span class="nv">%esp</span><span class="p">)</span> <span class="err">0</span><span class="nf">x08048f61</span> <span class="err">&lt;+</span><span class="mi">865</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">cmp</span> <span class="mi">0x88</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%ecx</span> <span class="err">0</span><span class="nf">x08048f68</span> <span class="err">&lt;+</span><span class="mi">872</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">jae</span> <span class="mh">0x8049033</span> <span class="p">&lt;</span><span class="no">main.main</span><span class="p">+</span><span class="mi">1075</span><span class="p">&gt;</span> <span class="err">0</span><span class="nf">x08048f6e</span> <span class="err">&lt;+</span><span class="mi">878</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0x84</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%ebx</span> <span class="err">0</span><span class="nf">x08048f75</span> <span class="err">&lt;+</span><span class="mi">885</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">lea</span> <span class="p">(</span><span class="nv">%ebx</span><span class="p">,</span><span class="nv">%ecx</span><span class="p">,</span><span class="mi">1</span><span class="p">),</span><span class="nv">%ebx</span> <span class="err">0</span><span class="nf">x08048f78</span> <span class="err">&lt;+</span><span class="mi">888</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">movzbl</span> <span class="p">(</span><span class="nv">%ebx</span><span class="p">),</span><span class="nv">%ebx</span> <span class="err">0</span><span class="nf">x08048f7b</span> <span class="err">&lt;+</span><span class="mi">891</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%edx</span><span class="p">,</span><span class="nv">%ebp</span> <span class="err">0</span><span class="nf">x08048f7d</span> <span class="err">&lt;+</span><span class="mi">893</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">xor</span> <span class="nv">%ebx</span><span class="p">,</span><span class="nv">%ebp</span> <span class="err">0</span><span class="nf">x08048f7f</span> <span class="err">&lt;+</span><span class="mi">895</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">xchg</span> <span class="nv">%eax</span><span class="p">,</span><span class="nv">%ebp</span> <span class="err">0</span><span class="nf">x08048f80</span> <span class="err">&lt;+</span><span class="mi">896</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">movzbl</span> <span class="nv">%al</span><span class="p">,</span><span class="nv">%eax</span> <span class="err">0</span><span class="nf">x08048f83</span> <span class="err">&lt;+</span><span class="mi">899</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">xchg</span> <span class="nv">%eax</span><span class="p">,</span><span class="nv">%ebp</span> <span class="err">0</span><span class="nf">x08048f84</span> <span class="err">&lt;+</span><span class="mi">900</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">xor</span> <span class="nv">%ecx</span><span class="p">,</span><span class="nv">%ecx</span> <span class="err">0</span><span class="nf">x08048f86</span> <span class="err">&lt;+</span><span class="mi">902</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%ebp</span><span class="p">,(</span><span class="nv">%esp</span><span class="p">)</span> <span class="err">0</span><span class="nf">x08048f89</span> <span class="err">&lt;+</span><span class="mi">905</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%ecx</span><span class="p">,</span><span class="mi">0x4</span><span class="p">(</span><span class="nv">%esp</span><span class="p">)</span> <span class="err">0</span><span class="nf">x08048f8d</span> <span class="err">&lt;+</span><span class="mi">909</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">call</span> <span class="mh">0x806a6b0</span> <span class="p">&lt;</span><span class="no">runtime.intstring</span><span class="p">&gt;</span> <span class="err">0</span><span class="nf">x08048f92</span> <span class="err">&lt;+</span><span class="mi">914</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0x8</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%ebx</span> <span class="err">0</span><span class="nf">x08048f96</span> <span class="err">&lt;+</span><span class="mi">918</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%ebx</span><span class="p">,</span><span class="mi">0x74</span><span class="p">(</span><span class="nv">%esp</span><span class="p">)</span> <span class="err">0</span><span class="nf">x08048f9a</span> <span class="err">&lt;+</span><span class="mi">922</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0xc</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%ebx</span> <span class="err">0</span><span class="nf">x08048f9e</span> <span class="err">&lt;+</span><span class="mi">926</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%ebx</span><span class="p">,</span><span class="mi">0x78</span><span class="p">(</span><span class="nv">%esp</span><span class="p">)</span> <span class="err">0</span><span class="nf">x08048fa2</span> <span class="err">&lt;+</span><span class="mi">930</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">lea</span> <span class="mi">0x7c</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%edi</span> <span class="err">0</span><span class="nf">x08048fa6</span> <span class="err">&lt;+</span><span class="mi">934</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">xor</span> <span class="nv">%eax</span><span class="p">,</span><span class="nv">%eax</span> <span class="err">0</span><span class="nf">x08048fa8</span> <span class="err">&lt;+</span><span class="mi">936</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">stos</span> <span class="nv">%eax</span><span class="p">,</span><span class="nv">%es</span><span class="p">:(</span><span class="nv">%edi</span><span class="p">)</span> <span class="err">0</span><span class="nf">x08048fa9</span> <span class="err">&lt;+</span><span class="mi">937</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">stos</span> <span class="nv">%eax</span><span class="p">,</span><span class="nv">%es</span><span class="p">:(</span><span class="nv">%edi</span><span class="p">)</span> <span class="err">0</span><span class="nf">x08048faa</span> <span class="err">&lt;+</span><span class="mi">938</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">lea</span> <span class="mi">0x7c</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%ebx</span> <span class="err">0</span><span class="nf">x08048fae</span> <span class="err">&lt;+</span><span class="mi">942</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">cmp</span> <span class="no">$0x0</span><span class="p">,</span><span class="nv">%ebx</span> <span class="err">0</span><span class="nf">x08048fb1</span> <span class="err">&lt;+</span><span class="mi">945</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">je</span> <span class="mh">0x804902f</span> <span class="p">&lt;</span><span class="no">main.main</span><span class="p">+</span><span class="mi">1071</span><span class="p">&gt;</span> <span class="err">0</span><span class="nf">x08048fb3</span> <span class="err">&lt;+</span><span class="mi">947</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%ebx</span><span class="p">,</span><span class="mi">0xa8</span><span class="p">(</span><span class="nv">%esp</span><span class="p">)</span> <span class="err">0</span><span class="nf">x08048fba</span> <span class="err">&lt;+</span><span class="mi">954</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">movl</span> <span class="no">$0x1</span><span class="p">,</span><span class="mi">0xac</span><span class="p">(</span><span class="nv">%esp</span><span class="p">)</span> <span class="err">0</span><span class="nf">x08048fc5</span> <span class="err">&lt;+</span><span class="mi">965</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">movl</span> <span class="no">$0x1</span><span class="p">,</span><span class="mi">0xb0</span><span class="p">(</span><span class="nv">%esp</span><span class="p">)</span> <span class="err">0</span><span class="nf">x08048fd0</span> <span class="err">&lt;+</span><span class="mi">976</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">movl</span> <span class="no">$0x80cc440</span><span class="p">,(</span><span class="nv">%esp</span><span class="p">)</span> <span class="err">0</span><span class="nf">x08048fd7</span> <span class="err">&lt;+</span><span class="mi">983</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">lea</span> <span class="mi">0x74</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%ebx</span> <span class="err">0</span><span class="nf">x08048fdb</span> <span class="err">&lt;+</span><span class="mi">987</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%ebx</span><span class="p">,</span><span class="mi">0x4</span><span class="p">(</span><span class="nv">%esp</span><span class="p">)</span> <span class="err">0</span><span class="nf">x08048fdf</span> <span class="err">&lt;+</span><span class="mi">991</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">call</span> <span class="mh">0x8065ed0</span> <span class="p">&lt;</span><span class="no">runtime.convT2E</span><span class="p">&gt;</span> <span class="err">0</span><span class="nf">x08048fe4</span> <span class="err">&lt;+</span><span class="mi">996</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0xa8</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%edi</span> <span class="err">0</span><span class="nf">x08048feb</span> <span class="err">&lt;+</span><span class="mi">1003</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">lea</span> <span class="mi">0x8</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%ebx</span> <span class="err">0</span><span class="nf">x08048fef</span> <span class="err">&lt;+</span><span class="mi">1007</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%ebx</span><span class="p">,</span><span class="nv">%esi</span> <span class="err">0</span><span class="nf">x08048ff1</span> <span class="err">&lt;+</span><span class="mi">1009</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%edi</span><span class="p">,</span><span class="nv">%edx</span> <span class="err">0</span><span class="nf">x08048ff3</span> <span class="err">&lt;+</span><span class="mi">1011</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">cld</span> <span class="mi">0x08048ff4</span> <span class="err">&lt;+</span><span class="mi">1012</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">movsl</span> <span class="nv">%ds</span><span class="p">:(</span><span class="nv">%esi</span><span class="p">),</span><span class="nv">%es</span><span class="p">:(</span><span class="nv">%edi</span><span class="p">)</span> <span class="err">0</span><span class="nf">x08048ff5</span> <span class="err">&lt;+</span><span class="mi">1013</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">movsl</span> <span class="nv">%ds</span><span class="p">:(</span><span class="nv">%esi</span><span class="p">),</span><span class="nv">%es</span><span class="p">:(</span><span class="nv">%edi</span><span class="p">)</span> <span class="err">0</span><span class="nf">x08048ff6</span> <span class="err">&lt;+</span><span class="mi">1014</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%edx</span><span class="p">,(</span><span class="nv">%esp</span><span class="p">)</span> <span class="err">0</span><span class="nf">x08048ff9</span> <span class="err">&lt;+</span><span class="mi">1017</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0xac</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%ebx</span> <span class="err">0</span><span class="nf">x08049000</span> <span class="err">&lt;+</span><span class="mi">1024</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%ebx</span><span class="p">,</span><span class="mi">0x4</span><span class="p">(</span><span class="nv">%esp</span><span class="p">)</span> <span class="err">0</span><span class="nf">x08049004</span> <span class="err">&lt;+</span><span class="mi">1028</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0xb0</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%ebx</span> <span class="err">0</span><span class="nf">x0804900b</span> <span class="err">&lt;+</span><span class="mi">1035</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%ebx</span><span class="p">,</span><span class="mi">0x8</span><span class="p">(</span><span class="nv">%esp</span><span class="p">)</span> <span class="err">0</span><span class="nf">x0804900f</span> <span class="err">&lt;+</span><span class="mi">1039</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">call</span> <span class="mh">0x8071720</span> <span class="p">&lt;</span><span class="no">fmt.Print</span><span class="p">&gt;</span> <span class="err">=&gt;</span> <span class="err">0</span><span class="nf">x08049014</span> <span class="err">&lt;+</span><span class="mi">1044</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0x1c</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%ecx</span> <span class="err">0</span><span class="nf">x08049018</span> <span class="err">&lt;+</span><span class="mi">1048</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">inc</span> <span class="nv">%ecx</span> <span class="err">0</span><span class="nf">x08049019</span> <span class="err">&lt;+</span><span class="mi">1049</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0x88</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%ebp</span> <span class="err">0</span><span class="nf">x08049020</span> <span class="err">&lt;+</span><span class="mi">1056</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">cmp</span> <span class="nv">%ecx</span><span class="p">,</span><span class="nv">%ebp</span> <span class="err">0</span><span class="nf">x08049022</span> <span class="err">&lt;+</span><span class="mi">1058</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">jg</span> <span class="mh">0x8048f2a</span> <span class="p">&lt;</span><span class="no">main.main</span><span class="p">+</span><span class="mi">810</span><span class="p">&gt;</span> <span class="err">0</span><span class="nf">x08049028</span> <span class="err">&lt;+</span><span class="mi">1064</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">add</span> <span class="no">$0xc0</span><span class="p">,</span><span class="nv">%esp</span> <span class="err">0</span><span class="nf">x0804902e</span> <span class="err">&lt;+</span><span class="mi">1070</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">ret</span> <span class="mi">0x0804902f</span> <span class="err">&lt;+</span><span class="mi">1071</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%eax</span><span class="p">,(</span><span class="nv">%ebx</span><span class="p">)</span> <span class="err">0</span><span class="nf">x08049031</span> <span class="err">&lt;+</span><span class="mi">1073</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">jmp</span> <span class="mh">0x8048fb3</span> <span class="p">&lt;</span><span class="no">main.main</span><span class="p">+</span><span class="mi">947</span><span class="p">&gt;</span> <span class="err">0</span><span class="nf">x08049033</span> <span class="err">&lt;+</span><span class="mi">1075</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">call</span> <span class="mh">0x8055f40</span> <span class="p">&lt;</span><span class="no">runtime.panicindex</span><span class="p">&gt;</span> <span class="err">0</span><span class="nf">x08049038</span> <span class="err">&lt;+</span><span class="mi">1080</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">ud2</span> <span class="mi">0x0804903a</span> <span class="err">&lt;+</span><span class="mi">1082</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">call</span> <span class="mh">0x8055f40</span> <span class="p">&lt;</span><span class="no">runtime.panicindex</span><span class="p">&gt;</span> <span class="err">0</span><span class="nf">x0804903f</span> <span class="err">&lt;+</span><span class="mi">1087</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">ud2</span> <span class="mi">0x08049041</span> <span class="err">&lt;+</span><span class="mi">1089</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">xor</span> <span class="nv">%ebp</span><span class="p">,</span><span class="nv">%ebp</span> <span class="err">0</span><span class="nf">x08049043</span> <span class="err">&lt;+</span><span class="mi">1091</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">jmp</span> <span class="mh">0x8048f43</span> <span class="p">&lt;</span><span class="no">main.main</span><span class="p">+</span><span class="mi">835</span><span class="p">&gt;</span> <span class="err">0</span><span class="nf">x08049048</span> <span class="err">&lt;+</span><span class="mi">1096</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">movl</span> <span class="no">$0x80ca7c0</span><span class="p">,(</span><span class="nv">%esp</span><span class="p">)</span> <span class="err">0</span><span class="nf">x0804904f</span> <span class="err">&lt;+</span><span class="mi">1103</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">call</span> <span class="mh">0x80681a0</span> <span class="p">&lt;</span><span class="no">runtime.new</span><span class="p">&gt;</span> <span class="err">0</span><span class="nf">x08049054</span> <span class="err">&lt;+</span><span class="mi">1108</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0x4</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%ebx</span> <span class="nf">Quit</span> <span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> </pre></div> </td></tr></table> <p>De nuevo otro bucle, siguiendo la misma estrategia buscaremos el jump anterior a el bucle que nos sacaría de el, obviando el primero que nos lleva a un <code>ret</code>, el siguente es </p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1 2</pre></div></td><td class="code"><div class="highlight"><pre> <span class="err">0</span><span class="nf">x08048f11</span> <span class="err">&lt;+</span><span class="mi">785</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">cmp</span> <span class="nv">%ebp</span><span class="p">,</span><span class="nv">%esi</span> <span class="err">0</span><span class="nf">x08048f13</span> <span class="err">&lt;+</span><span class="mi">787</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">je</span> <span class="mh">0x8049048</span> <span class="p">&lt;</span><span class="no">main.main</span><span class="p">+</span><span class="mi">1096</span><span class="p">&gt;</span> </pre></div> </td></tr></table> <p>Vamos allá (no nos olvidemos del parámetro)</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1 2 3 4 5 6 7 8 9 10 11 12</pre></div></td><td class="code"><div class="highlight"><pre><span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> <span class="no">break</span> <span class="p">*</span><span class="mi">0x08048f11</span> <span class="nf">Breakpoint</span> <span class="mi">8</span> <span class="no">at</span> <span class="mi">0x8048f11</span> <span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> <span class="no">delete</span> <span class="mi">7</span> <span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> <span class="no">run</span> <span class="no">test</span> <span class="nf">The</span> <span class="no">program</span> <span class="no">being</span> <span class="no">debugged</span> <span class="no">has</span> <span class="no">been</span> <span class="no">started</span> <span class="no">already.</span> <span class="nf">Start</span> <span class="no">it</span> <span class="no">from</span> <span class="no">the</span> <span class="no">beginning</span><span class="err">?</span> <span class="p">(</span><span class="no">y</span> <span class="no">or</span> <span class="no">n</span><span class="p">)</span> <span class="no">y</span> <span class="nf">Starting</span> <span class="no">program</span><span class="p">:</span> <span class="err">/</span><span class="no">home</span><span class="err">/</span><span class="no">kenkeiras</span><span class="err">/</span><span class="no">ctf</span><span class="err">/</span><span class="mi">2014</span><span class="err">/</span><span class="no">ncn</span><span class="err">/</span><span class="no">quals</span><span class="err">/</span><span class="no">inbincible</span><span class="err">/</span><span class="no">inbincible</span> <span class="no">test</span> <span class="nf">Breakpoint</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">0x08048f11</span> <span class="no">in</span> <span class="no">main.main</span> <span class="p">()</span> <span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> <span class="no">x</span><span class="err">/</span><span class="no">i</span> <span class="no">$eip</span> <span class="err">=&gt;</span> <span class="err">0</span><span class="nf">x8048f11</span> <span class="err">&lt;</span><span class="no">main.main</span><span class="err">+</span><span class="mi">785</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">cmp</span> <span class="nv">%ebp</span><span class="p">,</span><span class="nv">%esi</span> <span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> </pre></div> </td></tr></table> <p>Los valores son...</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1 2 3 4 5</pre></div></td><td class="code"><div class="highlight"><pre><span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> <span class="no">print</span> <span class="no">$ebp</span> <span class="nf">$3</span> <span class="err">=</span> <span class="p">(</span><span class="no">void</span> <span class="p">*)</span> <span class="mi">0x10</span> <span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> <span class="no">print</span> <span class="no">$esi</span> <span class="nf">$4</span> <span class="err">=</span> <span class="mi">4</span> <span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> </pre></div> </td></tr></table> <p>Un 0x10 y un 4, y la comprobación anterior era el número de parámetros, y el que habíamos probado tiene 4 caracteres, ¿uno de 16 será la solución?</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1 2 3 4 5 6 7 8 9 10 11</pre></div></td><td class="code"><div class="highlight"><pre><span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> <span class="no">run</span> <span class="no">testtesttesttest</span> <span class="nf">The</span> <span class="no">program</span> <span class="no">being</span> <span class="no">debugged</span> <span class="no">has</span> <span class="no">been</span> <span class="no">started</span> <span class="no">already.</span> <span class="nf">Start</span> <span class="no">it</span> <span class="no">from</span> <span class="no">the</span> <span class="no">beginning</span><span class="err">?</span> <span class="p">(</span><span class="no">y</span> <span class="no">or</span> <span class="no">n</span><span class="p">)</span> <span class="no">y</span> <span class="nf">Starting</span> <span class="no">program</span><span class="p">:</span> <span class="err">/</span><span class="no">home</span><span class="err">/</span><span class="no">kenkeiras</span><span class="err">/</span><span class="no">ctf</span><span class="err">/</span><span class="mi">2014</span><span class="err">/</span><span class="no">ncn</span><span class="err">/</span><span class="no">quals</span><span class="err">/</span><span class="no">inbincible</span><span class="err">/</span><span class="no">inbincible</span> <span class="no">testtesttesttest</span> <span class="nf">Breakpoint</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">0x08048f11</span> <span class="no">in</span> <span class="no">main.main</span> <span class="p">()</span> <span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> <span class="no">print</span> <span class="no">$ebp</span> <span class="nf">$7</span> <span class="err">=</span> <span class="p">(</span><span class="no">void</span> <span class="p">*)</span> <span class="mi">0x10</span> <span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> <span class="no">print</span> <span class="no">$esi</span> <span class="nf">$8</span> <span class="err">=</span> <span class="mi">16</span> <span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> </pre></div> </td></tr></table> <p>Toma un parámetro de 16 caracteres, vale, repetimos</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28</pre></div></td><td class="code"><div class="highlight"><pre><span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> <span class="no">delete</span> <span class="mi">8</span> <span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> <span class="no">continue</span> <span class="nf">Continuing.</span> <span class="nf">Nope</span><span class="err">!</span> <span class="err">[</span><span class="nf">Inferior</span> <span class="mi">1</span> <span class="p">(</span><span class="no">process</span> <span class="mi">20465</span><span class="p">)</span> <span class="no">exited</span> <span class="no">normally</span><span class="err">]</span> <span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> <span class="no">break</span> <span class="no">fmt.Print</span> <span class="nf">Breakpoint</span> <span class="mi">9</span> <span class="no">at</span> <span class="mi">0x8071720</span> <span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> <span class="no">run</span> <span class="no">testtesttesttest</span> <span class="nf">Starting</span> <span class="no">program</span><span class="p">:</span> <span class="err">/</span><span class="no">home</span><span class="err">/</span><span class="no">kenkeiras</span><span class="err">/</span><span class="no">ctf</span><span class="err">/</span><span class="mi">2014</span><span class="err">/</span><span class="no">ncn</span><span class="err">/</span><span class="no">quals</span><span class="err">/</span><span class="no">inbincible</span><span class="err">/</span><span class="no">inbincible</span> <span class="no">testtesttesttest</span> <span class="err">[</span><span class="nf">New</span> <span class="no">LWP</span> <span class="mi">20722</span><span class="err">]</span> <span class="err">[</span><span class="nf">Switching</span> <span class="no">to</span> <span class="no">LWP</span> <span class="mi">20722</span><span class="err">]</span> <span class="nf">Breakpoint</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">0x08071720</span> <span class="no">in</span> <span class="no">fmt.Print</span> <span class="p">()</span> <span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> <span class="no">bt</span> <span class="c">#0 0x08071720 in fmt.Print ()</span> <span class="c">#1 0x0804935a in main.main ()</span> <span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> <span class="no">break</span> <span class="p">*</span><span class="mi">0x0804935a</span> <span class="nf">Breakpoint</span> <span class="mi">10</span> <span class="no">at</span> <span class="mi">0x804935a</span> <span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> <span class="no">delete</span> <span class="mi">9</span> <span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> <span class="no">run</span> <span class="no">testtesttesttest</span> <span class="nf">The</span> <span class="no">program</span> <span class="no">being</span> <span class="no">debugged</span> <span class="no">has</span> <span class="no">been</span> <span class="no">started</span> <span class="no">already.</span> <span class="nf">Start</span> <span class="no">it</span> <span class="no">from</span> <span class="no">the</span> <span class="no">beginning</span><span class="err">?</span> <span class="p">(</span><span class="no">y</span> <span class="no">or</span> <span class="no">n</span><span class="p">)</span> <span class="no">y</span> <span class="nf">Starting</span> <span class="no">program</span><span class="p">:</span> <span class="err">/</span><span class="no">home</span><span class="err">/</span><span class="no">kenkeiras</span><span class="err">/</span><span class="no">ctf</span><span class="err">/</span><span class="mi">2014</span><span class="err">/</span><span class="no">ncn</span><span class="err">/</span><span class="no">quals</span><span class="err">/</span><span class="no">inbincible</span><span class="err">/</span><span class="no">inbincible</span> <span class="no">testtesttesttest</span> <span class="nf">N</span><span class="err">[</span><span class="no">New</span> <span class="no">LWP</span> <span class="mi">20800</span><span class="err">]</span> <span class="err">[</span><span class="nf">Switching</span> <span class="no">to</span> <span class="no">LWP</span> <span class="mi">20800</span><span class="err">]</span> <span class="nf">Breakpoint</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">0x0804935a</span> <span class="no">in</span> <span class="no">main.main</span> <span class="p">()</span> <span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> </pre></div> </td></tr></table> <p><a href="https://en.wikipedia.org/wiki/Light-weight_process">¿LWP?, ¡threads!</a>, parece que la cosa se complica, pero busquemos la condición</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76</pre></div></td><td class="code"><div class="highlight"><pre> <span class="na">...</span> <span class="err">0</span><span class="nf">x0804924e</span> <span class="err">&lt;+</span><span class="mi">1614</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">call</span> <span class="mh">0x8055f40</span> <span class="p">&lt;</span><span class="no">runtime.panicindex</span><span class="p">&gt;</span> <span class="err">0</span><span class="nf">x08049253</span> <span class="err">&lt;+</span><span class="mi">1619</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">ud2</span> <span class="mi">0x08049255</span> <span class="err">&lt;+</span><span class="mi">1621</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">call</span> <span class="mh">0x8055f40</span> <span class="p">&lt;</span><span class="no">runtime.panicindex</span><span class="p">&gt;</span> <span class="err">0</span><span class="nf">x0804925a</span> <span class="err">&lt;+</span><span class="mi">1626</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">ud2</span> <span class="mi">0x0804925c</span> <span class="err">&lt;+</span><span class="mi">1628</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">xor</span> <span class="nv">%ebp</span><span class="p">,</span><span class="nv">%ebp</span> <span class="err">0</span><span class="nf">x0804925e</span> <span class="err">&lt;+</span><span class="mi">1630</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">jmp</span> <span class="mh">0x804915e</span> <span class="p">&lt;</span><span class="no">main.main</span><span class="p">+</span><span class="mi">1374</span><span class="p">&gt;</span> <span class="err">0</span><span class="nf">x08049263</span> <span class="err">&lt;+</span><span class="mi">1635</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">xor</span> <span class="nv">%ecx</span><span class="p">,</span><span class="nv">%ecx</span> <span class="err">0</span><span class="nf">x08049265</span> <span class="err">&lt;+</span><span class="mi">1637</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0x88</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%ebp</span> <span class="err">0</span><span class="nf">x0804926c</span> <span class="err">&lt;+</span><span class="mi">1644</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">cmp</span> <span class="nv">%ecx</span><span class="p">,</span><span class="nv">%ebp</span> <span class="err">0</span><span class="nf">x0804926e</span> <span class="err">&lt;+</span><span class="mi">1646</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">jle</span> <span class="mh">0x8049243</span> <span class="p">&lt;</span><span class="no">main.main</span><span class="p">+</span><span class="mi">1603</span><span class="p">&gt;</span> <span class="err">0</span><span class="nf">x08049270</span> <span class="err">&lt;+</span><span class="mi">1648</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%ecx</span><span class="p">,</span><span class="nv">%edx</span> <span class="err">0</span><span class="nf">x08049272</span> <span class="err">&lt;+</span><span class="mi">1650</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0xa0</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%ebx</span> <span class="err">0</span><span class="nf">x08049279</span> <span class="err">&lt;+</span><span class="mi">1657</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%ecx</span><span class="p">,</span><span class="nv">%eax</span> <span class="err">0</span><span class="nf">x0804927b</span> <span class="err">&lt;+</span><span class="mi">1659</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">cmp</span> <span class="no">$0xffffffff</span><span class="p">,</span><span class="nv">%ebx</span> <span class="err">0</span><span class="nf">x0804927e</span> <span class="err">&lt;+</span><span class="mi">1662</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">je</span> <span class="mh">0x8049376</span> <span class="p">&lt;</span><span class="no">main.main</span><span class="p">+</span><span class="mi">1910</span><span class="p">&gt;</span> <span class="err">0</span><span class="nf">x08049284</span> <span class="err">&lt;+</span><span class="mi">1668</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">cltd</span> <span class="mi">0x08049285</span> <span class="err">&lt;+</span><span class="mi">1669</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">idiv</span> <span class="nv">%ebx</span> <span class="err">0</span><span class="nf">x08049287</span> <span class="err">&lt;+</span><span class="mi">1671</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%edx</span><span class="p">,</span><span class="nv">%ebp</span> <span class="err">0</span><span class="nf">x08049289</span> <span class="err">&lt;+</span><span class="mi">1673</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">cmp</span> <span class="mi">0xa0</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%ebp</span> <span class="err">0</span><span class="nf">x08049290</span> <span class="err">&lt;+</span><span class="mi">1680</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">jae</span> <span class="mh">0x804936f</span> <span class="p">&lt;</span><span class="no">main.main</span><span class="p">+</span><span class="mi">1903</span><span class="p">&gt;</span> <span class="err">0</span><span class="nf">x08049296</span> <span class="err">&lt;+</span><span class="mi">1686</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0x9c</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%edx</span> <span class="err">0</span><span class="nf">x0804929d</span> <span class="err">&lt;+</span><span class="mi">1693</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">lea</span> <span class="p">(</span><span class="nv">%edx</span><span class="p">,</span><span class="nv">%ebp</span><span class="p">,</span><span class="mi">1</span><span class="p">),</span><span class="nv">%edx</span> <span class="err">0</span><span class="nf">x080492a0</span> <span class="err">&lt;+</span><span class="mi">1696</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">movzbl</span> <span class="p">(</span><span class="nv">%edx</span><span class="p">),</span><span class="nv">%edx</span> <span class="err">0</span><span class="nf">x080492a3</span> <span class="err">&lt;+</span><span class="mi">1699</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%ecx</span><span class="p">,</span><span class="mi">0x2c</span><span class="p">(</span><span class="nv">%esp</span><span class="p">)</span> <span class="err">0</span><span class="nf">x080492a7</span> <span class="err">&lt;+</span><span class="mi">1703</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">cmp</span> <span class="mi">0x88</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%ecx</span> <span class="err">0</span><span class="nf">x080492ae</span> <span class="err">&lt;+</span><span class="mi">1710</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">jae</span> <span class="mh">0x8049368</span> <span class="p">&lt;</span><span class="no">main.main</span><span class="p">+</span><span class="mi">1896</span><span class="p">&gt;</span> <span class="err">0</span><span class="nf">x080492b4</span> <span class="err">&lt;+</span><span class="mi">1716</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0x84</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%ebx</span> <span class="err">0</span><span class="nf">x080492bb</span> <span class="err">&lt;+</span><span class="mi">1723</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">lea</span> <span class="p">(</span><span class="nv">%ebx</span><span class="p">,</span><span class="nv">%ecx</span><span class="p">,</span><span class="mi">1</span><span class="p">),</span><span class="nv">%ebx</span> <span class="err">0</span><span class="nf">x080492be</span> <span class="err">&lt;+</span><span class="mi">1726</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">movzbl</span> <span class="p">(</span><span class="nv">%ebx</span><span class="p">),</span><span class="nv">%ebx</span> <span class="err">0</span><span class="nf">x080492c1</span> <span class="err">&lt;+</span><span class="mi">1729</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%edx</span><span class="p">,</span><span class="nv">%ebp</span> <span class="err">0</span><span class="nf">x080492c3</span> <span class="err">&lt;+</span><span class="mi">1731</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">xor</span> <span class="nv">%ebx</span><span class="p">,</span><span class="nv">%ebp</span> <span class="err">0</span><span class="nf">x080492c5</span> <span class="err">&lt;+</span><span class="mi">1733</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">xchg</span> <span class="nv">%eax</span><span class="p">,</span><span class="nv">%ebp</span> <span class="err">0</span><span class="nf">x080492c6</span> <span class="err">&lt;+</span><span class="mi">1734</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">movzbl</span> <span class="nv">%al</span><span class="p">,</span><span class="nv">%eax</span> <span class="err">0</span><span class="nf">x080492c9</span> <span class="err">&lt;+</span><span class="mi">1737</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">xchg</span> <span class="nv">%eax</span><span class="p">,</span><span class="nv">%ebp</span> <span class="err">0</span><span class="nf">x080492ca</span> <span class="err">&lt;+</span><span class="mi">1738</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">xor</span> <span class="nv">%ecx</span><span class="p">,</span><span class="nv">%ecx</span> <span class="err">0</span><span class="nf">x080492cc</span> <span class="err">&lt;+</span><span class="mi">1740</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%ebp</span><span class="p">,(</span><span class="nv">%esp</span><span class="p">)</span> <span class="err">0</span><span class="nf">x080492cf</span> <span class="err">&lt;+</span><span class="mi">1743</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%ecx</span><span class="p">,</span><span class="mi">0x4</span><span class="p">(</span><span class="nv">%esp</span><span class="p">)</span> <span class="err">0</span><span class="nf">x080492d3</span> <span class="err">&lt;+</span><span class="mi">1747</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">call</span> <span class="mh">0x806a6b0</span> <span class="p">&lt;</span><span class="no">runtime.intstring</span><span class="p">&gt;</span> <span class="err">0</span><span class="nf">x080492d8</span> <span class="err">&lt;+</span><span class="mi">1752</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0x8</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%ebx</span> <span class="err">0</span><span class="nf">x080492dc</span> <span class="err">&lt;+</span><span class="mi">1756</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%ebx</span><span class="p">,</span><span class="mi">0x74</span><span class="p">(</span><span class="nv">%esp</span><span class="p">)</span> <span class="err">0</span><span class="nf">x080492e0</span> <span class="err">&lt;+</span><span class="mi">1760</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0xc</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%ebx</span> <span class="err">0</span><span class="nf">x080492e4</span> <span class="err">&lt;+</span><span class="mi">1764</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%ebx</span><span class="p">,</span><span class="mi">0x78</span><span class="p">(</span><span class="nv">%esp</span><span class="p">)</span> <span class="err">0</span><span class="nf">x080492e8</span> <span class="err">&lt;+</span><span class="mi">1768</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">lea</span> <span class="mi">0x7c</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%edi</span> <span class="err">0</span><span class="nf">x080492ec</span> <span class="err">&lt;+</span><span class="mi">1772</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">xor</span> <span class="nv">%eax</span><span class="p">,</span><span class="nv">%eax</span> <span class="err">0</span><span class="nf">x080492ee</span> <span class="err">&lt;+</span><span class="mi">1774</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">stos</span> <span class="nv">%eax</span><span class="p">,</span><span class="nv">%es</span><span class="p">:(</span><span class="nv">%edi</span><span class="p">)</span> <span class="err">0</span><span class="nf">x080492ef</span> <span class="err">&lt;+</span><span class="mi">1775</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">stos</span> <span class="nv">%eax</span><span class="p">,</span><span class="nv">%es</span><span class="p">:(</span><span class="nv">%edi</span><span class="p">)</span> <span class="err">0</span><span class="nf">x080492f0</span> <span class="err">&lt;+</span><span class="mi">1776</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">lea</span> <span class="mi">0x7c</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%ebx</span> <span class="err">0</span><span class="nf">x080492f4</span> <span class="err">&lt;+</span><span class="mi">1780</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">cmp</span> <span class="no">$0x0</span><span class="p">,</span><span class="nv">%ebx</span> <span class="err">0</span><span class="nf">x080492f7</span> <span class="err">&lt;+</span><span class="mi">1783</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">je</span> <span class="mh">0x8049364</span> <span class="p">&lt;</span><span class="no">main.main</span><span class="p">+</span><span class="mi">1892</span><span class="p">&gt;</span> <span class="err">0</span><span class="nf">x080492f9</span> <span class="err">&lt;+</span><span class="mi">1785</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%ebx</span><span class="p">,</span><span class="mi">0xa8</span><span class="p">(</span><span class="nv">%esp</span><span class="p">)</span> <span class="err">0</span><span class="nf">x08049300</span> <span class="err">&lt;+</span><span class="mi">1792</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">movl</span> <span class="no">$0x1</span><span class="p">,</span><span class="mi">0xac</span><span class="p">(</span><span class="nv">%esp</span><span class="p">)</span> <span class="err">0</span><span class="nf">x0804930b</span> <span class="err">&lt;+</span><span class="mi">1803</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">movl</span> <span class="no">$0x1</span><span class="p">,</span><span class="mi">0xb0</span><span class="p">(</span><span class="nv">%esp</span><span class="p">)</span> <span class="err">0</span><span class="nf">x08049316</span> <span class="err">&lt;+</span><span class="mi">1814</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">movl</span> <span class="no">$0x80cc440</span><span class="p">,(</span><span class="nv">%esp</span><span class="p">)</span> <span class="err">0</span><span class="nf">x0804931d</span> <span class="err">&lt;+</span><span class="mi">1821</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">lea</span> <span class="mi">0x74</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%ebx</span> <span class="err">0</span><span class="nf">x08049321</span> <span class="err">&lt;+</span><span class="mi">1825</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%ebx</span><span class="p">,</span><span class="mi">0x4</span><span class="p">(</span><span class="nv">%esp</span><span class="p">)</span> <span class="err">0</span><span class="nf">x08049325</span> <span class="err">&lt;+</span><span class="mi">1829</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">call</span> <span class="mh">0x8065ed0</span> <span class="p">&lt;</span><span class="no">runtime.convT2E</span><span class="p">&gt;</span> <span class="err">0</span><span class="nf">x0804932a</span> <span class="err">&lt;+</span><span class="mi">1834</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0xa8</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%edi</span> <span class="err">0</span><span class="nf">x08049331</span> <span class="err">&lt;+</span><span class="mi">1841</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">lea</span> <span class="mi">0x8</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%ebx</span> <span class="err">0</span><span class="nf">x08049335</span> <span class="err">&lt;+</span><span class="mi">1845</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%ebx</span><span class="p">,</span><span class="nv">%esi</span> <span class="err">0</span><span class="nf">x08049337</span> <span class="err">&lt;+</span><span class="mi">1847</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%edi</span><span class="p">,</span><span class="nv">%edx</span> <span class="err">0</span><span class="nf">x08049339</span> <span class="err">&lt;+</span><span class="mi">1849</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">cld</span> <span class="mi">0x0804933a</span> <span class="err">&lt;+</span><span class="mi">1850</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">movsl</span> <span class="nv">%ds</span><span class="p">:(</span><span class="nv">%esi</span><span class="p">),</span><span class="nv">%es</span><span class="p">:(</span><span class="nv">%edi</span><span class="p">)</span> <span class="err">0</span><span class="nf">x0804933b</span> <span class="err">&lt;+</span><span class="mi">1851</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">movsl</span> <span class="nv">%ds</span><span class="p">:(</span><span class="nv">%esi</span><span class="p">),</span><span class="nv">%es</span><span class="p">:(</span><span class="nv">%edi</span><span class="p">)</span> <span class="err">0</span><span class="nf">x0804933c</span> <span class="err">&lt;+</span><span class="mi">1852</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%edx</span><span class="p">,(</span><span class="nv">%esp</span><span class="p">)</span> <span class="err">0</span><span class="nf">x0804933f</span> <span class="err">&lt;+</span><span class="mi">1855</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0xac</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%ebx</span> <span class="err">0</span><span class="nf">x08049346</span> <span class="err">&lt;+</span><span class="mi">1862</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%ebx</span><span class="p">,</span><span class="mi">0x4</span><span class="p">(</span><span class="nv">%esp</span><span class="p">)</span> <span class="err">0</span><span class="nf">x0804934a</span> <span class="err">&lt;+</span><span class="mi">1866</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0xb0</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%ebx</span> <span class="err">0</span><span class="nf">x08049351</span> <span class="err">&lt;+</span><span class="mi">1873</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%ebx</span><span class="p">,</span><span class="mi">0x8</span><span class="p">(</span><span class="nv">%esp</span><span class="p">)</span> <span class="err">0</span><span class="nf">x08049355</span> <span class="err">&lt;+</span><span class="mi">1877</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">call</span> <span class="mh">0x8071720</span> <span class="p">&lt;</span><span class="no">fmt.Print</span><span class="p">&gt;</span> <span class="err">=&gt;</span> <span class="err">0</span><span class="nf">x0804935a</span> <span class="err">&lt;+</span><span class="mi">1882</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0x2c</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%ecx</span> <span class="err">0</span><span class="nf">x0804935e</span> <span class="err">&lt;+</span><span class="mi">1886</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">inc</span> <span class="nv">%ecx</span> <span class="err">0</span><span class="nf">x0804935f</span> <span class="err">&lt;+</span><span class="mi">1887</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">jmp</span> <span class="mh">0x8049265</span> <span class="p">&lt;</span><span class="no">main.main</span><span class="p">+</span><span class="mi">1637</span><span class="p">&gt;</span> <span class="err">---</span><span class="nf">Type</span> <span class="err">&lt;</span><span class="no">return</span><span class="err">&gt;</span> <span class="no">to</span> <span class="no">continue</span><span class="p">,</span> <span class="no">or</span> <span class="mh">q</span> <span class="p">&lt;</span><span class="no">return</span><span class="p">&gt;</span> <span class="no">to</span> <span class="no">quit---q</span> <span class="nf">Quit</span> <span class="err">(</span><span class="nf">gdb</span><span class="p">)</span> </pre></div> </td></tr></table> <p>El bucle llega hasta <strong>+1637</strong>, pero hay algun jump incondicional y alguna llamada nada prometedora a <code>&lt;runtime.panicindex&gt;</code>, así que esta vez habrá que buscar el jump que nos lleva aquí (por lo menos hasta <strong>+1635</strong>) y negarlo, en vez de al revés.</p> <p>Podemos encontrarlo en <strong>+1326</strong> </p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1 2</pre></div></td><td class="code"><div class="highlight"><pre> <span class="err">0</span><span class="nf">x0804912b</span> <span class="err">&lt;+</span><span class="mi">1323</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">cmp</span> <span class="no">$0x0</span><span class="p">,</span><span class="nv">%cl</span> <span class="err">0</span><span class="nf">x0804912e</span> <span class="err">&lt;+</span><span class="mi">1326</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">je</span> <span class="mh">0x8049263</span> <span class="p">&lt;</span><span class="no">main.main</span><span class="p">+</span><span class="mi">1635</span><span class="p">&gt;</span> </pre></div> </td></tr></table> <p>Ahí encontramos el bucle que nos interesa</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64</pre></div></td><td class="code"><div class="highlight"><pre> <span class="na">...</span> <span class="err">0</span><span class="nf">x08049084</span> <span class="err">&lt;+</span><span class="mi">1156</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0x6c</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%ebx</span> <span class="err">0</span><span class="nf">x08049088</span> <span class="err">&lt;+</span><span class="mi">1160</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0x4</span><span class="p">(</span><span class="nv">%ebx</span><span class="p">),</span><span class="nv">%ebp</span> <span class="err">0</span><span class="nf">x0804908b</span> <span class="err">&lt;+</span><span class="mi">1163</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%esi</span><span class="p">,</span><span class="mi">0x24</span><span class="p">(</span><span class="nv">%esp</span><span class="p">)</span> <span class="err">0</span><span class="nf">x0804908f</span> <span class="err">&lt;+</span><span class="mi">1167</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">cmp</span> <span class="nv">%esi</span><span class="p">,</span><span class="nv">%ebp</span> <span class="err">0</span><span class="nf">x08049091</span> <span class="err">&lt;+</span><span class="mi">1169</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">jle</span> <span class="mh">0x80490d6</span> <span class="p">&lt;</span><span class="no">main.main</span><span class="p">+</span><span class="mi">1238</span><span class="p">&gt;</span> <span class="err">0</span><span class="nf">x08049093</span> <span class="err">&lt;+</span><span class="mi">1171</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">movl</span> <span class="no">$0x80dfa60</span><span class="p">,(</span><span class="nv">%esp</span><span class="p">)</span> <span class="err">0</span><span class="nf">x0804909a</span> <span class="err">&lt;+</span><span class="mi">1178</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">call</span> <span class="mh">0x80681a0</span> <span class="p">&lt;</span><span class="no">runtime.new</span><span class="p">&gt;</span> <span class="err">0</span><span class="nf">x0804909f</span> <span class="err">&lt;+</span><span class="mi">1183</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0x4</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%eax</span> <span class="err">0</span><span class="nf">x080490a3</span> <span class="err">&lt;+</span><span class="mi">1187</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">movl</span> <span class="no">$0x80493c0</span><span class="p">,(</span><span class="nv">%eax</span><span class="p">)</span> <span class="err">0</span><span class="nf">x080490a9</span> <span class="err">&lt;+</span><span class="mi">1193</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0x68</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%edx</span> <span class="err">0</span><span class="nf">x080490ad</span> <span class="err">&lt;+</span><span class="mi">1197</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%edx</span><span class="p">,</span><span class="mi">0x4</span><span class="p">(</span><span class="nv">%eax</span><span class="p">)</span> <span class="err">0</span><span class="nf">x080490b0</span> <span class="err">&lt;+</span><span class="mi">1200</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0x6c</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%edx</span> <span class="err">0</span><span class="nf">x080490b4</span> <span class="err">&lt;+</span><span class="mi">1204</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%edx</span><span class="p">,</span><span class="mi">0x8</span><span class="p">(</span><span class="nv">%eax</span><span class="p">)</span> <span class="err">0</span><span class="nf">x080490b7</span> <span class="err">&lt;+</span><span class="mi">1207</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0x70</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%edx</span> <span class="err">0</span><span class="nf">x080490bb</span> <span class="err">&lt;+</span><span class="mi">1211</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%edx</span><span class="p">,</span><span class="mi">0xc</span><span class="p">(</span><span class="nv">%eax</span><span class="p">)</span> <span class="err">0</span><span class="nf">x080490be</span> <span class="err">&lt;+</span><span class="mi">1214</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0x24</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%ebx</span> <span class="err">0</span><span class="nf">x080490c2</span> <span class="err">&lt;+</span><span class="mi">1218</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%ebx</span><span class="p">,(</span><span class="nv">%esp</span><span class="p">)</span> <span class="err">0</span><span class="nf">x080490c5</span> <span class="err">&lt;+</span><span class="mi">1221</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">push</span> <span class="nv">%eax</span> <span class="err">0</span><span class="nf">x080490c6</span> <span class="err">&lt;+</span><span class="mi">1222</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">push</span> <span class="no">$0x4</span> <span class="err">0</span><span class="nf">x080490c5</span> <span class="err">&lt;+</span><span class="mi">1221</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">push</span> <span class="nv">%eax</span> <span class="err">0</span><span class="nf">x080490c6</span> <span class="err">&lt;+</span><span class="mi">1222</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">push</span> <span class="no">$0x4</span> <span class="err">0</span><span class="nf">x080490c8</span> <span class="err">&lt;+</span><span class="mi">1224</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">call</span> <span class="mh">0x805acf0</span> <span class="p">&lt;</span><span class="no">runtime.newproc</span><span class="p">&gt;</span> <span class="err">0</span><span class="nf">x080490cd</span> <span class="err">&lt;+</span><span class="mi">1229</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">pop</span> <span class="nv">%ecx</span> <span class="err">0</span><span class="nf">x080490ce</span> <span class="err">&lt;+</span><span class="mi">1230</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">pop</span> <span class="nv">%ecx</span> <span class="err">0</span><span class="nf">x080490cf</span> <span class="err">&lt;+</span><span class="mi">1231</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0x24</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%esi</span> <span class="err">0</span><span class="nf">x080490d3</span> <span class="err">&lt;+</span><span class="mi">1235</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">inc</span> <span class="nv">%esi</span> <span class="err">0</span><span class="nf">x080490d4</span> <span class="err">&lt;+</span><span class="mi">1236</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">jmp</span> <span class="mh">0x8049084</span> <span class="p">&lt;</span><span class="no">main.main</span><span class="p">+</span><span class="mi">1156</span><span class="p">&gt;</span> <span class="err">0</span><span class="nf">x080490d6</span> <span class="err">&lt;+</span><span class="mi">1238</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="no">$0x1</span><span class="p">,</span><span class="nv">%ecx</span> <span class="err">0</span><span class="nf">x080490db</span> <span class="err">&lt;+</span><span class="mi">1243</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">xor</span> <span class="nv">%edi</span><span class="p">,</span><span class="nv">%edi</span> <span class="err">0</span><span class="nf">x080490dd</span> <span class="err">&lt;+</span><span class="mi">1245</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0x6c</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%ebx</span> <span class="err">0</span><span class="nf">x080490e1</span> <span class="err">&lt;+</span><span class="mi">1249</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0x4</span><span class="p">(</span><span class="nv">%ebx</span><span class="p">),</span><span class="nv">%ebp</span> <span class="err">0</span><span class="nf">x080490e4</span> <span class="err">&lt;+</span><span class="mi">1252</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%edi</span><span class="p">,</span><span class="mi">0x20</span><span class="p">(</span><span class="nv">%esp</span><span class="p">)</span> <span class="err">0</span><span class="nf">x080490e8</span> <span class="err">&lt;+</span><span class="mi">1256</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">cmp</span> <span class="nv">%edi</span><span class="p">,</span><span class="nv">%ebp</span> <span class="err">0</span><span class="nf">x080490ea</span> <span class="err">&lt;+</span><span class="mi">1258</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">jle</span> <span class="mh">0x804912b</span> <span class="p">&lt;</span><span class="no">main.main</span><span class="p">+</span><span class="mi">1323</span><span class="p">&gt;</span> <span class="err">0</span><span class="nf">x080490ec</span> <span class="err">&lt;+</span><span class="mi">1260</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">cmp</span> <span class="no">$0x0</span><span class="p">,</span><span class="nv">%cl</span> <span class="err">0</span><span class="nf">x080490ef</span> <span class="err">&lt;+</span><span class="mi">1263</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">je</span> <span class="mh">0x8049127</span> <span class="p">&lt;</span><span class="no">main.main</span><span class="p">+</span><span class="mi">1319</span><span class="p">&gt;</span> <span class="err">0</span><span class="nf">x080490f1</span> <span class="err">&lt;+</span><span class="mi">1265</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">movb</span> <span class="no">$0x0</span><span class="p">,</span><span class="mi">0x1b</span><span class="p">(</span><span class="nv">%esp</span><span class="p">)</span> <span class="err">0</span><span class="nf">x080490f6</span> <span class="err">&lt;+</span><span class="mi">1270</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">movl</span> <span class="no">$0x80ca7c0</span><span class="p">,(</span><span class="nv">%esp</span><span class="p">)</span> <span class="err">0</span><span class="nf">x080490fd</span> <span class="err">&lt;+</span><span class="mi">1277</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0x68</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%ebx</span> <span class="err">0</span><span class="nf">x08049101</span> <span class="err">&lt;+</span><span class="mi">1281</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="p">(</span><span class="nv">%ebx</span><span class="p">),</span><span class="nv">%ebp</span> <span class="err">0</span><span class="nf">x08049103</span> <span class="err">&lt;+</span><span class="mi">1283</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%ebp</span><span class="p">,</span><span class="mi">0x4</span><span class="p">(</span><span class="nv">%esp</span><span class="p">)</span> <span class="err">0</span><span class="nf">x08049107</span> <span class="err">&lt;+</span><span class="mi">1287</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">lea</span> <span class="mi">0x1b</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%ebx</span> <span class="err">0</span><span class="nf">x0804910b</span> <span class="err">&lt;+</span><span class="mi">1291</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%ebx</span><span class="p">,</span><span class="mi">0x8</span><span class="p">(</span><span class="nv">%esp</span><span class="p">)</span> <span class="err">0</span><span class="nf">x0804910f</span> <span class="err">&lt;+</span><span class="mi">1295</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">call</span> <span class="mh">0x8063620</span> <span class="p">&lt;</span><span class="no">runtime.chanrecv1</span><span class="p">&gt;</span> <span class="err">0</span><span class="nf">x08049114</span> <span class="err">&lt;+</span><span class="mi">1300</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0x20</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%edi</span> <span class="err">0</span><span class="nf">x08049118</span> <span class="err">&lt;+</span><span class="mi">1304</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">cmpb</span> <span class="no">$0x0</span><span class="p">,</span><span class="mi">0x1b</span><span class="p">(</span><span class="nv">%esp</span><span class="p">)</span> <span class="err">0</span><span class="nf">x0804911d</span> <span class="err">&lt;+</span><span class="mi">1309</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">je</span> <span class="mh">0x8049127</span> <span class="p">&lt;</span><span class="no">main.main</span><span class="p">+</span><span class="mi">1319</span><span class="p">&gt;</span> <span class="err">0</span><span class="nf">x0804911f</span> <span class="err">&lt;+</span><span class="mi">1311</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="no">$0x1</span><span class="p">,</span><span class="nv">%ecx</span> <span class="err">0</span><span class="nf">x08049124</span> <span class="err">&lt;+</span><span class="mi">1316</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">inc</span> <span class="nv">%edi</span> <span class="err">0</span><span class="nf">x08049125</span> <span class="err">&lt;+</span><span class="mi">1317</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">jmp</span> <span class="mh">0x80490dd</span> <span class="p">&lt;</span><span class="no">main.main</span><span class="p">+</span><span class="mi">1245</span><span class="p">&gt;</span> <span class="err">0</span><span class="nf">x08049127</span> <span class="err">&lt;+</span><span class="mi">1319</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">xor</span> <span class="nv">%ecx</span><span class="p">,</span><span class="nv">%ecx</span> <span class="err">0</span><span class="nf">x08049129</span> <span class="err">&lt;+</span><span class="mi">1321</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">jmp</span> <span class="mh">0x8049124</span> <span class="p">&lt;</span><span class="no">main.main</span><span class="p">+</span><span class="mi">1316</span><span class="p">&gt;</span> <span class="err">--</span> <span class="err">0</span><span class="nf">x0804912b</span> <span class="err">&lt;+</span><span class="mi">1323</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">cmp</span> <span class="no">$0x0</span><span class="p">,</span><span class="nv">%cl</span> <span class="err">0</span><span class="nf">x0804912e</span> <span class="err">&lt;+</span><span class="mi">1326</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">je</span> <span class="mh">0x8049263</span> <span class="p">&lt;</span><span class="no">main.main</span><span class="p">+</span><span class="mi">1635</span><span class="p">&gt;</span> <span class="err">0</span><span class="nf">x08049134</span> <span class="err">&lt;+</span><span class="mi">1332</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">xor</span> <span class="nv">%ecx</span><span class="p">,</span><span class="nv">%ecx</span> <span class="err">0</span><span class="nf">x08049136</span> <span class="err">&lt;+</span><span class="mi">1334</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0x94</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%ebp</span> <span class="err">0</span><span class="nf">x0804913d</span> <span class="err">&lt;+</span><span class="mi">1341</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">cmp</span> <span class="nv">%ecx</span><span class="p">,</span><span class="nv">%ebp</span> <span class="err">0</span><span class="nf">x0804913f</span> <span class="err">&lt;+</span><span class="mi">1343</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">jle</span> <span class="mh">0x8049243</span> <span class="p">&lt;</span><span class="no">main.main</span><span class="p">+</span><span class="mi">1603</span><span class="p">&gt;</span> <span class="err">0</span><span class="nf">x08049145</span> <span class="err">&lt;+</span><span class="mi">1349</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%ecx</span><span class="p">,</span><span class="nv">%edx</span> <span class="err">0</span><span class="nf">x08049147</span> <span class="err">&lt;+</span><span class="mi">1351</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0xa0</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%ebx</span> <span class="err">0</span><span class="nf">x0804914e</span> <span class="err">&lt;+</span><span class="mi">1358</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="nv">%ecx</span><span class="p">,</span><span class="nv">%eax</span> <span class="err">0</span><span class="nf">x08049150</span> <span class="err">&lt;+</span><span class="mi">1360</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">cmp</span> <span class="no">$0xffffffff</span><span class="p">,</span><span class="nv">%ebx</span> <span class="err">0</span><span class="nf">x08049153</span> <span class="err">&lt;+</span><span class="mi">1363</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">je</span> <span class="mh">0x804925c</span> <span class="p">&lt;</span><span class="no">main.main</span><span class="p">+</span><span class="mi">1628</span><span class="p">&gt;</span> </pre></div> </td></tr></table> <p>La línea indicada es la de la comparación, parece que tenemos que mantener <code>%cl</code> a algo que no sea 0.</p> <p>A ese bucle se llega a través del salto a <strong>+1238</strong> que se puede ver al principio del listado, esa instrucción es</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1</pre></div></td><td class="code"><div class="highlight"><pre> <span class="err">0</span><span class="nf">x080490d6</span> <span class="err">&lt;+</span><span class="mi">1238</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="no">$0x1</span><span class="p">,</span><span class="nv">%ecx</span> </pre></div> </td></tr></table> <p>Así que al principio <code>%ecx</code> es 1, alguna instrucción lo pone a 0, una es </p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1 2</pre></div></td><td class="code"><div class="highlight"><pre> <span class="err">0</span><span class="nf">x08049127</span> <span class="err">&lt;+</span><span class="mi">1319</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">xor</span> <span class="nv">%ecx</span><span class="p">,</span><span class="nv">%ecx</span> <span class="err">0</span><span class="nf">x08049129</span> <span class="err">&lt;+</span><span class="mi">1321</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">jmp</span> <span class="mh">0x8049124</span> <span class="p">&lt;</span><span class="no">main.main</span><span class="p">+</span><span class="mi">1316</span><span class="p">&gt;</span> </pre></div> </td></tr></table> <p>Y llega ahí desde </p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1 2 3 4</pre></div></td><td class="code"><div class="highlight"><pre> <span class="err">0</span><span class="nf">x0804910f</span> <span class="err">&lt;+</span><span class="mi">1295</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">call</span> <span class="mh">0x8063620</span> <span class="p">&lt;</span><span class="no">runtime.chanrecv1</span><span class="p">&gt;</span> <span class="err">0</span><span class="nf">x08049114</span> <span class="err">&lt;+</span><span class="mi">1300</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">mov</span> <span class="mi">0x20</span><span class="p">(</span><span class="nv">%esp</span><span class="p">),</span><span class="nv">%edi</span> <span class="err">0</span><span class="nf">x08049118</span> <span class="err">&lt;+</span><span class="mi">1304</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">cmpb</span> <span class="no">$0x0</span><span class="p">,</span><span class="mi">0x1b</span><span class="p">(</span><span class="nv">%esp</span><span class="p">)</span> <span class="err">0</span><span class="nf">x0804911d</span> <span class="err">&lt;+</span><span class="mi">1309</span><span class="err">&gt;</span><span class="p">:</span> <span class="no">je</span> <span class="mh">0x8049127</span> <span class="p">&lt;</span><span class="no">main.main</span><span class="p">+</span><span class="mi">1319</span><span class="p">&gt;</span> </pre></div> </td></tr></table> <h4><a name="python" class="anchor">La trama se complica</a></h4> <p>El salto es dependiente de lo que parece el resultado de lo que se recibe por un canal que se deja en 0x1b(%esp), y yo lo siento, no se debuggear hilos que se interconectan y cosas así :(</p> <p>Pero hagamos un último esfuerzo, eso es un bucle, con un poco de suerte hará una pasada por cada letra... con un poco de suerte dirá si cada letra es correcta o no y podamos ir resolviendolo haciendo fuerza bruta letra a letra, algo que es bastante más asequible que atacar 16 (256**16 posibilidades en el peor de los casos). </p> <p>¿O no suena mejor buscar uno entre <strong>4096</strong> que uno entre <strong>340282366920938463463374607431768211456</strong>?</p> <p>Por suerte gdb se puede automatizar facilmente, por ejemplo, si ponemos esto en un archivo</p> <div class="highlight"><pre><span class="x">break *0x08049118</span> <span class="x">run testtesttesttest</span> <span class="x">x/1c (</span><span class="p">$</span><span class="nv">esp</span><span class="x">) + 0x1b</span> </pre></div> <p>Y le decimos a gdb que lo ejecute...</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1 2 3 4 5 6 7 8</pre></div></td><td class="code"><div class="highlight"><pre><span class="nv">$ </span>gdb -batch -x man ./inbincible Breakpoint <span class="m">1</span> at 0x8049118 <span class="o">[</span>New LWP 30150<span class="o">]</span> <span class="o">[</span>Switching to LWP 30150<span class="o">]</span> Breakpoint 1, 0x08049118 in main.main <span class="o">()</span> 0xf7edeef3: <span class="m">0</span> <span class="s1">&#39;\000&#39;</span> <span class="err">$</span> </pre></div> </td></tr></table> <p>Tachán! podemos ver que pasa en la memoria del programa, veamos si podemos scriptearlo para que pruebe todas las letras, primero tenemos que generar los archivos de control para cada password y añadiremos unos cuantos “continues” para que siga después del primer resultado</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1 2 3 4 5 6 7 8 9 10 11 12 13</pre></div></td><td class="code"><div class="highlight"><pre><span class="n">CONTROLLER_NAME</span> <span class="o">=</span> <span class="s">&#39;manipulator&#39;</span> <span class="k">def</span> <span class="nf">gen_ctrl</span><span class="p">(</span><span class="n">passwd</span><span class="p">):</span> <span class="n">f</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">CONTROLLER_NAME</span><span class="p">,</span> <span class="s">&#39;w&#39;</span><span class="p">)</span> <span class="c"># Breakpoint</span> <span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">&quot;break *0x08049118</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">)</span> <span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">&quot;run </span><span class="si">%s</span><span class="se">\n</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">passwd</span><span class="p">)</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">xrange</span><span class="p">(</span><span class="mi">128</span><span class="p">):</span> <span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">&quot;x/1c ($esp) + 0x1b</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">)</span> <span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">&quot;continue</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">)</span> <span class="n">f</span><span class="o">.</span><span class="n">close</span><span class="p">()</span> </pre></div> </td></tr></table> <p>Lo siguiente será lanzar el gdb, ya aprovechamos que estamos en python para hacer el tratamiento que haga falta</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26</pre></div></td><td class="code"><div class="highlight"><pre><span class="n">PROGNAME</span> <span class="o">=</span> <span class="s">&#39;inbincible&#39;</span> <span class="kn">import</span> <span class="nn">subprocess</span> <span class="k">def</span> <span class="nf">test</span><span class="p">(</span><span class="n">passwd</span><span class="p">):</span> <span class="c"># Generamos el archivo de control</span> <span class="n">gen_ctrl</span><span class="p">(</span><span class="n">passwd</span><span class="p">)</span> <span class="c"># Lanzamos el gdb y tomamos control de su stdout y stderr</span> <span class="n">p</span> <span class="o">=</span> <span class="n">subprocess</span><span class="o">.</span><span class="n">Popen</span><span class="p">([</span><span class="s">&quot;gdb&quot;</span><span class="p">,</span> <span class="n">PROGNAME</span><span class="p">,</span> <span class="s">&#39;-batch&#39;</span><span class="p">,</span> <span class="s">&#39;-x&#39;</span><span class="p">,</span> <span class="n">CONTROLLER_NAME</span><span class="p">],</span> <span class="n">stdout</span><span class="o">=</span><span class="n">subprocess</span><span class="o">.</span><span class="n">PIPE</span><span class="p">,</span> <span class="n">stderr</span><span class="o">=</span><span class="n">subprocess</span><span class="o">.</span><span class="n">PIPE</span><span class="p">)</span> <span class="k">print</span> <span class="n">passwd</span> <span class="c"># Buscaremos en el stdout las líneas con el dump de la memoria</span> <span class="c"># que son las que siguen al aviso de que se llegó a un breakpoint</span> <span class="n">o</span> <span class="o">=</span> <span class="n">p</span><span class="o">.</span><span class="n">stdout</span><span class="o">.</span><span class="n">read</span><span class="p">()</span> <span class="n">nxt</span> <span class="o">=</span> <span class="bp">False</span> <span class="k">for</span> <span class="n">l</span> <span class="ow">in</span> <span class="n">o</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">&#39;</span><span class="se">\n</span><span class="s">&#39;</span><span class="p">):</span> <span class="k">if</span> <span class="n">nxt</span><span class="p">:</span> <span class="k">print</span> <span class="n">l</span> <span class="n">nxt</span> <span class="o">=</span> <span class="bp">False</span> <span class="k">if</span> <span class="s">&#39;Breakpoint 1, 0x08049118 in main.main ()&#39;</span> <span class="ow">in</span> <span class="n">l</span><span class="p">:</span> <span class="n">nxt</span> <span class="o">=</span> <span class="bp">True</span> </pre></div> </td></tr></table> <p>Bien, eso debería mostrar las líneas con la información que nos interesa por ahora veamos que tal va y ya parsearemos y tal luego</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1 2 3 4 5</pre></div></td><td class="code"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">string</span> <span class="n">CHARS</span> <span class="o">=</span> <span class="n">string</span><span class="o">.</span><span class="n">printable</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span> <span class="k">for</span> <span class="n">c</span> <span class="ow">in</span> <span class="n">CHARS</span><span class="p">:</span> <span class="n">test</span><span class="p">(</span><span class="n">c</span> <span class="o">*</span> <span class="mi">16</span><span class="p">)</span> </pre></div> </td></tr></table> <p>A ver, ¿algo dará 1 o toca debuggear hilos?</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106</pre></div></td><td class="code"><div class="highlight"><pre><span class="nv">$ </span>python test.py aaaaaaaaaaaaaaaa 0xf7edeef3: <span class="m">0</span> <span class="s1">&#39;\000&#39;</span> bbbbbbbbbbbbbbbb 0xf7edeef3: <span class="m">0</span> <span class="s1">&#39;\000&#39;</span> cccccccccccccccc 0xf7edeef3: <span class="m">0</span> <span class="s1">&#39;\000&#39;</span> dddddddddddddddd 0xf7edeef3: <span class="m">0</span> <span class="s1">&#39;\000&#39;</span> eeeeeeeeeeeeeeee 0xf7edeef3: <span class="m">0</span> <span class="s1">&#39;\000&#39;</span> ffffffffffffffff 0xf7edeef3: <span class="m">0</span> <span class="s1">&#39;\000&#39;</span> gggggggggggggggg 0xf7edeef3: <span class="m">0</span> <span class="s1">&#39;\000&#39;</span> hhhhhhhhhhhhhhhh 0xf7edeef3: <span class="m">0</span> <span class="s1">&#39;\000&#39;</span> iiiiiiiiiiiiiiii 0xf7edeef3: <span class="m">0</span> <span class="s1">&#39;\000&#39;</span> jjjjjjjjjjjjjjjj 0xf7edeef3: <span class="m">0</span> <span class="s1">&#39;\000&#39;</span> kkkkkkkkkkkkkkkk 0xf7edeef3: <span class="m">0</span> <span class="s1">&#39;\000&#39;</span> llllllllllllllll 0xf7edeef3: <span class="m">0</span> <span class="s1">&#39;\000&#39;</span> mmmmmmmmmmmmmmmm 0xf7edeef3: <span class="m">0</span> <span class="s1">&#39;\000&#39;</span> nnnnnnnnnnnnnnnn 0xf7edeef3: <span class="m">0</span> <span class="s1">&#39;\000&#39;</span> oooooooooooooooo 0xf7edeef3: <span class="m">0</span> <span class="s1">&#39;\000&#39;</span> pppppppppppppppp 0xf7edeef3: <span class="m">0</span> <span class="s1">&#39;\000&#39;</span> qqqqqqqqqqqqqqqq 0xf7edeef3: <span class="m">0</span> <span class="s1">&#39;\000&#39;</span> rrrrrrrrrrrrrrrr 0xf7edeef3: <span class="m">0</span> <span class="s1">&#39;\000&#39;</span> ssssssssssssssss 0xf7edeef3: <span class="m">0</span> <span class="s1">&#39;\000&#39;</span> tttttttttttttttt 0xf7edeef3: <span class="m">0</span> <span class="s1">&#39;\000&#39;</span> uuuuuuuuuuuuuuuu 0xf7edeef3: <span class="m">0</span> <span class="s1">&#39;\000&#39;</span> vvvvvvvvvvvvvvvv 0xf7edeef3: <span class="m">0</span> <span class="s1">&#39;\000&#39;</span> wwwwwwwwwwwwwwww 0xf7edeef3: <span class="m">0</span> <span class="s1">&#39;\000&#39;</span> xxxxxxxxxxxxxxxx 0xf7edeef3: <span class="m">0</span> <span class="s1">&#39;\000&#39;</span> yyyyyyyyyyyyyyyy 0xf7edeef3: <span class="m">0</span> <span class="s1">&#39;\000&#39;</span> zzzzzzzzzzzzzzzz 0xf7edeef3: <span class="m">0</span> <span class="s1">&#39;\000&#39;</span> AAAAAAAAAAAAAAAA 0xf7edeef3: <span class="m">0</span> <span class="s1">&#39;\000&#39;</span> BBBBBBBBBBBBBBBB 0xf7edeef3: <span class="m">0</span> <span class="s1">&#39;\000&#39;</span> CCCCCCCCCCCCCCCC 0xf7edeef3: <span class="m">0</span> <span class="s1">&#39;\000&#39;</span> DDDDDDDDDDDDDDDD 0xf7edeef3: <span class="m">0</span> <span class="s1">&#39;\000&#39;</span> EEEEEEEEEEEEEEEE 0xf7edeef3: <span class="m">0</span> <span class="s1">&#39;\000&#39;</span> FFFFFFFFFFFFFFFF 0xf7edeef3: <span class="m">0</span> <span class="s1">&#39;\000&#39;</span> GGGGGGGGGGGGGGGG 0xf7edeef3: <span class="m">1</span> <span class="s1">&#39;\001&#39;</span> 0xf7edeef3: <span class="m">0</span> <span class="s1">&#39;\000&#39;</span> HHHHHHHHHHHHHHHH 0xf7edeef3: <span class="m">0</span> <span class="s1">&#39;\000&#39;</span> IIIIIIIIIIIIIIII 0xf7edeef3: <span class="m">0</span> <span class="s1">&#39;\000&#39;</span> JJJJJJJJJJJJJJJJ 0xf7edeef3: <span class="m">0</span> <span class="s1">&#39;\000&#39;</span> KKKKKKKKKKKKKKKK 0xf7edeef3: <span class="m">0</span> <span class="s1">&#39;\000&#39;</span> LLLLLLLLLLLLLLLL 0xf7edeef3: <span class="m">0</span> <span class="s1">&#39;\000&#39;</span> MMMMMMMMMMMMMMMM 0xf7edeef3: <span class="m">0</span> <span class="s1">&#39;\000&#39;</span> NNNNNNNNNNNNNNNN 0xf7edeef3: <span class="m">0</span> <span class="s1">&#39;\000&#39;</span> OOOOOOOOOOOOOOOO 0xf7edeef3: <span class="m">0</span> <span class="s1">&#39;\000&#39;</span> PPPPPPPPPPPPPPPP 0xf7edeef3: <span class="m">0</span> <span class="s1">&#39;\000&#39;</span> QQQQQQQQQQQQQQQQ 0xf7edeef3: <span class="m">0</span> <span class="s1">&#39;\000&#39;</span> RRRRRRRRRRRRRRRR 0xf7edeef3: <span class="m">0</span> <span class="s1">&#39;\000&#39;</span> SSSSSSSSSSSSSSSS 0xf7edeef3: <span class="m">0</span> <span class="s1">&#39;\000&#39;</span> TTTTTTTTTTTTTTTT 0xf7edeef3: <span class="m">0</span> <span class="s1">&#39;\000&#39;</span> UUUUUUUUUUUUUUUU 0xf7edeef3: <span class="m">0</span> <span class="s1">&#39;\000&#39;</span> VVVVVVVVVVVVVVVV 0xf7edeef3: <span class="m">0</span> <span class="s1">&#39;\000&#39;</span> WWWWWWWWWWWWWWWW 0xf7edeef3: <span class="m">0</span> <span class="s1">&#39;\000&#39;</span> XXXXXXXXXXXXXXXX 0xf7edeef3: <span class="m">0</span> <span class="s1">&#39;\000&#39;</span> YYYYYYYYYYYYYYYY 0xf7edeef3: <span class="m">0</span> <span class="s1">&#39;\000&#39;</span> ZZZZZZZZZZZZZZZZ ... </pre></div> </td></tr></table> <p>¡Sí!</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1 2 3</pre></div></td><td class="code"><div class="highlight"><pre>GGGGGGGGGGGGGGGG 0xf7edeef3: <span class="m">1</span> <span class="s1">&#39;\001&#39;</span> 0xf7edeef3: <span class="m">0</span> <span class="s1">&#39;\000&#39;</span> </pre></div> </td></tr></table> <p>Y no hace falta ni parsear si sigue pasando por ahí es que vamos bien, podemos simplemente contar las veces que se pasa por el breakpoint :D, hacemos un par de arreglos, en <code>test()</code></p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24</pre></div></td><td class="code"><div class="highlight"><pre><span class="k">def</span> <span class="nf">test</span><span class="p">(</span><span class="n">passwd</span><span class="p">):</span> <span class="c"># Generamos el archivo de control</span> <span class="n">gen_ctrl</span><span class="p">(</span><span class="n">passwd</span><span class="p">)</span> <span class="c"># Lanzamos el gdb y tomamos control de su stdout y stderr</span> <span class="n">p</span> <span class="o">=</span> <span class="n">subprocess</span><span class="o">.</span><span class="n">Popen</span><span class="p">([</span><span class="s">&quot;gdb&quot;</span><span class="p">,</span> <span class="n">PROGNAME</span><span class="p">,</span> <span class="s">&#39;-batch&#39;</span><span class="p">,</span> <span class="s">&#39;-x&#39;</span><span class="p">,</span> <span class="n">CONTROLLER_NAME</span><span class="p">],</span> <span class="n">stdout</span><span class="o">=</span><span class="n">subprocess</span><span class="o">.</span><span class="n">PIPE</span><span class="p">,</span> <span class="n">stderr</span><span class="o">=</span><span class="n">subprocess</span><span class="o">.</span><span class="n">PIPE</span><span class="p">)</span> <span class="c"># Buscaremos en el stdout las líneas con el dump de la memoria</span> <span class="c"># que son las que siguen al aviso de que se llegó a un breakpoint</span> <span class="n">o</span> <span class="o">=</span> <span class="n">p</span><span class="o">.</span><span class="n">stdout</span><span class="o">.</span><span class="n">read</span><span class="p">()</span> <span class="n">nxt</span> <span class="o">=</span> <span class="bp">False</span> <span class="n">i</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span> <span class="k">for</span> <span class="n">l</span> <span class="ow">in</span> <span class="n">o</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">&#39;</span><span class="se">\n</span><span class="s">&#39;</span><span class="p">):</span> <span class="k">if</span> <span class="n">nxt</span><span class="p">:</span> <span class="n">i</span> <span class="o">+=</span> <span class="mi">1</span> <span class="n">nxt</span> <span class="o">=</span> <span class="bp">False</span> <span class="k">if</span> <span class="s">&#39;Breakpoint 1, 0x08049118 in main.main ()&#39;</span> <span class="ow">in</span> <span class="n">l</span><span class="p">:</span> <span class="n">nxt</span> <span class="o">=</span> <span class="bp">True</span> <span class="k">return</span> <span class="n">i</span> </pre></div> </td></tr></table> <p>En el bucle principal</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1 2 3 4 5 6 7 8 9 10 11</pre></div></td><td class="code"><div class="highlight"><pre><span class="n">CHARS</span> <span class="o">=</span> <span class="n">string</span><span class="o">.</span><span class="n">printable</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span> <span class="n">best</span> <span class="o">=</span> <span class="bp">None</span> <span class="n">top</span> <span class="o">=</span> <span class="mi">0</span> <span class="k">for</span> <span class="n">c</span> <span class="ow">in</span> <span class="n">CHARS</span><span class="p">:</span> <span class="n">result</span> <span class="o">=</span> <span class="n">test</span><span class="p">(</span><span class="n">c</span> <span class="o">*</span> <span class="mi">16</span><span class="p">)</span> <span class="k">if</span> <span class="n">result</span> <span class="o">&gt;</span> <span class="n">top</span><span class="p">:</span> <span class="n">best</span> <span class="o">=</span> <span class="n">c</span> <span class="n">top</span> <span class="o">=</span> <span class="n">result</span> <span class="k">print</span> <span class="s">&quot;Best:&quot;</span><span class="p">,</span> <span class="n">best</span> <span class="k">print</span> <span class="s">&quot;With&quot;</span> <span class="p">,</span> <span class="n">top</span><span class="p">,</span> <span class="s">&quot;matches&quot;</span> </pre></div> </td></tr></table> <p>El resultado es el que habíamos encontrado antes, claro, la primera letra es:</p> <div class="highlight"><pre><span class="nv">$ </span>python test.py Best: G With <span class="m">1</span> matches <span class="err">$</span> </pre></div> <p>Ahora podemos hacer que busque el resto, si repetimos ese bucle para cada letra guardando las anteriores...</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17</pre></div></td><td class="code"><div class="highlight"><pre><span class="n">matches</span> <span class="o">=</span> <span class="p">[]</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">xrange</span><span class="p">(</span><span class="mi">16</span><span class="p">):</span> <span class="n">best</span> <span class="o">=</span> <span class="bp">None</span> <span class="n">top</span> <span class="o">=</span> <span class="mi">0</span> <span class="k">for</span> <span class="n">c</span> <span class="ow">in</span> <span class="n">CHARS</span><span class="p">:</span> <span class="n">result</span> <span class="o">=</span> <span class="n">test</span><span class="p">(</span><span class="s">&#39;&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">matches</span><span class="p">)</span> <span class="o">+</span> <span class="n">c</span> <span class="o">*</span> <span class="p">(</span><span class="mi">16</span> <span class="o">-</span> <span class="nb">len</span><span class="p">(</span><span class="n">matches</span><span class="p">)))</span> <span class="k">if</span> <span class="n">result</span> <span class="o">&gt;</span> <span class="n">top</span><span class="p">:</span> <span class="n">best</span> <span class="o">=</span> <span class="n">c</span> <span class="n">top</span> <span class="o">=</span> <span class="n">result</span> <span class="c"># ↓decoración, eliminar si se ve mal</span> <span class="k">print</span> <span class="s">&quot;Current:&quot;</span><span class="p">,</span> <span class="s">&#39;&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">matches</span><span class="p">)</span> <span class="o">+</span> <span class="s">&#39;</span><span class="se">\x1b</span><span class="s">[1m&#39;</span> <span class="o">+</span> <span class="n">best</span> <span class="o">+</span> <span class="s">&#39;</span><span class="se">\x1b</span><span class="s">[0m&#39;</span> <span class="n">matches</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">best</span><span class="p">)</span> <span class="k">print</span> <span class="s">&quot;Best:&quot;</span><span class="p">,</span> <span class="n">best</span> <span class="k">print</span> <span class="s">&quot;With&quot;</span> <span class="p">,</span> <span class="n">top</span><span class="p">,</span> <span class="s">&quot;matches&quot;</span> <span class="k">print</span> <span class="s">&quot;Resultado: &quot;</span><span class="p">,</span> <span class="s">&#39;&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">matches</span><span class="p">)</span> </pre></div> </td></tr></table> <p>Y ahí va...</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51</pre></div></td><td class="code"><div class="highlight"><pre><span class="nv">$ </span>python test.py Current: G Best: G With <span class="m">1</span> matches Current: G0 Best: 0 With <span class="m">2</span> matches Current: G0w Best: w With <span class="m">3</span> matches Current: G0w1 Best: 1 With <span class="m">4</span> matches Current: G0w1n Best: n With <span class="m">5</span> matches Current: G0w1n! Best: ! With <span class="m">6</span> matches Current: G0w1n!C Best: C With <span class="m">7</span> matches Current: G0w1n!C0 Best: 0 With <span class="m">8</span> matches Current: G0w1n!C0n Best: n With <span class="m">9</span> matches Current: G0w1n!C0ng Best: g With <span class="m">10</span> matches Current: G0w1n!C0ngr Best: r With <span class="m">11</span> matches Current: G0w1n!C0ngr4 Best: 4 With <span class="m">12</span> matches Current: G0w1n!C0ngr4t Best: t With <span class="m">13</span> matches Current: G0w1n!C0ngr4t5 Best: 5 With <span class="m">14</span> matches Current: G0w1n!C0ngr4t5! Best: ! With <span class="m">15</span> matches Current: G0w1n!C0ngr4t5!0 Best: 0 With <span class="m">15</span> matches Resultado: G0w1n!C0ngr4t5!0 <span class="err">$</span> </pre></div> </td></tr></table> <p>“G0w1n!C0ngr4t5!0”, lo probamos y ...</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1 2 3</pre></div></td><td class="code"><div class="highlight"><pre><span class="nv">$ </span>./inbincible <span class="s1">&#39;G0w1n!C0ngr4t5!0&#39;</span> Nope! <span class="err">$</span> </pre></div> </td></tr></table> <p>¿¡Qué!?</p> <p>Bien, resulta que el último caracter no lo saca bien por que da igual para el número de iteraciones (lo que tiene ahorrarse medio minuto contando líneas en vez de buscar unos :P), si hacemos el bucle como debiera ser...</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1 2 3 4 5 6 7 8 9 10 11 12</pre></div></td><td class="code"><div class="highlight"><pre><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span> <span class="k">for</span> <span class="n">l</span> <span class="ow">in</span> <span class="n">o</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">&#39;</span><span class="se">\n</span><span class="s">&#39;</span><span class="p">):</span> <span class="k">if</span> <span class="n">nxt</span><span class="p">:</span> <span class="k">if</span> <span class="s">&#39;</span><span class="se">\\</span><span class="s">001&#39;</span> <span class="ow">in</span> <span class="n">l</span><span class="p">:</span> <span class="n">i</span> <span class="o">+=</span> <span class="mi">1</span> <span class="n">nxt</span> <span class="o">=</span> <span class="bp">False</span> <span class="k">if</span> <span class="s">&#39;Breakpoint 1, 0x08049118 in main.main ()&#39;</span> <span class="ow">in</span> <span class="n">l</span><span class="p">:</span> <span class="n">nxt</span> <span class="o">=</span> <span class="bp">True</span> <span class="k">return</span> <span class="n">i</span> </pre></div> </td></tr></table> <p>Acabamos con el resultado real</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1 2 3 4 5 6 7 8 9 10</pre></div></td><td class="code"><div class="highlight"><pre><span class="nv">$ </span>python test.py Current: G Best: G With <span class="m">1</span> matches ... Current: G0w1n!C0ngr4t5!! Best: ! With <span class="m">16</span> matches Resultado: G0w1n!C0ngr4t5!! <span class="err">$</span> </pre></div> </td></tr></table> <p>Y ahora sí</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1 2 3</pre></div></td><td class="code"><div class="highlight"><pre><span class="nv">$ </span>./inbincible <span class="s1">&#39;G0w1n!C0ngr4t5!!&#39;</span> Yeah! <span class="err">$</span> </pre></div> </td></tr></table> Extrayendo subtitulos de un .mkv tag:codigoparallevar.com/blog,2014-07-20:/2014/extrayendo-subtitulos-de-un-mkv 2014-07-20T00:46:00Z kenkeiras http://codigoparallevar.com/blog/ me@codigoparallevar.com <p><em>Realmente sobre esto ya había escrito pero se perdió en alguna migración... así que aquí está de nuevo</em></p> <p>Todo el parseado y la extracción la implementa <a href="http://www.bunkus.org/videotools/mkvtoolnix/"><code>mkvtoolnix</code></a>, así que habiéndolo instalado...</p> <pre class="highlight"><code class="language-bash linenums">sudo apt-get install mkvtoolnix</code></pre> <p>A partir de ahí podemos ver las pistas que tiene un archivo</p> <pre class="highlight"><code class="language-bash linenums">mkvinfo video.mkv</code></pre> <!-- more --> <p>Si hacemos <code>|grep track</code> se ve mejor, por ejemplo</p> <pre class="highlight"><code class="language-bash linenums">$ mkvinfo video.mkv |grep Track | + Track number: 1 (track ID for mkvmerge &amp; mkvextract: 0) | + Track UID: 1 | + Track type: video | + Track number: 2 (track ID for mkvmerge &amp; mkvextract: 1) | + Track UID: 6584684576 | + Track type: audio | + Track number: 3 (track ID for mkvmerge &amp; mkvextract: 2) | + Track UID: 685789658 | + Track type: subtitles</code></pre> <p>En este caso nos interesa la pista número 3 (que será la 2 para <code>mkvmerge</code> y <code>mkvextract</code> como indica), así que la extraemos con</p> <pre class="highlight"><code class="language-bash linenums">mkvextract tracks video.mkv 2:subtitulos</code></pre> <p>Durante el proceso la interfaz indica el tipo de subtítulos, por si queremos ponerle la extensión adecuada al archivo resultante</p> <pre class="highlight"><code class="language-bash linenums">$ mkvextract tracks video.mkv 2:subtitulos Extracting track 2 with the CodecID 'S_TEXT/ASS' to the file 'subtitulos. Container format: SSA/ASS text subtitles Progress: 100% $ mv subtitulos subtitulos.ssa</code></pre> <p>Y eso es todo, por supuestos se podría extraer cualquier pista, si cambiamos el <code>2:</code> por <code>1:</code> extraeríamos (en este caso) el audio.</p> Migrando ownCloud de MySQL a SQLite tag:codigoparallevar.com/blog,2014-05-02:/2014/migrando-owncloud-de-mysql-a-sqlite 2014-05-02T20:46:00Z kenkeiras http://codigoparallevar.com/blog/ me@codigoparallevar.com <p>En su momento realicé una instalación de <a href="http://owncloud.org/">ownCloud</a> utilizando MySQL como base de datos, más tarde se hizo obvio que esta no era la opción correcta y que la necesidad de ahorrar toda la memoria RAM posible y el hecho de que no hubiera más accesos que los míos apuntaron a que debía haber optado por SQLite, el proceso es algo complicado la primera vez así que aquí queda explicado por si hay que repetirlo...</p> <p>Lo primero es convertir la propia base de datos a SQlite, idealmente esto supondría sacar un <a href="https://dev.mysql.com/doc/refman/5.5/en/mysqldump.html"><code>mysqdump</code></a>, pasárselo a SQLite y el estándar del lenguaje haría el resto... </p> <p>Pero esto no es tan sencillo, resulta que hay incompatibilidades entre estos dos dialectos y resolverlas a mano requeriría un tiempo del que probablemente no dispongamos, para esto podemos recurrir a <a href="https://rubygems.org/gems/sequel"><code>sequel</code></a>, con Ruby y las librerías de desarrollo de los clientes de MySQL y SQLite instaladas podemos conseguirlo haciendo</p> <pre class="highlight"><code class="language-bash linenums">gem sqlite3 gem mysql gem sequel</code></pre> <p>Una vez instalado para convertir la base de datos solo habría que hacer</p> <pre class="highlight"><code class="language-bash linenums">sequel 'mysql://db_username:db_pass@db_host/db_name' -C &quot;sqlite://db.sqlite&quot;</code></pre> <p>Y tendremos la base de daños migrada a SQLite en <code>db.sqlite</code>, solo falta la configuración.</p> <p>En el directorio de instalación de ownCloud hay uno llamado <code>config</code>, dentro, el archivo a editar para pasar a la nueva base de datos es <code>config.php</code>, el significado de cada línea se puede ver en <code>config.sample.php</code>, concretamente habría que cambiar las líneas "dbtype" de <strong>mysql</strong> a <strong>sqlite</strong>.</p> <p>Por último queda añadir la nueva base de datos a la carpeta <code>data</code> con el nombre que tomaba la base de datos y la extensión <strong>.db</strong> y listo, tras asignar los permisos para que ownCloud pueda acceder y modificar el archivo ya podemos usar de nuevo la plataforma.</p> Haciendo MySQLdumps más amigables tag:codigoparallevar.com/blog,2014-03-16:/2014/haciendo-mysqldumps-mas-amigables 2014-03-16T19:36:00Z kenkeiras http://codigoparallevar.com/blog/ me@codigoparallevar.com <p>Hace un tiempo había tenido que tratar con dumps de MySQL generados por <a href="http://man.cx/mysqldump">mysqldump(1)</a>, a falta de una forma de control de versiones más específica (que por suerte no llegó a hacer falta) se utilizó <a href="http://man.cx/git(7)">git(7)</a>. Ahora bien, git permite hacer <a href="http://man.cx/diff">diff</a> entre versiones, pero esto (al menos por defecto) se hace línea por línea, lo que produce que los diff entre dumps muestren grandes cambios aunque solo se produzcan en una fila de la base de datos, para solucionar ese inconveniente está este programa <a href="http://codigoparallevar.com/blog/files/2014/02/sqlsplit.c">sqlsplit.c</a>.</p> <p>El programa no está muy pulido, tiene una función main que solo abre archivos y otra que (con la ayuda de dos macros *_*) simula algo parecido a un autómata de estados (realmente con una pila), la compilación es simple.</p> <pre class="highlight"><code class="language-bash linenums">gcc sqlsplit.c -o sqlsplit</code></pre> <p>Por ejemplo, si la entrada fuera</p> <pre class="highlight"><code class="language-mysql linenums">set autocommit=0; INSERT INTO `input_table` VALUES (1,'Title 1','File 1','Type','NULL','Date 1'),(2,'Another title','Another file, too','Type, you know','Language','9999'),(3,'A third title','File with \' too.heh','Some, types','NULL','Tomorrow'); /*!40000 ALTER TABLE `input_table` ENABLE KEYS */; UNLOCK TABLES; commit;</code></pre> <p>Haciendo esto...</p> <pre class="highlight"><code class="language-bash linenums">./sqlsplit intput.sql output.sql</code></pre> <p>Conseguiríamos algo más legible</p> <pre class="highlight"><code class="language-mysql linenums">set autocommit=0; INSERT INTO `input_table` VALUES (1,'Title 1','File 1','Type','NULL','Date 1'), (2,'Another title','Another file, too','Type, you know','Language','9999'), (3,'A third title','File with \' too.heh','Some, types','NULL','Tomorrow'); /*!40000 ALTER TABLE `input_table` ENABLE KEYS */; UNLOCK TABLES; commit;</code></pre> <p>Eso es todo, por supuesto si quisiéramos que aceptar o mostrar la salida por el terminal (por ejemplo para tomar o devolver archivos comprimidos) usaríamos /dev/stdin como entrada y/o /dev/stdout como salida.</p> Usando andEngine desde emacs tag:codigoparallevar.com/blog,2014-02-23:/2014/usando-andengine-desde-emacs 2014-02-23T16:30:00Z kenkeiras http://codigoparallevar.com/blog/ me@codigoparallevar.com <p>Hoy estaba hechando un vistazo a la programación de juegos en android, una librería con buena pinta para hacerlo es <a href="https://github.com/nicolasgramlich/AndEngine">AndEngine</a>, los tutoriales que he encontrado para hacerlo son para Eclipse, pero después de intentarlo y acabar un par de veces con un segfault ¡importando un proyecto! toca volver a los clásicos, vamos a ver como hacerlo con emacs. <!-- more --></p> <h4>Instalar android-mode</h4> <p>Partimos de tener <a href="https://github.com/remvee/android-mode">android-mode</a>, para instalarlo habrá que meterlo en el path, si queremos que sea global lo haremos en <code>/usr/share/emacs/site-lisp/</code> (para esto harán falta permisos de root), sino tendremos que añadir el directorio al path con</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1</pre></div></td><td class="code"><div class="highlight"><pre><span class="p">(</span><span class="nv">add-to-list</span> <span class="ss">&#39;load-path</span> <span class="s">&quot;&lt;directorio&gt;&quot;</span><span class="p">)</span> </pre></div> </td></tr></table> <p>Después habrá que cargarlo y ajustar el path del SDK de android, en mi caso está en <code>/home/kenkeiras/.android-sdk/</code>, así que...</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1 2</pre></div></td><td class="code"><div class="highlight"><pre><span class="p">(</span><span class="nb">require</span> <span class="ss">&#39;android-mode</span><span class="p">)</span> <span class="p">(</span><span class="k">setq</span> <span class="nv">android-mode-sdk-dir</span> <span class="s">&quot;/home/kenkeiras/.android-sdk/&quot;</span><span class="p">)</span> </pre></div> </td></tr></table> <p>Estas cosas se pueden hacer en el buffer <code>*Scratch*</code> con lo que habría que repetirlas cada vez que vayamos a usar el plugin, o escribirlas en el archivo <a href="https://www.gnu.org/software/emacs/manual/html_node/emacs/Init-File.html">init.el</a> para que lo haga automáticamente al iniciarse, si quisieramos aplicar los cambios al instante podríamos hacerlo pulsado <code>C-x C-e</code> (Control-x, Control-x) al final de cada línea.</p> <h4>Crear un proyecto</h4> <p>Una vez que tengamos eso instalado habrá que crear un proyecto, para esto desde emacs haremos <code>M-x android-create-project</code> (Alt-x android-create-project), el plugin nos preguntará en que directorio ubicar el proyecto, el nombre que se asignará al paquete, el de la actividad principal y un target. El target es la <a href="https://en.wikipedia.org/wiki/Android_versions#Version_history_by_API_level">versión de Android</a> para la que se “compilará” el código, pulsar tabulador dos veces probablemente hará que muestre las opciones (no se si será cosa de <a href="https://github.com/overtone/emacs-live">emacs-live</a>).</p> <p>Y con esto ya tendríamos el proyecto creado, si hicieramos</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1</pre></div></td><td class="code"><div class="highlight"><pre>M-x android-build-debug (Alt-x android-build-debug) </pre></div> </td></tr></table> <p>y</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1</pre></div></td><td class="code"><div class="highlight"><pre>M-x android-build-install (Alt-x android-build-install) </pre></div> </td></tr></table> <p>construiría el proyecto y lo transferiría al dispositivo que se encuentre activo, y ya se puede lanzar.</p> <p><img alt="Hello world" src="http://codigoparallevar.com/blog/files/2014/02/hello-world.png"/></p> <h4>Construyendo AndEngine</h4> <p>Para esto descargamos el proyecto en otro directorio, por ejemplo desde el repositorio</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1</pre></div></td><td class="code"><div class="highlight"><pre>git clone https://github.com/nicolasgramlich/AndEngine </pre></div> </td></tr></table> <p>Dentro del directorio creado crearemos un archivo <code>local.properties</code> con la ubicación del SDK, en mi caso</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1</pre></div></td><td class="code"><div class="highlight"><pre>sdk.dir=/home/kenkeiras/.android-sdk </pre></div> </td></tr></table> <p>Hecho esto, se puede construir (teniendo en cuenta que la versión del API por defecto <a href="https://github.com/nicolasgramlich/AndEngine/blob/GLES2/project.properties#L14">es la 15</a>, esto se puede cambiar en <code>project.properties</code>).</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1</pre></div></td><td class="code"><div class="highlight"><pre>ant debug </pre></div> </td></tr></table> <p>Producirá un archivo <code>classes.jar</code> en el directorio <code>bin</code>, que deberá ser importado en el directorio <code>libs</code> de nuestro proyecto.</p> <h4>Código de ejemplo</h4> <p>Por último probaremos si funciona con algo tomado de <a href="https://beginningandengine.wordpress.com/2012/09/08/setting-up-andengine/">Beggining andengine</a></p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39</pre></div></td><td class="code"><div class="highlight"><pre><span class="kn">package</span> <span class="nn">com.example.sampleandengineapp</span><span class="o">;</span> <span class="kn">import</span> <span class="nn">org.andengine.engine.camera.Camera</span><span class="o">;</span> <span class="kn">import</span> <span class="nn">org.andengine.engine.options.EngineOptions</span><span class="o">;</span> <span class="kn">import</span> <span class="nn">org.andengine.engine.options.ScreenOrientation</span><span class="o">;</span> <span class="kn">import</span> <span class="nn">org.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy</span><span class="o">;</span> <span class="kn">import</span> <span class="nn">org.andengine.entity.scene.Scene</span><span class="o">;</span> <span class="kn">import</span> <span class="nn">org.andengine.entity.scene.background.Background</span><span class="o">;</span> <span class="kn">import</span> <span class="nn">org.andengine.ui.activity.SimpleBaseGameActivity</span><span class="o">;</span> <span class="kd">public</span> <span class="kd">class</span> <span class="nc">MainActivity</span> <span class="kd">extends</span> <span class="n">SimpleBaseGameActivity</span><span class="o">{</span> <span class="kd">static</span> <span class="kd">final</span> <span class="kt">int</span> <span class="n">CAMERA_WIDTH</span> <span class="o">=</span> <span class="mi">800</span><span class="o">;</span> <span class="kd">static</span> <span class="kd">final</span> <span class="kt">int</span> <span class="n">CAMERA_HEIGHT</span> <span class="o">=</span> <span class="mi">480</span><span class="o">;</span> <span class="nd">@Override</span> <span class="kd">public</span> <span class="n">EngineOptions</span> <span class="nf">onCreateEngineOptions</span><span class="o">(){</span> <span class="n">Camera</span> <span class="n">mCamera</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Camera</span><span class="o">(</span><span class="mi">0</span><span class="o">,</span> <span class="mi">0</span><span class="o">,</span> <span class="n">CAMERA_WIDTH</span><span class="o">,</span> <span class="n">CAMERA_HEIGHT</span><span class="o">);</span> <span class="k">return</span> <span class="k">new</span> <span class="n">EngineOptions</span><span class="o">(</span> <span class="kc">true</span><span class="o">,</span> <span class="n">ScreenOrientation</span><span class="o">.</span><span class="na">LANDSCAPE_SENSOR</span><span class="o">,</span> <span class="k">new</span> <span class="n">RatioResolutionPolicy</span><span class="o">(</span><span class="n">CAMERA_WIDTH</span><span class="o">,</span> <span class="n">CAMERA_HEIGHT</span><span class="o">),</span> <span class="n">mCamera</span><span class="o">);</span> <span class="o">}</span> <span class="nd">@Override</span> <span class="kd">protected</span> <span class="kt">void</span> <span class="nf">onCreateResources</span><span class="o">(){</span> <span class="o">}</span> <span class="nd">@Override</span> <span class="kd">protected</span> <span class="n">Scene</span> <span class="nf">onCreateScene</span><span class="o">(){</span> <span class="n">Scene</span> <span class="n">scene</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Scene</span><span class="o">();</span> <span class="n">scene</span><span class="o">.</span><span class="na">setBackground</span><span class="o">(</span><span class="k">new</span> <span class="n">Background</span><span class="o">(</span><span class="mf">0.09704f</span><span class="o">,</span> <span class="mf">0.3454f</span><span class="o">,</span> <span class="mi">0</span><span class="o">));</span> <span class="k">return</span> <span class="n">scene</span><span class="o">;</span> <span class="o">}</span> <span class="o">}</span> </pre></div> </td></tr></table> <p>No es gran cosa, pero funciona</p> <p><img alt="solo un fondo" src="http://codigoparallevar.com/blog/files/2014/02/background.png"/></p> <p>(Sí, es una pantalla en verde :P)</p> Escribiendo un port de Erlang tag:codigoparallevar.com/blog,2014-01-23:/2014/escribiendo-un-port-de-erlang 2014-01-23T02:34:00Z kenkeiras http://codigoparallevar.com/blog/ me@codigoparallevar.com <p>Resulta que este cuatrimestre ha habido una asignatura cuya práctica se ha desarrollado en <a href="http://www.erlang.org/">Erlang</a>, un <a href="https://es.wikipedia.org/wiki/Programaci%C3%B3n_funcional">lenguaje funcional</a> que favorece la programación concurrente y la comunicación de los procesos usando <a href="https://en.wikipedia.org/wiki/Message_passing">paso de mensajes</a>. El resultado de la práctica es un crawler donde cada dominio tiene asignado un “hilo” que tendrá que hacer las peticiones al servidor web, más otro que se encargará de descargar imágenes e indexarlas utilizando <a href="http://phash.org/">pHash</a>, el programa se compone de más partes pero ahora nos centraremos en esto.</p> <p>(Por cierto, el proyecto se ha desarrollado en abierto, tenéis el código en <a href="https://github.com/kenkeiras/EPC">su repositorio de GitHub, EPC</a>).</p> <p><a href="https://github.com/kenkeiras/EPC/blob/aa0dada1cc1ba97a1128e221cd677802e74ea700/src/web_lib.erl#L21">Al principio</a> cada hilo simplemente hacía una llamada a <a href="http://www.erlang.org/doc/man/httpc.html#request-1">httpc:request</a>, que es la forma que ofrece la libería estándar del lenguaje de hacer estas peticiones, pero <em>parece</em> que la concurrencia que ofrece deja que desear, esto producía inanicción en el proceso de indexación.</p> <p>Más abajo la especificación muestra una posible solución:</p> <blockquote> <p>Detalles de Option (option()): <br /> sync <br /> &nbsp;&nbsp;&nbsp;&nbsp;La petición debe ser síncrona o asíncrona. <br /> &nbsp;&nbsp;&nbsp;&nbsp;Por defecto true. <br /></p> </blockquote> <p>En su momento no se comprobó si esta era una solución, sinó que se implementaron otras dos, una fué <a href="https://github.com/stbnps/EPC/commit/15556f7164093062a52d616205cae4b76945a4cf">el uso de un proceso</a> que se encargara de realizar las descargas dándole prioridad al indexer y que los crawler no le produjeran inanicción ya que toma un tiempo para obtener las características de la imágen (no mucho pero algo), esto está implementado en Erlang puro y fué el que se tomó en la rama master.</p> <p>Otra opción fué implementar la descarga como un <a href="http://www.erlang.org/doc/tutorial/overview.html">port</a>, un programa externo escrito en este caso en C y que sería llamado desde un proceso de Erlang, esta posibilidad quedó registrada en la rama <a href="https://github.com/kenkeiras/EPC/tree/GET-by-port">GET-by-port</a>.</p> <h3>Comunicación C - Erlang</h3> <p>El port tiene dos componentes, <a href="https://github.com/kenkeiras/EPC/blob/GET-by-port/include/http_get.c">la parte en C</a> y <a href="https://github.com/kenkeiras/EPC/blob/GET-by-port/src/http_get.erl">la parte en Erlang</a>, la comunicación se puede hacer de varios tipos, y se define con <code>PortSettings</code> en <a href="http://www.erlang.org/doc/man/erlang.html#open_port-2">open_port</a>, las posibilidades son</p> <ul> <li> <p><strong>{packet, N}</strong></p> <p>Los mensajes son precedidos por su longitud, enviada en N bytes, con el más significativo primero, los valores válidos de N son 1, 2 y 4.</p> </li> <li> <p><strong>stream</strong></p> <p>Los mensajes son enviados sin longitud de paquete. Debe establecerse un protocolo definido por el usuario entre el proceso Erlang y el objeto externo.</p> </li> <li> <p><strong>{line, L}</strong></p> <p>Los mensajes son enviados por líneas. Cada línea (delimitada por una secuencia de fin de línea dependiente del SO) se envía en un solo mensaje is. El formato del mensaje es {Flag, Línea}. Donde Flag es o <strong>eol</strong> o <strong>noeol</strong> y Línea son los datos realmente enviados (sin la sequencia de salto de línea).</p> <p>L especifica la lóngitud máxima de la línea en bytes. Las línea mayores que estas serán enviadas en más de un mensaje Lines, con el Flag <strong>noeol</strong> para todos los mensajes menos el último. Si el fin de archivo se encuentra en cualquier otro lugar a parte de inmediatamente siguiendo un salto de línea, la última línea también será enviada con el Flag <strong>noeol</strong>. En el resto de casos, las líneas son enviadas con el Flag <strong>eol</strong>.</p> <p>Las opciones <strong>{packet, N}</strong> y <strong>{line, L}</strong> son mútuamente exclusivas.</p> </li> </ul> <p>En este caso elegiremos <strong>{packet, 4}</strong>, suficiente para enviar páginas enteras de vuelta.</p> <h3>Comunicación - El lado de C</h3> <p>Centrémonos ahora en lo que ocurre en el programa escrito en C cuando recibe los datos, la función que maneja esto es <a href="https://github.com/kenkeiras/EPC/blob/GET-by-port/include/http_get.c#L22">char* read_url()</a></p> <p>El proceso es sencillo, lee 4 bytes de <strong>stdin</strong> y los guarda como un <a href="http://www.nongnu.org/avr-libc/user-manual/group__avr__stdint.html">uint32_t</a></p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1 2 3 4</pre></div></td><td class="code"><div class="highlight"><pre><span class="kt">uint32_t</span> <span class="n">length</span><span class="p">;</span> <span class="k">if</span> <span class="p">(</span><span class="n">fread</span><span class="p">(</span><span class="o">&amp;</span><span class="n">length</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="n">stdin</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">1</span><span class="p">){</span> <span class="k">return</span> <span class="nb">NULL</span><span class="p">;</span> <span class="p">}</span> </pre></div> </td></tr></table> <p>Después convierte los datos de <a href="https://en.wikipedia.org/wiki/Endianness">big-endian</a> a la codificación del host, esto se hace con la función <a href="http://beej.us/guide/bgnet/output/html/multipage/htonsman.html">ntohl()</a></p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1</pre></div></td><td class="code"><div class="highlight"><pre><span class="n">length</span> <span class="o">=</span> <span class="n">ntohl</span><span class="p">(</span><span class="n">length</span><span class="p">);</span> </pre></div> </td></tr></table> <p>El resto es simplemente leer la cadena de <strong>stdin</strong>, sin ninguna transformación y conociendo su longitud</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1 2 3 4 5 6 7 8 9 10 11</pre></div></td><td class="code"><div class="highlight"><pre><span class="kt">char</span> <span class="o">*</span><span class="n">url</span> <span class="o">=</span> <span class="n">malloc</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="kt">char</span><span class="p">)</span> <span class="o">*</span> <span class="p">(</span><span class="n">length</span> <span class="o">+</span> <span class="mi">1</span><span class="p">));</span> <span class="k">if</span> <span class="p">(</span><span class="n">url</span> <span class="o">==</span> <span class="nb">NULL</span><span class="p">){</span> <span class="k">return</span> <span class="nb">NULL</span><span class="p">;</span> <span class="p">}</span> <span class="kt">unsigned</span> <span class="kt">int</span> <span class="n">already_read</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="k">while</span> <span class="p">(</span><span class="n">already_read</span> <span class="o">&lt;</span> <span class="n">length</span><span class="p">){</span> <span class="n">already_read</span> <span class="o">+=</span> <span class="n">fread</span><span class="p">(</span><span class="o">&amp;</span><span class="n">url</span><span class="p">[</span><span class="n">already_read</span><span class="p">],</span> <span class="k">sizeof</span><span class="p">(</span><span class="kt">uint8_t</span><span class="p">),</span> <span class="n">length</span> <span class="o">-</span> <span class="n">already_read</span><span class="p">,</span> <span class="n">stdin</span><span class="p">);</span> <span class="p">}</span> <span class="n">url</span><span class="p">[</span><span class="n">length</span><span class="p">]</span> <span class="o">=</span> <span class="sc">&#39;\0&#39;</span><span class="p">;</span> </pre></div> </td></tr></table> <p>El devolver los datos a Erlang no supone mucho más esfuerzo, como se puede ver en el procedimiento <a href="https://github.com/kenkeiras/EPC/blob/GET-by-port/include/http_get.c#L49">void show_result(headers, body)</a>. Los datos se mandan en dos grupos, primero las cabeceras y después el cuerpo del resultado, enviar las cabeceras supone convertir su tamaño a big-endian usando <strong>htonl</strong> y escribirlo a <strong>stdout</strong>, para después escribir toda la cadena directamente</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1 2 3 4 5 6 7 8 9</pre></div></td><td class="code"><div class="highlight"><pre><span class="cm">/* Pueden pasar cosas muy extrañas si olvidamos esto */</span> <span class="kt">uint32_t</span> <span class="n">headers_size</span> <span class="o">=</span> <span class="n">htonl</span><span class="p">(</span><span class="n">headers</span><span class="p">.</span><span class="n">size</span><span class="p">);</span> <span class="n">fwrite</span><span class="p">(</span><span class="o">&amp;</span><span class="n">headers_size</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="n">stdout</span><span class="p">);</span> <span class="kt">unsigned</span> <span class="kt">int</span> <span class="n">written_head</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="k">while</span> <span class="p">(</span><span class="n">written_head</span> <span class="o">&lt;</span> <span class="n">headers</span><span class="p">.</span><span class="n">size</span><span class="p">){</span> <span class="n">written_head</span> <span class="o">+=</span> <span class="n">fwrite</span><span class="p">(</span><span class="o">&amp;</span><span class="p">(</span><span class="n">headers</span><span class="p">.</span><span class="n">memory</span><span class="p">[</span><span class="n">written_head</span><span class="p">]),</span> <span class="k">sizeof</span><span class="p">(</span><span class="kt">uint8_t</span><span class="p">),</span> <span class="n">headers</span><span class="p">.</span><span class="n">size</span> <span class="o">-</span> <span class="n">written_head</span><span class="p">,</span> <span class="n">stdout</span><span class="p">);</span> <span class="p">}</span> </pre></div> </td></tr></table> <p>... repetiríamos lo mismo para el cuerpo de la respuesta</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1 2 3 4 5 6 7 8</pre></div></td><td class="code"><div class="highlight"><pre><span class="kt">uint32_t</span> <span class="n">body_size</span> <span class="o">=</span> <span class="n">htonl</span><span class="p">(</span><span class="n">body</span><span class="p">.</span><span class="n">size</span><span class="p">);</span> <span class="n">fwrite</span><span class="p">(</span><span class="o">&amp;</span><span class="n">body_size</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="n">stdout</span><span class="p">);</span> <span class="kt">unsigned</span> <span class="kt">int</span> <span class="n">written_body</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="k">while</span> <span class="p">(</span><span class="n">written_body</span> <span class="o">&lt;</span> <span class="n">body</span><span class="p">.</span><span class="n">size</span><span class="p">){</span> <span class="n">written_body</span> <span class="o">+=</span> <span class="n">fwrite</span><span class="p">(</span><span class="o">&amp;</span><span class="p">(</span><span class="n">body</span><span class="p">.</span><span class="n">memory</span><span class="p">[</span><span class="n">written_body</span><span class="p">]),</span> <span class="k">sizeof</span><span class="p">(</span><span class="kt">uint8_t</span><span class="p">),</span> <span class="n">body</span><span class="p">.</span><span class="n">size</span> <span class="o">-</span> <span class="n">written_body</span><span class="p">,</span> <span class="n">stdout</span><span class="p">);</span> <span class="p">}</span> </pre></div> </td></tr></table> <p>Y eso es todo lo que hay que hacer para completar la interfaz con Erlang, el resto es lógica común de C, en este caso sería hacer peticiones HTTP, algo que usando <a href="http://curl.haxx.se/">cURL</a> no supone un gran problema y cada vez que quisieramos tomar una url solo habría que llamar a <strong>read_url()</strong>, y por supuesto la compilación se hace de la forma habitual.</p> <h3>Comunicación - El lado de Erlang</h3> <p>La lógica que debe manejar el proceso Erlang no es tampoco complicada, simplemente habría que utilizar <a href="http://www.erlang.org/doc/man/erlang.html#open_port-2">open_port</a>, que devolvería el <strong>PID</strong> con el que comunicarse, suponiendo que hayamos definido <em>HTTP_GET_BINARY_PATH</em> con la ruta al binario compilado que complete el port</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1</pre></div></td><td class="code"><div class="highlight"><pre><span class="nv">Port</span> <span class="o">=</span> <span class="nb">open_port</span><span class="p">({</span><span class="nb">spawn</span><span class="p">,</span> <span class="o">?</span><span class="nv">HTTP_GET_BINARY_PATH</span><span class="p">},</span> <span class="p">[{</span><span class="n">packet</span><span class="p">,</span> <span class="mi">4</span><span class="p">}])</span> </pre></div> </td></tr></table> <p>Cuando hubiera que enviar datos al binario se enviarían a través de ese <strong>PID</strong>, enviando una tupla</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1</pre></div></td><td class="code"><div class="highlight"><pre><span class="p">{</span><span class="nv">Pid_del_proceso_actual</span><span class="p">,</span> <span class="p">{</span><span class="n">command</span><span class="p">,</span> <span class="nv">Mensaje</span><span class="p">}}</span> </pre></div> </td></tr></table> <p><a href="https://github.com/kenkeiras/EPC/blob/GET-by-port/src/http_get.erl#L67">Por ejemplo</a></p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1</pre></div></td><td class="code"><div class="highlight"><pre><span class="nv">Port</span> <span class="o">!</span> <span class="p">{</span><span class="n">self</span><span class="p">(),</span> <span class="p">{</span><span class="n">command</span><span class="p">,</span> <span class="nv">Msg</span><span class="p">}},</span> </pre></div> </td></tr></table> <p>Esto se convierte en los datos que recibe el binario, de la misma forma cuando este envíe datos <a href="https://github.com/kenkeiras/EPC/blob/GET-by-port/src/http_get.erl#L68">se recibirán en un mensaje</a> con la forma</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1</pre></div></td><td class="code"><div class="highlight"><pre><span class="p">{</span><span class="nv">Pid_del_port</span><span class="p">,</span> <span class="p">{</span><span class="n">data</span><span class="p">,</span> <span class="nv">Mensaje_recibido</span><span class="p">}}</span> </pre></div> </td></tr></table> <p>Como se reciben dos, las cabeceras y el cuerpo del mensaje...</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1 2 3 4 5 6 7 8 9</pre></div></td><td class="code"><div class="highlight"><pre><span class="k">receive</span> <span class="p">{</span><span class="nv">Port</span><span class="p">,</span> <span class="p">{</span><span class="n">data</span><span class="p">,</span> <span class="nv">Headers</span><span class="p">}}</span> <span class="o">-&gt;</span> <span class="k">receive</span> <span class="p">{</span><span class="nv">Port</span><span class="p">,</span> <span class="p">{</span><span class="n">data</span><span class="p">,</span> <span class="nv">Body</span><span class="p">}}</span> <span class="o">-&gt;</span> <span class="nv">From</span> <span class="o">!</span> <span class="p">{</span><span class="n">self</span><span class="p">(),</span> <span class="p">{</span><span class="n">http_get</span><span class="p">,</span> <span class="p">{</span><span class="n">ok</span><span class="p">,</span> <span class="p">{</span><span class="mi">200</span><span class="p">,</span> <span class="n">process_headers</span><span class="p">(</span><span class="nv">Headers</span><span class="p">),</span> <span class="nv">Body</span><span class="p">}}}}</span> <span class="k">end</span> <span class="k">end</span><span class="p">,</span> </pre></div> </td></tr></table> <p>Se puede ver que el resultado se muestra en un mensaje, esto es por que está pensado para correr <a href="https://github.com/kenkeiras/EPC/blob/GET-by-port/src/http_get.erl#L64">dentro de un bucle</a> y mantener el port activo en un proceso aislado hasta que el proceso que lo haya creado se cierre, pero no es necesario que se maneje de esta forma, no hay ningún motivo por el que no debiera devolver el resultado directamente como una función “normal”, aunque ¿quizá? dé problemas al coordinar el acceso al input/output si hay varios procesos dándole uso.</p> <p>... y eso es todo, ya tenemos nuestro trozo de código en C ejecutandose desde Erlang, por supuesto al ser <strong>stdin</strong>/<strong>stdout</strong> la interfaz cualquier lenguaje puede ser usado, es una estrategia que da bastante juego :)</p> Trabajando en un repo de Debian tag:codigoparallevar.com/blog,2013-11-27:/2013/trabajando-en-un-repo-de-debian 2013-11-27T03:36:00Z kenkeiras http://codigoparallevar.com/blog/ me@codigoparallevar.com <p><strong>Actualización</strong>: Parece ser que ya lo han subido al repo oficial ^_^ , así que no tiene sentido mantener este.</p> <p>Tras pasar las últimas horas dando palos de ciego he podido montar un repo de Debian, empaquetar <a href="http://mars-game.sourceforge.net/">M.A.R.S.</a> y subirlo, la idea es hacer una recopilación de juegos libres que no estén en los repos oficiales (intentaría mandarlos ahí pero carezco de la constancia para mantenerlos y no es plan).</p> <p>Teneis el repo en <a href="http://codigoparallevar.com/debian/">codigoparallevar.com/debian/</a> y la clave pública usada para firmar es la de siempre <a href="http://codigoparallevar.com/0x453125AC.asc">0x453125AC</a></p> <p>Y ya va siendo hora de parar por hoy...</p> <p><stroke>ps: Por ahora solo soporta amd64 y no tiene permitido el listado de entradas de directorio, ya lo puliré. La configuración sería esta:</stroke></p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1 2</pre></div></td><td class="code"><div class="highlight"><pre><span class="k">deb</span> <span class="s">http://codigoparallevar.com/debian/</span> <span class="kp">unstable/$(ARCH)/</span> <span class="k">deb-src</span> <span class="s">http://codigoparallevar.com/debian/</span> <span class="kp">unstable/source/</span> </pre></div> </td></tr></table> Filtración del hostname en HTTPS tag:codigoparallevar.com/blog,2013-11-20:/2013/filtracion-del-hostname-en-https 2013-11-20T00:21:00Z kenkeiras http://codigoparallevar.com/blog/ me@codigoparallevar.com <p>Por si alguien lo dudaba, en HTTPS <strong>si</strong> se puede saber a que hostname le hace la petición un cliente sin necesidad de descifrar nada, por ejemplo una petición a una página de <a href="https://en.wikipedia.org/">https://en.wikipedia.org/</a> lleva algo como esto: <!-- more --></p> <p><img alt="Filtración del hostname en wireshark" src="http://codigoparallevar.com/blog/files/2013/11/hostname-leak.png"/></p> Editando archivos en uso tag:codigoparallevar.com/blog,2013-11-17:/2013/editando-archivos-en-uso 2013-11-17T19:58:00Z kenkeiras http://codigoparallevar.com/blog/ me@codigoparallevar.com <p>Leyendo el manual de <a href="http://linux.die.net/man/1/rsync">rsync(1)</a>, en la documentación de la opción <strong>--inplace</strong> avisa de que:</p> <blockquote> <p>In-use binaries cannot be updated (either the OS will prevent this from happening, or binaries that attempt to swap-in their data will misbehave or crash).</p> </blockquote> <p>Resulta que hace un tiempo había intentado hacer un programa que modificara su propio binario para guardar datos (sin ningún motivo concreto), pero resultaba en errores al modificar el propio archivo mientras aún estaba en uso, además es posible (en sistemas POSIX) eliminar archivos en uso. La lectura de la opción de antes encendió una bombilla, he aquí ese programa que modifica su binario para guardar un número, lo hace cargando su propio archivo en memoria, eliminando el archivo y creando uno nuevo... probablemente la localización del punto en memoria se podía hacer de una forma más sofisticada, pero es solo un programilla de prueba.</p> <p>Pueden dar warning al compilar, <a href="http://linux.die.net/man/3/memmem">memmem</a> parece que no se porta muy bien con los <a href="http://gcc.gnu.org/onlinedocs/gcc/Volatiles.html">volatile</a>, pero hace falta que esa estructura lo sea para asegurarse de que no queda modificada en las optimizaciones.</p> <p><a href="http://codigoparallevar.com/blog/files/2013/11/selfedit-unlink.c">selfedit-unlink.c</a></p> <pre class="highlight"><code class="language-bash linenums">$ gcc selfedit-unlink.c -o selfedit selfedit-unlink.c: In function ‘locate_value’: selfedit-unlink.c:58:5: warning: passing argument 3 of ‘memmem’ discards ‘volatile’ qualifier from pointer target type [enabled by default] /usr/include/string.h:382:14: note: expected ‘const void *’ but argument is of type ‘volatile char *’ $ ./selfedit Stored: 0 $ ./selfedit 7 Stored: 0 $ ./selfedit Stored: 7 $ ./selfedit 11 Stored: 7 $ ./selfedit 13 Stored: 11 $ ./selfedit Stored: 13 $</code></pre> <p>Ahora... lo complicado va a ser encontrarle un uso útil :P</p> CM sin agentes de servidor? Prueba ansible tag:codigoparallevar.com/blog,2013-11-05:/2013/cm-sin-agentes-de-servidor-prueba-ansible 2013-11-05T20:23:00Z kenkeiras http://codigoparallevar.com/blog/ me@codigoparallevar.com <p>Hace unas semanas había hechado un vistazo a algunas herramientas de <a href="https://en.wikipedia.org/wiki/Configuration_management">gestión de la onfiguración</a> como <a href="http://www.opscode.com/chef/">chef</a>, <a href="https://puppetlabs.com/">puppet</a> y <a href="https://readthedocs.org/projects/salt/">salt</a>, pero lo dejé cuando vi que requerían un servicio en el servidor donde se instalaran.</p> <p>Pues bien, resulta que este sábado, en el <a href="http://sindominio.net/hackmeeting/">hackmeeting</a> se <a href="http://sindominio.net/hackmeeting/wiki/2013/Nodos/Automatizando_el_curro_del_sysadmin_con_Ansible">habló de ansible</a>, una herramienta para este propósito escrita en python. Me perdí la charla pero hoy le heché un vistazo a <a href="http://ansibleworks.com/docs/">la página web</a></p> <blockquote> <p>Ansible is a radically simple IT orchestration engine that makes your applications and systems easier to deploy. Avoid writing scripts or custom code to deploy and update your applications— automate in a language that approaches plain English, using SSH, <strong>with no agents to install on remote systems</strong>.</p> </blockquote> <p>Eso suena muy, muy bien, ando probándolo y por ahora anda genial, quizá es lo que estabas buscando :P.</p> Detectando errores al vuelo con emacs tag:codigoparallevar.com/blog,2013-10-09:/2013/detectando-errores-al-vuelo-con-emacs 2013-10-08T23:37:00Z kenkeiras http://codigoparallevar.com/blog/ me@codigoparallevar.com <p>Los editores “clásicos” como Emacs y VIM pueden parecer cosa del pasado cuando hoy en día IDEs como NetBeans o Eclipse detectan errores en el código sin necesidad esperar a compilarlo para encontrarlo (aunque esto se de sobre todo con Java, por algún extraño motivo...), sin embargo la extensionalidad de estos editores permite replicar esto sin grandes problemas.</p> <p>Emacs incluye por defecto un “<a href="http://www.emacswiki.org/emacs/MinorMode">minor-mode</a>” llamado <a href="http://www.emacswiki.org/emacs/FlyMake">flymake</a> que permite hacerlo, aunque haya que hacer unas pequeñas configuraciones dependiendo del lenguaje, la <a href="http://www.emacswiki.org/emacs/FlyMake#toc1">Wiki de Emacs describe como hacerlo</a> para unos cuantos lenguajes.</p> <p>Pero, y si el lenguaje no está soportado, como Flex o ensamblador? La solución es sencilla, solo habrá que crear un Makefile con una entrada <em>check-syntax</em> que lance el comando adecuado sobre los archivos $(CHK_SOURCES), por ejemplo:</p> <pre class="highlight"><code class="language-makefile linenums">AS=nasm -g check-syntax: $(AS) $(CHK_SOURCES) -o /dev/null</code></pre> <p>Puede que al activar el flymake-mode, este se desactive automáticamente por que interpreta la extensión como no válida para esto, se puede añadir a la lista de permitidas con</p> <pre class="highlight"><code class="language-common-lisp linenums">(push '(&quot;\\.&lt;extensión&gt;$&quot; flymake-simple-make-init) flymake-allowed-file-name-masks) ;;; Por ejemplo, para ensamblador (push '(&quot;\\.asm$&quot; flymake-simple-make-init) flymake-allowed-file-name-masks)</code></pre> <p>Y ya podemos programar en ensamblador con los avisos en tiempo real de cualquier IDE. <img alt="Flymake sobre un archivo en ensamblador" src="http://codigoparallevar.com/blog/files/2013/10/flymake-asm.png"/></p> Detectando el lenguaje de un texto tag:codigoparallevar.com/blog,2013-10-02:/2013/detectando-el-lenguaje-de-un-texto 2013-10-02T00:00:00Z kenkeiras http://codigoparallevar.com/blog/ me@codigoparallevar.com <p>A veces puede resultar útil detectar el lenguaje de un texto, en los sistemas *NIX es habitual tener un directorio con listas de palabras habituales de varios idiomas, simplemente comparando la proporción de palabras de un texto que cae en esa lista a través de los distintos lenguajes da un número que <strong>parece</strong> bastante significativo acerca de que idioma se trata.</p> <p>Por ejemplo, probando esta aproximación sobre el texto traducido (en <a href="http://daringfireball.net/projects/markdown/">Markdown</a>, sin convertir a HTML) de la <a href="http://codigoparallevar.com/blog/2013/entrevista-de-edward-snowden-para-der-spiegel/">entrevista de Snowden para Der Spiegel</a> muestra los siguientes resultados:</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1 2 3 4 5 6 7</pre></div></td><td class="code"><div class="highlight"><pre><span class="nv">$ </span>python lang.py entrevista-de-edward-snowden-para-der-spiegel.txt entrevista-de-edward-snowden-para-der-spiegel.txt <span class="o">[</span>2341<span class="o">]</span> 58.61% spanish 51.60% galician 29.18% american-english 29.09% british-english </pre></div> </td></tr></table> <p>Hacerlo sobre el texto de la GPLv3 (en inglés) resulta en:</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1 2 3 4 5 6 7</pre></div></td><td class="code"><div class="highlight"><pre><span class="nv">$ </span>python lang.py LICENSE LICENSE <span class="o">[</span>5251<span class="o">]</span> 98.36% american-english 98.15% british-english 12.82% spanish 10.68% galician </pre></div> </td></tr></table> <p>Si bien la aproximación es muy basta, parece que el resultado es aceptable.</p> <p>El script usado para las pruebas fué este, está pensado para usar los diccionarios de "american-english", "british-english", "galician" y "spanish" pero se podría usar cualquiera, claro:</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86</pre></div></td><td class="code"><div class="highlight"><pre><span class="c">#!/usr/bin/env python</span> <span class="kn">import</span> <span class="nn">re</span> <span class="kn">import</span> <span class="nn">os</span> <span class="kn">import</span> <span class="nn">sys</span> <span class="c"># Define un color para mostrar los resultados</span> <span class="n">color</span> <span class="o">=</span> <span class="bp">True</span> <span class="k">if</span> <span class="n">color</span><span class="p">:</span> <span class="n">colorfile</span> <span class="o">=</span> <span class="s">&quot;</span><span class="se">\x1b</span><span class="s">[0;92m&quot;</span> <span class="c"># Verde</span> <span class="n">colorend</span> <span class="o">=</span> <span class="s">&quot;</span><span class="se">\x1b</span><span class="s">[0m&quot;</span> <span class="c"># Fin del color</span> <span class="k">else</span><span class="p">:</span> <span class="n">colorfile</span> <span class="o">=</span> <span class="n">colorend</span> <span class="o">=</span> <span class="s">&quot;&quot;</span> <span class="c"># Diccionarios a comprobar</span> <span class="n">dictionaries</span> <span class="o">=</span> <span class="p">[</span><span class="s">&quot;american-english&quot;</span><span class="p">,</span> <span class="s">&quot;british-english&quot;</span><span class="p">,</span> <span class="s">&quot;galician&quot;</span><span class="p">,</span> <span class="s">&quot;spanish&quot;</span><span class="p">]</span> <span class="n">path</span> <span class="o">=</span> <span class="s">&quot;/usr/share/dict&quot;</span> <span class="k">class</span> <span class="nc">LangReader</span><span class="p">:</span> <span class="n">words</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="s">r&#39;\w+&#39;</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">dicts</span><span class="p">):</span> <span class="sd">&#39;&#39;&#39;Carga los diccionarios con las palabras, una por línea, en minúsculas.&#39;&#39;&#39;</span> <span class="bp">self</span><span class="o">.</span><span class="n">dicts</span> <span class="o">=</span> <span class="p">{}</span> <span class="k">for</span> <span class="n">d</span> <span class="ow">in</span> <span class="n">dicts</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">dicts</span><span class="p">[</span><span class="n">d</span><span class="p">]</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="k">lambda</span> <span class="n">x</span><span class="p">:</span> <span class="n">x</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span><span class="o">.</span><span class="n">lower</span><span class="p">(),</span> <span class="nb">open</span><span class="p">(</span><span class="n">d</span><span class="p">,</span> <span class="s">&quot;rt&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">read</span><span class="p">()</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span><span class="o">.</span><span class="n">split</span><span class="p">(</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">get_file_props</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">f</span><span class="p">):</span> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_props</span><span class="p">(</span><span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">())</span> <span class="k">def</span> <span class="nf">get_percents</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span> <span class="sd">&#39;&#39;&#39;Devuelve el porcentaje de palabras de cada idioma.&#39;&#39;&#39;</span> <span class="n">props</span><span class="p">,</span> <span class="n">total</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_props</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> <span class="n">percents</span> <span class="o">=</span> <span class="p">{}</span> <span class="k">for</span> <span class="n">lang</span> <span class="ow">in</span> <span class="n">props</span><span class="p">:</span> <span class="n">percents</span><span class="p">[</span><span class="n">lang</span><span class="p">]</span> <span class="o">=</span> <span class="nb">round</span><span class="p">((</span><span class="nb">float</span><span class="p">(</span><span class="n">props</span><span class="p">[</span><span class="n">lang</span><span class="p">])</span> <span class="o">/</span> <span class="n">total</span><span class="p">)</span> <span class="o">*</span> <span class="mi">100</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span> <span class="k">return</span> <span class="n">percents</span> <span class="k">def</span> <span class="nf">get_props</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span> <span class="sd">&#39;&#39;&#39;Devuelve el número de palabras que se corresponde</span> <span class="sd"> con el diccionario de cada idioma.&#39;&#39;&#39;</span> <span class="n">counters</span> <span class="o">=</span> <span class="p">{}</span> <span class="n">total</span> <span class="o">=</span> <span class="mi">0</span> <span class="n">words</span> <span class="o">=</span> <span class="nb">map</span><span class="p">(</span><span class="k">lambda</span> <span class="n">w</span><span class="p">:</span> <span class="n">w</span><span class="o">.</span><span class="n">lower</span><span class="p">(),</span> <span class="bp">self</span><span class="o">.</span><span class="n">words</span><span class="o">.</span><span class="n">findall</span><span class="p">(</span><span class="n">data</span><span class="p">))</span> <span class="k">for</span> <span class="n">lang</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">dicts</span><span class="p">:</span> <span class="n">ldict</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">dicts</span><span class="p">[</span><span class="n">lang</span><span class="p">]</span> <span class="n">counter</span> <span class="o">=</span> <span class="mi">0</span> <span class="k">for</span> <span class="n">word</span> <span class="ow">in</span> <span class="n">words</span><span class="p">:</span> <span class="k">if</span> <span class="n">word</span> <span class="ow">in</span> <span class="n">ldict</span><span class="p">:</span> <span class="n">counter</span> <span class="o">+=</span> <span class="mi">1</span> <span class="n">counters</span><span class="p">[</span><span class="n">lang</span><span class="p">]</span> <span class="o">=</span> <span class="n">counter</span> <span class="k">return</span> <span class="n">counters</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">words</span><span class="p">)</span> <span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&quot;__main__&quot;</span><span class="p">:</span> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span> <span class="k">print</span> <span class="o">&gt;&gt;</span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;</span><span class="si">%s</span><span class="s"> &lt;file&gt;&quot;</span> <span class="o">%</span> <span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="nb">exit</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> <span class="n">files</span> <span class="o">=</span> <span class="nb">map</span><span class="p">(</span><span class="k">lambda</span> <span class="n">x</span><span class="p">:</span> <span class="nb">open</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="s">&quot;rt&quot;</span><span class="p">),</span> <span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">:])</span> <span class="n">os</span><span class="o">.</span><span class="n">chdir</span><span class="p">(</span><span class="n">path</span><span class="p">)</span> <span class="n">ld</span> <span class="o">=</span> <span class="n">LangReader</span><span class="p">(</span><span class="n">dictionaries</span><span class="p">)</span> <span class="n">first</span> <span class="o">=</span> <span class="bp">True</span> <span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">files</span><span class="p">:</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">first</span><span class="p">:</span> <span class="k">print</span> <span class="s">&quot;</span><span class="se">\n</span><span class="s">&quot;</span> <span class="n">props</span><span class="p">,</span> <span class="n">total</span> <span class="o">=</span> <span class="n">ld</span><span class="o">.</span><span class="n">get_file_props</span><span class="p">(</span><span class="n">f</span><span class="p">)</span> <span class="k">if</span> <span class="n">total</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span> <span class="k">print</span> <span class="s">&quot;</span><span class="si">%s%s%s</span><span class="s"> [</span><span class="si">%i</span><span class="s">]</span><span class="se">\n</span><span class="s">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">colorfile</span><span class="p">,</span> <span class="n">f</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="n">colorend</span><span class="p">,</span> <span class="n">total</span><span class="p">)</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">props</span><span class="p">,</span> <span class="k">lambda</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">:</span> <span class="n">props</span><span class="p">[</span><span class="n">x</span><span class="p">]</span><span class="o">.</span><span class="n">__cmp__</span><span class="p">(</span><span class="n">props</span><span class="p">[</span><span class="n">y</span><span class="p">]),</span> <span class="n">reverse</span> <span class="o">=</span> <span class="bp">True</span><span class="p">):</span> <span class="k">print</span> <span class="s">&quot;</span><span class="si">%5.2f%%</span><span class="s"> </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="p">((</span><span class="n">props</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">/</span> <span class="nb">float</span><span class="p">(</span><span class="n">total</span><span class="p">))</span> <span class="o">*</span> <span class="mi">100</span><span class="p">,</span> <span class="n">i</span><span class="p">)</span> <span class="k">else</span><span class="p">:</span> <span class="k">print</span> <span class="s">&quot;</span><span class="si">%s%s%s</span><span class="s"> nothing found&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">colorfile</span><span class="p">,</span> <span class="n">f</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="n">colorend</span><span class="p">)</span> <span class="n">first</span> <span class="o">=</span> <span class="bp">False</span> </pre></div> </td></tr></table> Dándole color a tcpdump tag:codigoparallevar.com/blog,2013-08-13:/2013/dandole-color-a-tcpdump 2013-08-13T18:19:00Z kenkeiras http://codigoparallevar.com/blog/ me@codigoparallevar.com <p>Hace un tiempo escribí <a href="https://www.gitorious.org/rand/candy-shell/blobs/master/src/candy-tcpdump.py">un script para colorear la salida de tcpdump</a> y convertir esa marea de carácteres en algo más fácil de leer <!-- more --></p> <p><img alt="salida por defecto de tcpdump" src="http://codigoparallevar.com/blog/files/2013/08/tcpdump.png"/></p> <p>con este script se convierte en</p> <p><img alt="salida usando el script" src="http://codigoparallevar.com/blog/files/2013/08/colordump.png"/></p> <p>Solo hay que dejarlo en un directorio en el $PATH como ejecutable (con otro nombre que no sea tcpdump), pasará todos los flags a tcpdump, y hará lo posible por colorear la salida (aunque supongo que aún habrá opciones por probar)</p> <pre class="highlight"><code class="language-python linenums">proc = subprocess.Popen([&quot;tcpdump&quot;, &quot;-l&quot;] + sys.argv[1:], bufsize=0, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)</code></pre> <p>La idea era hacer unos cuantos scripts para otros programas (el repo <a href="https://www.gitorious.org/rand/candy-shell/">está en gitorious como candy-shell</a>), pero por ahora solo contiene este script y <a href="https://www.gitorious.org/rand/candy-shell/blobs/master/src/candy-mvn.py">uno para maven</a>, con el tiempo habrá más</p> <p>... o siempre se pueden hacer pull requests ;)</p> Instalando minted, syntax highlight para LaTeX tag:codigoparallevar.com/blog,2013-07-28:/2013/instalando-minted-syntax-highlight-para-latex 2013-07-28T22:08:00Z kenkeiras http://codigoparallevar.com/blog/ me@codigoparallevar.com <p><a href="https://code.google.com/p/minted/">Minted</a> es un paquete que provee de coloreado de sintaxis en LaTeX, ya van un par de veces que tuve que instalarlo y siempre me olvido de como es, para la próxima ya está apuntado: <!-- more --></p> <p>A parte de los módulos de LaTeX, depende de <a href="http://pygments.org/">pygments</a>, instalable en los derivados de Debian con:</p> <pre class="highlight"><code class="language-bash linenums">apt-get install python-pygments</code></pre> <p>o usando <a href="https://pypi.python.org/pypi/pip">PIP</a></p> <pre class="highlight"><code class="language-bash linenums">pip install Pygments</code></pre> <p>Para instalar el própio minted, el proceso consiste en crear un directorio <strong>~/texmf/tex/latex/</strong>, en el descargamos <a href="https://github.com/gpoore/minted">el código fuente</a></p> <pre class="highlight"><code class="language-bash linenums">git clone https://github.com/gpoore/minted/</code></pre> <p>una vez ahí entramos en el subdirectorio <strong>source</strong> y ejecutamos </p> <pre class="highlight"><code class="language-bash linenums">tex mintex.ins</code></pre> <p>Minted ya está installado, pero además también depende de los siguientes paquetes:</p> <ul> <li>keyval</li> <li>fancyvrb</li> <li>xcolor</li> <li>float</li> <li>ifthen</li> <li>calc</li> <li>ifplatform</li> </ul> <p>Parece ser que el único que no incluyen las distribuciones tipo Debian de LaTeX es <a href="http://ctan.org/pkg/ifplatform">ifplatform</a>, para instalarlo hay que descargar <a href="http://ctan.org/tex-archive/macros/latex/contrib/ifplatform">del CTAN</a> el <a href="http://mirrors.ctan.org/macros/latex/contrib/ifplatform/ifplatform.dtx">ifplatform.dtx</a> e <a href="http://mirrors.ctan.org/macros/latex/contrib/ifplatform/ifplatform.ins">ifplatform.ins</a>, se introducen en un subdirectorio de <strong>~/texmf/tex/latex/</strong> (<strong>ifplatform</strong> por ejemplo) y como con minted se hace</p> <pre class="highlight"><code class="language-bash linenums">tex ifplatform.ins</code></pre> <p>Por último, ejecutaremos</p> <pre class="highlight"><code class="language-bash linenums">texhash ~/texmf/</code></pre> <p>Y ya está instalado :)</p> Cambios en Hackliza tag:codigoparallevar.com/blog,2013-07-25:/2013/cambios-en-hackliza 2013-07-25T22:00:00Z kenkeiras http://codigoparallevar.com/blog/ me@codigoparallevar.com <p><a href="http://hackliza.blogspot.com.es/2013/07/mudamonos-unha-web-e-mais-novidades.html">Mudámonos a unha web e máis novidades</a></p> Un salvapantallas simple tag:codigoparallevar.com/blog,2013-07-21:/2013/un-salvapantallas-simple 2013-07-21T20:27:00Z kenkeiras http://codigoparallevar.com/blog/ me@codigoparallevar.com <p>Tenía la intención de añadirle unos halos con un gaussian blur, pero lleva bastante tiempo parado y ya cumple su cometido.</p> <p><a href="https://gitorious.org/rand/neon-rain">En Gitorious</a> | <a href="https://github.com/kenkeiras/neon-rain">En GitHub</a></p> <p>Es algo así: <!-- more --></p> <p><img alt="imagen del salvapantallas" src="http://codigoparallevar.com/blog/files/2013/07/neon-rain.png"/></p> <p>Aunque sigo pensando que quedaría mejor de la otra forma, sería algo así</p> <p><img alt="imagen con gaussian blur" src="http://codigoparallevar.com/blog/files/2013/07/neon-rain-blur.png"/></p> Entrevista de Edward Snowden para Der Spiegel tag:codigoparallevar.com/blog,2013-07-12:/2013/entrevista-de-edward-snowden-para-der-spiegel 2013-07-12T16:36:00Z kenkeiras http://codigoparallevar.com/blog/ me@codigoparallevar.com <p>Leyendo <a href="http://darkernet.in/">darkernet.in</a> me enteré de que <a href="https://es.wikipedia.org/wiki/Edward_Snowden">Edward Snowden</a> había hecho <a href="http://www.spiegel.de/international/world/interview-with-whistleblower-edward-snowden-on-global-spying-a-910006.html">una entrevista anónima para <em>Der Spiegel</em></a> antes de que se destapara todo lo de <a href="https://en.wikipedia.org/wiki/PRISM_%28surveillance_program%29">PRISM</a>, he aquí la traducción en castellano de la versión en inglés (exceptuando el de la nota al pie nº8, los enlaces no estaban incluídos en la versión original):</p> <blockquote> <p>Poco antes de convertirse en un nombre familiar alrededor del mundo como informante, Edward Snowden respondió una exhaustiva lista de preguntas. Estas salieron de <a href="https://en.wikipedia.org/wiki/Jacob_Appelbaum">Jacob Appelbaum</a>, de 30 años, un desarrollador de cifrados y software de seguridad. Appelbaum provee de entrenamiento sobre como usar Internet de forma anónima a grupos internacionales por los derechos humanos y periodistas.</p> <p>Appelbaum se hizo ampliamente conocido por primera vez después de hablar en nombre del fundador de <a href="http://wikileaks.org/">WikiLeaks</a> <a href="https://en.wikipedia.org/wiki/Julian_Assange">Julian Assange</a> en una conferencia de hackers en Nueva York en 2010. Junto con Assange y otros co-autores, Appelbaum liberó recientemente una recopilación de entrevistas en forma de libro bajo el título <a href="http://cryptome.org/2012/11/cypherpunks-ffi.htm">"Cypherpunks: Freedom and the Future of the Internet"</a>.</p> <p>Appelbaum terminó en el radar de las autoridades americanas durante el transcurso de su inverstigación sobre las revelaciónes de WikiLeaks. Desde entoces estas han presentado órdenes legales a Twitter, Google y Sonic para entregar información sobre sus cuentas. Pero Appelbaum describe su relación con WikiLeaks como "ambigua", y explica aquí como fué capaz de plantear preguntas a Snowden.</p> <p>"A mediados de mayo, la realizadora de documentales <a href="https://en.wikipedia.org/wiki/Laura_Poitras">Laura Poitras</a> contactó conmigo", dijo Appelbaum. "Ella me dijo que estaba en contacto con una posible fuente de la <a href="https://en.wikipedia.org/wiki/Nsa">Agencia de Seguridad Nacional</a> (NSA) que había aceptado entrevistarse con ella".</p> <p>"Ella estaba en proceso de reunir preguntas y pensó que hacer algunas preguntas específicamente técnicas era una parte importante del proceso de verificación de la fuente. Uno de los objetivos era determinar si estábamos o no realmente tratando con un informante de la NSA. Estaba profundamente preocupado por una trampa del estilo de <a href="https://en.wikipedia.org/wiki/COINTELPRO">COINTELPRO</a>. Enviamos las preguntas cifradas de forma segura a nuestra fuente. No tenía conocimente de la identidad de Edward Snowden antes de que fuera revelada al mundo en Hong Kong. El tampoco sabía quien era yo. Esperaba que cuando el anonimato fuera eliminado, encontraramos a una persona de unos sesenta años."</p> <p>"Las siguientes preguntas son un extracto de una entrevista mayor que cubrió numerosos temas, varios de ellos de una naturaleza altamente técnica. Algunas de las preguntas han sido reordenadas para proveer el contexto necesario. Las preguntas se centran casi exclusivamente en las capacidades y actividades de la NSA. Es crítico entender que estas preguntas no fueron hechas en un contexto reactivo a los eventos de la última semana o incluso el último mes. Fueron hechas en un periodo relativamente calmado, cuando Snowden probablemente estaba disfrutando de sus últimos momentos en el paraiso Hawaiano -- un paraíso que abandonó para que todas las personas en el planeta pudieran entender la situación actual como el lo hace.</p> <p>"En un punto posterior, también tuve contacto directo con Edward Snowden en el que revelé my propia identidad. En ese momento, el expresó su deseo de que sus sentimiento y observaciones sobre ese tema fueran publicadas cuando pensara que el momento era el adecuado."</p> <p>Nota del editor: Los extractos siguientes han sido temados de la versión original en inglés de la entrevista. Las potenciales diferencias entre las versiones alemanas e inglesas pueden ser explicadas por el hecho de que hemos preservado la mayoría de los términos técnicos utilizados por Snowden en la transcipción. Las explicaciones sobre la terminología usada por Snowden, así como las notas del editor están provistas en forma de notas al pie.</p> <p><strong>Entrevistador</strong>: ¿Cual es la misión de la Agencia de Seguridad Nacional (NSA) -- y como es el trabajo que hace compatible con la aplicación de la ley?</p> <p><strong>Snowden</strong>: Ellos tienen la tarea de saber todo lo que tenga importancia que ocurra fuera de los Estados Unidos. Ese es un reto significativo. Cuando se le hace aparentar que no sabe todo sobre todo el mundo se hace una crisis existencial, entonces piensas que está bien doblar las reglas. Una vez que la gente de ódia por doblar las reglas, romperlas se convierte en una cuestión de supervivencia.</p> <p><strong>Entrevistador</strong>: ¿Están las autoridades alemanas o sus políticos involucrados con el sistema de vigilancia de la NSA?</p> <p><strong>Snowden</strong>: Sí, claro. Nosotros <sup>1</sup> dormimos en la misma cama que los alemanos, de la misma forma que la mayoría de los países occidentales. Por ejemplo, nosotros <sup>2</sup> les avisamos cuando alguien que queremos vuela a través de uno de sus aeropuertos (que por ejemplo, hemos descubierto a través del teléfono de la novia de un hacker sospechoso en un tercer país sin ninguna relación) -- y ellos nos lo mandan. Ellos <sup>3</sup> no piden explicaciones sobre como sabemos algo, y viceversa, para aislar sus líderes políticos del golpe de saber de lo seriamente que se viola la privacidad global.</p> <p><strong>Entrevistador</strong>: ¿Pero si los detalles de este sistema son expuestos ahora, a quién se culpará?</p> <p><strong>Snowden</strong>: ¿Frente a una corte de los EEUU? No estoy seguro de que hables en serio. Una investigación encontró la gente concreate que autorizó la escucha de millones y millones de comunicaciones, lo que debería resultar en la mayor de las sentencias en la historia del mundo, y uno de nuestros altos oficiales simplemente pidió que la investigación se detuviera. Quién "puede" ser culpado es inmaterial cuando la aplicación de la ley no se respeta. Las leyes son para vosostros, no para ellos.</p> <p><strong>Entrevistador</strong>: ¿Hace equipo la NSA con otras naciones, como Israel?</p> <p><strong>Snowden</strong>: Sí. Continuamente. La NSA tiene un enorme cuerpo responsable de esto: FAD, la junta directiva de asuntos extranjeros (Foreign Affairs Directorate).</p> <p><strong>Entrevistador</strong>: ¿Ayudó la NSA a crear <a href="https://es.wikipedia.org/wiki/Stuxnet">Stuxnet</a>? (Stuxnet es el gusando informático desplegado contra el programa nuclear iraní.)</p> <p><strong>Snowden</strong>: La NSA e Israel lo co-escribieron.</p> <p><strong>Entrevistador</strong>: ¿Cuáles son algunos de los grandes programas de vigilancia activos hoy en día y como ayudan los socios internacionales a la NSA?</p> <p><strong>Snowden</strong>: En algunos casos, los llamados "Socios de Cinco Ojos"<sup>4</sup> (<a href="https://en.wikipedia.org/wiki/UKUSA_Agreement">Five eye partners</a>) van más allá de lo que hace la propia NSA. Por ejemplo, el Cuarter General de Comunicaciones de Reino Unido tiene un sistema llamado <a href="https://en.wikipedia.org/wiki/Tempora">TEMPORA</a>. TEMPORA es el primer buffer "full-take"" de Intenet de la comunidad de inteligencia de señales que no se preocupa del tipo de los contenidos y solo presta una atención marginal al <a href="https://en.wikipedia.org/wiki/Human_Rights_Act_1998">Humans Right Act</a>. Husmea en todo, en un buffer giratorio para permitir una investigación retroactiva sin perder un solo bit. Ahora mismo el buffer puede mantener tres días de tráfico, pero esto está siendo mejorado. Tres días puede no parecer mucho, pero recuerda que no son <a href="https://en.wikipedia.org/wiki/Meta_data">metadatos</a>. "Full-take" significa que no se deja nada, e ingiere la totalidad de la capacidad de cada circuito. Si envías in solo paquete <a href="https://en.wikipedia.org/wiki/Internet_Control_Message_Protocol">ICMP</a> <sup>5</sup> y este hace su ruta a través del Reino Unido, lo tenemos. Si Descargas algo y resulta que el <a href="https://en.wikipedia.org/wiki/Content_delivery_network">CDN</a> (red de distribución de contenidos) sirve los contenidos desde el Reino Unido, lo tenemos. Si los registros médicos de tu hija enferma son procesados en un centro de llamadas en Londres … bien, ya entiendes la idea.</p> <p><strong>Entrevistador</strong>: ¿Hay alguna forma de esquivarlo?</p> <p><strong>Snowden</strong>: Como regla general, mientras tengas alguna opción, tu tráfico nunca debe pasar o comunicarse con el Reino Unido bajo ninguna circunstancia. Sus fibras son radioactivas, e incluso las "auto-fotos" (¿selfies?) de la reina al chico de la piscina son registradas.</p> <p><strong>Entrevistador</strong>: ¿Hacen la NSA y sus socios una red de recolección de datos para llamadas de teléfono, texto y datos?</p> <p><strong>Snowden</strong>: Sí, pero cuanto consiguen depende de las capacidades de los sitios de recolección individuales -- por ejemplo, algunos circuítos tienen tubos anchos pero pequeños sistemas de recolección, así que tienen que ser selectivos. Este es más un problema en la recolección de datos del otro lado del mar que domésticos <sup>6</sup>, lo que hace la recolección de datos domésticos tan terrorífica. La NSA no está limitada por problemas de electricidad, espacio y refrigaración PSC.</p> <p><strong>Entrevistador</strong>: La NSA está construyendo un nuevo centro de datos gigantesco en Utah. ¿Cual es su propósito?</p> <p><strong>Snowden</strong>: Los repositorios masivos de datos.</p> <p><strong>Entrevistador</strong>: ¿Por cuanto tiempo se almacenan los datos recojidos?</p> <p><strong>Snowden</strong>: Ahora mismo, la recolección de datos completos envejece rápidamente (unos pocos días) debido a su tamaño a menos que un analista <sup>7</sup> haya encargado un objetivo o comunicación, en ese momento la comunicación encargada es almacenada "por siempre jamás", sin tener en cuenta la política, por que siempre puedes conseguir una renuncia. Los metadatos <sup>8</sup> también envejecen, aunque más lentamente. La NSA quiere llegar a un punto donde al menos todos los metadatos son almacenados permanentemente. En la mayoría de los casos, el contenido no vale tanto como los metadatos por que siempre puedes recuperar el contenido basandote en sus metadatos o, sino, simplemente encargar la recojida permanente de todas las comunicaciones de interes futuras dado que los metadatos te dicen lo que necesitas de sus propios datos.</p> <p><strong>Entrevistador</strong>: ¿Ayudan empresas privadas a la NSA?</p> <p><strong>Snowden</strong>: Sí. La prueba definitiva de esto es lo más dificil por que la NSA considera la identidad de los colaboradores de telecomunicaciones como joyas en su corona de omnisciencia. Como regla general, las multinacionales basadas en el Reino Unido no son fiables hasta que hayan probado lo contrario. Esto es triste, por que tendrían la capacidad de proveer los mejores y más fiables servicios en el mundo si de verdad quisieran hacerlo. Para facilitar esto, las organicaciones por los derechos civiles deberían usar esta publicación para animarlos a actualizar sus contratos para incluir cláusulas que se puedan hacer cumplir indicando que no son espiadas, y que daben implementar cambios técnicos. Si ellos consiguien que al menos una que una compañía entre en su juego, puede cambiar la seguridad de las comunicaciones globales para siempre. Si no, considera comenzar esa compañía.</p> <p><strong>Entrevistador</strong>: ¿Hay compañías que rechazan cooperar con la NSA?</p> <p><strong>Snowden</strong>: También si, pero no soy consciente de ninguna lista. Esta categoría será mucho mayor si los colaboradores son castigados por los consumidores en el mercado, lo que debería ser considerada la mayor priodidad para alguien que cree en la libertad del pensamiento.</p> <p><strong>Entrevistador</strong>: ¿Que páginas web debería evitar una persona si no quiere ser un objetivo de la NSA?</p> <p><strong>Snowden</strong>: Normalmente serías elegido como objetivo basándose en, por ejemplo, el contenido de tu Facebook o tu webmail. Lo único que sé personalmente que te puede dar sin estar en el objetivo son foros jihadistas.</p> <p><strong>Entrevistador</strong>: ¿Que pasa cuando un usuario se convierte en el objetivo de la NSA?</p> <p><strong>Snowden</strong>: Que son <a href="https://en.wikipedia.org/wiki/Owned">owneados</a>. Un analista tendrá un informe diario (o programado basandose en un resumen de filtraciones anteriores) sobre que cambió en el sistema, <a href="https://en.wikipedia.org/wiki/Libpcap">PCAPs</a><sup>9</sup> de restos de datos que no fueron comprendidos por analizadores automáticos, y demás. Depende del analista hacer lo que quieran en ese momento -- la máquina del objetivo no le pertenece ya, pertenece al gobierno de los Estados Unidos.</p> <p><strong>Notas al pie</strong>:</p> <p>[1] "Nosotros" se refiera a la NSA.</p> <p>[2] "Nosotros" se refiere a la maquinaria del servicio de inteligencia delos EEUU.</p> <p>[3] "Ellos" se refiere a otras autoridades.</p> <p>[4] Los "Socios de Cinco Ojos" (Five Eye Partners) es una referencia a los servicios de inteligencia de los Estados Unidos, Gran Bretaña, Australia, Nueva Zelanda y Canada.</p> <p>[5] "ICMP" se refiere a Protocolo de Mensajes de Control de Internet (Internet Control Message Protocol). La respuesta privosta aquí por Snowden era áltamente técnica, pero claramente se refería a todos los paquetes de datos enviados a o desde Gran Bretaña.</p> <p>[6] "Doméstico" se refiere a los Estados Unidos.</p> <p>[7] En este contexto, "encargado" se refiere a la completa recolección y almacenamiento de metadatos y contenido para cualquier de los identificadores coincidentes por la NSA o sus socios.</p> <p>[8] "Metadatos" puede incluir números de teléfono, direcciones IP y tiempos de conexión entre otras cosas. La revista <a href="http://www.wired.com/">Wired</a> ofrece una sólida introducción a los <a href="http://www.wired.com/opinion/2013/06/phew-it-was-just-metadata-not-think-again/">metadatos</a>.</p> <p>[9] "PCAPS" es una abreviación del término "packet capture".</p> <p><em>Entrevista conducida por Jacob Appelbaum y Laura Poitras</em></p> </blockquote> <p>PS: también hay una copia de los artículos en <a href="http://cryptome.org/2013/07/snowden-spiegel-13-0707-en.htm">cryptome.org</a></p>