Skip to content

Instantly share code, notes, and snippets.

@Barakat
Last active August 31, 2019 21:10
Show Gist options
  • Save Barakat/f60b1e1d1ecdd01112918fe75505c7b5 to your computer and use it in GitHub Desktop.
Save Barakat/f60b1e1d1ecdd01112918fe75505c7b5 to your computer and use it in GitHub Desktop.
Egg hunter shellcode that performs "linear search" looking for an egg shellcode and executes it
#include <Windows.h>
#include <cassert>
#include <cstring>
#include <cstdio>
#include <cinttypes>
#include <random>
int main()
{
static const unsigned char hunter_shellcode[] = {
// mov rax, 0x5fe12c200000
// mov r12, rax
// L1:
// mov edx, DWORD PTR [r12]
// cmp edx, 1634885954
// jne L2
// mov edx, DWORD PTR [3+r12]
// cmp edx, 1952541537
// jne L2
// lea rdx, QWORD PTR [7+r12]
// jmp rdx
// L2:
// inc r12
// jmp L1
0x48, 0xb8, 0x00, 0x00, 0x20, 0x2c, 0xe1, 0x5f, 0x00, 0x00,
0x49, 0x89, 0xc4,
0x41, 0x8b, 0x14, 0x24,
0x81, 0xfa, 0x42, 0x61, 0x72, 0x61,
0x75, 0x14,
0x41, 0x8b, 0x54, 0x24, 0x03,
0x81, 0xfa, 0x61, 0x6b, 0x61, 0x74,
0x75, 0x07,
0x49, 0x8d, 0x54, 0x24, 0x07,
0xff, 0xe2,
0x49, 0xff, 0xc4,
0xeb, 0xdb
};
static const unsigned char egg_shellcode[] = {
// B a r a k a t # 7-bytes egg :D
// mov rax, 1337
// ret
'B', 'a', 'r', 'a', 'k', 'a', 't',
0x48, 0xc7, 0xc0, 0x39, 0x05, 0x00, 0x00,
0xc3
};
// memory for the egg hunter
static const DWORD hunter_memory_size = 1 * 1024;
void *hunter_memory = VirtualAlloc(nullptr, hunter_memory_size, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
std::memcpy(hunter_memory, hunter_shellcode, sizeof(hunter_shellcode));
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// memory for the egg
static const DWORD egg_memory_size = 16 * 1024;
void *egg_memory = VirtualAlloc(reinterpret_cast<void *>(0x00005fe12c200000), egg_memory_size, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
std::random_device random_device;
std::mt19937 generator(random_device());
// fill the memory with random data
std::uniform_int_distribution<> distribution0(0x00, 0xff);
for (std::size_t i = 0; i < egg_memory_size; ++i)
{
(static_cast<unsigned char *>(egg_memory))[i] = static_cast<unsigned char>(distribution0(generator));
}
// place the egg shellcode at some random place
std::uniform_int_distribution<> distribution1(0, egg_memory_size - sizeof(egg_shellcode));
std::memcpy(static_cast<unsigned char *>(egg_memory) + distribution1(generator), egg_shellcode, sizeof(egg_shellcode));
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// invoke the egg hunter shellcode, it will search for the egg by doing "linear search" and execute it
std::printf("%" PRId64 "\n", (reinterpret_cast<uint64_t (*)()>(hunter_memory))()); // prints 1337
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
VirtualFree(hunter_memory, hunter_memory_size, MEM_RELEASE);
VirtualFree(egg_memory, egg_memory_size, MEM_RELEASE);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment