Merge pull request #671 from nikzad66/uin-uout-commands
Some checks failed
vs2026-ci / win-amd64-build (debug, x64) (push) Has been cancelled
vs2026-ci / win-amd64-build (release, x64) (push) Has been cancelled
vs2026-ci / Deploy release (push) Has been cancelled

Uin uout commands
This commit is contained in:
Sina Karvandi 2026-08-10 12:00:21 +02:00 • committed by GitHub
commit 80f224fa58
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
24 changed files with 1128 additions and 13 deletions

View file

@ -29,4 +29,5 @@ Just so you know – the attributions listed on this credits page are acknowledg
- unrustled.jimmies for helping us debug and fix issues, and his contributions in HyperDbg
- Hari Mishal ([@harimishal1](https://github.com/harimishal1)) for his works on the hypertrace project for supporting Last Branch Record (LBR)
- Masoud Rahimi Jafari ([@masoudrahimi01](https://github.com/masoudrahimi01)) for his works on the hypertrace project for supporting Intel Processor Trace (PT)
- Abolfazl Hassani ([@FallinBinary](https://github.com/FallinBinary)) for his contributions in HyperDbg
- Abolfazl Hassani ([@FallinBinary](https://github.com/FallinBinary)) for his contributions in HyperDbg
- Hossein Shirdel ([@nikzad66](https://github.com/nikzad66)) for his contributions in HyperDbg

View file

@ -1529,6 +1529,104 @@ DebuggerCommandCpuid(PDEBUGGER_CPUID_REQUEST_RESPONSE DebuggerCpuidRequest)
return STATUS_SUCCESS;
}
/**
* @brief Handle User IN request in vmx-root mode
*
* @param DebuggerUserInRequest perform IN instruction (user specified)
* @return NTSTATUS
*/
NTSTATUS
DebuggerCommandUserIn(PDEBUGGER_USER_IN_REQUEST_RESPONSE DebuggerUserInRequest)
{
SHORT Register = DebuggerUserInRequest->UserChosenRegister;
USHORT Port = DebuggerUserInRequest->PortAddress;
//
// Zero out memory buffer
//
RtlZeroMemory(DebuggerUserInRequest, SIZEOF_DEBUGGER_USER_IN_REQUEST_RESPONSE);
//
// we're already in kernel mode, so there is no need to check for CPL and IOPL, TSS and etc.
//
//
// handle I/O instructions
//
switch (Register)
{
//
// store the results in the Data field
//
case AL_8_BIT_REGISTER:
DebuggerUserInRequest->Data = CpuIoInByte(Port);
break;
case AX_16_BIT_REGISTER:
DebuggerUserInRequest->Data = CpuIoInWord(Port);
break;
case EAX_32_BIT_REGISTER:
DebuggerUserInRequest->Data = CpuIoInDword(Port);
break;
}
DebuggerUserInRequest->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
return STATUS_SUCCESS;
}
/**
* @brief Handle User OUT request in vmx-root mode
*
* @param DebuggerUserInRequest perform OUT instruction (user specified)
* @return NTSTATUS
*/
NTSTATUS
DebuggerCommandUserOut(PDEBUGGER_USER_OUT_REQUEST_RESPONSE DebuggerUserOutRequest)
{
SHORT Register = DebuggerUserOutRequest->UserChosenRegister;
USHORT Port = DebuggerUserOutRequest->PortAddress;
UINT32 Value = DebuggerUserOutRequest->Value;
//
// Zero out memory buffer
//
RtlZeroMemory(DebuggerUserOutRequest, SIZEOF_DEBUGGER_USER_OUT_REQUEST_RESPONSE);
//
// we're already in kernel mode, so there is no need to check for CPL and IOPL, TSS and etc.
//
//
// handle I/O instructions
//
switch (Register)
{
case AL_8_BIT_REGISTER:
__outbyte(Port, (UCHAR)Value);
break;
case AX_16_BIT_REGISTER:
__outword(Port, (USHORT)Value);
break;
case EAX_32_BIT_REGISTER:
__outdword(Port, Value);
break;
}
DebuggerUserOutRequest->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
return STATUS_SUCCESS;
}
/**
* @brief Perform the command finished signal
*

View file

@ -2261,6 +2261,8 @@ KdDispatchAndPerformCommandsFromDebugger(PROCESSOR_DEBUGGING_STATE * DbgState)
PDEBUGGEE_STEP_PACKET SteppingPacket;
PDEBUGGER_FLUSH_LOGGING_BUFFERS FlushPacket;
PDEBUGGER_CPUID_REQUEST_RESPONSE CpuidPacket;
PDEBUGGER_USER_IN_REQUEST_RESPONSE InPacket;
PDEBUGGER_USER_OUT_REQUEST_RESPONSE OutPacket;
PDEBUGGER_CALLSTACK_REQUEST CallstackPacket;
PDEBUGGER_SINGLE_CALLSTACK_FRAME CallstackFrameBuffer;
PDEBUGGER_DEBUGGER_TEST_QUERY_BUFFER TestQueryPacket;
@ -2552,6 +2554,44 @@ KdDispatchAndPerformCommandsFromDebugger(PROCESSOR_DEBUGGING_STATE * DbgState)
break;
case DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_MODE_USER_IN_INSTRUCTION:
InPacket = (DEBUGGER_USER_IN_REQUEST_RESPONSE *)(((CHAR *)TheActualPacket) + sizeof(DEBUGGER_REMOTE_PACKET));
//
// Receieve IN instruction result
//
DebuggerCommandUserIn(InPacket);
//
// Send the result of IN instruction back to the debugger
//
KdResponsePacketToDebugger(DEBUGGER_REMOTE_PACKET_TYPE_DEBUGGEE_TO_DEBUGGER,
DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_OF_USER_IN_INSTRUCTION,
(CHAR *)InPacket,
sizeof(DEBUGGER_USER_IN_REQUEST_RESPONSE));
break;
case DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_MODE_USER_OUT_INSTRUCTION:
OutPacket = (DEBUGGER_USER_OUT_REQUEST_RESPONSE *)(((CHAR *)TheActualPacket) + sizeof(DEBUGGER_REMOTE_PACKET));
//
// Receieve OUT instruction result
//
DebuggerCommandUserOut(OutPacket);
//
// Send the result of OUT instruction back to the debugger
//
KdResponsePacketToDebugger(DEBUGGER_REMOTE_PACKET_TYPE_DEBUGGEE_TO_DEBUGGER,
DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_OF_USER_OUT_INSTRUCTION,
(CHAR *)OutPacket,
sizeof(DEBUGGER_USER_OUT_REQUEST_RESPONSE));
break;
case DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_MODE_CALLSTACK:
CallstackPacket = (DEBUGGER_CALLSTACK_REQUEST *)(((CHAR *)TheActualPacket) + sizeof(DEBUGGER_REMOTE_PACKET));

View file

@ -411,6 +411,8 @@ DrvDispatchVmmIoControl(PIRP Irp, PIO_STACK_LOCATION IrpStack, BOOLEAN * DoNotCh
PDEBUGGER_MODIFY_EVENTS DebuggerModifyEventRequest;
PDEBUGGER_FLUSH_LOGGING_BUFFERS DebuggerFlushBuffersRequest;
PDEBUGGER_CPUID_REQUEST_RESPONSE DebuggerCpuidRequest;
PDEBUGGER_USER_IN_REQUEST_RESPONSE DebuggerUserInRequest;
PDEBUGGER_USER_OUT_REQUEST_RESPONSE DebuggerUserOutRequest;
PDEBUGGER_PREALLOC_COMMAND DebuggerReservePreallocPoolRequest;
PDEBUGGER_PREACTIVATE_COMMAND DebuggerPreactivationRequest;
PDEBUGGER_APIC_REQUEST DebuggerApicRequest;
@ -864,6 +866,62 @@ DrvDispatchVmmIoControl(PIRP Irp, PIO_STACK_LOCATION IrpStack, BOOLEAN * DoNotCh
break;
case IOCTL_DEBUGGER_USER_IN:
//
// Validate and adjust the parameters, and set the target buffer to the system buffer of the IRP
//
if (!DrvValidateAndAdjustIoctlParameter(SIZEOF_DEBUGGER_USER_IN_REQUEST_RESPONSE,
(PVOID *)&DebuggerUserInRequest,
Irp,
IrpStack,
&InBuffLength,
&OutBuffLength))
{
Status = STATUS_INVALID_PARAMETER;
break;
}
//
// Perform IN instruction
//
DebuggerCommandUserIn(DebuggerUserInRequest);
//
// Adjust the status and output size
//
DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGER_USER_IN_REQUEST_RESPONSE, DoNotChangeInformation, Irp, &Status);
break;
case IOCTL_DEBUGGER_USER_OUT:
//
// Validate and adjust the parameters, and set the target buffer to the system buffer of the IRP
//
if (!DrvValidateAndAdjustIoctlParameter(SIZEOF_DEBUGGER_USER_OUT_REQUEST_RESPONSE,
(PVOID *)&DebuggerUserOutRequest,
Irp,
IrpStack,
&InBuffLength,
&OutBuffLength))
{
Status = STATUS_INVALID_PARAMETER;
break;
}
//
// Perform OUT instruction
//
DebuggerCommandUserOut(DebuggerUserOutRequest);
//
// Adjust the status and output size
//
DrvAdjustStatusAndSetOutputSize(SIZEOF_DEBUGGER_USER_OUT_REQUEST_RESPONSE, DoNotChangeInformation, Irp, &Status);
break;
case IOCTL_DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS:
//

View file

@ -48,6 +48,12 @@ DebuggerCommandFlush(PDEBUGGER_FLUSH_LOGGING_BUFFERS DebuggerFlushBuffersRequest
NTSTATUS
DebuggerCommandCpuid(PDEBUGGER_CPUID_REQUEST_RESPONSE DebuggerCpuidRequest);
NTSTATUS
DebuggerCommandUserIn(PDEBUGGER_USER_IN_REQUEST_RESPONSE DebuggerUserInRequest);
NTSTATUS
DebuggerCommandUserOut(PDEBUGGER_USER_OUT_REQUEST_RESPONSE DebuggerUserOutRequest);
NTSTATUS
DebuggerCommandSignalExecutionState(PDEBUGGER_SEND_COMMAND_EXECUTION_FINISHED_SIGNAL DebuggerFinishedExecutionRequest);

View file

@ -76,6 +76,8 @@ typedef enum _DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION
DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_MODE_CHANGE_CORE,
DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_MODE_FLUSH_BUFFERS,
DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_MODE_USER_CPUID_REQUEST,
DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_MODE_USER_IN_INSTRUCTION,
DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_MODE_USER_OUT_INSTRUCTION,
DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_MODE_CALLSTACK,
DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_MODE_TEST_QUERY,
DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_MODE_CHANGE_PROCESS,
@ -119,6 +121,8 @@ typedef enum _DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION
DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_OF_FORMATS,
DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_OF_FLUSH,
DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_OF_USER_CPUID,
DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_OF_USER_IN_INSTRUCTION,
DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_OF_USER_OUT_INSTRUCTION,
DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_OF_CALLSTACK,
DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_TEST_QUERY,
DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_OF_REGISTERING_EVENT,

View file

@ -396,6 +396,20 @@
#define IOCTL_DEBUGGER_CPUID \
CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x27, METHOD_BUFFERED, FILE_ANY_ACCESS)
/**
* @brief ioctl, to perform IN instruction
*
*/
#define IOCTL_DEBUGGER_USER_IN \
CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x28, METHOD_BUFFERED, FILE_ANY_ACCESS)
/**
* @brief ioctl, to perform OUT instruction
*
*/
#define IOCTL_DEBUGGER_USER_OUT \
CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_VMM_IOCTL + 0x29, METHOD_BUFFERED, FILE_ANY_ACCESS)
//////////////////////////////////////////////////
// HyperTrace IOCTLs //
//////////////////////////////////////////////////

View file

@ -1774,3 +1774,47 @@ typedef struct _DEBUGGER_CPUID_REQUEST_RESPONSE
} DEBUGGER_CPUID_REQUEST_RESPONSE, *PDEBUGGER_CPUID_REQUEST_RESPONSE;
// ==============================================================================================
#define SIZEOF_DEBUGGER_USER_IN_REQUEST_RESPONSE \
sizeof(DEBUGGER_USER_IN_REQUEST_RESPONSE)
/**
* @brief Cpu registers for I/O instructions (related to _DEBUGGER_USER_IN_REQUEST_RESPONSE
* and SIZEOF_DEBUGGER_USER_OUT_REQUEST_RESPONSE structs)
*
*/
typedef enum _DEBUGGER_CPU_REGISTER_USER_IO
{
AL_8_BIT_REGISTER,
AX_16_BIT_REGISTER,
EAX_32_BIT_REGISTER
} DEBUGGER_CPU_REGISTER_USER_IO;
/**
* @brief Request and response for user IN instruction
*
*/
typedef struct _DEBUGGER_USER_IN_REQUEST_RESPONSE
{
DEBUGGER_CPU_REGISTER_USER_IO UserChosenRegister; // from enum data type (_DEBUGGER_CPU_REGISTER_USER_IO)
USHORT PortAddress; // totally 65,536 (2^16) port address (0 - 65,535)
ULONG Data; // returned result
UINT32 KernelStatus;
} DEBUGGER_USER_IN_REQUEST_RESPONSE, *PDEBUGGER_USER_IN_REQUEST_RESPONSE;
// ==============================================================================================
#define SIZEOF_DEBUGGER_USER_OUT_REQUEST_RESPONSE \
sizeof(DEBUGGER_USER_OUT_REQUEST_RESPONSE)
typedef struct _DEBUGGER_USER_OUT_REQUEST_RESPONSE
{
DEBUGGER_CPU_REGISTER_USER_IO UserChosenRegister; // from enum data type (_DEBUGGER_CPU_REGISTER_USER_IO)
USHORT PortAddress; // totally 65,536 (2^16) port address (0 - 65,535)
UINT32 Value; // the value to be written to the port address
UINT32 KernelStatus;
} DEBUGGER_USER_OUT_REQUEST_RESPONSE, *PDEBUGGER_USER_OUT_REQUEST_RESPONSE;
// ==============================================================================================

View file

@ -336,6 +336,20 @@ hyperdbg_u_pt_mmap(HYPERTRACE_PT_MMAP_PACKETS * MmapRequest);
IMPORT_EXPORT_LIBHYPERDBG BOOLEAN
hyperdbg_u_request_cpuid(UINT32 FunctionId, UINT32 SubFunctionId);
//
// IN instruction related command
// Exported functionality of the 'uin'
//
IMPORT_EXPORT_LIBHYPERDBG BOOLEAN
hyperdebg_u_in_instruction(DEBUGGER_USER_IN_REQUEST_RESPONSE InRequest);
//
// OUT instruction related command
// Exported functionality of the 'uout'
//
IMPORT_EXPORT_LIBHYPERDBG BOOLEAN
hyperdebg_u_out_instruction(DEBUGGER_USER_OUT_REQUEST_RESPONSE OutRequest);
//
// Transparent mode related command
// Exported functionality of the '!hide', and '!unhide' commands

View file

@ -342,7 +342,7 @@ ConvertStringToUInt64(string TextToConvert, PUINT64 Result)
}
/**
* @brief check and convert string to a 32 bit unsigned it and also
* @brief check and convert string to a 32 bit unsigned int and also
* check for special notations like 0x etc.
* @param TextToConvert the target string
* @param Result result will be save to the pointer
@ -433,6 +433,95 @@ ConvertStringToUInt32(string TextToConvert, PUINT32 Result)
}
}
/**
* @brief check and convert string to a 16 bit unsigned int and also
* check for special notations like 0x etc.
* @param TextToConvert the target string
* @param Result result will be save to the pointer
* @return BOOLEAN shows whether the conversion was successful or not
*/
BOOLEAN
ConvertStringToUInt16(string TextToConvert, PUINT16 Result)
{
BOOLEAN IsDecimal = FALSE; // By default everything is hex
if (TextToConvert.rfind("0x", 0) == 0 || TextToConvert.rfind("0X", 0) == 0 ||
TextToConvert.rfind("\\x", 0) == 0 ||
TextToConvert.rfind("\\X", 0) == 0)
{
TextToConvert = TextToConvert.erase(0, 2);
}
else if (TextToConvert.rfind('x', 0) == 0 ||
TextToConvert.rfind('X', 0) == 0)
{
TextToConvert = TextToConvert.erase(0, 1);
}
else if (TextToConvert.rfind("0n", 0) == 0 || TextToConvert.rfind("0N", 0) == 0 ||
TextToConvert.rfind("\\n", 0) == 0 ||
TextToConvert.rfind("\\N", 0) == 0)
{
TextToConvert = TextToConvert.erase(0, 2);
IsDecimal = TRUE;
}
else if (TextToConvert.rfind('n', 0) == 0 ||
TextToConvert.rfind('N', 0) == 0)
{
TextToConvert = TextToConvert.erase(0, 1);
IsDecimal = TRUE;
}
TextToConvert.erase(remove(TextToConvert.begin(), TextToConvert.end(), '`'),
TextToConvert.end());
int Base = IsDecimal ? 10 : 16;
if (IsDecimal)
{
if (!IsDecimalNotation(TextToConvert))
{
return FALSE;
}
}
else
{
if (!IsHexNotation(TextToConvert))
{
return FALSE;
}
}
try
{
size_t Pos = 0;
unsigned long UL = std::stoul(TextToConvert, &Pos, Base); // use stoul (unsigned long) for 16-bit values
//
// check for 16-bit overflow (0 - 65,535)
//
if (Pos != TextToConvert.size() || UL > (std::numeric_limits<UINT16>::max)())
{
return FALSE;
}
*Result = static_cast<UINT16>(UL);
return TRUE;
}
catch (std::invalid_argument const &)
{
//
// Bad input: std::invalid_argument thrown
//
return FALSE;
}
catch (std::out_of_range const &)
{
//
// Integer overflow: std::out_of_range thrown
//
return FALSE;
}
}
/**
* @brief check and convert command token to a 64 bit unsigned integer
*
@ -554,6 +643,28 @@ ConvertTokenToUInt32(CommandToken TargetToken, PUINT32 Result)
return ConvertStringToUInt32(TargetTokenValue, Result);
}
/**
* @brief check and convert command token to a 16 bit unsigned integer
*
* @param TargetToken the target command token
* @param Result result will be save to the pointer
*
* @return BOOLEAN shows whether the conversion was successful or not
*/
BOOLEAN
ConvertTokenToUInt16(CommandToken TargetToken, PUINT16 Result)
{
//
// Extract the token type and value from the tuple
//
std::string TargetTokenValue = std::get<1>(TargetToken);
//
// Convert the token value to 32 bit unsigned integer
//
return ConvertStringToUInt16(TargetTokenValue, Result);
}
/**
* @brief checks whether the string ends with a special string or not
*

View file

@ -43,6 +43,10 @@ CommandUserCpuidHelp()
/**
* @brief ucpuid command show messages
*
* @param FunctionId
* @param SubFunctionId
* @param CpuidRequest
*
* @return VOID
*/
VOID
@ -2065,9 +2069,12 @@ CommandShowUserCpuidMessage(UINT32 FunctionId,
/**
* @brief ucpuid command handler
*
* @return VOID
* @param FunctionId
* @param SubFunctionId
*
* @return BOOLEAN
*/
VOID
BOOLEAN
CommandCpuidRequestCpuid(UINT32 FunctionId, UINT32 SubFunctionId)
{
BOOL Status;
@ -2082,15 +2089,14 @@ CommandCpuidRequestCpuid(UINT32 FunctionId, UINT32 SubFunctionId)
//
// It's on a debugger mode
//
KdSendUserCpuidPacketToDebuggee(FunctionId, SubFunctionId);
return;
return KdSendUserCpuidPacketToDebuggee(FunctionId, SubFunctionId);
}
else
{
//
// It's on a local debugging mode
//
AssertShowMessageReturnStmt(g_IsKdModuleLoaded, g_DeviceHandle, ASSERT_MESSAGE_KD_NOT_LOADED, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturn);
AssertShowMessageReturnStmt(g_IsKdModuleLoaded, g_DeviceHandle, ASSERT_MESSAGE_KD_NOT_LOADED, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
//
// By the way, we don't need to send an input buffer
@ -2113,17 +2119,19 @@ CommandCpuidRequestCpuid(UINT32 FunctionId, UINT32 SubFunctionId)
if (!Status)
{
ShowMessages("ioctl failed with code 0x%x\n", PlatformGetLastError());
return;
return FALSE;
}
if (CpuidRequest->KernelStatus == DEBUGGER_OPERATION_WAS_SUCCESSFUL)
{
CommandShowUserCpuidMessage(FunctionId, SubFunctionId, CpuidRequest);
return TRUE;
}
else
{
ShowMessages("Receiving CPUID result was not successful :(\n");
ShowMessages("Receiving CPUID result was not successful\n");
return FALSE;
}
}
}

View file

@ -0,0 +1,251 @@
/**
* @file uin.cpp
* @author Nikzad (Hossein Shirdel)
* @brief uin command - read from i/o port address (user specified)
* @details
* @version 0.24
* @date 2026-08-01
*
* @copyright This project is released under the GNU Public License v3.
*
*/
#include "pch.h"
//
// Global Variables
//
extern BOOLEAN g_IsKdModuleLoaded;
extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
/**
* @brief help of the uin command
*
* @return VOID
*/
VOID
CommandUserInHelp()
{
ShowMessages(
"uin : Read from I/O port (User IN)\n\n"
"Syntax : uin <register> <port>\n\n"
"Parameters :\n"
" register : Destination register: AL, AX, or EAX (case-insensitive)\n"
" port : I/O port address (hex or decimal, 0x0000 - 0xFFFF)\n\n"
"Examples :\n"
" uin al 0x60 Read a byte from keyboard port\n"
" uin Ax 0x3F8 Read a word from COM1\n"
" uin EAX 0xCF8 Read 32-bit from PCI config address\n");
}
/**
* @brief uin command show messages
*
* @param UserChosenRegister
* @param PortAddress
* @param Data
*
* @return VOID
*/
VOID
CommandShowUserInMessage(USHORT UserChosenRegister,
USHORT PortAddress,
ULONG Data)
{
const char * RegisterName = "";
switch (UserChosenRegister)
{
case AL_8_BIT_REGISTER:
RegisterName = "AL";
break;
case AX_16_BIT_REGISTER:
RegisterName = "AX";
break;
case EAX_32_BIT_REGISTER:
RegisterName = "EAX";
break;
}
ShowMessages(" Port: 0x%04X (%d)\n", PortAddress, PortAddress);
ShowMessages(" Register: %s\n", RegisterName);
ShowMessages(" Result: 0x%08X\n", Data);
}
/**
* @brief uin command handler
*
* @param InRequest
*
* @return BOOLEAN
*/
BOOLEAN
CommandUserInRequest(DEBUGGER_USER_IN_REQUEST_RESPONSE InRequest)
{
BOOL Status;
ULONG ReturnedLength;
USHORT UserChosenRegister = InRequest.UserChosenRegister;
USHORT PortAddress = InRequest.PortAddress;
if (g_IsSerialConnectedToRemoteDebuggee)
{
//
// It's on a debugger mode
//
return KdSendUserInPacketToDebuggee(InRequest);
}
else
{
//
// It's on a local debugging mode
//
AssertShowMessageReturnStmt(g_IsKdModuleLoaded, g_DeviceHandle, ASSERT_MESSAGE_KD_NOT_LOADED, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
//
// By the way, we don't need to send an input buffer
// to the kernel, but let's keep it like this, if we
// want to pass some other arguments to the kernel in
// the future
//
Status = PlatformDeviceIoControl(
g_DeviceHandle, // Handle to device
IOCTL_DEBUGGER_USER_IN, // IO Control Code (IOCTL)
&InRequest, // Input Buffer to driver.
SIZEOF_DEBUGGER_USER_IN_REQUEST_RESPONSE, // Input buffer length
&InRequest, // Output Buffer from driver.
SIZEOF_DEBUGGER_USER_IN_REQUEST_RESPONSE, // Length of output buffer in
// bytes.
&ReturnedLength, // Bytes placed in buffer.
NULL // synchronous call
);
if (!Status)
{
ShowMessages("ioctl failed with code 0x%x\n", PlatformGetLastError());
return FALSE;
}
if (InRequest.KernelStatus == DEBUGGER_OPERATION_WAS_SUCCESSFUL)
{
//
// The Data field is initialized to 0 before the ioctl call.
// After the ioctl call, the Data field is populated, so we shouldn't define Data variable
// before ioctl. Therefore, Data field must be defined after ioctl in order to be passed to
// CommandShowUserInMessage function, because IOCTL will populate Data field.
//
ULONG Data = InRequest.Data;
CommandShowUserInMessage(UserChosenRegister, PortAddress, Data);
return TRUE;
}
else
{
ShowMessages("Receiving IN instruction result was not successful\n");
return FALSE;
}
}
}
/**
* @brief uin command handler
*
* @param CommandTokens
* @param Command
*
* @return VOID
*/
VOID
CommandUserIn(vector<CommandToken> CommandTokens, string Command)
{
DEBUGGER_USER_IN_REQUEST_RESPONSE InRequest = {};
USHORT Port = 0;
BOOL SetRegister = FALSE;
BOOL SetPort = FALSE;
BOOLEAN IsFirstCommand = TRUE;
if (CommandTokens.size() != 3)
{
ShowMessages("incorrect use of the '%s'\n\n",
GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
CommandUserInHelp();
return;
}
for (auto Section : CommandTokens)
{
if (IsFirstCommand == TRUE)
{
IsFirstCommand = FALSE;
continue;
}
//
// Parse Register (first parameter)
//
if (!SetRegister)
{
string RegisterStr = GetCaseSensitiveStringFromCommandToken(Section);
//
// convert to lowercase for case-insensitive comparison
//
transform(RegisterStr.begin(), RegisterStr.end(), RegisterStr.begin(), ::tolower);
//
// convert register string to enum
//
if (RegisterStr == "al")
{
InRequest.UserChosenRegister = AL_8_BIT_REGISTER;
}
else if (RegisterStr == "ax")
{
InRequest.UserChosenRegister = AX_16_BIT_REGISTER;
}
else if (RegisterStr == "eax")
{
InRequest.UserChosenRegister = EAX_32_BIT_REGISTER;
}
else
{
ShowMessages("invalid cpu register, please use `al`, `ax`, or `eax` (case-insensitive)\n\n");
}
SetRegister = TRUE;
continue;
}
if (!SetPort)
{
//
// Parse Port Address (second parameter)
//
if (!ConvertTokenToUInt16(Section, &Port))
{
ShowMessages("please specify a correct hex/dec value for port address\n\n");
CommandUserInHelp();
return;
}
InRequest.PortAddress = Port;
SetPort = TRUE;
continue;
}
}
//
// Check if register and port address was provided
//
if (!SetRegister || !SetPort)
{
ShowMessages("missing required parameters\n");
ShowMessages("Usage: uin <register> <port>\n\n");
CommandUserInHelp();
return;
}
//
// use IN instruction
//
CommandUserInRequest(InRequest);
}

View file

@ -0,0 +1,268 @@
/**
* @file uout.cpp
* @author Nikzad (Hossein Shirdel)
* @brief uout command - write from cpu register to i/o port address (user specified)
* @details
* @version 0.24
* @date 2026-08-01
*
* @copyright This project is released under the GNU Public License v3.
*
*/
#include "pch.h"
//
// Global Variables
//
extern BOOLEAN g_IsKdModuleLoaded;
extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
/**
* @brief help of the uout command
*
* @return VOID
*/
VOID
CommandUserOutHelp()
{
ShowMessages(
"uout : Write to I/O port (User OUT)\n\n"
"Syntax : uout <register> <port> <value>\n\n"
"Parameters :\n"
" register : Source register: AL, AX, or EAX (case-insensitive)\n"
" port : I/O port address (hex or decimal, 0x0000 - 0xFFFF)\n"
" value : Value to write (hex or decimal)\n\n"
"Examples :\n"
" uout al 0x60 0xED Write to keyboard controller\n"
" uout AX 0x3F8 0x004D Write word to COM1\n"
" uout Eax 0xCF8 0x80000000 Write 32-bit to PCI config address\n");
}
/**
* @brief uout command show messages
*
* @param UserChosenRegister
* @param PortAddress
* @param Value
*
* @return VOID
*/
VOID
CommandShowUserOutMessage(USHORT UserChosenRegister,
USHORT PortAddress,
UINT32 Value)
{
const char * RegisterName = "";
switch (UserChosenRegister)
{
case AL_8_BIT_REGISTER:
RegisterName = "AL";
break;
case AX_16_BIT_REGISTER:
RegisterName = "AX";
break;
case EAX_32_BIT_REGISTER:
RegisterName = "EAX";
break;
}
ShowMessages(" Port: 0x%04X (%d)\n", PortAddress, PortAddress);
ShowMessages(" Register: %s\n", RegisterName);
ShowMessages(" Entered Value: 0x%08X\n", Value);
}
/**
* @brief uout command handler
*
* @param OutRequest
*
* @return BOOLEAN
*/
BOOLEAN
CommandUserOutRequest(DEBUGGER_USER_OUT_REQUEST_RESPONSE OutRequest)
{
BOOL Status;
ULONG ReturnedLength;
USHORT UserChosenRegister = OutRequest.UserChosenRegister;
USHORT PortAddress = OutRequest.PortAddress;
UINT32 Value = OutRequest.Value;
if (g_IsSerialConnectedToRemoteDebuggee)
{
//
// It's on a debugger mode
//
return KdSendUserOutPacketToDebuggee(OutRequest);
}
else
{
//
// It's on a local debugging mode
//
AssertShowMessageReturnStmt(g_IsKdModuleLoaded, g_DeviceHandle, ASSERT_MESSAGE_KD_NOT_LOADED, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
//
// By the way, we don't need to send an input buffer
// to the kernel, but let's keep it like this, if we
// want to pass some other arguments to the kernel in
// the future
//
Status = PlatformDeviceIoControl(
g_DeviceHandle, // Handle to device
IOCTL_DEBUGGER_USER_OUT, // IO Control Code (IOCTL)
&OutRequest, // Input Buffer to driver.
SIZEOF_DEBUGGER_USER_OUT_REQUEST_RESPONSE, // Input buffer length
&OutRequest, // Output Buffer from driver.
SIZEOF_DEBUGGER_USER_OUT_REQUEST_RESPONSE, // Length of output buffer in
// bytes.
&ReturnedLength, // Bytes placed in buffer.
NULL // synchronous call
);
if (!Status)
{
ShowMessages("ioctl failed with code 0x%x\n", PlatformGetLastError());
return FALSE;
}
if (OutRequest.KernelStatus == DEBUGGER_OPERATION_WAS_SUCCESSFUL)
{
CommandShowUserOutMessage(UserChosenRegister, PortAddress, Value);
return TRUE;
}
else
{
ShowMessages("Receiving OUT instruction result was not successful\n");
return FALSE;
}
}
}
/**
* @brief uout command handler
*
* @param CommandTokens
* @param Command
*
* @return VOID
*/
VOID
CommandUserOut(vector<CommandToken> CommandTokens, string Command)
{
DEBUGGER_USER_OUT_REQUEST_RESPONSE OutRequest = {};
USHORT Port = 0;
UINT32 Value = 0;
BOOL SetRegister = FALSE;
BOOL SetPort = FALSE;
BOOL SetValue = FALSE;
BOOLEAN IsFirstCommand = TRUE;
if (CommandTokens.size() != 4)
{
ShowMessages("incorrect use of the '%s'\n\n",
GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
CommandUserOutHelp();
return;
}
for (auto Section : CommandTokens)
{
if (IsFirstCommand == TRUE)
{
IsFirstCommand = FALSE;
continue;
}
//
// Parse Register (first parameter)
//
if (!SetRegister)
{
string RegisterStr = GetCaseSensitiveStringFromCommandToken(Section);
//
// convert to lowercase for case-insensitive comparison
//
transform(RegisterStr.begin(), RegisterStr.end(), RegisterStr.begin(), ::tolower);
//
// convert register string to enum
//
if (RegisterStr == "al")
{
OutRequest.UserChosenRegister = AL_8_BIT_REGISTER;
}
else if (RegisterStr == "ax")
{
OutRequest.UserChosenRegister = AX_16_BIT_REGISTER;
}
else if (RegisterStr == "eax")
{
OutRequest.UserChosenRegister = EAX_32_BIT_REGISTER;
}
else
{
ShowMessages("invalid cpu register, please use `al`, `ax`, or `eax` (case-insensitive)\n\n");
}
SetRegister = TRUE;
continue;
}
//
// Parse Port Address (second parameter)
//
if (!SetPort)
{
if (!ConvertTokenToUInt16(Section, &Port))
{
ShowMessages("please specify a correct hex/dec value for port address\n\n");
CommandUserOutHelp();
return;
}
OutRequest.PortAddress = Port;
SetPort = TRUE;
continue;
}
//
// Parse Value (third parameter)
//
if (!SetValue)
{
if (!ConvertTokenToUInt32(Section, &Value))
{
ShowMessages("please specify a correct hex/dec value for Value\n\n");
CommandUserOutHelp();
return;
}
OutRequest.Value = Value;
SetValue = TRUE;
continue;
}
}
//
// Check if register, port address, and value was provided
//
if (!SetRegister || !SetPort || !SetValue)
{
ShowMessages("missing required parameters\n");
ShowMessages("Usage: uout <register> <port> <value>\n\n");
CommandUserOutHelp();
return;
}
//
// use OUT instruction
//
CommandUserOutRequest(OutRequest);
}

View file

@ -1423,6 +1423,9 @@ InitializeCommandsDictionary()
g_CommandsList["ucpuid"] = {&CommandUserCpuid, &CommandUserCpuidHelp, DEBUGGER_COMMAND_USER_CPUID_ATTRIBUTES};
g_CommandsList["cpuid"] = {&CommandUserCpuid, &CommandUserCpuidHelp, DEBUGGER_COMMAND_USER_CPUID_ATTRIBUTES};
g_CommandsList["uin"] = {&CommandUserIn, &CommandUserInHelp, DEBUGGER_COMMAND_USER_IN_ATTRIBUTES};
g_CommandsList["uout"] = {&CommandUserOut, &CommandUserOutHelp, DEBUGGER_COMMAND_USER_OUT_ATTRIBUTES};
g_CommandsList["pause"] = {&CommandPause, &CommandPauseHelp, DEBUGGER_COMMAND_PAUSE_ATTRIBUTES};
g_CommandsList[".pause"] = {&CommandPause, &CommandPauseHelp, DEBUGGER_COMMAND_PAUSE_ATTRIBUTES};

View file

@ -339,6 +339,9 @@ KdSendFlushPacketToDebuggee()
/**
* @brief Send a CPUID request to the debuggee
*
* @param FunctionId
* @param SubFunctionId
*
* @return BOOLEAN
*/
BOOLEAN
@ -368,6 +371,66 @@ KdSendUserCpuidPacketToDebuggee(UINT32 FunctionId, UINT32 SubFunctionId)
return TRUE;
}
/**
* @brief Send IN instruction to the debuggee
*
* @param InRequest
*
* @return BOOLEAN
*/
BOOLEAN
KdSendUserInPacketToDebuggee(DEBUGGER_USER_IN_REQUEST_RESPONSE InRequest)
{
//
// Send 'uin' command as packet
//
if (!KdCommandPacketAndBufferToDebuggee(
DEBUGGER_REMOTE_PACKET_TYPE_DEBUGGER_TO_DEBUGGEE_EXECUTE_ON_VMX_ROOT,
DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_MODE_USER_IN_INSTRUCTION,
(CHAR *)&InRequest,
sizeof(DEBUGGER_USER_IN_REQUEST_RESPONSE)))
{
return FALSE;
}
//
// Wait until the result of IN instruction received
//
DbgWaitForKernelResponse(DEBUGGER_SYNCRONIZATION_OBJECT_KERNEL_DEBUGGER_USER_IN_RESULT);
return TRUE;
}
/**
* @brief Send OUT instruction to the debuggee
*
* @param OutRequest
*
* @return BOOLEAN
*/
BOOLEAN
KdSendUserOutPacketToDebuggee(DEBUGGER_USER_OUT_REQUEST_RESPONSE OutRequest)
{
//
// Send 'uout' command as packet
//
if (!KdCommandPacketAndBufferToDebuggee(
DEBUGGER_REMOTE_PACKET_TYPE_DEBUGGER_TO_DEBUGGEE_EXECUTE_ON_VMX_ROOT,
DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_MODE_USER_OUT_INSTRUCTION,
(CHAR *)&OutRequest,
sizeof(DEBUGGER_USER_OUT_REQUEST_RESPONSE)))
{
return FALSE;
}
//
// Wait until the result of OUT instruction received
//
DbgWaitForKernelResponse(DEBUGGER_SYNCRONIZATION_OBJECT_KERNEL_DEBUGGER_USER_OUT_RESULT);
return TRUE;
}
/**
* @brief Send a callstack request to the debuggee
* @param BaseAddress

View file

@ -58,6 +58,8 @@ ListeningSerialPortInDebugger()
PDEBUGGEE_DETAILS_AND_SWITCH_THREAD_PACKET ChangeThreadPacket;
PDEBUGGER_FLUSH_LOGGING_BUFFERS FlushPacket;
PDEBUGGER_CPUID_REQUEST_RESPONSE CpuidPacket;
PDEBUGGER_USER_IN_REQUEST_RESPONSE InPacket;
PDEBUGGER_USER_OUT_REQUEST_RESPONSE OutPacket;
PDEBUGGER_CALLSTACK_REQUEST CallstackPacket;
PDEBUGGER_SINGLE_CALLSTACK_FRAME CallstackFramePacket;
PDEBUGGER_DEBUGGER_TEST_QUERY_BUFFER TestQueryPacket;
@ -602,6 +604,54 @@ StartAgain:
break;
case DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_OF_USER_IN_INSTRUCTION:
InPacket = (DEBUGGER_USER_IN_REQUEST_RESPONSE *)(((CHAR *)TheActualPacket) + sizeof(DEBUGGER_REMOTE_PACKET));
if (InPacket->KernelStatus == DEBUGGER_OPERATION_WAS_SUCCESSFUL)
{
USHORT UserChosenRegister = InPacket->UserChosenRegister;
USHORT PortAddress = InPacket->PortAddress;
ULONG Data = InPacket->Data;
CommandShowUserInMessage(UserChosenRegister, PortAddress, Data);
}
else
{
ShowErrorMessage(InPacket->KernelStatus);
}
//
// Signal the event relating to receiving result of IN instruction
//
DbgReceivedKernelResponse(DEBUGGER_SYNCRONIZATION_OBJECT_KERNEL_DEBUGGER_USER_IN_RESULT);
break;
case DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_OF_USER_OUT_INSTRUCTION:
OutPacket = (DEBUGGER_USER_OUT_REQUEST_RESPONSE *)(((CHAR *)TheActualPacket) + sizeof(DEBUGGER_REMOTE_PACKET));
if (OutPacket->KernelStatus == DEBUGGER_OPERATION_WAS_SUCCESSFUL)
{
USHORT UserChosenRegister = OutPacket->UserChosenRegister;
USHORT PortAddress = OutPacket->PortAddress;
UINT32 Value = OutPacket->Value;
CommandShowUserOutMessage(UserChosenRegister, PortAddress, Value);
}
else
{
ShowErrorMessage(OutPacket->KernelStatus);
}
//
// Signal the event relating to receiving result of OUT instruction
//
DbgReceivedKernelResponse(DEBUGGER_SYNCRONIZATION_OBJECT_KERNEL_DEBUGGER_USER_OUT_RESULT);
break;
case DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_OF_CALLSTACK:
CallstackPacket = (DEBUGGER_CALLSTACK_REQUEST *)(((CHAR *)TheActualPacket) + sizeof(DEBUGGER_REMOTE_PACKET));

View file

@ -1044,4 +1044,30 @@ hyperdbg_u_request_cpuid(UINT32 FunctionId, UINT32 SubFunctionId)
CommandCpuidRequestCpuid(FunctionId, SubFunctionId);
return TRUE;
}
}
/**
* @brief I/O instruction (IN)
*
* @param InRequest
*
* @return BOOLEAN TRUE if successful, FALSE otherwise
*/
BOOLEAN
hyperdebg_u_in_instruction(DEBUGGER_USER_IN_REQUEST_RESPONSE InRequest)
{
return CommandUserInRequest(InRequest);
}
/**
* @brief I/O instruction (OUT)
*
* @param OutRequest
*
* @return BOOLEAN TRUE if successful, FALSE otherwise
*/
BOOLEAN
hyperdebg_u_out_instruction(DEBUGGER_USER_OUT_REQUEST_RESPONSE OutRequest)
{
return CommandUserOutRequest(OutRequest);
}

View file

@ -247,12 +247,18 @@ ConvertStringToUInt64(string TextToConvert, PUINT64 Result);
BOOLEAN
ConvertStringToUInt32(string TextToConvert, PUINT32 Result);
BOOLEAN
ConvertStringToUInt16(string TextToConvert, PUINT16 Result);
BOOLEAN
ConvertTokenToUInt64(CommandToken TargetToken, PUINT64 Result);
BOOLEAN
ConvertTokenToUInt32(CommandToken TargetToken, PUINT32 Result);
BOOLEAN
ConvertTokenToUInt16(CommandToken TargetToken, PUINT16 Result);
std::string
GetCaseSensitiveStringFromCommandToken(CommandToken TargetToken);

View file

@ -304,6 +304,12 @@ typedef std::map<std::string, COMMAND_DETAIL> CommandType;
#define DEBUGGER_COMMAND_USER_CPUID_ATTRIBUTES \
DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_COMMAND_IN_DEBUGGER_MODE
#define DEBUGGER_COMMAND_USER_IN_ATTRIBUTES \
DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_COMMAND_IN_DEBUGGER_MODE
#define DEBUGGER_COMMAND_USER_OUT_ATTRIBUTES \
DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_COMMAND_IN_DEBUGGER_MODE
#define DEBUGGER_COMMAND_UNLOAD_ATTRIBUTES NULL
#define DEBUGGER_COMMAND_SCRIPT_ATTRIBUTES \
@ -650,6 +656,12 @@ CommandFlush(vector<CommandToken> CommandTokens, string Command);
VOID
CommandUserCpuid(vector<CommandToken> CommandTokens, string Command);
VOID
CommandUserIn(vector<CommandToken> CommandTokens, string Command);
VOID
CommandUserOut(vector<CommandToken> CommandTokens, string Command);
VOID
CommandPause(vector<CommandToken> CommandTokens, string Command);

View file

@ -174,6 +174,12 @@ CommandFlushHelp();
VOID
CommandUserCpuidHelp();
VOID
CommandUserInHelp();
VOID
CommandUserOutHelp();
VOID
CommandPauseHelp();

View file

@ -65,6 +65,8 @@
#define DEBUGGER_SYNCRONIZATION_OBJECT_KERNEL_DEBUGGER_HYPERTRACE_LBR_DUMP_RESULT 0x20
#define DEBUGGER_SYNCRONIZATION_OBJECT_KERNEL_DEBUGGER_HYPERTRACE_PT_OPERATION_RESULT 0x21
#define DEBUGGER_SYNCRONIZATION_OBJECT_KERNEL_DEBUGGER_USER_CPUID_RESULT 0x22
#define DEBUGGER_SYNCRONIZATION_OBJECT_KERNEL_DEBUGGER_USER_IN_RESULT 0x23
#define DEBUGGER_SYNCRONIZATION_OBJECT_KERNEL_DEBUGGER_USER_OUT_RESULT 0x24
//////////////////////////////////////////////////
// Event Details //
@ -221,7 +223,7 @@ CommandEventsClearAllEventsAndResetTags();
VOID
CommandFlushRequestFlush();
VOID
BOOLEAN
CommandCpuidRequestCpuid(UINT32 FunctionId, UINT32 SubFunctionId);
VOID
@ -229,6 +231,22 @@ CommandShowUserCpuidMessage(UINT32 FunctionId,
UINT32 SubFunctionId,
PDEBUGGER_CPUID_REQUEST_RESPONSE CpuidRequest);
BOOLEAN
CommandUserInRequest(DEBUGGER_USER_IN_REQUEST_RESPONSE InRequest);
BOOLEAN
CommandUserOutRequest(DEBUGGER_USER_OUT_REQUEST_RESPONSE OutRequest);
VOID
CommandShowUserInMessage(USHORT UserChosenRegister,
USHORT PortAddress,
ULONG Data);
VOID
CommandShowUserOutMessage(USHORT UserChosenRegister,
USHORT PortAddress,
UINT32 Value);
UINT64
GetCommandAttributes(const string & FirstCommand);

View file

@ -116,6 +116,12 @@ KdSendFlushPacketToDebuggee();
BOOLEAN
KdSendUserCpuidPacketToDebuggee(UINT32 FunctionId, UINT32 SubFunctionId);
BOOLEAN
KdSendUserInPacketToDebuggee(DEBUGGER_USER_IN_REQUEST_RESPONSE InRequest);
BOOLEAN
KdSendUserOutPacketToDebuggee(DEBUGGER_USER_OUT_REQUEST_RESPONSE OutRequest);
BOOLEAN
KdSendCallStackPacketToDebuggee(UINT64 BaseAddress,
UINT32 Size,

View file

@ -199,6 +199,9 @@ msbuild "$(SolutionDir)dependencies\zydis\msvc\Zydis.sln" /m /p:Configuration="R
<ClCompile Include="code\debugger\commands\debugging-commands\k.cpp" />
<ClCompile Include="code\debugger\commands\debugging-commands\preactivate.cpp" />
<ClCompile Include="code\debugger\commands\debugging-commands\prealloc.cpp" />
<ClCompile Include="code\debugger\commands\debugging-commands\ucpuid.cpp" />
<ClCompile Include="code\debugger\commands\debugging-commands\uin.cpp" />
<ClCompile Include="code\debugger\commands\debugging-commands\uout.cpp" />
<ClCompile Include="code\debugger\commands\extension-commands\apic.cpp" />
<ClCompile Include="code\debugger\commands\extension-commands\crwrite.cpp" />
<ClCompile Include="code\debugger\commands\extension-commands\idt.cpp" />
@ -247,7 +250,6 @@ msbuild "$(SolutionDir)dependencies\zydis\msvc\Zydis.sln" /m /p:Configuration="R
<ClCompile Include="code\hwdbg\hwdbg-scripts.cpp" />
<ClCompile Include="code\objects\objects.cpp" />
<ClCompile Include="code\rev\rev-ctrl.cpp" />
<ClCompile Include="ucpuid.cpp" />
<ClCompile Include="pch.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='debug|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='release|x64'">Create</PrecompiledHeader>

View file

@ -742,7 +742,13 @@
<ClCompile Include="code\debugger\misc\pt-helper.cpp">
<Filter>code\debugger\misc</Filter>
</ClCompile>
<ClCompile Include="ucpuid.cpp">
<ClCompile Include="code\debugger\commands\debugging-commands\ucpuid.cpp">
<Filter>code\debugger\commands\debugging-commands</Filter>
</ClCompile>
<ClCompile Include="code\debugger\commands\debugging-commands\uin.cpp">
<Filter>code\debugger\commands\debugging-commands</Filter>
</ClCompile>
<ClCompile Include="code\debugger\commands\debugging-commands\uout.cpp">
<Filter>code\debugger\commands\debugging-commands</Filter>
</ClCompile>
</ItemGroup>