Valhalla Legends Forums Archive | Advanced Programming | Self modifying code, a better way?

AuthorMessageTime
zorm
I was wondering if there is a better way to do this? Its pretty ugly right now.
[code]
typedef void (* fHashOperation)(unsigned long *, unsigned long *, unsigned long *, unsigned long);
fHashOperation HashOperation;
unsigned long oldprotect = 0;
HashOperation = (fHashOperation)malloc(64);
((unsigned char *)HashOperation)[0] = 0x55;
((unsigned char *)HashOperation)[1] = 0x8B;
((unsigned char *)HashOperation)[2] = 0xEC;
((unsigned char *)HashOperation)[3] = 0x8B;
((unsigned char *)HashOperation)[4] = 0x45;
((unsigned char *)HashOperation)[5] = 0x08;
((unsigned char *)HashOperation)[6] = 0x8B;
((unsigned char *)HashOperation)[7] = 0x08;
switch (cOperations[0]) {
case '+':
((unsigned char *)HashOperation)[8] = 0x03; //operation 1 add
break;
case '-':
((unsigned char *)HashOperation)[8] = 0x2B; //operation 1 sub
break;
case '^':
((unsigned char *)HashOperation)[8] = 0x33; //operation 1 xor
break;
default:
return 1;
}
((unsigned char *)HashOperation)[9] = 0x4D;
((unsigned char *)HashOperation)[10] = 0x14;
((unsigned char *)HashOperation)[11] = 0x8B;
((unsigned char *)HashOperation)[12] = 0x55;
((unsigned char *)HashOperation)[13] = 0x08;
((unsigned char *)HashOperation)[14] = 0x89;
((unsigned char *)HashOperation)[15] = 0x0A;
((unsigned char *)HashOperation)[16] = 0x8B;
((unsigned char *)HashOperation)[17] = 0x45;
((unsigned char *)HashOperation)[18] = 0x0C;
((unsigned char *)HashOperation)[19] = 0x8B;
((unsigned char *)HashOperation)[20] = 0x08;
((unsigned char *)HashOperation)[21] = 0x8B;
((unsigned char *)HashOperation)[22] = 0x55;
((unsigned char *)HashOperation)[23] = 0x10;
switch (cOperations[1]) {
case '+':
((unsigned char *)HashOperation)[24] = 0x03; //operation 2 add
break;
case '-':
((unsigned char *)HashOperation)[24] = 0x2B; //operation 2 sub
break;
case '^':
((unsigned char *)HashOperation)[24] = 0x33; //operation 2 xor
break;
default:
return 1;
}
((unsigned char *)HashOperation)[25] = 0x0A;
((unsigned char *)HashOperation)[26] = 0x8B;
((unsigned char *)HashOperation)[27] = 0x45;
((unsigned char *)HashOperation)[28] = 0x0C;
((unsigned char *)HashOperation)[29] = 0x89;
((unsigned char *)HashOperation)[30] = 0x08;
((unsigned char *)HashOperation)[31] = 0x8B;
((unsigned char *)HashOperation)[32] = 0x4D;
((unsigned char *)HashOperation)[33] = 0x10;
((unsigned char *)HashOperation)[34] = 0x8B;
((unsigned char *)HashOperation)[35] = 0x55;
((unsigned char *)HashOperation)[36] = 0x08;
((unsigned char *)HashOperation)[37] = 0x8B;
((unsigned char *)HashOperation)[38] = 0x01;
switch (cOperations[2]) {
case '+':
((unsigned char *)HashOperation)[39] = 0x03; //operation 3 add
break;
case '-':
((unsigned char *)HashOperation)[39] = 0x2B; //operation 3 sub
break;
case '^':
((unsigned char *)HashOperation)[39] = 0x33; //operation 3 xor
break;
default:
return 1;
}
((unsigned char *)HashOperation)[40] = 0x02;
((unsigned char *)HashOperation)[41] = 0x8B;
((unsigned char *)HashOperation)[42] = 0x4D;
((unsigned char *)HashOperation)[43] = 0x10;
((unsigned char *)HashOperation)[44] = 0x89;
((unsigned char *)HashOperation)[45] = 0x01;
((unsigned char *)HashOperation)[46] = 0x8B;
((unsigned char *)HashOperation)[47] = 0x55;
((unsigned char *)HashOperation)[48] = 0x08;
((unsigned char *)HashOperation)[49] = 0x8B;
((unsigned char *)HashOperation)[50] = 0x45;
((unsigned char *)HashOperation)[51] = 0x0C;
((unsigned char *)HashOperation)[52] = 0x8B;
((unsigned char *)HashOperation)[53] = 0x0A;
switch (cOperations[3]) {
case '+':
((unsigned char *)HashOperation)[54] = 0x03; //operation 4 add
break;
case '-':
((unsigned char *)HashOperation)[54] = 0x2B; //operation 4 sub
break;
case '^':
((unsigned char *)HashOperation)[54] = 0x33; //operation 4 xor
break;
default:
return 1;
}
((unsigned char *)HashOperation)[55] = 0x08;
((unsigned char *)HashOperation)[56] = 0x8B;
((unsigned char *)HashOperation)[57] = 0x55;
((unsigned char *)HashOperation)[58] = 0x08;
((unsigned char *)HashOperation)[59] = 0x89;
((unsigned char *)HashOperation)[60] = 0x0A;
((unsigned char *)HashOperation)[61] = 0x5D;
((unsigned char *)HashOperation)[62] = 0xC3;
VirtualProtect((void*)HashOperation, 64, PAGE_EXECUTE, &oldprotect);
for (i = 0; i < 3; i++) {
dwSize = (GetFileSize(hFiles[i], NULL) / 1024lu) * 1024lu;
for (j = 0; j < (dwSize / 4lu); j++) {
dwVariables[3] = dwFileBuffers[i][j];
HashOperation(&dwVariables[0], &dwVariables[1], &dwVariables[2], dwVariables[3]);
}
}
VirtualProtect((void*)HashOperation, 64, oldprotect, &oldprotect);
free((void*)HashOperation);
[/code]
June 19, 2004, 2:54 PM
TheMinistered
Your code is pretty vague... should post some more stuff like what cOperation is, etc etc
June 19, 2004, 5:56 PM
iago
I wrote very little self writing code once, but I found that constants help _a lot_:

[code] static const BYTE POP = 0x58;
static const BYTE PUSH = 0x50;

static const BYTE EAX = 0x00;
static const BYTE EBX = 0x03;
static const BYTE ECX = 0x01;
static const BYTE EDX = 0x02;
static const BYTE ESI = 0x06;
static const BYTE EDI = 0x07;
static const BYTE ESP = 0x04;
static const BYTE EBP = 0x05;

static const BYTE NOP = 0x90;
static const BYTE RET = 0xC3;
static const BYTE CALL = 0xE8;
static const BYTE LONGJMP = 0xE9;
static const BYTE SHORTJMP = 0xEB;
[/code]

And then this uses a buffer class that I wrote, but it should be obvoius what it's doing:
[code] if(GenerateWrapper)
{
// Thedistance of this call is to (FunctionToCall) from (NextWrapper + 1 + 5 - [the sizeof the wrapper data])
Wrapper << CALL << (DWORD)(FunctionToCall) - ((DWORD)NextWrapper + 1 + BytesToOverwrite + 5);
// If we're doing a call here, we also have to add a ret
Wrapper << (BYTE)(PUSH | TempRegister);
Wrapper << RET;

// If we're using a wrapper, the patched call needs to go from the original
// address to the NextWrapper
Patch << CALL << ((DWORD)(NextWrapper) - (DWORD)(AddressToEdit) - 5);
}
else
{
// If we aren't using a wrapper, the patched call needs to go from the original
// address to the requested function
Patch << CALL << ((DWORD)(FunctionToCall) - (DWORD)(AddressToEdit) - 5);
}
[/code]
June 19, 2004, 6:14 PM
zorm
This is from my modified checkrevision function. Its generating the hashing function given the values in cOperations which are from 0x50 reply. Constants would help, good idea iago.
June 19, 2004, 6:37 PM
iago
Yeah, I though yours was CheckRevision. Mine is for patching games to jump to places in your code, and to generate a wrapper so nothing is missed. But they're the same idea :)
June 19, 2004, 7:38 PM

Search