├── Makefile ├── entry.c ├── entry_32.S ├── entry_64.S ├── libudis86 ├── LICENSE ├── Makefile ├── README ├── decode.c ├── decode.h ├── extern.h ├── itab.c ├── itab.h ├── types.h ├── udint.h └── udis86.c ├── trace.c └── udis86.h /Makefile: -------------------------------------------------------------------------------- 1 | NAME := scthook 2 | 3 | obj-m := $(NAME).o 4 | obj-y := libudis86/ 5 | 6 | $(NAME)-y := entry.o trace.o \ 7 | libudis86/built-in.o 8 | 9 | ifeq ($(CONFIG_X86_32),y) 10 | $(NAME)-y += entry_32.o 11 | endif 12 | 13 | ifeq ($(CONFIG_X86_64),y) 14 | $(NAME)-y += entry_64.o 15 | endif 16 | 17 | all: 18 | make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) 19 | 20 | clean: 21 | make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) clean 22 | -------------------------------------------------------------------------------- /entry.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "udis86.h" 10 | 11 | #define debug(fmt...) \ 12 | pr_info("[" KBUILD_MODNAME "] " fmt) 13 | 14 | #define to_ptr(x) \ 15 | (void *)((unsigned long)(x)) 16 | 17 | typedef typeof(module_alloc) modalloc_t; 18 | modalloc_t *modalloc = NULL; 19 | 20 | // 21 | // x86 helpers 22 | // 23 | 24 | typedef struct { 25 | unsigned short limit; 26 | void * base; 27 | } __attribute__((packed)) x86_idt_reg_t; 28 | 29 | typedef struct { 30 | unsigned short offset_low; 31 | unsigned short selector; 32 | unsigned char zero1; 33 | unsigned char type; 34 | #ifdef CONFIG_X86_64 35 | unsigned short offset_middle; 36 | unsigned int offset_high; 37 | unsigned int zero2; 38 | #else 39 | unsigned short offset_high; 40 | #endif 41 | } __attribute__((packed)) x86_idt_desc_t; 42 | 43 | static unsigned long long x86_get_msr(int msr) 44 | { 45 | unsigned long msrl = 0, msrh = 0; 46 | 47 | /* NOTE: rdmsr is always return EDX:EAX pair value */ 48 | asm volatile ("rdmsr" : "=a"(msrl), "=d"(msrh) : "c"(msr)); 49 | 50 | return ((unsigned long long)msrh << 32) | msrl; 51 | } 52 | 53 | static void *x86_get_isr(int vec) 54 | { 55 | x86_idt_reg_t reg; 56 | x86_idt_desc_t desc; 57 | unsigned long address; 58 | 59 | asm volatile("sidt %0" : "=m"(reg)); 60 | 61 | memcpy(&desc, reg.base + vec * sizeof(desc), sizeof(desc)); 62 | 63 | address = desc.offset_high; 64 | #ifdef CONFIG_X86_64 65 | address = (address << 16) | desc.offset_middle; 66 | #endif 67 | address = (address << 16) | desc.offset_low; 68 | 69 | return to_ptr(address); 70 | } 71 | 72 | static void x86_insert_jmp(void *a, const void *f, const void *t) 73 | { 74 | *((char *)(a + 0)) = 0xE9; 75 | *(( int *)(a + 1)) = (long)(t - (f + 5)); 76 | } 77 | 78 | static void x86_insert_call(void *a, const void *f, const void *t, int insn_len) 79 | { 80 | /* 5-byte CALL REL32 -- E8 xx.xx.xx.xx */ 81 | if (insn_len == 5) { 82 | *((char *)(a + 0)) = 0xE8; 83 | *(( int *)(a + 1)) = (long)(t - (f + 5)); 84 | } 85 | 86 | /* 7-byte CALL MEM32 -- FF.14.x5 xx.xx.xx.xx */ 87 | if (insn_len == 7) { 88 | *((char *)(a + 0)) = 0xFF; 89 | *((char *)(a + 1)) = 0x14; 90 | #ifdef CONFIG_X86_64 91 | *((char *)(a + 2)) = 0xC5; 92 | #else 93 | *((char *)(a + 2)) = 0x85; 94 | #endif 95 | *(( int *)(a + 3)) = (long)t; 96 | } 97 | } 98 | 99 | // 100 | // kernel symbol lookup helper 101 | // 102 | 103 | typedef struct { 104 | const char * name; 105 | void * address; 106 | } ksymstr_t; 107 | 108 | static int on_each_symbol(void *data, const char *name, struct module *module, unsigned long address) 109 | { 110 | ksymstr_t *sym = to_ptr(data); 111 | 112 | if (strcmp(name, sym->name) == 0) { 113 | sym->address = to_ptr(address); 114 | return 1; 115 | } 116 | 117 | return 0; 118 | } 119 | 120 | void *get_symbol_address(const char *name) 121 | { 122 | ksymstr_t sym = { 123 | .name = name, .address = NULL, 124 | }; 125 | 126 | kallsyms_on_each_symbol(on_each_symbol, &sym); 127 | 128 | return sym.address; 129 | } 130 | 131 | // 132 | // udis86 helpers 133 | // 134 | 135 | const void *ud_find_insn(const void *entry, int limit, enum ud_mnemonic_code insn_mne, int insn_len) 136 | { 137 | ud_t ud; 138 | const void *result = NULL; 139 | 140 | ud_initialize(&ud, BITS_PER_LONG, UD_VENDOR_ANY, entry, limit); 141 | while (ud_disassemble(&ud)) { 142 | if (ud.mnemonic == insn_mne && ud_insn_len(&ud) == insn_len) { 143 | result = entry + ud_insn_off(&ud); 144 | break; 145 | } 146 | } 147 | 148 | return result; 149 | } 150 | 151 | // 152 | // system call entry hooking 153 | // 154 | 155 | #define STUB_SIZE 512 156 | 157 | static uint8_t *stubsarea = NULL; 158 | 159 | typedef struct scentry { 160 | 161 | const char *name; 162 | 163 | const void *entry; 164 | const void *table; 165 | 166 | const void *pcall; 167 | void *pcall_map; 168 | 169 | void *stub; 170 | const void *handler; 171 | 172 | void (*prepare)(struct scentry *); 173 | void (*implant)(struct scentry *); 174 | void (*restore)(struct scentry *); 175 | void (*cleanup)(struct scentry *); 176 | 177 | } scentry_t; 178 | 179 | /* 180 | * map_writable creates a shadow page mapping of the range 181 | * [addr, addr + len) so that we can write to code mapped read-only. 182 | * 183 | * It is similar to a generalized version of x86's text_poke. But 184 | * because one cannot use vmalloc/vfree() inside stop_machine, we use 185 | * map_writable to map the pages before stop_machine, then use the 186 | * mapping inside stop_machine, and unmap the pages afterwards. 187 | * 188 | * STOLEN from: https://github.com/jirislaby/ksplice 189 | */ 190 | 191 | static void *map_writable(const void *addr, size_t len) 192 | { 193 | void *vaddr; 194 | int nr_pages = DIV_ROUND_UP(offset_in_page(addr) + len, PAGE_SIZE); 195 | struct page **pages = kmalloc(nr_pages * sizeof(*pages), GFP_KERNEL); 196 | void *page_addr = (void *)((unsigned long)addr & PAGE_MASK); 197 | int i; 198 | 199 | if (pages == NULL) 200 | return NULL; 201 | 202 | for (i = 0; i < nr_pages; i++) { 203 | if (__module_address((unsigned long)page_addr) == NULL) { 204 | pages[i] = virt_to_page(page_addr); 205 | WARN_ON(!PageReserved(pages[i])); 206 | } else { 207 | pages[i] = vmalloc_to_page(page_addr); 208 | } 209 | if (pages[i] == NULL) { 210 | kfree(pages); 211 | return NULL; 212 | } 213 | page_addr += PAGE_SIZE; 214 | } 215 | vaddr = vmap(pages, nr_pages, VM_MAP, PAGE_KERNEL); 216 | kfree(pages); 217 | if (vaddr == NULL) 218 | return NULL; 219 | return vaddr + offset_in_page(addr); 220 | } 221 | 222 | static void fixup_stub(scentry_t *se) 223 | { 224 | ud_t ud; 225 | 226 | memset(se->stub, 0x90, STUB_SIZE); 227 | 228 | ud_initialize(&ud, BITS_PER_LONG, \ 229 | UD_VENDOR_ANY, se->handler, STUB_SIZE); 230 | 231 | while (ud_disassemble(&ud)) { 232 | void *insn = se->stub + ud_insn_off(&ud); 233 | const void *orig_insn = se->handler + ud_insn_off(&ud); 234 | 235 | memcpy(insn, orig_insn, ud_insn_len(&ud)); 236 | 237 | /* fixup sys_call_table dispatcher calls (FF.14.x5.xx.xx.xx.xx) */ 238 | if (ud.mnemonic == UD_Icall && ud_insn_len(&ud) == 7) { 239 | x86_insert_call(insn, NULL, se->table, 7); 240 | continue; 241 | } 242 | 243 | /* fixup ServiceTraceEnter/Leave calls (E8.xx.xx.xx.xx) */ 244 | if (ud.mnemonic == UD_Icall && ud_insn_len(&ud) == 5) { 245 | x86_insert_call(insn, insn, orig_insn + (long)(*(int *)(orig_insn + 1)) + 5, 5); 246 | continue; 247 | } 248 | 249 | /* fixup jump back (E9.xx.xx.xx.xx) */ 250 | if (ud.mnemonic == UD_Ijmp && ud_insn_len(&ud) == 5) { 251 | x86_insert_jmp(insn, insn, se->pcall + 7); 252 | break; 253 | } 254 | } 255 | 256 | se->pcall_map = map_writable(se->pcall, 64); 257 | } 258 | 259 | #if defined (CONFIG_X86_64) 260 | #if defined (CONFIG_IA32_EMULATION) 261 | extern void service_syscall32(void); 262 | static void prepare_syscall32(scentry_t *se) 263 | { 264 | /* 265 | * searching for -- 'call *ia32_sys_call_table(,%rax,8)' 266 | * http://lxr.free-electrons.com/source/arch/x86/ia32/ia32entry.S?v=3.13#L320 267 | */ 268 | 269 | se->entry = get_symbol_address(se->name); 270 | se->entry = se->entry ? se->entry : to_ptr(x86_get_msr(MSR_CSTAR)); 271 | if (!se->entry) return; 272 | 273 | se->pcall = ud_find_insn(se->entry, 512, UD_Icall, 7); 274 | if (!se->pcall) return; 275 | 276 | se->table = to_ptr(*(int *)(se->pcall + 3)); 277 | } 278 | #endif 279 | extern void service_syscall64(void); 280 | static void prepare_syscall64_1(scentry_t *se) 281 | { 282 | /* 283 | * searching for -- 'call *sys_call_table(,%rax,8)' 284 | * http://lxr.free-electrons.com/source/arch/x86/kernel/entry_64.S?v=3.13#L629 285 | */ 286 | 287 | se->entry = get_symbol_address(se->name); 288 | se->entry = se->entry ? se->entry : to_ptr(x86_get_msr(MSR_LSTAR)); 289 | if (!se->entry) return; 290 | 291 | se->pcall = ud_find_insn(se->entry, 512, UD_Icall, 7); 292 | if (!se->pcall) return; 293 | 294 | se->table = to_ptr(*(int *)(se->pcall + 3)); 295 | } 296 | extern void service_syscall64(void); 297 | static void prepare_syscall64_2(scentry_t *se) 298 | { 299 | const void *jtracesys; 300 | 301 | /* 302 | * searching for -- 'jnz tracesys' (1 step) 303 | * http://lxr.free-electrons.com/source/arch/x86/kernel/entry_64.S?v=3.13#L619 304 | */ 305 | 306 | se->entry = get_symbol_address(se->name); 307 | se->entry = se->entry ? se->entry : to_ptr(x86_get_msr(MSR_LSTAR)); 308 | if (!se->entry) return; 309 | 310 | jtracesys = ud_find_insn(se->entry, 512, UD_Ijnz, 6); 311 | if (!jtracesys) return; 312 | 313 | /* 314 | * searching for -- 'call *sys_call_table(,%rax,8)' (2 step) 315 | * http://lxr.free-electrons.com/source/arch/x86/kernel/entry_64.S?v=3.13#L629 316 | */ 317 | 318 | se->pcall = ud_find_insn(jtracesys + *(int *)(jtracesys + 2), 512, UD_Icall, 7); 319 | if (!se->pcall) return; 320 | 321 | se->table = to_ptr(*(int *)(se->pcall + 3)); 322 | } 323 | #endif 324 | 325 | #if defined (CONFIG_X86_32) || defined (CONFIG_IA32_EMULATION) 326 | extern void service_int80(void); 327 | static void prepare_int80(scentry_t *se) 328 | { 329 | /* 330 | * searching for -- 'call *ia32_sys_call_table(,%rax,4)' (x86_32) 331 | * http://lxr.free-electrons.com/source/arch/x86/kernel/entry_32.S?v=3.13#L515 332 | * searching for -- 'call *ia32_sys_call_table(,%rax,8)' (x86_64 + ia32e) 333 | * http://lxr.free-electrons.com/source/arch/x86/ia32/ia32entry.S?v=3.13#L428 334 | */ 335 | 336 | se->entry = get_symbol_address(se->name); 337 | se->entry = se->entry ? se->entry : to_ptr(x86_get_isr(0x80)); 338 | if (!se->entry) return; 339 | 340 | se->pcall = ud_find_insn(se->entry, 512, UD_Icall, 7); 341 | if (!se->pcall) return; 342 | 343 | se->table = to_ptr(*(int *)(se->pcall + 3)); 344 | } 345 | extern void service_sysenter(void); 346 | static void prepare_sysenter(scentry_t *se) 347 | { 348 | /* 349 | * searching for -- 'call *ia32_sys_call_table(,%rax,4)' (x86_32) 350 | * http://lxr.free-electrons.com/source/arch/x86/kernel/entry_32.S?v=3.13#L435 351 | * searching for -- 'call *ia32_sys_call_table(,%rax,8)' (x86_64 + ia32e) 352 | * http://lxr.free-electrons.com/source/arch/x86/ia32/ia32entry.S?v=3.13#L163 353 | */ 354 | 355 | se->entry = get_symbol_address(se->name); 356 | se->entry = se->entry ? se->entry : to_ptr(x86_get_msr(MSR_IA32_SYSENTER_EIP)); 357 | if (!se->entry) return; 358 | 359 | se->pcall = ud_find_insn(se->entry, 512, UD_Icall, 7); 360 | if (!se->pcall) return; 361 | 362 | se->table = to_ptr(*(int *)(se->pcall + 3)); 363 | } 364 | #endif 365 | 366 | /* called under the stop_machine() */ 367 | static void generic_implant(scentry_t *se) 368 | { 369 | if (!se->pcall_map) return; 370 | 371 | debug(" [o] implanting jump to stub handler %p (%s)\n", se->stub, se->name); 372 | 373 | x86_insert_jmp(se->pcall_map, se->pcall, se->stub); 374 | } 375 | 376 | /* called under the stop_machine() */ 377 | static void generic_restore(scentry_t *se) 378 | { 379 | ud_t ud; 380 | 381 | if (!se->pcall_map) return; 382 | 383 | ud_initialize(&ud, BITS_PER_LONG, \ 384 | UD_VENDOR_ANY, se->stub, STUB_SIZE); 385 | 386 | while (ud_disassemble(&ud)) { 387 | if (ud.mnemonic == UD_Icall && ud_insn_len(&ud) == 5) { 388 | memset(se->stub + ud_insn_off(&ud), 0x90, ud_insn_len(&ud)); 389 | continue; 390 | } 391 | if (ud.mnemonic == UD_Ijmp) 392 | break; 393 | } 394 | 395 | debug(" [o] restoring original call instruction %p (%s)\n", se->pcall, se->name); 396 | 397 | x86_insert_call(se->pcall_map, NULL, se->table, 7); 398 | } 399 | 400 | static void generic_cleanup(scentry_t *se) 401 | { 402 | if (!se->pcall_map) return; 403 | 404 | vunmap(to_ptr((unsigned long)se->pcall_map & PAGE_MASK)); 405 | 406 | debug(" [o] cleanning up resources (%s)\n", se->name); 407 | } 408 | 409 | /* 410 | * List of all the possible entries 411 | */ 412 | 413 | scentry_t elist[] = { 414 | #ifdef CONFIG_X86_64 415 | #ifdef CONFIG_IA32_EMULATION 416 | { 417 | .name = "ia32_syscall", /* INT 0x80: IDT(0x80), ia32/ia32entry.S (emu) */ 418 | .handler = service_int80, 419 | .prepare = prepare_int80, 420 | }, 421 | { 422 | .name = "ia32_sysenter_target", /* SYSENTER: MSR(IA32_SYSENTER_EIP), ia32/ia32entry.S (emu) */ 423 | .handler = service_sysenter, 424 | .prepare = prepare_sysenter, 425 | }, 426 | { 427 | .name = "ia32_cstar_target", /* SYSCALL32: MSR(CSTAR), ia32/ia32entry.S (emu) */ 428 | .handler = service_syscall32, 429 | .prepare = prepare_syscall32, 430 | }, 431 | #endif 432 | { 433 | .name = "system_call", /* SYSCALL: MSR(LSTAR), kernel/entry_64.S (1) */ 434 | .handler = service_syscall64, 435 | .prepare = prepare_syscall64_1 436 | }, 437 | { 438 | .name = "system_call", /* SYSCALL: MSR(LSTAR), kernel/entry_64.S (2) */ 439 | .handler = service_syscall64, 440 | .prepare = prepare_syscall64_2 441 | }, 442 | #else 443 | { 444 | .name = "system_call", /* INT 0x80: IDT(0x80), kernel/entry_32.S */ 445 | .handler = service_int80, 446 | .prepare = prepare_int80, 447 | }, 448 | { 449 | .name = "ia32_sysenter_target", 450 | .handler = service_sysenter, 451 | .prepare = prepare_sysenter, /* SYSENTER: MSR(IA32_SYSENTER_TARGET), kernel/entry_32.S */ 452 | }, 453 | #endif 454 | }; 455 | 456 | static int prepare(void) 457 | { 458 | int i; 459 | 460 | debug("# prepare\n"); 461 | 462 | for (i = 0; i < ARRAY_SIZE(elist); i++) { 463 | scentry_t *se = &elist[i]; 464 | 465 | se->stub = stubsarea + STUB_SIZE * i; 466 | 467 | if (!se->implant) se->implant = generic_implant; 468 | if (!se->restore) se->restore = generic_restore; 469 | if (!se->cleanup) se->cleanup = generic_cleanup; 470 | 471 | se->prepare(&elist[i]); 472 | if (se->table) fixup_stub(se); 473 | 474 | debug(" [o] prepared stub %p (%s)\n", se->stub, se->name); 475 | debug(" entry:%p pcall:%p table:%p\n", se->entry, se->pcall, se->table); 476 | } 477 | 478 | debug("# prepare OK\n"); 479 | 480 | return 0; 481 | } 482 | 483 | static int do_implant(void *arg) 484 | { 485 | int i; 486 | 487 | for (i = 0; i < ARRAY_SIZE(elist); i++) 488 | elist[i].implant(&elist[i]); 489 | 490 | return 0; 491 | } 492 | 493 | static int implant(void) 494 | { 495 | int result; 496 | 497 | debug("# implant\n"); 498 | result = stop_machine(do_implant, NULL, NULL); 499 | debug("# implant OK\n"); 500 | 501 | return result; 502 | } 503 | 504 | static int do_restore(void *arg) 505 | { 506 | int i; 507 | 508 | for (i = 0; i < ARRAY_SIZE(elist); i++) 509 | elist[i].restore(&elist[i]); 510 | 511 | return 0; 512 | } 513 | 514 | static void restore(void) 515 | { 516 | debug("# restore\n"); 517 | stop_machine(do_restore, NULL, NULL); 518 | debug("# restore OK\n"); 519 | } 520 | 521 | static void cleanup(void) 522 | { 523 | int i; 524 | 525 | debug("# cleanup\n"); 526 | 527 | for (i = 0; i < ARRAY_SIZE(elist); i++) 528 | elist[i].cleanup(&elist[i]); 529 | 530 | debug("# cleanup OK\n"); 531 | } 532 | 533 | int init_module(void) 534 | { 535 | debug("# SYSCALL hooking module\n"); 536 | 537 | modalloc = (modalloc_t *)get_symbol_address("module_alloc"); 538 | if (!modalloc) 539 | return -EINVAL; 540 | 541 | stubsarea = modalloc(STUB_SIZE * ARRAY_SIZE(elist)); 542 | if (!stubsarea) 543 | return -ENOMEM; 544 | 545 | return (prepare() || implant()); 546 | } 547 | 548 | void cleanup_module(void) 549 | { 550 | restore(); 551 | cleanup(); 552 | 553 | debug("# DONE\n"); 554 | } 555 | 556 | MODULE_LICENSE("GPL"); 557 | MODULE_AUTHOR("Ilya V. Matveychikov "); 558 | -------------------------------------------------------------------------------- /entry_32.S: -------------------------------------------------------------------------------- 1 | #undef CONFIG_AS_CFI 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | .global service_int80 8 | service_int80: 9 | movl %esp, %eax 10 | call ServiceTraceEnter 11 | 12 | movl PT_ORIG_EAX(%esp), %eax 13 | call *0x00000000(,%eax,4) // origin call 14 | movl %eax, PT_EAX(%esp) 15 | 16 | movl %esp, %eax 17 | call ServiceTraceLeave 18 | 19 | mov PT_EAX(%esp), %eax 20 | jmp 0x00000000 21 | 22 | .global service_sysenter 23 | service_sysenter: 24 | movl %esp, %eax 25 | call ServiceTraceEnter 26 | 27 | movl PT_ORIG_EAX(%esp), %eax 28 | call *0x00000000(,%eax,4) // origin call 29 | movl %eax, PT_EAX(%esp) 30 | 31 | movl %esp, %eax 32 | call ServiceTraceLeave 33 | 34 | mov PT_EAX(%esp), %eax 35 | jmp 0x00000000 36 | -------------------------------------------------------------------------------- /entry_64.S: -------------------------------------------------------------------------------- 1 | #undef CONFIG_AS_CFI 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #ifdef CONFIG_IA32_EMULATION 8 | 9 | .macro IA32_ARG_FIXUP noebp=0 10 | movl %edi, %r8d 11 | .if \noebp 12 | .else 13 | movl %ebp, %r9d 14 | .endif 15 | xchg %ecx, %esi 16 | movl %ebx, %edi 17 | movl %edx, %edx /* zero extension */ 18 | .endm 19 | 20 | .macro LOAD_ARGS32 offset, _r9=0 21 | .if \_r9 22 | movl \offset + 16(%rsp), %r9d 23 | .endif 24 | movl \offset + 40(%rsp), %ecx 25 | movl \offset + 48(%rsp), %edx 26 | movl \offset + 56(%rsp), %esi 27 | movl \offset + 64(%rsp), %edi 28 | movl %eax, %eax /* zero extension */ 29 | .endm 30 | 31 | .global service_int80 32 | service_int80: 33 | SAVE_REST 34 | movq %rsp, %rdi 35 | call ServiceTraceEnter 36 | RESTORE_REST 37 | 38 | LOAD_ARGS32 0 39 | IA32_ARG_FIXUP 40 | movq ORIG_RAX - ARGOFFSET(%rsp), %rax 41 | call *0x00000000(,%rax,8) // origin call 42 | movq %rax, RAX - ARGOFFSET(%rsp) 43 | 44 | SAVE_REST 45 | movq %rsp, %rdi 46 | call ServiceTraceLeave 47 | RESTORE_REST 48 | 49 | movq RAX - ARGOFFSET(%rsp), %rax 50 | jmp 0x00000000 51 | 52 | .global service_sysenter 53 | service_sysenter: 54 | SAVE_REST 55 | movq %rsp, %rdi 56 | call ServiceTraceEnter 57 | RESTORE_REST 58 | 59 | LOAD_ARGS32 0 60 | IA32_ARG_FIXUP 61 | movq ORIG_RAX - ARGOFFSET(%rsp), %rax 62 | call *0x00000000(,%rax,8) // origin call 63 | movq %rax, RAX - ARGOFFSET(%rsp) 64 | 65 | SAVE_REST 66 | movq %rsp, %rdi 67 | call ServiceTraceLeave 68 | RESTORE_REST 69 | 70 | movq RAX - ARGOFFSET(%rsp), %rax 71 | jmp 0x00000000 72 | 73 | .global service_syscall32 74 | service_syscall32: 75 | SAVE_REST 76 | movq %rsp, %rdi 77 | call ServiceTraceEnter 78 | RESTORE_REST 79 | 80 | LOAD_ARGS32 0 81 | IA32_ARG_FIXUP 1 82 | movq ORIG_RAX - ARGOFFSET(%rsp), %rax 83 | call *0x00000000(,%rax,8) // origin call 84 | movq %rax, RAX - ARGOFFSET(%rsp) 85 | 86 | SAVE_REST 87 | movq %rsp, %rdi 88 | call ServiceTraceLeave 89 | RESTORE_REST 90 | 91 | movq RAX - ARGOFFSET(%rsp), %rax 92 | jmp 0x00000000 93 | 94 | #endif /* CONFIG_IA32_EMULATION */ 95 | 96 | .global service_syscall64 97 | service_syscall64: 98 | SAVE_REST 99 | movq %rsp, %rdi 100 | call ServiceTraceEnter 101 | RESTORE_REST 102 | 103 | LOAD_ARGS 0 104 | movq %r10, %rcx 105 | movq ORIG_RAX - ARGOFFSET(%rsp), %rax 106 | call *0x00000000(,%rax,8) // origin call 107 | movq %rax, RAX - ARGOFFSET(%rsp) 108 | 109 | SAVE_REST 110 | movq %rsp, %rdi 111 | call ServiceTraceLeave 112 | RESTORE_REST 113 | 114 | movq RAX - ARGOFFSET(%rsp), %rax 115 | jmp 0x00000000 116 | -------------------------------------------------------------------------------- /libudis86/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2002-2012, Vivek Thampi 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, 5 | are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, 8 | this list of conditions and the following disclaimer. 9 | 2. Redistributions in binary form must reproduce the above copyright notice, 10 | this list of conditions and the following disclaimer in the documentation 11 | and/or other materials provided with the distribution. 12 | 13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 14 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 17 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 18 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 19 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 20 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 22 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | -------------------------------------------------------------------------------- /libudis86/Makefile: -------------------------------------------------------------------------------- 1 | obj-y := decode.o itab.o udis86.o 2 | ccflags-y := -D__UD_STANDALONE__ 3 | -------------------------------------------------------------------------------- /libudis86/README: -------------------------------------------------------------------------------- 1 | libudis86 @ 5a7e0fbf44aad5454f0fdddff15585cd05810840 2 | 3 | 1) clone udis86 repo 4 | 5 | $ git clone https://github.com/vmt/udis86 . 6 | 7 | 2) configure and make 8 | 9 | $ cd udis86 10 | $ ./autogen.sh 11 | $ ./configire --prefix=/usr/local 12 | $ make 13 | 14 | 3) copy libudis86 sources as it shown here 15 | 16 | src/ 17 | udis86.h 18 | src/libudis86/ 19 | decode.{c,h} 20 | extern.h 21 | itab.{c,h} 22 | types.h 23 | udint.h 24 | udis86.c 25 | -------------------------------------------------------------------------------- /libudis86/decode.c: -------------------------------------------------------------------------------- 1 | /* udis86 - libudis86/decode.c 2 | * 3 | * Copyright (c) 2002-2009 Vivek Thampi 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 19 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 22 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | #include "udint.h" 27 | #include "types.h" 28 | #include "decode.h" 29 | 30 | #ifndef __UD_STANDALONE__ 31 | # include 32 | #endif /* __UD_STANDALONE__ */ 33 | 34 | /* The max number of prefixes to an instruction */ 35 | #define MAX_PREFIXES 15 36 | 37 | /* rex prefix bits */ 38 | #define REX_W(r) ( ( 0xF & ( r ) ) >> 3 ) 39 | #define REX_R(r) ( ( 0x7 & ( r ) ) >> 2 ) 40 | #define REX_X(r) ( ( 0x3 & ( r ) ) >> 1 ) 41 | #define REX_B(r) ( ( 0x1 & ( r ) ) >> 0 ) 42 | #define REX_PFX_MASK(n) ( ( P_REXW(n) << 3 ) | \ 43 | ( P_REXR(n) << 2 ) | \ 44 | ( P_REXX(n) << 1 ) | \ 45 | ( P_REXB(n) << 0 ) ) 46 | 47 | /* scable-index-base bits */ 48 | #define SIB_S(b) ( ( b ) >> 6 ) 49 | #define SIB_I(b) ( ( ( b ) >> 3 ) & 7 ) 50 | #define SIB_B(b) ( ( b ) & 7 ) 51 | 52 | /* modrm bits */ 53 | #define MODRM_REG(b) ( ( ( b ) >> 3 ) & 7 ) 54 | #define MODRM_NNN(b) ( ( ( b ) >> 3 ) & 7 ) 55 | #define MODRM_MOD(b) ( ( ( b ) >> 6 ) & 3 ) 56 | #define MODRM_RM(b) ( ( b ) & 7 ) 57 | 58 | static int decode_ext(struct ud *u, uint16_t ptr); 59 | static int decode_opcode(struct ud *u); 60 | 61 | enum reg_class { /* register classes */ 62 | REGCLASS_GPR, 63 | REGCLASS_MMX, 64 | REGCLASS_CR, 65 | REGCLASS_DB, 66 | REGCLASS_SEG, 67 | REGCLASS_XMM 68 | }; 69 | 70 | /* 71 | * inp_start 72 | * Should be called before each de-code operation. 73 | */ 74 | static void 75 | inp_start(struct ud *u) 76 | { 77 | u->inp_ctr = 0; 78 | } 79 | 80 | static uint8_t 81 | inp_peek(struct ud *u) 82 | { 83 | if (u->inp_end == 0) { 84 | if (u->inp_buf != NULL) { 85 | if (u->inp_buf_index < u->inp_buf_size) { 86 | return u->inp_buf[u->inp_buf_index]; 87 | } 88 | } else if (u->inp_peek != UD_EOI) { 89 | return u->inp_peek; 90 | } else { 91 | int c; 92 | if ((c = u->inp_hook(u)) != UD_EOI) { 93 | u->inp_peek = c; 94 | return u->inp_peek; 95 | } 96 | } 97 | } 98 | u->inp_end = 1; 99 | UDERR(u, "byte expected, eoi received\n"); 100 | return 0; 101 | } 102 | 103 | static uint8_t 104 | inp_next(struct ud *u) 105 | { 106 | if (u->inp_end == 0) { 107 | if (u->inp_buf != NULL) { 108 | if (u->inp_buf_index < u->inp_buf_size) { 109 | u->inp_ctr++; 110 | return (u->inp_curr = u->inp_buf[u->inp_buf_index++]); 111 | } 112 | } else { 113 | int c = u->inp_peek; 114 | if (c != UD_EOI || (c = u->inp_hook(u)) != UD_EOI) { 115 | u->inp_peek = UD_EOI; 116 | u->inp_curr = c; 117 | u->inp_sess[u->inp_ctr++] = u->inp_curr; 118 | return u->inp_curr; 119 | } 120 | } 121 | } 122 | u->inp_end = 1; 123 | UDERR(u, "byte expected, eoi received\n"); 124 | return 0; 125 | } 126 | 127 | static uint8_t 128 | inp_curr(struct ud *u) 129 | { 130 | return u->inp_curr; 131 | } 132 | 133 | 134 | /* 135 | * inp_uint8 136 | * int_uint16 137 | * int_uint32 138 | * int_uint64 139 | * Load little-endian values from input 140 | */ 141 | static uint8_t 142 | inp_uint8(struct ud* u) 143 | { 144 | return inp_next(u); 145 | } 146 | 147 | static uint16_t 148 | inp_uint16(struct ud* u) 149 | { 150 | uint16_t r, ret; 151 | 152 | ret = inp_next(u); 153 | r = inp_next(u); 154 | return ret | (r << 8); 155 | } 156 | 157 | static uint32_t 158 | inp_uint32(struct ud* u) 159 | { 160 | uint32_t r, ret; 161 | 162 | ret = inp_next(u); 163 | r = inp_next(u); 164 | ret = ret | (r << 8); 165 | r = inp_next(u); 166 | ret = ret | (r << 16); 167 | r = inp_next(u); 168 | return ret | (r << 24); 169 | } 170 | 171 | static uint64_t 172 | inp_uint64(struct ud* u) 173 | { 174 | uint64_t r, ret; 175 | 176 | ret = inp_next(u); 177 | r = inp_next(u); 178 | ret = ret | (r << 8); 179 | r = inp_next(u); 180 | ret = ret | (r << 16); 181 | r = inp_next(u); 182 | ret = ret | (r << 24); 183 | r = inp_next(u); 184 | ret = ret | (r << 32); 185 | r = inp_next(u); 186 | ret = ret | (r << 40); 187 | r = inp_next(u); 188 | ret = ret | (r << 48); 189 | r = inp_next(u); 190 | return ret | (r << 56); 191 | } 192 | 193 | 194 | static inline int 195 | eff_opr_mode(int dis_mode, int rex_w, int pfx_opr) 196 | { 197 | if (dis_mode == 64) { 198 | return rex_w ? 64 : (pfx_opr ? 16 : 32); 199 | } else if (dis_mode == 32) { 200 | return pfx_opr ? 16 : 32; 201 | } else { 202 | UD_ASSERT(dis_mode == 16); 203 | return pfx_opr ? 32 : 16; 204 | } 205 | } 206 | 207 | 208 | static inline int 209 | eff_adr_mode(int dis_mode, int pfx_adr) 210 | { 211 | if (dis_mode == 64) { 212 | return pfx_adr ? 32 : 64; 213 | } else if (dis_mode == 32) { 214 | return pfx_adr ? 16 : 32; 215 | } else { 216 | UD_ASSERT(dis_mode == 16); 217 | return pfx_adr ? 32 : 16; 218 | } 219 | } 220 | 221 | 222 | /* 223 | * decode_prefixes 224 | * 225 | * Extracts instruction prefixes. 226 | */ 227 | static int 228 | decode_prefixes(struct ud *u) 229 | { 230 | int done = 0; 231 | uint8_t curr = 0, last = 0; 232 | UD_RETURN_ON_ERROR(u); 233 | 234 | do { 235 | last = curr; 236 | curr = inp_next(u); 237 | UD_RETURN_ON_ERROR(u); 238 | if (u->inp_ctr == MAX_INSN_LENGTH) { 239 | UD_RETURN_WITH_ERROR(u, "max instruction length"); 240 | } 241 | 242 | switch (curr) 243 | { 244 | case 0x2E: 245 | u->pfx_seg = UD_R_CS; 246 | break; 247 | case 0x36: 248 | u->pfx_seg = UD_R_SS; 249 | break; 250 | case 0x3E: 251 | u->pfx_seg = UD_R_DS; 252 | break; 253 | case 0x26: 254 | u->pfx_seg = UD_R_ES; 255 | break; 256 | case 0x64: 257 | u->pfx_seg = UD_R_FS; 258 | break; 259 | case 0x65: 260 | u->pfx_seg = UD_R_GS; 261 | break; 262 | case 0x67: /* adress-size override prefix */ 263 | u->pfx_adr = 0x67; 264 | break; 265 | case 0xF0: 266 | u->pfx_lock = 0xF0; 267 | break; 268 | case 0x66: 269 | u->pfx_opr = 0x66; 270 | break; 271 | case 0xF2: 272 | u->pfx_str = 0xf2; 273 | break; 274 | case 0xF3: 275 | u->pfx_str = 0xf3; 276 | break; 277 | default: 278 | /* consume if rex */ 279 | done = (u->dis_mode == 64 && (curr & 0xF0) == 0x40) ? 0 : 1; 280 | break; 281 | } 282 | } while (!done); 283 | /* rex prefixes in 64bit mode, must be the last prefix */ 284 | if (u->dis_mode == 64 && (last & 0xF0) == 0x40) { 285 | u->pfx_rex = last; 286 | } 287 | return 0; 288 | } 289 | 290 | 291 | /* 292 | * vex_l, vex_w 293 | * Return the vex.L and vex.W bits 294 | */ 295 | static inline uint8_t 296 | vex_l(const struct ud *u) 297 | { 298 | UD_ASSERT(u->vex_op != 0); 299 | return ((u->vex_op == 0xc4 ? u->vex_b2 : u->vex_b1) >> 2) & 1; 300 | } 301 | 302 | static inline uint8_t 303 | vex_w(const struct ud *u) 304 | { 305 | UD_ASSERT(u->vex_op != 0); 306 | return u->vex_op == 0xc4 ? ((u->vex_b2 >> 7) & 1) : 0; 307 | } 308 | 309 | 310 | static inline uint8_t 311 | modrm(struct ud * u) 312 | { 313 | if ( !u->have_modrm ) { 314 | u->modrm = inp_next( u ); 315 | u->have_modrm = 1; 316 | } 317 | return u->modrm; 318 | } 319 | 320 | 321 | static unsigned int 322 | resolve_operand_size(const struct ud* u, enum ud_operand_size osize) 323 | { 324 | switch (osize) { 325 | case SZ_V: 326 | return u->opr_mode; 327 | case SZ_Z: 328 | return u->opr_mode == 16 ? 16 : 32; 329 | case SZ_Y: 330 | return u->opr_mode == 16 ? 32 : u->opr_mode; 331 | case SZ_RDQ: 332 | return u->dis_mode == 64 ? 64 : 32; 333 | case SZ_X: 334 | UD_ASSERT(u->vex_op != 0); 335 | return (P_VEXL(u->itab_entry->prefix) && vex_l(u)) ? SZ_QQ : SZ_DQ; 336 | default: 337 | return osize; 338 | } 339 | } 340 | 341 | 342 | static int resolve_mnemonic( struct ud* u ) 343 | { 344 | /* resolve 3dnow weirdness. */ 345 | if ( u->mnemonic == UD_I3dnow ) { 346 | u->mnemonic = ud_itab[ u->le->table[ inp_curr( u ) ] ].mnemonic; 347 | } 348 | /* SWAPGS is only valid in 64bits mode */ 349 | if ( u->mnemonic == UD_Iswapgs && u->dis_mode != 64 ) { 350 | UDERR(u, "swapgs invalid in 64bits mode\n"); 351 | return -1; 352 | } 353 | 354 | if (u->mnemonic == UD_Ixchg) { 355 | if ((u->operand[0].type == UD_OP_REG && u->operand[0].base == UD_R_AX && 356 | u->operand[1].type == UD_OP_REG && u->operand[1].base == UD_R_AX) || 357 | (u->operand[0].type == UD_OP_REG && u->operand[0].base == UD_R_EAX && 358 | u->operand[1].type == UD_OP_REG && u->operand[1].base == UD_R_EAX)) { 359 | u->operand[0].type = UD_NONE; 360 | u->operand[1].type = UD_NONE; 361 | u->mnemonic = UD_Inop; 362 | } 363 | } 364 | 365 | if (u->mnemonic == UD_Inop && u->pfx_repe) { 366 | u->pfx_repe = 0; 367 | u->mnemonic = UD_Ipause; 368 | } 369 | return 0; 370 | } 371 | 372 | 373 | /* ----------------------------------------------------------------------------- 374 | * decode_a()- Decodes operands of the type seg:offset 375 | * ----------------------------------------------------------------------------- 376 | */ 377 | static void 378 | decode_a(struct ud* u, struct ud_operand *op) 379 | { 380 | if (u->opr_mode == 16) { 381 | /* seg16:off16 */ 382 | op->type = UD_OP_PTR; 383 | op->size = 32; 384 | op->lval.ptr.off = inp_uint16(u); 385 | op->lval.ptr.seg = inp_uint16(u); 386 | } else { 387 | /* seg16:off32 */ 388 | op->type = UD_OP_PTR; 389 | op->size = 48; 390 | op->lval.ptr.off = inp_uint32(u); 391 | op->lval.ptr.seg = inp_uint16(u); 392 | } 393 | } 394 | 395 | /* ----------------------------------------------------------------------------- 396 | * decode_gpr() - Returns decoded General Purpose Register 397 | * ----------------------------------------------------------------------------- 398 | */ 399 | static enum ud_type 400 | decode_gpr(register struct ud* u, unsigned int s, unsigned char rm) 401 | { 402 | switch (s) { 403 | case 64: 404 | return UD_R_RAX + rm; 405 | case 32: 406 | return UD_R_EAX + rm; 407 | case 16: 408 | return UD_R_AX + rm; 409 | case 8: 410 | if (u->dis_mode == 64 && u->pfx_rex) { 411 | if (rm >= 4) 412 | return UD_R_SPL + (rm-4); 413 | return UD_R_AL + rm; 414 | } else return UD_R_AL + rm; 415 | case 0: 416 | /* invalid size in case of a decode error */ 417 | UD_ASSERT(u->error); 418 | return UD_NONE; 419 | default: 420 | UD_ASSERT(!"invalid operand size"); 421 | return UD_NONE; 422 | } 423 | } 424 | 425 | static void 426 | decode_reg(struct ud *u, 427 | struct ud_operand *opr, 428 | int type, 429 | int num, 430 | int size) 431 | { 432 | int reg; 433 | size = resolve_operand_size(u, size); 434 | switch (type) { 435 | case REGCLASS_GPR : reg = decode_gpr(u, size, num); break; 436 | case REGCLASS_MMX : reg = UD_R_MM0 + (num & 7); break; 437 | case REGCLASS_XMM : 438 | reg = num + (size == SZ_QQ ? UD_R_YMM0 : UD_R_XMM0); 439 | break; 440 | case REGCLASS_CR : reg = UD_R_CR0 + num; break; 441 | case REGCLASS_DB : reg = UD_R_DR0 + num; break; 442 | case REGCLASS_SEG : { 443 | /* 444 | * Only 6 segment registers, anything else is an error. 445 | */ 446 | if ((num & 7) > 5) { 447 | UDERR(u, "invalid segment register value\n"); 448 | return; 449 | } else { 450 | reg = UD_R_ES + (num & 7); 451 | } 452 | break; 453 | } 454 | default: 455 | UD_ASSERT(!"invalid register type"); 456 | return; 457 | } 458 | opr->type = UD_OP_REG; 459 | opr->base = reg; 460 | opr->size = size; 461 | } 462 | 463 | 464 | /* 465 | * decode_imm 466 | * 467 | * Decode Immediate values. 468 | */ 469 | static void 470 | decode_imm(struct ud* u, unsigned int size, struct ud_operand *op) 471 | { 472 | op->size = resolve_operand_size(u, size); 473 | op->type = UD_OP_IMM; 474 | 475 | switch (op->size) { 476 | case 8: op->lval.sbyte = inp_uint8(u); break; 477 | case 16: op->lval.uword = inp_uint16(u); break; 478 | case 32: op->lval.udword = inp_uint32(u); break; 479 | case 64: op->lval.uqword = inp_uint64(u); break; 480 | default: return; 481 | } 482 | } 483 | 484 | 485 | /* 486 | * decode_mem_disp 487 | * 488 | * Decode mem address displacement. 489 | */ 490 | static void 491 | decode_mem_disp(struct ud* u, unsigned int size, struct ud_operand *op) 492 | { 493 | switch (size) { 494 | case 8: 495 | op->offset = 8; 496 | op->lval.ubyte = inp_uint8(u); 497 | break; 498 | case 16: 499 | op->offset = 16; 500 | op->lval.uword = inp_uint16(u); 501 | break; 502 | case 32: 503 | op->offset = 32; 504 | op->lval.udword = inp_uint32(u); 505 | break; 506 | case 64: 507 | op->offset = 64; 508 | op->lval.uqword = inp_uint64(u); 509 | break; 510 | default: 511 | return; 512 | } 513 | } 514 | 515 | 516 | /* 517 | * decode_modrm_reg 518 | * 519 | * Decodes reg field of mod/rm byte 520 | * 521 | */ 522 | static inline void 523 | decode_modrm_reg(struct ud *u, 524 | struct ud_operand *operand, 525 | unsigned int type, 526 | unsigned int size) 527 | { 528 | uint8_t reg = (REX_R(u->_rex) << 3) | MODRM_REG(modrm(u)); 529 | decode_reg(u, operand, type, reg, size); 530 | } 531 | 532 | 533 | /* 534 | * decode_modrm_rm 535 | * 536 | * Decodes rm field of mod/rm byte 537 | * 538 | */ 539 | static void 540 | decode_modrm_rm(struct ud *u, 541 | struct ud_operand *op, 542 | unsigned char type, /* register type */ 543 | unsigned int size) /* operand size */ 544 | 545 | { 546 | size_t offset = 0; 547 | unsigned char mod, rm; 548 | 549 | /* get mod, r/m and reg fields */ 550 | mod = MODRM_MOD(modrm(u)); 551 | rm = (REX_B(u->_rex) << 3) | MODRM_RM(modrm(u)); 552 | 553 | /* 554 | * If mod is 11b, then the modrm.rm specifies a register. 555 | * 556 | */ 557 | if (mod == 3) { 558 | decode_reg(u, op, type, rm, size); 559 | return; 560 | } 561 | 562 | /* 563 | * !11b => Memory Address 564 | */ 565 | op->type = UD_OP_MEM; 566 | op->size = resolve_operand_size(u, size); 567 | 568 | if (u->adr_mode == 64) { 569 | op->base = UD_R_RAX + rm; 570 | if (mod == 1) { 571 | offset = 8; 572 | } else if (mod == 2) { 573 | offset = 32; 574 | } else if (mod == 0 && (rm & 7) == 5) { 575 | op->base = UD_R_RIP; 576 | offset = 32; 577 | } else { 578 | offset = 0; 579 | } 580 | /* 581 | * Scale-Index-Base (SIB) 582 | */ 583 | if ((rm & 7) == 4) { 584 | inp_next(u); 585 | 586 | op->base = UD_R_RAX + (SIB_B(inp_curr(u)) | (REX_B(u->_rex) << 3)); 587 | op->index = UD_R_RAX + (SIB_I(inp_curr(u)) | (REX_X(u->_rex) << 3)); 588 | /* special conditions for base reference */ 589 | if (op->index == UD_R_RSP) { 590 | op->index = UD_NONE; 591 | op->scale = UD_NONE; 592 | } else { 593 | op->scale = (1 << SIB_S(inp_curr(u))) & ~1; 594 | } 595 | 596 | if (op->base == UD_R_RBP || op->base == UD_R_R13) { 597 | if (mod == 0) { 598 | op->base = UD_NONE; 599 | } 600 | if (mod == 1) { 601 | offset = 8; 602 | } else { 603 | offset = 32; 604 | } 605 | } 606 | } else { 607 | op->scale = UD_NONE; 608 | op->index = UD_NONE; 609 | } 610 | } else if (u->adr_mode == 32) { 611 | op->base = UD_R_EAX + rm; 612 | if (mod == 1) { 613 | offset = 8; 614 | } else if (mod == 2) { 615 | offset = 32; 616 | } else if (mod == 0 && rm == 5) { 617 | op->base = UD_NONE; 618 | offset = 32; 619 | } else { 620 | offset = 0; 621 | } 622 | 623 | /* Scale-Index-Base (SIB) */ 624 | if ((rm & 7) == 4) { 625 | inp_next(u); 626 | 627 | op->scale = (1 << SIB_S(inp_curr(u))) & ~1; 628 | op->index = UD_R_EAX + (SIB_I(inp_curr(u)) | (REX_X(u->pfx_rex) << 3)); 629 | op->base = UD_R_EAX + (SIB_B(inp_curr(u)) | (REX_B(u->pfx_rex) << 3)); 630 | 631 | if (op->index == UD_R_ESP) { 632 | op->index = UD_NONE; 633 | op->scale = UD_NONE; 634 | } 635 | 636 | /* special condition for base reference */ 637 | if (op->base == UD_R_EBP) { 638 | if (mod == 0) { 639 | op->base = UD_NONE; 640 | } 641 | if (mod == 1) { 642 | offset = 8; 643 | } else { 644 | offset = 32; 645 | } 646 | } 647 | } else { 648 | op->scale = UD_NONE; 649 | op->index = UD_NONE; 650 | } 651 | } else { 652 | const unsigned int bases[] = { UD_R_BX, UD_R_BX, UD_R_BP, UD_R_BP, 653 | UD_R_SI, UD_R_DI, UD_R_BP, UD_R_BX }; 654 | const unsigned int indices[] = { UD_R_SI, UD_R_DI, UD_R_SI, UD_R_DI, 655 | UD_NONE, UD_NONE, UD_NONE, UD_NONE }; 656 | op->base = bases[rm & 7]; 657 | op->index = indices[rm & 7]; 658 | op->scale = UD_NONE; 659 | if (mod == 0 && rm == 6) { 660 | offset = 16; 661 | op->base = UD_NONE; 662 | } else if (mod == 1) { 663 | offset = 8; 664 | } else if (mod == 2) { 665 | offset = 16; 666 | } 667 | } 668 | 669 | if (offset) { 670 | decode_mem_disp(u, offset, op); 671 | } else { 672 | op->offset = 0; 673 | } 674 | } 675 | 676 | 677 | /* 678 | * decode_moffset 679 | * Decode offset-only memory operand 680 | */ 681 | static void 682 | decode_moffset(struct ud *u, unsigned int size, struct ud_operand *opr) 683 | { 684 | opr->type = UD_OP_MEM; 685 | opr->base = UD_NONE; 686 | opr->index = UD_NONE; 687 | opr->scale = UD_NONE; 688 | opr->size = resolve_operand_size(u, size); 689 | decode_mem_disp(u, u->adr_mode, opr); 690 | } 691 | 692 | 693 | static void 694 | decode_vex_vvvv(struct ud *u, struct ud_operand *opr, unsigned size) 695 | { 696 | uint8_t vvvv; 697 | UD_ASSERT(u->vex_op != 0); 698 | vvvv = ((u->vex_op == 0xc4 ? u->vex_b2 : u->vex_b1) >> 3) & 0xf; 699 | decode_reg(u, opr, REGCLASS_XMM, (0xf & ~vvvv), size); 700 | } 701 | 702 | 703 | /* 704 | * decode_vex_immreg 705 | * Decode source operand encoded in immediate byte [7:4] 706 | */ 707 | static int 708 | decode_vex_immreg(struct ud *u, struct ud_operand *opr, unsigned size) 709 | { 710 | uint8_t imm = inp_next(u); 711 | uint8_t mask = u->dis_mode == 64 ? 0xf : 0x7; 712 | UD_RETURN_ON_ERROR(u); 713 | UD_ASSERT(u->vex_op != 0); 714 | decode_reg(u, opr, REGCLASS_XMM, mask & (imm >> 4), size); 715 | return 0; 716 | } 717 | 718 | 719 | /* 720 | * decode_operand 721 | * 722 | * Decodes a single operand. 723 | * Returns the type of the operand (UD_NONE if none) 724 | */ 725 | static int 726 | decode_operand(struct ud *u, 727 | struct ud_operand *operand, 728 | enum ud_operand_code type, 729 | unsigned int size) 730 | { 731 | operand->type = UD_NONE; 732 | operand->_oprcode = type; 733 | 734 | switch (type) { 735 | case OP_A : 736 | decode_a(u, operand); 737 | break; 738 | case OP_MR: 739 | decode_modrm_rm(u, operand, REGCLASS_GPR, 740 | MODRM_MOD(modrm(u)) == 3 ? 741 | Mx_reg_size(size) : Mx_mem_size(size)); 742 | break; 743 | case OP_F: 744 | u->br_far = 1; 745 | /* intended fall through */ 746 | case OP_M: 747 | if (MODRM_MOD(modrm(u)) == 3) { 748 | UDERR(u, "expected modrm.mod != 3\n"); 749 | } 750 | /* intended fall through */ 751 | case OP_E: 752 | decode_modrm_rm(u, operand, REGCLASS_GPR, size); 753 | break; 754 | case OP_G: 755 | decode_modrm_reg(u, operand, REGCLASS_GPR, size); 756 | break; 757 | case OP_sI: 758 | case OP_I: 759 | decode_imm(u, size, operand); 760 | break; 761 | case OP_I1: 762 | operand->type = UD_OP_CONST; 763 | operand->lval.udword = 1; 764 | break; 765 | case OP_N: 766 | if (MODRM_MOD(modrm(u)) != 3) { 767 | UDERR(u, "expected modrm.mod == 3\n"); 768 | } 769 | /* intended fall through */ 770 | case OP_Q: 771 | decode_modrm_rm(u, operand, REGCLASS_MMX, size); 772 | break; 773 | case OP_P: 774 | decode_modrm_reg(u, operand, REGCLASS_MMX, size); 775 | break; 776 | case OP_U: 777 | if (MODRM_MOD(modrm(u)) != 3) { 778 | UDERR(u, "expected modrm.mod == 3\n"); 779 | } 780 | /* intended fall through */ 781 | case OP_W: 782 | decode_modrm_rm(u, operand, REGCLASS_XMM, size); 783 | break; 784 | case OP_V: 785 | decode_modrm_reg(u, operand, REGCLASS_XMM, size); 786 | break; 787 | case OP_H: 788 | decode_vex_vvvv(u, operand, size); 789 | break; 790 | case OP_MU: 791 | decode_modrm_rm(u, operand, REGCLASS_XMM, 792 | MODRM_MOD(modrm(u)) == 3 ? 793 | Mx_reg_size(size) : Mx_mem_size(size)); 794 | break; 795 | case OP_S: 796 | decode_modrm_reg(u, operand, REGCLASS_SEG, size); 797 | break; 798 | case OP_O: 799 | decode_moffset(u, size, operand); 800 | break; 801 | case OP_R0: 802 | case OP_R1: 803 | case OP_R2: 804 | case OP_R3: 805 | case OP_R4: 806 | case OP_R5: 807 | case OP_R6: 808 | case OP_R7: 809 | decode_reg(u, operand, REGCLASS_GPR, 810 | (REX_B(u->_rex) << 3) | (type - OP_R0), size); 811 | break; 812 | case OP_AL: 813 | case OP_AX: 814 | case OP_eAX: 815 | case OP_rAX: 816 | decode_reg(u, operand, REGCLASS_GPR, 0, size); 817 | break; 818 | case OP_CL: 819 | case OP_CX: 820 | case OP_eCX: 821 | decode_reg(u, operand, REGCLASS_GPR, 1, size); 822 | break; 823 | case OP_DL: 824 | case OP_DX: 825 | case OP_eDX: 826 | decode_reg(u, operand, REGCLASS_GPR, 2, size); 827 | break; 828 | case OP_ES: 829 | case OP_CS: 830 | case OP_DS: 831 | case OP_SS: 832 | case OP_FS: 833 | case OP_GS: 834 | /* in 64bits mode, only fs and gs are allowed */ 835 | if (u->dis_mode == 64) { 836 | if (type != OP_FS && type != OP_GS) { 837 | UDERR(u, "invalid segment register in 64bits\n"); 838 | } 839 | } 840 | operand->type = UD_OP_REG; 841 | operand->base = (type - OP_ES) + UD_R_ES; 842 | operand->size = 16; 843 | break; 844 | case OP_J : 845 | decode_imm(u, size, operand); 846 | operand->type = UD_OP_JIMM; 847 | break ; 848 | case OP_R : 849 | if (MODRM_MOD(modrm(u)) != 3) { 850 | UDERR(u, "expected modrm.mod == 3\n"); 851 | } 852 | decode_modrm_rm(u, operand, REGCLASS_GPR, size); 853 | break; 854 | case OP_C: 855 | decode_modrm_reg(u, operand, REGCLASS_CR, size); 856 | break; 857 | case OP_D: 858 | decode_modrm_reg(u, operand, REGCLASS_DB, size); 859 | break; 860 | case OP_I3 : 861 | operand->type = UD_OP_CONST; 862 | operand->lval.sbyte = 3; 863 | break; 864 | case OP_ST0: 865 | case OP_ST1: 866 | case OP_ST2: 867 | case OP_ST3: 868 | case OP_ST4: 869 | case OP_ST5: 870 | case OP_ST6: 871 | case OP_ST7: 872 | operand->type = UD_OP_REG; 873 | operand->base = (type - OP_ST0) + UD_R_ST0; 874 | operand->size = 80; 875 | break; 876 | case OP_L: 877 | decode_vex_immreg(u, operand, size); 878 | break; 879 | default : 880 | operand->type = UD_NONE; 881 | break; 882 | } 883 | return operand->type; 884 | } 885 | 886 | 887 | /* 888 | * decode_operands 889 | * 890 | * Disassemble upto 3 operands of the current instruction being 891 | * disassembled. By the end of the function, the operand fields 892 | * of the ud structure will have been filled. 893 | */ 894 | static int 895 | decode_operands(struct ud* u) 896 | { 897 | decode_operand(u, &u->operand[0], 898 | u->itab_entry->operand1.type, 899 | u->itab_entry->operand1.size); 900 | if (u->operand[0].type != UD_NONE) { 901 | decode_operand(u, &u->operand[1], 902 | u->itab_entry->operand2.type, 903 | u->itab_entry->operand2.size); 904 | } 905 | if (u->operand[1].type != UD_NONE) { 906 | decode_operand(u, &u->operand[2], 907 | u->itab_entry->operand3.type, 908 | u->itab_entry->operand3.size); 909 | } 910 | if (u->operand[2].type != UD_NONE) { 911 | decode_operand(u, &u->operand[3], 912 | u->itab_entry->operand4.type, 913 | u->itab_entry->operand4.size); 914 | } 915 | return 0; 916 | } 917 | 918 | /* ----------------------------------------------------------------------------- 919 | * clear_insn() - clear instruction structure 920 | * ----------------------------------------------------------------------------- 921 | */ 922 | static void 923 | clear_insn(register struct ud* u) 924 | { 925 | u->error = 0; 926 | u->pfx_seg = 0; 927 | u->pfx_opr = 0; 928 | u->pfx_adr = 0; 929 | u->pfx_lock = 0; 930 | u->pfx_repne = 0; 931 | u->pfx_rep = 0; 932 | u->pfx_repe = 0; 933 | u->pfx_rex = 0; 934 | u->pfx_str = 0; 935 | u->mnemonic = UD_Inone; 936 | u->itab_entry = NULL; 937 | u->have_modrm = 0; 938 | u->br_far = 0; 939 | u->vex_op = 0; 940 | u->_rex = 0; 941 | u->operand[0].type = UD_NONE; 942 | u->operand[1].type = UD_NONE; 943 | u->operand[2].type = UD_NONE; 944 | u->operand[3].type = UD_NONE; 945 | } 946 | 947 | 948 | static inline int 949 | resolve_pfx_str(struct ud* u) 950 | { 951 | if (u->pfx_str == 0xf3) { 952 | if (P_STR(u->itab_entry->prefix)) { 953 | u->pfx_rep = 0xf3; 954 | } else { 955 | u->pfx_repe = 0xf3; 956 | } 957 | } else if (u->pfx_str == 0xf2) { 958 | u->pfx_repne = 0xf3; 959 | } 960 | return 0; 961 | } 962 | 963 | 964 | static int 965 | resolve_mode( struct ud* u ) 966 | { 967 | int default64; 968 | /* if in error state, bail out */ 969 | if ( u->error ) return -1; 970 | 971 | /* propagate prefix effects */ 972 | if ( u->dis_mode == 64 ) { /* set 64bit-mode flags */ 973 | 974 | /* Check validity of instruction m64 */ 975 | if ( P_INV64( u->itab_entry->prefix ) ) { 976 | UDERR(u, "instruction invalid in 64bits\n"); 977 | return -1; 978 | } 979 | 980 | /* compute effective rex based on, 981 | * - vex prefix (if any) 982 | * - rex prefix (if any, and not vex) 983 | * - allowed prefixes specified by the opcode map 984 | */ 985 | if (u->vex_op == 0xc4) { 986 | /* vex has rex.rxb in 1's complement */ 987 | u->_rex = ((~(u->vex_b1 >> 5) & 0x7) /* rex.0rxb */ | 988 | ((u->vex_b2 >> 4) & 0x8) /* rex.w000 */); 989 | } else if (u->vex_op == 0xc5) { 990 | /* vex has rex.r in 1's complement */ 991 | u->_rex = (~(u->vex_b1 >> 5)) & 4; 992 | } else { 993 | UD_ASSERT(u->vex_op == 0); 994 | u->_rex = u->pfx_rex; 995 | } 996 | u->_rex &= REX_PFX_MASK(u->itab_entry->prefix); 997 | 998 | /* whether this instruction has a default operand size of 999 | * 64bit, also hardcoded into the opcode map. 1000 | */ 1001 | default64 = P_DEF64( u->itab_entry->prefix ); 1002 | /* calculate effective operand size */ 1003 | if (REX_W(u->_rex)) { 1004 | u->opr_mode = 64; 1005 | } else if ( u->pfx_opr ) { 1006 | u->opr_mode = 16; 1007 | } else { 1008 | /* unless the default opr size of instruction is 64, 1009 | * the effective operand size in the absence of rex.w 1010 | * prefix is 32. 1011 | */ 1012 | u->opr_mode = default64 ? 64 : 32; 1013 | } 1014 | 1015 | /* calculate effective address size */ 1016 | u->adr_mode = (u->pfx_adr) ? 32 : 64; 1017 | } else if ( u->dis_mode == 32 ) { /* set 32bit-mode flags */ 1018 | u->opr_mode = ( u->pfx_opr ) ? 16 : 32; 1019 | u->adr_mode = ( u->pfx_adr ) ? 16 : 32; 1020 | } else if ( u->dis_mode == 16 ) { /* set 16bit-mode flags */ 1021 | u->opr_mode = ( u->pfx_opr ) ? 32 : 16; 1022 | u->adr_mode = ( u->pfx_adr ) ? 32 : 16; 1023 | } 1024 | 1025 | return 0; 1026 | } 1027 | 1028 | 1029 | static inline int 1030 | decode_insn(struct ud *u, uint16_t ptr) 1031 | { 1032 | UD_ASSERT((ptr & 0x8000) == 0); 1033 | u->itab_entry = &ud_itab[ ptr ]; 1034 | u->mnemonic = u->itab_entry->mnemonic; 1035 | return (resolve_pfx_str(u) == 0 && 1036 | resolve_mode(u) == 0 && 1037 | decode_operands(u) == 0 && 1038 | resolve_mnemonic(u) == 0) ? 0 : -1; 1039 | } 1040 | 1041 | 1042 | /* 1043 | * decode_3dnow() 1044 | * 1045 | * Decoding 3dnow is a little tricky because of its strange opcode 1046 | * structure. The final opcode disambiguation depends on the last 1047 | * byte that comes after the operands have been decoded. Fortunately, 1048 | * all 3dnow instructions have the same set of operand types. So we 1049 | * go ahead and decode the instruction by picking an arbitrarily chosen 1050 | * valid entry in the table, decode the operands, and read the final 1051 | * byte to resolve the menmonic. 1052 | */ 1053 | static inline int 1054 | decode_3dnow(struct ud* u) 1055 | { 1056 | uint16_t ptr; 1057 | UD_ASSERT(u->le->type == UD_TAB__OPC_3DNOW); 1058 | UD_ASSERT(u->le->table[0xc] != 0); 1059 | decode_insn(u, u->le->table[0xc]); 1060 | inp_next(u); 1061 | if (u->error) { 1062 | return -1; 1063 | } 1064 | ptr = u->le->table[inp_curr(u)]; 1065 | UD_ASSERT((ptr & 0x8000) == 0); 1066 | u->mnemonic = ud_itab[ptr].mnemonic; 1067 | return 0; 1068 | } 1069 | 1070 | 1071 | static int 1072 | decode_ssepfx(struct ud *u) 1073 | { 1074 | uint8_t idx; 1075 | uint8_t pfx; 1076 | 1077 | /* 1078 | * String prefixes (f2, f3) take precedence over operand 1079 | * size prefix (66). 1080 | */ 1081 | pfx = u->pfx_str; 1082 | if (pfx == 0) { 1083 | pfx = u->pfx_opr; 1084 | } 1085 | idx = ((pfx & 0xf) + 1) / 2; 1086 | if (u->le->table[idx] == 0) { 1087 | idx = 0; 1088 | } 1089 | if (idx && u->le->table[idx] != 0) { 1090 | /* 1091 | * "Consume" the prefix as a part of the opcode, so it is no 1092 | * longer exported as an instruction prefix. 1093 | */ 1094 | u->pfx_str = 0; 1095 | if (pfx == 0x66) { 1096 | /* 1097 | * consume "66" only if it was used for decoding, leaving 1098 | * it to be used as an operands size override for some 1099 | * simd instructions. 1100 | */ 1101 | u->pfx_opr = 0; 1102 | } 1103 | } 1104 | return decode_ext(u, u->le->table[idx]); 1105 | } 1106 | 1107 | 1108 | static int 1109 | decode_vex(struct ud *u) 1110 | { 1111 | uint8_t index; 1112 | if (u->dis_mode != 64 && MODRM_MOD(inp_peek(u)) != 0x3) { 1113 | index = 0; 1114 | } else { 1115 | u->vex_op = inp_curr(u); 1116 | u->vex_b1 = inp_next(u); 1117 | if (u->vex_op == 0xc4) { 1118 | uint8_t pp, m; 1119 | /* 3-byte vex */ 1120 | u->vex_b2 = inp_next(u); 1121 | UD_RETURN_ON_ERROR(u); 1122 | m = u->vex_b1 & 0x1f; 1123 | if (m == 0 || m > 3) { 1124 | UD_RETURN_WITH_ERROR(u, "reserved vex.m-mmmm value"); 1125 | } 1126 | pp = u->vex_b2 & 0x3; 1127 | index = (pp << 2) | m; 1128 | } else { 1129 | /* 2-byte vex */ 1130 | UD_ASSERT(u->vex_op == 0xc5); 1131 | index = 0x1 | ((u->vex_b1 & 0x3) << 2); 1132 | } 1133 | } 1134 | return decode_ext(u, u->le->table[index]); 1135 | } 1136 | 1137 | 1138 | /* 1139 | * decode_ext() 1140 | * 1141 | * Decode opcode extensions (if any) 1142 | */ 1143 | static int 1144 | decode_ext(struct ud *u, uint16_t ptr) 1145 | { 1146 | uint8_t idx = 0; 1147 | if ((ptr & 0x8000) == 0) { 1148 | return decode_insn(u, ptr); 1149 | } 1150 | u->le = &ud_lookup_table_list[(~0x8000 & ptr)]; 1151 | if (u->le->type == UD_TAB__OPC_3DNOW) { 1152 | return decode_3dnow(u); 1153 | } 1154 | 1155 | switch (u->le->type) { 1156 | case UD_TAB__OPC_MOD: 1157 | /* !11 = 0, 11 = 1 */ 1158 | idx = (MODRM_MOD(modrm(u)) + 1) / 4; 1159 | break; 1160 | /* disassembly mode/operand size/address size based tables. 1161 | * 16 = 0,, 32 = 1, 64 = 2 1162 | */ 1163 | case UD_TAB__OPC_MODE: 1164 | idx = u->dis_mode != 64 ? 0 : 1; 1165 | break; 1166 | case UD_TAB__OPC_OSIZE: 1167 | idx = eff_opr_mode(u->dis_mode, REX_W(u->pfx_rex), u->pfx_opr) / 32; 1168 | break; 1169 | case UD_TAB__OPC_ASIZE: 1170 | idx = eff_adr_mode(u->dis_mode, u->pfx_adr) / 32; 1171 | break; 1172 | case UD_TAB__OPC_X87: 1173 | idx = modrm(u) - 0xC0; 1174 | break; 1175 | case UD_TAB__OPC_VENDOR: 1176 | if (u->vendor == UD_VENDOR_ANY) { 1177 | /* choose a valid entry */ 1178 | idx = (u->le->table[idx] != 0) ? 0 : 1; 1179 | } else if (u->vendor == UD_VENDOR_AMD) { 1180 | idx = 0; 1181 | } else { 1182 | idx = 1; 1183 | } 1184 | break; 1185 | case UD_TAB__OPC_RM: 1186 | idx = MODRM_RM(modrm(u)); 1187 | break; 1188 | case UD_TAB__OPC_REG: 1189 | idx = MODRM_REG(modrm(u)); 1190 | break; 1191 | case UD_TAB__OPC_SSE: 1192 | return decode_ssepfx(u); 1193 | case UD_TAB__OPC_VEX: 1194 | return decode_vex(u); 1195 | case UD_TAB__OPC_VEX_W: 1196 | idx = vex_w(u); 1197 | break; 1198 | case UD_TAB__OPC_VEX_L: 1199 | idx = vex_l(u); 1200 | break; 1201 | case UD_TAB__OPC_TABLE: 1202 | inp_next(u); 1203 | return decode_opcode(u); 1204 | default: 1205 | UD_ASSERT(!"not reached"); 1206 | break; 1207 | } 1208 | 1209 | return decode_ext(u, u->le->table[idx]); 1210 | } 1211 | 1212 | 1213 | static int 1214 | decode_opcode(struct ud *u) 1215 | { 1216 | uint16_t ptr; 1217 | UD_ASSERT(u->le->type == UD_TAB__OPC_TABLE); 1218 | UD_RETURN_ON_ERROR(u); 1219 | ptr = u->le->table[inp_curr(u)]; 1220 | return decode_ext(u, ptr); 1221 | } 1222 | 1223 | 1224 | /* ============================================================================= 1225 | * ud_decode() - Instruction decoder. Returns the number of bytes decoded. 1226 | * ============================================================================= 1227 | */ 1228 | unsigned int 1229 | ud_decode(struct ud *u) 1230 | { 1231 | inp_start(u); 1232 | clear_insn(u); 1233 | u->le = &ud_lookup_table_list[0]; 1234 | u->error = decode_prefixes(u) == -1 || 1235 | decode_opcode(u) == -1 || 1236 | u->error; 1237 | /* Handle decode error. */ 1238 | if (u->error) { 1239 | /* clear out the decode data. */ 1240 | clear_insn(u); 1241 | /* mark the sequence of bytes as invalid. */ 1242 | u->itab_entry = &ud_itab[0]; /* entry 0 is invalid */ 1243 | u->mnemonic = u->itab_entry->mnemonic; 1244 | } 1245 | 1246 | /* maybe this stray segment override byte 1247 | * should be spewed out? 1248 | */ 1249 | if ( !P_SEG( u->itab_entry->prefix ) && 1250 | u->operand[0].type != UD_OP_MEM && 1251 | u->operand[1].type != UD_OP_MEM ) 1252 | u->pfx_seg = 0; 1253 | 1254 | u->insn_offset = u->pc; /* set offset of instruction */ 1255 | u->asm_buf_fill = 0; /* set translation buffer index to 0 */ 1256 | u->pc += u->inp_ctr; /* move program counter by bytes decoded */ 1257 | 1258 | /* return number of bytes disassembled. */ 1259 | return u->inp_ctr; 1260 | } 1261 | 1262 | /* 1263 | vim: set ts=2 sw=2 expandtab 1264 | */ 1265 | -------------------------------------------------------------------------------- /libudis86/decode.h: -------------------------------------------------------------------------------- 1 | /* udis86 - libudis86/decode.h 2 | * 3 | * Copyright (c) 2002-2009 Vivek Thampi 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 19 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 22 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | #ifndef UD_DECODE_H 27 | #define UD_DECODE_H 28 | 29 | #include "types.h" 30 | #include "itab.h" 31 | 32 | #define MAX_INSN_LENGTH 15 33 | 34 | /* itab prefix bits */ 35 | #define P_none ( 0 ) 36 | 37 | #define P_inv64 ( 1 << 0 ) 38 | #define P_INV64(n) ( ( n >> 0 ) & 1 ) 39 | #define P_def64 ( 1 << 1 ) 40 | #define P_DEF64(n) ( ( n >> 1 ) & 1 ) 41 | 42 | #define P_oso ( 1 << 2 ) 43 | #define P_OSO(n) ( ( n >> 2 ) & 1 ) 44 | #define P_aso ( 1 << 3 ) 45 | #define P_ASO(n) ( ( n >> 3 ) & 1 ) 46 | 47 | #define P_rexb ( 1 << 4 ) 48 | #define P_REXB(n) ( ( n >> 4 ) & 1 ) 49 | #define P_rexw ( 1 << 5 ) 50 | #define P_REXW(n) ( ( n >> 5 ) & 1 ) 51 | #define P_rexr ( 1 << 6 ) 52 | #define P_REXR(n) ( ( n >> 6 ) & 1 ) 53 | #define P_rexx ( 1 << 7 ) 54 | #define P_REXX(n) ( ( n >> 7 ) & 1 ) 55 | 56 | #define P_seg ( 1 << 8 ) 57 | #define P_SEG(n) ( ( n >> 8 ) & 1 ) 58 | 59 | #define P_vexl ( 1 << 9 ) 60 | #define P_VEXL(n) ( ( n >> 9 ) & 1 ) 61 | #define P_vexw ( 1 << 10 ) 62 | #define P_VEXW(n) ( ( n >> 10 ) & 1 ) 63 | 64 | #define P_str ( 1 << 11 ) 65 | #define P_STR(n) ( ( n >> 11 ) & 1 ) 66 | #define P_strz ( 1 << 12 ) 67 | #define P_STR_ZF(n) ( ( n >> 12 ) & 1 ) 68 | 69 | /* operand type constants -- order is important! */ 70 | 71 | enum ud_operand_code { 72 | OP_NONE, 73 | 74 | OP_A, OP_E, OP_M, OP_G, 75 | OP_I, OP_F, 76 | 77 | OP_R0, OP_R1, OP_R2, OP_R3, 78 | OP_R4, OP_R5, OP_R6, OP_R7, 79 | 80 | OP_AL, OP_CL, OP_DL, 81 | OP_AX, OP_CX, OP_DX, 82 | OP_eAX, OP_eCX, OP_eDX, 83 | OP_rAX, OP_rCX, OP_rDX, 84 | 85 | OP_ES, OP_CS, OP_SS, OP_DS, 86 | OP_FS, OP_GS, 87 | 88 | OP_ST0, OP_ST1, OP_ST2, OP_ST3, 89 | OP_ST4, OP_ST5, OP_ST6, OP_ST7, 90 | 91 | OP_J, OP_S, OP_O, 92 | OP_I1, OP_I3, OP_sI, 93 | 94 | OP_V, OP_W, OP_Q, OP_P, 95 | OP_U, OP_N, OP_MU, OP_H, 96 | OP_L, 97 | 98 | OP_R, OP_C, OP_D, 99 | 100 | OP_MR 101 | } UD_ATTR_PACKED; 102 | 103 | 104 | /* operand size constants */ 105 | 106 | enum ud_operand_size { 107 | SZ_NA = 0, 108 | SZ_Z = 1, 109 | SZ_V = 2, 110 | SZ_RDQ = 7, 111 | 112 | /* the following values are used as is, 113 | * and thus hard-coded. changing them 114 | * will break internals 115 | */ 116 | SZ_B = 8, 117 | SZ_W = 16, 118 | SZ_D = 32, 119 | SZ_Q = 64, 120 | SZ_T = 80, 121 | SZ_O = 128, 122 | SZ_DQ = 128, /* double quad */ 123 | SZ_QQ = 256, /* quad quad */ 124 | 125 | SZ_Y = 17, 126 | SZ_X = 18, 127 | 128 | /* 129 | * complex size types, that encode sizes for operands 130 | * of type MR (memory or register), for internal use 131 | * only. Id space 256 and above. 132 | */ 133 | SZ_BD = (SZ_B << 8) | SZ_D, 134 | SZ_BV = (SZ_B << 8) | SZ_V, 135 | SZ_WD = (SZ_W << 8) | SZ_D, 136 | SZ_WV = (SZ_W << 8) | SZ_V, 137 | SZ_WY = (SZ_W << 8) | SZ_Y, 138 | SZ_DY = (SZ_D << 8) | SZ_Y, 139 | SZ_WO = (SZ_W << 8) | SZ_O, 140 | SZ_DO = (SZ_D << 8) | SZ_O, 141 | SZ_QO = (SZ_Q << 8) | SZ_O, 142 | 143 | } UD_ATTR_PACKED; 144 | 145 | 146 | /* resolve complex size type. 147 | */ 148 | static inline enum ud_operand_size 149 | Mx_mem_size(enum ud_operand_size size) 150 | { 151 | return (size >> 8) & 0xff; 152 | } 153 | 154 | static inline enum ud_operand_size 155 | Mx_reg_size(enum ud_operand_size size) 156 | { 157 | return size & 0xff; 158 | } 159 | 160 | /* A single operand of an entry in the instruction table. 161 | * (internal use only) 162 | */ 163 | struct ud_itab_entry_operand 164 | { 165 | enum ud_operand_code type; 166 | enum ud_operand_size size; 167 | }; 168 | 169 | 170 | /* A single entry in an instruction table. 171 | *(internal use only) 172 | */ 173 | struct ud_itab_entry 174 | { 175 | enum ud_mnemonic_code mnemonic; 176 | struct ud_itab_entry_operand operand1; 177 | struct ud_itab_entry_operand operand2; 178 | struct ud_itab_entry_operand operand3; 179 | struct ud_itab_entry_operand operand4; 180 | uint32_t prefix; 181 | }; 182 | 183 | struct ud_lookup_table_list_entry { 184 | const uint16_t *table; 185 | enum ud_table_type type; 186 | const char *meta; 187 | }; 188 | 189 | extern struct ud_itab_entry ud_itab[]; 190 | extern struct ud_lookup_table_list_entry ud_lookup_table_list[]; 191 | 192 | #endif /* UD_DECODE_H */ 193 | 194 | /* vim:cindent 195 | * vim:expandtab 196 | * vim:ts=4 197 | * vim:sw=4 198 | */ 199 | -------------------------------------------------------------------------------- /libudis86/extern.h: -------------------------------------------------------------------------------- 1 | /* udis86 - libudis86/extern.h 2 | * 3 | * Copyright (c) 2002-2009, 2013 Vivek Thampi 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 19 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 22 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | #ifndef UD_EXTERN_H 27 | #define UD_EXTERN_H 28 | 29 | #ifdef __cplusplus 30 | extern "C" { 31 | #endif 32 | 33 | #include "types.h" 34 | 35 | /* ============================= PUBLIC API ================================= */ 36 | 37 | extern void ud_init(struct ud*); 38 | 39 | extern void ud_initialize(struct ud*, uint8_t, 40 | unsigned, const uint8_t*, size_t); 41 | 42 | extern void ud_set_mode(struct ud*, uint8_t); 43 | 44 | extern void ud_set_pc(struct ud*, uint64_t); 45 | 46 | extern void ud_set_input_hook(struct ud*, int (*)(struct ud*)); 47 | 48 | extern void ud_set_input_buffer(struct ud*, const uint8_t*, size_t); 49 | 50 | #ifndef __UD_STANDALONE__ 51 | extern void ud_set_input_file(struct ud*, FILE*); 52 | #endif /* __UD_STANDALONE__ */ 53 | 54 | extern void ud_set_vendor(struct ud*, unsigned); 55 | 56 | extern void ud_set_syntax(struct ud*, void (*)(struct ud*)); 57 | 58 | extern void ud_input_skip(struct ud*, size_t); 59 | 60 | extern int ud_input_end(const struct ud*); 61 | 62 | extern unsigned int ud_decode(struct ud*); 63 | 64 | extern unsigned int ud_disassemble(struct ud*); 65 | 66 | extern void ud_translate_intel(struct ud*); 67 | 68 | extern void ud_translate_att(struct ud*); 69 | 70 | extern const char* ud_insn_asm(const struct ud* u); 71 | 72 | extern const uint8_t* ud_insn_ptr(const struct ud* u); 73 | 74 | extern uint64_t ud_insn_off(const struct ud*); 75 | 76 | extern const char* ud_insn_hex(struct ud*); 77 | 78 | extern unsigned int ud_insn_len(const struct ud* u); 79 | 80 | extern const struct ud_operand* ud_insn_opr(const struct ud *u, unsigned int n); 81 | 82 | extern int ud_opr_is_sreg(const struct ud_operand *opr); 83 | 84 | extern int ud_opr_is_gpr(const struct ud_operand *opr); 85 | 86 | extern enum ud_mnemonic_code ud_insn_mnemonic(const struct ud *u); 87 | 88 | extern const char* ud_lookup_mnemonic(enum ud_mnemonic_code c); 89 | 90 | extern void ud_set_user_opaque_data(struct ud*, void*); 91 | 92 | extern void* ud_get_user_opaque_data(const struct ud*); 93 | 94 | extern uint64_t ud_insn_sext_imm(const struct ud*, const struct ud_operand*); 95 | 96 | extern void ud_set_asm_buffer(struct ud *u, char *buf, size_t size); 97 | 98 | extern void ud_set_sym_resolver(struct ud *u, 99 | const char* (*resolver)(struct ud*, 100 | uint64_t addr, 101 | int64_t *offset)); 102 | 103 | /* ========================================================================== */ 104 | 105 | #ifdef __cplusplus 106 | } 107 | #endif 108 | #endif /* UD_EXTERN_H */ 109 | -------------------------------------------------------------------------------- /libudis86/itab.h: -------------------------------------------------------------------------------- 1 | #ifndef UD_ITAB_H 2 | #define UD_ITAB_H 3 | 4 | /* itab.h -- generated by udis86:scripts/ud_itab.py, do no edit */ 5 | 6 | /* ud_table_type -- lookup table types (see decode.c) */ 7 | enum ud_table_type { 8 | UD_TAB__OPC_VEX, 9 | UD_TAB__OPC_TABLE, 10 | UD_TAB__OPC_X87, 11 | UD_TAB__OPC_MOD, 12 | UD_TAB__OPC_RM, 13 | UD_TAB__OPC_OSIZE, 14 | UD_TAB__OPC_MODE, 15 | UD_TAB__OPC_VEX_L, 16 | UD_TAB__OPC_3DNOW, 17 | UD_TAB__OPC_REG, 18 | UD_TAB__OPC_ASIZE, 19 | UD_TAB__OPC_VEX_W, 20 | UD_TAB__OPC_SSE, 21 | UD_TAB__OPC_VENDOR 22 | }; 23 | 24 | /* ud_mnemonic -- mnemonic constants */ 25 | enum ud_mnemonic_code { 26 | UD_Iaaa, 27 | UD_Iaad, 28 | UD_Iaam, 29 | UD_Iaas, 30 | UD_Iadc, 31 | UD_Iadd, 32 | UD_Iaddpd, 33 | UD_Iaddps, 34 | UD_Iaddsd, 35 | UD_Iaddss, 36 | UD_Iaddsubpd, 37 | UD_Iaddsubps, 38 | UD_Iaesdec, 39 | UD_Iaesdeclast, 40 | UD_Iaesenc, 41 | UD_Iaesenclast, 42 | UD_Iaesimc, 43 | UD_Iaeskeygenassist, 44 | UD_Iand, 45 | UD_Iandnpd, 46 | UD_Iandnps, 47 | UD_Iandpd, 48 | UD_Iandps, 49 | UD_Iarpl, 50 | UD_Iblendpd, 51 | UD_Iblendps, 52 | UD_Iblendvpd, 53 | UD_Iblendvps, 54 | UD_Ibound, 55 | UD_Ibsf, 56 | UD_Ibsr, 57 | UD_Ibswap, 58 | UD_Ibt, 59 | UD_Ibtc, 60 | UD_Ibtr, 61 | UD_Ibts, 62 | UD_Icall, 63 | UD_Icbw, 64 | UD_Icdq, 65 | UD_Icdqe, 66 | UD_Iclc, 67 | UD_Icld, 68 | UD_Iclflush, 69 | UD_Iclgi, 70 | UD_Icli, 71 | UD_Iclts, 72 | UD_Icmc, 73 | UD_Icmova, 74 | UD_Icmovae, 75 | UD_Icmovb, 76 | UD_Icmovbe, 77 | UD_Icmovg, 78 | UD_Icmovge, 79 | UD_Icmovl, 80 | UD_Icmovle, 81 | UD_Icmovno, 82 | UD_Icmovnp, 83 | UD_Icmovns, 84 | UD_Icmovnz, 85 | UD_Icmovo, 86 | UD_Icmovp, 87 | UD_Icmovs, 88 | UD_Icmovz, 89 | UD_Icmp, 90 | UD_Icmppd, 91 | UD_Icmpps, 92 | UD_Icmpsb, 93 | UD_Icmpsd, 94 | UD_Icmpsq, 95 | UD_Icmpss, 96 | UD_Icmpsw, 97 | UD_Icmpxchg, 98 | UD_Icmpxchg16b, 99 | UD_Icmpxchg8b, 100 | UD_Icomisd, 101 | UD_Icomiss, 102 | UD_Icpuid, 103 | UD_Icqo, 104 | UD_Icrc32, 105 | UD_Icvtdq2pd, 106 | UD_Icvtdq2ps, 107 | UD_Icvtpd2dq, 108 | UD_Icvtpd2pi, 109 | UD_Icvtpd2ps, 110 | UD_Icvtpi2pd, 111 | UD_Icvtpi2ps, 112 | UD_Icvtps2dq, 113 | UD_Icvtps2pd, 114 | UD_Icvtps2pi, 115 | UD_Icvtsd2si, 116 | UD_Icvtsd2ss, 117 | UD_Icvtsi2sd, 118 | UD_Icvtsi2ss, 119 | UD_Icvtss2sd, 120 | UD_Icvtss2si, 121 | UD_Icvttpd2dq, 122 | UD_Icvttpd2pi, 123 | UD_Icvttps2dq, 124 | UD_Icvttps2pi, 125 | UD_Icvttsd2si, 126 | UD_Icvttss2si, 127 | UD_Icwd, 128 | UD_Icwde, 129 | UD_Idaa, 130 | UD_Idas, 131 | UD_Idec, 132 | UD_Idiv, 133 | UD_Idivpd, 134 | UD_Idivps, 135 | UD_Idivsd, 136 | UD_Idivss, 137 | UD_Idppd, 138 | UD_Idpps, 139 | UD_Iemms, 140 | UD_Ienter, 141 | UD_Iextractps, 142 | UD_If2xm1, 143 | UD_Ifabs, 144 | UD_Ifadd, 145 | UD_Ifaddp, 146 | UD_Ifbld, 147 | UD_Ifbstp, 148 | UD_Ifchs, 149 | UD_Ifclex, 150 | UD_Ifcmovb, 151 | UD_Ifcmovbe, 152 | UD_Ifcmove, 153 | UD_Ifcmovnb, 154 | UD_Ifcmovnbe, 155 | UD_Ifcmovne, 156 | UD_Ifcmovnu, 157 | UD_Ifcmovu, 158 | UD_Ifcom, 159 | UD_Ifcom2, 160 | UD_Ifcomi, 161 | UD_Ifcomip, 162 | UD_Ifcomp, 163 | UD_Ifcomp3, 164 | UD_Ifcomp5, 165 | UD_Ifcompp, 166 | UD_Ifcos, 167 | UD_Ifdecstp, 168 | UD_Ifdiv, 169 | UD_Ifdivp, 170 | UD_Ifdivr, 171 | UD_Ifdivrp, 172 | UD_Ifemms, 173 | UD_Iffree, 174 | UD_Iffreep, 175 | UD_Ifiadd, 176 | UD_Ificom, 177 | UD_Ificomp, 178 | UD_Ifidiv, 179 | UD_Ifidivr, 180 | UD_Ifild, 181 | UD_Ifimul, 182 | UD_Ifincstp, 183 | UD_Ifist, 184 | UD_Ifistp, 185 | UD_Ifisttp, 186 | UD_Ifisub, 187 | UD_Ifisubr, 188 | UD_Ifld, 189 | UD_Ifld1, 190 | UD_Ifldcw, 191 | UD_Ifldenv, 192 | UD_Ifldl2e, 193 | UD_Ifldl2t, 194 | UD_Ifldlg2, 195 | UD_Ifldln2, 196 | UD_Ifldpi, 197 | UD_Ifldz, 198 | UD_Ifmul, 199 | UD_Ifmulp, 200 | UD_Ifninit, 201 | UD_Ifnop, 202 | UD_Ifnsave, 203 | UD_Ifnstcw, 204 | UD_Ifnstenv, 205 | UD_Ifnstsw, 206 | UD_Ifpatan, 207 | UD_Ifprem, 208 | UD_Ifprem1, 209 | UD_Ifptan, 210 | UD_Ifrndint, 211 | UD_Ifrstor, 212 | UD_Ifscale, 213 | UD_Ifsin, 214 | UD_Ifsincos, 215 | UD_Ifsqrt, 216 | UD_Ifst, 217 | UD_Ifstp, 218 | UD_Ifstp1, 219 | UD_Ifstp8, 220 | UD_Ifstp9, 221 | UD_Ifsub, 222 | UD_Ifsubp, 223 | UD_Ifsubr, 224 | UD_Ifsubrp, 225 | UD_Iftst, 226 | UD_Ifucom, 227 | UD_Ifucomi, 228 | UD_Ifucomip, 229 | UD_Ifucomp, 230 | UD_Ifucompp, 231 | UD_Ifxam, 232 | UD_Ifxch, 233 | UD_Ifxch4, 234 | UD_Ifxch7, 235 | UD_Ifxrstor, 236 | UD_Ifxsave, 237 | UD_Ifxtract, 238 | UD_Ifyl2x, 239 | UD_Ifyl2xp1, 240 | UD_Igetsec, 241 | UD_Ihaddpd, 242 | UD_Ihaddps, 243 | UD_Ihlt, 244 | UD_Ihsubpd, 245 | UD_Ihsubps, 246 | UD_Iidiv, 247 | UD_Iimul, 248 | UD_Iin, 249 | UD_Iinc, 250 | UD_Iinsb, 251 | UD_Iinsd, 252 | UD_Iinsertps, 253 | UD_Iinsw, 254 | UD_Iint, 255 | UD_Iint1, 256 | UD_Iint3, 257 | UD_Iinto, 258 | UD_Iinvd, 259 | UD_Iinvept, 260 | UD_Iinvlpg, 261 | UD_Iinvlpga, 262 | UD_Iinvvpid, 263 | UD_Iiretd, 264 | UD_Iiretq, 265 | UD_Iiretw, 266 | UD_Ija, 267 | UD_Ijae, 268 | UD_Ijb, 269 | UD_Ijbe, 270 | UD_Ijcxz, 271 | UD_Ijecxz, 272 | UD_Ijg, 273 | UD_Ijge, 274 | UD_Ijl, 275 | UD_Ijle, 276 | UD_Ijmp, 277 | UD_Ijno, 278 | UD_Ijnp, 279 | UD_Ijns, 280 | UD_Ijnz, 281 | UD_Ijo, 282 | UD_Ijp, 283 | UD_Ijrcxz, 284 | UD_Ijs, 285 | UD_Ijz, 286 | UD_Ilahf, 287 | UD_Ilar, 288 | UD_Ilddqu, 289 | UD_Ildmxcsr, 290 | UD_Ilds, 291 | UD_Ilea, 292 | UD_Ileave, 293 | UD_Iles, 294 | UD_Ilfence, 295 | UD_Ilfs, 296 | UD_Ilgdt, 297 | UD_Ilgs, 298 | UD_Ilidt, 299 | UD_Illdt, 300 | UD_Ilmsw, 301 | UD_Ilock, 302 | UD_Ilodsb, 303 | UD_Ilodsd, 304 | UD_Ilodsq, 305 | UD_Ilodsw, 306 | UD_Iloop, 307 | UD_Iloope, 308 | UD_Iloopne, 309 | UD_Ilsl, 310 | UD_Ilss, 311 | UD_Iltr, 312 | UD_Imaskmovdqu, 313 | UD_Imaskmovq, 314 | UD_Imaxpd, 315 | UD_Imaxps, 316 | UD_Imaxsd, 317 | UD_Imaxss, 318 | UD_Imfence, 319 | UD_Iminpd, 320 | UD_Iminps, 321 | UD_Iminsd, 322 | UD_Iminss, 323 | UD_Imonitor, 324 | UD_Imontmul, 325 | UD_Imov, 326 | UD_Imovapd, 327 | UD_Imovaps, 328 | UD_Imovbe, 329 | UD_Imovd, 330 | UD_Imovddup, 331 | UD_Imovdq2q, 332 | UD_Imovdqa, 333 | UD_Imovdqu, 334 | UD_Imovhlps, 335 | UD_Imovhpd, 336 | UD_Imovhps, 337 | UD_Imovlhps, 338 | UD_Imovlpd, 339 | UD_Imovlps, 340 | UD_Imovmskpd, 341 | UD_Imovmskps, 342 | UD_Imovntdq, 343 | UD_Imovntdqa, 344 | UD_Imovnti, 345 | UD_Imovntpd, 346 | UD_Imovntps, 347 | UD_Imovntq, 348 | UD_Imovq, 349 | UD_Imovq2dq, 350 | UD_Imovsb, 351 | UD_Imovsd, 352 | UD_Imovshdup, 353 | UD_Imovsldup, 354 | UD_Imovsq, 355 | UD_Imovss, 356 | UD_Imovsw, 357 | UD_Imovsx, 358 | UD_Imovsxd, 359 | UD_Imovupd, 360 | UD_Imovups, 361 | UD_Imovzx, 362 | UD_Impsadbw, 363 | UD_Imul, 364 | UD_Imulpd, 365 | UD_Imulps, 366 | UD_Imulsd, 367 | UD_Imulss, 368 | UD_Imwait, 369 | UD_Ineg, 370 | UD_Inop, 371 | UD_Inot, 372 | UD_Ior, 373 | UD_Iorpd, 374 | UD_Iorps, 375 | UD_Iout, 376 | UD_Ioutsb, 377 | UD_Ioutsd, 378 | UD_Ioutsw, 379 | UD_Ipabsb, 380 | UD_Ipabsd, 381 | UD_Ipabsw, 382 | UD_Ipackssdw, 383 | UD_Ipacksswb, 384 | UD_Ipackusdw, 385 | UD_Ipackuswb, 386 | UD_Ipaddb, 387 | UD_Ipaddd, 388 | UD_Ipaddq, 389 | UD_Ipaddsb, 390 | UD_Ipaddsw, 391 | UD_Ipaddusb, 392 | UD_Ipaddusw, 393 | UD_Ipaddw, 394 | UD_Ipalignr, 395 | UD_Ipand, 396 | UD_Ipandn, 397 | UD_Ipavgb, 398 | UD_Ipavgusb, 399 | UD_Ipavgw, 400 | UD_Ipblendvb, 401 | UD_Ipblendw, 402 | UD_Ipclmulqdq, 403 | UD_Ipcmpeqb, 404 | UD_Ipcmpeqd, 405 | UD_Ipcmpeqq, 406 | UD_Ipcmpeqw, 407 | UD_Ipcmpestri, 408 | UD_Ipcmpestrm, 409 | UD_Ipcmpgtb, 410 | UD_Ipcmpgtd, 411 | UD_Ipcmpgtq, 412 | UD_Ipcmpgtw, 413 | UD_Ipcmpistri, 414 | UD_Ipcmpistrm, 415 | UD_Ipextrb, 416 | UD_Ipextrd, 417 | UD_Ipextrq, 418 | UD_Ipextrw, 419 | UD_Ipf2id, 420 | UD_Ipf2iw, 421 | UD_Ipfacc, 422 | UD_Ipfadd, 423 | UD_Ipfcmpeq, 424 | UD_Ipfcmpge, 425 | UD_Ipfcmpgt, 426 | UD_Ipfmax, 427 | UD_Ipfmin, 428 | UD_Ipfmul, 429 | UD_Ipfnacc, 430 | UD_Ipfpnacc, 431 | UD_Ipfrcp, 432 | UD_Ipfrcpit1, 433 | UD_Ipfrcpit2, 434 | UD_Ipfrsqit1, 435 | UD_Ipfrsqrt, 436 | UD_Ipfsub, 437 | UD_Ipfsubr, 438 | UD_Iphaddd, 439 | UD_Iphaddsw, 440 | UD_Iphaddw, 441 | UD_Iphminposuw, 442 | UD_Iphsubd, 443 | UD_Iphsubsw, 444 | UD_Iphsubw, 445 | UD_Ipi2fd, 446 | UD_Ipi2fw, 447 | UD_Ipinsrb, 448 | UD_Ipinsrd, 449 | UD_Ipinsrq, 450 | UD_Ipinsrw, 451 | UD_Ipmaddubsw, 452 | UD_Ipmaddwd, 453 | UD_Ipmaxsb, 454 | UD_Ipmaxsd, 455 | UD_Ipmaxsw, 456 | UD_Ipmaxub, 457 | UD_Ipmaxud, 458 | UD_Ipmaxuw, 459 | UD_Ipminsb, 460 | UD_Ipminsd, 461 | UD_Ipminsw, 462 | UD_Ipminub, 463 | UD_Ipminud, 464 | UD_Ipminuw, 465 | UD_Ipmovmskb, 466 | UD_Ipmovsxbd, 467 | UD_Ipmovsxbq, 468 | UD_Ipmovsxbw, 469 | UD_Ipmovsxdq, 470 | UD_Ipmovsxwd, 471 | UD_Ipmovsxwq, 472 | UD_Ipmovzxbd, 473 | UD_Ipmovzxbq, 474 | UD_Ipmovzxbw, 475 | UD_Ipmovzxdq, 476 | UD_Ipmovzxwd, 477 | UD_Ipmovzxwq, 478 | UD_Ipmuldq, 479 | UD_Ipmulhrsw, 480 | UD_Ipmulhrw, 481 | UD_Ipmulhuw, 482 | UD_Ipmulhw, 483 | UD_Ipmulld, 484 | UD_Ipmullw, 485 | UD_Ipmuludq, 486 | UD_Ipop, 487 | UD_Ipopa, 488 | UD_Ipopad, 489 | UD_Ipopcnt, 490 | UD_Ipopfd, 491 | UD_Ipopfq, 492 | UD_Ipopfw, 493 | UD_Ipor, 494 | UD_Iprefetch, 495 | UD_Iprefetchnta, 496 | UD_Iprefetcht0, 497 | UD_Iprefetcht1, 498 | UD_Iprefetcht2, 499 | UD_Ipsadbw, 500 | UD_Ipshufb, 501 | UD_Ipshufd, 502 | UD_Ipshufhw, 503 | UD_Ipshuflw, 504 | UD_Ipshufw, 505 | UD_Ipsignb, 506 | UD_Ipsignd, 507 | UD_Ipsignw, 508 | UD_Ipslld, 509 | UD_Ipslldq, 510 | UD_Ipsllq, 511 | UD_Ipsllw, 512 | UD_Ipsrad, 513 | UD_Ipsraw, 514 | UD_Ipsrld, 515 | UD_Ipsrldq, 516 | UD_Ipsrlq, 517 | UD_Ipsrlw, 518 | UD_Ipsubb, 519 | UD_Ipsubd, 520 | UD_Ipsubq, 521 | UD_Ipsubsb, 522 | UD_Ipsubsw, 523 | UD_Ipsubusb, 524 | UD_Ipsubusw, 525 | UD_Ipsubw, 526 | UD_Ipswapd, 527 | UD_Iptest, 528 | UD_Ipunpckhbw, 529 | UD_Ipunpckhdq, 530 | UD_Ipunpckhqdq, 531 | UD_Ipunpckhwd, 532 | UD_Ipunpcklbw, 533 | UD_Ipunpckldq, 534 | UD_Ipunpcklqdq, 535 | UD_Ipunpcklwd, 536 | UD_Ipush, 537 | UD_Ipusha, 538 | UD_Ipushad, 539 | UD_Ipushfd, 540 | UD_Ipushfq, 541 | UD_Ipushfw, 542 | UD_Ipxor, 543 | UD_Ircl, 544 | UD_Ircpps, 545 | UD_Ircpss, 546 | UD_Ircr, 547 | UD_Irdmsr, 548 | UD_Irdpmc, 549 | UD_Irdtsc, 550 | UD_Irdtscp, 551 | UD_Irep, 552 | UD_Irepne, 553 | UD_Iret, 554 | UD_Iretf, 555 | UD_Irol, 556 | UD_Iror, 557 | UD_Iroundpd, 558 | UD_Iroundps, 559 | UD_Iroundsd, 560 | UD_Iroundss, 561 | UD_Irsm, 562 | UD_Irsqrtps, 563 | UD_Irsqrtss, 564 | UD_Isahf, 565 | UD_Isalc, 566 | UD_Isar, 567 | UD_Isbb, 568 | UD_Iscasb, 569 | UD_Iscasd, 570 | UD_Iscasq, 571 | UD_Iscasw, 572 | UD_Iseta, 573 | UD_Isetae, 574 | UD_Isetb, 575 | UD_Isetbe, 576 | UD_Isetg, 577 | UD_Isetge, 578 | UD_Isetl, 579 | UD_Isetle, 580 | UD_Isetno, 581 | UD_Isetnp, 582 | UD_Isetns, 583 | UD_Isetnz, 584 | UD_Iseto, 585 | UD_Isetp, 586 | UD_Isets, 587 | UD_Isetz, 588 | UD_Isfence, 589 | UD_Isgdt, 590 | UD_Ishl, 591 | UD_Ishld, 592 | UD_Ishr, 593 | UD_Ishrd, 594 | UD_Ishufpd, 595 | UD_Ishufps, 596 | UD_Isidt, 597 | UD_Iskinit, 598 | UD_Isldt, 599 | UD_Ismsw, 600 | UD_Isqrtpd, 601 | UD_Isqrtps, 602 | UD_Isqrtsd, 603 | UD_Isqrtss, 604 | UD_Istc, 605 | UD_Istd, 606 | UD_Istgi, 607 | UD_Isti, 608 | UD_Istmxcsr, 609 | UD_Istosb, 610 | UD_Istosd, 611 | UD_Istosq, 612 | UD_Istosw, 613 | UD_Istr, 614 | UD_Isub, 615 | UD_Isubpd, 616 | UD_Isubps, 617 | UD_Isubsd, 618 | UD_Isubss, 619 | UD_Iswapgs, 620 | UD_Isyscall, 621 | UD_Isysenter, 622 | UD_Isysexit, 623 | UD_Isysret, 624 | UD_Itest, 625 | UD_Iucomisd, 626 | UD_Iucomiss, 627 | UD_Iud2, 628 | UD_Iunpckhpd, 629 | UD_Iunpckhps, 630 | UD_Iunpcklpd, 631 | UD_Iunpcklps, 632 | UD_Ivaddpd, 633 | UD_Ivaddps, 634 | UD_Ivaddsd, 635 | UD_Ivaddss, 636 | UD_Ivaddsubpd, 637 | UD_Ivaddsubps, 638 | UD_Ivaesdec, 639 | UD_Ivaesdeclast, 640 | UD_Ivaesenc, 641 | UD_Ivaesenclast, 642 | UD_Ivaesimc, 643 | UD_Ivaeskeygenassist, 644 | UD_Ivandnpd, 645 | UD_Ivandnps, 646 | UD_Ivandpd, 647 | UD_Ivandps, 648 | UD_Ivblendpd, 649 | UD_Ivblendps, 650 | UD_Ivblendvpd, 651 | UD_Ivblendvps, 652 | UD_Ivbroadcastsd, 653 | UD_Ivbroadcastss, 654 | UD_Ivcmppd, 655 | UD_Ivcmpps, 656 | UD_Ivcmpsd, 657 | UD_Ivcmpss, 658 | UD_Ivcomisd, 659 | UD_Ivcomiss, 660 | UD_Ivcvtdq2pd, 661 | UD_Ivcvtdq2ps, 662 | UD_Ivcvtpd2dq, 663 | UD_Ivcvtpd2ps, 664 | UD_Ivcvtps2dq, 665 | UD_Ivcvtps2pd, 666 | UD_Ivcvtsd2si, 667 | UD_Ivcvtsd2ss, 668 | UD_Ivcvtsi2sd, 669 | UD_Ivcvtsi2ss, 670 | UD_Ivcvtss2sd, 671 | UD_Ivcvtss2si, 672 | UD_Ivcvttpd2dq, 673 | UD_Ivcvttps2dq, 674 | UD_Ivcvttsd2si, 675 | UD_Ivcvttss2si, 676 | UD_Ivdivpd, 677 | UD_Ivdivps, 678 | UD_Ivdivsd, 679 | UD_Ivdivss, 680 | UD_Ivdppd, 681 | UD_Ivdpps, 682 | UD_Iverr, 683 | UD_Iverw, 684 | UD_Ivextractf128, 685 | UD_Ivextractps, 686 | UD_Ivhaddpd, 687 | UD_Ivhaddps, 688 | UD_Ivhsubpd, 689 | UD_Ivhsubps, 690 | UD_Ivinsertf128, 691 | UD_Ivinsertps, 692 | UD_Ivlddqu, 693 | UD_Ivmaskmovdqu, 694 | UD_Ivmaskmovpd, 695 | UD_Ivmaskmovps, 696 | UD_Ivmaxpd, 697 | UD_Ivmaxps, 698 | UD_Ivmaxsd, 699 | UD_Ivmaxss, 700 | UD_Ivmcall, 701 | UD_Ivmclear, 702 | UD_Ivminpd, 703 | UD_Ivminps, 704 | UD_Ivminsd, 705 | UD_Ivminss, 706 | UD_Ivmlaunch, 707 | UD_Ivmload, 708 | UD_Ivmmcall, 709 | UD_Ivmovapd, 710 | UD_Ivmovaps, 711 | UD_Ivmovd, 712 | UD_Ivmovdqu, 713 | UD_Ivmovhlps, 714 | UD_Ivmovhpd, 715 | UD_Ivmovhps, 716 | UD_Ivmovlhps, 717 | UD_Ivmovmskpd, 718 | UD_Ivmovmskps, 719 | UD_Ivmovntdq, 720 | UD_Ivmovntdqa, 721 | UD_Ivmovntpd, 722 | UD_Ivmovntps, 723 | UD_Ivmovq, 724 | UD_Ivmovsd, 725 | UD_Ivmovshdup, 726 | UD_Ivmovsldup, 727 | UD_Ivmovss, 728 | UD_Ivmovupd, 729 | UD_Ivmovups, 730 | UD_Ivmpsadbw, 731 | UD_Ivmptrld, 732 | UD_Ivmptrst, 733 | UD_Ivmread, 734 | UD_Ivmresume, 735 | UD_Ivmrun, 736 | UD_Ivmsave, 737 | UD_Ivmulpd, 738 | UD_Ivmulps, 739 | UD_Ivmulsd, 740 | UD_Ivmulss, 741 | UD_Ivmwrite, 742 | UD_Ivmxoff, 743 | UD_Ivmxon, 744 | UD_Ivorpd, 745 | UD_Ivorps, 746 | UD_Ivpabsb, 747 | UD_Ivpabsd, 748 | UD_Ivpabsw, 749 | UD_Ivpackssdw, 750 | UD_Ivpacksswb, 751 | UD_Ivpackusdw, 752 | UD_Ivpackuswb, 753 | UD_Ivpaddb, 754 | UD_Ivpaddd, 755 | UD_Ivpaddq, 756 | UD_Ivpaddsb, 757 | UD_Ivpaddsw, 758 | UD_Ivpaddusb, 759 | UD_Ivpaddusw, 760 | UD_Ivpaddw, 761 | UD_Ivpalignr, 762 | UD_Ivpand, 763 | UD_Ivpandn, 764 | UD_Ivpavgb, 765 | UD_Ivpavgw, 766 | UD_Ivpblendvb, 767 | UD_Ivpblendw, 768 | UD_Ivpclmulqdq, 769 | UD_Ivpcmpeqb, 770 | UD_Ivpcmpeqd, 771 | UD_Ivpcmpeqq, 772 | UD_Ivpcmpeqw, 773 | UD_Ivpcmpestri, 774 | UD_Ivpcmpestrm, 775 | UD_Ivpcmpgtb, 776 | UD_Ivpcmpgtd, 777 | UD_Ivpcmpgtq, 778 | UD_Ivpcmpgtw, 779 | UD_Ivpcmpistri, 780 | UD_Ivpcmpistrm, 781 | UD_Ivperm2f128, 782 | UD_Ivpermilpd, 783 | UD_Ivpermilps, 784 | UD_Ivpextrb, 785 | UD_Ivpextrd, 786 | UD_Ivpextrq, 787 | UD_Ivpextrw, 788 | UD_Ivphaddd, 789 | UD_Ivphaddsw, 790 | UD_Ivphaddw, 791 | UD_Ivphminposuw, 792 | UD_Ivphsubd, 793 | UD_Ivphsubsw, 794 | UD_Ivphsubw, 795 | UD_Ivpinsrb, 796 | UD_Ivpinsrd, 797 | UD_Ivpinsrq, 798 | UD_Ivpinsrw, 799 | UD_Ivpmaddubsw, 800 | UD_Ivpmaddwd, 801 | UD_Ivpmaxsb, 802 | UD_Ivpmaxsd, 803 | UD_Ivpmaxsw, 804 | UD_Ivpmaxub, 805 | UD_Ivpmaxud, 806 | UD_Ivpmaxuw, 807 | UD_Ivpminsb, 808 | UD_Ivpminsd, 809 | UD_Ivpminsw, 810 | UD_Ivpminub, 811 | UD_Ivpminud, 812 | UD_Ivpminuw, 813 | UD_Ivpmovmskb, 814 | UD_Ivpmovsxbd, 815 | UD_Ivpmovsxbq, 816 | UD_Ivpmovsxbw, 817 | UD_Ivpmovsxwd, 818 | UD_Ivpmovsxwq, 819 | UD_Ivpmovzxbd, 820 | UD_Ivpmovzxbq, 821 | UD_Ivpmovzxbw, 822 | UD_Ivpmovzxdq, 823 | UD_Ivpmovzxwd, 824 | UD_Ivpmovzxwq, 825 | UD_Ivpmuldq, 826 | UD_Ivpmulhrsw, 827 | UD_Ivpmulhuw, 828 | UD_Ivpmulhw, 829 | UD_Ivpmulld, 830 | UD_Ivpmullw, 831 | UD_Ivpor, 832 | UD_Ivpsadbw, 833 | UD_Ivpshufb, 834 | UD_Ivpshufd, 835 | UD_Ivpshufhw, 836 | UD_Ivpshuflw, 837 | UD_Ivpsignb, 838 | UD_Ivpsignd, 839 | UD_Ivpsignw, 840 | UD_Ivpslld, 841 | UD_Ivpslldq, 842 | UD_Ivpsllq, 843 | UD_Ivpsllw, 844 | UD_Ivpsrad, 845 | UD_Ivpsraw, 846 | UD_Ivpsrld, 847 | UD_Ivpsrldq, 848 | UD_Ivpsrlq, 849 | UD_Ivpsrlw, 850 | UD_Ivpsubb, 851 | UD_Ivpsubd, 852 | UD_Ivpsubq, 853 | UD_Ivpsubsb, 854 | UD_Ivpsubsw, 855 | UD_Ivpsubusb, 856 | UD_Ivpsubusw, 857 | UD_Ivpsubw, 858 | UD_Ivptest, 859 | UD_Ivpunpckhbw, 860 | UD_Ivpunpckhdq, 861 | UD_Ivpunpckhqdq, 862 | UD_Ivpunpckhwd, 863 | UD_Ivpunpcklbw, 864 | UD_Ivpunpckldq, 865 | UD_Ivpunpcklwd, 866 | UD_Ivpxor, 867 | UD_Ivrcpps, 868 | UD_Ivrcpss, 869 | UD_Ivroundpd, 870 | UD_Ivroundps, 871 | UD_Ivroundsd, 872 | UD_Ivroundss, 873 | UD_Ivrsqrtps, 874 | UD_Ivrsqrtss, 875 | UD_Ivshufpd, 876 | UD_Ivshufps, 877 | UD_Ivsqrtpd, 878 | UD_Ivsqrtps, 879 | UD_Ivsqrtsd, 880 | UD_Ivsqrtss, 881 | UD_Ivstmxcsr, 882 | UD_Ivsubpd, 883 | UD_Ivsubps, 884 | UD_Ivsubsd, 885 | UD_Ivsubss, 886 | UD_Ivtestpd, 887 | UD_Ivtestps, 888 | UD_Ivucomisd, 889 | UD_Ivucomiss, 890 | UD_Ivunpckhpd, 891 | UD_Ivunpckhps, 892 | UD_Ivunpcklpd, 893 | UD_Ivunpcklps, 894 | UD_Ivxorpd, 895 | UD_Ivxorps, 896 | UD_Ivzeroall, 897 | UD_Ivzeroupper, 898 | UD_Iwait, 899 | UD_Iwbinvd, 900 | UD_Iwrmsr, 901 | UD_Ixadd, 902 | UD_Ixchg, 903 | UD_Ixcryptcbc, 904 | UD_Ixcryptcfb, 905 | UD_Ixcryptctr, 906 | UD_Ixcryptecb, 907 | UD_Ixcryptofb, 908 | UD_Ixgetbv, 909 | UD_Ixlatb, 910 | UD_Ixor, 911 | UD_Ixorpd, 912 | UD_Ixorps, 913 | UD_Ixrstor, 914 | UD_Ixsave, 915 | UD_Ixsetbv, 916 | UD_Ixsha1, 917 | UD_Ixsha256, 918 | UD_Ixstore, 919 | UD_Iinvalid, 920 | UD_I3dnow, 921 | UD_Inone, 922 | UD_Idb, 923 | UD_Ipause, 924 | UD_MAX_MNEMONIC_CODE 925 | } UD_ATTR_PACKED; 926 | 927 | extern const char * ud_mnemonics_str[]; 928 | 929 | #endif /* UD_ITAB_H */ 930 | -------------------------------------------------------------------------------- /libudis86/types.h: -------------------------------------------------------------------------------- 1 | /* udis86 - libudis86/types.h 2 | * 3 | * Copyright (c) 2002-2013 Vivek Thampi 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 19 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 22 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | #ifndef UD_TYPES_H 27 | #define UD_TYPES_H 28 | 29 | #ifdef __KERNEL__ 30 | /* -D__KERNEL__ is automatically passed on the command line when 31 | building something as part of the Linux kernel */ 32 | # include 33 | # include 34 | # ifndef __UD_STANDALONE__ 35 | # define __UD_STANDALONE__ 1 36 | #endif 37 | #endif /* __KERNEL__ */ 38 | 39 | #if defined(_MSC_VER) || defined(__BORLANDC__) 40 | # include 41 | # include 42 | # define inline __inline /* MS Visual Studio requires __inline 43 | instead of inline for C code */ 44 | #elif !defined(__UD_STANDALONE__) 45 | # include 46 | # include 47 | #endif /* !__UD_STANDALONE__ */ 48 | 49 | /* gcc specific extensions */ 50 | #ifdef __GNUC__ 51 | # define UD_ATTR_PACKED __attribute__((packed)) 52 | #else 53 | # define UD_ATTR_PACKED 54 | #endif /* UD_ATTR_PACKED */ 55 | 56 | 57 | /* ----------------------------------------------------------------------------- 58 | * All possible "types" of objects in udis86. Order is Important! 59 | * ----------------------------------------------------------------------------- 60 | */ 61 | enum ud_type 62 | { 63 | UD_NONE, 64 | 65 | /* 8 bit GPRs */ 66 | UD_R_AL, UD_R_CL, UD_R_DL, UD_R_BL, 67 | UD_R_AH, UD_R_CH, UD_R_DH, UD_R_BH, 68 | UD_R_SPL, UD_R_BPL, UD_R_SIL, UD_R_DIL, 69 | UD_R_R8B, UD_R_R9B, UD_R_R10B, UD_R_R11B, 70 | UD_R_R12B, UD_R_R13B, UD_R_R14B, UD_R_R15B, 71 | 72 | /* 16 bit GPRs */ 73 | UD_R_AX, UD_R_CX, UD_R_DX, UD_R_BX, 74 | UD_R_SP, UD_R_BP, UD_R_SI, UD_R_DI, 75 | UD_R_R8W, UD_R_R9W, UD_R_R10W, UD_R_R11W, 76 | UD_R_R12W, UD_R_R13W, UD_R_R14W, UD_R_R15W, 77 | 78 | /* 32 bit GPRs */ 79 | UD_R_EAX, UD_R_ECX, UD_R_EDX, UD_R_EBX, 80 | UD_R_ESP, UD_R_EBP, UD_R_ESI, UD_R_EDI, 81 | UD_R_R8D, UD_R_R9D, UD_R_R10D, UD_R_R11D, 82 | UD_R_R12D, UD_R_R13D, UD_R_R14D, UD_R_R15D, 83 | 84 | /* 64 bit GPRs */ 85 | UD_R_RAX, UD_R_RCX, UD_R_RDX, UD_R_RBX, 86 | UD_R_RSP, UD_R_RBP, UD_R_RSI, UD_R_RDI, 87 | UD_R_R8, UD_R_R9, UD_R_R10, UD_R_R11, 88 | UD_R_R12, UD_R_R13, UD_R_R14, UD_R_R15, 89 | 90 | /* segment registers */ 91 | UD_R_ES, UD_R_CS, UD_R_SS, UD_R_DS, 92 | UD_R_FS, UD_R_GS, 93 | 94 | /* control registers*/ 95 | UD_R_CR0, UD_R_CR1, UD_R_CR2, UD_R_CR3, 96 | UD_R_CR4, UD_R_CR5, UD_R_CR6, UD_R_CR7, 97 | UD_R_CR8, UD_R_CR9, UD_R_CR10, UD_R_CR11, 98 | UD_R_CR12, UD_R_CR13, UD_R_CR14, UD_R_CR15, 99 | 100 | /* debug registers */ 101 | UD_R_DR0, UD_R_DR1, UD_R_DR2, UD_R_DR3, 102 | UD_R_DR4, UD_R_DR5, UD_R_DR6, UD_R_DR7, 103 | UD_R_DR8, UD_R_DR9, UD_R_DR10, UD_R_DR11, 104 | UD_R_DR12, UD_R_DR13, UD_R_DR14, UD_R_DR15, 105 | 106 | /* mmx registers */ 107 | UD_R_MM0, UD_R_MM1, UD_R_MM2, UD_R_MM3, 108 | UD_R_MM4, UD_R_MM5, UD_R_MM6, UD_R_MM7, 109 | 110 | /* x87 registers */ 111 | UD_R_ST0, UD_R_ST1, UD_R_ST2, UD_R_ST3, 112 | UD_R_ST4, UD_R_ST5, UD_R_ST6, UD_R_ST7, 113 | 114 | /* extended multimedia registers */ 115 | UD_R_XMM0, UD_R_XMM1, UD_R_XMM2, UD_R_XMM3, 116 | UD_R_XMM4, UD_R_XMM5, UD_R_XMM6, UD_R_XMM7, 117 | UD_R_XMM8, UD_R_XMM9, UD_R_XMM10, UD_R_XMM11, 118 | UD_R_XMM12, UD_R_XMM13, UD_R_XMM14, UD_R_XMM15, 119 | 120 | /* 256B multimedia registers */ 121 | UD_R_YMM0, UD_R_YMM1, UD_R_YMM2, UD_R_YMM3, 122 | UD_R_YMM4, UD_R_YMM5, UD_R_YMM6, UD_R_YMM7, 123 | UD_R_YMM8, UD_R_YMM9, UD_R_YMM10, UD_R_YMM11, 124 | UD_R_YMM12, UD_R_YMM13, UD_R_YMM14, UD_R_YMM15, 125 | 126 | UD_R_RIP, 127 | 128 | /* Operand Types */ 129 | UD_OP_REG, UD_OP_MEM, UD_OP_PTR, UD_OP_IMM, 130 | UD_OP_JIMM, UD_OP_CONST 131 | }; 132 | 133 | #include "itab.h" 134 | 135 | union ud_lval { 136 | int8_t sbyte; 137 | uint8_t ubyte; 138 | int16_t sword; 139 | uint16_t uword; 140 | int32_t sdword; 141 | uint32_t udword; 142 | int64_t sqword; 143 | uint64_t uqword; 144 | struct { 145 | uint16_t seg; 146 | uint32_t off; 147 | } ptr; 148 | }; 149 | 150 | /* ----------------------------------------------------------------------------- 151 | * struct ud_operand - Disassembled instruction Operand. 152 | * ----------------------------------------------------------------------------- 153 | */ 154 | struct ud_operand { 155 | enum ud_type type; 156 | uint16_t size; 157 | enum ud_type base; 158 | enum ud_type index; 159 | uint8_t scale; 160 | uint8_t offset; 161 | union ud_lval lval; 162 | /* 163 | * internal use only 164 | */ 165 | uint64_t _legacy; /* this will be removed in 1.8 */ 166 | uint8_t _oprcode; 167 | }; 168 | 169 | /* ----------------------------------------------------------------------------- 170 | * struct ud - The udis86 object. 171 | * ----------------------------------------------------------------------------- 172 | */ 173 | struct ud 174 | { 175 | /* 176 | * input buffering 177 | */ 178 | int (*inp_hook) (struct ud*); 179 | #ifndef __UD_STANDALONE__ 180 | FILE* inp_file; 181 | #endif 182 | const uint8_t* inp_buf; 183 | size_t inp_buf_size; 184 | size_t inp_buf_index; 185 | uint8_t inp_curr; 186 | size_t inp_ctr; 187 | uint8_t inp_sess[64]; 188 | int inp_end; 189 | int inp_peek; 190 | 191 | void (*translator)(struct ud*); 192 | uint64_t insn_offset; 193 | char insn_hexcode[64]; 194 | 195 | /* 196 | * Assembly output buffer 197 | */ 198 | char *asm_buf; 199 | size_t asm_buf_size; 200 | size_t asm_buf_fill; 201 | char asm_buf_int[128]; 202 | 203 | /* 204 | * Symbol resolver for use in the translation phase. 205 | */ 206 | const char* (*sym_resolver)(struct ud*, uint64_t addr, int64_t *offset); 207 | 208 | uint8_t dis_mode; 209 | uint64_t pc; 210 | uint8_t vendor; 211 | enum ud_mnemonic_code mnemonic; 212 | struct ud_operand operand[4]; 213 | uint8_t error; 214 | uint8_t _rex; 215 | uint8_t pfx_rex; 216 | uint8_t pfx_seg; 217 | uint8_t pfx_opr; 218 | uint8_t pfx_adr; 219 | uint8_t pfx_lock; 220 | uint8_t pfx_str; 221 | uint8_t pfx_rep; 222 | uint8_t pfx_repe; 223 | uint8_t pfx_repne; 224 | uint8_t opr_mode; 225 | uint8_t adr_mode; 226 | uint8_t br_far; 227 | uint8_t br_near; 228 | uint8_t have_modrm; 229 | uint8_t modrm; 230 | uint8_t vex_op; 231 | uint8_t vex_b1; 232 | uint8_t vex_b2; 233 | uint8_t primary_opcode; 234 | void * user_opaque_data; 235 | struct ud_itab_entry * itab_entry; 236 | struct ud_lookup_table_list_entry *le; 237 | }; 238 | 239 | /* ----------------------------------------------------------------------------- 240 | * Type-definitions 241 | * ----------------------------------------------------------------------------- 242 | */ 243 | typedef enum ud_type ud_type_t; 244 | typedef enum ud_mnemonic_code ud_mnemonic_code_t; 245 | 246 | typedef struct ud ud_t; 247 | typedef struct ud_operand ud_operand_t; 248 | 249 | #define UD_SYN_INTEL ud_translate_intel 250 | #define UD_SYN_ATT ud_translate_att 251 | #define UD_EOI (-1) 252 | #define UD_INP_CACHE_SZ 32 253 | #define UD_VENDOR_AMD 0 254 | #define UD_VENDOR_INTEL 1 255 | #define UD_VENDOR_ANY 2 256 | 257 | #endif 258 | 259 | /* 260 | vim: set ts=2 sw=2 expandtab 261 | */ 262 | -------------------------------------------------------------------------------- /libudis86/udint.h: -------------------------------------------------------------------------------- 1 | /* udis86 - libudis86/udint.h -- definitions for internal use only 2 | * 3 | * Copyright (c) 2002-2009 Vivek Thampi 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 19 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 22 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | #ifndef _UDINT_H_ 27 | #define _UDINT_H_ 28 | 29 | #ifdef HAVE_CONFIG_H 30 | # include 31 | #endif /* HAVE_CONFIG_H */ 32 | 33 | #if defined(UD_DEBUG) && HAVE_ASSERT_H 34 | # include 35 | # define UD_ASSERT(_x) assert(_x) 36 | #else 37 | # define UD_ASSERT(_x) 38 | #endif /* !HAVE_ASSERT_H */ 39 | 40 | #if defined(UD_DEBUG) 41 | #define UDERR(u, msg) \ 42 | do { \ 43 | (u)->error = 1; \ 44 | fprintf(stderr, "decode-error: %s:%d: %s", \ 45 | __FILE__, __LINE__, (msg)); \ 46 | } while (0) 47 | #else 48 | #define UDERR(u, m) \ 49 | do { \ 50 | (u)->error = 1; \ 51 | } while (0) 52 | #endif /* !LOGERR */ 53 | 54 | #define UD_RETURN_ON_ERROR(u) \ 55 | do { \ 56 | if ((u)->error != 0) { \ 57 | return (u)->error; \ 58 | } \ 59 | } while (0) 60 | 61 | #define UD_RETURN_WITH_ERROR(u, m) \ 62 | do { \ 63 | UDERR(u, m); \ 64 | return (u)->error; \ 65 | } while (0) 66 | 67 | #ifndef __UD_STANDALONE__ 68 | # define UD_NON_STANDALONE(x) x 69 | #else 70 | # define UD_NON_STANDALONE(x) 71 | #endif 72 | 73 | /* printf formatting int64 specifier */ 74 | #ifdef FMT64 75 | # undef FMT64 76 | #endif 77 | #if defined(_MSC_VER) || defined(__BORLANDC__) 78 | # define FMT64 "I64" 79 | #else 80 | # if defined(__APPLE__) 81 | # define FMT64 "ll" 82 | # elif defined(__amd64__) || defined(__x86_64__) 83 | # define FMT64 "l" 84 | # else 85 | # define FMT64 "ll" 86 | # endif /* !x64 */ 87 | #endif 88 | 89 | #endif /* _UDINT_H_ */ 90 | -------------------------------------------------------------------------------- /libudis86/udis86.c: -------------------------------------------------------------------------------- 1 | /* udis86 - libudis86/udis86.c 2 | * 3 | * Copyright (c) 2002-2013 Vivek Thampi 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 19 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 22 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | 27 | #include "udint.h" 28 | #include "extern.h" 29 | #include "decode.h" 30 | 31 | #if !defined(__UD_STANDALONE__) 32 | # if HAVE_STRING_H 33 | # include 34 | # endif 35 | #endif /* !__UD_STANDALONE__ */ 36 | 37 | static void ud_inp_init(struct ud *u); 38 | 39 | /* ============================================================================= 40 | * ud_init 41 | * Initializes ud_t object. 42 | * ============================================================================= 43 | */ 44 | extern void 45 | ud_init(struct ud* u) 46 | { 47 | memset((void*)u, 0, sizeof(struct ud)); 48 | ud_set_mode(u, 16); 49 | u->mnemonic = UD_Iinvalid; 50 | ud_set_pc(u, 0); 51 | #ifndef __UD_STANDALONE__ 52 | ud_set_input_file(u, stdin); 53 | #endif /* __UD_STANDALONE__ */ 54 | 55 | ud_set_asm_buffer(u, u->asm_buf_int, sizeof(u->asm_buf_int)); 56 | } 57 | 58 | 59 | /* ============================================================================= 60 | * ud_initialize 61 | * Initializes ud_t object (extended). 62 | * ============================================================================= 63 | */ 64 | extern void 65 | ud_initialize(struct ud* u, uint8_t m, 66 | unsigned v, const uint8_t* buf, size_t len) 67 | { 68 | ud_init(u); 69 | ud_set_mode(u, m); 70 | ud_set_vendor(u, v); 71 | ud_set_input_buffer(u, buf, len); 72 | } 73 | 74 | 75 | /* ============================================================================= 76 | * ud_disassemble 77 | * Disassembles one instruction and returns the number of 78 | * bytes disassembled. A zero means end of disassembly. 79 | * ============================================================================= 80 | */ 81 | extern unsigned int 82 | ud_disassemble(struct ud* u) 83 | { 84 | int len; 85 | if (u->inp_end) { 86 | return 0; 87 | } 88 | if ((len = ud_decode(u)) > 0) { 89 | if (u->translator != NULL) { 90 | u->asm_buf[0] = '\0'; 91 | u->translator(u); 92 | } 93 | } 94 | return len; 95 | } 96 | 97 | 98 | /* ============================================================================= 99 | * ud_set_mode() - Set Disassemly Mode. 100 | * ============================================================================= 101 | */ 102 | extern void 103 | ud_set_mode(struct ud* u, uint8_t m) 104 | { 105 | switch(m) { 106 | case 16: 107 | case 32: 108 | case 64: u->dis_mode = m ; return; 109 | default: u->dis_mode = 16; return; 110 | } 111 | } 112 | 113 | /* ============================================================================= 114 | * ud_set_vendor() - Set vendor. 115 | * ============================================================================= 116 | */ 117 | extern void 118 | ud_set_vendor(struct ud* u, unsigned v) 119 | { 120 | switch(v) { 121 | case UD_VENDOR_INTEL: 122 | u->vendor = v; 123 | break; 124 | case UD_VENDOR_ANY: 125 | u->vendor = v; 126 | break; 127 | default: 128 | u->vendor = UD_VENDOR_AMD; 129 | } 130 | } 131 | 132 | /* ============================================================================= 133 | * ud_set_pc() - Sets code origin. 134 | * ============================================================================= 135 | */ 136 | extern void 137 | ud_set_pc(struct ud* u, uint64_t o) 138 | { 139 | u->pc = o; 140 | } 141 | 142 | /* ============================================================================= 143 | * ud_set_syntax() - Sets the output syntax. 144 | * ============================================================================= 145 | */ 146 | extern void 147 | ud_set_syntax(struct ud* u, void (*t)(struct ud*)) 148 | { 149 | u->translator = t; 150 | } 151 | 152 | /* ============================================================================= 153 | * ud_insn() - returns the disassembled instruction 154 | * ============================================================================= 155 | */ 156 | const char* 157 | ud_insn_asm(const struct ud* u) 158 | { 159 | return u->asm_buf; 160 | } 161 | 162 | /* ============================================================================= 163 | * ud_insn_offset() - Returns the offset. 164 | * ============================================================================= 165 | */ 166 | uint64_t 167 | ud_insn_off(const struct ud* u) 168 | { 169 | return u->insn_offset; 170 | } 171 | 172 | 173 | /* ============================================================================= 174 | * ud_insn_hex() - Returns hex form of disassembled instruction. 175 | * ============================================================================= 176 | */ 177 | const char* 178 | ud_insn_hex(struct ud* u) 179 | { 180 | u->insn_hexcode[0] = 0; 181 | if (!u->error) { 182 | unsigned int i; 183 | const unsigned char *src_ptr = ud_insn_ptr(u); 184 | char* src_hex; 185 | src_hex = (char*) u->insn_hexcode; 186 | /* for each byte used to decode instruction */ 187 | for (i = 0; i < ud_insn_len(u) && i < sizeof(u->insn_hexcode) / 2; 188 | ++i, ++src_ptr) { 189 | sprintf(src_hex, "%02x", *src_ptr & 0xFF); 190 | src_hex += 2; 191 | } 192 | } 193 | return u->insn_hexcode; 194 | } 195 | 196 | 197 | /* ============================================================================= 198 | * ud_insn_ptr 199 | * Returns a pointer to buffer containing the bytes that were 200 | * disassembled. 201 | * ============================================================================= 202 | */ 203 | extern const uint8_t* 204 | ud_insn_ptr(const struct ud* u) 205 | { 206 | return (u->inp_buf == NULL) ? 207 | u->inp_sess : u->inp_buf + (u->inp_buf_index - u->inp_ctr); 208 | } 209 | 210 | 211 | /* ============================================================================= 212 | * ud_insn_len 213 | * Returns the count of bytes disassembled. 214 | * ============================================================================= 215 | */ 216 | extern unsigned int 217 | ud_insn_len(const struct ud* u) 218 | { 219 | return u->inp_ctr; 220 | } 221 | 222 | 223 | /* ============================================================================= 224 | * ud_insn_get_opr 225 | * Return the operand struct representing the nth operand of 226 | * the currently disassembled instruction. Returns NULL if 227 | * there's no such operand. 228 | * ============================================================================= 229 | */ 230 | const struct ud_operand* 231 | ud_insn_opr(const struct ud *u, unsigned int n) 232 | { 233 | if (n > 3 || u->operand[n].type == UD_NONE) { 234 | return NULL; 235 | } else { 236 | return &u->operand[n]; 237 | } 238 | } 239 | 240 | 241 | /* ============================================================================= 242 | * ud_opr_is_sreg 243 | * Returns non-zero if the given operand is of a segment register type. 244 | * ============================================================================= 245 | */ 246 | int 247 | ud_opr_is_sreg(const struct ud_operand *opr) 248 | { 249 | return opr->type == UD_OP_REG && 250 | opr->base >= UD_R_ES && 251 | opr->base <= UD_R_GS; 252 | } 253 | 254 | 255 | /* ============================================================================= 256 | * ud_opr_is_sreg 257 | * Returns non-zero if the given operand is of a general purpose 258 | * register type. 259 | * ============================================================================= 260 | */ 261 | int 262 | ud_opr_is_gpr(const struct ud_operand *opr) 263 | { 264 | return opr->type == UD_OP_REG && 265 | opr->base >= UD_R_AL && 266 | opr->base <= UD_R_R15; 267 | } 268 | 269 | 270 | /* ============================================================================= 271 | * ud_set_user_opaque_data 272 | * ud_get_user_opaque_data 273 | * Get/set user opaqute data pointer 274 | * ============================================================================= 275 | */ 276 | void 277 | ud_set_user_opaque_data(struct ud * u, void* opaque) 278 | { 279 | u->user_opaque_data = opaque; 280 | } 281 | 282 | void* 283 | ud_get_user_opaque_data(const struct ud *u) 284 | { 285 | return u->user_opaque_data; 286 | } 287 | 288 | 289 | /* ============================================================================= 290 | * ud_set_asm_buffer 291 | * Allow the user to set an assembler output buffer. If `buf` is NULL, 292 | * we switch back to the internal buffer. 293 | * ============================================================================= 294 | */ 295 | void 296 | ud_set_asm_buffer(struct ud *u, char *buf, size_t size) 297 | { 298 | if (buf == NULL) { 299 | ud_set_asm_buffer(u, u->asm_buf_int, sizeof(u->asm_buf_int)); 300 | } else { 301 | u->asm_buf = buf; 302 | u->asm_buf_size = size; 303 | } 304 | } 305 | 306 | 307 | /* ============================================================================= 308 | * ud_set_sym_resolver 309 | * Set symbol resolver for relative targets used in the translation 310 | * phase. 311 | * 312 | * The resolver is a function that takes a uint64_t address and returns a 313 | * symbolic name for the that address. The function also takes a second 314 | * argument pointing to an integer that the client can optionally set to a 315 | * non-zero value for offsetted targets. (symbol+offset) The function may 316 | * also return NULL, in which case the translator only prints the target 317 | * address. 318 | * 319 | * The function pointer maybe NULL which resets symbol resolution. 320 | * ============================================================================= 321 | */ 322 | void 323 | ud_set_sym_resolver(struct ud *u, const char* (*resolver)(struct ud*, 324 | uint64_t addr, 325 | int64_t *offset)) 326 | { 327 | u->sym_resolver = resolver; 328 | } 329 | 330 | 331 | /* ============================================================================= 332 | * ud_insn_mnemonic 333 | * Return the current instruction mnemonic. 334 | * ============================================================================= 335 | */ 336 | enum ud_mnemonic_code 337 | ud_insn_mnemonic(const struct ud *u) 338 | { 339 | return u->mnemonic; 340 | } 341 | 342 | 343 | /* ============================================================================= 344 | * ud_lookup_mnemonic 345 | * Looks up mnemonic code in the mnemonic string table. 346 | * Returns NULL if the mnemonic code is invalid. 347 | * ============================================================================= 348 | */ 349 | const char* 350 | ud_lookup_mnemonic(enum ud_mnemonic_code c) 351 | { 352 | if (c < UD_MAX_MNEMONIC_CODE) { 353 | return ud_mnemonics_str[c]; 354 | } else { 355 | return NULL; 356 | } 357 | } 358 | 359 | 360 | /* 361 | * ud_inp_init 362 | * Initializes the input system. 363 | */ 364 | static void 365 | ud_inp_init(struct ud *u) 366 | { 367 | u->inp_hook = NULL; 368 | u->inp_buf = NULL; 369 | u->inp_buf_size = 0; 370 | u->inp_buf_index = 0; 371 | u->inp_curr = 0; 372 | u->inp_ctr = 0; 373 | u->inp_end = 0; 374 | u->inp_peek = UD_EOI; 375 | UD_NON_STANDALONE(u->inp_file = NULL); 376 | } 377 | 378 | 379 | /* ============================================================================= 380 | * ud_inp_set_hook 381 | * Sets input hook. 382 | * ============================================================================= 383 | */ 384 | void 385 | ud_set_input_hook(register struct ud* u, int (*hook)(struct ud*)) 386 | { 387 | ud_inp_init(u); 388 | u->inp_hook = hook; 389 | } 390 | 391 | /* ============================================================================= 392 | * ud_inp_set_buffer 393 | * Set buffer as input. 394 | * ============================================================================= 395 | */ 396 | void 397 | ud_set_input_buffer(register struct ud* u, const uint8_t* buf, size_t len) 398 | { 399 | ud_inp_init(u); 400 | u->inp_buf = buf; 401 | u->inp_buf_size = len; 402 | u->inp_buf_index = 0; 403 | } 404 | 405 | 406 | #ifndef __UD_STANDALONE__ 407 | /* ============================================================================= 408 | * ud_input_set_file 409 | * Set FILE as input. 410 | * ============================================================================= 411 | */ 412 | static int 413 | inp_file_hook(struct ud* u) 414 | { 415 | return fgetc(u->inp_file); 416 | } 417 | 418 | void 419 | ud_set_input_file(register struct ud* u, FILE* f) 420 | { 421 | ud_inp_init(u); 422 | u->inp_hook = inp_file_hook; 423 | u->inp_file = f; 424 | } 425 | #endif /* __UD_STANDALONE__ */ 426 | 427 | 428 | /* ============================================================================= 429 | * ud_input_skip 430 | * Skip n input bytes. 431 | * ============================================================================ 432 | */ 433 | void 434 | ud_input_skip(struct ud* u, size_t n) 435 | { 436 | if (u->inp_end) { 437 | return; 438 | } 439 | if (u->inp_buf == NULL) { 440 | while (n--) { 441 | int c = u->inp_hook(u); 442 | if (c == UD_EOI) { 443 | goto eoi; 444 | } 445 | } 446 | return; 447 | } else { 448 | if (n > u->inp_buf_size || 449 | u->inp_buf_index > u->inp_buf_size - n) { 450 | u->inp_buf_index = u->inp_buf_size; 451 | goto eoi; 452 | } 453 | u->inp_buf_index += n; 454 | return; 455 | } 456 | eoi: 457 | u->inp_end = 1; 458 | UDERR(u, "cannot skip, eoi received\b"); 459 | return; 460 | } 461 | 462 | 463 | /* ============================================================================= 464 | * ud_input_end 465 | * Returns non-zero on end-of-input. 466 | * ============================================================================= 467 | */ 468 | int 469 | ud_input_end(const struct ud *u) 470 | { 471 | return u->inp_end; 472 | } 473 | 474 | /* vim:set ts=2 sw=2 expandtab */ 475 | -------------------------------------------------------------------------------- /trace.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #ifdef CONFIG_X86_32 6 | # define IS_IA32 1 7 | #elif defined(CONFIG_IA32_EMULATION) 8 | # define IS_IA32 is_compat_task() 9 | #else 10 | # define IS_IA32 0 11 | #endif 12 | 13 | #ifndef __NR_ia32_open 14 | # define __NR_ia32_open __NR_open 15 | #endif 16 | 17 | static void trace_syscall_entry(int arch, unsigned long major, \ 18 | unsigned long a0, unsigned long a1, unsigned long a2, unsigned long a3) 19 | { 20 | char *filename = NULL; 21 | 22 | if (major == __NR_open || major == __NR_ia32_open) { 23 | filename = kmalloc(PATH_MAX, GFP_KERNEL); 24 | if (!filename || strncpy_from_user(filename, (const void __user *)a0, PATH_MAX) < 0) 25 | goto out; 26 | printk("%s open(%s) [%s]\n", arch ? "X86_64" : "I386", filename, current->comm); 27 | } 28 | 29 | out: 30 | if (filename) kfree(filename); 31 | } 32 | 33 | void ServiceTraceEnter(struct pt_regs *regs) 34 | { 35 | if (IS_IA32) 36 | trace_syscall_entry(0, regs->orig_ax, \ 37 | regs->bx, regs->cx, regs->dx, regs->si); 38 | #ifdef CONFIG_X86_64 39 | else 40 | trace_syscall_entry(1, regs->orig_ax, \ 41 | regs->di, regs->si, regs->dx, regs->r10); 42 | 43 | #endif 44 | } 45 | 46 | static void trace_syscall_leave(struct pt_regs *regs) 47 | { 48 | /* TODO: add more code here */ 49 | } 50 | 51 | void ServiceTraceLeave(struct pt_regs *regs) 52 | { 53 | trace_syscall_leave(regs); 54 | } 55 | -------------------------------------------------------------------------------- /udis86.h: -------------------------------------------------------------------------------- 1 | /* udis86 - udis86.h 2 | * 3 | * Copyright (c) 2002-2009 Vivek Thampi 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 19 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 22 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | #ifndef UDIS86_H 27 | #define UDIS86_H 28 | 29 | #include "libudis86/types.h" 30 | #include "libudis86/extern.h" 31 | #include "libudis86/itab.h" 32 | 33 | #endif 34 | --------------------------------------------------------------------------------