in Exdi/exdigdbsrv/ExdiGdbSrv/LiveExdiGdbSrvServer.cpp [1146:1256]
HRESULT STDMETHODCALLTYPE CLiveExdiGdbSrvServer::GetContextEx(_In_ DWORD processorNumber, _Inout_ PCONTEXT_X86_64 pContext)
{
if (pContext == nullptr)
{
return E_POINTER;
}
try
{
AsynchronousGdbSrvController * pController = GetGdbSrvController();
if (pController == nullptr)
{
return E_POINTER;
}
pController->StopTargetAtRun();
memset(pContext, 0, sizeof(CONTEXT_X86_64));
//We do not fetch the actual descriptors, thus we mark them as invalid
pContext->DescriptorCs.SegFlags = static_cast<DWORD>(-1);
pContext->DescriptorSs.SegFlags = static_cast<DWORD>(-1);
pContext->DescriptorGs.SegFlags = static_cast<DWORD>(-1);
pContext->DescriptorFs.SegFlags = static_cast<DWORD>(-1);
pContext->DescriptorEs.SegFlags = static_cast<DWORD>(-1);
pContext->DescriptorDs.SegFlags = static_cast<DWORD>(-1);
std::map<std::string, std::string> registers = pController->QueryAllRegisters(processorNumber);
pContext->Rax = GdbSrvController::ParseRegisterValue(registers["rax"]);
pContext->Rbx = GdbSrvController::ParseRegisterValue(registers["rbx"]);
pContext->Rcx = GdbSrvController::ParseRegisterValue(registers["rcx"]);
pContext->Rdx = GdbSrvController::ParseRegisterValue(registers["rdx"]);
pContext->Rsi = GdbSrvController::ParseRegisterValue(registers["rsi"]);
pContext->Rdi = GdbSrvController::ParseRegisterValue(registers["rdi"]);
pContext->Rip = GdbSrvController::ParseRegisterValue(registers["rip"]);
// Store the last 'pc' value in order to notify the engine with the last obtained 'pc' value,
// This is required for cases when the GdbServer responds with target unvailable packet.
m_lastPcAddress = pContext->Rip;
pContext->Rsp = GdbSrvController::ParseRegisterValue(registers["rsp"]);
pContext->Rbp = GdbSrvController::ParseRegisterValue(registers["rbp"]);
pContext->R8 = GdbSrvController::ParseRegisterValue(registers["r8"]);
pContext->R9 = GdbSrvController::ParseRegisterValue(registers["r9"]);
pContext->R10 = GdbSrvController::ParseRegisterValue(registers["r10"]);
pContext->R11 = GdbSrvController::ParseRegisterValue(registers["r11"]);
pContext->R12 = GdbSrvController::ParseRegisterValue(registers["r12"]);
pContext->R13 = GdbSrvController::ParseRegisterValue(registers["r13"]);
pContext->R14 = GdbSrvController::ParseRegisterValue(registers["r14"]);
pContext->R15 = GdbSrvController::ParseRegisterValue(registers["r15"]);
pContext->EFlags = GdbSrvController::ParseRegisterValue32(registers["eflags"]);
pContext->RegGroupSelection.fIntegerRegs = TRUE;
pContext->ModeFlags = AMD64_CONTEXT_AMD64 | AMD64_CONTEXT_CONTROL |
AMD64_CONTEXT_INTEGER | AMD64_CONTEXT_SEGMENTS;
// Segment registers
pContext->SegCs = static_cast<DWORD>(GdbSrvController::ParseRegisterValue(registers["cs"]));
pContext->SegSs = static_cast<DWORD>(GdbSrvController::ParseRegisterValue(registers["ss"]));
pContext->SegDs = static_cast<DWORD>(GdbSrvController::ParseRegisterValue(registers["ds"]));
pContext->SegEs = static_cast<DWORD>(GdbSrvController::ParseRegisterValue(registers["es"]));
pContext->SegFs = static_cast<DWORD>(GdbSrvController::ParseRegisterValue(registers["fs"]));
pContext->SegGs = static_cast<DWORD>(GdbSrvController::ParseRegisterValue(registers["gs"]));
pContext->RegGroupSelection.fSegmentRegs = TRUE;
// Control registers (System registers)
pContext->RegCr0 = static_cast<DWORD>(GdbSrvController::ParseRegisterValue(registers["cr0"]));
pContext->RegCr2 = static_cast<DWORD>(GdbSrvController::ParseRegisterValue(registers["cr2"]));
pContext->RegCr3 = static_cast<DWORD>(GdbSrvController::ParseRegisterValue(registers["cr3"]));
pContext->RegCr4 = static_cast<DWORD>(GdbSrvController::ParseRegisterValue(registers["cr4"]));
pContext->RegCr8 = static_cast<DWORD>(GdbSrvController::ParseRegisterValue(registers["cr8"]));
pContext->RegGroupSelection.fSystemRegisters = TRUE;
// get all floating point registers (FPU)
pContext->ControlWord = static_cast<DWORD>(GdbSrvController::ParseRegisterValue32(registers["fctrl"]));
pContext->StatusWord = static_cast<DWORD>(GdbSrvController::ParseRegisterValue32(registers["fstat"]));
pContext->TagWord = static_cast<DWORD>(GdbSrvController::ParseRegisterValue32(registers["ftag"]));
pContext->ErrorOffset = static_cast<DWORD>(GdbSrvController::ParseRegisterValue32(registers["fioff"]));
pContext->ErrorSelector = static_cast<DWORD>(GdbSrvController::ParseRegisterValue32(registers["fiseg"]));
pContext->DataOffset = static_cast<DWORD>(GdbSrvController::ParseRegisterValue32(registers["fooff"]));
pContext->DataSelector = static_cast<DWORD>(GdbSrvController::ParseRegisterValue32(registers["foseg"]));
// x87 registers (FPU)
for (int index = 0; index < s_numberFPRegList; ++index)
{
std::string regName(s_fpRegList[index]);
GdbSrvController::ParseRegisterVariableSize(registers[regName],
reinterpret_cast<BYTE*>(&pContext->RegisterArea[index * s_numberOfBytesCoprocessorRegister]),
s_numberOfBytesCoprocessorRegister);
}
pContext->RegGroupSelection.fFloatingPointRegs = TRUE;
// Get X64 SSE registers if the x64 SSE context enabled?
if (m_fEnableSSEContext)
{
registers = pController->QueryRegisters(processorNumber, s_sseX64RegList, s_numberOfSseX64Registers);
const int numberOfBytesSseX64Registers = sizeof(pContext->RegSSE[0]);
for (int index = 0; index < s_numberOfSseX64Registers; ++index)
{
std::string regName(s_sseX64RegList[index]);
GdbSrvController::ParseRegisterVariableSize(registers[regName],
reinterpret_cast<BYTE*>(&pContext->RegSSE[index]),
numberOfBytesSseX64Registers);
}
pContext->RegMXCSR = static_cast<DWORD>(GdbSrvController::ParseRegisterValue32(registers["mxcsr"]));
pContext->RegGroupSelection.fSSERegisters = TRUE;
}
pContext->RegGroupSelection.fSegmentDescriptors = FALSE;
pContext->RegGroupSelection.fDebugRegs = FALSE;
return S_OK;
}
CATCH_AND_RETURN_HRESULT;
}