HyperDbg Debugger
Loading...
Searching...
No Matches
Disassembler.c File Reference
#include "pch.h"

Functions

BOOLEAN DisassemblerShowInstructionsInVmxNonRootMode (PVOID Address, UINT32 Length, BOOLEAN Is32Bit)
 Disassembler show the instructions.
BOOLEAN DisassemblerShowOneInstructionInVmxNonRootMode (PVOID Address, UINT64 ActualRip, BOOLEAN Is32Bit)
 Disassembler show only one instruction.
UINT32 DisassemblerLengthDisassembleEngine (PVOID Address, BOOLEAN Is32Bit)
 Disassembler length disassemble engine.
UINT32 DisassemblerLengthDisassembleEngineInVmxRootOnTargetProcess (PVOID Address, BOOLEAN Is32Bit)
 Disassembler length disassembler engine.
UINT32 DisassemblerLengthDisassembleEngineByProcessId (PVOID Address, BOOLEAN Is32Bit, UINT32 ProcessId)
 Disassembler length disassembler engine.
UINT32 DisassemblerShowOneInstructionInVmxRootMode (PVOID Address, BOOLEAN Is32Bit)
 Shows the disassembly of only one instruction.

Function Documentation

◆ DisassemblerLengthDisassembleEngine()

UINT32 DisassemblerLengthDisassembleEngine ( PVOID Address,
BOOLEAN Is32Bit )

Disassembler length disassemble engine.

if you want to call it directly, shouldn't not be in VMX-root mode, otherwise, you can call DisassemblerLengthDisassembleEngineInVmxRootOnTargetProcess to access memory safely

Parameters
Address
Is32Bit
Returns
UINT32
226{
227 ZydisDecoder Decoder;
228 ZydisDecodedInstruction Instruction;
229 ZydisDecodedOperand Operands[ZYDIS_MAX_OPERAND_COUNT];
230 ZyanStatus Status;
231
232 if (ZydisGetVersion() != ZYDIS_VERSION)
233 {
234 LogError("Err, invalid zydis version");
235 return NULL_ZERO;
236 }
237
238 //
239 // Initialize Zydis decoder
240 //
241 if (Is32Bit)
242 {
243 if (!ZYAN_SUCCESS(ZydisDecoderInit(&Decoder, ZYDIS_MACHINE_MODE_LONG_COMPAT_32, ZYDIS_STACK_WIDTH_32)))
244 {
245 return NULL_ZERO;
246 }
247 }
248 else
249 {
250 if (!ZYAN_SUCCESS(ZydisDecoderInit(&Decoder, ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_STACK_WIDTH_64)))
251 {
252 return NULL_ZERO;
253 }
254 }
255
256 //
257 // Start the decode loop
258 //
259 while ((Status = ZydisDecoderDecodeFull(&Decoder,
260 (PVOID)((UINT64)Address),
262 &Instruction,
263 Operands)) != ZYDIS_STATUS_NO_MORE_DATA)
264 {
265 NT_ASSERT(ZYAN_SUCCESS(Status));
266
267 if (!ZYAN_SUCCESS(Status))
268 {
269 //
270 // Probably invalid instruction
271 //
272 return NULL_ZERO;
273 }
274
275 //
276 // This is a length disassembler, so we just return the length
277 //
278 return Instruction.length;
279 }
280
281 //
282 // return an error status
283 //
284 return NULL_ZERO;
285}
void * PVOID
Definition BasicTypes.h:56
#define NULL_ZERO
Definition BasicTypes.h:110
#define MAXIMUM_INSTR_SIZE
maximum instruction size in Intel
Definition Constants.h:470
#define LogError(format,...)
Log in the case of error.
Definition HyperDbgHyperLogIntrinsics.h:113

◆ DisassemblerLengthDisassembleEngineByProcessId()

UINT32 DisassemblerLengthDisassembleEngineByProcessId ( PVOID Address,
BOOLEAN Is32Bit,
UINT32 ProcessId )

Disassembler length disassembler engine.

Can be called from VMX non-root mode

Parameters
Address
Is32Bit
ProcessId
Returns
UINT32
330{
331 UINT64 SizeOfBufferToRead = 0;
332 BYTE MemoryToRead[MAXIMUM_INSTR_SIZE] = {0};
333 CR3_TYPE CurrentProcessCr3 = {0};
334
335 //
336 // Switch to the target process memory layout by using the process id
337 //
338 CurrentProcessCr3 = SwitchToProcessMemoryLayout(ProcessId);
339
340 //
341 // Read the maximum number of instruction that is valid to be read in the
342 // target address
343 //
344 SizeOfBufferToRead = CheckAddressMaximumInstructionLength(Address);
345
346 //
347 // Restore the original process
348 //
349 SwitchToPreviousProcess(CurrentProcessCr3);
350
351 //
352 // Find the current instruction
353 //
354 MemoryMapperReadMemoryUnsafe((UINT64)Address,
355 MemoryToRead,
356 SizeOfBufferToRead,
357 ProcessId);
358
359 return DisassemblerLengthDisassembleEngine(MemoryToRead, Is32Bit);
360}
UINT32 DisassemblerLengthDisassembleEngine(PVOID Address, BOOLEAN Is32Bit)
Disassembler length disassemble engine.
Definition Disassembler.c:225
unsigned char BYTE
Definition BasicTypes.h:40
struct _CR3_TYPE CR3_TYPE
CR3 Structure.
IMPORT_EXPORT_VMM BOOLEAN MemoryMapperReadMemoryUnsafe(_In_ UINT64 VaAddressToRead, _Inout_ PVOID BufferToSaveMemory, _In_ SIZE_T SizeToRead, _In_ UINT32 TargetProcessId)
IMPORT_EXPORT_VMM VOID SwitchToPreviousProcess(_In_ CR3_TYPE PreviousProcess)
IMPORT_EXPORT_VMM UINT32 CheckAddressMaximumInstructionLength(PVOID Address)
This function returns the maximum instruction length that can be read from this address.
Definition AddressCheck.c:345
IMPORT_EXPORT_VMM CR3_TYPE SwitchToProcessMemoryLayout(_In_ UINT32 ProcessId)

◆ DisassemblerLengthDisassembleEngineInVmxRootOnTargetProcess()

UINT32 DisassemblerLengthDisassembleEngineInVmxRootOnTargetProcess ( PVOID Address,
BOOLEAN Is32Bit )

Disassembler length disassembler engine.

Should be called in VMX-root mode

Parameters
Address
Is32Bit
Returns
UINT32
298{
299 BYTE SafeMemoryToRead[MAXIMUM_INSTR_SIZE] = {0};
300 UINT64 SizeOfSafeBufferToRead = 0;
301
302 //
303 // Read the maximum number of instruction that is valid to be read in the
304 // target address
305 //
306 SizeOfSafeBufferToRead = CheckAddressMaximumInstructionLength(Address);
307
308 //
309 // Find the current instruction
310 //
312 SafeMemoryToRead,
313 SizeOfSafeBufferToRead);
314
315 return DisassemblerLengthDisassembleEngine(SafeMemoryToRead, Is32Bit);
316}
IMPORT_EXPORT_VMM BOOLEAN MemoryMapperReadMemorySafeOnTargetProcess(_In_ UINT64 VaAddressToRead, _Inout_ PVOID BufferToSaveMemory, _In_ SIZE_T SizeToRead)

◆ DisassemblerShowInstructionsInVmxNonRootMode()

BOOLEAN DisassemblerShowInstructionsInVmxNonRootMode ( PVOID Address,
UINT32 Length,
BOOLEAN Is32Bit )

Disassembler show the instructions.

This function should not be called from VMX-root mode

Parameters
Address
Length
Is32Bit
Returns
BOOLEAN
27{
28 ZydisDecoder Decoder;
29 ZydisFormatter Formatter;
30 SIZE_T ReadOffset = 0;
31 ZydisDecodedInstruction Instruction;
32 ZydisDecodedOperand Operands[ZYDIS_MAX_OPERAND_COUNT];
33 ZyanStatus Status;
34 CHAR PrintBuffer[128];
35
36 PAGED_CODE();
37
38 if (ZydisGetVersion() != ZYDIS_VERSION)
39 {
40 LogError("Err, invalid zydis version");
41 return FALSE;
42 }
43
44 //
45 // Initialize Zydis decoder
46 //
47 if (Is32Bit)
48 {
49 if (!ZYAN_SUCCESS(ZydisDecoderInit(&Decoder, ZYDIS_MACHINE_MODE_LONG_COMPAT_32, ZYDIS_STACK_WIDTH_32)))
50 {
51 return FALSE;
52 }
53 }
54 else
55 {
56 if (!ZYAN_SUCCESS(ZydisDecoderInit(&Decoder, ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_STACK_WIDTH_64)))
57 {
58 return FALSE;
59 }
60 }
61
62 //
63 // Initialize Zydis formatter
64 //
65 if (!ZYAN_SUCCESS(ZydisFormatterInit(&Formatter, ZYDIS_FORMATTER_STYLE_INTEL)))
66 {
67 return FALSE;
68 }
69
70 //
71 // Start the decode loop
72 //
73 while ((Status = ZydisDecoderDecodeFull(&Decoder,
74 (PVOID)((UINT64)Address + ReadOffset),
75 Length - ReadOffset,
76 &Instruction,
77 Operands)) != ZYDIS_STATUS_NO_MORE_DATA)
78 {
79 NT_ASSERT(ZYAN_SUCCESS(Status));
80 if (!ZYAN_SUCCESS(Status))
81 {
82 ReadOffset++;
83 continue;
84 }
85
86 // Format and print the instruction
87 const ZyanU64 InstrAddress = (ZyanU64)((UINT64)Address + ReadOffset);
88 ZydisFormatterFormatInstruction(
89 &Formatter,
90 &Instruction,
91 Operands,
92 Instruction.operand_count_visible,
93 PrintBuffer,
94 sizeof(PrintBuffer),
95 InstrAddress,
96 NULL);
97
98 LogInfo("+%-4X 0x%-16llX\t\t%hs\n", (UINT32)ReadOffset, InstrAddress, PrintBuffer);
99
100 ReadOffset += Instruction.length;
101 }
102
103 //
104 // return an error status so that the driver does not have to be unloaded after running
105 //
106 return TRUE;
107}
#define TRUE
Definition BasicTypes.h:114
#define FALSE
Definition BasicTypes.h:113
unsigned int UINT32
Definition BasicTypes.h:54
char CHAR
Definition BasicTypes.h:33
#define LogInfo(format,...)
Define log variables.
Definition HyperDbgHyperLogIntrinsics.h:71

◆ DisassemblerShowOneInstructionInVmxNonRootMode()

BOOLEAN DisassemblerShowOneInstructionInVmxNonRootMode ( PVOID Address,
UINT64 ActualRip,
BOOLEAN Is32Bit )

Disassembler show only one instruction.

This function should not be directly called from VMX-root mode if the caller is sure that the target buffer is safe to be access, then it's okay

Parameters
Address
ActualRip
Is32Bit
Returns
BOOLEAN
122{
123 ZydisDecoder Decoder;
124 ZydisFormatter Formatter;
125 SIZE_T ReadOffset = 0;
126 ZydisDecodedInstruction Instruction;
127 ZydisDecodedOperand Operands[ZYDIS_MAX_OPERAND_COUNT];
128 ZyanStatus Status;
129 CHAR PrintBuffer[128];
130
131 if (ZydisGetVersion() != ZYDIS_VERSION)
132 {
133 LogError("Err, invalid zydis version");
134 return FALSE;
135 }
136
137 //
138 // Initialize Zydis decoder
139 //
140 if (Is32Bit)
141 {
142 if (!ZYAN_SUCCESS(ZydisDecoderInit(&Decoder, ZYDIS_MACHINE_MODE_LONG_COMPAT_32, ZYDIS_STACK_WIDTH_32)))
143 {
144 return FALSE;
145 }
146 }
147 else
148 {
149 if (!ZYAN_SUCCESS(ZydisDecoderInit(&Decoder, ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_STACK_WIDTH_64)))
150 {
151 return FALSE;
152 }
153 }
154
155 //
156 // Initialize Zydis formatter
157 //
158 if (!ZYAN_SUCCESS(ZydisFormatterInit(&Formatter, ZYDIS_FORMATTER_STYLE_INTEL)))
159 {
160 return FALSE;
161 }
162
163 //
164 // Start the decode loop
165 //
166 while ((Status = ZydisDecoderDecodeFull(&Decoder,
167 (PVOID)((UINT64)Address + ReadOffset),
168 MAXIMUM_INSTR_SIZE - ReadOffset,
169 &Instruction,
170 Operands)) != ZYDIS_STATUS_NO_MORE_DATA)
171 {
172 NT_ASSERT(ZYAN_SUCCESS(Status));
173 if (!ZYAN_SUCCESS(Status))
174 {
175 ReadOffset++;
176 continue;
177 }
178
179 // Format and print the instruction
180 const ZyanU64 InstrAddress = (ZyanU64)((UINT64)ActualRip + ReadOffset);
181 ZydisFormatterFormatInstruction(
182 &Formatter,
183 &Instruction,
184 Operands,
185 Instruction.operand_count_visible,
186 PrintBuffer,
187 sizeof(PrintBuffer),
188 InstrAddress,
189 NULL);
190
191 // LogInfo("+%-4X 0x%-16llX\t\t%hs\n", (UINT32)ReadOffset, InstrAddress, PrintBuffer);
192
193 Log("core: %x | pid: %x - tid: %x,\t %llx \t\t\t\t%hs\n",
194 KeGetCurrentProcessorNumberEx(NULL),
195 PsGetCurrentProcessId(),
196 PsGetCurrentThreadId(),
197 ActualRip,
198 PrintBuffer);
199
200 // ReadOffset += Instruction.length;
201
202 //
203 // Only one instruction is enough
204 //
205 break;
206 }
207
208 //
209 // return an error status so that the driver does not have to be unloaded after running
210 //
211 return TRUE;
212}
#define Log(format,...)
Log without any prefix.
Definition HyperDbgHyperLogIntrinsics.h:129

◆ DisassemblerShowOneInstructionInVmxRootMode()

UINT32 DisassemblerShowOneInstructionInVmxRootMode ( PVOID Address,
BOOLEAN Is32Bit )

Shows the disassembly of only one instruction.

Should be called in VMX-root mode

Parameters
Address
Is32Bit
Returns
UINT32
373{
374 BYTE SafeMemoryToRead[MAXIMUM_INSTR_SIZE] = {0};
375 UINT64 SizeOfSafeBufferToRead = 0;
376
377 //
378 // Read the maximum number of instruction that is valid to be read in the
379 // target address
380 //
381 SizeOfSafeBufferToRead = CheckAddressMaximumInstructionLength(Address);
382
383 //
384 // Find the current instruction
385 //
387 SafeMemoryToRead,
388 SizeOfSafeBufferToRead);
389
390 return DisassemblerShowOneInstructionInVmxNonRootMode(SafeMemoryToRead, (UINT64)Address, Is32Bit);
391}
BOOLEAN DisassemblerShowOneInstructionInVmxNonRootMode(PVOID Address, UINT64 ActualRip, BOOLEAN Is32Bit)
Disassembler show only one instruction.
Definition Disassembler.c:121