PsGetCurrentProcess()->CreateReported = TRUE;
/* Send the LPC command */
-#if 0
Status = LpcRequestWaitReplyPort(Port,
(PPORT_MESSAGE)Message,
(PPORT_MESSAGE)&Buffer[0]);
-#else
- Status = STATUS_UNSUCCESSFUL;
-#endif
/* Flush the instruction cache */
ZwFlushInstructionCache(NtCurrentProcess(), NULL, 0);
i = 0;
while ((NextEntry != ListHead) && (i < 500))
{
+ /* Skip the first entry */
+ if (!i)
+ {
+ /* Go to the next module */
+ NextEntry = NextEntry->Flink;
+ i++;
+ continue;
+ }
+
/* Get the entry */
LdrEntry = CONTAINING_RECORD(NextEntry,
LDR_DATA_TABLE_ENTRY,
/* Get the next thread */
ThisThread = PsGetNextProcessThread(Process, ThisThread);
OldThread = pLastThread;
- } while(ThisThread);
+ } while (ThisThread);
/* Check the API status */
if (!NT_SUCCESS(Status))
OwnerProcess, DebugObject);
/* If this isn't the last handle, do nothing */
- if (HandleCount > 1) return;
+ if (SystemHandleCount > 1) return;
/* Otherwise, lock the debug object */
ExAcquireFastMutex(&DebugObject->Mutex);
/* Check if we couldn't acquire rundown for it */
if (DebugEvent->Flags & 0x10)
{
- /* Set busy flag */
- InterlockedOr((PLONG)&DebugEvent->Flags, 0x100);
+ /* Set the skip termination flag */
+ PspSetCrossThreadFlag(EventThread, CT_SKIP_CREATION_MSG_BIT);
+
+ /* Insert it into the temp list */
+ RemoveEntryList(&DebugEvent->EventList);
+ InsertTailList(&TempList, &DebugEvent->EventList);
}
else
{
/* Clear the backout thread */
DebugEvent->BackoutThread = NULL;
- /* Set flag */
- InterlockedOr((PLONG)&DebugEvent->Flags, 0x80);
+ /* Set skip flag */
+ PspSetCrossThreadFlag(EventThread, CT_SKIP_CREATION_MSG_BIT);
}
}
else
{
- /* FIXME: TODO */
- DPRINT1("Unhandled dbgk path!\n");
- KEBUGCHECK(0);
+ /* Insert it into the temp list */
+ RemoveEntryList(&DebugEvent->EventList);
+ InsertTailList(&TempList, &DebugEvent->EventList);
}
/* Check if the lock is held */
if (LastThread) ObDereferenceObject(LastThread);
/* Loop our temporary list */
- NextEntry = TempList.Flink;
- while (NextEntry != &TempList)
+ while (!IsListEmpty(&TempList))
{
- /* FIXME: TODO */
- KEBUGCHECK(0);
+ /* Remove the event */
+ NextEntry = RemoveHeadList(&TempList);
+ DebugEvent = CONTAINING_RECORD (NextEntry, DEBUG_EVENT, EventList);
+
+ /* Wake it */
+ DbgkpWakeTarget(DebugEvent);
}
/* Check if we got here through success and mark the PEB, then return */
/* Make sure that the status is valid */
if ((ContinueStatus != DBG_CONTINUE) &&
+ (ContinueStatus != DBG_EXCEPTION_HANDLED) &&
(ContinueStatus != DBG_EXCEPTION_NOT_HANDLED) &&
- (ContinueStatus != DBG_REPLY_LATER) &&
- (ContinueStatus != DBG_UNABLE_TO_PROVIDE_HANDLE) &&
(ContinueStatus != DBG_TERMINATE_THREAD) &&
(ContinueStatus != DBG_TERMINATE_PROCESS))
{
DBGUI_WAIT_STATE_CHANGE WaitStateChange;
NTSTATUS Status = STATUS_SUCCESS;
PDEBUG_EVENT DebugEvent, DebugEvent2;
- PLIST_ENTRY ListHead, NextEntry;
+ PLIST_ENTRY ListHead, NextEntry, NextEntry2;
PAGED_CODE();
DBGKTRACE(DBGK_OBJECT_DEBUG, "Handle: %p\n", DebugHandle);
/* Clear the initial wait state change structure */
RtlZeroMemory(&WaitStateChange, sizeof(WaitStateChange));
- /* Check if the call was from user mode */
- if (PreviousMode != KernelMode)
+ /* Protect probe in SEH */
+ _SEH_TRY
{
- /* Protect probe in SEH */
- _SEH_TRY
+ /* Check if we came with a timeout */
+ if (Timeout)
{
- /* Check if we came with a timeout */
- if (Timeout)
+ /* Check if the call was from user mode */
+ if (PreviousMode != KernelMode)
{
- /* Make a copy on the stack */
- SafeTimeOut = ProbeForReadLargeInteger(Timeout);
- Timeout = &SafeTimeOut;
+ /* Probe it */
+ ProbeForReadLargeInteger(Timeout);
}
- /* Probe the state change structure */
- ProbeForWrite(StateChange, sizeof(*StateChange), sizeof(ULONG));
+ /* Make a local copy */
+ SafeTimeOut = *Timeout;
+ Timeout = &SafeTimeOut;
+
+ /* Query the current time */
+ KeQuerySystemTime(&StartTime);
}
- _SEH_HANDLE
+
+ /* Check if the call was from user mode */
+ if (PreviousMode != KernelMode)
{
- /* Get the exception code */
- Status = _SEH_GetExceptionCode();
+ /* Probe the state change structure */
+ ProbeForWrite(StateChange, sizeof(*StateChange), sizeof(ULONG));
}
- _SEH_END;
- if (!NT_SUCCESS(Status)) return Status;
-
- /* Query the current time */
- KeQuerySystemTime(&StartTime);
}
+ _SEH_HANDLE
+ {
+ /* Get the exception code */
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+ if (!NT_SUCCESS(Status)) return Status;
/* Get the debug object */
Status = ObReferenceObjectByHandle(DebugHandle,
Thread = NULL;
/* Wait on the debug object given to us */
- Status = KeWaitForSingleObject(DebugObject,
- Executive,
- PreviousMode,
- Alertable,
- Timeout);
while (TRUE)
{
+ Status = KeWaitForSingleObject(DebugObject,
+ Executive,
+ PreviousMode,
+ Alertable,
+ Timeout);
if (!NT_SUCCESS(Status) ||
(Status == STATUS_TIMEOUT) ||
(Status == STATUS_ALERTED) ||
GotEvent = TRUE;
/* Loop the list internally */
- while (&DebugEvent->EventList != NextEntry)
+ NextEntry2 = DebugObject->EventList.Flink;
+ while (NextEntry2 != NextEntry)
{
/* Get the debug event */
- DebugEvent2 = CONTAINING_RECORD(NextEntry,
+ DebugEvent2 = CONTAINING_RECORD(NextEntry2,
DEBUG_EVENT,
EventList);
}
/* Move to the next entry */
- NextEntry = NextEntry->Flink;
+ NextEntry2 = NextEntry2->Flink;
}
/* Check if we still have a valid event */
/* Set flag */
DebugEvent->Flags |= 1;
- Status = STATUS_SUCCESS;
}
else
{
/* Unsignal the event */
- DebugObject->EventsPresent.Header.SignalState = 0;
- Status = STATUS_SUCCESS;
+ KeClearEvent(&DebugObject->EventsPresent);
}
+
+ /* Set success */
+ Status = STATUS_SUCCESS;
}
/* Release the mutex */
if (!GotEvent)
{
/* Check if we can wait again */
- if (!SafeTimeOut.QuadPart)
+ if (SafeTimeOut.QuadPart < 0)
{
/* Query the new time */
KeQuerySystemTime(&NewTime);
/* Substract times */
- /* FIXME: TODO */
+ SafeTimeOut.QuadPart += (NewTime.QuadPart - StartTime.QuadPart);
+ StartTime = NewTime;
+
+ /* Check if we've timed out */
+ if (SafeTimeOut.QuadPart > 0)
+ {
+ /* We have, break out of the loop */
+ Status = STATUS_TIMEOUT;
+ break;
+ }
}
}
else
_UnhandledMsg:
.asciz "\n\x7\x7!!! Unhandled or Unexpected Code at line: %lx!!!\n"
+_KiTrapPrefixTable:
+ .byte 0xF2 /* REP */
+ .byte 0xF3 /* REP INS/OUTS */
+ .byte 0x67 /* ADDR */
+ .byte 0xF0 /* LOCK */
+ .byte 0x66 /* OP */
+ .byte 0x2E /* SEG */
+ .byte 0x3E /* DS */
+ .byte 0x26 /* ES */
+ .byte 0x64 /* FS */
+ .byte 0x65 /* GS */
+ .byte 0x36 /* SS */
+
+_KiTrapIoTable:
+ .byte 0xE4 /* IN */
+ .byte 0xE5 /* IN */
+ .byte 0xEC /* IN */
+ .byte 0xED /* IN */
+ .byte 0x6C /* INS */
+ .byte 0x6D /* INS */
+ .byte 0xE6 /* OUT */
+ .byte 0xE7 /* OUT */
+ .byte 0xEE /* OUT */
+ .byte 0xEF /* OUT */
+ .byte 0x6E /* OUTS */
+ .byte 0x6F /* OUTS */
+
/* SOFTWARE INTERRUPT SERVICES ***********************************************/
.text
jmp _KiSystemFatalException
.endfunc
+.func KiTrapExceptHandler
+_KiTrapExceptHandler:
+
+ /* Setup SEH handler frame */
+ mov esp, [esp+8]
+ pop fs:[KPCR_EXCEPTION_LIST]
+ add esp, 4
+ pop ebp
+
+ /* Check if the fault came from user mode */
+ test dword ptr [ebp+KTRAP_FRAME_CS], MODE_MASK
+ jnz SetException
+
+ /* Kernel fault, bugcheck */
+ push ebp
+ push 0
+ push 0
+ push 0
+ push 0
+ push KMODE_EXCEPTION_NOT_HANDLED
+ call _KeBugCheckWithTf@24
+.endfunc
+
.func KiTrap13
Dr_kitd: DR_TRAP_FIXUP
V86_kitd: V86_TRAP_FIXUP
lea eax, [ebp+KTRAP_FRAME_ESP]
cmp edx, eax
jz HandleSegPop
+ int 3
/* Handle segment POP fault by setting it to 0 */
HandleSegPop:
/* Update EIP (will be updated below again) */
add dword ptr [ebp+KTRAP_FRAME_EIP], 1
-HandleBop4:
+HandleEsPop:
/* Clear the segment, update EIP and ESP */
mov dword ptr [edx], 0
add dword ptr [ebp+KTRAP_FRAME_EIP], 1
cmp dword ptr [ebx+EPROCESS_VDM_OBJECTS], 0
jz CheckPrivilegedInstruction
+ /* Bring interrupts back */
+ sti
+
/* Check what kind of instruction this is */
mov eax, [ebp+KTRAP_FRAME_EIP]
mov eax, [eax]
/* FIXME: Check for BOP4 */
- /* Check if this is POP FS */
+ /* Check if this is POP ES */
mov edx, ebp
- add edx, KTRAP_FRAME_FS
+ add edx, KTRAP_FRAME_ES
+ cmp al, 0x07
+ jz HandleEsPop
+
+ /* Check if this is POP FS */
+ add edx, KTRAP_FRAME_FS - KTRAP_FRAME_ES
cmp ax, 0xA10F
jz HandleSegPop2
jz HandleSegPop2
CheckPrivilegedInstruction:
+ /* Bring interrupts back */
+ sti
+
+ /* Setup a SEH handler */
+ push ebp
+ push offset _KiTrapExceptHandler
+ push fs:[KPCR_EXCEPTION_LIST]
+ mov fs:[KPCR_EXCEPTION_LIST], esp
+
+ /* Get EIP */
+ mov esi, [ebp+KTRAP_FRAME_EIP]
+
+ /* Setup loop count */
+ mov ecx, 15
+
+InstLoop:
+ /* Save loop count */
+ push ecx
+
+ /* Get the instruction */
+ lods byte ptr [esi]
+
+ /* Now lookup in the prefix table */
+ mov ecx, 11
+ mov edi, offset _KiTrapPrefixTable
+ repnz scasb
+
+ /* Restore loop count */
+ pop ecx
+
+ /* If it's not a prefix byte, check other instructions */
+ jnz NotPrefixByte
+
/* FIXME */
UNHANDLED_PATH
-CheckPrivilegedInstruction2:
+NotPrefixByte:
+ /* FIXME: Check if it's a HLT */
+
+ /* Check if the instruction has two bytes */
+ cmp al, 0xF
+ jne CheckRing3Io
+
/* FIXME */
UNHANDLED_PATH
+CheckRing3Io:
+ /* Get EFLAGS and IOPL */
+ mov ebx, [ebp+KTRAP_FRAME_EFLAGS]
+ and ebx, 0x3000
+ shr ebx, 12
+
+ /* Check the CS's RPL mask */
+ mov ecx, [ebp+KTRAP_FRAME_CS]
+ and ecx, RPL_MASK
+ cmp ebx, ecx
+ jge NotIoViolation
+
+CheckPrivilegedInstruction2:
+ /* Check if this is a CLI or STI */
+ cmp al, 0xFA
+ je IsPrivInstruction
+ cmp al, 0xFB
+ je IsPrivInstruction
+
+ /* Setup I/O table lookup */
+ mov ecx, 13
+ mov edi, offset _KiTrapIoTable
+
+ /* Loopup in the table */
+ repnz scasb
+ jnz NotIoViolation
+
+ /* FIXME: Check IOPM!!! */
+
+IsPrivInstruction:
+ /* Cleanup the SEH frame */
+ pop fs:[KPCR_EXCEPTION_LIST]
+ add esp, 8
+
+ /* Setup the exception */
+ mov ebx, [ebp+KTRAP_FRAME_EIP]
+ mov eax, STATUS_PRIVILEGED_INSTRUCTION
+ jmp _DispatchNoParam
+
+NotIoViolation:
+ /* Cleanup the SEH frame */
+ pop fs:[KPCR_EXCEPTION_LIST]
+ add esp, 8
+
SetException:
- /* FIXME */
- UNHANDLED_PATH
+ /* Setup the exception */
+ mov ebx, [ebp+KTRAP_FRAME_EIP]
+ mov esi, -1
+ mov eax, STATUS_ACCESS_VIOLATION
+ jmp _DispatchTwoParam
DispatchV86Gpf:
/* FIXME */