void osReleaseFreeMemory(void) { alloc_rec *prev_a, *a; alloc_rec head_a; block_rec *prev_fb, *fb; block_rec head_fb; char *a_end, *fb_end; /* go through allocs and free_blocks in lockstep, looking for allocs that are completely free, and uncommit them */ head_a.base = 0; head_a.size = 0; head_a.next = allocs; head_fb.base = 0; head_fb.size = 0; head_fb.next = free_blocks; prev_a = &head_a; a = allocs; prev_fb = &head_fb; fb = free_blocks; while (a != NULL) { a_end = a->base + a->size; /* If a is freeable then there is a single freeblock in fb that covers it. The end of this free block must be >= the end of a, so skip anything in fb that ends before a. */ while (fb != NULL && fb->base + fb->size < a_end) { prev_fb = fb; fb = fb->next; } if (fb == NULL) { /* If we have nothing left in fb, then neither a nor anything later in the list is freeable, so we are done. */ break; } else { fb_end = fb->base + fb->size; /* We have a candidate fb. But does it really cover a? */ if (fb->base <= a->base) { /* Yes, the alloc is within the free block. Now we need to know if it sticks out at either end. */ if (fb_end == a_end) { if (fb->base == a->base) { /* fb and a are identical, so just free fb */ prev_fb->next = fb->next; stgFree(fb); fb = prev_fb->next; } else { /* fb begins earlier, so truncate it to not include a */ fb->size = a->base - fb->base; } } else { /* fb ends later, so we'll make fb just be the part after a. First though, if it also starts earlier, we make a new free block record for the before bit. */ if (fb->base != a->base) { block_rec *new_fb; new_fb = (block_rec *)stgMallocBytes(sizeof(block_rec), "osReleaseFreeMemory"); new_fb->base = fb->base; new_fb->size = a->base - fb->base; new_fb->next = fb; prev_fb->next = new_fb; } fb->size = fb_end - a_end; fb->base = a_end; } /* Now we can free the alloc */ prev_a->next = a->next; if(!VirtualFree((void *)a->base, 0, MEM_RELEASE)) { sysErrorBelch("freeAllMBlocks: VirtualFree MEM_RELEASE " "failed"); stg_exit(EXIT_FAILURE); } stgFree(a); a = prev_a->next; } else { /* Otherwise this alloc is not freeable, so go on to the next one */ prev_a = a; a = a->next; } } } allocs = head_a.next; free_blocks = head_fb.next; }
static GFINLINE void my_large_gf_free(void *ptr) { if (ptr) VirtualFree(ptr, 0, MEM_RELEASE); }
/********************************************************************** * 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); // 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 ) { dbg_printf("Trying to load PE image for unsupported architecture ("); switch (nt->FileHeader.Machine) { case IMAGE_FILE_MACHINE_UNKNOWN: dbg_printf("Unknown"); break; case IMAGE_FILE_MACHINE_I860: dbg_printf("I860"); break; case IMAGE_FILE_MACHINE_R3000: dbg_printf("R3000"); break; case IMAGE_FILE_MACHINE_R4000: dbg_printf("R4000"); break; case IMAGE_FILE_MACHINE_R10000: dbg_printf("R10000"); break; case IMAGE_FILE_MACHINE_ALPHA: dbg_printf("Alpha"); break; case IMAGE_FILE_MACHINE_POWERPC: dbg_printf("PowerPC"); break; default: dbg_printf("Unknown-%04x", nt->FileHeader.Machine); break; } dbg_printf(")\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 && !strstr(filename, "xanlib.dll")) { 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; }
SystemProcessInformation::~SystemProcessInformation() { VirtualFree( m_pBuffer, 0, MEM_RELEASE ); }
void OSAllocator::decommit(void* address, size_t bytes) { bool result = VirtualFree(address, bytes, MEM_DECOMMIT); if (!result) CRASH(); }
void STDCALL OSVirtualFree(LPVOID lpData) { VirtualFree(lpData, 0, MEM_RELEASE); }
void ExecutablePool::systemRelease(const ExecutablePool::Allocation& alloc) { VirtualFree(alloc.pages, 0, MEM_RELEASE); }
static int unreserveObjectAddresses(int i) { return VirtualFree((LPVOID)(SHAREDMEMBASEADDRESS+i*1024*1024), 0, MEM_RELEASE ); }
void Munmap(uptr base, u32 size) { if( base == NULL ) return; VirtualFree((void*)base, size, MEM_DECOMMIT); VirtualFree((void*)base, 0, MEM_RELEASE); }
int main(int argc, char* argv[]) { int NoProtect = 0; AllowLinear = true; double MaxMSE = 4.0; CmdLineArgs args; if (args.size() == 1) { Usage(); return 1; } const char* InputDir = NULL; const char* OutputFilename = "Textures.xpr"; for (unsigned int i = 1; i < args.size(); ++i) { if (!stricmp(args[i], "-help") || !stricmp(args[i], "-h") || !stricmp(args[i], "-?")) { Usage(); return 1; } else if (!stricmp(args[i], "-input") || !stricmp(args[i], "-i")) { InputDir = args[++i]; } else if (!stricmp(args[i], "-output") || !stricmp(args[i], "-o")) { OutputFilename = args[++i]; } else if (!stricmp(args[i], "-noprotect") || !stricmp(args[i], "-p")) { NoProtect = 1; } else if (!stricmp(args[i], "-onlyswizzled") || !stricmp(args[i], "-s")) { AllowLinear = false; } else if (!stricmp(args[i], "-quality") || !stricmp(args[i], "-q")) { ++i; if (!stricmp(args[i], "min")) { MaxMSE = DBL_MAX; } else if (!stricmp(args[i], "low")) { MaxMSE = 20.0; } else if (!stricmp(args[i], "normal")) { MaxMSE = 4.0; } else if (!stricmp(args[i], "high")) { MaxMSE = 1.5; } else if (!stricmp(args[i], "max")) { MaxMSE = 0.0; } else { printf("Unrecognised quality setting: %s\n", args[i]); } } else { printf("Unrecognised command line flag: %s\n", args[i]); } } // Initialize DirectDraw pD3D = Direct3DCreate8(D3D_SDK_VERSION); if (pD3D == NULL) { puts("Cannot init D3D"); return 1; } HRESULT hr; D3DDISPLAYMODE dispMode; D3DPRESENT_PARAMETERS presentParams; pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &dispMode); ZeroMemory(&presentParams, sizeof(presentParams)); presentParams.Windowed = TRUE; presentParams.hDeviceWindow = GetConsoleWindow(); presentParams.SwapEffect = D3DSWAPEFFECT_COPY; presentParams.BackBufferWidth = 8; presentParams.BackBufferHeight = 8; presentParams.BackBufferFormat = dispMode.Format; hr = pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, NULL, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &presentParams, &pD3DDevice); if (FAILED(hr)) { printf("Cannot init D3D device: %08x\n", hr); pD3D->Release(); return 1; } char HomeDir[MAX_PATH]; GetCurrentDirectory(MAX_PATH, HomeDir); XPRFile.OutputBuf = (char*)VirtualAlloc(0, 64 * 1024 * 1024, MEM_RESERVE, PAGE_NOACCESS); if (!XPRFile.OutputBuf) { printf("Memory allocation failure: %08x\n", GetLastError()); pD3DDevice->Release(); pD3D->Release(); return 1; } Bundler.StartBundle(); // Scan the input directory (or current dir if false) for media files ConvertDirectory(InputDir, NULL, MaxMSE); VirtualFree(XPRFile.OutputBuf, 0, MEM_RELEASE); pD3DDevice->Release(); pD3D->Release(); SetCurrentDirectory(HomeDir); DWORD attr = GetFileAttributes(OutputFilename); if (attr != -1 && (attr & FILE_ATTRIBUTE_DIRECTORY)) { SetCurrentDirectory(OutputFilename); OutputFilename = "Textures.xpr"; } printf("\nWriting bundle: %s", OutputFilename); int BundleSize = Bundler.WriteBundle(OutputFilename, NoProtect); if (BundleSize == -1) { printf("\nERROR: %08x\n", GetLastError()); return 1; } printf("\nUncompressed texture size: %6dkB\nCompressed texture size: %8dkB\nBundle size: %8dkB\n\nWasted Pixels: %u/%u (%5.2f%%)\n", (UncompressedSize + 1023) / 1024, (((CompressedSize + 1023) / 1024) + 3) & ~3, (BundleSize + 1023) / 1024, TotalDstPixels - TotalSrcPixels, TotalDstPixels, 100.f * (float)(TotalDstPixels - TotalSrcPixels) / (float)TotalDstPixels); return 0; }
static void ReleaseRegion(void *page) { VirtualFree(page, PAGESIZE, MEM_RELEASE); }
//Returns a record matching qurey or null pointer USN_RECORD * Engine::GetUSN(std::wstring & CheckFor){ MFT_ENUM_DATA mft_enum_data; DWORD bytecount = 1; void * buffer; USN_RECORD * record; USN_RECORD * recordend; USN_JOURNAL_DATA * journal; DWORDLONG nextid; DWORDLONG filecount = 0; buffer = VirtualAlloc(NULL, BUFFER_SIZE, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); if (buffer == NULL) { //printf("VirtualAlloc: %u\n", GetLastError()); return nullptr; } //TODO: CHECK ALL NTFS DRIVES drive = CreateFile("\\\\?\\C:", GENERIC_READ, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_FLAG_NO_BUFFERING, NULL); if (drive == INVALID_HANDLE_VALUE) { //printf("CreateFile: %u\n", GetLastError()); return nullptr; } if (!DeviceIoControl(drive, FSCTL_QUERY_USN_JOURNAL, NULL, 0, buffer, BUFFER_SIZE, &bytecount, NULL)) { //printf("FSCTL_QUERY_USN_JOURNAL: %u\n", GetLastError()); return nullptr; } journal = (USN_JOURNAL_DATA *)buffer; //printf("UsnJournalID: %lu\n", journal->UsnJournalID); //printf("FirstUsn: %lu\n", journal->FirstUsn); //printf("NextUsn: %lu\n", journal->NextUsn); //printf("LowestValidUsn: %lu\n", journal->LowestValidUsn); //printf("MaxUsn: %lu\n", journal->MaxUsn); //printf("MaximumSize: %lu\n", journal->MaximumSize); //printf("AllocationDelta: %lu\n", journal->AllocationDelta); maxusn = journal->MaxUsn; mft_enum_data.StartFileReferenceNumber = 0; mft_enum_data.LowUsn = 0; mft_enum_data.HighUsn = maxusn; //FSCTL_ENUM_USN_DATA for (;;) { if (!DeviceIoControl(drive, FSCTL_ENUM_USN_DATA, &mft_enum_data, sizeof(mft_enum_data), buffer, BUFFER_SIZE, &bytecount, NULL)) { //printf("FSCTL_ENUM_USN_DATA: %u\n", GetLastError()); //printf("Final ID: %lu\n", nextid); //printf("File count: %lu\n", filecount); return nullptr; } nextid = *((DWORDLONG *)buffer); record = (USN_RECORD *)((USN *)buffer + 1); recordend = (USN_RECORD *)(((BYTE *)buffer) + bytecount); while (record < recordend) { filecount++; if (check_record(record, CheckFor)) { return record; }; //show_record(record); record = (USN_RECORD *)(((BYTE *)record) + record->RecordLength); } mft_enum_data.StartFileReferenceNumber = nextid; } if (buffer) VirtualFree(buffer, NULL, MEM_RELEASE); return nullptr; }
SleshLibrary::SleshLibrary(const char* moduleName) { find_module_path(moduleName); hmod = NULL; string error; ULONG retadr = 0; DWORD rb; HANDLE hFile; IMAGE_DOS_HEADER DosHeader; IMAGE_NT_HEADERS PeHeader; IMAGE_SECTION_HEADER Section[MAX_SECTIONS]; char tmp[1024]; // откроем файл на чтение string path = find_module_path(moduleName); hFile = CreateFileA(path.c_str(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if ( hFile == INVALID_HANDLE_VALUE ) { getLastError(error, "CreateFile"); error += ": "; error += moduleName; throw DllException(error.c_str()); } // считаем DOS заголовок if ( ReadFile(hFile, &DosHeader, sizeof(IMAGE_DOS_HEADER), &rb, 0) == 0 ) { getLastError(error, "ReadFile"); CloseHandle(hFile); throw DllException(error.c_str()); } if (DosHeader.e_magic == IMAGE_DOS_SIGNATURE) { // проверим сигнатуру // если есть какимето данные между DOS заголовком и PE // то считаем их. В MS компиляторах это часто Rich данные if (sizeof(IMAGE_DOS_HEADER) < DosHeader.e_lfanew) { if ( ReadFile(hFile, &tmp[0], DosHeader.e_lfanew - sizeof(IMAGE_DOS_HEADER), &rb, 0) == 0 ) { getLastError(error, "ReadFile"); CloseHandle(hFile); throw DllException(error.c_str()); } } // установим указатель в файле на PE заголовок if ( SetFilePointer(hFile, DosHeader.e_lfanew, 0, FILE_BEGIN) == INVALID_SET_FILE_POINTER ) { getLastError(error, "SetFilePointer"); CloseHandle(hFile); throw DllException(error.c_str()); } // считаем заголовок if ( ReadFile(hFile, &PeHeader, sizeof(IMAGE_NT_HEADERS), &rb, 0) == 0 ) { getLastError(error, "ReadFile"); CloseHandle(hFile); throw DllException(error.c_str()); } if ( PeHeader.Signature == IMAGE_NT_SIGNATURE ) { // проверим сигнатуру // считаем 10 секций if ( ReadFile(hFile, &Section[0], sizeof(IMAGE_SECTION_HEADER) * PeHeader.FileHeader.NumberOfSections, &rb, 0) == 0 ) { getLastError(error, "ReadFile"); CloseHandle(hFile); throw DllException(error.c_str()); } // выделим память столько, сколько указано в SIZE OF BASE retadr = (ULONG)VirtualAlloc(0, PeHeader.OptionalHeader.SizeOfImage, MEM_COMMIT | MEM_RESERVE | MEM_TOP_DOWN, PAGE_EXECUTE_READWRITE); if ( retadr == NULL ) { getLastError(error, "VirtualAlloc"); CloseHandle(hFile); throw DllException(error.c_str()); } // скопируем туда DOS заголовок memcpy((void*) retadr, &DosHeader, sizeof(IMAGE_DOS_HEADER)); // скопируем туда PE заголовок memcpy((void*)(retadr + DosHeader.e_lfanew), &PeHeader, sizeof(IMAGE_NT_HEADERS)); // скопируем туда таблицу секций memcpy((void*)(retadr + DosHeader.e_lfanew + sizeof(IMAGE_NT_HEADERS)), &Section[0], sizeof(IMAGE_SECTION_HEADER) * PeHeader.FileHeader.NumberOfSections); // если есть Rich данные то и их тоже скопируем if ( sizeof(IMAGE_DOS_HEADER) < DosHeader.e_lfanew ) { memcpy((void*)(retadr + sizeof(IMAGE_DOS_HEADER)), &tmp[0], DosHeader.e_lfanew - sizeof(IMAGE_DOS_HEADER)); } // обработаем каждую секцию for ( int i = 0; i < PeHeader.FileHeader.NumberOfSections; i++ ){ // установим указатель в файле не начало секции в файле if ( SetFilePointer(hFile, Section[i].PointerToRawData, 0, FILE_BEGIN) == INVALID_SET_FILE_POINTER ) { getLastError(error, "SetFilePointer"); CloseHandle(hFile); VirtualFree((LPVOID)retadr, 0, MEM_RELEASE); // очищаем память throw DllException(error.c_str()); } // считаем всё секцию if ( ReadFile(hFile, (void*)(retadr + Section[i].VirtualAddress), Section[i].SizeOfRawData, &rb,0) == 0 ) { getLastError(error, "ReadFile"); CloseHandle(hFile); VirtualFree((LPVOID)retadr, 0, MEM_RELEASE); throw DllException(error.c_str()); } } CloseHandle(hFile); // Обработаем релоки try { progressReloc(retadr); progressImport(retadr); } catch ( DllException e ) { VirtualFree((LPVOID)retadr, 0, MEM_RELEASE); throw DllException(e.what()); } __asm { mov eax, PeHeader.OptionalHeader.AddressOfEntryPoint add eax, retadr // EAX = ENTRY POINT push 0 push DLL_PROCESS_ATTACH // ставим флаг что подгрузили DLL push retadr call eax // передадим управление на точку входа в DLL } hmod = (HMODULE)retadr; } } }
void osReleaseHeapMemory (void) { VirtualFree(heap_base, 0, MEM_RELEASE); }
// from TitanEngine SDK - Property of ReversingLabs www.reversinglabs.com long long __stdcall hd_FindEx(HANDLE hProcess, LPVOID MemoryStart, DWORD MemorySize, LPVOID SearchPattern, DWORD PatternSize, LPBYTE WildCard) { /* Description: Searches for a specific pattern of bytes in a process. Syntax: long long FindEx( __in HANDLE hProcess, __in LPVOID MemoryStart, __in DWORD MemorySize, __in LPVOID SearchPattern, __in DWORD PatternSize, __in_opt WildCard ); Parameters: - Return value: - */ int i = NULL; int j = NULL; ULONG_PTR Return = NULL; LPVOID ueReadBuffer = NULL; PUCHAR SearchBuffer = NULL; PUCHAR CompareBuffer = NULL; MEMORY_BASIC_INFORMATION memoryInformation = {}; ULONG_PTR ueNumberOfBytesRead = NULL; LPVOID currentSearchPosition = NULL; DWORD currentSizeOfSearch = NULL; BYTE nWildCard = NULL; if(WildCard == NULL){WildCard = &nWildCard;} if(hProcess != NULL && MemoryStart != NULL && MemorySize != NULL){ if(hProcess != GetCurrentProcess()){ ueReadBuffer = VirtualAlloc(NULL, MemorySize, MEM_COMMIT, PAGE_READWRITE); if(!ReadProcessMemory(hProcess, MemoryStart, ueReadBuffer, MemorySize, &ueNumberOfBytesRead)){ if(ueNumberOfBytesRead == NULL){ if(VirtualQueryEx(hProcess, MemoryStart, &memoryInformation, sizeof memoryInformation) != NULL){ MemorySize = (DWORD)((ULONG_PTR)memoryInformation.BaseAddress + memoryInformation.RegionSize - (ULONG_PTR)MemoryStart); if(!ReadProcessMemory(hProcess, MemoryStart, ueReadBuffer, MemorySize, &ueNumberOfBytesRead)){ VirtualFree(ueReadBuffer, NULL, MEM_RELEASE); return(NULL); }else{ SearchBuffer = (PUCHAR)ueReadBuffer; } }else{ VirtualFree(ueReadBuffer, NULL, MEM_RELEASE); return(NULL); } }else{ SearchBuffer = (PUCHAR)ueReadBuffer; } }else{ SearchBuffer = (PUCHAR)ueReadBuffer; } }else{ SearchBuffer = (PUCHAR)MemoryStart; } __try{ CompareBuffer = (PUCHAR)SearchPattern; for(i = 0; i < (int)MemorySize && Return == NULL; i++){ for(j = 0; j < (int)PatternSize; j++){ if(CompareBuffer[j] != *(PUCHAR)WildCard && SearchBuffer[i + j] != CompareBuffer[j]){ break; } } if(j == (int)PatternSize){ Return = (ULONG_PTR)MemoryStart + i; } } VirtualFree(ueReadBuffer, NULL, MEM_RELEASE); return(Return); }__except(EXCEPTION_EXECUTE_HANDLER){ VirtualFree(ueReadBuffer, NULL, MEM_RELEASE); return(NULL); } }else{ return(NULL);
int __cdecl main(int argc, char *argv[]) { LPVOID PageOne, PageTwo, PageThree; if(0 != (PAL_Initialize(argc, argv))) { return FAIL; } /* Reserve enough space for four pages. We'll commit this memory and set the correct access for each page below. */ PageOne = VirtualAlloc(NULL, PAGE_SIZE*4, MEM_RESERVE, PAGE_NOACCESS); if(PageOne == NULL) { Fail("ERROR: VirtualAlloc failed to reserve the required memory.\n"); } /* Set the first Page to PAGE_NOACCESS */ PageOne = VirtualAlloc(PageOne, PAGE_SIZE, MEM_COMMIT, PAGE_NOACCESS); if(PageOne == NULL) { VirtualFree(PageOne,0,MEM_RELEASE); Fail("ERROR: VirtualAlloc failed to commit the required memory " "for the first page.\n"); } /* Set the second Page to PAGE_READWRITE */ PageTwo = VirtualAlloc(((BYTE*)PageOne)+PAGE_SIZE, PAGE_SIZE, MEM_COMMIT, PAGE_READWRITE); if(PageTwo == NULL) { VirtualFree(PageOne,0,MEM_RELEASE); Fail("ERROR: VirtualAlloc failed to allocate the required memory " "for the second page. %d\n",GetLastError()); } /* Set the third Page to PAGE_NOACCESS */ PageThree = VirtualAlloc(((BYTE*)PageTwo) + (2 * PAGE_SIZE), PAGE_SIZE, MEM_COMMIT, PAGE_NOACCESS); if(PageThree == NULL) { VirtualFree(PageOne,0,MEM_RELEASE); Fail("ERROR: VirtualAlloc failed to allocate the required memory. " "For the third page.\n"); } /* Check that calling IsBadWritePtr on the first page returns non-zero */ if(IsBadWritePtr(PageThree,PAGE_SIZE) == 0) { VirtualFree(PageOne,0,MEM_RELEASE); Fail("ERROR: Called IsBadWritePtr on a page which was set NOACCESS " "but the return value was 0, indicating that the memory is " "writable.\n"); } /* Check that calling IsBadWritePtr on the middle page returns 0 */ if(IsBadWritePtr(PageTwo,PAGE_SIZE) != 0) { VirtualFree(PageOne,0,MEM_RELEASE); Fail("ERROR: IsBadWritePtr didn't return 0 when called on a " "page which should have been writable.\n"); } /* Check that calling IsBadWritePtr on the third page returns non-zero */ if(IsBadWritePtr(PageThree,PAGE_SIZE) == 0) { VirtualFree(PageOne,0,MEM_RELEASE); Fail("ERROR: Called IsBadWritePtr on a page which was set NOACCESS " "but the return value was 0, indicating that the memory is " "writable.\n"); } VirtualFree(PageOne,0,MEM_RELEASE); PAL_Terminate(); return PASS; }
void os_free(void* ptr, size_t bytes) { if (bytes == 0) return; VirtualFree(ptr,0,MEM_RELEASE); }
int MVM_platform_free_pages(void *pages, size_t size) { (void)size; return VirtualFree(pages, 0, MEM_RELEASE); }
FastReadStream::~FastReadStream() { delete pHeaders; if (pBuffer) VirtualFree(pBuffer, 0, MEM_RELEASE); }
void * mmap_realloc (void **var, size_t nbytes) { MEMORY_BASIC_INFORMATION memInfo, m2; void *old_ptr; if (*var == NULL) return mmap_alloc (var, nbytes); /* This case happens in init_buffer(). */ if (nbytes == 0) { mmap_free (var); return mmap_alloc (var, nbytes); } memset (&memInfo, 0, sizeof (memInfo)); if (VirtualQuery (*var, &memInfo, sizeof (memInfo)) == 0) DebPrint (("mmap_realloc: VirtualQuery error = %ld\n", GetLastError ())); /* We need to enlarge the block. */ if (memInfo.RegionSize < nbytes) { memset (&m2, 0, sizeof (m2)); if (VirtualQuery ((char *)*var + memInfo.RegionSize, &m2, sizeof(m2)) == 0) DebPrint (("mmap_realloc: VirtualQuery error = %ld\n", GetLastError ())); /* If there is enough room in the current reserved area, then commit more pages as needed. */ if (m2.State == MEM_RESERVE && m2.AllocationBase == memInfo.AllocationBase && nbytes <= memInfo.RegionSize + m2.RegionSize) { void *p; p = VirtualAlloc (*var, nbytes, MEM_COMMIT, PAGE_READWRITE); if (!p /* && GetLastError() != ERROR_NOT_ENOUGH_MEMORY */) { DebPrint (("realloc enlarge: VirtualAlloc (%p + %I64x, %I64x) error %ld\n", *var, (uint64_t)memInfo.RegionSize, (uint64_t)(nbytes - memInfo.RegionSize), GetLastError ())); DebPrint (("next region: %p %p %I64x %x\n", m2.BaseAddress, m2.AllocationBase, (uint64_t)m2.RegionSize, m2.AllocationProtect)); } else return *var; } /* Else we must actually enlarge the block by allocating a new one and copying previous contents from the old to the new one. */ old_ptr = *var; if (mmap_alloc (var, nbytes)) { CopyMemory (*var, old_ptr, memInfo.RegionSize); mmap_free (&old_ptr); return *var; } else { /* We failed to reallocate the buffer. */ *var = old_ptr; return NULL; } } /* If we are shrinking by more than one page... */ if (memInfo.RegionSize > nbytes + getpagesize()) { /* If we are shrinking a lot... */ if ((memInfo.RegionSize / 2) > nbytes) { /* Let's give some memory back to the system and release some pages. */ old_ptr = *var; if (mmap_alloc (var, nbytes)) { CopyMemory (*var, old_ptr, nbytes); mmap_free (&old_ptr); return *var; } else { /* In case we fail to shrink, try to go on with the old block. But that means there is a lot of memory pressure. We could also decommit pages. */ *var = old_ptr; return *var; } } /* We still can decommit pages. */ if (VirtualFree ((char *)*var + nbytes + get_page_size(), memInfo.RegionSize - nbytes - get_page_size(), MEM_DECOMMIT) == 0) DebPrint (("mmap_realloc: VirtualFree error %ld\n", GetLastError ())); return *var; } /* Not enlarging, not shrinking by more than one page. */ return *var; }
void OsMemory_free_chunk(address chunk_ptr) { VirtualFree(chunk_ptr, 0, MEM_RELEASE); }
/*********************************************************************** * VxDCall_VMM */ static DWORD VxDCall_VMM( DWORD service, CONTEXT86 *context ) { switch ( LOWORD(service) ) { case 0x0011: /* RegOpenKey */ { HKEY hkey = (HKEY) stack32_pop( context ); LPCSTR lpszSubKey = (LPCSTR)stack32_pop( context ); LPHKEY retkey = (LPHKEY)stack32_pop( context ); return RegOpenKeyA( hkey, lpszSubKey, retkey ); } case 0x0012: /* RegCreateKey */ { HKEY hkey = (HKEY) stack32_pop( context ); LPCSTR lpszSubKey = (LPCSTR)stack32_pop( context ); LPHKEY retkey = (LPHKEY)stack32_pop( context ); return RegCreateKeyA( hkey, lpszSubKey, retkey ); } case 0x0013: /* RegCloseKey */ { HKEY hkey = (HKEY)stack32_pop( context ); return RegCloseKey( hkey ); } case 0x0014: /* RegDeleteKey */ { HKEY hkey = (HKEY) stack32_pop( context ); LPCSTR lpszSubKey = (LPCSTR)stack32_pop( context ); return RegDeleteKeyA( hkey, lpszSubKey ); } case 0x0015: /* RegSetValue */ { HKEY hkey = (HKEY) stack32_pop( context ); LPCSTR lpszSubKey = (LPCSTR)stack32_pop( context ); DWORD dwType = (DWORD) stack32_pop( context ); LPCSTR lpszData = (LPCSTR)stack32_pop( context ); DWORD cbData = (DWORD) stack32_pop( context ); return RegSetValueA( hkey, lpszSubKey, dwType, lpszData, cbData ); } case 0x0016: /* RegDeleteValue */ { HKEY hkey = (HKEY) stack32_pop( context ); LPSTR lpszValue = (LPSTR)stack32_pop( context ); return RegDeleteValueA( hkey, lpszValue ); } case 0x0017: /* RegQueryValue */ { HKEY hkey = (HKEY) stack32_pop( context ); LPSTR lpszSubKey = (LPSTR) stack32_pop( context ); LPSTR lpszData = (LPSTR) stack32_pop( context ); LPDWORD lpcbData = (LPDWORD)stack32_pop( context ); return RegQueryValueA( hkey, lpszSubKey, lpszData, lpcbData ); } case 0x0018: /* RegEnumKey */ { HKEY hkey = (HKEY) stack32_pop( context ); DWORD iSubkey = (DWORD)stack32_pop( context ); LPSTR lpszName = (LPSTR)stack32_pop( context ); DWORD lpcchName = (DWORD)stack32_pop( context ); return RegEnumKeyA( hkey, iSubkey, lpszName, lpcchName ); } case 0x0019: /* RegEnumValue */ { HKEY hkey = (HKEY) stack32_pop( context ); DWORD iValue = (DWORD) stack32_pop( context ); LPSTR lpszValue = (LPSTR) stack32_pop( context ); LPDWORD lpcchValue = (LPDWORD)stack32_pop( context ); LPDWORD lpReserved = (LPDWORD)stack32_pop( context ); LPDWORD lpdwType = (LPDWORD)stack32_pop( context ); LPBYTE lpbData = (LPBYTE) stack32_pop( context ); LPDWORD lpcbData = (LPDWORD)stack32_pop( context ); return RegEnumValueA( hkey, iValue, lpszValue, lpcchValue, lpReserved, lpdwType, lpbData, lpcbData ); } case 0x001A: /* RegQueryValueEx */ { HKEY hkey = (HKEY) stack32_pop( context ); LPSTR lpszValue = (LPSTR) stack32_pop( context ); LPDWORD lpReserved = (LPDWORD)stack32_pop( context ); LPDWORD lpdwType = (LPDWORD)stack32_pop( context ); LPBYTE lpbData = (LPBYTE) stack32_pop( context ); LPDWORD lpcbData = (LPDWORD)stack32_pop( context ); return RegQueryValueExA( hkey, lpszValue, lpReserved, lpdwType, lpbData, lpcbData ); } case 0x001B: /* RegSetValueEx */ { HKEY hkey = (HKEY) stack32_pop( context ); LPSTR lpszValue = (LPSTR) stack32_pop( context ); DWORD dwReserved = (DWORD) stack32_pop( context ); DWORD dwType = (DWORD) stack32_pop( context ); LPBYTE lpbData = (LPBYTE)stack32_pop( context ); DWORD cbData = (DWORD) stack32_pop( context ); return RegSetValueExA( hkey, lpszValue, dwReserved, dwType, lpbData, cbData ); } case 0x001C: /* RegFlushKey */ { HKEY hkey = (HKEY)stack32_pop( context ); return RtlNtStatusToDosError (NtFlushKey (hkey)); } case 0x001D: /* RegQueryInfoKey */ { /* NOTE: This VxDCall takes only a subset of the parameters that the corresponding Win32 API call does. The implementation in Win95 ADVAPI32 sets all output parameters not mentioned here to zero. */ HKEY hkey = (HKEY) stack32_pop( context ); LPDWORD lpcSubKeys = (LPDWORD)stack32_pop( context ); LPDWORD lpcchMaxSubKey = (LPDWORD)stack32_pop( context ); LPDWORD lpcValues = (LPDWORD)stack32_pop( context ); LPDWORD lpcchMaxValueName = (LPDWORD)stack32_pop( context ); LPDWORD lpcchMaxValueData = (LPDWORD)stack32_pop( context ); return RegQueryInfoKeyA( hkey, NULL, NULL, NULL, lpcSubKeys, lpcchMaxSubKey, NULL, lpcValues, lpcchMaxValueName, lpcchMaxValueData, NULL, NULL ); } case 0x0021: /* RegLoadKey */ { HKEY hkey = (HKEY) stack32_pop( context ); LPCSTR lpszSubKey = (LPCSTR)stack32_pop( context ); LPCSTR lpszFile = (LPCSTR)stack32_pop( context ); return RegLoadKeyA( hkey, lpszSubKey, lpszFile ); } case 0x0022: /* RegUnLoadKey */ { HKEY hkey = (HKEY) stack32_pop( context ); LPCSTR lpszSubKey = (LPCSTR)stack32_pop( context ); FIXME ("(%p, %s): stub (should call NtUnloadKey)\n", (void *)hkey, lpszSubKey); return ERROR_SUCCESS; } case 0x0023: /* RegSaveKey */ { HKEY hkey = (HKEY) stack32_pop( context ); LPCSTR lpszFile = (LPCSTR)stack32_pop( context ); LPSECURITY_ATTRIBUTES sa = (LPSECURITY_ATTRIBUTES)stack32_pop( context ); return RegSaveKeyA( hkey, lpszFile, sa ); } #if 0 /* Functions are not yet implemented in misc/registry.c */ case 0x0024: /* RegRemapPreDefKey */ case 0x0026: /* RegQueryMultipleValues */ #endif case 0x0027: /* RegReplaceKey */ { HKEY hkey = (HKEY) stack32_pop( context ); LPCSTR lpszSubKey = (LPCSTR)stack32_pop( context ); LPCSTR lpszNewFile= (LPCSTR)stack32_pop( context ); LPCSTR lpszOldFile= (LPCSTR)stack32_pop( context ); FIXME ("(%p, %s, %s, %s): stub (should call NtReplaceKey)\n", (void *)hkey, lpszSubKey, lpszNewFile, lpszOldFile); return ERROR_SUCCESS; } case 0x0000: /* PageReserve */ { LPVOID address; LPVOID ret; DWORD psize = getpagesize(); ULONG page = (ULONG) stack32_pop( context ); ULONG npages = (ULONG) stack32_pop( context ); ULONG flags = (ULONG) stack32_pop( context ); TRACE("PageReserve: page: %08lx, npages: %08lx, flags: %08lx partial stub!\n", page, npages, flags ); if ( page == PR_SYSTEM ) { ERR("Can't reserve ring 1 memory\n"); return -1; } /* FIXME: This has to be handled separately for the separate address-spaces we now have */ if ( page == PR_PRIVATE || page == PR_SHARED ) page = 0; /* FIXME: Handle flags in some way */ address = (LPVOID )(page * psize); ret = VirtualAlloc ( address, ( npages * psize ), MEM_RESERVE, 0 ); TRACE("PageReserve: returning: %08lx\n", (DWORD )ret ); if ( ret == NULL ) return -1; else return (DWORD )ret; } case 0x0001: /* PageCommit */ { LPVOID address; LPVOID ret; DWORD virt_perm; DWORD psize = getpagesize(); ULONG page = (ULONG) stack32_pop( context ); ULONG npages = (ULONG) stack32_pop( context ); ULONG hpd = (ULONG) stack32_pop( context ); ULONG pagerdata = (ULONG) stack32_pop( context ); ULONG flags = (ULONG) stack32_pop( context ); TRACE("PageCommit: page: %08lx, npages: %08lx, hpd: %08lx pagerdata: " "%08lx, flags: %08lx partial stub\n", page, npages, hpd, pagerdata, flags ); if ( flags & PC_USER ) if ( flags & PC_WRITEABLE ) virt_perm = PAGE_EXECUTE_READWRITE; else virt_perm = PAGE_EXECUTE_READ; else virt_perm = PAGE_NOACCESS; address = (LPVOID )(page * psize); ret = VirtualAlloc ( address, ( npages * psize ), MEM_COMMIT, virt_perm ); TRACE("PageCommit: Returning: %08lx\n", (DWORD )ret ); return (DWORD )ret; } case 0x0002: /* PageDecommit */ { LPVOID address; BOOL ret; DWORD psize = getpagesize(); ULONG page = (ULONG) stack32_pop( context ); ULONG npages = (ULONG) stack32_pop( context ); ULONG flags = (ULONG) stack32_pop( context ); TRACE("PageDecommit: page: %08lx, npages: %08lx, flags: %08lx partial stub\n", page, npages, flags ); address = (LPVOID )( page * psize ); ret = VirtualFree ( address, ( npages * psize ), MEM_DECOMMIT ); TRACE("PageDecommit: Returning: %s\n", ret ? "TRUE" : "FALSE" ); return ret; } case 0x000d: /* PageModifyPermissions */ { DWORD pg_old_perm; DWORD pg_new_perm; DWORD virt_old_perm; DWORD virt_new_perm; MEMORY_BASIC_INFORMATION mbi; LPVOID address; DWORD psize = getpagesize(); ULONG page = stack32_pop ( context ); ULONG npages = stack32_pop ( context ); ULONG permand = stack32_pop ( context ); ULONG permor = stack32_pop ( context ); TRACE("PageModifyPermissions %08lx %08lx %08lx %08lx partial stub\n", page, npages, permand, permor ); address = (LPVOID )( page * psize ); VirtualQuery ( address, &mbi, sizeof ( MEMORY_BASIC_INFORMATION )); virt_old_perm = mbi.Protect; switch ( virt_old_perm & mbi.Protect ) { case PAGE_READONLY: case PAGE_EXECUTE: case PAGE_EXECUTE_READ: pg_old_perm = PC_USER; break; case PAGE_READWRITE: case PAGE_WRITECOPY: case PAGE_EXECUTE_READWRITE: case PAGE_EXECUTE_WRITECOPY: pg_old_perm = PC_USER | PC_WRITEABLE; break; case PAGE_NOACCESS: default: pg_old_perm = 0; break; } pg_new_perm = pg_old_perm; pg_new_perm &= permand & ~PC_STATIC; pg_new_perm |= permor & ~PC_STATIC; virt_new_perm = ( virt_old_perm ) & ~0xff; if ( pg_new_perm & PC_USER ) { if ( pg_new_perm & PC_WRITEABLE ) virt_new_perm |= PAGE_EXECUTE_READWRITE; else virt_new_perm |= PAGE_EXECUTE_READ; } if ( ! VirtualProtect ( address, ( npages * psize ), virt_new_perm, &virt_old_perm ) ) { ERR("Can't change page permissions for %08lx\n", (DWORD )address ); return 0xffffffff; } TRACE("Returning: %08lx\n", pg_old_perm ); return pg_old_perm; } case 0x000a: /* PageFree */ { BOOL ret; LPVOID hmem = (LPVOID) stack32_pop( context ); DWORD flags = (DWORD ) stack32_pop( context ); TRACE("PageFree: hmem: %08lx, flags: %08lx partial stub\n", (DWORD )hmem, flags ); ret = VirtualFree ( hmem, 0, MEM_RELEASE ); context->Eax = ret; TRACE("Returning: %d\n", ret ); return 0; } case 0x001e: /* GetDemandPageInfo */ { DWORD dinfo = (DWORD)stack32_pop( context ); DWORD flags = (DWORD)stack32_pop( context ); /* GetDemandPageInfo is supposed to fill out the struct at * "dinfo" with various low-level memory management information. * Apps are certainly not supposed to call this, although it's * demoed and documented by Pietrek on pages 441-443 of "Windows * 95 System Programming Secrets" if any program needs a real * implementation of this. */ FIXME("GetDemandPageInfo(%08lx %08lx): stub!\n", dinfo, flags); return 0; } default: if (LOWORD(service) < N_VMM_SERVICE) FIXME( "Unimplemented service %s (%08lx)\n", VMM_Service_Name[LOWORD(service)], service); else FIXME( "Unknown service %08lx\n", service); break; } return 0xffffffff; /* FIXME */ }
BOOL SystemHandleInformation::Refresh() { DWORD size = 0x2000; DWORD needed = 0; DWORD i = 0; BOOL ret = TRUE; CString strType; m_HandleInfos.RemoveAll(); if ( !INtDll::NtDllStatus ) return FALSE; // Allocate the memory for the buffer SYSTEM_HANDLE_INFORMATION* pSysHandleInformation = (SYSTEM_HANDLE_INFORMATION*) VirtualAlloc( NULL, size, MEM_COMMIT, PAGE_READWRITE ); if ( pSysHandleInformation == NULL ) return FALSE; // Query the needed buffer size for the objects ( system wide ) if ( INtDll::NtQuerySystemInformation( 16, pSysHandleInformation, size, &needed ) != 0 ) { if ( needed == 0 ) { ret = FALSE; goto cleanup; } // The size was not enough VirtualFree( pSysHandleInformation, 0, MEM_RELEASE ); pSysHandleInformation = (SYSTEM_HANDLE_INFORMATION*) VirtualAlloc( NULL, size = needed + 256, MEM_COMMIT, PAGE_READWRITE ); } if ( pSysHandleInformation == NULL ) return FALSE; // Query the objects ( system wide ) if ( INtDll::NtQuerySystemInformation( 16, pSysHandleInformation, size, NULL ) != 0 ) { ret = FALSE; goto cleanup; } // Iterating through the objects for ( i = 0; i < pSysHandleInformation->Count; i++ ) { if ( !IsSupportedHandle( pSysHandleInformation->Handles[i] ) ) continue; // ProcessId filtering check if ( pSysHandleInformation->Handles[i].ProcessID == m_processId || m_processId == (DWORD)-1 ) { BOOL bAdd = FALSE; if ( m_strTypeFilter == _T("") ) bAdd = TRUE; else { // Type filtering GetTypeToken( (HANDLE)pSysHandleInformation->Handles[i].HandleNumber, strType, pSysHandleInformation->Handles[i].ProcessID ); bAdd = strType == m_strTypeFilter; } // That's it. We found one. if ( bAdd ) { pSysHandleInformation->Handles[i].HandleType = (WORD)(pSysHandleInformation->Handles[i].HandleType % 256); m_HandleInfos.AddTail( pSysHandleInformation->Handles[i] ); } } } cleanup: if ( pSysHandleInformation != NULL ) VirtualFree( pSysHandleInformation, 0, MEM_RELEASE ); return ret; }
void vfree (void *what, uint size) { VirtualFree(what, 0, MEM_RELEASE); }
BOOL MemoryDefaultFree(LPVOID lpAddress, SIZE_T dwSize, DWORD dwFreeType, void* userdata) { UNREFERENCED_PARAMETER(userdata); return VirtualFree(lpAddress, dwSize, dwFreeType); }
void free_file(BYTE* buffer, size_t buffer_size) { VirtualFree(buffer, buffer_size, MEM_RELEASE); }
static void ReleaseRegion(void *region, PRUword size) { VirtualFree(region, size, MEM_RELEASE); }
HMEMORYMODULE MemoryLoadLibraryEx(const void *data, CustomLoadLibraryFunc loadLibrary, CustomGetProcAddressFunc getProcAddress, CustomFreeLibraryFunc freeLibrary, void *userdata) { PMEMORYMODULE result; PIMAGE_DOS_HEADER dos_header; PIMAGE_NT_HEADERS old_header; unsigned char *code, *headers; SIZE_T locationDelta; SYSTEM_INFO sysInfo; HMODULE hModule; dos_header = (PIMAGE_DOS_HEADER)data; if (dos_header->e_magic != IMAGE_DOS_SIGNATURE) { SetLastError(ERROR_BAD_EXE_FORMAT); return NULL; } old_header = (PIMAGE_NT_HEADERS)&((const unsigned char *)(data))[dos_header->e_lfanew]; if (old_header->Signature != IMAGE_NT_SIGNATURE) { SetLastError(ERROR_BAD_EXE_FORMAT); return NULL; } #ifdef _WIN64 if (old_header->FileHeader.Machine != IMAGE_FILE_MACHINE_AMD64) { #else if (old_header->FileHeader.Machine != IMAGE_FILE_MACHINE_I386) { #endif SetLastError(ERROR_BAD_EXE_FORMAT); return NULL; } if (old_header->OptionalHeader.SectionAlignment & 1) { // Only support section alignments that are a multiple of 2 SetLastError(ERROR_BAD_EXE_FORMAT); return NULL; } // reserve memory for image of library // XXX: is it correct to commit the complete memory region at once? // calling DllEntry raises an exception if we don't... code = (unsigned char *)VirtualAlloc((LPVOID)(old_header->OptionalHeader.ImageBase), old_header->OptionalHeader.SizeOfImage, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); if (code == NULL) { // try to allocate memory at arbitrary position code = (unsigned char *)VirtualAlloc(NULL, old_header->OptionalHeader.SizeOfImage, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); if (code == NULL) { SetLastError(ERROR_OUTOFMEMORY); return NULL; } } result = (PMEMORYMODULE)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MEMORYMODULE)); if (result == NULL) { VirtualFree(code, 0, MEM_RELEASE); SetLastError(ERROR_OUTOFMEMORY); return NULL; } result->codeBase = code; result->isDLL = (old_header->FileHeader.Characteristics & IMAGE_FILE_DLL) != 0; result->loadLibrary = loadLibrary; result->getProcAddress = getProcAddress; result->freeLibrary = freeLibrary; result->userdata = userdata; hModule = LoadLibrary ("kernel32.dll"); if (hModule) { int (WINAPI *GetNativeSystemInfo) (SYSTEM_INFO *systemInfo); GetNativeSystemInfo = (void *) GetProcAddress (hModule, "GetNativeSystemInfo"); GetNativeSystemInfo(&sysInfo); } result->pageSize = sysInfo.dwPageSize; // commit memory for headers headers = (unsigned char *)VirtualAlloc(code, old_header->OptionalHeader.SizeOfHeaders, MEM_COMMIT, PAGE_READWRITE); // copy PE header to code memcpy(headers, dos_header, old_header->OptionalHeader.SizeOfHeaders); result->headers = (PIMAGE_NT_HEADERS)&((const unsigned char *)(headers))[dos_header->e_lfanew]; // update position result->headers->OptionalHeader.ImageBase = (uintptr_t)code; // copy sections from DLL file block to new memory location if (!CopySections((const unsigned char *) data, old_header, result)) { goto error; } // adjust base address of imported data locationDelta = (SIZE_T)(code - old_header->OptionalHeader.ImageBase); if (locationDelta != 0) { result->isRelocated = PerformBaseRelocation(result, locationDelta); } else { result->isRelocated = TRUE; } // load required dlls and adjust function table of imports if (!BuildImportTable(result)) { goto error; } // mark memory pages depending on section headers and release // sections that are marked as "discardable" if (!FinalizeSections(result)) { goto error; } // TLS callbacks are executed BEFORE the main loading if (!ExecuteTLS(result)) { goto error; } // get entry point of loaded library if (result->headers->OptionalHeader.AddressOfEntryPoint != 0) { if (result->isDLL) { DllEntryProc DllEntry = (DllEntryProc) (code + result->headers->OptionalHeader.AddressOfEntryPoint); // notify library about attaching to process BOOL successfull = (*DllEntry)((HINSTANCE)code, DLL_PROCESS_ATTACH, 0); if (!successfull) { SetLastError(ERROR_DLL_INIT_FAILED); goto error; } result->initialized = TRUE; } else { result->exeEntry = (ExeEntryProc) (code + result->headers->OptionalHeader.AddressOfEntryPoint); } } else { result->exeEntry = NULL; } return (HMEMORYMODULE)result; error: // cleanup MemoryFreeLibrary(result); return NULL; } FARPROC MemoryGetProcAddress(HMEMORYMODULE module, LPCSTR name) { unsigned char *codeBase = ((PMEMORYMODULE)module)->codeBase; DWORD idx; PIMAGE_EXPORT_DIRECTORY exports; PIMAGE_DATA_DIRECTORY directory = GET_HEADER_DICTIONARY((PMEMORYMODULE)module, IMAGE_DIRECTORY_ENTRY_EXPORT); if (directory->Size == 0) { // no export table found SetLastError(ERROR_PROC_NOT_FOUND); return NULL; } exports = (PIMAGE_EXPORT_DIRECTORY) (codeBase + directory->VirtualAddress); if (exports->NumberOfNames == 0 || exports->NumberOfFunctions == 0) { // DLL doesn't export anything SetLastError(ERROR_PROC_NOT_FOUND); return NULL; } if (HIWORD(name) == 0) { // load function by ordinal value if (LOWORD(name) < exports->Base) { SetLastError(ERROR_PROC_NOT_FOUND); return NULL; } idx = LOWORD(name) - exports->Base; } else { // search function name in list of exported names DWORD i; DWORD *nameRef = (DWORD *) (codeBase + exports->AddressOfNames); WORD *ordinal = (WORD *) (codeBase + exports->AddressOfNameOrdinals); BOOL found = FALSE; for (i=0; i<exports->NumberOfNames; i++, nameRef++, ordinal++) { if (_stricmp(name, (const char *) (codeBase + (*nameRef))) == 0) { idx = *ordinal; found = TRUE; break; } } if (!found) { // exported symbol not found SetLastError(ERROR_PROC_NOT_FOUND); return NULL; } } if (idx > exports->NumberOfFunctions) { // name <-> ordinal number don't match SetLastError(ERROR_PROC_NOT_FOUND); return NULL; } // AddressOfFunctions contains the RVAs to the "real" functions return (FARPROC) (codeBase + (*(DWORD *) (codeBase + exports->AddressOfFunctions + (idx*4)))); }
void ReserveBottomMemory() { #if defined(_WIN64) && defined(_DEBUG) static bool s_initialized = false; if ( s_initialized ) return; s_initialized = true; // Start by reserving large blocks of address space, and then // gradually reduce the size in order to capture all of the // fragments. Technically we should continue down to 64 KB but // stopping at 1 MB is sufficient to keep most allocators out. const size_t LOW_MEM_LINE = 0x100000000LL; size_t totalReservation = 0; size_t numVAllocs = 0; size_t numHeapAllocs = 0; size_t oneMB = 1024 * 1024; for (size_t size = 256 * oneMB; size >= oneMB; size /= 2) { for (;;) { void* p = VirtualAlloc(0, size, MEM_RESERVE, PAGE_NOACCESS); if (!p) break; if ((size_t)p >= LOW_MEM_LINE) { // We don't need this memory, so release it completely. VirtualFree(p, 0, MEM_RELEASE); break; } totalReservation += size; ++numVAllocs; } } // Now repeat the same process but making heap allocations, to use up // the already reserved heap blocks that are below the 4 GB line. HANDLE heap = GetProcessHeap(); for (size_t blockSize = 64 * 1024; blockSize >= 16; blockSize /= 2) { for (;;) { void* p = HeapAlloc(heap, 0, blockSize); if (!p) break; if ((size_t)p >= LOW_MEM_LINE) { // We don't need this memory, so release it completely. HeapFree(heap, 0, p); break; } totalReservation += blockSize; ++numHeapAllocs; } } // Perversely enough the CRT doesn't use the process heap. Suck up // the memory the CRT heap has already reserved. for (size_t blockSize = 64 * 1024; blockSize >= 16; blockSize /= 2) { for (;;) { void* p = malloc(blockSize); if (!p) break; if ((size_t)p >= LOW_MEM_LINE) { // We don't need this memory, so release it completely. free(p); break; } totalReservation += blockSize; ++numHeapAllocs; } } // Print diagnostics showing how many allocations we had to make in // order to reserve all of low memory, typically less than 200. char buffer[1000]; sprintf_s(buffer, "Reserved %1.3f MB (%d vallocs," "%d heap allocs) of low-memory.\n", totalReservation / (1024 * 1024.0), (int)numVAllocs, (int)numHeapAllocs); OutputDebugStringA(buffer); #endif }
void IH_GetImportTableAddresses() //Retrieve basic import data { HINSTANCE kernel32; // Handle to kernel32 unsigned int VirtualProtect_Addr; // VirtualProtect Address unsigned int OutputDebugStringA_Addr; // OutputDebugStringA Address unsigned int WriteProcessMemory_Addr; // WriteProcessMemory Address unsigned int GetEnvironmentVariableA_Addr; // GetEnvironmentVariableA Address unsigned int SetEnvironmentVariableA_Addr; // SetEnvironmentVariableA Address unsigned int LoadLibraryA_Addr; // LoadLibraryA Address unsigned int GetProcAddress_Addr; // GetProcAddress address DeleteFile("loaded_binary.mem"); DumpProcess(IH_fdProcessInfo->hProcess, (void*)g_fdImageBase, (char*)"loaded_binary.mem", g_fdEntryPoint); kernel32=GetModuleHandleA("kernel32"); VirtualProtect_Addr=ImporterGetRemoteAPIAddress(IH_fdProcessInfo->hProcess, (unsigned int)GetProcAddress(kernel32, "VirtualProtect")); OutputDebugStringA_Addr=ImporterGetRemoteAPIAddress(IH_fdProcessInfo->hProcess, (unsigned int)GetProcAddress(kernel32, "OutputDebugStringA")); GetEnvironmentVariableA_Addr=ImporterGetRemoteAPIAddress(IH_fdProcessInfo->hProcess, (unsigned int)GetProcAddress(kernel32, "GetEnvironmentVariableA")); SetEnvironmentVariableA_Addr=ImporterGetRemoteAPIAddress(IH_fdProcessInfo->hProcess, (unsigned int)GetProcAddress(kernel32, "SetEnvironmentVariableA")); LoadLibraryA_Addr=ImporterGetRemoteAPIAddress(IH_fdProcessInfo->hProcess, (unsigned int)GetProcAddress(kernel32, "LoadLibraryA")); GetProcAddress_Addr=ImporterGetRemoteAPIAddress(IH_fdProcessInfo->hProcess, (unsigned int)GetProcAddress(kernel32, "GetProcAddress")); WriteProcessMemory_Addr=ImporterGetRemoteAPIAddress(IH_fdProcessInfo->hProcess, (unsigned int)GetProcAddress(kernel32, "WriteProcessMemory")); HANDLE hFile=CreateFileA("loaded_binary.mem", GENERIC_ALL, 0, 0, OPEN_EXISTING, 0, 0); DWORD high=0,filesize=GetFileSize(hFile, &high); BYTE* dump_addr=(BYTE*)VirtualAlloc(VirtualAlloc(0, filesize+0x1000, MEM_RESERVE, PAGE_EXECUTE_READWRITE), filesize+0x1000, MEM_COMMIT, PAGE_EXECUTE_READWRITE); ReadFile(hFile, dump_addr, filesize, &high, 0); CloseHandle(hFile); unsigned int result_addr=0; // Find VirtualProtect address result_addr=FindDwordInMemory(dump_addr, VirtualProtect_Addr, filesize); if(result_addr) VirtualProtect_Addr=(unsigned int)(result_addr+g_fdImageBase); else VirtualProtect_Addr=0; g_PtrTargetData->VirtualProtect_Addr=VirtualProtect_Addr; // Find OutputDebugStringA address result_addr=FindDwordInMemory(dump_addr, OutputDebugStringA_Addr, filesize); if(result_addr) OutputDebugStringA_Addr=(unsigned int)(result_addr+g_fdImageBase); else OutputDebugStringA_Addr=0; g_PtrTargetData->OutputDebugStringA_Addr=OutputDebugStringA_Addr; // Find GetEnvironmentVariableA address result_addr=FindDwordInMemory(dump_addr, GetEnvironmentVariableA_Addr, filesize); if(result_addr) GetEnvironmentVariableA_Addr=(unsigned int)(result_addr+g_fdImageBase); else GetEnvironmentVariableA_Addr=0; g_PtrTargetData->GetEnvironmentVariableA_Addr=GetEnvironmentVariableA_Addr; // Find SetEnvironmentVariableA address result_addr=FindDwordInMemory(dump_addr, SetEnvironmentVariableA_Addr, filesize); if(result_addr) SetEnvironmentVariableA_Addr=(unsigned int)(result_addr+g_fdImageBase); else SetEnvironmentVariableA_Addr=0; g_PtrTargetData->SetEnvironmentVariableA_Addr=SetEnvironmentVariableA_Addr; // Find LoadLibraryA address result_addr=FindDwordInMemory(dump_addr, LoadLibraryA_Addr, filesize); if(result_addr) LoadLibraryA_Addr=(unsigned int)(result_addr+g_fdImageBase); else LoadLibraryA_Addr=0; g_PtrTargetData->LoadLibraryA_Addr=LoadLibraryA_Addr; // Find GetProcAddress address result_addr=FindDwordInMemory(dump_addr, GetProcAddress_Addr, filesize); if(result_addr) GetProcAddress_Addr=(unsigned int)(result_addr+g_fdImageBase); else GetProcAddress_Addr=0; g_PtrTargetData->GetProcAddress_Addr=GetProcAddress_Addr; // Find WriteProcessMemory address result_addr=FindDwordInMemory(dump_addr, WriteProcessMemory_Addr, filesize); if(result_addr) WriteProcessMemory_Addr=(unsigned int)(result_addr+g_fdImageBase); else WriteProcessMemory_Addr=0; g_PtrTargetData->WriteProcessMemory_Addr=WriteProcessMemory_Addr; // Free the memory and close the handle VirtualFree(dump_addr, filesize+0x1000, MEM_DECOMMIT); }