aboutsummaryrefslogtreecommitdiff
path: root/source/tools/runbin.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/tools/runbin.c')
-rw-r--r--source/tools/runbin.c217
1 files changed, 217 insertions, 0 deletions
diff --git a/source/tools/runbin.c b/source/tools/runbin.c
new file mode 100644
index 0000000..af3b8f4
--- /dev/null
+++ b/source/tools/runbin.c
@@ -0,0 +1,217 @@
+/* modified (from http://securityxploded.com/memory-execution-of-executable.php) */
+#include <windows.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "loader.h"
+
+#define DEREF_32( name )*(DWORD *)(name)
+
+
+static volatile PVOID kernel32 asm("__kernel32") = NULL;
+static volatile PVOID getproc asm("__getproc") = NULL;
+static volatile DWORD EntryAddr asm("__EntryAddr");
+static volatile PVOID memalloc asm("__memalloc") = NULL;
+static volatile PVOID ldr_ptr asm("__ldr") = NULL;
+
+static volatile struct loader_x86_data ldr;
+static volatile DWORD size = 0x0;
+static volatile PVOID vpointer = NULL;
+
+static volatile DWORD retval asm("__retval") = -1;
+
+
+int main(int argc, char *argv[])
+{
+ if (argc != 2 && argc != 3 && argc != 4) {
+ fprintf(stderr, "usage: %s path-to-dynamic-library [preferred-Virtual-Address] [wait-time]\n", argv[0]);
+ return -1;
+ }
+
+ DWORD dwWait = 2;
+
+ if (argc == 4) {
+ errno = 0;
+ dwWait = strtoul(argv[3], NULL, 10);
+ if (errno != 0)
+ dwWait = 2;
+ }
+
+ BOOL doAllocAt = FALSE;
+ PVOID allocPtr = NULL;
+ if (argc >= 3) {
+ doAllocAt = TRUE;
+ char* errch = NULL;
+ allocPtr = (PVOID)strtoul(argv[2], &errch, 16);
+ }
+
+ HANDLE handle;
+ HINSTANCE laddress;
+ LPSTR libname;
+ DWORD byteread;
+ PIMAGE_NT_HEADERS nt;
+ PIMAGE_SECTION_HEADER section;
+ DWORD dwValueA;
+ DWORD dwValueB;
+ DWORD dwValueC;
+ DWORD dwValueD;
+
+ // read the file
+ printf("Reading file..\n");
+ handle = CreateFile(argv[1],GENERIC_READ,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
+ if (handle == INVALID_HANDLE_VALUE) {
+ fprintf(stderr, "%s: file(%s) does not exist or is not readable\n", argv[0], argv[1]);
+ return -1;
+ }
+
+ // get the file size
+ size = GetFileSize(handle,NULL);
+ if (size <= 0) {
+ fprintf(stderr, "%s: invalid file(%s) size\n", argv[0], argv[1]);
+ return -1;
+ }
+
+ // Allocate the space
+ vpointer = VirtualAlloc(NULL,size,MEM_COMMIT,PAGE_READWRITE);
+
+ // read file on the allocated space
+ ReadFile(handle,vpointer,size,&byteread,NULL);
+ CloseHandle(handle);
+ printf("File loaded into memory ..\n");
+ printf("address............: 0x%X (%lu)\n", (unsigned int)vpointer, (long unsigned int)vpointer);
+ printf("size...............: 0x%X (%lu)\n", (unsigned int)size, size);
+ printf("Parse PE-Header ..\n");
+
+ // read NT header of the file
+ nt = (PIMAGE_NT_HEADERS)((PCHAR)vpointer + ((PIMAGE_DOS_HEADER)vpointer)->e_lfanew);
+ printf("e_lfanew...........: 0x%X (%ld)\n", (unsigned int)((PIMAGE_DOS_HEADER)vpointer)->e_lfanew, ((PIMAGE_DOS_HEADER)vpointer)->e_lfanew);
+ handle = GetCurrentProcess();
+
+ // get VA of entry point
+ printf("AddressOfEntryPoint: 0x%X (%ld)\n", (unsigned int)nt->OptionalHeader.AddressOfEntryPoint, nt->OptionalHeader.AddressOfEntryPoint);
+ printf("ImageBase..........: 0x%X (%ld)\n", (unsigned int)nt->OptionalHeader.ImageBase, nt->OptionalHeader.ImageBase);
+ printf("SizeOfImage........: 0x%X (%ld)\n", (unsigned int)nt->OptionalHeader.SizeOfImage, nt->OptionalHeader.SizeOfImage);
+ printf("SizeOfHeaders......: 0x%X (%ld)\n", (unsigned int)nt->OptionalHeader.SizeOfHeaders, nt->OptionalHeader.SizeOfHeaders);
+ printf("SizeOptionalHeader.: 0x%X (%d)\n", (unsigned int)nt->FileHeader.SizeOfOptionalHeader, nt->FileHeader.SizeOfOptionalHeader);
+
+ // Allocate the space with Imagebase as a desired address allocation request
+ memalloc = VirtualAllocEx(
+ handle,
+ (doAllocAt == FALSE ? (LPVOID)nt->OptionalHeader.ImageBase : allocPtr),
+ nt->OptionalHeader.SizeOfImage,
+ MEM_RESERVE | MEM_COMMIT,
+ PAGE_EXECUTE_READWRITE
+ );
+
+ // Check for NULL (esp. if the user wants to chooose a specific VA)
+ if (!memalloc) {
+ printf("FATAL: VirtualAllocEx failed with %d\n", (int)GetLastError());
+ exit(1);
+ }
+ EntryAddr = (DWORD)memalloc + nt->OptionalHeader.AddressOfEntryPoint;
+
+ // Write headers on the allocated space
+ WriteProcessMemory(handle,
+ memalloc,
+ vpointer,
+ nt->OptionalHeader.SizeOfHeaders,
+ 0
+ );
+
+
+ // write sections on the allocated space
+ section = IMAGE_FIRST_SECTION(nt);
+ printf("sizeof(section)....: 0x%X (%u)\n", sizeof(IMAGE_SECTION_HEADER), sizeof(IMAGE_SECTION_HEADER));
+ printf("FirstSectionRVA....: 0x%X (%ld)\n", (unsigned int)section[0].VirtualAddress, section[0].VirtualAddress);
+ printf("FirstSectionPTR....: 0x%X (%ld)\n", (unsigned int)section[0].PointerToRawData, section[0].PointerToRawData);
+ if ((unsigned int)memalloc != (unsigned int)nt->OptionalHeader.ImageBase) {
+ printf("Allocated memory block does not start at DLL image base!\n"
+ " -> 0x%X != 0x%X\n", (unsigned int)memalloc, (unsigned int)nt->OptionalHeader.ImageBase);
+ }
+
+ for (ULONG i = 0; i < nt->FileHeader.NumberOfSections; i++)
+ {
+ WriteProcessMemory(
+ handle,
+ (PCHAR)memalloc + section[i].VirtualAddress,
+ (PCHAR)vpointer + section[i].PointerToRawData,
+ section[i].SizeOfRawData,
+ 0
+ );
+ }
+
+ if (*(DWORD*)&(nt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]) != 0x00000000)
+ {
+ // read import dirctory, if exists
+ dwValueB = (DWORD) &(nt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]);
+
+ // get the VA
+ dwValueC = (DWORD)(memalloc) +
+ ((PIMAGE_DATA_DIRECTORY)dwValueB)->VirtualAddress;
+
+ while(((PIMAGE_IMPORT_DESCRIPTOR)dwValueC)->Name)
+ {
+ // get DLL name
+ libname = (LPSTR)((DWORD)(memalloc) +
+ ((PIMAGE_IMPORT_DESCRIPTOR)dwValueC)->Name);
+
+ // Load dll
+ laddress = LoadLibrary(libname);
+
+ // get first thunk, it will become our IAT
+ dwValueA = (DWORD)(memalloc) +
+ ((PIMAGE_IMPORT_DESCRIPTOR)dwValueC)->FirstThunk;
+
+ // resolve function addresses
+ while(DEREF_32(dwValueA))
+ {
+ dwValueD = (DWORD)(memalloc) + DEREF_32(dwValueA);
+ // get function name
+ LPSTR Fname = (LPSTR)((PIMAGE_IMPORT_BY_NAME)dwValueD)->Name;
+ // get function addresses
+ DEREF_32(dwValueA) = (DWORD)GetProcAddress(laddress,Fname);
+ dwValueA += 4;
+ }
+
+ dwValueC += sizeof( IMAGE_IMPORT_DESCRIPTOR );
+ }
+ } else printf("No Import Table found, nothing to import ..\n");
+
+ memset((void*)&ldr, '\0', sizeof(ldr));
+ ldr.ptrToDLL = (uint32_t)vpointer;
+ ldr.sizOfDLL = size;
+ unsigned char marker[] = { _LOADER_ENDMARKER };
+ memcpy((void*)&ldr.endMarker, &marker[0], sizeof(ldr.endMarker));
+
+ ldr_ptr = (volatile PVOID) &ldr;
+ kernel32 = LoadLibraryA("KERNEL32.dll");
+ getproc = GetProcAddress((void*)kernel32, "GetProcAddress");
+
+ printf("Calling DLL AdrOfEntry ..\n");
+ // call the entry point :: here we assume that everything is ok.
+ asm volatile(
+ ".intel_syntax noprefix\n"
+ "pushad\n\t"
+ "pushfd\n\t"
+ "mov ebx,0xdeadbeef\n\t"
+ "mov ecx,[__getproc]\n\t"
+ "mov edx,[__kernel32]\n\t"
+ "mov edi,__memalloc\n\t"
+ "mov esi,__ldr\n\t"
+ "push 0x00000000\n\t"
+ "call [__EntryAddr]\n\t"
+ "pop esi\n\t"
+ "mov [__retval],eax\n\t"
+ "popfd\n\t"
+ "popad\n\t"
+ ".att_syntax\n"
+ );
+
+ sleep(dwWait);
+ printf("DLL returned: %X (%d)\n", (unsigned int)retval, (int)retval);
+ printf("GetLastError: 0x%X (%ld)\n", (unsigned int)GetLastError(), GetLastError());
+
+ return retval;
+}