Untitled
unknown
plain_text
2 years ago
7.9 kB
1
Indexable
Never
#include <stdio.h> #include <windows.h> #include <psapi.h> #include <stdlib.h> #include <string.h> #include <stdint.h> #include <assert.h> #include <dbghelp.h> /* HMODULE moduleHandles[1024]; DWORD cbNeeded; if (EnumProcessModules(processHandle, moduleHandles, sizeof(moduleHandles), &cbNeeded)) { for (DWORD i = 0; i < (cbNeeded / sizeof(HMODULE)); i++) { TCHAR moduleName[MAX_PATH]; if (GetModuleFileNameEx(processHandle, moduleHandles[i], moduleName, sizeof(moduleName) / sizeof(TCHAR))) { printf("%s address: %p difference address: %td\n", moduleName, (uintptr_t)moduleHandles[i], (ptrdiff_t)event.u.Exception.ExceptionRecord.ExceptionAddress - (ptrdiff_t)moduleHandles[i]); } } } else { printf("Failed to enumerate process modules.\n"); } */ static __typeof__(NtAllocateVirtualMemory) *fnNtAllocateVirtualMemory; //optimize(0) #define PIC CALLBACK __attribute__((noclone,noinline,)) HMODULE RemoteAddressToModule( HANDLE hProcess , void* pAddress ) { //context for input/output from the remote function //must contain REMOTE PROCESS pointers to any function that will be called (kernel32/ntdll is free.) //so for other than kernel32 is better to import LoadLibraryA / GetProcAddressA // FreeLibraryA and use there typedef struct { HMODULE hModuleOut; void *pAddressIn; __typeof__(GetModuleHandleExA) *fnGetModuleHandleExA; } RemoteFuncContext; //declaring functions before and after to serve as barriers, and to know the function size //the function must not use constant strings or any other constant that would be end being in .data .rodata etc... sections //those must reside on the context if required, so no accessing global or TLS variables //no directly accessing any other functions except those that are forcefully inlined void PIC RemoteFuncA() {} BOOL PIC RemoteFuncN( RemoteFuncContext *p ) { return p->fnGetModuleHandleExA( 0x6 , (LPCSTR)p->pAddressIn , &(p->hModuleOut) ); } void PIC RemoteFuncZ() {} assert( ((uintptr_t)RemoteFuncZ) > ((uintptr_t)RemoteFuncN) ); assert( ((uintptr_t)RemoteFuncN) > ((uintptr_t)RemoteFuncA) ); //RemoteFunctionN(); //printf("%p %p %p\n",RemoteFuncA,RemoteFuncN,RemoteFuncZ); //printf("size = %i\n", ((uintptr_t)RemoteFuncZ)-((uintptr_t)RemoteFuncN)); //module handles for import kernel32 import functions HMODULE hKernel32 = GetModuleHandle("kernel32.dll"); //initialize context with function pointers and input parameter or constants that would not be inside code RemoteFuncContext tCtx = { .pAddressIn = pAddress, .fnGetModuleHandleExA = (void*)GetProcAddress(hKernel32,"GetModuleHandleExA") }; if (!tCtx.fnGetModuleHandleExA) { puts("failed to get import addresses"); } //allocate memory on the remote process and copy code/data to it int CodeSize = (((uintptr_t)RemoteFuncZ)-((uintptr_t)RemoteFuncN)) , DataSize = sizeof(tCtx); RemoteFuncContext *pCtx = NTAllocateVirtualMemory( hProcess , NULL , CodeSize+DataSize , MEM_COMMIT , PAGE_EXECUTE_READWRITE ); if (!pCtx) { DWORD dwErr = GetLastError(); printf("Failed to allocated memory. Error: %d\n", dwErr); return NULL; } WriteProcessMemory( hProcess , pCtx , &tCtx , DataSize , NULL ); WriteProcessMemory( hProcess , pCtx+1 , RemoteFuncN , CodeSize , NULL ); //create thread and wait for it to finish DWORD dwTID; HANDLE hThread = CreateRemoteThread( hProcess , NULL , 0 , (LPTHREAD_START_ROUTINE)(pCtx+1) , pCtx , 0 , &dwTID ); if (!hThread) { puts("Failed to create remote thread"); } else { WaitForSingleObject( hThread , INFINITE ); CloseHandle(hThread); } //copy back structure data (output) so it can even do a partial copy of the structure with just OUTPUT elements ReadProcessMemory( hProcess , pCtx , &tCtx , sizeof(tCtx) , NULL ); VirtualFreeEx( hProcess , pCtx , CodeSize+DataSize , MEM_RELEASE ); //done return tCtx.hModuleOut; } // Exception handler function void checkBits(DWORD pid) { /* check the bits of the process */ HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid); if (hProcess == NULL) { printf("Error: OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid) failed with error code %d\n", GetLastError()); return; } BOOL isWow64 = FALSE; if (!IsWow64Process(hProcess, &isWow64)) { printf("Error: !IsWow64Process(hProcess, &isWow64) failed with error code %d\n", GetLastError()); CloseHandle(hProcess); return; } if (isWow64) { printf("Process %d is running as a 32-bit process on a 64-bit system.\n", pid); } else { printf("Process %d is running as a 64-bit process.\n", pid); } CloseHandle(hProcess); } // Main function int main(int argc, char *argv[]) { // Check if target process ID was provided as argument if (argc < 2) { printf("Usage: %s <Process ID>\n", argv[0]); return 1; } HANDLE hNtDll = GetModuleHandle("ntdll.dll"); fnNtAllocateVirtualMemory = (void*)GetProcAddress(hNtDll, "NtAllocateVirtualMemory"); // Convert target process ID from string to integer DWORD processId = atoi(argv[1]); checkBits(processId); // Attach to target process if (!DebugActiveProcess(processId)) { printf("Error attaching to process (error code %d)\n", GetLastError()); return 1; } // Loop indefinitel DEBUG_EVENT event; while (WaitForDebugEvent(&event, INFINITE)) { switch (event.dwDebugEventCode) { case EXCEPTION_DEBUG_EVENT: printf("Exception occurred with code 0x%08X at address 0x%p ", event.u.Exception.ExceptionRecord.ExceptionCode, event.u.Exception.ExceptionRecord.ExceptionAddress); HMODULE moduleToTheAddress; if (!GetModuleHandleEx(0x00000004, (LPCSTR)event.u.Exception.ExceptionRecord.ExceptionAddress, &moduleToTheAddress)) { printf("Error GetModuleHandleEx(0x00000004, ptr, &moduleToTheAddress) (error code %d)\n", GetLastError()); /* Enumerating Modules Loaded */ HANDLE processHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processId); if (processHandle == NULL) { printf("Failed to open process handle.\n"); return 0; } HMODULE moduleTaken = RemoteAddressToModule( processHandle, (void*) event.u.Exception.ExceptionRecord.ExceptionAddress ); char moduleName[MAX_PATH]; GetModuleFileNameEx(processHandle, moduleTaken, moduleName, MAX_PATH); printf(" Module Name: %s", moduleName); CloseHandle(processHandle); }else{ char moduleName[MAX_PATH]; GetModuleFileName(moduleToTheAddress, moduleName, MAX_PATH); printf(" Module Name: %s", moduleName); /* Enumerating Modules Loaded */ HANDLE processHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processId); if (processHandle == NULL) { printf("Failed to open process handle.\n"); return 0; } HMODULE moduleTaken = RemoteAddressToModule( processHandle, (void*) event.u.Exception.ExceptionRecord.ExceptionAddress ); char moduleName2[MAX_PATH]; GetModuleFileNameEx(processHandle, moduleTaken, moduleName2, MAX_PATH); printf(" Module Name: %s", moduleName2); CloseHandle(processHandle); } printf("\n"); ContinueDebugEvent(event.dwProcessId, event.dwThreadId, DBG_CONTINUE); break; default: ContinueDebugEvent(event.dwProcessId, event.dwThreadId, DBG_CONTINUE); break; } } // Detach from target process DebugActiveProcessStop(processId); return 0; }