Commit a958b5ae authored by Eric Pouech's avatar Eric Pouech Committed by Alexandre Julliard

dbghelp: Identify a 32bit multi-arch wow64 debuggee as a live target.

Note: from now on, winedbg will 'see' the ELF 64 bit modules (not yet the PE ones) in multi-arch wow64 use case. Modules can be displayed in 'info wow share' command and their debug information is loaded. Stack manipulation and backtracking are not available. Signed-off-by: 's avatarEric Pouech <eric.pouech@gmail.com>
parent 23494334
...@@ -350,7 +350,8 @@ const struct cpu* process_get_cpu(const struct process* pcs) ...@@ -350,7 +350,8 @@ const struct cpu* process_get_cpu(const struct process* pcs)
static BOOL check_live_target(struct process* pcs, BOOL wow64, BOOL child_wow64) static BOOL check_live_target(struct process* pcs, BOOL wow64, BOOL child_wow64)
{ {
PROCESS_BASIC_INFORMATION pbi; PROCESS_BASIC_INFORMATION pbi;
ULONG_PTR base = 0, env = 0; DWORD64 base = 0, env = 0;
const char* peb_addr;
if (!GetProcessId(pcs->handle)) return FALSE; if (!GetProcessId(pcs->handle)) return FALSE;
if (GetEnvironmentVariableA("DBGHELP_NOLIVE", NULL, 0)) return FALSE; if (GetEnvironmentVariableA("DBGHELP_NOLIVE", NULL, 0)) return FALSE;
...@@ -359,27 +360,44 @@ static BOOL check_live_target(struct process* pcs, BOOL wow64, BOOL child_wow64) ...@@ -359,27 +360,44 @@ static BOOL check_live_target(struct process* pcs, BOOL wow64, BOOL child_wow64)
&pbi, sizeof(pbi), NULL )) &pbi, sizeof(pbi), NULL ))
return FALSE; return FALSE;
/* Note: we have to deal with the PEB64 and PEB32 in debuggee process
* while debugger can be in same or different bitness.
* For a 64 bit debuggee, use PEB64 and underlying ELF/system 64 (easy).
* For a 32 bit debuggee,
* - for environment variables, we need PEB32
* - for ELF/system base address, we need PEB32 when run in pure 32bit
* or run in old wow configuration, but PEB64 when run in new wow
* configuration.
* - this must be read from a debugger in either 32 or 64 bit setup.
*/
peb_addr = (const char*)pbi.PebBaseAddress;
if (!pcs->is_64bit) if (!pcs->is_64bit)
{ {
const char* peb32_addr;
DWORD env32; DWORD env32;
PEB32 peb32; PEB32 peb32;
C_ASSERT(sizeof(void*) != 4 || FIELD_OFFSET(RTL_USER_PROCESS_PARAMETERS, Environment) == 0x48); C_ASSERT(sizeof(void*) != 4 || FIELD_OFFSET(RTL_USER_PROCESS_PARAMETERS, Environment) == 0x48);
peb32_addr = (const char*)pbi.PebBaseAddress;
if (!wow64 && child_wow64) if (!wow64 && child_wow64)
/* current process is 64bit, while child process is 32 bit, need to read 32bit PEB */ /* current process is 64bit, while child process is 32 bit, need to read 32bit PEB */
peb32_addr += 0x1000; peb_addr += 0x1000;
if (!ReadProcessMemory(pcs->handle, peb32_addr, &peb32, sizeof(peb32), NULL)) return FALSE; if (!ReadProcessMemory(pcs->handle, peb_addr, &peb32, sizeof(peb32), NULL)) return FALSE;
if (!ReadProcessMemory(pcs->handle, peb32_addr + 0x460 /* CloudFileFlags */, &base, sizeof(base), NULL)) return FALSE; base = *(const DWORD*)((const char*)&peb32 + 0x460 /* CloudFileFlags */);
pcs->is_system_64bit = FALSE;
if (read_process_memory(pcs, peb32.ProcessParameters + 0x48, &env32, sizeof(env32))) env = env32; if (read_process_memory(pcs, peb32.ProcessParameters + 0x48, &env32, sizeof(env32))) env = env32;
} }
else if (pcs->is_64bit || base == 0)
{ {
PEB peb; PEB64 peb;
if (!ReadProcessMemory(pcs->handle, pbi.PebBaseAddress, &peb, sizeof(peb), NULL)) return FALSE;
if (!ReadProcessMemory(pcs->handle, (char *)pbi.PebBaseAddress + FIELD_OFFSET(PEB, CloudFileFlags), &base, sizeof(base), NULL)) return FALSE; if (!pcs->is_64bit) peb_addr -= 0x1000; /* PEB32 => PEB64 */
ReadProcessMemory(pcs->handle, (char *)peb.ProcessParameters + FIELD_OFFSET(RTL_USER_PROCESS_PARAMETERS, Environment), &env, sizeof(env), NULL); if (!ReadProcessMemory(pcs->handle, peb_addr, &peb, sizeof(peb), NULL)) return FALSE;
base = peb.CloudFileFlags;
pcs->is_system_64bit = TRUE;
if (pcs->is_64bit)
ReadProcessMemory(pcs->handle,
(char *)(ULONG_PTR)peb.ProcessParameters + FIELD_OFFSET(RTL_USER_PROCESS_PARAMETERS, Environment),
&env, sizeof(env), NULL);
} }
/* read debuggee environment block */ /* read debuggee environment block */
...@@ -420,9 +438,9 @@ static BOOL check_live_target(struct process* pcs, BOOL wow64, BOOL child_wow64) ...@@ -420,9 +438,9 @@ static BOOL check_live_target(struct process* pcs, BOOL wow64, BOOL child_wow64)
if (!base) return FALSE; if (!base) return FALSE;
TRACE("got debug info address %#Ix from PEB %p\n", base, pbi.PebBaseAddress); TRACE("got debug info address %#I64x from PEB %p\n", base, pbi.PebBaseAddress);
if (!elf_read_wine_loader_dbg_info(pcs, base) && !macho_read_wine_loader_dbg_info(pcs, base)) if (!elf_read_wine_loader_dbg_info(pcs, base) && !macho_read_wine_loader_dbg_info(pcs, base))
WARN("couldn't load process debug info at %#Ix\n", base); WARN("couldn't load process debug info at %#I64x\n", base);
return TRUE; return TRUE;
} }
......
...@@ -515,6 +515,7 @@ struct process ...@@ -515,6 +515,7 @@ struct process
void* buffer; void* buffer;
BOOL is_64bit; BOOL is_64bit;
BOOL is_system_64bit;
}; };
static inline BOOL read_process_memory(const struct process *process, UINT64 addr, void *buf, size_t size) static inline BOOL read_process_memory(const struct process *process, UINT64 addr, void *buf, size_t size)
......
...@@ -1373,7 +1373,7 @@ static BOOL elf_search_auxv(const struct process* pcs, unsigned type, ULONG_PTR* ...@@ -1373,7 +1373,7 @@ static BOOL elf_search_auxv(const struct process* pcs, unsigned type, ULONG_PTR*
while (addr < str_max && ReadProcessMemory(pcs->handle, addr, &str, sizeof(str), NULL) && str == NULL) while (addr < str_max && ReadProcessMemory(pcs->handle, addr, &str, sizeof(str), NULL) && str == NULL)
addr = (void*)((DWORD_PTR)addr + sizeof(str)); addr = (void*)((DWORD_PTR)addr + sizeof(str));
if (pcs->is_64bit) if (pcs->is_system_64bit)
{ {
struct struct
{ {
...@@ -1467,7 +1467,7 @@ static BOOL elf_enum_modules_internal(const struct process* pcs, ...@@ -1467,7 +1467,7 @@ static BOOL elf_enum_modules_internal(const struct process* pcs,
char bufstr[256]; char bufstr[256];
ULONG_PTR lm_addr; ULONG_PTR lm_addr;
if (pcs->is_64bit) if (pcs->is_system_64bit)
{ {
struct struct
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment