Download - C Code and the Art of Obfuscation

Transcript
Page 1: C Code and the Art of Obfuscation

C Code and the Art of Obfuscation

Lloyd MarkleFebruary 2nd, 2007

Page 2: C Code and the Art of Obfuscation

A Little background● What's C?

– C is a programming language– Designed at AT&T Bell Labs– Available on every platform– The most popular language of all time?– Kerningham & Ritchie published the first good

reference (fondly referred to as K&R C)

Page 3: C Code and the Art of Obfuscation

A Little C● Some C Syntax

● Some more...

int x, y;x = 5;y = x;printf( “x = %d, y = %d\n”, x, y );

if( x > y ) {printf( “x is bigger than y\n” );

}else {

printf( “x is not bigger than y\n” );}

int i;for( i = 0; i < 10; i++ ) {

printf( “%d\n”, i );}

Page 4: C Code and the Art of Obfuscation

A Little C Program● This...

● Outputs this...

hello world!

#include <stdio.h>int main() {

printf( “hello world!\n” );}

Page 5: C Code and the Art of Obfuscation

More Syntax

Syntax Result++i i is increased by 1i++ i is evaluated, then increasedi += 1 i = i + 1i -= 1 i = i – 1i *= 1 i = i * 1i < j 1 if i is greater than ji > j 1 if i is greater than j!( i < j ) 0 if i is greater than j

Page 6: C Code and the Art of Obfuscation

Exotic Syntax

Okay, we've some of the basics... now for some fun!

Page 7: C Code and the Art of Obfuscation

Exotic Syntax 101

This is easy...

But what about this?

int x, y;x = 5;y = ( x = 5 );

int x;x = ( 5 == 5 );

Page 8: C Code and the Art of Obfuscation

Exotic Syntax 101

Consider these...

int y;y = 5 == 4;

int x, y, i;for( i = 0, x = 0, y = 5; x++ < --y; i++ )

printf( “%d\n”, i );printf( “%d\n”, i );

int x, y;x = 5;y = ( x = 5 )++;

Page 9: C Code and the Art of Obfuscation

Exotic Syntax: Bitwise Operations● Bitwise OR

10 | 4 = ?10 | 4 = ?

Page 10: C Code and the Art of Obfuscation

Exotic Syntax: Bitwise Operations● Bitwise OR

● Think like this...

10 | 4 = ?10 | 4 = ?

10 | 4-----

1010 | 0100 -------

1010 | 0100 ------- 1110

Page 11: C Code and the Art of Obfuscation

Exotic Syntax: Bitwise Operations● Bitwise AND

10 | 4 = ?10 & 6 = ?

Page 12: C Code and the Art of Obfuscation

Exotic Syntax: Bitwise Operations● Bitwise AND

● Similarly...

10 | 4 = ?10 & 6 = ?

10 & 6-----

1010 & 0110 -------

1010 & 0110 ------- 0010

Page 13: C Code and the Art of Obfuscation

Exotic Syntax: Bitwise Operations● Shift left

10 | 4 = ?1 << 2 = ?

Page 14: C Code and the Art of Obfuscation

Exotic Syntax: Bitwise Operations● Shift left

● Think like this...

10 | 4 = ?1 << 2 = ?

0001 << 2 0100

Page 15: C Code and the Art of Obfuscation

Exotic Syntax: Bitwise Operations● Shift left (again...)

10 | 4 = ?10 << 3 = ?

Page 16: C Code and the Art of Obfuscation

Exotic Syntax: Bitwise Operations● Shift left (again...)

● Think like this...

10 | 4 = ?10 << 3 = ?

0000 1010 << 3 0101 0000

Page 17: C Code and the Art of Obfuscation
Page 18: C Code and the Art of Obfuscation

Obfuscation● What is obfuscation?

– “Obfuscate: tr.v. -cated, -cating, -cates. 1. a) To render obscure. b) To darken. 2. To confuse: his emotions obfuscated his judgment.” -- ioccc.org

– “Obfuscation refers to the concept of concealing the meaning of communication by making it more confusing and harder to interpret” -- wikipedia.org

Page 19: C Code and the Art of Obfuscation

Why Obfuscate?● Mainly to prevent reverse engineering

– Java or C# programs are easy to decompile– Obfuscated code is difficult to read– Should have no value to unauthorized users

● Fun!– The International Obfuscated C Code Contest

(IOCCC) http://www.ioccc.org/– After all, coding is an art!

Page 20: C Code and the Art of Obfuscation

How to Obfuscate● Take an easy task, make it hard!● Meaningless variable/function names● For the IOCCC you can try:

– Interesting code format– Complex C syntax

● In general be creative!

Page 21: C Code and the Art of Obfuscation

IOCCC Examples (omoikane 2006) /* ,*/ #include <time.h> #include/* _ ,o*/ <stdlib.h> #define c(C)/* - . */return ( C); /* 2004*/ #include <stdio.h>/*. Moekan "' `\b-' */ typedef/* */char p;p* u ,w [9 ][128] ,*v;typedef int _;_ R,i,N,I,A ,m,o,e [9], a[256],k [9], n[ 256];FILE*f ;_ x (_ K,_ r ,_ q){; for(; r< q ; K =(( 0xffffff) &(K>>8))^ n[255 & ( K ^u[0 + r ++ ] )]);c (K )} _ E (p*r, p*q ){ c( f = fopen (r ,q))}_ B(_ q){c( fseek (f, 0 ,q))}_ D(){c( fclose(f ))}_ C( p *q){c( 0- puts(q ) )}_/* / */main(_ t,p**z){if(t<4)c( C("<in" "file>" "\40<l" "a" "yout> " /*b9213272*/"<outfile>" ) )u=0;i=I=(E(z[1],"rb")) ?B(2)?0 : (((o =ftell (f))>=8)?(u =(p*)malloc(o))?B(0)?0:!fread(u,o,1,f):0:0)?0: D():0 ;if( !u)c(C(" bad\40input "));if(E(z[2],"rb" )){for(N=-1;256> i;n[i++] =-1 )a[ i]=0; for(i=I=0; i<o&&(R =fgetc( f))>-1;i++)++a[R] ?(R==N)?( ++I>7)?(n[ N]+1 )?0:(n [N ]=i-7):0: (N=R) |(I=1):0;A =-1;N=o+1;for(i=33;i<127;i++ )( n[i ]+ 1&&N>a[i])? N= a [A=i] :0;B(i=I=0);if(A+1)for(N=n[A]; I< 8&& (R =fgetc(f ))> -1&& i <o ;i++)(i<N||i>N+7)?(R==A)?((*w[I ] =u [i])?1:(*w[I]= 46))?(a [I++]=i):0:0:0;D();}if(I<1)c(C( " bad\40la" "yout "))for(i =0;256>(R= i);n[i++]=R)for(A=8; A >0;A --) R = ( (R&1)==0) ?(unsigned int)R>>(01):((unsigned /*kero Q' ,KSS */)R>> 1)^ 0xedb88320;m=a[I-1];a[I ]=(m <N)?(m= N+8): ++ m;for(i=00;i<I;e[i++]=0){ v=w [i]+1;for(R =33;127 >R;R++)if(R-47&&R-92 && R-(_)* w[i])*( v++)= (p)R;*v=0;}for(sprintf /*'_ G*/ (*w+1, "%0" "8x",x(R=time(i=0),m,o)^~ 0) ;i< 8;++ i)u [N+ i]=*(*w+i+1);for(*k=x(~ 0,i=0 ,*a);i>- 1; ){for (A=i;A<I;A++){u[+a [ A] ]=w[A ][e[A]] ; k [A+1]=x (k[A],a[A],a[A+1] );}if (R==k[I]) c( (E(z[3 ],"wb+"))?fwrite( /* */ u,o,1,f)?D ()|C(" \n OK."):0 :C( " \n WriteError" )) for (i =+I- 1 ;i >-1?!w[i][++ e[+ i]]:0; ) for( A=+i--; A<I;e[A++] =0); (i <I-4 )?putchar ((_ ) 46) | fflush /*' ,*/ ( stdout ): 0& 0;}c(C (" \n fail") ) /* dP' / dP pd ' ' zc */ }

Page 22: C Code and the Art of Obfuscation

IOCCC Examples (westley 1990)

char*lie;double time, me= !0XFACE,not; int rested, get, out;main(ly, die) char ly, **die ;{ signed char lotte,

dear; (char)lotte--;for(get= !me;; not){1 - out & out ;lie;{char lotte, my= dear,**let= !!me *!not+ ++die; (char*)(lie=

"The gloves are OFF this time, I detest you, snot\n\0sed GEEK!");do {not= *lie++ & 0xF00L* !me;#define love (char*)lie -love 1s *!(not= atoi(let[get -me? (char)lotte-

Page 23: C Code and the Art of Obfuscation

IOCCC Examples (tomx 2000)

#include <stdio.h>#define true

true /*:all

CC=ccPROG=tomx

false :make -f $0 $1exit 0

all: $(PROG)

%:%.c$(CC) $< -o $@

clean:rm $(PROG)

.PHONY: /* true clean */int main() {return!printf("Hello, world\n");}

Page 24: C Code and the Art of Obfuscation
Page 25: C Code and the Art of Obfuscation

Why We Love C● Consider the following...

#include <stdio.h>

int main() {printf( “hello world!\n” );

}

Page 26: C Code and the Art of Obfuscation

Why We Love C● This is equivalent...

#include <stdio.h>

int main( int argc, char **argv ) {printf( “hello world!\n” );

}

Page 27: C Code and the Art of Obfuscation

Why We Love C● And so is this...

#include <stdio.h> int main(int argc,char**argv){printf(“hello world!\n”);}

Page 28: C Code and the Art of Obfuscation

Why We Love C● And so is this...

#include <stdio.h> #define WHY_I_LOVE_C “hello world!”int main( int argc, char **argv ) {

char *x = WHY_I_LOVE_C;int i;

for( i = 0; i < 13; i++ )printf( “%c”, x[i] );

printf( “\n” );}

Page 29: C Code and the Art of Obfuscation

Why We Love C● And so is this.../* Program by Bruce Holloway, Digital Research */#include "stdio.h"#define e 3#define g (e/e)#define h ((g+e)/2)#define f (e-g-h)#define j (e*e-g)#define k (j-h)#define l(x) tab2[x]/h#define m(n,a) ((n&(a))==(a))long tab1[]={ 989L,5L,26L,0L,88319L,123L,0L,9367L };int tab2[]={ 4,6,10,14,22,26,34,38,46,58,62,74,82,86 };main(m1,s) char *s; {

int a,b,c,d,o[k],n=(int)s;if(m1==1){ char b[2*j+f-g]; main(l(h+e)+h+e,b); printf(b); }else switch(m1-=h){

case f:a=(b=(c=(d=g)<<g)<<g)<<g;return(m(n,a|c)|m(n,b)|m(n,a|d)|m(n,c|d));

case h:for(a=f;a<j;++a)if(tab1[a]&&!(tab1[a]%((long)l(n))))return(a);

case g:if(n<h)return(g);if(n<j){n-=g;c='D';o[f]=h;o[g]=f;}else{c='\r'-'\b';n-=j-g;o[f]=o[g]=g;}if((b=n)>=e)for(b=g<<g;b<n;++b)o[b]=o[b-h]+o[b-g]+c;return(o[b-g]%n+k-h);

default:if(m1-=e) main(m1-g+e+h,s+g); else *(s+g)=f;for(*s=a=f;a<e;) *s=(*s<<e)|main(h+a++,(char *)m1);

}}

Page 30: C Code and the Art of Obfuscation

Why We Love C● And so is this... but how?/* Program by Bruce Holloway, Digital Research */#include "stdio.h"#define e 3#define g (e/e)#define h ((g+e)/2)#define f (e-g-h)#define j (e*e-g)#define k (j-h)#define l(x) tab2[x]/h#define m(n,a) ((n&(a))==(a))long tab1[]={ 989L,5L,26L,0L,88319L,123L,0L,9367L };int tab2[]={ 4,6,10,14,22,26,34,38,46,58,62,74,82,86 };main(m1,s) char *s; {

int a,b,c,d,o[k],n=(int)s;if(m1==1){ char b[2*j+f-g]; main(l(h+e)+h+e,b); printf(b); }else switch(m1-=h){

case f:a=(b=(c=(d=g)<<g)<<g)<<g;return(m(n,a|c)|m(n,b)|m(n,a|d)|m(n,c|d));

case h:for(a=f;a<j;++a)if(tab1[a]&&!(tab1[a]%((long)l(n))))return(a);

case g:if(n<h)return(g);if(n<j){n-=g;c='D';o[f]=h;o[g]=f;}else{c='\r'-'\b';n-=j-g;o[f]=o[g]=g;}if((b=n)>=e)for(b=g<<g;b<n;++b)o[b]=o[b-h]+o[b-g]+c;return(o[b-g]%n+k-h);

default:if(m1-=e) main(m1-g+e+h,s+g); else *(s+g)=f;for(*s=a=f;a<e;) *s=(*s<<e)|main(h+a++,(char *)m1);

}}

Page 31: C Code and the Art of Obfuscation

IOCCC Examples (holloway 1986)

/* Program by Bruce Holloway, Digital Research */#include "stdio.h"#define e 3#define g (e/e)#define h ((g+e)/2)#define f (e-g-h)#define j (e*e-g)#define k (j-h)#define l(x) tab2[x]/h#define m(n,a) ((n&(a))==(a))long tab1[]={ 989L,5L,26L,0L,88319L,123L,0L,9367L };int tab2[]={ 4,6,10,14,22,26,34,38,46,58,62,74,82,86 };main(m1,s) char *s; {

int a,b,c,d,o[k],n=(int)s;if(m1==1){ char b[2*j+f-g]; main(l(h+e)+h+e,b); printf(b); }else switch(m1-=h){

case f:a=(b=(c=(d=g)<<g)<<g)<<g;return(m(n,a|c)|m(n,b)|m(n,a|d)|m(n,c|d));

case h:for(a=f;a<j;++a)if(tab1[a]&&!(tab1[a]%((long)l(n))))return(a);

case g:if(n<h)return(g);if(n<j){n-=g;c='D';o[f]=h;o[g]=f;}else{c='\r'-'\b';n-=j-g;o[f]=o[g]=g;}if((b=n)>=e)for(b=g<<g;b<n;++b)o[b]=o[b-h]+o[b-g]+c;return(o[b-g]%n+k-h);

default:if(m1-=e) main(m1-g+e+h,s+g); else *(s+g)=f;for(*s=a=f;a<e;) *s=(*s<<e)|main(h+a++,(char *)m1);

}}

● Let's make it a little easier...

Page 32: C Code and the Art of Obfuscation

IOCCC Examples (holloway 1986)

/* Program by Bruce Holloway, Digital Research */#include "stdio.h"#define e 3#define g (e/e)#define h ((g+e)/2)#define f (e-g-h)#define j (e*e-g)#define k (j-h)#define l(x) tab2[x]/h#define m(n,a) ((n&(a))==(a))

Page 33: C Code and the Art of Obfuscation

IOCCC Examples (holloway 1986)

/* Program by Bruce Holloway, Digital Research */#include "stdio.h"#define e 3#define g 1#define h 2#define f 0#define j 8#define k 6#define l(x) tab2[x]/h#define m(n,a) ((n&(a))==(a))

Page 34: C Code and the Art of Obfuscation

IOCCC Examples (holloway 1986)/* Program by Bruce Holloway, Digital Research */#include "stdio.h"

#define l( x ) tab2[ x ] / 2#define m( n, a ) ( ( n & (a) ) == (a) )

long tab1[] = { 989L, 5L, 26L, 0L, 88319L, 123L, 0L, 9367L };int tab2[] = { 4, 6, 10, 14, 22, 26, 34, 38, 46, 58, 62, 74, 82, 86 };

main( m1, s ) char *s; {int a, b, c, d, o[6], n = (int)s;

if( m1 == 1 ) { char b[ 15 ]; main( l( 5 ) + 5, b ); printf( b );}else {

switch ( m1 -= 2 ) {case 0:

a = ( b = ( c = ( d = 1 ) << 1 ) << 1 ) << 1;return ( m( n, a | c ) | m( n, b ) | m( n, a | d ) | m( n, c | d ) );

case 2:for( a = 0; a < 8; ++a )

if( tab1[ a ] && !( tab1[ a ] % ( (long)l( n ) ) ) ) return ( a );

case 1:if( n < 2 ) return ( 1 );if( n < 8 ) { n -= 1; c = 'D'; o[ 0 ] = 2; o[ 1 ] = 0; }else { c = '\r' - '\b'; n -= 7; o[ 0 ] = o[ 1 ] = 1; }if( ( b = n ) >= 3 )

for( b = 1 << 1; b < n; ++b ) o[ b ] = o[ b - 2 ] + o[ b - 1 ] + c;return ( o[ b - 1] % n + 4 );

default:if( m1 -= 3 ) main( m1 + 4, s + 1 ); else *( s + 1 ) = 0; for( *s = a = 0; a < 3; ) *s = ( *s << 3 ) | main( 2 + a++, (char *)m1 );

}}

}

Page 35: C Code and the Art of Obfuscation

IOCCC Examples (holloway 1986)/* Program by Bruce Holloway, Digital Research */#include "stdio.h"

#define l( x ) tab2[ x ] / 2#define m( n, a ) ( ( n & (a) ) == (a) )

long tab1[] = { 989L, 5L, 26L, 0L, 88319L, 123L, 0L, 9367L };int tab2[] = { 4, 6, 10, 14, 22, 26, 34, 38, 46, 58, 62, 74, 82, 86 };

main( m1, s ) char *s; {int a, b, c, d, o[6], n = (int)s;

if( m1 == 1 ) { char b[ 15 ]; main( l( 5 ) + 5, b ); printf( b );}else {

switch ( m1 -= 2 ) {case 0:

a = ( b = ( c = ( d = 1 ) << 1 ) << 1 ) << 1;return ( m( n, a | c ) | m( n, b ) | m( n, a | d ) | m( n, c | d ) );

case 2:for( a = 0; a < 8; ++a )

if( tab1[ a ] && !( tab1[ a ] % ( (long)l( n ) ) ) ) return ( a );

case 1:if( n < 2 ) return ( 1 );if( n < 8 ) { n -= 1; c = 'D'; o[ 0 ] = 2; o[ 1 ] = 0; }else { c = '\r' - '\b'; n -= 7; o[ 0 ] = o[ 1 ] = 1; }if( ( b = n ) >= 3 )

for( b = 1 << 1; b < n; ++b ) o[ b ] = o[ b - 2 ] + o[ b - 1 ] + c;return ( o[ b - 1] % n + 4 );

default:if( m1 -= 3 ) main( m1 + 4, s + 1 ); else *( s + 1 ) = 0; for( *s = a = 0; a < 3; ) *s = ( *s << 3 ) | main( 2 + a++, (char *)m1 );

}}

}

Page 36: C Code and the Art of Obfuscation

IOCCC Examples (holloway 1986)

/* Program by Bruce Holloway, Digital Research */#include "stdio.h"#define l( x ) tab2[ x ] / 2#define m( n, a ) ( ( n & (a) ) == (a) )long tab1[] = { 989L, 5L, 26L, 0L, 88319L, ... };int tab2[] = { 4, 6, 10, 14, 22, 26, 34, 38, ... };main( m1, s ) char *s; {

int a, b, c, d, o[6], n = (int)s;if( m1 == 1 ) {

char b[ 15 ]; main( l( 5 ) + 5, b ); printf( b );

}else {

...}

}

Page 37: C Code and the Art of Obfuscation

IOCCC Examples (holloway 1986)/* Program by Bruce Holloway, Digital Research */#include "stdio.h"

#define l( x ) tab2[ x ] / 2#define m( n, a ) ( ( n & (a) ) == (a) )

long tab1[] = { 989L, 5L, 26L, 0L, 88319L, 123L, 0L, 9367L };int tab2[] = { 4, 6, 10, 14, 22, 26, 34, 38, 46, 58, 62, 74, 82, 86 };

main( m1, s ) char *s; {int a, b, c, d, o[6], n = (int)s;

if( m1 == 1 ) { char b[ 15 ]; main( l( 5 ) + 5, b ); printf( b );}else {

switch ( m1 -= 2 ) {case 0:

a = ( b = ( c = ( d = 1 ) << 1 ) << 1 ) << 1;return ( m( n, a | c ) | m( n, b ) | m( n, a | d ) | m( n, c | d ) );

case 2:for( a = 0; a < 8; ++a )

if( tab1[ a ] && !( tab1[ a ] % ( (long)l( n ) ) ) ) return ( a );

case 1:if( n < 2 ) return ( 1 );if( n < 8 ) { n -= 1; c = 'D'; o[ 0 ] = 2; o[ 1 ] = 0; }else { c = '\r' - '\b'; n -= 7; o[ 0 ] = o[ 1 ] = 1; }if( ( b = n ) >= 3 )

for( b = 1 << 1; b < n; ++b ) o[ b ] = o[ b - 2 ] + o[ b - 1 ] + c;return ( o[ b - 1] % n + 4 );

default:if( m1 -= 3 ) main( m1 + 4, s + 1 ); else *( s + 1 ) = 0; for( *s = a = 0; a < 3; ) *s = ( *s << 3 ) | main( 2 + a++, (char *)m1 );

}}

}

Page 38: C Code and the Art of Obfuscation

IOCCC Examples (holloway 1986)switch ( m1 -= 2 ) {

case 0:a = ( b = ( c = ( d = 1 ) << 1 ) << 1 ) << 1;return ( m(n,a|c) | m(n,b) | m(n,a|d) | m(n,c|d) );

case 2:for( a = 0; a < 8; ++a )

if( tab1[ a ] && !( tab1[ a ] % ( (long)l( n ) ) ) ) return ( a );

case 1:if( n < 2 ) return ( 1 );if( n < 8 ) { n -= 1; c = 'D'; o[ 0 ] = 2; o[ 1 ] = 0; }else { c = '\r' - '\b'; n -= 7; o[ 0 ] = o[ 1 ] = 1; }if( ( b = n ) >= 3 ) for( b = 1 << 1; b < n; ++b )

o[ b ] = o[ b - 2 ] + o[ b - 1 ] + c;return ( o[ b - 1] % n + 4 );

default:if( m1 -= 3 ) main( m1 + 4, s + 1 ); else *( s + 1 ) = 0; for( *s = a = 0; a < 3; )

*s = ( *s << 3 ) | main( 2 + a++, (char *)m1 );}

Page 39: C Code and the Art of Obfuscation

IOCCC Examples (holloway 1986)default:

if( m1 -= 3 ) main( m1 + 4, s + 1 );

else *( s + 1 ) = 0;

for( *s = a = 0; a < 3; ) *s = ( *s << 3 ) | main( 2 + a++, (char *)m1 );

● Build string recursively● Each character built in three stages

Page 40: C Code and the Art of Obfuscation

String Building● Need to generate “hello world!”

Page 41: C Code and the Art of Obfuscation

String Building● Need to generate “hello world!”● But we also need a \r\n at the end.● So we need “hello world!\r\n”

Page 42: C Code and the Art of Obfuscation

String Building● Need to generate “hello world!”● But we also need a \r\n at the end.● So we need “hello world!\r\n”● But we're doing this recursively...

default:if( m1 -= 3 )

main( m1 + 4, s + 1 ); else

*( s + 1 ) = 0;

for( *s = a = 0; a < 3; ) *s = ( *s << 3 ) | main( 2 + a++, (char *)m1 );

Page 43: C Code and the Art of Obfuscation

String Building● Need to generate “hello world!”● But we also need a \r\n at the end.● So we need “hello world!\r\n”● But we're doing this recursively...

● We need “\n\r!dlrow olleh”

default:if( m1 -= 3 )

main( m1 + 4, s + 1 ); else

*( s + 1 ) = 0;

for( *s = a = 0; a < 3; ) *s = ( *s << 3 ) | main( 2 + a++, (char *)m1 );

Page 44: C Code and the Art of Obfuscation

String Building n ASCII bin0 \n 10 00010101 \r 13 00011012 ! 33 01000013 d 100 11001004 l 108 11011005 r 114 11100106 o 111 11011117 w 119 11101118 32 01000009 o 111 1101111

10 l 108 110110011 l 108 110110012 e 101 110010113 h 104 1101000

int

Page 45: C Code and the Art of Obfuscation

Generating Binary Numbersdefault:

if( m1 -= 3 ) main( m1 + 4, s + 1 );

else *( s + 1 ) = 0;

for( *s = a = 0; a < 3; ) *s = ( *s << 3 ) | main( 2 + a++, (char *)m1 );

Page 46: C Code and the Art of Obfuscation

Generating Binary Numbersdefault:

if( m1 -= 3 ) main( m1 + 4, s + 1 );

else *( s + 1 ) = 0;

for( *s = a = 0; a < 3; ) *s = ( *s << 3 ) | main( 2 + a++, (char *)m1 );

main( m1, s ) char *s; {...if( m1 == 1 ) { ... }else {

switch ( m1 -= 2 ) {case 0: ...case 1: ...case 2: ...default: ...

}}

}

Page 47: C Code and the Art of Obfuscation

String Building

n ASCII bin Case 0 Case 1 Case 20 \n 10 0001010 000 001 0101 \r 13 0001101 000 001 1012 ! 33 0100001 000 100 0013 d 100 1100100 001 100 1004 l 108 1101100 001 101 1005 r 114 1110010 001 110 0106 o 111 1101111 001 101 1117 w 119 1110111 001 110 1118 32 0100000 000 100 0009 o 111 1101111 001 101 111

10 l 108 1101100 001 101 10011 l 108 1101100 001 101 10012 e 101 1100101 001 100 10113 h 104 1101000 001 101 000

int

Page 48: C Code and the Art of Obfuscation

IOCCC Examples (holloway 1986)switch ( m1 -= 2 ) {

case 0:a = ( b = ( c = ( d = 1 ) << 1 ) << 1 ) << 1;return ( m(n,a|c) | m(n,b) | m(n,a|d) | m(n,c|d) );

case 2:for( a = 0; a < 8; ++a )

if( tab1[ a ] && !( tab1[ a ] % ( (long)l( n ) ) ) ) return ( a );

case 1:if( n < 2 ) return ( 1 );if( n < 8 ) { n -= 1; c = 'D'; o[ 0 ] = 2; o[ 1 ] = 0; }else { c = '\r' - '\b'; n -= 7; o[ 0 ] = o[ 1 ] = 1; }if( ( b = n ) >= 3 ) for( b = 1 << 1; b < n; ++b )

o[ b ] = o[ b - 2 ] + o[ b - 1 ] + c;return ( o[ b - 1] % n + 4 );

default:if( m1 -= 3 ) main( m1 + 4, s + 1 ); else *( s + 1 ) = 0; for( *s = a = 0; a < 3; )

*s = ( *s << 3 ) | main( 2 + a++, (char *)m1 );}

Page 49: C Code and the Art of Obfuscation

Case 0case 0:

a=(b=(c=(d=1)<<1)<<1)<<1;return(m(n,a|c)|m(n,b)|m(n,a|d)|m(n,c|d));

Page 50: C Code and the Art of Obfuscation

Case 0

● What are a, b, c, and d?

case 0:a=(b=(c=(d=1)<<1)<<1)<<1;return(m(n,a|c)|m(n,b)|m(n,a|d)|m(n,c|d));

Page 51: C Code and the Art of Obfuscation

Case 0case 0:

a=(b=(c=(d=1)<<1)<<1)<<1;return(m(n,a|c)|m(n,b)|m(n,a|d)|m(n,c|d));

● What are a, b, c, and d?a = 8, b = 4, c = 2, d = 1

● Why all the bitwise ORs? n 0 1 2 3 4 5 6 7 8 9 10 11 12 13

0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101Case 0 0 0 0 1 1 1 1 1 0 1 1 1 1 1

(n)2

Page 52: C Code and the Art of Obfuscation

Case 0case 0:

a=(b=(c=(d=1)<<1)<<1)<<1;return(m(n,a|c)|m(n,b)|m(n,a|d)|m(n,c|d));

● What are a, b, c, and d?a = 8, b = 4, c = 2, d = 1

● Why all the bitwise ORs?

● What is m(x,y)?

n 0 1 2 3 4 5 6 7 8 9 10 11 12 130000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101

Case 0 0 0 0 1 1 1 1 1 0 1 1 1 1 1(n)

2

#define m(n,a) ( ( n & (a) ) == (a) )

Page 53: C Code and the Art of Obfuscation

Case 1

We'll see it later

Page 54: C Code and the Art of Obfuscation

IOCCC Examples (holloway 1986)switch ( m1 -= 2 ) {

case 0:a = ( b = ( c = ( d = 1 ) << 1 ) << 1 ) << 1;return ( m(n,a|c) | m(n,b) | m(n,a|d) | m(n,c|d) );

case 2:for( a = 0; a < 8; ++a )

if( tab1[ a ] && !( tab1[ a ] % ( (long)l( n ) ) ) ) return ( a );

case 1:if( n < 2 ) return ( 1 );if( n < 8 ) { n -= 1; c = 'D'; o[ 0 ] = 2; o[ 1 ] = 0; }else { c = '\r' - '\b'; n -= 7; o[ 0 ] = o[ 1 ] = 1; }if( ( b = n ) >= 3 ) for( b = 1 << 1; b < n; ++b )

o[ b ] = o[ b - 2 ] + o[ b - 1 ] + c;return ( o[ b - 1] % n + 4 );

default:if( m1 -= 3 ) main( m1 + 4, s + 1 ); else *( s + 1 ) = 0; for( *s = a = 0; a < 3; )

*s = ( *s << 3 ) | main( 2 + a++, (char *)m1 );}

Page 55: C Code and the Art of Obfuscation

Case 2

#define l(x) tab2[x] / 2long tab1[]={ 989L, 5L, 26L, 0L, 88319L, 123L, 0L, 9367L };int tab2[]={ 4, 6, 10, 14, 22, 26, 34, 38, 46, 58, 62, 74, 82, 86 };case 2:

for( a = 0; a < 8; ++a ) if( tab1[a] && !( tab1[a] % ((long)l( n ))) )

return ( a );

Page 56: C Code and the Art of Obfuscation

Case 2

#define l(x) tab2[x] / 2long tab1[]={ 989L, 5L, 26L, 0L, 88319L, 123L, 0L, 9367L };int tab2[]={ 4, 6, 10, 14, 22, 26, 34, 38, 46, 58, 62, 74, 82, 86 };case 2:

for( a = 0; a < 8; ++a ) if( tab1[a] && !( tab1[a] % ((long)l( n ))) )

return ( a );

Page 57: C Code and the Art of Obfuscation

Case 2

#define l(x) tab2[x] / 2long tab1[]={ 989L, 5L, 26L, 0L, 88319L, 123L, 0L, 9367L };int tab2[]={ 4, 6, 10, 14, 22, 26, 34, 38, 46, 58, 62, 74, 82, 86 };

Page 58: C Code and the Art of Obfuscation

Case 2

#define l(x) tab2[x] / 2long tab1[]={ 989L, 5L, 26L, 0L, 88319L, 123L, 0L, 9367L };int tab2[]={ 4, 6, 10, 14, 22, 26, 34, 38, 46, 58, 62, 74, 82, 86 };

● Make a new tab2...

int ltab2[]={ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43 };

Page 59: C Code and the Art of Obfuscation

Case 2#define l(x) tab2[x] / 2long tab1[]={ 989L, 5L, 26L, 0L, 88319L, 123L, 0L, 9367L };int tab2[]={ 4, 6, 10, 14, 22, 26, 34, 38, 46, 58, 62, 74, 82, 86 };int ltab2[]={ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43 };case 2:

for( a = 0; a < 8; ++a ) if( tab1[a] && !( tab1[a] % ((long)ltab2[n])) )

return ( a );

Page 60: C Code and the Art of Obfuscation

Case 2

long tab1[]={ 989L, 5L, 26L, 0L, 88319L, 123L, 0L, 9367L };

● And tab1?● Anything to do here?

Page 61: C Code and the Art of Obfuscation

Case 2

long tab1[]={ 989L, 5L, 26L, 0L, 88319L, 123L, 0L, 9367L };

● And tab1?● Anything to do here?

– Notice: ● 23*43 = 989● 2*13 = 26● 7*11*31*37 = 88319● 3*41 = 123● 17*19*29 = 9367

Page 62: C Code and the Art of Obfuscation

Case 2

long tab1[]={ 23*43, 5, 2*13, 0, 7*11*31*37, 3*41, 0, 17*19*29 };int ltab2[]={ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43 };case 2:

for( a = 0; a < 8; ++a ) if( tab1[a] && !( tab1[a] % ((long)ltab2[n])) )

return ( a );

Page 63: C Code and the Art of Obfuscation

Case 2

long tab1[]={ 23*43, 5, 2*13, 0, 7*11*31*37, 3*41, 0, 17*19*29 };int ltab2[]={ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43 };case 2:

for( a = 0; a < 8; ++a ) if( tab1[a] && !( tab1[a] % ((long)ltab2[n])) )

return ( a );

● Careful inspection and we see we get the result:

n 0 1 2 3 4 5 6 7 8 9 10 11 12 13Case 2 010 101 001 100 100 010 111 111 000 111 100 100 101 000Case 2 2 5 1 4 4 2 7 7 0 7 4 4 5 0

Page 64: C Code and the Art of Obfuscation

IOCCC Examples (holloway 1986)switch ( m1 -= 2 ) {

case 0:a = ( b = ( c = ( d = 1 ) << 1 ) << 1 ) << 1;return ( m(n,a|c) | m(n,b) | m(n,a|d) | m(n,c|d) );

case 2:for( a = 0; a < 8; ++a )

if( tab1[ a ] && !( tab1[ a ] % ( (long)l( n ) ) ) ) return ( a );

case 1:if( n < 2 ) return ( 1 );if( n < 8 ) { n -= 1; c = 'D'; o[ 0 ] = 2; o[ 1 ] = 0; }else { c = '\r' - '\b'; n -= 7; o[ 0 ] = o[ 1 ] = 1; }if( ( b = n ) >= 3 ) for( b = 1 << 1; b < n; ++b )

o[ b ] = o[ b - 2 ] + o[ b - 1 ] + c;return ( o[ b - 1] % n + 4 );

default:if( m1 -= 3 ) main( m1 + 4, s + 1 ); else *( s + 1 ) = 0; for( *s = a = 0; a < 3; )

*s = ( *s << 3 ) | main( 2 + a++, (char *)m1 );}

Page 65: C Code and the Art of Obfuscation

Case 1

case 1:if( n < 2 ) return ( 1 );if( n < 8 ) {

n -= 1; c = 'D'; o[ 0 ] = 2; o[ 1 ] = 0;

}else {

c = '\r' - '\b'; n -= 7; o[ 0 ] = o[ 1 ] = 1;

}if( ( b = n ) >= 3 )

for( b = 1 << 1; b < n; ++b ) o[ b ] = o[ b - 2 ] + o[ b - 1 ] + c;

return ( o[ b - 1] % n + 4 );

● Is too hard... n Case 1 Case 10 001 11 001 12 100 43 100 44 101 55 110 66 101 57 110 68 100 49 101 5

10 101 511 101 512 100 413 101 5

Page 66: C Code and the Art of Obfuscation

Case 1

case 1:if( n < 2 ) return ( 1 );if( n < 8 ) {

n -= 1; c = 'D'; o[ 0 ] = 2; o[ 1 ] = 0;

}else {

c = '\r' - '\b'; n -= 7; o[ 0 ] = o[ 1 ] = 1;

}if( ( b = n ) >= 3 )

for( b = 1 << 1; b < n; ++b ) o[ b ] = o[ b - 2 ] + o[ b - 1 ] + c;

return ( o[ b - 1] % n + 4 );

● Is too hard... n Case 1 Case 10 001 11 001 12 100 43 100 44 101 55 110 66 101 57 110 68 100 49 101 5

10 101 511 101 512 100 413 101 5

Page 67: C Code and the Art of Obfuscation

A Masterpiece: One Last Look/* Program by Bruce Holloway, Digital Research */#include "stdio.h"#define e 3#define g (e/e)#define h ((g+e)/2)#define f (e-g-h)#define j (e*e-g)#define k (j-h)#define l(x) tab2[x]/h#define m(n,a) ((n&(a))==(a))

long tab1[]={ 989L,5L,26L,0L,88319L,123L,0L,9367L };int tab2[]={ 4,6,10,14,22,26,34,38,46,58,62,74,82,86 };

main(m1,s) char *s; {int a,b,c,d,o[k],n=(int)s;

if(m1==1){ char b[2*j+f-g]; main(l(h+e)+h+e,b); printf(b); }else switch(m1-=h){

case f:a=(b=(c=(d=g)<<g)<<g)<<g;return(m(n,a|c)|m(n,b)|m(n,a|d)|m(n,c|d));

case h:for(a=f;a<j;++a)if(tab1[a]&&!(tab1[a]%((long)l(n))))return(a);

case g:if(n<h)return(g);if(n<j){n-=g;c='D';o[f]=h;o[g]=f;}else{c='\r'-'\b';n-=j-g;o[f]=o[g]=g;}if((b=n)>=e)for(b=g<<g;b<n;++b)o[b]=o[b-h]+o[b-g]+c;return(o[b-g]%n+k-h);

default:if(m1-=e) main(m1-g+e+h,s+g); else *(s+g)=f;for(*s=a=f;a<e;) *s=(*s<<e)|main(h+a++,(char *)m1);

}}

Page 68: C Code and the Art of Obfuscation
Page 69: C Code and the Art of Obfuscation

C Code and the Art of Obfuscation● It should remain an art● Do not use in practice● Please try it at home!● IOCCC submission deadline:

February 28th, 2007Details at: www.ioccc.org

Page 70: C Code and the Art of Obfuscation

Credits and Acknowledgements● Art Contributions on slides 17, 20, 24, 49-52,

53, 55-63, 68, and 69 thanks to Asbjorn Lonvig, (used without permission)

● Special thanks to Bruce Holloway and the IOCCC

Page 71: C Code and the Art of Obfuscation

Credits and Acknowledgements● Image on slides 39-47 from www.websitehelper.com/ (used without

permission)● Image on slide 1 from www.indeutsch.com (used without permission)● Image on slide 2 from www.onlineprintworks.com (used without permission)● Image on slide 3 from www.yourhome123.com (used without permission)● Image on slide 4 from www.purrfection.com (used without permission)● Image on slide 6 from www.spectris.com (used without permission)● Image on slides 7-16 from www.germes-online.com (used without

permission)● Image on slide 18 from www.smartboxat.com (used without permission)


Top Related