That is not polymorphic code. You (/ the guy who made this) run through a nop sled wich you then repeatedly fill with random garbage.
Polymorphic code is, by definition, code that
mutates but keeps the original algorithm in tact.
I made a quick demonstration, but I would not consider this real polymorphic code, since I don't morph any part of the code wich is relevant to execution. It does how ever execute mutated code and continuously morph itself.
Code:
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <windows.h>
/* 04.05.2014
Harava's simple junk polymorphism demo.
I would not consider this real polymorphism,
since I am not morphing any part of the code
that is actually relevant to execution.
*/
#define MAX_JUNKS 1024
#define Jdw __asm _emit 0x01 __asm _emit 0x01 __asm _emit 0x01 __asm _emit 0x01
#define Jins __asm _emit 0x50 __asm _emit 0x50 __asm _emit 0xB8 Jdw __asm _emit 0x69 __asm _emit 0xC0 Jdw __asm _emit 0x8B __asm _emit 0xC0 __asm _emit 0x3D Jdw __asm _emit 0x74 __asm _emit 0xFF __asm _emit 0x58 __asm _emit 0x58
#define Junk Jins Jins Jins
/*
This is what the Junk looks like:
0112117A > 50 PUSH EAX
0112117B . 50 PUSH EAX
0112117C . B8 01010101 MOV EAX,1010101
01121181 . 69C0 01010101 IMUL EAX,EAX,1010101
01121187 . 8BC0 MOV EAX,EAX
01121189 . 3D 01010101 CMP EAX,1010101
0112118E . 74 FF JE SHORT ScratchP.0112118F
01121190 . 58 POP EAX
01121191 . 58 POP EAX
*/
DWORD dwEndOfScan, dwStartOfScan, dwOldProt;
DWORD dwAdressesOfJunks[MAX_JUNKS];
int nNumberOfJunksFound = 0, nTimesMutated = 1;
HANDLE hMainThread; // HANDLE of main thread for suspending
DWORD RandVal;
BYTE RandOffset;
BYTE RandReg;
void ScanStartAddress(){}
DWORD WINAPI MutatorThread( LPVOID lpParam )
{
if(!VirtualProtect((LPVOID)dwStartOfScan, (dwEndOfScan-dwStartOfScan), PAGE_EXECUTE_READWRITE, &dwOldProt))
{
ExitProcess(-1);Junk;
}
while(1)
{
if(nTimesMutated % 250 == 0)
printf("Mutation cycle %d\n", nTimesMutated);Junk;
nTimesMutated++;Junk;
SuspendThread(hMainThread); // Suspend the main thread, just in case it was in the middle of executing a junk block
for(int n = 0; n < nNumberOfJunksFound; n++)
{
RandReg = rand() % 4;
RandOffset = (rand() % 0xFF) + 1;
RandVal = (rand() % 0xFFFFFFFF) + 1;
*(BYTE*)(dwAdressesOfJunks[n]+1) = 0x50 + RandReg;Junk; // Randomize register of second push
*(BYTE*)(dwAdressesOfJunks[n]+2) = 0xB8 + RandReg;Junk; // Randomize register of mov
*(DWORD*)(dwAdressesOfJunks[n]+3) = RandVal;Junk; // Randomize value of mov
*(BYTE*)(dwAdressesOfJunks[n]+8) = 0xC0 + (RandReg*8);Junk; // Randomize register of imul
*(DWORD*)(dwAdressesOfJunks[n]+9) = RandVal;Junk; // Randomize value of imul
*(BYTE*)(dwAdressesOfJunks[n]+14) = 0xC0 + RandReg;Junk; // Randomize register of mov
*(DWORD*)(dwAdressesOfJunks[n]+16) = ((RandVal%100)-999);Junk; // Randomize value of cmp
*(BYTE*)(dwAdressesOfJunks[n]+21) = RandOffset;Junk; // Randomize offset of jmp
*(BYTE*)(dwAdressesOfJunks[n]+22) = 0x58 + RandReg;Junk; // Randomize register of second last pop
}
ResumeThread(hMainThread);
Sleep(1);
}
}
bool MutateMain(DWORD AddressOfScanStart, DWORD SizeOfScan)
{
Junk; // Since execution is not altered by the junk code or morphing, the Morph function can alter itself too.
if(!VirtualProtect((LPVOID)AddressOfScanStart, SizeOfScan, PAGE_EXECUTE_READWRITE, &dwOldProt))
{
ExitProcess(-1);Junk;
}
for(int n = AddressOfScanStart; n < (AddressOfScanStart+SizeOfScan); n++) // Scan memory for all junk blocks
{
Junk;
if(*(BYTE*)n == 0x50 && *(BYTE*)(n+23)==0x58) // Check for the push pop eax
{
dwAdressesOfJunks[nNumberOfJunksFound] = n; // Store the address of the junk for continuous mutation
nNumberOfJunksFound++;
RandReg = rand() % 4;Junk;
RandOffset = rand() % 0xFF;Junk;
RandVal = rand() % 0xFFFFFFFF + 1;
printf("Found junk at %x\n", n);Junk; // Some initial randomization:
*(BYTE*)(n+1) += RandReg;Junk; // Randomize register of second push
*(BYTE*)(n+2) += RandReg;Junk; // Randomize register of mov
*(DWORD*)(n+3) = RandVal;Junk; // Randomize value of mov
*(BYTE*)(n+8) += (RandReg*8);Junk; // Randomize register of imul
*(DWORD*)(n+9) = RandVal;Junk; // Randomize value of imul
*(BYTE*)(n+14) += RandReg;Junk; // Randomize register of mov
*(DWORD*)(n+16) = ((RandVal%100)-999);Junk; // Randomize value of cmp
*(BYTE*)(n+21) = RandOffset;Junk; // Randomize offset of jmp
*(BYTE*)(n+22) += RandReg;Junk; // Randomize register of second last pop
}
}
CreateThread(NULL, NULL, MutatorThread, NULL, NULL, NULL); // Spawn a thread to continuously mutate the code
return true;
}
int main()
{
hMainThread = OpenThread(THREAD_ALL_ACCESS, FALSE, GetCurrentThreadId());
srand(time(NULL));
dwStartOfScan = (DWORD)&ScanStartAddress; // Grab the address of the scan
goto labelMainEnd; // Go grab the address of the end of the scan
labelStartOfMain:
Junk;
Junk;
Junk;
MutateMain(dwStartOfScan, (dwEndOfScan-dwStartOfScan));
Junk;
Junk;
while(1)
{
Junk;
for(int n = 0; n < 100; n++)
{
Sleep(10);Junk; // We execute mutated code, but it does not screw up execution. That is the whole point in polymorphism
}
printf("MainThread says hello!\n");Junk;
}
Junk;
Junk;
return 1;
labelMainEnd: // Grab the address of "end" of main
__asm
{
PUSH EAX
CALL labelFetchAddress
labelFetchAddress:
POP EAX
MOV dwEndOfScan, EAX
POP EAX
jmp labelStartOfMain // Back to beginning of main
}
}
This is how execution looks in a debugger:
Also, you don't need to call FlushInstructionCache() on x86 or x64.