Guest User

Untitled

a guest
Feb 12th, 2013
121
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <cmath>
  2. #include <cstdarg>
  3. #include <cstdio>
  4. #include <cstdlib>
  5. #include <cstring>
  6. #include <ctime>
  7. #include <map>
  8. #include <queue>
  9. #include <set>
  10. #include <vector>
  11.  
  12. #include "libdasm.h"
  13. #include "opcode_tables.h"
  14.  
  15. typedef struct __opcode_t
  16. {
  17.    INSTRUCTION i;
  18.    char bytes[32];
  19.    BYTE *addr;
  20. } opcode_t;
  21.  
  22. typedef struct __formula_t
  23. {
  24.    BYTE *formula;
  25.    size_t size;
  26.    BYTE *entry;
  27. } formula_t;
  28.  
  29. typedef struct __font_point_t
  30. {
  31.    double x,y;
  32. } font_point_t;
  33.  
  34. typedef struct __font_line_t
  35. {
  36.    size_t from,to;
  37. } font_line_t;
  38.  
  39. typedef struct __font_t
  40. {
  41.    double rx,ry;
  42.    size_t plotsize, drawsize;
  43.    font_point_t *plot;
  44.    font_line_t *draw;
  45. } font_t;
  46.  
  47. void
  48. takeSnapshot
  49.    (std::vector<BYTE *> *snapshot, BYTE *data, size_t size)
  50. {
  51.    BYTE *buffer = (BYTE *)malloc(sizeof(BYTE)*size);
  52.    memcpy(buffer, data, size);
  53.    snapshot->push_back(buffer);
  54. }
  55.  
  56. void
  57. initSinewaveConstants
  58.    (size_t plotSize, size_t instructions, std::map<char*,double> *constants)
  59. {
  60.    unsigned int max, amp, freq;
  61.  
  62.    max = floor(sqrt((float)plotSize));
  63.    amp = (rand()+1)%(max/4)+(max/4);
  64.    freq = (rand()+1)%15+10;
  65.    (*constants)["max"] = max;
  66.    (*constants)["amp"] = amp;
  67.    (*constants)["freq"] = freq;
  68.    (*constants)["disposition"] = 0;
  69.    (*constants)["lastX"] = 0;
  70. }
  71.  
  72. double
  73. sinewaveYVal
  74.    (double x, int opSize, std::map<char*,double> *constants)
  75. {
  76.    double y, index;
  77.    unsigned int max, amp, freq, disposition;
  78.  
  79.    max = (*constants)["max"];
  80.    amp = (*constants)["amp"];
  81.    freq = (*constants)["freq"];
  82.  
  83.    /* if (((int)x-1)%max < (*constants)["lastX"])
  84.    {
  85.       disposition = fmod((rand()+1),(max-amp))-((max-amp)/2);
  86.       (*constants)["disposition"] = disposition;
  87.    }
  88.    else */ disposition = (*constants)["disposition"];
  89.  
  90.    printf("[D] %d %d\n", x, max);
  91.    fflush(stdout);
  92.    (*constants)["lastX"] = ((int)x-1)%max;
  93.  
  94.    y = floor((sin(x/freq)+1)*amp); /* plot Y */
  95.    index = (((int)x-1)%max)*max+(y+disposition);
  96.    return index;
  97. }
  98.  
  99. void
  100. initSpiralConstants
  101.    (size_t plotSize, size_t instructions, std::map<char*,double> *constants)
  102. {
  103.    double max, rate, hyp, maxrate;
  104.  
  105.    max = floor(sqrt((double)plotSize));
  106.    maxrate = (max/2.0)/(double)instructions;
  107.  
  108.    /* give us a little bit of padding */
  109.    maxrate *= 0.75;
  110.    maxrate *= 100.0;
  111.    rate = fmod((rand()+1),maxrate/2.0)+maxrate/4.0;
  112.    rate /= 100.0;
  113.    (*constants)["max"] = max;
  114.    (*constants)["rad"] = rate;
  115.    (*constants)["inst"] = instructions;
  116. }
  117.  
  118. double
  119. spiralYVal
  120.    (double x, int opSize, std::map<char*,double> *constants)
  121. {
  122.    unsigned double index;
  123.    double y, nx, rad, max;
  124.    double centerX, centerY;
  125.  
  126.    max = (*constants)["max"];
  127.    rad = (*constants)["rad"];
  128.    centerX = centerY = max/2.0;
  129.  
  130.    y = floor((x*rad)*sin(x/180.0)+centerY);
  131.    nx = floor((x*rad)*cos(x/180.0)+centerX);
  132.    index = (nx-1)*max+y;
  133.  
  134.    return index;
  135. }
  136.  
  137. /*
  138. font_t
  139. suckADickFatty
  140.    (void)
  141. {
  142.    font_t ret;
  143.    font_point_t points[] = { {
  144.    ret.rx = 3; ret.ry = 1;
  145. */
  146. typedef formula_t (*OBFUS_T)(void *, void(*)(size_t, size_t, std::map<char*,double> *),
  147.                              double (*)(double, int, std::map<char*,double> *),
  148.                              std::vector<BYTE *> *);
  149.  
  150. formula_t
  151. obfuscateByFormula
  152.    (void *func, void (*initConstants)(size_t, size_t, std::map<char*,double> *),
  153.       double (*formulaFunc)(double, int, std::map<char*,double> *),
  154.       std::vector<BYTE *> *snapshot)
  155. {
  156.    BOOL *written;
  157.    BYTE *disPtr;
  158.    BYTE *entry = NULL;
  159.    BYTE *newSection;
  160.    DWORD oldProt;
  161.    SIZE_T blocksize = 0;
  162.    SIZE_T maxPlot;
  163.    /* one-byte op-codes which take immediate arguments */
  164.    char oneByteImm[] = "\x04\x0c\x0d\x14\x15\x1c\x1d\x24\x25\x2c\x2d\x34\x35"
  165.                        "\x3c\x3d\x68\x6a\x70\x71\x72\x73\x74\x75\x76\x77\x78"
  166.                        "\x79\x7a\x7b\x7c\x7d\x7e\x7f\xca\xcd\xe3\xe6\xe7\xe8"
  167.                        "\xe9\xeb";
  168.    int x,plot,jmpSize=5; /* TODO dynamic jumps */
  169.    formula_t ret;
  170.  
  171.    std::map<BYTE *,BYTE *> jumperSources,jumperTargets,sineSources,sineTargets;
  172.    std::map<BYTE *,BYTE *>::iterator jumperIterator;
  173.    std::map<BYTE *,opcode_t> assembly;
  174.    std::map<char,char> shortToLong;
  175.    std::map<char*,double> constants;
  176.    std::queue<BYTE *> branchQueue;
  177.    std::set<BYTE *>::iterator visitedIter;
  178.    std::set<BYTE *> visited;
  179.    std::vector<BYTE *> writePointers;
  180.  
  181.    shortToLong['\xEB'] = '\xE9'; /* JMP SHORT -> JMP */
  182.  
  183.    for (int i=0x70; i<0x80; ++i)
  184.       shortToLong[(char)i] = (char)(i+0x10);
  185.  
  186.    disPtr = (BYTE *)func;
  187.    branchQueue.push(disPtr);
  188.  
  189.    /* get the instructions */
  190.    while (1)
  191.    {
  192.       INSTRUCTION i;
  193.       opcode_t op;
  194.  
  195.       get_instruction(&i, disPtr, MODE_32);
  196.       op.i = i;
  197.       op.addr = disPtr;
  198.       blocksize += i.length;
  199.  
  200.       memset(op.bytes, 0, 32);
  201.  
  202.       for (int x=0; x<op.i.length; ++x)
  203.          op.bytes[x] = disPtr[x];
  204.  
  205.       /* all functions which jump in one way or another are totally fucked
  206.        * when transposed, so we fix this here and later */
  207.       if (i.op1.type==OPERAND_TYPE_IMMEDIATE && (i.type==INSTRUCTION_TYPE_JMP
  208.          || i.type==INSTRUCTION_TYPE_JMPC || i.type==INSTRUCTION_TYPE_CALL))
  209.       {
  210.          /* convert any short jumps to long jumps-- this just makes things
  211.           * painless. */
  212.          if (op.i.immbytes == 1)
  213.          {
  214.             int opsize = (op.bytes[0] == '\xEB') ? 1 : 2;
  215.             op.i.immbytes = 4;
  216.             op.i.length += opsize+2;
  217.  
  218.             if (op.i.op1.immediate & 0x80) /* this byte is signed-- extend it */
  219.             {
  220.                op.i.op1.immediate |= 0xFFFFFF00;
  221.                *(int *)(op.bytes+opsize) = op.i.op1.immediate;
  222.             }
  223.  
  224.             op.bytes[opsize-1] = shortToLong[op.bytes[0]];
  225.  
  226.             if (opsize == 2)
  227.                op.bytes[0] = 0x0F;
  228.          }
  229.  
  230.          jumperSources[disPtr] = disPtr+i.length+i.op1.immediate;
  231.          jumperTargets[disPtr+i.length+i.op1.immediate] = disPtr;
  232.       }
  233.            
  234.       /* when we reach a return or a visited node, we've reached the end of
  235.        * this branch */
  236.       if (i.type == INSTRUCTION_TYPE_RET ||
  237.          visited.find(disPtr) != visited.end())
  238.       {
  239.          if (i.type == INSTRUCTION_TYPE_RET)
  240.          {
  241.             assembly[disPtr] = op;
  242.             visited.insert(disPtr);
  243.          }
  244.  
  245.          branchQueue.pop();
  246.  
  247.          if (branchQueue.empty())
  248.             break;
  249.          else
  250.             disPtr = branchQueue.front();
  251.  
  252.          continue;
  253.       }
  254.       else if (i.type == INSTRUCTION_TYPE_JMPC)
  255.       {
  256.          if (i.op1.type != OPERAND_TYPE_IMMEDIATE)
  257.             puts("warning: function contains unpredictable jump");
  258.          else
  259.             branchQueue.push(disPtr+i.op1.immediate+i.length);
  260.       }
  261.  
  262.       assembly[disPtr] = op;
  263.       visited.insert(disPtr);
  264.       disPtr = disPtr+i.length;
  265.  
  266.       if (i.type == INSTRUCTION_TYPE_JMP)
  267.       {
  268.          if (i.op1.type != OPERAND_TYPE_IMMEDIATE)
  269.             puts("warning: function contains unpredictable jump");
  270.          else
  271.             disPtr = disPtr+i.op1.immbytes;
  272.       }
  273.    }
  274.    /* end decompile loop */
  275.    
  276.    maxPlot = blocksize*16;
  277.    plot = sqrt((float)maxPlot); /* fuck you C++ */
  278.    newSection = (BYTE *)malloc(maxPlot);
  279.    written = (BOOL *)malloc(maxPlot*sizeof(BOOL));
  280.  
  281.    memset(written, 0, maxPlot*sizeof(BOOL));
  282.  
  283.    for (int i=0; i<maxPlot; ++i)
  284.       newSection[i] = oneByteImm[rand()%strlen(oneByteImm)];
  285.  
  286.    if (snapshot != NULL)
  287.       takeSnapshot(snapshot, newSection, maxPlot);
  288.  
  289.    x = 1;
  290.    initConstants(maxPlot, visited.size(), &constants);
  291.  
  292.    for (visitedIter=visited.begin(); visitedIter!=visited.end(); visitedIter++)
  293.    {
  294.       opcode_t op = assembly[*visitedIter];
  295.       size_t y;
  296.       int writtenFlag;
  297.       int disposition = 0;
  298.  
  299.       do
  300.       {
  301.          writtenFlag = 0;
  302.          y = (size_t)floor(formulaFunc(x,op.i.length+jmpSize,&constants));
  303.  
  304.          /* +5 is for E9+00000000 [jmp] */
  305.          for (size_t i=y; i<(y+op.i.length+jmpSize) && !writtenFlag; ++i)
  306.          {
  307.             if (i >= maxPlot) /* array overlap-- we shouldn't write. */
  308.             {
  309.                writtenFlag = 1;
  310.                break;
  311.             }
  312.             writtenFlag |= written[i];
  313.          }
  314.          ++x;
  315.       } while (writtenFlag);
  316.  
  317.       for (int i=y; i<(y+op.i.length+jmpSize); ++i)
  318.          written[i] = 1;
  319.  
  320.       /* if the address of this target exists already, fix it for later */
  321.       if (jumperSources.find(op.addr) != jumperSources.end())
  322.          sineSources[op.addr] = newSection+y;
  323.      
  324.       if (jumperTargets.find(op.addr) != jumperTargets.end())
  325.          sineTargets[op.addr] = newSection+y;
  326.  
  327.       writePointers.push_back(newSection+y);
  328.    }
  329.  
  330.    free(written);
  331.    x = 0;
  332.  
  333.    /* write the instructions and their links */
  334.    for (visitedIter=visited.begin(); visitedIter!=visited.end(); visitedIter++)
  335.    {
  336.       opcode_t op = assembly[*visitedIter];
  337.       BYTE *code,*next;
  338.       int jumpDistance = 0;
  339.  
  340.       code = writePointers[x];
  341.       memcpy(code, op.bytes, op.i.length);
  342.  
  343.       if (x != writePointers.size()-1)
  344.       {
  345.          next = writePointers[x+1];
  346.          jumpDistance = next-(code+op.i.length+5);
  347.          *(code+op.i.length) = '\xe9'; /* jmp */
  348.          *(int *)(code+op.i.length+1) = jumpDistance;
  349.       }
  350.  
  351.       ++x;
  352.    }
  353.  
  354.    if (snapshot != NULL)
  355.       takeSnapshot(snapshot, newSection, maxPlot);
  356.  
  357.    /* repair conditional jumps */
  358.    for (jumperIterator=jumperSources.begin();
  359.         jumperIterator!=jumperSources.end();
  360.         jumperIterator++)
  361.    {
  362.       BYTE *addr = jumperIterator->first;
  363.       BYTE *newSource, *newTarget;
  364.       opcode_t op;
  365.       int offset;
  366.  
  367.       op = assembly[addr];
  368.       newSource = sineSources[addr];
  369.       newTarget = jumperSources[addr];
  370.  
  371.       /* this appears to be a jump into our own section */
  372.       if (sineTargets.find(newTarget) != sineTargets.end())
  373.          newTarget = sineTargets[newTarget];
  374.  
  375.       offset = newTarget-(newSource+op.i.length);
  376.       *(int *)((newSource+op.i.length)-sizeof(int)) = offset;
  377.    }
  378.  
  379.    VirtualProtectEx(GetCurrentProcess(), newSection, maxPlot,
  380.       PAGE_EXECUTE_READWRITE, &oldProt);
  381.  
  382.    ret.formula = newSection;
  383.    ret.size = maxPlot;
  384.    ret.entry = writePointers[0];
  385.    return ret;
  386. }
  387.  
  388. void __cdecl
  389. testFunction
  390.    (void)
  391. {
  392.    int i;
  393.    unsigned int hash=0xBEEFBABE^0x80000000;
  394.  
  395.    for (i=0; i<32; ++i)
  396.    {
  397.       hash ^= rand()<<16;
  398.       hash ^= rand();
  399.    }
  400.  
  401.    while (!(hash & 0x80000000) || !(hash & 0x1))
  402.    {
  403.       if (!(hash & 0x80000000))
  404.       {
  405.          hash <<= 1;
  406.          hash ^= rand()&0xFFFF;
  407.       }
  408.  
  409.       if (!(hash & 0x1))
  410.       {
  411.          hash >>= 1;
  412.          hash ^= (rand() << 16);
  413.       }
  414.    }
  415.  
  416.    printf("0x%08X\n", hash);
  417. }
  418.  
  419. int
  420. main
  421.    (int argc, char **argv)
  422. {
  423.    formula_t sinedata;
  424.    formula_t newdata;
  425.    OBFUS_T newfunc;
  426.    std::vector<BYTE *> sineSnapshots;
  427.    std::vector<BYTE *>::iterator sineIter;
  428.    FILE *fp;
  429.    int hash = 0;
  430.    int i;
  431.    char filename[] = "Z:\\mathtroll\\formula-00000000-00000000.bin";
  432.  
  433.    srand(time(0));
  434.  
  435.    //for (i=0; i<2; ++i)
  436.    //{
  437.    puts("[+] obfuscating the obfuscator");
  438.       sinedata = obfuscateByFormula(  
  439.                                      obfuscateByFormula,
  440.                                      initSinewaveConstants,
  441.                                      sinewaveYVal,
  442.                                      // &sineSnapshots
  443.                                      NULL
  444.                  );
  445.    puts("[+] obfuscating the obfuscator with the obfuscated method");
  446.    newfunc = (OBFUS_T)sinedata.entry;
  447.    newdata = newfunc(obfuscateByFormula, initSinewaveConstants, sinewaveYVal, NULL);
  448.    free(newdata.formula);
  449.       // ((void(__cdecl *)(void))sinedata.entry)();
  450.       free(sinedata.formula);
  451.    //}
  452.    /*
  453.    sinedata = obfuscateByFormula(
  454.                                     obfuscateByFormula,
  455.                                     initSpiralConstants,
  456.                                     spiralYVal,
  457.                                     &sineSnapshots
  458.               );
  459.    free(sinedata.formula); */
  460.  
  461.    do
  462.    {
  463.       hash <<= 16;
  464.       hash |= rand();
  465.    } while ((hash & 0xFFFF0000) == 0);
  466.  
  467.    hash ^= (rand()<<16)|rand();
  468.  
  469.    snprintf((char *)(filename+strlen("Z:\\mathtroll\\formula-")), 8, "%08x", hash);
  470.  
  471.    i = 0;
  472.    for (sineIter=sineSnapshots.begin();sineIter!=sineSnapshots.end();sineIter++)
  473.    {
  474.       snprintf((char *)(filename+strlen("Z:\\mathtroll\\formula-00000000-")), 8, "%08d", i++);
  475.       fp = fopen(filename, "wb");
  476.       fwrite(*sineIter, sinedata.size, 1, fp);
  477.       fclose(fp);
  478.       free(*sineIter);
  479.    }
  480. }
RAW Paste Data