HyperDbg/hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/r.cpp
2022-01-18 22:38:56 +03:30

370 lines
9.5 KiB
C++

/**
* @file r.cpp
* @author Alee Amini (alee@hyperdbg.org)
* @author Sina Karvandi (sina@hyperdbg.org)
* @brief r command
* @details
* @version 0.1
* @date 2021-02-27
*
* @copyright This project is released under the GNU Public License v3.
*
*/
#include "..\hprdbgctrl\pch.h"
using namespace std;
//
// Global Variables
//
extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
map<string, REGS_ENUM> RegistersMap = {
{"rax", REGISTER_RAX},
{"eax", REGISTER_EAX},
{"ax", REGISTER_AX},
{"ah", REGISTER_AH},
{"al", REGISTER_AL},
{"rbx", REGISTER_RBX},
{"ebx", REGISTER_EBX},
{"bx", REGISTER_BX},
{"bh", REGISTER_BH},
{"bl", REGISTER_BL},
{"rcx", REGISTER_RCX},
{"ecx", REGISTER_ECX},
{"cx", REGISTER_CX},
{"ch", REGISTER_CH},
{"cl", REGISTER_CL},
{"rdx", REGISTER_RDX},
{"edx", REGISTER_EDX},
{"dx", REGISTER_DX},
{"dh", REGISTER_DH},
{"dl", REGISTER_DL},
{"rsi", REGISTER_RSI},
{"esi", REGISTER_ESI},
{"si", REGISTER_SI},
{"sil", REGISTER_SIL},
{"rdi", REGISTER_RDI},
{"edi", REGISTER_EDI},
{"di", REGISTER_DI},
{"dil", REGISTER_DIL},
{"rbp", REGISTER_RBP},
{"ebp", REGISTER_EBP},
{"bp", REGISTER_BP},
{"bpl", REGISTER_BPL},
{"rsp", REGISTER_RSP},
{"esp", REGISTER_ESP},
{"sp", REGISTER_SP},
{"spl", REGISTER_SPL},
{"r8", REGISTER_R8},
{"r8d", REGISTER_R8D},
{"r8w", REGISTER_R8W},
{"r8h", REGISTER_R8H},
{"r8l", REGISTER_R8L},
{"r9", REGISTER_R9},
{"r9d", REGISTER_R9D},
{"r9w", REGISTER_R9W},
{"r9h", REGISTER_R9H},
{"r9l", REGISTER_R9L},
{"r10", REGISTER_R10},
{"r10d", REGISTER_R10D},
{"r10w", REGISTER_R10W},
{"r10h", REGISTER_R10H},
{"r10l", REGISTER_R10L},
{"r11", REGISTER_R11},
{"r11d", REGISTER_R11D},
{"r11w", REGISTER_R11W},
{"r11h", REGISTER_R11H},
{"r11l", REGISTER_R11L},
{"r12", REGISTER_R12},
{"r12d", REGISTER_R12D},
{"r12w", REGISTER_R12W},
{"r12h", REGISTER_R12H},
{"r12l", REGISTER_R12L},
{"r13", REGISTER_R13},
{"r13d", REGISTER_R13D},
{"r13w", REGISTER_R13W},
{"r13h", REGISTER_R13H},
{"r13l", REGISTER_R13L},
{"r14", REGISTER_R14},
{"r14d", REGISTER_R14D},
{"r14w", REGISTER_R14W},
{"r14h", REGISTER_R14H},
{"r14l", REGISTER_R14L},
{"r15", REGISTER_R15},
{"r15d", REGISTER_R15D},
{"r15w", REGISTER_R15W},
{"r15h", REGISTER_R15H},
{"r15l", REGISTER_R15L},
{"ds", REGISTER_DS},
{"es", REGISTER_ES},
{"fs", REGISTER_FS},
{"gs", REGISTER_GS},
{"cs", REGISTER_CS},
{"ss", REGISTER_SS},
{"rflags", REGISTER_RFLAGS},
{"eflags", REGISTER_EFLAGS},
{"flags", REGISTER_FLAGS},
{"cf", REGISTER_CF},
{"pf", REGISTER_PF},
{"af", REGISTER_AF},
{"zf", REGISTER_ZF},
{"sf", REGISTER_SF},
{"tf", REGISTER_TF},
{"if", REGISTER_IF},
{"df", REGISTER_DF},
{"of", REGISTER_OF},
{"iopl", REGISTER_IOPL},
{"nt", REGISTER_NT},
{"rf", REGISTER_RF},
{"vm", REGISTER_VM},
{"ac", REGISTER_AC},
{"vif", REGISTER_VIF},
{"vip", REGISTER_VIP},
{"id", REGISTER_ID},
{"idtr", REGISTER_IDTR},
{"gdtr", REGISTER_GDTR},
{"ldtr", REGISTER_LDTR},
{"tr", REGISTER_TR},
{"cr0", REGISTER_CR0},
{"cr2", REGISTER_CR2},
{"cr3", REGISTER_CR3},
{"cr4", REGISTER_CR4},
{"cr8", REGISTER_CR8},
{"dr0", REGISTER_DR0},
{"dr1", REGISTER_DR1},
{"dr2", REGISTER_DR2},
{"dr3", REGISTER_DR3},
{"dr6", REGISTER_DR6},
{"dr7", REGISTER_DR7},
{"rip", REGISTER_RIP},
{"eip", REGISTER_EIP},
{"ip", REGISTER_IP},
};
/**
* @brief help of r command
*
* @return VOID
*/
VOID
CommandRHelp()
{
ShowMessages("r : read or modify registers.\n\n");
ShowMessages("syntax : \tr [register] [= expr]\n");
ShowMessages("\t\te.g : r @rax\n");
ShowMessages("\t\te.g : r rax\n");
ShowMessages("\t\te.g : r rax = 0x55\n");
ShowMessages("\t\te.g : r rax = @rbx + @rcx + 0n10\n");
}
/**
* @brief handler of r show all registers command
*
* @return BOOLEAN
*/
VOID
ShowAllRegisters()
{
PDEBUGGEE_REGISTER_READ_DESCRIPTION RegD =
new DEBUGGEE_REGISTER_READ_DESCRIPTION;
RegD->RegisterID = DEBUGGEE_SHOW_ALL_REGISTERS;
KdSendReadRegisterPacketToDebuggee(RegD);
delete (RegD);
}
/**
* @brief handler of r command
*
* @param SplittedCommand
* @param Command
* @return VOID
*/
VOID
CommandR(vector<string> SplittedCommand, string Command)
{
//
// Interpret here
//
PVOID CodeBuffer;
UINT64 BufferAddress;
UINT32 BufferLength;
UINT32 Pointer;
REGS_ENUM Reg;
vector<string> Tmp;
string SetRegValue = "SetRegValue";
if (SplittedCommand[0] != "r")
{
return;
}
if (SplittedCommand.size() == 1)
{
//
// show all registers
//
if (g_IsSerialConnectedToRemoteDebuggee)
{
ShowAllRegisters();
}
else
{
ShowMessages("err, reading registers (r) is not valid in the current "
"context, you should connect to a debuggee\n");
}
return;
}
//
// clear additional space of the command string
//
//
// if command does not contain a '=' means user wants to read it
//
if (Command.find('=', 0) == string::npos)
{
//
//erase '=' from the string now we have just the name of register
//
Command.erase(0, 1);
PDEBUGGEE_REGISTER_READ_DESCRIPTION RegD =
new DEBUGGEE_REGISTER_READ_DESCRIPTION;
ReplaceAll(Command, "@", "");
ReplaceAll(Command, " ", "");
if (RegistersMap.find(Command) != RegistersMap.end())
{
Reg = RegistersMap[Command];
}
else
{
//
//set the Reg to -1(invalid register)
//
Reg = (REGS_ENUM)-1;
}
if (Reg != -1)
{
RegD->RegisterID = Reg;
//
// send the request
//
if (g_IsSerialConnectedToRemoteDebuggee)
{
KdSendReadRegisterPacketToDebuggee(RegD);
}
else
{
ShowMessages("err, reading registers (r) is not valid in the current "
"context, you should connect to a debuggee\n");
}
}
else
{
ShowMessages("err, invalid register\n");
}
delete (RegD);
}
//
// if command contains a '=' means user wants modify the register
//
else if (Command.find('=', 0) != string::npos)
{
PDEBUGGEE_REGISTER_READ_DESCRIPTION RegD =
new DEBUGGEE_REGISTER_READ_DESCRIPTION;
Command.erase(0, 1);
Tmp = Split(Command, '=');
if (Tmp.size() == 2)
{
ReplaceAll(Tmp[0], " ", "");
string tmp = Tmp[0];
if (RegistersMap.find(Tmp[0]) != RegistersMap.end())
{
Reg = RegistersMap[Tmp[0]];
}
else
{
ReplaceAll(tmp, "@", "");
if (RegistersMap.find(tmp) != RegistersMap.end())
{
Reg = RegistersMap[tmp];
}
else
{
Reg = (REGS_ENUM)-1;
}
}
if (Reg != -1)
{
RegD->RegisterID = Reg;
//
// send the request
//
SetRegValue = "@" + tmp + '=' + Tmp[1] + "; ";
if (g_IsSerialConnectedToRemoteDebuggee)
{
//
// Send over serial
//
//
// Run script engine handler
//
CodeBuffer = ScriptEngineParseWrapper((char *)SetRegValue.c_str(), TRUE);
if (CodeBuffer == NULL)
{
//
// return to show that this item contains an script
//
delete RegD;
return;
}
//
// Print symbols (test)
//
// PrintSymbolBufferWrapper(CodeBuffer);
//
// Set the buffer and length
//
BufferAddress = ScriptEngineWrapperGetHead(CodeBuffer);
BufferLength = ScriptEngineWrapperGetSize(CodeBuffer);
Pointer = ScriptEngineWrapperGetPointer(CodeBuffer);
//
// Send it to the remote debuggee
//
KdSendScriptPacketToDebuggee(BufferAddress, BufferLength, Pointer, FALSE);
//
// Remove the buffer of script engine interpreted code
//
ScriptEngineWrapperRemoveSymbolBuffer(CodeBuffer);
}
else
{
//
// error
//
ShowMessages("err, you're not connected to any debuggee\n");
}
}
else
{
//
// error
//
ShowMessages("err, invalid register\n");
}
}
}
}