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

unsigned char __inbyte (unsigned short)
 
UINT8 IoInByte (UINT16 port)
 
unsigned short __inword (unsigned short)
 
UINT16 IoInWord (UINT16 port)
 
unsigned long __indword (unsigned short)
 
UINT32 IoInDword (UINT16 port)
 
void __inbytestring (unsigned short, unsigned char *, unsigned long)
 
void IoInByteString (UINT16 port, UINT8 *data, UINT32 size)
 
void __inwordstring (unsigned short, unsigned short *, unsigned long)
 
void IoInWordString (UINT16 port, UINT16 *data, UINT32 size)
 
void __indwordstring (unsigned short, unsigned long *, unsigned long)
 
void IoInDwordString (UINT16 port, UINT32 *data, UINT32 size)
 
void __outbyte (unsigned short, unsigned char)
 
void IoOutByte (UINT16 port, UINT8 value)
 
void __outword (unsigned short, unsigned short)
 
void IoOutWord (UINT16 port, UINT16 value)
 
void __outdword (unsigned short, unsigned long)
 
void IoOutDword (UINT16 port, UINT32 value)
 
void __outbytestring (unsigned short, unsigned char *, unsigned long)
 
void IoOutByteString (UINT16 port, UINT8 *data, UINT32 count)
 
void __outwordstring (unsigned short, unsigned short *, unsigned long)
 
void IoOutWordString (UINT16 port, UINT16 *data, UINT32 count)
 
void __outdwordstring (unsigned short, unsigned long *, unsigned long)
 
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

◆ __inbyte()

unsigned char __inbyte ( unsigned short )

◆ __inbytestring()

void __inbytestring ( unsigned short ,
unsigned char * ,
unsigned long  )

◆ __indword()

unsigned long __indword ( unsigned short )

◆ __indwordstring()

void __indwordstring ( unsigned short ,
unsigned long * ,
unsigned long  )

◆ __inword()

unsigned short __inword ( unsigned short )

◆ __inwordstring()

void __inwordstring ( unsigned short ,
unsigned short * ,
unsigned long  )

◆ __outbyte()

void __outbyte ( unsigned short ,
unsigned char  )

◆ __outbytestring()

void __outbytestring ( unsigned short ,
unsigned char * ,
unsigned long  )

◆ __outdword()

void __outdword ( unsigned short ,
unsigned long  )

◆ __outdwordstring()

void __outdwordstring ( unsigned short ,
unsigned long * ,
unsigned long  )

◆ __outword()

void __outword ( unsigned short ,
unsigned short  )

◆ __outwordstring()

void __outwordstring ( unsigned short ,
unsigned short * ,
unsigned long  )

◆ 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 unsigned char * AsBytePtr;
41 unsigned short * AsWordPtr;
42 unsigned long * AsDwordPtr;
43
44 void * 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}
unsigned short UINT16
Definition BasicTypes.h:47
unsigned __int64 UINT64
Definition BasicTypes.h:21
unsigned char UINT8
Definition BasicTypes.h:46
unsigned int UINT32
Definition BasicTypes.h:48
UINT32 IoInDword(UINT16 port)
Definition IoHandler.h:67
void IoOutWord(UINT16 port, UINT16 value)
Definition IoHandler.h:117
void IoInDwordString(UINT16 port, UINT32 *data, UINT32 size)
Definition IoHandler.h:97
void IoOutByteString(UINT16 port, UINT8 *data, UINT32 count)
Definition IoHandler.h:137
UINT16 IoInWord(UINT16 port)
Definition IoHandler.h:57
void IoOutWordString(UINT16 port, UINT16 *data, UINT32 count)
Definition IoHandler.h:147
UINT8 IoInByte(UINT16 port)
Definition IoHandler.h:47
void IoOutByte(UINT16 port, UINT8 value)
Definition IoHandler.h:107
void IoOutDword(UINT16 port, UINT32 value)
Definition IoHandler.h:127
void IoInByteString(UINT16 port, UINT8 *data, UINT32 size)
Definition IoHandler.h:77
void IoInWordString(UINT16 port, UINT16 *data, UINT32 size)
Definition IoHandler.h:87
void IoOutDwordString(UINT16 port, UINT32 *data, UINT32 count)
Definition IoHandler.h:157
GUEST_REGS * Regs
Definition State.h:305
Definition BasicTypes.h:70
UINT64 rdi
Definition BasicTypes.h:82
UINT64 rax
Definition BasicTypes.h:75
UINT64 rcx
Definition BasicTypes.h:76
UINT64 rsi
Definition BasicTypes.h:81

◆ 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((void *)VCpu->IoBitmapVirtualAddressA, 0xFF, PAGE_SIZE);
249 memset((void *)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}
#define DEBUGGER_EVENT_ALL_IO_PORTS
Apply to all I/O ports.
Definition Constants.h:641
BOOLEAN IoHandleSetIoBitmap(VIRTUAL_MACHINE_STATE *VCpu, UINT32 Port)
Set bits in I/O Bitmap.
Definition IoHandler.c:214
#define PAGE_SIZE
Size of each page (4096 bytes)
Definition common.h:69
UINT64 IoBitmapVirtualAddressB
Definition State.h:319
UINT64 IoBitmapVirtualAddressA
Definition State.h:317

◆ 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((void *)VCpu->IoBitmapVirtualAddressA, 0x0, PAGE_SIZE);
274 memset((void *)VCpu->IoBitmapVirtualAddressB, 0x0, PAGE_SIZE);
275}

◆ IoInByte()

UINT8 IoInByte ( UINT16 port)
inline
48{
49 return __inbyte(port);
50}
unsigned char __inbyte(unsigned short)

◆ IoInByteString()

void IoInByteString ( UINT16 port,
UINT8 * data,
UINT32 size )
inline
78{
79 __inbytestring(port, data, size);
80}
void __inbytestring(unsigned short, unsigned char *, unsigned long)

◆ IoInDword()

UINT32 IoInDword ( UINT16 port)
inline
68{
69 return __indword(port);
70}
unsigned long __indword(unsigned short)

◆ IoInDwordString()

void IoInDwordString ( UINT16 port,
UINT32 * data,
UINT32 size )
inline
98{
99 __indwordstring(port, (unsigned long *)data, size);
100}
void __indwordstring(unsigned short, unsigned long *, unsigned long)

◆ IoInWord()

UINT16 IoInWord ( UINT16 port)
inline
58{
59 return __inword(port);
60}
unsigned short __inword(unsigned short)

◆ IoInWordString()

void IoInWordString ( UINT16 port,
UINT16 * data,
UINT32 size )
inline
88{
89 __inwordstring(port, data, size);
90}
void __inwordstring(unsigned short, unsigned short *, unsigned long)

◆ IoOutByte()

void IoOutByte ( UINT16 port,
UINT8 value )
inline
108{
109 __outbyte(port, value);
110}
void __outbyte(unsigned short, unsigned char)

◆ IoOutByteString()

void IoOutByteString ( UINT16 port,
UINT8 * data,
UINT32 count )
inline
138{
139 __outbytestring(port, data, count);
140}
void __outbytestring(unsigned short, unsigned char *, unsigned long)

◆ IoOutDword()

void IoOutDword ( UINT16 port,
UINT32 value )
inline
128{
129 __outdword(port, value);
130}
void __outdword(unsigned short, unsigned long)

◆ IoOutDwordString()

void IoOutDwordString ( UINT16 port,
UINT32 * data,
UINT32 count )
inline
158{
159 __outdwordstring(port, (unsigned long *)data, count);
160}
void __outdwordstring(unsigned short, unsigned long *, unsigned long)

◆ IoOutWord()

void IoOutWord ( UINT16 port,
UINT16 value )
inline
118{
119 __outword(port, value);
120}
void __outword(unsigned short, unsigned short)

◆ IoOutWordString()

void IoOutWordString ( UINT16 port,
UINT16 * data,
UINT32 count )
inline
148{
149 __outwordstring(port, data, count);
150}
void __outwordstring(unsigned short, unsigned short *, unsigned long)