Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <cmath>
- #include <cstdarg>
- #include <cstdio>
- #include <cstdlib>
- #include <cstring>
- #include <ctime>
- #include <map>
- #include <queue>
- #include <set>
- #include <vector>
- #include "libdasm.h"
- #include "opcode_tables.h"
- typedef struct __opcode_t
- {
- INSTRUCTION i;
- char bytes[32];
- BYTE *addr;
- } opcode_t;
- typedef struct __formula_t
- {
- BYTE *formula;
- size_t size;
- BYTE *entry;
- } formula_t;
- typedef struct __font_point_t
- {
- double x,y;
- } font_point_t;
- typedef struct __font_line_t
- {
- size_t from,to;
- } font_line_t;
- typedef struct __font_t
- {
- double rx,ry;
- size_t plotsize, drawsize;
- font_point_t *plot;
- font_line_t *draw;
- } font_t;
- void
- takeSnapshot
- (std::vector<BYTE *> *snapshot, BYTE *data, size_t size)
- {
- BYTE *buffer = (BYTE *)malloc(sizeof(BYTE)*size);
- memcpy(buffer, data, size);
- snapshot->push_back(buffer);
- }
- void
- initSinewaveConstants
- (size_t plotSize, size_t instructions, std::map<char*,double> *constants)
- {
- unsigned int max, amp, freq;
- max = floor(sqrt((float)plotSize));
- amp = (rand()+1)%(max/4)+(max/4);
- freq = (rand()+1)%15+10;
- (*constants)["max"] = max;
- (*constants)["amp"] = amp;
- (*constants)["freq"] = freq;
- (*constants)["disposition"] = 0;
- (*constants)["lastX"] = 0;
- }
- double
- sinewaveYVal
- (double x, int opSize, std::map<char*,double> *constants)
- {
- double y, index;
- unsigned int max, amp, freq, disposition;
- max = (*constants)["max"];
- amp = (*constants)["amp"];
- freq = (*constants)["freq"];
- /* if (((int)x-1)%max < (*constants)["lastX"])
- {
- disposition = fmod((rand()+1),(max-amp))-((max-amp)/2);
- (*constants)["disposition"] = disposition;
- }
- else */ disposition = (*constants)["disposition"];
- printf("[D] %d %d\n", x, max);
- fflush(stdout);
- (*constants)["lastX"] = ((int)x-1)%max;
- y = floor((sin(x/freq)+1)*amp); /* plot Y */
- index = (((int)x-1)%max)*max+(y+disposition);
- return index;
- }
- void
- initSpiralConstants
- (size_t plotSize, size_t instructions, std::map<char*,double> *constants)
- {
- double max, rate, hyp, maxrate;
- max = floor(sqrt((double)plotSize));
- maxrate = (max/2.0)/(double)instructions;
- /* give us a little bit of padding */
- maxrate *= 0.75;
- maxrate *= 100.0;
- rate = fmod((rand()+1),maxrate/2.0)+maxrate/4.0;
- rate /= 100.0;
- (*constants)["max"] = max;
- (*constants)["rad"] = rate;
- (*constants)["inst"] = instructions;
- }
- double
- spiralYVal
- (double x, int opSize, std::map<char*,double> *constants)
- {
- unsigned double index;
- double y, nx, rad, max;
- double centerX, centerY;
- max = (*constants)["max"];
- rad = (*constants)["rad"];
- centerX = centerY = max/2.0;
- y = floor((x*rad)*sin(x/180.0)+centerY);
- nx = floor((x*rad)*cos(x/180.0)+centerX);
- index = (nx-1)*max+y;
- return index;
- }
- /*
- font_t
- suckADickFatty
- (void)
- {
- font_t ret;
- font_point_t points[] = { {
- ret.rx = 3; ret.ry = 1;
- */
- typedef formula_t (*OBFUS_T)(void *, void(*)(size_t, size_t, std::map<char*,double> *),
- double (*)(double, int, std::map<char*,double> *),
- std::vector<BYTE *> *);
- formula_t
- obfuscateByFormula
- (void *func, void (*initConstants)(size_t, size_t, std::map<char*,double> *),
- double (*formulaFunc)(double, int, std::map<char*,double> *),
- std::vector<BYTE *> *snapshot)
- {
- BOOL *written;
- BYTE *disPtr;
- BYTE *entry = NULL;
- BYTE *newSection;
- DWORD oldProt;
- SIZE_T blocksize = 0;
- SIZE_T maxPlot;
- /* one-byte op-codes which take immediate arguments */
- char oneByteImm[] = "\x04\x0c\x0d\x14\x15\x1c\x1d\x24\x25\x2c\x2d\x34\x35"
- "\x3c\x3d\x68\x6a\x70\x71\x72\x73\x74\x75\x76\x77\x78"
- "\x79\x7a\x7b\x7c\x7d\x7e\x7f\xca\xcd\xe3\xe6\xe7\xe8"
- "\xe9\xeb";
- int x,plot,jmpSize=5; /* TODO dynamic jumps */
- formula_t ret;
- std::map<BYTE *,BYTE *> jumperSources,jumperTargets,sineSources,sineTargets;
- std::map<BYTE *,BYTE *>::iterator jumperIterator;
- std::map<BYTE *,opcode_t> assembly;
- std::map<char,char> shortToLong;
- std::map<char*,double> constants;
- std::queue<BYTE *> branchQueue;
- std::set<BYTE *>::iterator visitedIter;
- std::set<BYTE *> visited;
- std::vector<BYTE *> writePointers;
- shortToLong['\xEB'] = '\xE9'; /* JMP SHORT -> JMP */
- for (int i=0x70; i<0x80; ++i)
- shortToLong[(char)i] = (char)(i+0x10);
- disPtr = (BYTE *)func;
- branchQueue.push(disPtr);
- /* get the instructions */
- while (1)
- {
- INSTRUCTION i;
- opcode_t op;
- get_instruction(&i, disPtr, MODE_32);
- op.i = i;
- op.addr = disPtr;
- blocksize += i.length;
- memset(op.bytes, 0, 32);
- for (int x=0; x<op.i.length; ++x)
- op.bytes[x] = disPtr[x];
- /* all functions which jump in one way or another are totally fucked
- * when transposed, so we fix this here and later */
- if (i.op1.type==OPERAND_TYPE_IMMEDIATE && (i.type==INSTRUCTION_TYPE_JMP
- || i.type==INSTRUCTION_TYPE_JMPC || i.type==INSTRUCTION_TYPE_CALL))
- {
- /* convert any short jumps to long jumps-- this just makes things
- * painless. */
- if (op.i.immbytes == 1)
- {
- int opsize = (op.bytes[0] == '\xEB') ? 1 : 2;
- op.i.immbytes = 4;
- op.i.length += opsize+2;
- if (op.i.op1.immediate & 0x80) /* this byte is signed-- extend it */
- {
- op.i.op1.immediate |= 0xFFFFFF00;
- *(int *)(op.bytes+opsize) = op.i.op1.immediate;
- }
- op.bytes[opsize-1] = shortToLong[op.bytes[0]];
- if (opsize == 2)
- op.bytes[0] = 0x0F;
- }
- jumperSources[disPtr] = disPtr+i.length+i.op1.immediate;
- jumperTargets[disPtr+i.length+i.op1.immediate] = disPtr;
- }
- /* when we reach a return or a visited node, we've reached the end of
- * this branch */
- if (i.type == INSTRUCTION_TYPE_RET ||
- visited.find(disPtr) != visited.end())
- {
- if (i.type == INSTRUCTION_TYPE_RET)
- {
- assembly[disPtr] = op;
- visited.insert(disPtr);
- }
- branchQueue.pop();
- if (branchQueue.empty())
- break;
- else
- disPtr = branchQueue.front();
- continue;
- }
- else if (i.type == INSTRUCTION_TYPE_JMPC)
- {
- if (i.op1.type != OPERAND_TYPE_IMMEDIATE)
- puts("warning: function contains unpredictable jump");
- else
- branchQueue.push(disPtr+i.op1.immediate+i.length);
- }
- assembly[disPtr] = op;
- visited.insert(disPtr);
- disPtr = disPtr+i.length;
- if (i.type == INSTRUCTION_TYPE_JMP)
- {
- if (i.op1.type != OPERAND_TYPE_IMMEDIATE)
- puts("warning: function contains unpredictable jump");
- else
- disPtr = disPtr+i.op1.immbytes;
- }
- }
- /* end decompile loop */
- maxPlot = blocksize*16;
- plot = sqrt((float)maxPlot); /* fuck you C++ */
- newSection = (BYTE *)malloc(maxPlot);
- written = (BOOL *)malloc(maxPlot*sizeof(BOOL));
- memset(written, 0, maxPlot*sizeof(BOOL));
- for (int i=0; i<maxPlot; ++i)
- newSection[i] = oneByteImm[rand()%strlen(oneByteImm)];
- if (snapshot != NULL)
- takeSnapshot(snapshot, newSection, maxPlot);
- x = 1;
- initConstants(maxPlot, visited.size(), &constants);
- for (visitedIter=visited.begin(); visitedIter!=visited.end(); visitedIter++)
- {
- opcode_t op = assembly[*visitedIter];
- size_t y;
- int writtenFlag;
- int disposition = 0;
- do
- {
- writtenFlag = 0;
- y = (size_t)floor(formulaFunc(x,op.i.length+jmpSize,&constants));
- /* +5 is for E9+00000000 [jmp] */
- for (size_t i=y; i<(y+op.i.length+jmpSize) && !writtenFlag; ++i)
- {
- if (i >= maxPlot) /* array overlap-- we shouldn't write. */
- {
- writtenFlag = 1;
- break;
- }
- writtenFlag |= written[i];
- }
- ++x;
- } while (writtenFlag);
- for (int i=y; i<(y+op.i.length+jmpSize); ++i)
- written[i] = 1;
- /* if the address of this target exists already, fix it for later */
- if (jumperSources.find(op.addr) != jumperSources.end())
- sineSources[op.addr] = newSection+y;
- if (jumperTargets.find(op.addr) != jumperTargets.end())
- sineTargets[op.addr] = newSection+y;
- writePointers.push_back(newSection+y);
- }
- free(written);
- x = 0;
- /* write the instructions and their links */
- for (visitedIter=visited.begin(); visitedIter!=visited.end(); visitedIter++)
- {
- opcode_t op = assembly[*visitedIter];
- BYTE *code,*next;
- int jumpDistance = 0;
- code = writePointers[x];
- memcpy(code, op.bytes, op.i.length);
- if (x != writePointers.size()-1)
- {
- next = writePointers[x+1];
- jumpDistance = next-(code+op.i.length+5);
- *(code+op.i.length) = '\xe9'; /* jmp */
- *(int *)(code+op.i.length+1) = jumpDistance;
- }
- ++x;
- }
- if (snapshot != NULL)
- takeSnapshot(snapshot, newSection, maxPlot);
- /* repair conditional jumps */
- for (jumperIterator=jumperSources.begin();
- jumperIterator!=jumperSources.end();
- jumperIterator++)
- {
- BYTE *addr = jumperIterator->first;
- BYTE *newSource, *newTarget;
- opcode_t op;
- int offset;
- op = assembly[addr];
- newSource = sineSources[addr];
- newTarget = jumperSources[addr];
- /* this appears to be a jump into our own section */
- if (sineTargets.find(newTarget) != sineTargets.end())
- newTarget = sineTargets[newTarget];
- offset = newTarget-(newSource+op.i.length);
- *(int *)((newSource+op.i.length)-sizeof(int)) = offset;
- }
- VirtualProtectEx(GetCurrentProcess(), newSection, maxPlot,
- PAGE_EXECUTE_READWRITE, &oldProt);
- ret.formula = newSection;
- ret.size = maxPlot;
- ret.entry = writePointers[0];
- return ret;
- }
- void __cdecl
- testFunction
- (void)
- {
- int i;
- unsigned int hash=0xBEEFBABE^0x80000000;
- for (i=0; i<32; ++i)
- {
- hash ^= rand()<<16;
- hash ^= rand();
- }
- while (!(hash & 0x80000000) || !(hash & 0x1))
- {
- if (!(hash & 0x80000000))
- {
- hash <<= 1;
- hash ^= rand()&0xFFFF;
- }
- if (!(hash & 0x1))
- {
- hash >>= 1;
- hash ^= (rand() << 16);
- }
- }
- printf("0x%08X\n", hash);
- }
- int
- main
- (int argc, char **argv)
- {
- formula_t sinedata;
- formula_t newdata;
- OBFUS_T newfunc;
- std::vector<BYTE *> sineSnapshots;
- std::vector<BYTE *>::iterator sineIter;
- FILE *fp;
- int hash = 0;
- int i;
- char filename[] = "Z:\\mathtroll\\formula-00000000-00000000.bin";
- srand(time(0));
- //for (i=0; i<2; ++i)
- //{
- puts("[+] obfuscating the obfuscator");
- sinedata = obfuscateByFormula(
- obfuscateByFormula,
- initSinewaveConstants,
- sinewaveYVal,
- // &sineSnapshots
- NULL
- );
- puts("[+] obfuscating the obfuscator with the obfuscated method");
- newfunc = (OBFUS_T)sinedata.entry;
- newdata = newfunc(obfuscateByFormula, initSinewaveConstants, sinewaveYVal, NULL);
- free(newdata.formula);
- // ((void(__cdecl *)(void))sinedata.entry)();
- free(sinedata.formula);
- //}
- /*
- sinedata = obfuscateByFormula(
- obfuscateByFormula,
- initSpiralConstants,
- spiralYVal,
- &sineSnapshots
- );
- free(sinedata.formula); */
- do
- {
- hash <<= 16;
- hash |= rand();
- } while ((hash & 0xFFFF0000) == 0);
- hash ^= (rand()<<16)|rand();
- snprintf((char *)(filename+strlen("Z:\\mathtroll\\formula-")), 8, "%08x", hash);
- i = 0;
- for (sineIter=sineSnapshots.begin();sineIter!=sineSnapshots.end();sineIter++)
- {
- snprintf((char *)(filename+strlen("Z:\\mathtroll\\formula-00000000-")), 8, "%08d", i++);
- fp = fopen(filename, "wb");
- fwrite(*sineIter, sinedata.size, 1, fp);
- fclose(fp);
- free(*sineIter);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement