<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Mundo Geek &#187; ofuscado</title>
	<atom:link href="http://mundogeek.net/etiqueta/ofuscado/feed/" rel="self" type="application/rss+xml" />
	<link>http://mundogeek.net</link>
	<description>Mundo geek, bitácora sobre todo lo geek: software, gadgets, tecnología, internet, ...</description>
	<lastBuildDate>Wed, 08 Feb 2012 16:09:25 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Hola mundo ofuscados</title>
		<link>http://mundogeek.net/archivos/2008/02/27/hola-mundo-ofuscados/</link>
		<comments>http://mundogeek.net/archivos/2008/02/27/hola-mundo-ofuscados/#comments</comments>
		<pubDate>Wed, 27 Feb 2008 10:00:17 +0000</pubDate>
		<dc:creator>Zootropo</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[ofuscado]]></category>
		<category><![CDATA[programacion]]></category>

		<guid isPermaLink="false">http://mundogeek.net/archivos/2008/02/27/hola-mundo-ofuscados/</guid>
		<description><![CDATA[En fitzrovian.com podemos encontrar varios Hola Mundo escritos en C ofuscado. Se llama código ofuscado a aquel en el que se utilizan todos los artificios posibles para dificultar al máximo la lectura del programa, a modo de chiste, broma, y pasatiempo. A continuación he copiado cada uno de ellos, junto con una explicación de cómo [...]]]></description>
			<content:encoded><![CDATA[<p><script type="text/javascript">
var altura = 0;
var velocidad = 10;
function expandir(id) {
    var objeto = document.getElementById(id);
    objeto.style.visibility = "visible";
    objeto.style.height = "auto";
    altura += velocidad;
    if (!(altura >= 250)) {
        objeto.style.height = altura;
        window.setTimeout ("expandir();", 20);
    }
}
</script></p>
<p>En fitzrovian.com podemos encontrar varios <a href="http://www.fitzrovian.com/hello.html" title="Hola Mundo ofuscados">Hola Mundo escritos en C ofuscado</a>. Se llama código ofuscado a aquel en el que se utilizan todos los artificios posibles para dificultar al máximo la lectura del programa, a modo de chiste, broma, y pasatiempo.</p>
<p>A continuación he copiado cada uno de ellos, junto con una explicación de cómo imprime &#8220;Hello world&#8221; cada programa, explicación a la que podéis acceder pulsando sobre el botón del mismo nombre.</p>
<p>¿Cuántos podéis descifrar por vosotros mismos?</p>
<h2>hello1.c</h2>
<blockquote><pre><code>#define _________ }
#define ________ putchar
#define _______ main
#define _(a) ________(a);
#define ______ _______(){
#define __ ______ _(0x48)_(0x65)_(0x6C)_(0x6C)
#define ___ _(0x6F)_(0x2C)_(0x20)_(0x77)_(0x6F)
#define ____ _(0x72)_(0x6C)_(0x64)_(0x21)
#define _____ __ ___ ____ _________
#include&lt;stdio.h&gt;
_____</code></pre>
</blockquote>
<p><span id="more-1392"></span></p>
<input type="button" onClick="expandir('codigo1');" value="Explicación..."/>
<div id="codigo1" style="visibility:hidden;height:0;">La instrucción de preprocesador #define sirve para crear macros o &#8220;alias&#8221; en C. Es decir, algo como <code>#define x y</code> haría que se sustituyera el texto x por y en el archivo antes de ejecutarlo. Por lo tanto tras hacer las sustituciones y obviando los define que ya no necesitamos nos quedaría algo como</p>
<blockquote><pre><code>#include&lt;stdio.h&gt;
main(){
    putchar(0x48);
    putchar(0x65);
    putchar(0x6C);
    putchar(0x6C);
    putchar(0x6F);
    putchar(0x2C);
    putchar(0x20);
    putchar(0x77);
    putchar(0x6F);
    putchar(0x72);
    putchar(0x6C);
    putchar(0x64);
    putchar(0x21);
}<code></pre>
</blockquote>
<p>El método putchar no hace más que imprimir el carácter que se le pasa. Sin embargo el carácter en este caso está expresado con su código ASCII en hexadecimal.</p></div>
<h2>hello2.c</h2>
<blockquote><pre><code>#include&lt;stdio.h&gt;
main(){
    int x=0,y[14],*z=&#038;y;*(z++)=0x48;*(z++)=y[x++]+0x1D;
    *(z++)=y[x++]+0x07;*(z++)=y[x++]+0x00;*(z++)=y[x++]+0x03;
    *(z++)=y[x++]-0x43;*(z++)=y[x++]-0x0C;*(z++)=y[x++]+0x57;
    *(z++)=y[x++]-0x08;*(z++)=y[x++]+0x03;*(z++)=y[x++]-0x06;
    *(z++)=y[x++]-0x08;*(z++)=y[x++]-0x43;*(z++)=y[x]-0x21;
    x=*(--z);while(y[x]!=NULL)putchar(y[x++]);
}</code></pre>
</blockquote>
<input type="button" onClick="expandir('codigo2');" value="Explicación..."/>
<div id="codigo2" style="visibility:hidden;height:0;">Primero echemos un vistazo al código formateado:</p>
<blockquote><pre><code>#include&lt;stdio.h&gt;

main() {
    int x = 0, y[14], *z = &#038;y;

    *(z++) = 0x48;
    *(z++) = y[x++] + 0x1D;
    *(z++) = y[x++] + 0x07;
    *(z++) = y[x++] + 0x00;
    *(z++) = y[x++] + 0x03;
    *(z++) = y[x++] - 0x43;
    *(z++) = y[x++] - 0x0C;
    *(z++) = y[x++] + 0x57;
    *(z++) = y[x++] - 0x08;
    *(z++) = y[x++] + 0x03;
    *(z++) = y[x++] - 0x06;
    *(z++) = y[x++] - 0x08;
    *(z++) = y[x++] - 0x43;
    *(z++) = y[x] - 0x21;
    x = *(--z);

    while(y[x] != NULL)
        putchar(y[x++]);
}
</code></pre>
</blockquote>
<p>Como vemos tenemos una matriz 'y' en la que almacenaremos los caracteres de "hello world" y una variable 'x' que sirve como índice para recorrer la matriz e imprimir cada uno de los caracteres en un while. De nuevo se utiliza la representación en ASCII de cada caracter, sin embargo esta vez hay que lidiar con punteros (direcciones de memoria).</p>
<p>El operador &#038; sirve para obtener la dirección de memoria de una variable, mientras que el operador * sirve para referirse al contenido que se almacena en una dirección de memoria.</p>
<p>La variable z se trata de una variable de tipo puntero que almacena la dirección en la que se guarda la matriz y. Al sumar 1 a z con el operador ++ lo que estamos haciendo es aumentar la dirección de memoria en el tamaño que tiene un entero en la plataforma en la que se ejecuta el programa. Por lo tanto con <code>*(z++) = 0x48</code> lo que estamos haciendo es asignarle el caracter 0x48 (H) a la posición 1 de la matriz.</p>
<p>Para terminar de rizar el rizo los siguientes caracteres a introducir en las posiciones de la matriz se obtienen sumando y restando del valor de la posición anterior de la matriz. Por ejemplo 0x48 + 0x1D da como resultado 0x65, que es el caracter e.</p></div>
<h2>hello3.c</h2>
<blockquote><pre><code>#include&lt;stdio.h&gt;
#define __(a) goto a;
#define ___(a) putchar(a);
#define _(a,b) ___(a) __(b);
main()
{ _:__(t)a:_('r',g)b:_('$',p)
  c:_('l',f)d:_(' ',s)e:_('a',s)
  f:_('o',q)g:_('l',h)h:_('d',n)
  i:_('e',w)j:_('e',x)k:_('\n',z)
  l:_('H',l)m:_('X',i)n:_('!',k)
  o:_('z',q)p:_('q',b)q:_(',',d)
  r:_('i',l)s:_('w',v)t:_('H',j)
  u:_('a',a)v:_('o',a)w:_(')',k)
  x:_('l',c)y:_('\t',g)z:___(0x0)}
</code></pre>
</blockquote>
<input type="button" onClick="expandir('codigo3');" value="Explicación..."/>
<div id="codigo3" style="visibility:hidden;height:0;">El resultado una vez hechas las sustituciones de #define y formateado el código es el siguiente</p>
<blockquote><pre><code>#include&lt;stdio.h&gt;

main() {
    _:
        goto t;
    a:
        putchar('r');
        goto g;
    b:
        putchar('$');
        goto p;
    c:
        putchar('l');
        goto f;
    d:
        putchar(' ');
        goto s;
    e:
        putchar('a');
        goto s;
    f:
        putchar('o');
        goto q;
    g:
        putchar('l');
        goto h;
    h:
        putchar('d');
        goto n;
    i:
        putchar('e');
        goto w;
    j:
        putchar('e');
        goto x;
    k:
        putchar('\n');
        goto z;
    l:
        putchar('H');
        goto l;
    m:
        putchar('X');
        goto i;
    n:
        putchar('!');
        goto k;
    o:
        putchar('z');
        goto q;
    p:
        putchar('q');
        goto b;
    q:
        putchar(',');
        goto d;
    r:
        putchar('i');
        goto l;
    s:
        putchar('w');
        goto v;
    t:
        putchar('H');
        goto j;
    u:
        putchar('a');
        goto a;
    v:
        putchar('o');
        goto a;
    w:
        putchar(')');
        goto k;
    x:
        putchar('l');
        goto c;
    y:
        putchar('\t');
        goto g;
    z:
       putchar(0x0);
}
</code></pre>
</blockquote>
<p>Este "puzzle" se basa en las etiquetas y los goto. Las etiquetas se parecen a los procedimientos en tanto que permiten asociar un nombre a un fragmento de código, que podemos ejecutar mediante goto. </p>
<p>Lo primero con lo que nos encontraríamos es un <code>goto t</code> por lo que saltaríamos a ejecutar el código definido en esa etiqueta: la impresión del caracter H y un salto a j, donde a su vez se imprime el caracter e y se salta a x. Y asi sucesivamente.</div>
<h2>hello4.c</h2>
<blockquote><pre><code>int n[]={0x48,
0x65,0x6C,0x6C,
0x6F,0x2C,0x20,
0x77,0x6F,0x72,
0x6C,0x64,0x21,
0x0A,0x00},*m=n;
main(n){putchar
(*m)!='\0'?main
(m++):exit(n++);}
</code></pre>
</blockquote>
<input type="button" onClick="expandir('codigo4');" value="Explicación..."/>
<div id="codigo4" style="visibility:hidden;height:0;">Este es el código en un formato menos enrevesado.</p>
<blockquote><pre><code>
int n[] = {0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x2C, 0x20,
           0x77, 0x6F, 0x72, 0x6C, 0x64, 0x21, 0x0A,
           0x00}, *m = n;
main(n) {
    putchar(*m) != '\0' ? main(m++) : exit(n++);
}</code></pre>
</blockquote>
<p>Como vemos n es una matriz con los caracteres de "Hello, world!" y m un puntero a n. Cada vez que se ejecuta main se imprime el caracter al que apunta m. Además se comprueba si el caracter es '\0', es decir, el final de la cadena. Si se cumple la condición hemos terminado, en caso contrario, se llama a main aumentando en 1 el puntero, es decir, apuntando al próximo caracter de la matriz.</p></div>
<h2>hello5.c</h2>
<blockquote><pre><code>
main(){int i,n[]={(((1&lt;&lt;1)&lt;&lt;(1&lt;&lt;1)&lt;&lt;(1&lt;&lt;
1)&lt;&lt;(1&lt;&lt;(1&gt;&gt;1)))+((1&lt;&lt;1)&lt;&lt;(1&lt;&lt;1))), (((1
&lt;&lt;1)&lt;&lt;(1&lt;&lt;1)&lt;&lt;(1&lt;&lt;1)&lt;&lt;(1&lt;&lt;1))-((1&lt;&lt;1)&lt;&lt;(
1&lt;&lt;1)&lt;&lt;(1&lt;&lt;1))+((1&lt;&lt;1)&lt;&lt;(1&lt;&lt;(1&gt;&gt;1)))+ (1
&lt;&lt;(1&gt;&gt;1))),(((1&lt;&lt;1)&lt;&lt;(1&lt;&lt;1)&lt;&lt;(1&lt;&lt;1)&lt;&lt; (1
&lt;&lt;1))-((1&lt;&lt;1)&lt;&lt;(1&lt;&lt;1)&lt;&lt;(1&lt;&lt;(1&gt;&gt;1)))- ((1
&lt;&lt;1)&lt;&lt;(1&lt;&lt;(1&gt;&gt;1)))),(((1&lt;&lt;1)&lt;&lt;(1&lt;&lt;1)&lt;&lt;(1
&lt;&lt;1)&lt;&lt;(1&lt;&lt;1))-((1&lt;&lt;1)&lt;&lt;(1&lt;&lt;1)&lt;&lt;(1&lt;&lt;(1&gt;&gt;1
)))-((1&lt;&lt;1)&lt;&lt;(1&lt;&lt;(1&gt;&gt;1)))),(((1&lt;&lt;1)&lt;&lt; (1
&lt;&lt;1)&lt;&lt;(1&lt;&lt;1)&lt;&lt;(1&lt;&lt;1))-((1&lt;&lt;1)&lt;&lt;(1&lt;&lt;1)&lt;&lt;(
1&lt;&lt;(1&gt;&gt;1)))-(1&lt;&lt;(1&gt;&gt;1))),(((1&lt;&lt;1)&lt;&lt;(1&lt;&lt;1
)&lt;&lt;(1&lt;&lt;1))+((1&lt;&lt;1)&lt;&lt;(1&lt;&lt;1)&lt;&lt;(1&lt;&lt;(1&gt;&gt;1)))
-((1&lt;&lt;1)&lt;&lt;(1&lt;&lt;(1&gt;&gt;1)))),((1&lt;&lt;1)&lt;&lt; (1&lt;&lt;1)
&lt;&lt;(1&lt;&lt;1)),(((1&lt;&lt;1)&lt;&lt;(1&lt;&lt;1)&lt;&lt;(1&lt;&lt;1)&lt;&lt;(1&lt;&lt;
1))-((1&lt;&lt;1)&lt;&lt;(1&lt;&lt;1))-(1&lt;&lt;(1&gt;&gt;1))),(((1&lt;&lt;
1)&lt;&lt;(1&lt;&lt;1)&lt;&lt;(1&lt;&lt;1)&lt;&lt;(1&lt;&lt;1))-((1&lt;&lt;1)&lt;&lt; (1
&lt;&lt;1)&lt;&lt;(1&lt;&lt;(1&gt;&gt;1)))-(1&lt;&lt;(1&gt;&gt;1))), (((1&lt;&lt;1
)&lt;&lt;(1&lt;&lt;1)&lt;&lt;(1&lt;&lt;1)&lt;&lt;(1&lt;&lt;1))- ((1&lt;&lt;1)&lt;&lt; (1
&lt;&lt;1)&lt;&lt;(1&lt;&lt;(1&gt;&gt;1)))+(1&lt;&lt;1)), (((1&lt;&lt;1)&lt;&lt; (
1&lt;&lt;1)&lt;&lt;(1&lt;&lt;1)&lt;&lt; (1&lt;&lt;1))-((1&lt;&lt;1)&lt;&lt; (1&lt;&lt;1)
&lt;&lt;(1&lt;&lt;(1&gt;&gt;1)))-((1&lt;&lt;1) &lt;&lt;(1&lt;&lt; (1&gt;&gt;1)))),
(((1&lt;&lt;1)&lt;&lt; (1&lt;&lt;1)&lt;&lt;(1&lt;&lt;1)&lt;&lt; (1&lt;&lt;1))- ((1
&lt;&lt;1)&lt;&lt;(1&lt;&lt;1)&lt;&lt;(1&lt;&lt;1))+((1&lt;&lt;1)&lt;&lt; (1&lt;&lt;(1&gt;&gt;
1)))), (((1&lt;&lt;1)&lt;&lt;(1&lt;&lt;1) &lt;&lt;(1&lt;&lt;1))+(1&lt;&lt;(1
&gt;&gt;1))),(((1&lt;&lt;1)&lt;&lt;(1&lt;&lt;1))+((1&lt;&lt;1)&lt;&lt; (1&lt;&lt;(
1&gt;&gt;1))) + (1&lt;&lt; (1&gt;&gt;1)))}; for(i=(1&gt;&gt;1);i
&lt;(((1&lt;&lt;1) &lt;&lt;(1&lt;&lt;1))+((1 &lt;&lt;1)&lt;&lt; (1&lt;&lt;(1&gt;&gt;1
))) + (1&lt;&lt;1)); i++) printf("%c",n[i]); }</code></pre>
</blockquote>
<input type="button" onClick="expandir('codigo5');" value="Explicación..."/>
<div id="codigo5" style="visibility:hidden;height:0;">En este ejemplo los caracteres se obtienen haciendo desplazamiento de bits. Por último tenemos un for que imprime los caracteres.</div>
<h2>hello6.c</h2>
<blockquote><pre><code>#include &lt;stdio.h&gt;
#define _(_) putchar(_);
int main(void){int i = 0;_(
++++++++++++++++++++++++++++
++++++++++++++++++++++++++++
++++++++++++++++++++++++++++
++++++++++++++++++++++++++++
++++++++++++++++++++++++++++
++++i)_(++++++++++++++++++++
++++++++++++++++++++++++++++
++++++++++i)_(++++++++++++++
i)_(--++i)_(++++++i)_(------
----------------------------
----------------------------
----------------------------
----------------------------
----------------i)_(--------
----------------i)_(++++++++
++++++++++++++++++++++++++++
++++++++++++++++++++++++++++
++++++++++++++++++++++++++++
++++++++++++++++++++++++++++
++++++++++++++++++++++++++++
++++++++++++++++++++++++++i)
_(----------------i)_(++++++
i)_(------------i)_(--------
--------i)_(----------------
----------------------------
----------------------------
----------------------------
----------------------------
------i)_(------------------
----------------------------
i)return i;}
</code></pre>
</blockquote>
<input type="button" onClick="expandir('codigo6');" value="Explicación..."/>
<div id="codigo6" style="visibility:hidden;height:0;">Este ejemplo, tras hacer las sustituciones correspondientes queda reducido a un cierto número de llamadas a putchar cuyos parámetros se calculan mediante el operador -- y ++ sobre la variable i. En el primer putchar, por ejemplo, nos encontrarmos con 144 caracteres '+' seguidos de una i, o lo que es lo mismo 72 veces el operador '++' seguido de una i, lo que no haría otra cosa que sumar 1 a i 72 veces obteniendo el entero correspondiente a H en ASCII.</div>
]]></content:encoded>
			<wfw:commentRss>http://mundogeek.net/archivos/2008/02/27/hola-mundo-ofuscados/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
	</channel>
</rss>

