Last active
February 9, 2023 00:47
-
-
Save whokilleddb/181ce0de520c5b6282a42a9d8d910a77 to your computer and use it in GitHub Desktop.
PE without any imports!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Compile with: cl.exe /Ox /W0 /GS- launcher.c | |
// Check imports with: dumpbin /imports launcher.exe | |
#include <windows.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#pragma comment(linker, "/entry:WinMain") | |
// Function Pointers | |
typedef BOOL (WINAPI * CreateProcessA_t)( | |
LPCSTR lpApplicationName, | |
LPSTR lpCommandLine, | |
LPSECURITY_ATTRIBUTES lpProcessAttributes, | |
LPSECURITY_ATTRIBUTES lpThreadAttributes, | |
BOOL bInheritHandles, | |
DWORD dwCreationFlags, | |
LPVOID lpEnvironment, | |
LPCSTR lpCurrentDirectory, | |
LPSTARTUPINFOA lpStartupInfo, | |
LPPROCESS_INFORMATION lpProcessInformation | |
); | |
typedef DWORD (WINAPI *WaitForSingleObject_t)( | |
HANDLE hHandle, | |
DWORD dwMilliseconds | |
); | |
typedef BOOL (WINAPI *CloseHandle_t)( | |
HANDLE hObject | |
); | |
// Process Environment Block(PEB) Loader data Structure | |
// https://processhacker.sourceforge.io/doc/ntpsapi_8h_source.html#l00063 | |
typedef struct _PEB_LDR_DATA{ | |
ULONG Length; | |
BOOLEAN Initialized; | |
HANDLE SsHandle; | |
LIST_ENTRY InLoadOrderModuleList; | |
LIST_ENTRY InMemoryOrderModuleList; | |
LIST_ENTRY InInitializationOrderModuleList; | |
PVOID EntryInProgress; | |
BOOLEAN ShutdownInProgress; | |
HANDLE ShutdownThreadId; | |
} PEB_LDR_DATA; | |
// Unicode string | |
// https://processhacker.sourceforge.io/doc/ntbasic_8h_source.html#l00111 | |
typedef struct _UNICODE_STRING { | |
USHORT Length; | |
USHORT MaximumLength; | |
PWSTR Buffer; | |
} UNICODE_STRING; | |
// https://processhacker.sourceforge.io/doc/ntldr_8h_source.html#l00102 | |
// Structure pointed by PEB_LDR_DATA->InMemoryOrderModuleList | |
typedef struct _LDR_DATA_TABLE_ENTRY { | |
LIST_ENTRY InLoadOrderLinks; | |
LIST_ENTRY InMemoryOrderLinks; | |
union { | |
LIST_ENTRY InInitializationOrderLinks; | |
LIST_ENTRY InProgressLinks; | |
}; | |
PVOID DllBase; | |
PVOID EntryPoint; | |
ULONG SizeOfImage; | |
UNICODE_STRING FullDllName; | |
UNICODE_STRING BaseDllName; | |
BYTE Reserved[136-104]; | |
} LDR_DATA_TABLE_ENTRY; | |
// Structure Representing Process Environment Block(PEB) | |
// https://processhacker.sourceforge.io/doc/ntpebteb_8h_source.html#l00008 | |
typedef struct _PEB { | |
BOOLEAN InheritedAddressSpace; | |
BOOLEAN ReadImageFileExecOptions; | |
BOOLEAN BeingDebugged; | |
union | |
{ | |
BOOLEAN BitField; | |
struct { | |
BOOLEAN ImageUsesLargePages : 1; | |
BOOLEAN IsProtectedProcess : 1; | |
BOOLEAN IsImageDynamicallyRelocated : 1; | |
BOOLEAN SkipPatchingUser32Forwarders : 1; | |
BOOLEAN IsPackagedProcess : 1; | |
BOOLEAN IsAppContainer : 1; | |
BOOLEAN IsProtectedProcessLight : 1; | |
BOOLEAN SpareBits : 1; | |
}; | |
}; | |
HANDLE Mutant; | |
PVOID ImageBaseAddress; | |
PEB_LDR_DATA* Ldr; | |
BYTE Reserved[712-32]; | |
} PEB; | |
HMODULE WINAPI __get_module_handle(LPCWSTR lpModuleName){ | |
// get the offset of Process Environment Block | |
#ifdef _M_IX86 | |
PEB * peb_blk = (PEB *) __readfsdword(0x30); // for 32 bit, the address of PEB is stored at an offset of 0x30 in the fs register | |
#else | |
PEB * peb_blk = (PEB *) __readgsqword(0x60); // for 64 bit, the address of PEB is stored at an offset of 0x60 in the gs register | |
#endif | |
if(NULL == lpModuleName) | |
return (HMODULE) (peb_blk->ImageBaseAddress); | |
PEB_LDR_DATA * __ldr = peb_blk->Ldr; | |
LIST_ENTRY * __in_memory_order_module_list = &__ldr->InMemoryOrderModuleList; // Address of Beginning of Doubly Linked List | |
LIST_ENTRY * __start_list_entry = __in_memory_order_module_list->Flink; | |
// Iterate through Doubly Linked List | |
for(LIST_ENTRY * _cell = __start_list_entry; // Initial Cell of InMemoryOrderModuleList | |
_cell != __in_memory_order_module_list; // Iterate over all values of the Doubly Linked List | |
_cell = _cell->Flink){ | |
// Get Current Data Table Entry | |
LDR_DATA_TABLE_ENTRY * _entry = (LDR_DATA_TABLE_ENTRY *) ((BYTE *)_cell - sizeof(LIST_ENTRY)); | |
if (strcmp((const char*)lpModuleName, (const char*)_entry->BaseDllName.Buffer) == 0){ | |
return (HMODULE) _entry->DllBase; | |
} | |
} | |
return NULL; | |
} | |
FARPROC WINAPI __get_proc_address(HMODULE hModule, char *lpProcName) | |
{ | |
char * base_addr = (char *)hModule; | |
void * retaddr = NULL; | |
// Get a pointer to DOS Header | |
IMAGE_DOS_HEADER * __dos_hdr = (IMAGE_DOS_HEADER *)base_addr; | |
// Get a pointer to NT Headers | |
IMAGE_NT_HEADERS * __nt_hdr = (IMAGE_NT_HEADERS *) (base_addr + __dos_hdr->e_lfanew); | |
// Get a pointer to Optional Header | |
IMAGE_OPTIONAL_HEADER * __optional_hdr = &__nt_hdr->OptionalHeader; | |
// Get a pointer to Data Directory | |
IMAGE_DATA_DIRECTORY * __data_dir = (IMAGE_DATA_DIRECTORY *)(&__optional_hdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]); | |
// Get a pointer to Export Directory | |
IMAGE_EXPORT_DIRECTORY * export_dir_addr = (IMAGE_EXPORT_DIRECTORY *)(base_addr + __data_dir->VirtualAddress); | |
// Resolve Address to Export Address Table | |
DWORD * addr_eat = (DWORD *)(base_addr + export_dir_addr->AddressOfFunctions); | |
// Resolve Address to Table of Function Names | |
DWORD * addr_func_name_tbl = (DWORD *)(base_addr + export_dir_addr->AddressOfNames); | |
// Resolve Address to Table of Ordinals | |
WORD * addr_ord_tbl = (WORD *)(base_addr + export_dir_addr->AddressOfNameOrdinals); | |
// Resolve function by name | |
for (DWORD i = 0; i < export_dir_addr->NumberOfNames; i++) { | |
char * __temp_name = (char *)base_addr + (DWORD_PTR) addr_func_name_tbl[i]; | |
if (strcmp(lpProcName, __temp_name) == 0) { | |
retaddr = (FARPROC)(base_addr + (DWORD_PTR)addr_eat[addr_ord_tbl[i]]); | |
break; | |
} | |
} | |
// Return Address | |
return (FARPROC)retaddr; | |
} | |
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){ | |
LPSTR path = "c:\\Windows\\System32\\calc.exe"; | |
STARTUPINFO si; | |
PROCESS_INFORMATION pi; | |
HMODULE _kernel32 = __get_module_handle(L"KERNEL32.DLL"); | |
if (!_kernel32) { | |
return -2; | |
} | |
CreateProcessA_t __createprocessa = (CreateProcessA_t)__get_proc_address(_kernel32, "CreateProcessA"); | |
WaitForSingleObject_t __wait_for_single_object = (WaitForSingleObject_t)__get_proc_address(_kernel32, "WaitForSingleObject"); | |
CloseHandle_t __close_handle = (CloseHandle_t)__get_proc_address(_kernel32, "CloseHandle"); | |
ZeroMemory(&si, sizeof(si)); | |
si.cb = sizeof(si); | |
ZeroMemory(&pi, sizeof(pi)); | |
if (!__createprocessa( NULL, // No module name | |
path, // Path to cmd.exe executable | |
NULL, // Process handle not inheritable | |
NULL, // Thread handle not inheritable | |
FALSE, // Set handle inheritance to FALSE | |
0, // No creation flags | |
NULL, // Use parent's environment block | |
NULL, // Use parent's starting directory | |
&si, // Pointer to STARTUPINFO structure | |
&pi ) // Pointer to PROCESS_INFORMATION structure | |
) { | |
return -1; | |
} | |
__wait_for_single_object(pi.hProcess, INFINITE); | |
__close_handle(pi.hProcess); | |
__close_handle(pi.hThread); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment