size_t ProcessWindows::DoWriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size, Error &error) { llvm::sys::ScopedLock lock(m_mutex); WINLOG_IFALL(WINDOWS_LOG_MEMORY, "DoWriteMemory attempting to write %u bytes into address 0x%I64x", size, vm_addr); if (!m_session_data) { WINERR_IFANY(WINDOWS_LOG_MEMORY, "DoWriteMemory cannot write, there is no active debugger connection."); return 0; } HostProcess process = m_session_data->m_debugger->GetProcess(); void *addr = reinterpret_cast<void *>(vm_addr); SIZE_T bytes_written = 0; lldb::process_t handle = process.GetNativeProcess().GetSystemHandle(); if (WriteProcessMemory(handle, addr, buf, size, &bytes_written)) FlushInstructionCache(handle, addr, bytes_written); else { error.SetError(GetLastError(), eErrorTypeWin32); WINLOG_IFALL(WINDOWS_LOG_MEMORY, "DoWriteMemory failed with error code %u", error.GetError()); } return bytes_written; }
Error ProcessWindowsLive::GetMemoryRegionInfo(lldb::addr_t vm_addr, MemoryRegionInfo &info) { Error error; llvm::sys::ScopedLock lock(m_mutex); if (!m_session_data) { error.SetErrorString("GetMemoryRegionInfo called with no debugging session."); WINERR_IFALL(WINDOWS_LOG_MEMORY, error.AsCString()); return error; } HostProcess process = m_session_data->m_debugger->GetProcess(); lldb::process_t handle = process.GetNativeProcess().GetSystemHandle(); if (handle == nullptr || handle == LLDB_INVALID_PROCESS) { error.SetErrorString("GetMemoryRegionInfo called with an invalid target process."); WINERR_IFALL(WINDOWS_LOG_MEMORY, error.AsCString()); return error; } WINLOG_IFALL(WINDOWS_LOG_MEMORY, "GetMemoryRegionInfo getting info for address 0x%I64x", vm_addr); void *addr = reinterpret_cast<void *>(vm_addr); MEMORY_BASIC_INFORMATION mem_info = {0}; SIZE_T result = ::VirtualQueryEx(handle, addr, &mem_info, sizeof(mem_info)); if (result == 0) { error.SetError(::GetLastError(), eErrorTypeWin32); WINERR_IFALL(WINDOWS_LOG_MEMORY, "VirtualQueryEx returned error %u while getting memory region info for address 0x%I64x", error.GetError(), vm_addr); return error; } const bool readable = IsPageReadable(mem_info.Protect); const bool executable = IsPageExecutable(mem_info.Protect); const bool writable = IsPageWritable(mem_info.Protect); info.SetReadable(readable ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo); info.SetExecutable(executable ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo); info.SetWritable(writable ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo); error.SetError(::GetLastError(), eErrorTypeWin32); WINLOGV_IFALL(WINDOWS_LOG_MEMORY, "Memory region info for address 0x%I64u: readable=%s, executable=%s, writable=%s", BOOL_STR(readable), BOOL_STR(executable), BOOL_STR(writable)); return error; }
size_t ProcessWindows::DoWriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size, Error &error) { llvm::sys::ScopedLock lock(m_mutex); if (!m_session_data) return 0; HostProcess process = m_session_data->m_debugger->GetProcess(); void *addr = reinterpret_cast<void *>(vm_addr); SIZE_T bytes_written = 0; lldb::process_t handle = process.GetNativeProcess().GetSystemHandle(); if (WriteProcessMemory(handle, addr, buf, size, &bytes_written)) FlushInstructionCache(handle, addr, bytes_written); else error.SetError(GetLastError(), eErrorTypeWin32); return bytes_written; }
size_t ProcessWindows::DoReadMemory(lldb::addr_t vm_addr, void *buf, size_t size, Error &error) { llvm::sys::ScopedLock lock(m_mutex); if (!m_session_data) return 0; HostProcess process = m_session_data->m_debugger->GetProcess(); void *addr = reinterpret_cast<void *>(vm_addr); SIZE_T bytes_read = 0; if (!ReadProcessMemory(process.GetNativeProcess().GetSystemHandle(), addr, buf, size, &bytes_read)) error.SetError(GetLastError(), eErrorTypeWin32); return bytes_read; }
size_t ProcessWindows::DoReadMemory(lldb::addr_t vm_addr, void *buf, size_t size, Error &error) { llvm::sys::ScopedLock lock(m_mutex); if (!m_session_data) return 0; WINLOG_IFALL(WINDOWS_LOG_MEMORY, "DoReadMemory attempting to read %u bytes from address 0x%I64x", size, vm_addr); HostProcess process = m_session_data->m_debugger->GetProcess(); void *addr = reinterpret_cast<void *>(vm_addr); SIZE_T bytes_read = 0; if (!ReadProcessMemory(process.GetNativeProcess().GetSystemHandle(), addr, buf, size, &bytes_read)) { error.SetError(GetLastError(), eErrorTypeWin32); WINERR_IFALL(WINDOWS_LOG_MEMORY, "DoReadMemory failed with error code %u", error.GetError()); } return bytes_read; }
Error ProcessWindows::GetMemoryRegionInfo(lldb::addr_t vm_addr, MemoryRegionInfo &info) { Error error; llvm::sys::ScopedLock lock(m_mutex); if (!m_session_data) { error.SetErrorString("ProcessWindows::GetMemoryRegionInfo called with no debugging session."); return error; } HostProcess process = m_session_data->m_debugger->GetProcess(); lldb::process_t handle = process.GetNativeProcess().GetSystemHandle(); if (handle == nullptr || handle == LLDB_INVALID_PROCESS) { error.SetErrorString("ProcessWindows::GetMemoryRegionInfo called with an invalid target process."); return error; } void *addr = reinterpret_cast<void *>(vm_addr); MEMORY_BASIC_INFORMATION mem_info = {0}; SIZE_T result = ::VirtualQueryEx(handle, addr, &mem_info, sizeof(mem_info)); if (result == 0) { error.SetError(::GetLastError(), eErrorTypeWin32); return error; } bool readable = !(mem_info.Protect & PAGE_NOACCESS); bool executable = mem_info.Protect & (PAGE_EXECUTE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY); bool writable = mem_info.Protect & (PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY | PAGE_READWRITE | PAGE_WRITECOPY); info.SetReadable(readable ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo); info.SetExecutable(executable ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo); info.SetWritable(writable ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo); return error; }