📄 kdapi.c
字号:
g_fForceReload = FALSE;
}
memcpy (&pdbgNotifPacket->u.Exception.ExceptionRecord,
pExceptionRecord,
sizeof (EXCEPTION_RECORD));
pdbgNotifPacket->u.Exception.dwFirstChance = !SecondChance;
#if defined(SH3)
g_pctxException->DebugRegisters.BarA = READ_REGISTER_ULONG(UBCBarA);
g_pctxException->DebugRegisters.BasrA = READ_REGISTER_UCHAR(UBCBasrA);
g_pctxException->DebugRegisters.BamrA = READ_REGISTER_UCHAR(UBCBamrA);
g_pctxException->DebugRegisters.BbrA = READ_REGISTER_USHORT(UBCBbrA);
g_pctxException->DebugRegisters.BarB = READ_REGISTER_ULONG(UBCBarB);
g_pctxException->DebugRegisters.BasrB = READ_REGISTER_UCHAR(UBCBasrB);
g_pctxException->DebugRegisters.BamrB = READ_REGISTER_UCHAR(UBCBamrB);
g_pctxException->DebugRegisters.BbrB = READ_REGISTER_USHORT(UBCBbrB);
g_pctxException->DebugRegisters.BdrB = READ_REGISTER_ULONG(UBCBdrB);
g_pctxException->DebugRegisters.BdmrB = READ_REGISTER_ULONG(UBCBdmrB);
g_pctxException->DebugRegisters.Brcr = READ_REGISTER_USHORT(UBCBrcr);
g_pctxException->DebugRegisters.Align = 0;
#endif
// Copy context record immediately following instruction stream
pdbgNotifPacket->u.Exception.Context = *g_pctxException;
#ifdef ARM
// Not editting the _CONTEXT struction. Here is the copy of additional register information
if (DetectConcanCoprocessors ())
{
DEBUGGERMSG(KDZONE_CONCAN, (L"Adding on the concan registers\n\r"));;
GetConcanRegisters (&pdbgNotifPacket->u.Exception.ConcanRegs);
}
#endif
}
BOOLEAN
KdpReportExceptionNotif (
IN PEXCEPTION_RECORD ExceptionRecord,
IN BOOLEAN SecondChance
)
/*++
Routine Description:
This routine sends an exception state change packet to the kernel
debugger and waits for a manipulate state message.
Arguments:
ExceptionRecord - Supplies a pointer to an exception record.
SecondChance - Supplies a boolean value that determines whether this is
the first or second chance for the exception.
Return Value:
A value of TRUE is returned if the exception is handled. Otherwise, a
value of FALSE is returned.
--*/
{
STRING MessageData;
STRING MessageHeader;
DBGKD_NOTIF dbgNotifPacket = {0};
BOOLEAN fHandled;
KdpSetNotifPacket (&dbgNotifPacket,
ExceptionRecord,
SecondChance
);
MessageHeader.Length = sizeof (DBGKD_NOTIF);
MessageHeader.Buffer = (PCHAR) &dbgNotifPacket;
MessageData.Length = 0;
// Send packet to the kernel debugger on the host machine, wait for answer.
fHandled = KdpSendNotifAndDoCmdLoop (&MessageHeader, &MessageData);
return fHandled;
}
#define MmDbgTranslatePhysicalAddress(Address) (Address)
VOID
KdpReadPhysicalMemory(
IN DBGKD_COMMAND *pdbgkdCmdPacket,
IN PSTRING AdditionalData
)
/*++
Routine Description:
This function is called in response to a read physical memory
command message. Its function is to read physical memory
and return.
Arguments:
pdbgkdCmdPacket - Supplies the command message.
AdditionalData - Supplies any additional data for the message.
Return Value:
None.
--*/
{
DBGKD_READ_MEMORY *a = &pdbgkdCmdPacket->u.ReadMemory;
ULONG Length;
STRING MessageHeader;
PVOID VirtualAddress;
PHYSICAL_ADDRESS Source;
PUCHAR Destination;
USHORT NumberBytes;
USHORT BytesLeft;
MessageHeader.Length = sizeof(*pdbgkdCmdPacket);
MessageHeader.Buffer = (PCHAR)pdbgkdCmdPacket;
//
// make sure that nothing but a read memory message was transmitted
//
KD_ASSERT(AdditionalData->Length == 0);
//
// Trim transfer count to fit in a single message
//
if (a->dwTransferCount > KDP_MESSAGE_BUFFER_SIZE)
{
Length = KDP_MESSAGE_BUFFER_SIZE;
}
else
{
Length = a->dwTransferCount;
}
//
// Since the MmDbgTranslatePhysicalAddress only maps in one physical
// page at a time, we need to break the memory move up into smaller
// moves which don't cross page boundaries. There are two cases we
// need to deal with. The area to be moved may start and end on the
// same page, or it may start and end on different pages (with an
// arbitrary number of pages in between)
//
Source = (PHYSICAL_ADDRESS) a->qwTgtAddress;
Destination = AdditionalData->Buffer;
BytesLeft = (USHORT)Length;
if (PAGE_ALIGN((PUCHAR) a->qwTgtAddress) ==
PAGE_ALIGN((PUCHAR)(a->qwTgtAddress)+Length))
{
//
// Memory move starts and ends on the same page.
//
VirtualAddress = (PVOID)MmDbgTranslatePhysicalAddress(Source);
AdditionalData->Length = (USHORT)KdpMoveMemory(
Destination,
VirtualAddress,
BytesLeft
);
BytesLeft -= AdditionalData->Length;
}
else
{
//
// Memory move spans page boundaries
//
VirtualAddress = (PVOID)MmDbgTranslatePhysicalAddress(Source);
NumberBytes = (USHORT)(PAGE_SIZE - BYTE_OFFSET(VirtualAddress));
AdditionalData->Length = (USHORT)KdpMoveMemory(
Destination,
VirtualAddress,
NumberBytes
);
Source += NumberBytes;
Destination += NumberBytes;
BytesLeft -= NumberBytes;
while(BytesLeft > 0) {
//
// Transfer a full page or the last bit,
// whichever is smaller.
//
VirtualAddress = (PVOID) MmDbgTranslatePhysicalAddress (Source);
NumberBytes = (USHORT) ((PAGE_SIZE < BytesLeft) ? PAGE_SIZE : BytesLeft);
AdditionalData->Length += (USHORT)KdpMoveMemory(
Destination,
VirtualAddress,
NumberBytes
);
Source += NumberBytes;
Destination += NumberBytes;
BytesLeft -= NumberBytes;
}
}
if (Length == AdditionalData->Length)
{
pdbgkdCmdPacket->dwReturnStatus = STATUS_SUCCESS;
}
else
{
pdbgkdCmdPacket->dwReturnStatus = STATUS_UNSUCCESSFUL;
}
a->dwActualBytesRead = AdditionalData->Length;
KdpSendKdApiCmdPacket (&MessageHeader, AdditionalData);
}
VOID
KdpWritePhysicalMemory(
IN DBGKD_COMMAND *pdbgkdCmdPacket,
IN PSTRING AdditionalData
)
/*++
Routine Description:
This function is called in response to a write physical memory
command message. Its function is to write physical memory
and return.
Arguments:
pdbgkdCmdPacket - Supplies the command message.
AdditionalData - Supplies any additional data for the message.
Return Value:
None.
--*/
{
DBGKD_WRITE_MEMORY *a = &pdbgkdCmdPacket->u.WriteMemory;
ULONG Length;
STRING MessageHeader;
PVOID VirtualAddress;
PHYSICAL_ADDRESS Destination;
PUCHAR Source;
USHORT NumberBytes;
USHORT BytesLeft;
MessageHeader.Length = sizeof(*pdbgkdCmdPacket);
MessageHeader.Buffer = (PCHAR)pdbgkdCmdPacket;
//
// Since the MmDbgTranslatePhysicalAddress only maps in one physical
// page at a time, we need to break the memory move up into smaller
// moves which don't cross page boundaries. There are two cases we
// need to deal with. The area to be moved may start and end on the
// same page, or it may start and end on different pages (with an
// arbitrary number of pages in between)
//
Destination = (PHYSICAL_ADDRESS) a->qwTgtAddress;
Source = AdditionalData->Buffer;
BytesLeft = (USHORT) a->dwTransferCount;
// TODO: Call kdpIsROM before writting
if(PAGE_ALIGN((PUCHAR)Destination) ==
PAGE_ALIGN((PUCHAR)(Destination)+BytesLeft)) {
//
// Memory move starts and ends on the same page.
//
VirtualAddress = (PVOID)MmDbgTranslatePhysicalAddress(Destination);
Length = (USHORT)KdpMoveMemory(
VirtualAddress,
Source,
BytesLeft
);
BytesLeft -= (USHORT) Length;
} else {
//
// Memory move spans page boundaries
//
VirtualAddress = (PVOID)MmDbgTranslatePhysicalAddress(Destination);
NumberBytes = (USHORT) (PAGE_SIZE - BYTE_OFFSET(VirtualAddress));
Length = (USHORT)KdpMoveMemory(
VirtualAddress,
Source,
NumberBytes
);
Source += NumberBytes;
Destination += NumberBytes;
BytesLeft -= NumberBytes;
while(BytesLeft > 0) {
//
// Transfer a full page or the last bit,
// whichever is smaller.
//
VirtualAddress = (PVOID)MmDbgTranslatePhysicalAddress(Destination);
NumberBytes = (USHORT) ((PAGE_SIZE < BytesLeft) ? PAGE_SIZE : BytesLeft);
Length += (USHORT)KdpMoveMemory(
VirtualAddress,
Source,
NumberBytes
);
Source += NumberBytes;
Destination += NumberBytes;
BytesLeft -= NumberBytes;
}
}
if (Length == AdditionalData->Length) {
pdbgkdCmdPacket->dwReturnStatus = STATUS_SUCCESS;
} else {
pdbgkdCmdPacket->dwReturnStatus = STATUS_UNSUCCESSFUL;
}
a->dwActualBytesWritten = Length;
KdpSendKdApiCmdPacket (&MessageHeader, NULL);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -