EASYHOOK_NT_INTERNAL LhDisassembleInstruction(void* InPtr, ULONG* length, PSTR buf, LONG buffSize, ULONG64 *nextInstr) { /* Description: Takes a pointer to machine code and returns the length and ASM code for the referenced instruction. Returns: STATUS_INVALID_PARAMETER The given pointer references invalid machine code. */ // some exotic instructions might not be supported see the project // at https://github.com/vmt/udis86. ud_t ud_obj; ud_init(&ud_obj); #ifdef _M_X64 ud_set_mode(&ud_obj, 64); #else ud_set_mode(&ud_obj, 32); #endif ud_set_syntax(&ud_obj, UD_SYN_INTEL); ud_set_asm_buffer(&ud_obj, buf, buffSize); ud_set_input_buffer(&ud_obj, (uint8_t *)InPtr, 32); *length = ud_disassemble(&ud_obj); *nextInstr = (ULONG64)InPtr + *length; if(length > 0) return STATUS_SUCCESS; else return STATUS_INVALID_PARAMETER; }
/* ============================================================================= * ud_set_asm_buffer * Allow the user to set an assembler output buffer. If `buf` is NULL, * we switch back to the internal buffer. * ============================================================================= */ void ud_set_asm_buffer(struct ud *u, char *buf, size_t size) { if (buf == NULL) { ud_set_asm_buffer(u, u->asm_buf_int, sizeof(u->asm_buf_int)); } else { u->asm_buf = buf; u->asm_buf_size = size; } }
/* ============================================================================= * ud_init * Initializes ud_t object. * ============================================================================= */ extern void ud_init(struct ud* u) { memset((void*)u, 0, sizeof(struct ud)); ud_set_mode(u, 16); u->mnemonic = UD_Iinvalid; ud_set_pc(u, 0); #ifndef __UD_STANDALONE__ ud_set_input_file(u, stdin); #endif /* __UD_STANDALONE__ */ ud_set_asm_buffer(u, u->asm_buf_int, sizeof(u->asm_buf_int)); }