mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-12 10:17:22 +01:00
Make RewriteRemoteEntryPointW report IErrorInfo, VirtualProtectEx before WriteProcessMemory
This commit is contained in:
parent
0cc28fb39d
commit
7e78b6293b
10 changed files with 254 additions and 123 deletions
|
|
@ -408,14 +408,20 @@ utils::signature_finder::result utils::signature_finder::find_one() const {
|
|||
return find(1, 1, false).front();
|
||||
}
|
||||
|
||||
utils::memory_tenderizer::memory_tenderizer(const void* pAddress, size_t length, DWORD dwNewProtect) : m_data(reinterpret_cast<char*>(const_cast<void*>(pAddress)), length) {
|
||||
utils::memory_tenderizer::memory_tenderizer(const void* pAddress, size_t length, DWORD dwNewProtect)
|
||||
: memory_tenderizer(GetCurrentProcess(), pAddress, length, dwNewProtect) {
|
||||
}
|
||||
|
||||
utils::memory_tenderizer::memory_tenderizer(HANDLE hProcess, const void* pAddress, size_t length, DWORD dwNewProtect)
|
||||
: m_process(hProcess)
|
||||
, m_data(static_cast<char*>(const_cast<void*>(pAddress)), length) {
|
||||
try {
|
||||
for (auto pCoveredAddress = &m_data[0];
|
||||
pCoveredAddress < &m_data[0] + m_data.size();
|
||||
pCoveredAddress = reinterpret_cast<char*>(m_regions.back().BaseAddress) + m_regions.back().RegionSize) {
|
||||
for (auto pCoveredAddress = m_data.data();
|
||||
pCoveredAddress < m_data.data() + m_data.size();
|
||||
pCoveredAddress = static_cast<char*>(m_regions.back().BaseAddress) + m_regions.back().RegionSize) {
|
||||
|
||||
MEMORY_BASIC_INFORMATION region{};
|
||||
if (!VirtualQuery(pCoveredAddress, ®ion, sizeof region)) {
|
||||
if (!VirtualQueryEx(hProcess, pCoveredAddress, ®ion, sizeof region)) {
|
||||
throw std::runtime_error(std::format(
|
||||
"VirtualQuery(addr=0x{:X}, ..., cb={}) failed with Win32 code 0x{:X}",
|
||||
reinterpret_cast<size_t>(pCoveredAddress),
|
||||
|
|
@ -423,7 +429,7 @@ utils::memory_tenderizer::memory_tenderizer(const void* pAddress, size_t length,
|
|||
GetLastError()));
|
||||
}
|
||||
|
||||
if (!VirtualProtect(region.BaseAddress, region.RegionSize, dwNewProtect, ®ion.Protect)) {
|
||||
if (!VirtualProtectEx(hProcess, region.BaseAddress, region.RegionSize, dwNewProtect, ®ion.Protect)) {
|
||||
throw std::runtime_error(std::format(
|
||||
"(Change)VirtualProtect(addr=0x{:X}, size=0x{:X}, ..., ...) failed with Win32 code 0x{:X}",
|
||||
reinterpret_cast<size_t>(region.BaseAddress),
|
||||
|
|
@ -436,7 +442,7 @@ utils::memory_tenderizer::memory_tenderizer(const void* pAddress, size_t length,
|
|||
|
||||
} catch (...) {
|
||||
for (auto& region : std::ranges::reverse_view(m_regions)) {
|
||||
if (!VirtualProtect(region.BaseAddress, region.RegionSize, region.Protect, ®ion.Protect)) {
|
||||
if (!VirtualProtectEx(hProcess, region.BaseAddress, region.RegionSize, region.Protect, ®ion.Protect)) {
|
||||
// Could not restore; fast fail
|
||||
__fastfail(GetLastError());
|
||||
}
|
||||
|
|
@ -448,7 +454,7 @@ utils::memory_tenderizer::memory_tenderizer(const void* pAddress, size_t length,
|
|||
|
||||
utils::memory_tenderizer::~memory_tenderizer() {
|
||||
for (auto& region : std::ranges::reverse_view(m_regions)) {
|
||||
if (!VirtualProtect(region.BaseAddress, region.RegionSize, region.Protect, ®ion.Protect)) {
|
||||
if (!VirtualProtectEx(m_process, region.BaseAddress, region.RegionSize, region.Protect, ®ion.Protect)) {
|
||||
// Could not restore; fast fail
|
||||
__fastfail(GetLastError());
|
||||
}
|
||||
|
|
@ -654,3 +660,25 @@ std::wstring utils::escape_shell_arg(const std::wstring& arg) {
|
|||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
std::wstring utils::format_win32_error(DWORD err) {
|
||||
wchar_t* pwszMsg = nullptr;
|
||||
FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
nullptr,
|
||||
err,
|
||||
MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
|
||||
reinterpret_cast<LPWSTR>(&pwszMsg),
|
||||
0,
|
||||
nullptr);
|
||||
if (pwszMsg) {
|
||||
std::wstring result = std::format(L"Win32 error ({}=0x{:X}): {}", err, err, pwszMsg);
|
||||
while (!result.empty() && std::isspace(result.back()))
|
||||
result.pop_back();
|
||||
LocalFree(pwszMsg);
|
||||
return result;
|
||||
}
|
||||
|
||||
return std::format(L"Win32 error ({}=0x{:X})", err, err);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue