[Bug 44648] New: x64dbg crashes during process attach ( kernel32.GetFinalPathNameByHandle() doesn' t support process image file handles)
wine-bugs at winehq.org
wine-bugs at winehq.org
Sat Mar 3 14:38:04 CST 2018
https://bugs.winehq.org/show_bug.cgi?id=44648
Bug ID: 44648
Summary: x64dbg crashes during process attach
(kernel32.GetFinalPathNameByHandle() doesn't support
process image file handles)
Product: Wine
Version: 3.3
Hardware: x86-64
OS: Linux
Status: NEW
Severity: normal
Priority: P2
Component: ntdll
Assignee: wine-bugs at winehq.org
Reporter: focht at gmx.net
Distribution: ---
Hello folks,
as it says.
* 64-bit process started
* attach with x64dbg to it
Relevant piece of trace log:
--- snip ---
...
004d:Call KERNEL32.DebugActiveProcess(0000003d,) ret=017a2abd
004d: debug_process( pid=003d, attach=1 )
004d: debug_process() = 0
004d:Ret KERNEL32.DebugActiveProcess() retval=00000001 ret=017a2abd
004d:Call KERNEL32.GetModuleHandleA(017f3610 "kernel32.dll",) ret=017a2af0
004d:Ret KERNEL32.GetModuleHandleA() retval=7b460000 ret=017a2af0
004d:Call KERNEL32.GetProcAddress(7b460000,017f35f0
"DebugSetProcessKillOnExit",) ret=017a2b00
004d:Ret KERNEL32.GetProcAddress() retval=7b46ce5c ret=017a2b00
004d:Call KERNEL32.DebugSetProcessKillOnExit(00000001,) ret=017a2b0b
004d: set_debugger_kill_on_exit( kill_on_exit=1 )
004d: set_debugger_kill_on_exit() = 0
004d:Ret KERNEL32.DebugSetProcessKillOnExit() retval=00000001 ret=017a2b0b
004d:Call KERNEL32.WaitForDebugEvent(0181e090,ffffffff,) ret=017c5e53
004d: wait_debug_event( get_handle=1 )
004d: wait_debug_event() = 0 { pid=003d, tid=003e, wait=0000,
event={create_process,file=0170,process=0168,thread=016c,base=140000000,offset=0,size=0,teb=7fffffea8000,start=00000000,name=00010a20,unicode=1}
}
004d:Ret KERNEL32.WaitForDebugEvent() retval=00000001 ret=017c5e53
...
004d:Call KERNEL32.GetModuleHandleW(015ab490 L"kernel32.dll",) ret=015a27e0
004d:Ret KERNEL32.GetModuleHandleW() retval=7b460000 ret=015a27e0
004d:Call KERNEL32.GetProcAddress(7b460000,015ab470
"GetFinalPathNameByHandleW",) ret=015a27f0
004d:Ret KERNEL32.GetProcAddress() retval=7b46e800 ret=015a27f0
004d:Call
KERNEL32.GetFinalPathNameByHandleW(00000170,0ca8ca80,00000104,00000000,)
ret=015a2817
004d:trace:ntdll:NtQueryObject
(0x170,0x00000001,0xca8c5c0,0x00000228,0xca8c3ac)
004d: get_handle_unix_name( handle=0170 )
004d: get_handle_unix_name() = OBJECT_TYPE_MISMATCH { name_len=0, name="" }
004d: get_object_info( handle=0170 )
004d: get_object_info() = 0 { access=00120089, ref_count=00000002,
handle_count=00000001, total=0, name=L"" }
004d:Ret KERNEL32.GetFinalPathNameByHandleW() retval=00000000 ret=015a2817
...
--- snip ---
0170 = handle to the process's image file, delivered through
CREATE_PROCESS_DEBUG_INFO structure in WaitForDebugEvent().
x64dbg source:
https://github.com/x64dbg/x64dbg/blob/development/src/dbg/debugger.cpp#L1324
--- snip ---
...
static void cbCreateProcess(CREATE_PROCESS_DEBUG_INFO* CreateProcessInfo)
{
fdProcessInfo->hProcess = CreateProcessInfo->hProcess;
fdProcessInfo->hThread = CreateProcessInfo->hThread;
varset("$hp", (duint)fdProcessInfo->hProcess, true);
void* base = CreateProcessInfo->lpBaseOfImage;
char DebugFileName[deflen] = "";
if(!GetFileNameFromHandle(CreateProcessInfo->hFile, DebugFileName) &&
!GetFileNameFromProcessHandle(CreateProcessInfo->hProcess, DebugFileName))
strcpy_s(DebugFileName, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "???
(GetFileNameFromHandle failed)")));
dprintf(QT_TRANSLATE_NOOP("DBG", "Process Started: %p %s\n"), base,
DebugFileName);
...
--- snip ---
'GetFileNameFromHandle' is implemented in a third-party library
'devicenameresolver', used by x64dbg.
https://bitbucket.org/mrexodia/devicenameresolver/src/0850d88fa6a759d79b3c859933870d9aa602aa79/DeviceNameResolver.cpp?at=master&fileviewer=file-view-default#DeviceNameResolver.cpp-79
--- snip ---
__declspec(dllexport) bool PathFromFileHandleW(HANDLE hFile, wchar_t* szPath,
size_t nSizeInChars)
{
typedef DWORD (WINAPI * GETFINALPATHNAMEBYHANDLEW)(
IN HANDLE /*hFile*/,
OUT wchar_t* /*lpszFilePath*/,
IN DWORD /*cchFilePath*/,
IN DWORD /*dwFlags*/
);
static GETFINALPATHNAMEBYHANDLEW GetFPNBHW =
GETFINALPATHNAMEBYHANDLEW(GetProcAddress(GetModuleHandleW(L"kernel32.dll"),
"GetFinalPathNameByHandleW"));
if(GetFPNBHW && GetFPNBHW(hFile, szPath, DWORD(nSizeInChars), 0))
{
if(_wcsnicmp(szPath, L"\\\\?\\UNC\\", 8) == 0) // Server path
{
wcsncpy_s(szPath, nSizeInChars, L"\\\\", _TRUNCATE);
wcsncat_s(szPath, nSizeInChars, &szPath[8], _TRUNCATE);
}
else if(_wcsnicmp(szPath, L"\\\\?\\", 4) == 0 && szPath[5] == L':') //
Drive path
{
wcsncpy_s(szPath, nSizeInChars, &szPath[4], _TRUNCATE);
}
return true;
}
if(!DevicePathFromFileHandleW(hFile, szPath, nSizeInChars))
return false;
std::wstring oldPath(szPath);
if(!DevicePathToPathW(szPath, szPath, nSizeInChars))
wcsncpy_s(szPath, nSizeInChars, oldPath.c_str(), _TRUNCATE);
return true;
}
--- snip ---
'GetFinalPathNameByHandleW()' fails in Wine, it should not on valid process
image file handle?
There is a fallback path 'DevicePathFromFileHandleW()':
https://bitbucket.org/mrexodia/devicenameresolver/src/0850d88fa6a759d79b3c859933870d9aa602aa79/DeviceNameResolver.cpp?at=master&fileviewer=file-view-default#DeviceNameResolver.cpp-35
--- snip ---
__declspec(dllexport) bool DevicePathFromFileHandleW(HANDLE hFile, wchar_t*
szDevicePath, size_t nSizeInChars)
{
NativeWinApi::initialize();
ULONG ReturnLength;
bool bRet = false;
if(NativeWinApi::NtQueryObject(hFile, ObjectNameInformation, 0, 0,
&ReturnLength) == STATUS_INFO_LENGTH_MISMATCH)
{
ReturnLength += 0x2000; //on Windows XP SP3 ReturnLength will not be
set just add some buffer space to fix this
POBJECT_NAME_INFORMATION NameInformation =
POBJECT_NAME_INFORMATION(GlobalAlloc(0, ReturnLength));
if(NativeWinApi::NtQueryObject(hFile, ObjectNameInformation,
NameInformation, ReturnLength, 0) == STATUS_SUCCESS)
{
NameInformation->Name.Buffer[NameInformation->Name.Length / 2] =
L'\0'; //null-terminate the UNICODE_STRING
wcsncpy_s(szDevicePath, nSizeInChars, NameInformation->Name.Buffer,
_TRUNCATE);
bRet = true;
}
GlobalFree(NameInformation);
}
if(!bRet)
return false;
if(_wcsnicmp(szDevicePath, L"\\Device\\LanmanRedirector\\", 25) == 0) //
Win XP
{
wcsncpy_s(szDevicePath, nSizeInChars, L"\\\\", _TRUNCATE);
wcsncat_s(szDevicePath, nSizeInChars, &szDevicePath[25], _TRUNCATE);
}
else if(_wcsnicmp(szDevicePath, L"\\Device\\Mup\\", 12) == 0) // Win 7
{
wcsncpy_s(szDevicePath, nSizeInChars, L"\\\\", _TRUNCATE);
wcsncat_s(szDevicePath, nSizeInChars, &szDevicePath[12], _TRUNCATE);
}
return true;
}
--- snip ---
Corresponding Wine trace log:
--- snip ---
...
004d:Call ntdll.NtQueryObject(00000170,00000001,00000000,00000000,0ca8c9e8,)
ret=015a1c8b
004d:trace:ntdll:NtQueryObject (0x170,0x00000001,(nil),0x00000000,0xca8c9e8)
004d: get_handle_unix_name( handle=0170 )
004d: get_handle_unix_name() = OBJECT_TYPE_MISMATCH { name_len=0, name="" }
004d: get_object_info( handle=0170 )
004d: get_object_info() = 0 { access=00120089, ref_count=00000002,
handle_count=00000001, total=0, name=L"" }
004d:Ret ntdll.NtQueryObject() retval=c0000004 ret=015a1c8b
004d:Call KERNEL32.GlobalAlloc(00000000,00002010,) ret=015a1cb2
004d:Ret KERNEL32.GlobalAlloc() retval=034d3700 ret=015a1cb2
004d:Call ntdll.NtQueryObject(00000170,00000001,034d3700,00002010,00000000,)
ret=015a1cd4
004d:trace:ntdll:NtQueryObject (0x170,0x00000001,0x34d3700,0x00002010,(nil))
004d: get_handle_unix_name( handle=0170 )
004d: get_handle_unix_name() = OBJECT_TYPE_MISMATCH { name_len=0, name="" }
004d: get_object_info( handle=0170 )
004d: get_object_info() = 0 { access=00120089, ref_count=00000002,
handle_count=00000001, total=0, name=L"" }
004d:Ret ntdll.NtQueryObject() retval=00000000 ret=015a1cd4
004d:Call KERNEL32.GetLastError() ret=015a58a8
004d:Ret KERNEL32.GetLastError() retval=00000006 ret=015a58a8
...
004d:Call
ntdll.RtlVirtualUnwind(00000000,015a0000,015a483b,015b34b0,0ca8c3a0,0ca8c2e8,0ca8c2f0,00000000,)
ret=015a488c
...
004d:Call KERNEL32.UnhandledExceptionFilter(0ca8c2d8,) ret=015a48d8
...
004d:trace:seh:start_debugger Starting debugger "winedbg --auto 42 404"
--- snip ---
'NtQueryObject()' fails first time with 'STATUS_INFO_LENGTH_MISMATCH'.
The second call of 'NtQueryObject()' doesn't fail but doesn't return any data,
which causes wcsncpy_s() to abort.
In any case, a least one code path should succeed.
$ sha1sum snapshot_2018-02-24_13-52.zip
1d64a63153aad56e23c626dcdd9a0fd684f9064b snapshot_2018-02-24_13-52.zip
$ du -sh snapshot_2018-02-24_13-52.zip
33M snapshot_2018-02-24_13-52.zip
$ wine --version
wine-3.3
Regards
--
Do not reply to this email, post in Bugzilla using the
above URL to reply.
You are receiving this mail because:
You are watching all bug changes.
More information about the wine-bugs
mailing list