Skip to content

Instantly share code, notes, and snippets.

@whokilleddb
Last active February 9, 2023 00:47
Show Gist options
  • Save whokilleddb/181ce0de520c5b6282a42a9d8d910a77 to your computer and use it in GitHub Desktop.
Save whokilleddb/181ce0de520c5b6282a42a9d8d910a77 to your computer and use it in GitHub Desktop.
PE without any imports!
// 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