HyperDbg/hyperdbg/hprdbgctrl/code/debugger/misc/readmem.cpp
Behrooz Abbassi f817cbb801
Refactor: Improve projects configurations
- Improve Precompiled header usage
- Change "Output Directory" and "Intermediate Directory" of all projects to the same values
- Discard pdb files from release file
2022-05-04 16:38:21 -07:00

409 lines
11 KiB
C++

/**
* @file readmem.cpp
* @author Sina Karvandi (sina@hyperdbg.org)
* @author Alee Amini (aleeamini@gmail.com)
* @brief HyperDbg command for u and d*
* @details
* @version 0.1
* @date 2020-05-27
*
* @copyright This project is released under the GNU Public License v3.
*
*/
#include "pch.h"
//
// Global Variables
//
extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
/**
* @brief Read memory and disassembler
*
* @param Style style of show memory (as byte, dwrod, qword)
* @param Address location of where to read the memory
* @param MemoryType type of memory (phyical or virtual)
* @param ReadingType read from kernel or vmx-root
* @param Pid The target process id
* @param Size size of memory to read
* @param DtDetails Options for dt structure show details
*
* @return VOID
*/
VOID
HyperDbgReadMemoryAndDisassemble(DEBUGGER_SHOW_MEMORY_STYLE Style,
UINT64 Address,
DEBUGGER_READ_MEMORY_TYPE MemoryType,
DEBUGGER_READ_READING_TYPE ReadingType,
UINT32 Pid,
UINT32 Size,
PDEBUGGER_DT_COMMAND_OPTIONS DtDetails)
{
BOOL Status;
ULONG ReturnedLength;
DEBUGGER_READ_MEMORY ReadMem = {0};
UINT32 OperationCode;
CHAR Character;
ReadMem.Address = Address;
ReadMem.Pid = Pid;
ReadMem.Size = Size;
ReadMem.MemoryType = MemoryType;
ReadMem.ReadingType = ReadingType;
ReadMem.Style = Style;
ReadMem.DtDetails = DtDetails;
//
// send the request
//
if (g_IsSerialConnectedToRemoteDebuggee)
{
KdSendReadMemoryPacketToDebuggee(&ReadMem);
return;
}
//
// It's on VMI mode
//
AssertShowMessageReturnStmt(g_DeviceHandle, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturn);
//
// allocate buffer for transfering messages
//
unsigned char * OutputBuffer = (unsigned char *)malloc(Size * sizeof(unsigned char));
ZeroMemory(OutputBuffer, Size * sizeof(unsigned char));
Status = DeviceIoControl(g_DeviceHandle, // Handle to device
IOCTL_DEBUGGER_READ_MEMORY, // IO Control code
&ReadMem, // Input Buffer to driver.
SIZEOF_DEBUGGER_READ_MEMORY, // Input buffer length
OutputBuffer, // Output Buffer from driver.
Size, // Length of output buffer in bytes.
&ReturnedLength, // Bytes placed in buffer.
NULL // synchronous call
);
if (!Status)
{
ShowMessages("ioctl failed with code 0x%x\n", GetLastError());
free(OutputBuffer);
return;
}
switch (Style)
{
case DEBUGGER_SHOW_COMMAND_DT:
//
// Show the 'dt' command view
//
if (Size == ReturnedLength)
{
ScriptEngineShowDataBasedOnSymbolTypesWrapper(DtDetails->TypeName,
Address,
FALSE,
OutputBuffer,
DtDetails->AdditionalParameters);
}
else if (ReturnedLength == 0)
{
ShowMessages("err, invalid address");
}
else
{
ShowMessages("err, invalid address or memory is smaller than the structure size");
}
break;
case DEBUGGER_SHOW_COMMAND_DB:
ShowMemoryCommandDB(OutputBuffer, Size, Address, MemoryType, ReturnedLength);
break;
case DEBUGGER_SHOW_COMMAND_DC:
ShowMemoryCommandDC(OutputBuffer, Size, Address, MemoryType, ReturnedLength);
break;
case DEBUGGER_SHOW_COMMAND_DD:
ShowMemoryCommandDD(OutputBuffer, Size, Address, MemoryType, ReturnedLength);
break;
case DEBUGGER_SHOW_COMMAND_DQ:
ShowMemoryCommandDQ(OutputBuffer, Size, Address, MemoryType, ReturnedLength);
break;
case DEBUGGER_SHOW_COMMAND_DISASSEMBLE64:
//
// Show diassembles
//
HyperDbgDisassembler64(OutputBuffer, Address, ReturnedLength, 0, FALSE, NULL);
break;
case DEBUGGER_SHOW_COMMAND_DISASSEMBLE32:
//
// Show diassembles
//
HyperDbgDisassembler32(OutputBuffer, Address, ReturnedLength, 0, FALSE, NULL);
break;
}
//
// free the buffer
//
free(OutputBuffer);
ShowMessages("\n");
}
/**
* @brief Show memory in bytes (DB)
*
* @param OutputBuffer the buffer to show
* @param Size size of memory to read
* @param Address location of where to read the memory
* @param MemoryType type of memory (phyical or virtual)
* @param Length Length of memory to show
*/
void
ShowMemoryCommandDB(unsigned char * OutputBuffer, UINT Size, UINT64 Address, DEBUGGER_READ_MEMORY_TYPE MemoryType, UINT64 Length)
{
unsigned int Character;
for (int i = 0; i < Size; i += 16)
{
if (MemoryType == DEBUGGER_READ_PHYSICAL_ADDRESS)
{
ShowMessages("#\t");
}
//
// Print address
//
ShowMessages("%s ", SeparateTo64BitValue((UINT64)(Address + i)).c_str());
//
// Print the hex code
//
for (size_t j = 0; j < 16; j++)
{
//
// check to see if the address is valid or not
//
if (i + j >= Length)
{
ShowMessages("?? ");
}
else
{
ShowMessages("%02X ", OutputBuffer[i + j]);
}
}
//
// Print the character
//
ShowMessages(" ");
for (size_t j = 0; j < 16; j++)
{
Character = (OutputBuffer[i + j]);
if (isprint(Character))
{
ShowMessages("%c", Character);
}
else
{
ShowMessages(".");
}
}
//
// Go to new line
//
ShowMessages("\n");
}
}
/**
* @brief Show memory in dword format (DC)
*
* @param OutputBuffer the buffer to show
* @param Size size of memory to read
* @param Address location of where to read the memory
* @param MemoryType type of memory (phyical or virtual)
* @param Length Length of memory to show
*/
void
ShowMemoryCommandDC(unsigned char * OutputBuffer, UINT Size, UINT64 Address, DEBUGGER_READ_MEMORY_TYPE MemoryType, UINT64 Length)
{
unsigned int Character;
for (int i = 0; i < Size; i += 16)
{
if (MemoryType == DEBUGGER_READ_PHYSICAL_ADDRESS)
{
ShowMessages("#\t");
}
//
// Print address
//
ShowMessages("%s ", SeparateTo64BitValue((UINT64)(Address + i)).c_str());
//
// Print the hex code
//
for (size_t j = 0; j < 16; j += 4)
{
//
// check to see if the address is valid or not
//
if (i + j >= Length)
{
ShowMessages("???????? ");
}
else
{
UINT32 OutputBufferVar = *((UINT32 *)&OutputBuffer[i + j]);
ShowMessages("%08X ", OutputBufferVar);
}
}
//
// Print the character
//
ShowMessages(" ");
for (size_t j = 0; j < 16; j++)
{
Character = (OutputBuffer[i + j]);
if (isprint(Character))
{
ShowMessages("%c", Character);
}
else
{
ShowMessages(".");
}
}
//
// Go to new line
//
ShowMessages("\n");
}
}
/**
* @brief Show memory in dword format (DD)
*
* @param OutputBuffer the buffer to show
* @param Size size of memory to read
* @param Address location of where to read the memory
* @param MemoryType type of memory (phyical or virtual)
* @param Length Length of memory to show
*/
void
ShowMemoryCommandDD(unsigned char * OutputBuffer, UINT Size, UINT64 Address, DEBUGGER_READ_MEMORY_TYPE MemoryType, UINT64 Length)
{
CHAR Character;
for (int i = 0; i < Size; i += 16)
{
if (MemoryType == DEBUGGER_READ_PHYSICAL_ADDRESS)
{
ShowMessages("#\t");
}
//
// Print address
//
ShowMessages("%s ", SeparateTo64BitValue((UINT64)(Address + i)).c_str());
//
// Print the hex code
//
for (size_t j = 0; j < 16; j += 4)
{
//
// check to see if the address is valid or not
//
if (i + j >= Length)
{
ShowMessages("???????? ");
}
else
{
UINT32 OutputBufferVar = *((UINT32 *)&OutputBuffer[i + j]);
ShowMessages("%08X ", OutputBufferVar);
}
}
//
// Go to new line
//
ShowMessages("\n");
}
}
/**
* @brief Show memory in qword format (DQ)
*
* @param OutputBuffer the buffer to show
* @param Size size of memory to read
* @param Address location of where to read the memory
* @param MemoryType type of memory (phyical or virtual)
* @param Length Length of memory to show
*/
void
ShowMemoryCommandDQ(unsigned char * OutputBuffer, UINT Size, UINT64 Address, DEBUGGER_READ_MEMORY_TYPE MemoryType, UINT64 Length)
{
for (int i = 0; i < Size; i += 16)
{
if (MemoryType == DEBUGGER_READ_PHYSICAL_ADDRESS)
{
ShowMessages("#\t");
}
//
// Print address
//
ShowMessages("%s ", SeparateTo64BitValue((UINT64)(Address + i)).c_str());
//
// Print the hex code
//
for (size_t j = 0; j < 16; j += 8)
{
//
// check to see if the address is valid or not
//
if (i + j >= Length)
{
ShowMessages("???????? ");
}
else
{
UINT32 OutputBufferVar = *((UINT32 *)&OutputBuffer[i + j + 4]);
ShowMessages("%08X`", OutputBufferVar);
OutputBufferVar = *((UINT32 *)&OutputBuffer[i + j]);
ShowMessages("%08X ", OutputBufferVar);
}
}
//
// Go to new line
//
ShowMessages("\n");
}
}