215 |
|
#endif |
216 |
|
#define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, siginfo_t *sip, void *scp |
217 |
|
#define SIGSEGV_FAULT_ADDRESS sip->si_addr |
218 |
+ |
#if (defined(i386) || defined(__i386__)) |
219 |
+ |
#define SIGSEGV_FAULT_INSTRUCTION (((struct sigcontext *)scp)->sc_eip) |
220 |
+ |
#define SIGSEGV_REGISTER_FILE ((unsigned int *)&(((struct sigcontext *)scp)->sc_edi)) |
221 |
+ |
#define SIGSEGV_SKIP_INSTRUCTION ix86_skip_instruction |
222 |
+ |
#endif |
223 |
|
#if defined(__linux__) |
224 |
|
#if (defined(i386) || defined(__i386__)) |
225 |
|
#include <sys/ucontext.h> |
393 |
|
X86_REG_EDI = 4 |
394 |
|
}; |
395 |
|
#endif |
396 |
+ |
#if defined(__NetBSD__) || defined(__FreeBSD__) |
397 |
+ |
enum { |
398 |
+ |
X86_REG_EIP = 10, |
399 |
+ |
X86_REG_EAX = 7, |
400 |
+ |
X86_REG_ECX = 6, |
401 |
+ |
X86_REG_EDX = 5, |
402 |
+ |
X86_REG_EBX = 4, |
403 |
+ |
X86_REG_ESP = 13, |
404 |
+ |
X86_REG_EBP = 2, |
405 |
+ |
X86_REG_ESI = 1, |
406 |
+ |
X86_REG_EDI = 0 |
407 |
+ |
}; |
408 |
+ |
#endif |
409 |
|
// FIXME: this is partly redundant with the instruction decoding phase |
410 |
|
// to discover transfer type and register number |
411 |
|
static inline int ix86_step_over_modrm(unsigned char * p) |
462 |
|
|
463 |
|
// Decode instruction |
464 |
|
switch (eip[0]) { |
465 |
+ |
case 0x0f: |
466 |
+ |
if (eip[1] == 0xb7) { // MOVZX r32, r/m16 |
467 |
+ |
switch (eip[2] & 0xc0) { |
468 |
+ |
case 0x80: |
469 |
+ |
reg = (eip[2] >> 3) & 7; |
470 |
+ |
transfer_type = TYPE_LOAD; |
471 |
+ |
break; |
472 |
+ |
case 0x40: |
473 |
+ |
reg = (eip[2] >> 3) & 7; |
474 |
+ |
transfer_type = TYPE_LOAD; |
475 |
+ |
break; |
476 |
+ |
case 0x00: |
477 |
+ |
reg = (eip[2] >> 3) & 7; |
478 |
+ |
transfer_type = TYPE_LOAD; |
479 |
+ |
break; |
480 |
+ |
} |
481 |
+ |
len += 3 + ix86_step_over_modrm(eip + 2); |
482 |
+ |
} |
483 |
+ |
break; |
484 |
|
case 0x8a: // MOV r8, r/m8 |
485 |
|
transfer_size = SIZE_BYTE; |
486 |
|
case 0x8b: // MOV r32, r/m32 (or 16-bit operation) |
803 |
|
if (!sigsegv_install_handler(sigsegv_insn_handler)) |
804 |
|
return 1; |
805 |
|
|
806 |
< |
if (vm_protect((char *)page, page_size, VM_PAGE_WRITE) < 0) |
806 |
> |
if (vm_protect((char *)page, page_size, VM_PAGE_READ | VM_PAGE_WRITE) < 0) |
807 |
|
return 1; |
808 |
|
|
809 |
|
for (int i = 0; i < page_size; i++) |