https://bugs.winehq.org/show_bug.cgi?id=50194
Bug ID: 50194 Summary: x64dbg snapshots >= 2020-11-12_05-12 crashes on unimplemented function ntdll.dll.NtCreateDebugObject when attaching to process Product: Wine Version: 5.22 Hardware: x86-64 OS: Linux Status: NEW Severity: normal Priority: P2 Component: ntdll Assignee: wine-bugs@winehq.org Reporter: focht@gmx.net Distribution: ---
Hello folks,
as it says. I've reported it to x64dbg project as well since they switched the debug engine implementation to use native API for attaching to processes.
https://github.com/x64dbg/x64dbg/issues/2525
Copy/pasta from there:
...
Symptom: attaching to any 32-bit or 64-bit process results in x32dbg/x64dbg crash. If x32dbg/x64dbg is registered as default crash handler you get a nice debugger crash "fork" bomb ;-)
It crashes on unimplemented NtCreateDebugObject() which is native API.
https://source.winehq.org/git/wine.git/blob/40d4fbe45997a1820296e7909ba22125...
--- snip --- 162 # @ stub NtCreateDebugObject --- snip ---
Even with a small stub it wouldn't work because NtDebugActiveProcess is a stub as well.
https://source.winehq.org/git/wine.git/blob/40d4fbe45997a1820296e7909ba22125...
The native API used to implement remote breakin:
https://github.com/x64dbg/TitanEngine/blob/91f57815c886d6bef94f1b512d60c5e2d...
--- snip --- static NTSTATUS NTAPI DbgUiConnectToDbg_() { if(NtCurrentTeb()->DbgSsReserved[1] != NULL) return STATUS_SUCCESS;
OBJECT_ATTRIBUTES ObjectAttributes; InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL); return NtCreateDebugObject(&NtCurrentTeb()->DbgSsReserved[1], DEBUG_ALL_ACCESS, &ObjectAttributes, 0); }
// Source: https://github.com/mirror/reactos/blob/c6d2b35ffc91e09f50dfb214ea58237509329... BOOL WINAPI DebugActiveProcess_(IN DWORD dwProcessId) { /* Connect to the debugger */ NTSTATUS Status = DbgUiConnectToDbg_(); if(!NT_SUCCESS(Status)) { BaseSetLastNTError(Status); return FALSE; }
/* Get the process handle */ HANDLE Handle = ProcessIdToHandle(dwProcessId); if(!Handle) { return FALSE; }
/* Now debug the process */ Status = DbgUiDebugActiveProcess_(Handle);
/* Close the handle since we're done */ NtClose(Handle);
/* Check if debugging worked */ if(!NT_SUCCESS(Status)) { /* Fail */ BaseSetLastNTError(Status); return FALSE; }
/* Success */ return TRUE; } --- snip ---
Apparently this debugging functionality which makes use of native API was switched to being a debug engine default here:
https://github.com/x64dbg/TitanEngine/commit/0a1c3236b84ab1e6022116e38df1cc5... ("Make SafeAttach the default")
Previously it could be controlled by *SafeAttach* config setting which is still there but now no longer usable:
https://github.com/x64dbg/x64dbg/blob/dad16543c320640fe681b8d897235bf8d6c301...
--- snip --- SetEngineVariable(UE_ENGINE_SAFE_ATTACH, settingboolget("Engine", "SafeAttach")); --- snip ---
A workaround exists: use the last snapshot before the breaking change:
https://sourceforge.net/projects/x64dbg/files/snapshots/snapshot_2020-11-05_...
As already mentioned a simple stub prevents the crash but doesn't make debugging work.
--- snip --- $ wine ./x32dbg.exe ... 0144:fixme:process:NtCreateDebugObject (0x7ff72f24 1f000f 0x614fe78 0), stub! 0144:fixme:process:NtDebugActiveProcess (0x214 (nil)), stub! --- snip ---
I will create follow-up bug(s) to cover the missing functionality.
$ sha1sum snapshot_2020-11-12_05-12.zip 6e88d4ce8fb967d08b381084f9ab805e5bcc4f18 snapshot_2020-11-12_05-12.zip
$ du -sh snapshot_2020-11-12_05-12.zip 32M snapshot_2020-11-12_05-12.zip
$ wine --version wine-5.22-96-g4957599bbf5
Regards