无法理解混淆的C代码

时间:2012-04-11 05:01:59

标签: c obfuscation

我在http://www.cise.ufl.edu/~manuel/obfuscate/obfuscate.html(http://www.cise.ufl.edu/~manuel/obfuscate/savastio)网站上看到了这段代码。但这段代码非常疯狂。当它发生时,我无法理解发生了什么。 请帮我。让我知道每一行执行时发生了什么。 例如printf函数在那里,如果我们看到没有被称为“Enter the number”的语句。但仍然在执行它时问“Enter the number”。来自哪里。 为什么代码是这样编写的。它看起来像“n!”(虽然它意味着阶乘)。 请帮帮我。

#include <stdio.h>

#define l11l 0xFFFF
#define ll1 for
#define ll111 if
#define l1l1 unsigned
#define l111 struct
#define lll11 short
#define ll11l long
#define ll1ll putchar
#define l1l1l(l) l=malloc(sizeof(l111 llll1));l->lll1l=1-1;l->ll1l1=1-1;
#define l1ll1 *lllll++=l1ll%10000;l1ll/=10000;
#define l1lll ll111(!l1->lll1l){l1l1l(l1->lll1l);l1->lll1l->ll1l1=l1;}\
lllll=(l1=l1->lll1l)->lll;ll=1-1;
#define llll 1000




                                                     l111 llll1 {
                                                     l111 llll1 *
      lll1l,*ll1l1        ;l1l1                      lll11 lll [
      llll];};main      (){l111 llll1                *ll11,*l1l,*
      l1, *ll1l, *    malloc ( ) ; l1l1              ll11l l1ll ;
      ll11l l11,ll  ,l;l1l1 lll11 *lll1,*            lllll; ll1(l
      =1-1 ;l< 14; ll1ll("\t\"8)>l\"9!.)>vl"         [l]^'L'),++l
      );scanf("%d",&l);l1l1l(l1l) l1l1l(ll11         ) (l1=l1l)->
      lll[l1l->lll[1-1]     =1]=l11l;ll1(l11         =1+1;l11<=l;
      ++l11){l1=ll11;         lll1 = (ll1l=(         ll11=l1l))->
      lll; lllll =(            l1l=l1)->lll;         ll=(l1ll=1-1
      );ll1(;ll1l->             lll1l||l11l!=        *lll1;){l1ll
      +=l11**lll1++             ;l1ll1 ll111         (++ll>llll){
      l1lll lll1=(              ll1l =ll1l->         lll1l)->lll;
      }}ll1(;l1ll;              ){l1ll1 ll111        (++ll>=llll)
      { l1lll} } *              lllll=l11l;}
      ll1(l=(ll=1-              1);(l<llll)&&
      (l1->lll[ l]              !=l11l);++l);        ll1 (;l1;l1=
      l1->ll1l1,l=              llll){ll1(--l        ;l>=1-1;--l,
      ++ll)printf(              (ll)?((ll%19)        ?"%04d":(ll=
      19,"\n%04d")              ):"%4d",l1->         lll[l] ) ; }
                                                     ll1ll(10); }

2 个答案:

答案 0 :(得分:10)

首先,您可以正确缩进代码并删除#define导致的间接。缩进可以由GNU indent完成,gcc -E将进行预处理。假设代码在factorial.c中(这需要使用命令行):

> gcc -E factorial.c | indent > clean_factorial.c

需要注意的是,预处理步骤会将所有stdio.h转储到clean_factorial.c;但这是无关紧要的信息,因此我们应该在运行#include<stdio.h>之前注释掉/删除gcc -E。这基本上给出了:

struct llll1
{
  struct llll1 *lll1l, *ll1l1;
  unsigned short lll[1000];
};
main ()
{
  struct llll1 *ll11, *l1l, *l1, *ll1l, *malloc ();
  unsigned long l1ll;
  long l11, ll, l;
  unsigned short *lll1, *lllll;
  for (l = 1 - 1; l < 14; putchar ("\t\"8)>l\"9!.)>vl"[l] ^ 'L'), ++l);
  scanf ("%d", &l);
  l1l = malloc (sizeof (struct llll1));
  l1l->lll1l = 1 - 1;
  l1l->ll1l1 = 1 - 1;
  ll11 = malloc (sizeof (struct llll1));
  ll11->lll1l = 1 - 1;
  ll11->ll1l1 = 1 - 1;
  (l1 = l1l)->lll[l1l->lll[1 - 1] = 1] = 0xFFFF;
  for (l11 = 1 + 1; l11 <= l; ++l11)
    {
      l1 = ll11;
      lll1 = (ll1l = (ll11 = l1l))->lll;
      lllll = (l1l = l1)->lll;
      ll = (l1ll = 1 - 1);
      for (; ll1l->lll1l || 0xFFFF != *lll1;)
        {
          l1ll += l11 ** lll1++;
          *lllll++ = l1ll % 10000;
          l1ll /= 10000;
          if (++ll > 1000)
            {
              if (!l1->lll1l)
                {
                  l1->lll1l = malloc (sizeof (struct llll1));
                  l1->lll1l->lll1l = 1 - 1;
                  l1->lll1l->ll1l1 = 1 - 1;;
                  l1->lll1l->ll1l1 = l1;
                }
              lllll = (l1 = l1->lll1l)->lll;
              ll = 1 - 1;
              lll1 = (ll1l = ll1l->lll1l)->lll;
            }
        }
      for (; l1ll;)
        {
          *lllll++ = l1ll % 10000;
          l1ll /= 10000;
          if (++ll >= 1000)
            {
              if (!l1->lll1l)
                {
                  l1->lll1l = malloc (sizeof (struct llll1));
                  l1->lll1l->lll1l = 1 - 1;
                  l1->lll1l->ll1l1 = 1 - 1;;
                  l1->lll1l->ll1l1 = l1;
                }
              lllll = (l1 = l1->lll1l)->lll;
              ll = 1 - 1;
            }
        }
      *lllll = 0xFFFF;
    }
  for (l = (ll = 1 - 1); (l < 1000) && (l1->lll[l] != 0xFFFF); ++l);
  for (; l1; l1 = l1->ll1l1, l = 1000)
    {
      for (--l; l >= 1 - 1; --l, ++ll)
        printf ((ll) ? ((ll % 19) ? "%04d" : (ll =
                                              19, "\n%04d")) : "%4d",
                l1->lll[l]);
    }
  putchar (10);
}

这有点可读,我们可以做一些事情,比如重命名变量,以便我们可以轻松区分它们,即使我们还不知道它们做了什么。例如。这会将结构重命名为structure,并调用其中的指针leftright(您也可以使用编辑器中的find-replace工具执行此操作):

> sed -i 's/llll1/structure/g; s/lll1l/left/g; s/ll1l1/right/g;' clean_factorial.c

(您必须小心订单,或者lll的替换可能与lllll冲突,例如)。

还有其他一些容易做的事情:

  • 1 - 1发生了很多:用0(和1 + 1替换它,除了用2代替0替换它。)
  • 带有"\t\"8)>l\"9!.)>vl"[l] ^ 'L'的行只是沿着字符串打印每个字符后用'L'进行xor'ing(找出原因!可能有助于将putchar放入体内for循环,而不是逗号语句。)
  • putchar(10)只需打印一个新行。
  • 了解comma operator

除此之外,这只是一项艰苦的工作。您可以而且应该使用调试器之类的工具来跟踪执行流程并找出正在发生的事情。

答案 1 :(得分:2)

这是我尝试展开它,在提示逻辑上有点卡住,所以我只是将longC初始化为零,并手动打印出一个数字请求:

#include <stdio.h>

struct StructName
{
    struct StructName *structA, *structB;

    unsigned short unsignedShortArrayA[1000];
};

main ()
{
    struct StructName *structC, *structD, *structE, *structF, *malloc();

    unsigned long unsignedLongA;

    long longA, longB, longC = 0;

    unsigned short *unsignedShortA, *unsignedShortB;

    //for(longC=0; longC< 14; putchar("\t\"8)>longC\"9!.)>vl" [longC]^'longC'),++longC )
    //;

    printf("%s", "Enter a number: " );

    scanf("%d", &longC);

    structD = malloc(sizeof(struct StructName));
    structD->structA=0;
    structD->structB=0;

    structC=malloc(sizeof(struct StructName));
    structC->structA=0;
    structC->structB=0;

    (structE=structD)->unsignedShortArrayA[structD->unsignedShortArrayA[0] =1] = 0xFFFF;

    for( longA=1+1;longA<=longC;++longA)
    {
        structE=structC;
        unsignedShortA = (structF=( structC=structD))->unsignedShortArrayA;
        unsignedShortB =( structD=structE)->unsignedShortArrayA;
        longB=(unsignedLongA=0);

        for( ; structF->structA || 0xFFFF != *unsignedShortA; )
        {
            unsignedLongA+=longA**unsignedShortA++;
            *unsignedShortB++=unsignedLongA%10000;
            unsignedLongA/=10000;

            if( ++longB>1000 )
            {
                if( !structE->structA )
                {
                    structE->structA=malloc(sizeof(struct StructName));
                    structE->structA->structA=0;
                    structE->structA->structB=0;

                    structE->structA->structB=structE;
                }

                unsignedShortB=(structE=structE->structA)->unsignedShortArrayA;
                longB=0;
                unsignedShortA=( structF =structF-> structA)->unsignedShortArrayA;
            }
        }

        for( ; unsignedLongA; )
        {
            *unsignedShortB++=unsignedLongA%10000;
            unsignedLongA/=10000;

            if( ++longB>=1000 )
            {
                if( !structE->structA )
                {
                    structE->structA=malloc(sizeof(struct StructName));
                    structE->structA->structA=0;
                    structE->structA->structB=0;

                    structE->structA->structB=structE;
                }

                unsignedShortB=(structE=structE->structA)->unsignedShortArrayA;
                longB=0;
            }
        }

        * unsignedShortB=0xFFFF;
    }

    for( longC=(longB=1- 1); (longC<1000) && (structE->unsignedShortArrayA[ longC] !=0xFFFF); ++longC )
    {
        ;
    }

    for( ; structE; structE=structE->structB, longC=1000 )
    {
        for( --longC; longC>=0; --longC, ++longB)
        {
            printf( (longB)?((longB%19) ? "%04d" : (longB=19,"\n%04d") ):"%4d",structE-> unsignedShortArrayA[longC] );
        }
    }

    putchar(10);
}

编辑:稍微清理一下。