HyperDbg Debugger
Loading...
Searching...
No Matches
IoHandler.h File Reference

The I/O Handler for vm-exit headers. More...

Go to the source code of this file.

Typedefs

typedef enum _IO_ACCESS_INSTR IO_ACCESS_INSTR
 IN Instruction or OUT Instruction.
typedef enum _IO_OP_ENCODING IO_OP_ENCODING
 Immediate value or in DX.

Enumerations

enum  _IO_ACCESS_INSTR { AccessOut = 0 , AccessIn = 1 }
 IN Instruction or OUT Instruction. More...
enum  _IO_OP_ENCODING { OpEncodingDx = 0 , OpEncodingImm = 1 }
 Immediate value or in DX. More...

Functions

UINT8 IoInByte (UINT16 port)
UINT16 IoInWord (UINT16 port)
UINT32 IoInDword (UINT16 port)
VOID IoInByteString (UINT16 port, UINT8 *data, UINT32 size)
VOID IoInWordString (UINT16 port, UINT16 *data, UINT32 size)
VOID IoInDwordString (UINT16 port, UINT32 *data, UINT32 size)
VOID IoOutByte (UINT16 port, UINT8 value)
VOID IoOutWord (UINT16 port, UINT16 value)
VOID IoOutDword (UINT16 port, UINT32 value)
VOID IoOutByteString (UINT16 port, UINT8 *data, UINT32 count)
VOID IoOutWordString (UINT16 port, UINT16 *data, UINT32 count)
VOID IoOutDwordString (UINT16 port, UINT32 *data, UINT32 count)
VOID IoHandleIoVmExits (VIRTUAL_MACHINE_STATE *VCpu, VMX_EXIT_QUALIFICATION_IO_INSTRUCTION IoQualification, RFLAGS Flags)
 VM-Exit handler for I/O Instructions (in/out).
VOID IoHandlePerformIoBitmapChange (VIRTUAL_MACHINE_STATE *VCpu, UINT32 Port)
 Change I/O Bitmap.
VOID IoHandlePerformIoBitmapReset (VIRTUAL_MACHINE_STATE *VCpu)
 Reset I/O Bitmap.

Detailed Description

The I/O Handler for vm-exit headers.

Author
Sina Karvandi (sina@.nosp@m.hype.nosp@m.rdbg..nosp@m.org)
Version
0.1
Date
2020-06-06

Typedef Documentation

◆ IO_ACCESS_INSTR

IN Instruction or OUT Instruction.

◆ IO_OP_ENCODING

Immediate value or in DX.

Enumeration Type Documentation

◆ _IO_ACCESS_INSTR

IN Instruction or OUT Instruction.

Enumerator
AccessOut 
AccessIn 
23{
24 AccessOut = 0,
25 AccessIn = 1,
@ AccessOut
Definition IoHandler.h:24
@ AccessIn
Definition IoHandler.h:25
enum _IO_ACCESS_INSTR IO_ACCESS_INSTR
IN Instruction or OUT Instruction.

◆ _IO_OP_ENCODING

Immediate value or in DX.

Enumerator
OpEncodingDx 
OpEncodingImm 
33{
34 OpEncodingDx = 0,
35 OpEncodingImm = 1,
enum _IO_OP_ENCODING IO_OP_ENCODING
Immediate value or in DX.
@ OpEncodingImm
Definition IoHandler.h:35
@ OpEncodingDx
Definition IoHandler.h:34

Function Documentation

◆ IoHandleIoVmExits()

VOID IoHandleIoVmExits ( VIRTUAL_MACHINE_STATE * VCpu,
VMX_EXIT_QUALIFICATION_IO_INSTRUCTION IoQualification,
RFLAGS Flags )

VM-Exit handler for I/O Instructions (in/out).

Parameters
VCpuThe virtual processor's state
IoQualificationThe I/O Qualification that indicates the instruction
FlagsGuest's RFLAGs
Returns
VOID
25{
26 UINT16 Port = 0;
27 UINT32 Count = 0;
28 UINT32 Size = 0;
29 PGUEST_REGS GuestRegs = VCpu->Regs;
30
31 //
32 // VMWare tools uses port (port 0x5658/0x5659) as I/O backdoor
33 // This function will not handle these cases so if you put bitmap
34 // to cause vm-exit on port 0x5658/0x5659 then VMWare tools will
35 // crash
36 //
37
38 union
39 {
40 UCHAR * AsBytePtr;
41 USHORT * AsWordPtr;
42 ULONG * AsDwordPtr;
43
44 PVOID AsPtr;
45 UINT64 AsUInt64;
46
47 } PortValue;
48
49 //
50 // The I/O Implementation is derived from Petr Benes's hvpp
51 // Take a look at :
52 // https://github.com/wbenny/hvpp/blob/f1eece7d0def506f329b5770befd892497be2047/src/hvpp/hvpp/vmexit/vmexit_passthrough.cpp
53 //
54
55 //
56 // We don't check if CPL == 0 here, because the CPU would
57 // raise #GP instead of VM-exit.
58 //
59 // See Vol3C[25.1.1(Relative Priority of Faults and VM Exits)]
60 //
61
62 //
63 // Resolve address of the source or destination.
64 //
65 if (IoQualification.StringInstruction)
66 {
67 //
68 // String operations always operate either on RDI (in) or
69 // RSI (out) registers.
70 //
71 PortValue.AsPtr = (PVOID)(IoQualification.DirectionOfAccess == AccessIn ? GuestRegs->rdi : GuestRegs->rsi);
72 }
73 else
74 {
75 //
76 // Save pointer to the RAX register.
77 //
78 PortValue.AsPtr = &GuestRegs->rax;
79 }
80
81 //
82 // Resolve port as a nice 16-bit number.
83 //
84 Port = (UINT16)IoQualification.PortNumber;
85
86 //
87 // Resolve number of bytes to send/receive.
88 // REP prefixed instructions always take their count
89 // from *CX register.
90 //
91 Count = IoQualification.RepPrefixed ? (GuestRegs->rcx & 0xffffffff) : 1;
92
93 Size = (UINT32)(IoQualification.SizeOfAccess + 1);
94
95 switch (IoQualification.DirectionOfAccess)
96 {
97 case AccessIn:
98 if (IoQualification.StringInstruction)
99 {
100 switch (Size)
101 {
102 case 1:
103 IoInByteString(Port, (UINT8 *)PortValue.AsBytePtr, Count);
104 break;
105 case 2:
106 IoInWordString(Port, (UINT16 *)PortValue.AsWordPtr, Count);
107 break;
108 case 4:
109 IoInDwordString(Port, (UINT32 *)PortValue.AsDwordPtr, Count);
110 break;
111 }
112 }
113 else
114 {
115 //
116 // Note that port_value holds pointer to the
117 // vp.context().rax member, therefore we're
118 // directly overwriting the RAX value.
119 //
120 switch (Size)
121 {
122 case 1:
123 *PortValue.AsBytePtr = IoInByte(Port);
124 break;
125 case 2:
126 *PortValue.AsWordPtr = IoInWord(Port);
127 break;
128 case 4:
129 *PortValue.AsDwordPtr = IoInDword(Port);
130 break;
131 }
132 }
133 break;
134
135 case AccessOut:
136 if (IoQualification.StringInstruction)
137 {
138 switch (Size)
139 {
140 case 1:
141 IoOutByteString(Port, (UINT8 *)PortValue.AsBytePtr, Count);
142 break;
143 case 2:
144 IoOutWordString(Port, (UINT16 *)PortValue.AsWordPtr, Count);
145 break;
146 case 4:
147 IoOutDwordString(Port, (UINT32 *)PortValue.AsDwordPtr, Count);
148 break;
149 }
150 }
151 else
152 {
153 //
154 // Note that port_value holds pointer to the
155 // vp.context().rax member, therefore we're
156 // directly reading from the RAX value.
157 //
158 switch (Size)
159 {
160 case 1:
161 IoOutByte(Port, *PortValue.AsBytePtr);
162 break;
163 case 2:
164 IoOutWord(Port, *PortValue.AsWordPtr);
165 break;
166 case 4:
167 IoOutDword(Port, *PortValue.AsDwordPtr);
168 break;
169 }
170 }
171 break;
172 }
173
174 if (IoQualification.StringInstruction)
175 {
176 //
177 // Update register:
178 // If the DF (direction flag) is set, decrement,
179 // otherwise increment.
180 //
181 // For in the register is RDI, for out it's RSI.
182 //
183 UINT64 GpReg = IoQualification.DirectionOfAccess == AccessIn ? GuestRegs->rdi : GuestRegs->rsi;
184
185 if (Flags.DirectionFlag)
186 {
187 GpReg -= Count * Size;
188 }
189 else
190 {
191 GpReg += Count * Size;
192 }
193
194 //
195 // We've sent/received everything, reset counter register
196 // to 0.
197 //
198 if (IoQualification.RepPrefixed)
199 {
200 GuestRegs->rcx = 0;
201 }
202 }
203}
UINT32 IoInDword(UINT16 port)
Definition IoHandler.h:55
VOID IoOutByteString(UINT16 port, UINT8 *data, UINT32 count)
Definition IoHandler.h:97
VOID IoInByteString(UINT16 port, UINT8 *data, UINT32 size)
Definition IoHandler.h:61
VOID IoOutByte(UINT16 port, UINT8 value)
Definition IoHandler.h:79
VOID IoOutWordString(UINT16 port, UINT16 *data, UINT32 count)
Definition IoHandler.h:103
UINT16 IoInWord(UINT16 port)
Definition IoHandler.h:49
UINT8 IoInByte(UINT16 port)
Definition IoHandler.h:43
VOID IoOutDword(UINT16 port, UINT32 value)
Definition IoHandler.h:91
VOID IoInDwordString(UINT16 port, UINT32 *data, UINT32 size)
Definition IoHandler.h:73
VOID IoInWordString(UINT16 port, UINT16 *data, UINT32 size)
Definition IoHandler.h:67
VOID IoOutDwordString(UINT16 port, UINT32 *data, UINT32 count)
Definition IoHandler.h:109
VOID IoOutWord(UINT16 port, UINT16 value)
Definition IoHandler.h:85
unsigned short UINT16
Definition BasicTypes.h:53
void * PVOID
Definition BasicTypes.h:56
struct GUEST_REGS * PGUEST_REGS
unsigned char UCHAR
Definition BasicTypes.h:34
unsigned short USHORT
Definition BasicTypes.h:30
unsigned char UINT8
Definition BasicTypes.h:52
unsigned int UINT32
Definition BasicTypes.h:54
unsigned long ULONG
Definition BasicTypes.h:31
GUEST_REGS * Regs
Definition State.h:326
UINT64 rdi
Definition BasicTypes.h:148
UINT64 rax
Definition BasicTypes.h:141
UINT64 rcx
Definition BasicTypes.h:142
UINT64 rsi
Definition BasicTypes.h:147

◆ IoHandlePerformIoBitmapChange()

VOID IoHandlePerformIoBitmapChange ( VIRTUAL_MACHINE_STATE * VCpu,
UINT32 Port )

Change I/O Bitmap.

should be called in vmx-root mode

Parameters
VCpuThe virtual processor's state
IoPortPort
Returns
VOID
242{
243 if (Port == DEBUGGER_EVENT_ALL_IO_PORTS)
244 {
245 //
246 // Means all the bitmaps should be put to 1
247 //
248 memset((PVOID)VCpu->IoBitmapVirtualAddressA, 0xFF, PAGE_SIZE);
249 memset((PVOID)VCpu->IoBitmapVirtualAddressB, 0xFF, PAGE_SIZE);
250 }
251 else
252 {
253 //
254 // Means only one i/o bitmap is target
255 //
256 IoHandleSetIoBitmap(VCpu, Port);
257 }
258}
BOOLEAN IoHandleSetIoBitmap(VIRTUAL_MACHINE_STATE *VCpu, UINT32 Port)
Set bits in I/O Bitmap.
Definition IoHandler.c:214
#define DEBUGGER_EVENT_ALL_IO_PORTS
Apply to all I/O ports.
Definition Constants.h:769
#define PAGE_SIZE
Size of each page (4096 bytes).
Definition common.h:80
UINT64 IoBitmapVirtualAddressB
Definition State.h:341
UINT64 IoBitmapVirtualAddressA
Definition State.h:339

◆ IoHandlePerformIoBitmapReset()

VOID IoHandlePerformIoBitmapReset ( VIRTUAL_MACHINE_STATE * VCpu)

Reset I/O Bitmap.

should be called in vmx-root mode

Parameters
VCpuThe virtual processor's state
Returns
VOID
269{
270 //
271 // Means all the bitmaps should be put to 0
272 //
273 memset((PVOID)VCpu->IoBitmapVirtualAddressA, 0x0, PAGE_SIZE);
274 memset((PVOID)VCpu->IoBitmapVirtualAddressB, 0x0, PAGE_SIZE);
275}

◆ IoInByte()

UINT8 IoInByte ( UINT16 port)
inline
44{
45 return CpuIoInByte(port);
46}
UINT8 CpuIoInByte(UINT16 Port)
Read a byte from an I/O port.
Definition PlatformIntrinsics.c:573

◆ IoInByteString()

VOID IoInByteString ( UINT16 port,
UINT8 * data,
UINT32 size )
inline
62{
63 CpuIoInByteString(port, data, size);
64}
VOID CpuIoInByteString(UINT16 Port, UINT8 *Data, UINT32 Size)
Read a byte string from an I/O port.
Definition PlatformIntrinsics.c:634

◆ IoInDword()

UINT32 IoInDword ( UINT16 port)
inline
56{
57 return CpuIoInDword(port);
58}
UINT32 CpuIoInDword(UINT16 Port)
Read a dword from an I/O port.
Definition PlatformIntrinsics.c:613

◆ IoInDwordString()

VOID IoInDwordString ( UINT16 port,
UINT32 * data,
UINT32 size )
inline
74{
75 CpuIoInDwordString(port, data, size);
76}
VOID CpuIoInDwordString(UINT16 Port, UINT32 *Data, UINT32 Size)
Read a dword string from an I/O port.
Definition PlatformIntrinsics.c:672

◆ IoInWord()

UINT16 IoInWord ( UINT16 port)
inline
50{
51 return CpuIoInWord(port);
52}
UINT16 CpuIoInWord(UINT16 Port)
Read a word from an I/O port.
Definition PlatformIntrinsics.c:593

◆ IoInWordString()

VOID IoInWordString ( UINT16 port,
UINT16 * data,
UINT32 size )
inline
68{
69 CpuIoInWordString(port, data, size);
70}
VOID CpuIoInWordString(UINT16 Port, UINT16 *Data, UINT32 Size)
Read a word string from an I/O port.
Definition PlatformIntrinsics.c:653

◆ IoOutByte()

VOID IoOutByte ( UINT16 port,
UINT8 value )
inline
80{
81 CpuIoOutByte(port, value);
82}
VOID CpuIoOutByte(UINT16 Port, UINT8 Value)
Write a byte to an I/O port.
Definition PlatformIntrinsics.c:690

◆ IoOutByteString()

VOID IoOutByteString ( UINT16 port,
UINT8 * data,
UINT32 count )
inline
98{
99 CpuIoOutByteString(port, data, count);
100}
VOID CpuIoOutByteString(UINT16 Port, UINT8 *Data, UINT32 Count)
Write a byte string to an I/O port.
Definition PlatformIntrinsics.c:745

◆ IoOutDword()

VOID IoOutDword ( UINT16 port,
UINT32 value )
inline
92{
93 CpuIoOutDword(port, value);
94}
VOID CpuIoOutDword(UINT16 Port, UINT32 Value)
Write a dword to an I/O port.
Definition PlatformIntrinsics.c:726

◆ IoOutDwordString()

VOID IoOutDwordString ( UINT16 port,
UINT32 * data,
UINT32 count )
inline
110{
111 CpuIoOutDwordString(port, data, count);
112}
VOID CpuIoOutDwordString(UINT16 Port, UINT32 *Data, UINT32 Count)
Write a dword string to an I/O port.
Definition PlatformIntrinsics.c:783

◆ IoOutWord()

VOID IoOutWord ( UINT16 port,
UINT16 value )
inline
86{
87 CpuIoOutWord(port, value);
88}
VOID CpuIoOutWord(UINT16 Port, UINT16 Value)
Write a word to an I/O port.
Definition PlatformIntrinsics.c:708

◆ IoOutWordString()

VOID IoOutWordString ( UINT16 port,
UINT16 * data,
UINT32 count )
inline
104{
105 CpuIoOutWordString(port, data, count);
106}
VOID CpuIoOutWordString(UINT16 Port, UINT16 *Data, UINT32 Count)
Write a word string to an I/O port.
Definition PlatformIntrinsics.c:764