diff --git a/x64_dbg_dbg/_dbgfunctions.cpp b/x64_dbg_dbg/_dbgfunctions.cpp index 299a145e..21a2d1c8 100644 --- a/x64_dbg_dbg/_dbgfunctions.cpp +++ b/x64_dbg_dbg/_dbgfunctions.cpp @@ -224,9 +224,9 @@ void dbgfunctionsinit() _dbgfunctions.GetJitAuto = _getjitauto; _dbgfunctions.GetDefJit = dbggetdefjit; _dbgfunctions.GetProcessList = _getprocesslist; - _dbgfunctions.GetPageRights = dbggetpagerights; - _dbgfunctions.SetPageRights = dbgsetpagerights; - _dbgfunctions.PageRightsToString = dbgpagerightstostring; + _dbgfunctions.GetPageRights = MemGetPageRights; + _dbgfunctions.SetPageRights = MemSetPageRights; + _dbgfunctions.PageRightsToString = MemPageRightsToString; _dbgfunctions.IsProcessElevated = IsProcessElevated; _dbgfunctions.GetCmdline = _getcmdline; _dbgfunctions.SetCmdline = _setcmdline; diff --git a/x64_dbg_dbg/debugger.cpp b/x64_dbg_dbg/debugger.cpp index d989d5ab..dee3c169 100644 --- a/x64_dbg_dbg/debugger.cpp +++ b/x64_dbg_dbg/debugger.cpp @@ -1627,118 +1627,6 @@ static bool readwritejitkey(wchar_t* jit_key_value, DWORD* jit_key_vale_size, ch return (lRv == ERROR_SUCCESS); } -bool dbgpagerightstostring(DWORD protect, char* rights) -{ - memset(rights, 0, RIGHTS_STRING_SIZE); - - switch(protect & 0xFF) - { - case PAGE_EXECUTE: - strcpy_s(rights, RIGHTS_STRING_SIZE, "E---"); - break; - case PAGE_EXECUTE_READ: - strcpy_s(rights, RIGHTS_STRING_SIZE, "ER--"); - break; - case PAGE_EXECUTE_READWRITE: - strcpy_s(rights, RIGHTS_STRING_SIZE, "ERW-"); - break; - case PAGE_EXECUTE_WRITECOPY: - strcpy_s(rights, RIGHTS_STRING_SIZE, "ERWC"); - break; - case PAGE_NOACCESS: - strcpy_s(rights, RIGHTS_STRING_SIZE, "----"); - break; - case PAGE_READONLY: - strcpy_s(rights, RIGHTS_STRING_SIZE, "-R--"); - break; - case PAGE_READWRITE: - strcpy_s(rights, RIGHTS_STRING_SIZE, "-RW-"); - break; - case PAGE_WRITECOPY: - strcpy_s(rights, RIGHTS_STRING_SIZE, "-RWC"); - break; - } - - if(protect & PAGE_GUARD) - strcat_s(rights, RIGHTS_STRING_SIZE, "G"); - else - strcat_s(rights, RIGHTS_STRING_SIZE, "-"); - - return true; -} - -static uint dbggetpageligned(uint addr) -{ -#ifdef _WIN64 - addr &= 0xFFFFFFFFFFFFF000; -#else // _WIN32 - addr &= 0xFFFFF000; -#endif // _WIN64 - return addr; -} - -static bool dbgpagerightsfromstring(DWORD* protect, const char* rights_string) -{ - if(strlen(rights_string) < 2) - return false; - - *protect = 0; - if(rights_string[0] == 'G' || rights_string[0] == 'g') - { - *protect |= PAGE_GUARD; - rights_string++; - } - - if(_strcmpi(rights_string, "Execute") == 0) - *protect |= PAGE_EXECUTE; - else if(_strcmpi(rights_string, "ExecuteRead") == 0) - *protect |= PAGE_EXECUTE_READ; - else if(_strcmpi(rights_string, "ExecuteReadWrite") == 0) - *protect |= PAGE_EXECUTE_READWRITE; - else if(_strcmpi(rights_string, "ExecuteWriteCopy") == 0) - *protect |= PAGE_EXECUTE_WRITECOPY; - else if(_strcmpi(rights_string, "NoAccess") == 0) - *protect |= PAGE_NOACCESS; - else if(_strcmpi(rights_string, "ReadOnly") == 0) - *protect |= PAGE_READONLY; - else if(_strcmpi(rights_string, "ReadWrite") == 0) - *protect |= PAGE_READWRITE; - else if(_strcmpi(rights_string, "WriteCopy") == 0) - *protect |= PAGE_WRITECOPY; - - if(*protect == 0) - return false; - - return true; -} - -bool dbgsetpagerights(uint addr, const char* rights_string) -{ - DWORD protect; - DWORD old_protect; - - addr = dbggetpageligned(addr); - - if(!dbgpagerightsfromstring(& protect, rights_string)) - return false; - - if(VirtualProtectEx(fdProcessInfo->hProcess, (void*)addr, PAGE_SIZE, protect, & old_protect) == 0) - return false; - - return true; -} - -bool dbggetpagerights(uint addr, char* rights) -{ - addr = dbggetpageligned(addr); - - MEMORY_BASIC_INFORMATION mbi; - if(VirtualQueryEx(fdProcessInfo->hProcess, (const void*)addr, &mbi, sizeof(mbi)) == 0) - return false; - - return dbgpagerightstostring(mbi.Protect, rights); -} - bool dbggetjitauto(bool* auto_on, arch arch_in, arch* arch_out, readwritejitkey_error_t* rw_error_out) { wchar_t jit_entry[4] = L""; diff --git a/x64_dbg_dbg/debugger.h b/x64_dbg_dbg/debugger.h index 74ce23f0..31da21df 100644 --- a/x64_dbg_dbg/debugger.h +++ b/x64_dbg_dbg/debugger.h @@ -100,9 +100,6 @@ bool dbglistprocesses(std::vector* list); bool IsProcessElevated(); bool dbgsetcmdline(const char* cmd_line, cmdline_error_t* cmd_line_error); bool dbggetcmdline(char** cmd_line, cmdline_error_t* cmd_line_error); -bool dbggetpagerights(uint addr, char* rights); -bool dbgsetpagerights(uint addr, const char* rights_string); -bool dbgpagerightstostring(DWORD protect, char* rights); void dbgstartscriptthread(CBPLUGINSCRIPT cbScript); uint dbggetdebuggedbase(); diff --git a/x64_dbg_dbg/debugger_commands.cpp b/x64_dbg_dbg/debugger_commands.cpp index 91b866bf..9ac04a76 100644 --- a/x64_dbg_dbg/debugger_commands.cpp +++ b/x64_dbg_dbg/debugger_commands.cpp @@ -1832,7 +1832,7 @@ CMDRESULT cbDebugGetPageRights(int argc, char* argv[]) return STATUS_ERROR; } - if(!dbggetpagerights(addr, rights)) + if(!MemGetPageRights(addr, rights)) { dprintf("Error getting rights of page: %s\n", argv[1]); return STATUS_ERROR; @@ -1854,13 +1854,13 @@ CMDRESULT cbDebugSetPageRights(int argc, char* argv[]) return STATUS_ERROR; } - if(!dbgsetpagerights(addr, argv[2])) + if(!MemSetPageRights(addr, argv[2])) { dprintf("Error: Set rights of "fhex" with Rights: %s\n", addr, argv[2]); return STATUS_ERROR; } - if(!dbggetpagerights(addr, rights)) + if(!MemGetPageRights(addr, rights)) { dprintf("Error getting rights of page: %s\n", argv[1]); return STATUS_ERROR; diff --git a/x64_dbg_dbg/memory.cpp b/x64_dbg_dbg/memory.cpp index 91c23ce3..2434fa22 100644 --- a/x64_dbg_dbg/memory.cpp +++ b/x64_dbg_dbg/memory.cpp @@ -325,6 +325,15 @@ bool MemIsCanonicalAddress(uint Address) #endif // ndef _WIN64 } +bool MemIsCodePage(uint Address, bool Refresh) +{ + MEMPAGE pageInfo; + if(!MemGetPageInfo(Address, &pageInfo, Refresh)) + return false; + + return (pageInfo.mbi.Protect & PAGE_EXECUTE) == PAGE_EXECUTE; +} + uint MemAllocRemote(uint Address, uint Size, DWORD Type, DWORD Protect) { return (uint)VirtualAllocEx(fdProcessInfo->hProcess, (LPVOID)Address, Size, Type, Protect); @@ -335,6 +344,11 @@ bool MemFreeRemote(uint Address) return !!VirtualFreeEx(fdProcessInfo->hProcess, (LPVOID)Address, 0, MEM_RELEASE); } +uint MemGetPageAligned(uint Address) +{ + return PAGE_ALIGN(Address); +} + bool MemGetPageInfo(uint Address, MEMPAGE* PageInfo, bool Refresh) { // Update the memory map if needed @@ -356,10 +370,106 @@ bool MemGetPageInfo(uint Address, MEMPAGE* PageInfo, bool Refresh) return true; } -bool MemIsCodePage(uint Address, bool Refresh) +bool MemSetPageRights(uint Address, const char* Rights) { - MEMPAGE PageInfo; - if(!MemGetPageInfo(Address, &PageInfo, Refresh)) + // Align address to page base + Address = MemGetPageAligned(Address); + + // String -> bit mask + DWORD protect; + if(!MemPageRightsFromString(&protect, Rights)) return false; - return (PageInfo.mbi.Protect & PAGE_EXECUTE) == PAGE_EXECUTE; + + DWORD oldProtect; + if(!VirtualProtectEx(fdProcessInfo->hProcess, (void*)Address, PAGE_SIZE, protect, &oldProtect)) + return false; + + return true; +} + +bool MemGetPageRights(uint Address, char* Rights) +{ + // Align address to page base + Address = MemGetPageAligned(Address); + + MEMORY_BASIC_INFORMATION mbi; + memset(&mbi, 0, sizeof(MEMORY_BASIC_INFORMATION)); + + if(!VirtualQueryEx(fdProcessInfo->hProcess, (void*)Address, &mbi, sizeof(mbi))) + return false; + + return MemPageRightsToString(mbi.Protect, Rights); +} + +bool MemPageRightsToString(DWORD Protect, char* Rights) +{ + memset(Rights, 0, RIGHTS_STRING_SIZE); + + switch(Protect & 0xFF) + { + case PAGE_NOACCESS: + strcpy_s(Rights, RIGHTS_STRING_SIZE, "----"); + break; + case PAGE_READONLY: + strcpy_s(Rights, RIGHTS_STRING_SIZE, "-R--"); + break; + case PAGE_READWRITE: + strcpy_s(Rights, RIGHTS_STRING_SIZE, "-RW-"); + break; + case PAGE_WRITECOPY: + strcpy_s(Rights, RIGHTS_STRING_SIZE, "-RWC"); + break; + case PAGE_EXECUTE: + strcpy_s(Rights, RIGHTS_STRING_SIZE, "E---"); + break; + case PAGE_EXECUTE_READ: + strcpy_s(Rights, RIGHTS_STRING_SIZE, "ER--"); + break; + case PAGE_EXECUTE_READWRITE: + strcpy_s(Rights, RIGHTS_STRING_SIZE, "ERW-"); + break; + case PAGE_EXECUTE_WRITECOPY: + strcpy_s(Rights, RIGHTS_STRING_SIZE, "ERWC"); + break; + } + + Rights[5] = ((Protect & PAGE_GUARD) == PAGE_GUARD) ? 'G' : '-'; + // Rights[6] = ((Protect & PAGE_NOCACHE) == PAGE_NOCACHE) ? '' : '-'; + // Rights[7] = ((Protect & PAGE_WRITECOMBINE) == PAGE_GUARD) ? '' : '-'; + + return true; +} + +bool MemPageRightsFromString(DWORD* Protect, const char* Rights) +{ + if(strlen(Rights) < 2) + return false; + + *Protect = 0; + + // Check for the PAGE_GUARD flag + if(Rights[0] == 'G' || Rights[0] == 'g') + { + *Protect |= PAGE_GUARD; + Rights++; + } + + if(_strcmpi(Rights, "Execute") == 0) + *Protect |= PAGE_EXECUTE; + else if(_strcmpi(Rights, "ExecuteRead") == 0) + *Protect |= PAGE_EXECUTE_READ; + else if(_strcmpi(Rights, "ExecuteReadWrite") == 0) + *Protect |= PAGE_EXECUTE_READWRITE; + else if(_strcmpi(Rights, "ExecuteWriteCopy") == 0) + *Protect |= PAGE_EXECUTE_WRITECOPY; + else if(_strcmpi(Rights, "NoAccess") == 0) + *Protect |= PAGE_NOACCESS; + else if(_strcmpi(Rights, "ReadOnly") == 0) + *Protect |= PAGE_READONLY; + else if(_strcmpi(Rights, "ReadWrite") == 0) + *Protect |= PAGE_READWRITE; + else if(_strcmpi(Rights, "WriteCopy") == 0) + *Protect |= PAGE_WRITECOPY; + + return (*Protect != 0); } \ No newline at end of file diff --git a/x64_dbg_dbg/memory.h b/x64_dbg_dbg/memory.h index 4707e128..d4fdcb4b 100644 --- a/x64_dbg_dbg/memory.h +++ b/x64_dbg_dbg/memory.h @@ -13,7 +13,12 @@ bool MemWrite(uint BaseAddress, const void* Buffer, uint Size, uint* NumberOfByt bool MemPatch(uint BaseAddress, const void* Buffer, uint Size, uint* NumberOfBytesWritten = nullptr); bool MemIsValidReadPtr(uint Address); bool MemIsCanonicalAddress(uint Address); +bool MemIsCodePage(uint Address, bool Refresh); uint MemAllocRemote(uint Address, uint Size, DWORD Type = MEM_RESERVE | MEM_COMMIT, DWORD Protect = PAGE_EXECUTE_READWRITE); bool MemFreeRemote(uint Address); +uint MemGetPageAligned(uint Address); bool MemGetPageInfo(uint Address, MEMPAGE* PageInfo, bool Refresh = false); -bool MemIsCodePage(uint Address, bool Refresh = false); \ No newline at end of file +bool MemSetPageRights(uint Address, const char* Rights); +bool MemGetPageRights(uint Address, char* Rights); +bool MemPageRightsToString(DWORD Protect, char* Rights); +bool MemPageRightsFromString(DWORD* Protect, const char* Rights); \ No newline at end of file