i'm trying to make exe packer 5
- extract exe to buffer(in my case: vector)
- add new section
- get offset of new EP and run
but after call newmain i got 0xC0000005
main.cpp: pastebin
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include "main.h"
typedef struct _BASE_RELOCATION_ENTRY
{ WORD Offset : 12; WORD Type : 4;
} BASE_RELOCATION_ENTRY;
BOOL applyRelocBlock(BASE_RELOCATION_ENTRY* block, size_t entriesNum, DWORD page, PVOID newBase)
{ PVOID ImageBaseAddress = NtCurrentTeb()->Peb->ImageBaseAddress; BASE_RELOCATION_ENTRY* entry = block; for (int i = 0; i < entriesNum; i++) { DWORD offset = entry->Offset; DWORD type = entry->Type; if (entry == NULL || type == 0 || offset == 0) { //printf("Applied relocations: %dn", i); return TRUE; //finish } if (type != 3) { printf("Not supported relocations format at %d: %dn", i, type); return FALSE; } uint32_t* relocateAddr = (uint32_t*)((ULONG_PTR)newBase + page + offset); (*relocateAddr) = ((*relocateAddr) - (ULONG_PTR)ImageBaseAddress) + (ULONG_PTR)newBase; entry = (BASE_RELOCATION_ENTRY*)((ULONG_PTR)entry + sizeof(uint16_t)); } return TRUE;
}
BOOL applyRelocations(PIMAGE_NT_HEADERS NtHeaders, PVOID newBase)
{ PVOID ImageBaseAddress = NtCurrentTeb()->Peb->ImageBaseAddress; //fetch relocation table from current image: IMAGE_DATA_DIRECTORY relocDir = NtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC]; if (relocDir.VirtualAddress == NULL) { printf("Cannot relocate - application have no relocation table!"); return FALSE; } DWORD maxSize = relocDir.Size; DWORD parsedSize = 0; DWORD relocAddr = relocDir.VirtualAddress; IMAGE_BASE_RELOCATION* reloc = NULL; while (parsedSize < maxSize) { reloc = (IMAGE_BASE_RELOCATION*)(relocAddr + parsedSize + (ULONG_PTR)ImageBaseAddress); parsedSize += reloc->SizeOfBlock; if (reloc->VirtualAddress == NULL || reloc->SizeOfBlock == 0) { continue; } printf("RelocBlock: %p %pn", reloc->VirtualAddress, reloc->SizeOfBlock); size_t entriesNum = (reloc->SizeOfBlock - 2 * sizeof(uint32_t)) / sizeof(uint16_t); DWORD page = reloc->VirtualAddress; BASE_RELOCATION_ENTRY* block = (BASE_RELOCATION_ENTRY*)((ULONG_PTR)reloc + sizeof(uint32_t) + sizeof(uint32_t)); if (applyRelocBlock(block, entriesNum, page, newBase) == FALSE) { return FALSE; } } return TRUE;
}
bool checkLibs()
{ return load_ntdll_functions() && load_kernel32_functions();
}
bool mapAndRun()
{ HANDLE hSection = NULL; PVOID ImageBaseAddress = NtCurrentTeb()->Peb->ImageBaseAddress; PIMAGE_NT_HEADERS NtHeaders = RtlImageNtHeader(ImageBaseAddress); if (NtHeaders == NULL) { printf("[ERROR] RtlImageNtHeader failed, error : %dn", GetLastError()); return false; } LARGE_INTEGER MaximumSize; ULONG ImageSize = NtHeaders->OptionalHeader.SizeOfImage; MaximumSize.LowPart = ImageSize; MaximumSize.HighPart = 0; NTSTATUS Status = NULL; if ((Status = ZwCreateSection(&hSection, SECTION_ALL_ACCESS, NULL, &MaximumSize, PAGE_EXECUTE_READWRITE, SEC_COMMIT, NULL)) != STATUS_SUCCESS) { printf("[ERROR] ZwCreateSection failed, status : %xn", Status); system("pause"); return false; } printf("Section handle: %xn", hSection); HANDLE hProcess = NULL; PVOID pSectionBaseAddress = NULL; SIZE_T ViewSize = 0; DWORD dwInheritDisposition = 1; //VIEW_SHARE // map the section in context of current process: if ((Status = NtMapViewOfSection(hSection, GetCurrentProcess(), &pSectionBaseAddress, NULL, NULL, NULL, &ViewSize, dwInheritDisposition, NULL, PAGE_EXECUTE_READWRITE)) != STATUS_SUCCESS) { printf("[ERROR] NtMapViewOfSection failed, status : %xn", Status); system("pause"); return false; } printf("Created new section, BaseAddress: %p ViewSize: %pn", pSectionBaseAddress, ViewSize); printf("Mapping into: %p <- current image: %p %pn", pSectionBaseAddress, ImageBaseAddress, ImageSize); RtlCopyMemory(pSectionBaseAddress, ImageBaseAddress, ImageSize); ZwClose(hSection); hSection = NULL; if (applyRelocations(NtHeaders, pSectionBaseAddress) == FALSE) { printf("Applying relocations failed, cannot continue!"); ZwTerminateProcess(GetCurrentProcess(), STATUS_FAILURE); } printf("Applied relocations!n"); // std::vector<unsigned char> extractedData = unpackExe(); //packe exe IMAGE_NT_HEADERS INH; IMAGE_DOS_HEADER IDH; memcpy(&IDH, &extractedData[0], sizeof(IDH)); memcpy(&INH, (void*)((DWORD)&extractedData[0] + IDH.e_lfanew), sizeof(INH)); LARGE_INTEGER MaximumSizeEX; ULONG ImageSizeEX = INH.OptionalHeader.SizeOfImage; MaximumSizeEX.LowPart = ImageSizeEX; MaximumSizeEX.HighPart = 0; ULONG_PTR exEP = INH.OptionalHeader.AddressOfEntryPoint; ULONG_PTR offsetFromBase = exEP - (ULONG_PTR)ImageBaseAddress; printf("extracted EP offset: %pn", offsetFromBase); ULONG_PTR newMain = ((ULONG_PTR)pSectionBaseAddress + offsetFromBase); printf("extracted EP address in new section: %pn", newMain); __asm { call newMain }; return true;
}
bool mapAndExecute()
{ if (checkLibs()) { if (mapAndRun()) { } } return true;
}
int main()
{ mapAndExecute(); std::cin.get();
}
main.h:pastebin: pastebin.com/Spc5WTsQ
#pragma once
#include <stdio.h>
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#if !defined NTSTATUS
typedef LONG NTSTATUS;
#endif
#define STATUS_SUCCESS 0
#define STATUS_FAILURE (-1)
#define NtCurrentProcess() ((HANDLE)-1)
typedef struct _CLIENT_ID
{ HANDLE UniqueProcess; HANDLE UniqueThread;
} CLIENT_ID, *PCLIENT_ID;
typedef LONG NTSTATUS, *PNTSTATUS;
typedef struct _UNICODE_STRING { USHORT Length; USHORT MaximumLength; PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
typedef struct _PEB_LDR_DATA
{ ULONG Length; BOOLEAN Initialized; PVOID SsHandle; LIST_ENTRY InLoadOrderModuleList; LIST_ENTRY InMemoryOrderModuleList; LIST_ENTRY InInitializationOrderModuleList;
} PEB_LDR_DATA, *PPEB_LDR_DATA;
typedef struct _PEB
{ BYTE Reserved1[2]; /* 00 */ BYTE BeingDebugged; /* 02 */ BYTE Reserved2[5]; /* 03 */ HMODULE ImageBaseAddress; /* 08 */ PPEB_LDR_DATA LdrData; /* 0c */ DWORD ProcessParameters; /* 10 */ PVOID __pad_14; /* 14 */ HANDLE ProcessHeap; /* 18 */ BYTE __pad_1c[36]; /* 1c */ DWORD TlsBitmap; /* 40 */ ULONG TlsBitmapBits[2]; /* 44 */ BYTE __pad_4c[24]; /* 4c */ ULONG NumberOfProcessors; /* 64 */ BYTE __pad_68[128]; /* 68 */ PVOID Reserved3[59]; /* e8 */ ULONG SessionId; /* 1d4 */
} PEB, *PPEB;
typedef struct _TEB
{ NT_TIB Tib; /* 000 */ PVOID EnvironmentPointer; /* 01c */ CLIENT_ID ClientId; /* 020 */ PVOID ActiveRpcHandle; /* 028 */ PVOID ThreadLocalStoragePointer; /* 02c */ PPEB Peb; /* 030 */ ULONG LastErrorValue; /* 034 */ BYTE __pad038[140]; /* 038 */ ULONG CurrentLocale; /* 0c4 */ BYTE __pad0c8[1752]; /* 0c8 */ PVOID Reserved2[278]; /* 7a0 */ UNICODE_STRING StaticUnicodeString; /* bf8 used by advapi32 */ WCHAR StaticUnicodeBuffer[261]; /* c00 used by advapi32 */ PVOID DeallocationStack; /* e0c */ PVOID TlsSlots[64]; /* e10 */ LIST_ENTRY TlsLinks; /* f10 */ PVOID Reserved4[26]; /* f18 */ PVOID ReservedForOle; /* f80 Windows 2000 only */ PVOID Reserved5[4]; /* f84 */ PVOID TlsExpansionSlots; /* f94 */
} TEB, *PTEB;
typedef
void
(*PKNORMAL_ROUTINE) ( void* NormalContext, void* SystemArgument1, void* SystemArgument2 );
typedef struct { int info; PKNORMAL_ROUTINE fun;
} *PIO_STATUS_BLOCK;
// Make sure we print the __stdcall properly
typedef
void
(__stdcall *PIO_APC_ROUTINE) ( void* ApcContext, PIO_STATUS_BLOCK IoStatusBlock, long Reserved );
#if !defined PROCESSINFOCLASS
typedef LONG PROCESSINFOCLASS;
#endif
#if !defined THREADINFOCLASS
typedef LONG THREADINFOCLASS;
#endif
#if !defined PPEB
typedef struct _PEB *PPEB;
#endif
#if !defined PROCESS_BASIC_INFORMATION
typedef struct _PROCESS_BASIC_INFORMATION { PVOID Reserved1; PPEB PebBaseAddress; PVOID Reserved2[2]; ULONG_PTR UniqueProcessId; PVOID Reserved3;
} PROCESS_BASIC_INFORMATION;
#endif;
/*
typedef LONG NTSTATUS, *PNTSTATUS;
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
*/
typedef struct _OBJECT_ATTRIBUTES { ULONG Length; HANDLE RootDirectory; PUNICODE_STRING ObjectName; ULONG Attributes; PVOID SecurityDescriptor; PVOID SecurityQualityOfService;
} OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;
typedef NTSTATUS(WINAPI * PFN_ZWQUERYINFORMATIONPROCESS)(HANDLE, PROCESSINFOCLASS, PVOID, ULONG, PULONG);
//ntdll api:
NTSTATUS(NTAPI *ZwQueryInformationProcess)( HANDLE ProcessHandle, PROCESSINFOCLASS ProcessInformationClass, PVOID ProcessInformation, ULONG ProcessInformationLength, PULONG ReturnLength OPTIONAL );
NTSTATUS(NTAPI *ZwCreateSection)( __out PHANDLE SectionHandle, __in ACCESS_MASK DesiredAccess, __in POBJECT_ATTRIBUTES ObjectAttributes, __in PLARGE_INTEGER MaximumSize, __in ULONG SectionPageProtection, __in ULONG AllocationAttributes, __in HANDLE FileHandle );
NTSTATUS(NTAPI *NtMapViewOfSection)( __in HANDLE SectionHandle, __in HANDLE ProcessHandle, __inout PVOID *BaseAddress, __in ULONG_PTR ZeroBits, __in SIZE_T CommitSize, __inout PLARGE_INTEGER SectionOffset, __inout PSIZE_T ViewSize, __in DWORD InheritDisposition, __in ULONG AllocationType, __in ULONG Win32Protect );
NTSTATUS(NTAPI *ZwCreateThreadEx) ( __out PHANDLE ThreadHandle, __in ACCESS_MASK DesiredAccess, __in POBJECT_ATTRIBUTES ObjectAttributes, __in HANDLE ProcessHandle, __in PVOID StartRoutine, __in PVOID Argument, __in ULONG CreateFlags, __in ULONG_PTR ZeroBits, __in SIZE_T StackSize, __in SIZE_T MaximumStackSize, __in PVOID AttributeList );
NTSTATUS(NTAPI *ZwUnmapViewOfSection) ( __in HANDLE ProcessHandle, __in PVOID BaseAddress );
NTSTATUS(NTAPI *ZwClose) ( __in HANDLE Handle );
NTSTATUS(NTAPI *ZwTerminateProcess) ( __in HANDLE ProcessHandle, __in NTSTATUS ExitStatus );
NTSTATUS(NTAPI *NtQueueApcThread)( __in HANDLE ThreadHandle, __in PVOID ApcRoutine, __in PVOID ApcRoutineContext OPTIONAL, __in PVOID ApcStatusBlock OPTIONAL, __in ULONG ApcReserved OPTIONAL );
NTSTATUS(NTAPI *ZwSetInformationThread) ( __in HANDLE ThreadHandle, __in THREADINFOCLASS ThreadInformationClass, __in PVOID ThreadInformation, __in ULONG ThreadInformationLength );
PIMAGE_NT_HEADERS(NTAPI *RtlImageNtHeader) ( __in PVOID ModuleAddress );
//kernel32 api
BOOL
(WINAPI *CreateProcessInternalW)(HANDLE hToken, LPCWSTR lpApplicationName, LPWSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation, PHANDLE hNewToken );
trying to adoptate source from here