First Patch
[lazyeval.git] / withUdis.c
1 #include <stdio.h>
2 #include <signal.h>
3 #include <string.h>
4 #include <stdlib.h>
5 #define __USE_GNU
6 #include <ucontext.h>
7 #include <udis86.h>
8
9 /* This code is only for x86_64 */
10
11 int k = 42;
12
13 void handle_segv(int segv, siginfo_t* siginfo, void* ucontext) {
14   ucontext_t* uc = (ucontext_t*) ucontext;
15
16   /* do disassembly at from IP */
17   ud_t ud_obj;
18   ud_init(&ud_obj);
19   ud_set_mode(&ud_obj, 64);
20   ud_set_syntax(&ud_obj, UD_SYN_ATT);
21   ud_set_input_buffer(&ud_obj, (unsigned char*) uc->uc_mcontext.gregs[REG_RIP],
22                       10);
23
24   /* was disassembly successful? */
25   if (!ud_disassemble(&ud_obj)) {
26     printf("Disassembly fail!\n");
27     exit(-1);
28   }
29
30   /* is disassembly a memory-operation? */
31   struct ud_operand op0 = ud_obj.operand[0];
32   struct ud_operand op1 = ud_obj.operand[1];
33   struct ud_operand op;
34
35   if (op0.type == UD_OP_MEM) {
36     op = op0;
37   } else if (op1.type == UD_OP_MEM) {
38     op = op1;
39   } else {
40     printf("Instruction unknown\n");
41     exit(-1);
42   }
43
44   /* find out the register - this part is clumsy as we have two sets
45      of constants */
46
47   int setreg;
48   switch (op.base) {
49   case UD_R_RAX:
50   case UD_R_EAX:
51     setreg = REG_RAX;
52     break;
53   case UD_R_RCX:
54   case UD_R_ECX:
55     setreg = REG_RCX;
56     break;
57   case UD_R_RDX:
58   case UD_R_EDX:
59     setreg = REG_RDX;
60     break;
61   case UD_R_RBX:
62   case UD_R_EBX:
63     setreg = REG_RBX;
64     break;
65   case UD_R_RSP:
66   case UD_R_ESP:
67     setreg = REG_RSP;
68     break;
69   case UD_R_RBP:
70   case UD_R_EBP:
71     setreg = REG_RBP;
72     break;
73   case UD_R_RSI:
74   case UD_R_ESI:
75     setreg = REG_RSI;
76     break;
77   case UD_R_RDI:
78   case UD_R_EDI:
79     setreg = REG_RDI;
80     break;
81   case UD_R_R8:
82   case UD_R_R8D:
83     setreg = REG_R8;
84     break;
85   case UD_R_R9:
86   case UD_R_R9D:
87     setreg = REG_R9;
88     break;
89   case UD_R_R10:
90   case UD_R_R10D:
91     setreg = REG_R10;
92     break;
93   case UD_R_R11:
94   case UD_R_R11D:
95     setreg = REG_R11;
96     break;
97   case UD_R_R12:
98   case UD_R_R12D:
99     setreg = REG_R12;
100     break;
101   case UD_R_R13:
102   case UD_R_R13D:
103     setreg = REG_R13;
104     break;
105   case UD_R_R14:
106   case UD_R_R14D:
107     setreg = REG_R14;
108     break;
109   case UD_R_R15:
110   case UD_R_R15D:
111     setreg = REG_R15;
112     break;
113   default:
114     printf("Register not supported!\n");
115     exit(-1);
116   }
117
118   /* set the register - as before */
119   uc->uc_mcontext.gregs[setreg] = (greg_t) &k;
120 }
121
122 void cause_segv (int* ptr) {
123   int d;
124   d =  *ptr;
125   printf("%d\n", d);
126 }
127
128 int main (void) {
129   struct sigaction q;
130   bzero(&q, sizeof(q));
131   q.sa_sigaction = handle_segv;
132   q.sa_flags = SA_SIGINFO;
133   sigaction(11, &q, NULL);
134   cause_segv(NULL);
135 }