- Fix a major bug while closing a process that was debugging another process, which would cause a bugcheck because it tried to kill itself while it was being killed -- instead, it should try killing the debuggee! fixes the bug that arty and I fought about when he said "process killing seems broken" and tried to add delayed-object-closing. Patch by Alex Ionescu.

- Remove a leftover from kernel32 which assumed that if "BeingDebugged" was TRUE, the library was being tested on an XP machine.

svn path=/trunk/; revision=33870
This commit is contained in:
Aleksey Bragin 2008-06-06 21:43:37 +00:00
parent edc9924731
commit 3eb4e85097
2 changed files with 9 additions and 57 deletions

View file

@ -257,42 +257,6 @@ DllMain(HANDLE hDll,
{ {
case DLL_PROCESS_ATTACH: case DLL_PROCESS_ATTACH:
#ifdef _M_IX86
/* OK, yes, this is really retarded but it works for now */
InWindows = NtCurrentPeb()->BeingDebugged;
/*
* CreateProcess will run in the real kernel32 and it will write
* its own BaseProcessStartThunk EIP in the CONTEXT that ZwContinue
* will get. We'll be first called by Ldr while initializing, and we'll
* be wrapped in 3 layers of SEH, followed by two frames, finally
* followed by our CONTEXT on the stack. We'll modify the EIP in it
* to match the correct one (our own) and then everything works.
* Tested on XP and 2K3, probably doesn't work in 2K.
*/
if (InWindows)
{
/*
* Due to yet another bug in how Windows handles .local, LDR will
* actually end up loading us twice. The second time will be the
* "official" load, at a totally different address. It will be,
* it will be at -that- address that all the APIs will be called.
* However, that address is dynamic while this one will be static,
* so we'll do initilization with this one. Plus, at this one,
* we know exactly that we're within 3 SEH layers.
*/
if (hDll == (HANDLE)0x7c800000)
{
PULONG Eip;
__debugbreak();
Eip = (PULONG)*(PULONG)*(PULONG)NtCurrentTeb()->Tib.ExceptionList +
0x9 +
FIELD_OFFSET(CONTEXT, Eip) / sizeof(ULONG);
*Eip = (ULONG)BaseProcessStartThunk;
}
}
#endif
/* Don't bother us for each thread */ /* Don't bother us for each thread */
LdrDisableThreadCalloutsForDll((PVOID)hDll); LdrDisableThreadCalloutsForDll((PVOID)hDll);

View file

@ -115,7 +115,7 @@ DbgkpQueueMessage(IN PEPROCESS Process,
KeInitializeEvent(&DebugEvent->ContinueEvent, SynchronizationEvent, FALSE); KeInitializeEvent(&DebugEvent->ContinueEvent, SynchronizationEvent, FALSE);
DebugEvent->Process = Process; DebugEvent->Process = Process;
DebugEvent->Thread = Thread; DebugEvent->Thread = Thread;
RtlCopyMemory(&DebugEvent->ApiMsg, Message, sizeof(DBGKM_MSG)); DebugEvent->ApiMsg = *Message;
DebugEvent->ClientId = Thread->Cid; DebugEvent->ClientId = Thread->Cid;
/* Check if we have a port object */ /* Check if we have a port object */
@ -176,7 +176,7 @@ DbgkpQueueMessage(IN PEPROCESS Process,
NULL); NULL);
/* Copy API Message back */ /* Copy API Message back */
RtlCopyMemory(Message, &DebugEvent->ApiMsg, sizeof(DBGKM_MSG)); *Message = DebugEvent->ApiMsg;
/* Set return status */ /* Set return status */
Status = DebugEvent->Status; Status = DebugEvent->Status;
@ -1079,8 +1079,6 @@ DbgkpCloseObject(IN PEPROCESS OwnerProcess OPTIONAL,
DBGKTRACE(DBGK_OBJECT_DEBUG, "OwnerProcess: %p DebugObject: %p\n", DBGKTRACE(DBGK_OBJECT_DEBUG, "OwnerProcess: %p DebugObject: %p\n",
OwnerProcess, DebugObject); OwnerProcess, DebugObject);
DPRINT("APC DISABLE: %d\n", ((PETHREAD)KeGetCurrentThread())->Tcb.CombinedApcDisable);
/* If this isn't the last handle, do nothing */ /* If this isn't the last handle, do nothing */
if (SystemHandleCount > 1) return; if (SystemHandleCount > 1) return;
@ -1124,13 +1122,13 @@ DbgkpCloseObject(IN PEPROCESS OwnerProcess OPTIONAL,
if (DebugPortCleared) if (DebugPortCleared)
{ {
/* Mark this in the PEB */ /* Mark this in the PEB */
DbgkpMarkProcessPeb(OwnerProcess); DbgkpMarkProcessPeb(Process);
/* Check if we terminate on exit */ /* Check if we terminate on exit */
if (DebugObject->KillProcessOnExit) if (DebugObject->KillProcessOnExit)
{ {
/* Terminate the process */ /* Terminate the process */
PsTerminateProcess(OwnerProcess, STATUS_DEBUGGER_INACTIVE); PsTerminateProcess(Process, STATUS_DEBUGGER_INACTIVE);
} }
/* Dereference the debug object */ /* Dereference the debug object */
@ -1192,6 +1190,7 @@ DbgkpSetProcessDebugObject(IN PEPROCESS Process,
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
/* Acquire the global lock */ /* Acquire the global lock */
ThreadScan:
GlobalHeld = TRUE; GlobalHeld = TRUE;
ExAcquireFastMutex(&DbgkpProcessDebugPortMutex); ExAcquireFastMutex(&DbgkpProcessDebugPortMutex);
@ -1203,7 +1202,6 @@ DbgkpSetProcessDebugObject(IN PEPROCESS Process,
} }
else else
{ {
ThreadScan:
/* Otherwise, set the port and reference the thread */ /* Otherwise, set the port and reference the thread */
Process->DebugPort = DebugObject; Process->DebugPort = DebugObject;
ObReferenceObject(LastThread); ObReferenceObject(LastThread);
@ -1235,14 +1233,7 @@ ThreadScan:
{ {
/* Dereference the first thread and re-acquire the lock */ /* Dereference the first thread and re-acquire the lock */
ObDereferenceObject(FirstThread); ObDereferenceObject(FirstThread);
GlobalHeld = TRUE; goto ThreadScan;
ExAcquireFastMutex(&DbgkpProcessDebugPortMutex);
/* Check if we should loop again */
if (!Process->DebugPort) goto ThreadScan;
/* Otherwise, we already have a port */
Status = STATUS_PORT_ALREADY_SET;
} }
} }
} }
@ -1265,8 +1256,7 @@ ThreadScan:
{ {
/* Set the process flags */ /* Set the process flags */
InterlockedOr((PLONG)&Process->Flags, InterlockedOr((PLONG)&Process->Flags,
PSF_NO_DEBUG_INHERIT_BIT | PSF_NO_DEBUG_INHERIT_BIT | PSF_CREATE_REPORTED_BIT);
PSF_CREATE_REPORTED_BIT);
/* Reference the debug object */ /* Reference the debug object */
ObDereferenceObject(DebugObject); ObDereferenceObject(DebugObject);
@ -2012,7 +2002,7 @@ NtWaitForDebugEvent(IN HANDLE DebugHandle,
StartTime = NewTime; StartTime = NewTime;
/* Check if we've timed out */ /* Check if we've timed out */
if (SafeTimeOut.QuadPart > 0) if (SafeTimeOut.QuadPart >= 0)
{ {
/* We have, break out of the loop */ /* We have, break out of the loop */
Status = STATUS_TIMEOUT; Status = STATUS_TIMEOUT;
@ -2037,9 +2027,7 @@ NtWaitForDebugEvent(IN HANDLE DebugHandle,
_SEH_TRY _SEH_TRY
{ {
/* Return our wait state change structure */ /* Return our wait state change structure */
RtlCopyMemory(StateChange, *StateChange = WaitStateChange;
&WaitStateChange,
sizeof(DBGUI_WAIT_STATE_CHANGE));
} }
_SEH_EXCEPT(_SEH_ExSystemExceptionFilter) _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
{ {