ragweed 0.1.7.3 → 0.2.0.pre1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.rdoc +33 -8
- data/Rakefile +80 -23
- data/VERSION +1 -0
- data/examples/hittracertux.rb +2 -6
- data/examples/hook_notepad.rb +1 -1
- data/examples/tux-example.rb +3 -2
- data/lib/.DS_Store +0 -0
- data/lib/ragweed/debugger32.rb +188 -145
- data/lib/ragweed/debuggerosx.rb +13 -13
- data/lib/ragweed/debuggertux.rb +267 -140
- data/lib/ragweed/rasm.rb +1 -1
- data/lib/ragweed/wrap32/debugging.rb +184 -64
- data/lib/ragweed/wrap32/hooks.rb +27 -11
- data/lib/ragweed/wrap32/process.rb +114 -7
- data/lib/ragweed/wrap32/process_token.rb +23 -7
- data/lib/ragweed/wrap32/thread_context.rb +100 -166
- data/lib/ragweed/wrap32/wrap32.rb +127 -72
- data/lib/ragweed/wrap32.rb +1 -1
- data/lib/ragweed/wraposx/constants.rb +1 -9
- data/lib/ragweed/wraposx/region_info.rb +209 -188
- data/lib/ragweed/wraposx/structs.rb +102 -0
- data/lib/ragweed/wraposx/thread_context.rb +636 -159
- data/lib/ragweed/wraposx/thread_info.rb +40 -107
- data/lib/ragweed/wraposx/thread_info.rb.old +121 -0
- data/lib/ragweed/wraposx/wraposx.rb +154 -231
- data/lib/ragweed/wraposx.rb +2 -1
- data/lib/ragweed/wraptux/constants.rb +46 -22
- data/lib/ragweed/wraptux/struct_helpers.rb +25 -0
- data/lib/ragweed/wraptux/threads.rb +0 -0
- data/lib/ragweed/wraptux/wraptux.rb +58 -62
- data/lib/ragweed/wraptux.rb +3 -4
- data/lib/ragweed.rb +36 -8
- data/ragweed.gemspec +85 -15
- metadata +50 -18
@@ -1,203 +1,680 @@
|
|
1
|
+
# 127 ((x == x86_THREAD_STATE32) || \
|
2
|
+
# 128 (x == x86_FLOAT_STATE32) || \
|
3
|
+
# 129 (x == x86_EXCEPTION_STATE32) || \
|
4
|
+
# 130 (x == x86_DEBUG_STATE32) || \
|
5
|
+
# 131 (x == x86_THREAD_STATE64) || \
|
6
|
+
# 132 (x == x86_FLOAT_STATE64) || \
|
7
|
+
# 133 (x == x86_EXCEPTION_STATE64) || \
|
8
|
+
# 134 (x == x86_DEBUG_STATE64) || \
|
9
|
+
# 135 (x == x86_THREAD_STATE) || \
|
10
|
+
# 136 (x == x86_FLOAT_STATE) || \
|
11
|
+
# 137 (x == x86_EXCEPTION_STATE) || \
|
12
|
+
# 138 (x == x86_DEBUG_STATE) || \
|
13
|
+
|
1
14
|
module Ragweed; end
|
2
|
-
module Ragweed::Wraposx
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
15
|
+
module Ragweed::Wraposx::ThreadContext
|
16
|
+
|
17
|
+
X86_THREAD_STATE32 = 1
|
18
|
+
X86_FLOAT_STATE32 = 2
|
19
|
+
X86_EXCEPTION_STATE32 = 3
|
20
|
+
X86_DEBUG_STATE32 = 10
|
21
|
+
X86_THREAD_STATE64 = 4
|
22
|
+
X86_FLOAT_STATE64 = 5
|
23
|
+
X86_EXCEPTION_STATE64 = 6
|
24
|
+
X86_DEBUG_STATE64 = 11
|
25
|
+
# factory requests (return 32 or 64 bit structure)
|
26
|
+
X86_THREAD_STATE = 7
|
27
|
+
X86_FLOAT_STATE = 8
|
28
|
+
X86_EXCEPTION_STATE = 9
|
29
|
+
X86_DEBUG_STATE = 12
|
30
|
+
THREAD_STATE_NONE = 13
|
31
|
+
|
32
|
+
# depricated request names
|
33
|
+
I386_THREAD_STATE = X86_THREAD_STATE32
|
34
|
+
I386_FLOAT_STATE = X86_FLOAT_STATE32
|
35
|
+
I386_EXCEPTION_STATE = X86_EXCEPTION_STATE32
|
36
|
+
|
37
|
+
# struct x86_state_hdr {
|
38
|
+
# int flavor;
|
39
|
+
# int count;
|
40
|
+
# };
|
41
|
+
class X86StateHdr < FFI::Struct
|
42
|
+
include Ragweed::FFIStructInclude
|
43
|
+
layout :flavor, :int,
|
44
|
+
:count, :int
|
26
45
|
end
|
27
|
-
end
|
28
46
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
47
|
+
# _STRUCT_X86_THREAD_STATE32
|
48
|
+
# {
|
49
|
+
# unsigned int eax;
|
50
|
+
# unsigned int ebx;
|
51
|
+
# unsigned int ecx;
|
52
|
+
# unsigned int edx;
|
53
|
+
# unsigned int edi;
|
54
|
+
# unsigned int esi;
|
55
|
+
# unsigned int ebp;
|
56
|
+
# unsigned int esp;
|
57
|
+
# unsigned int ss;
|
58
|
+
# unsigned int eflags;
|
59
|
+
# unsigned int eip;
|
60
|
+
# unsigned int cs;
|
61
|
+
# unsigned int ds;
|
62
|
+
# unsigned int es;
|
63
|
+
# unsigned int fs;
|
64
|
+
# unsigned int gs;
|
65
|
+
# };
|
66
|
+
class State32 < FFI::Struct
|
67
|
+
include Ragweed::FFIStructInclude
|
68
|
+
FLAVOR = 1
|
69
|
+
layout :eax, :uint,
|
70
|
+
:ebx, :uint,
|
71
|
+
:ecx, :uint,
|
72
|
+
:edx, :uint,
|
73
|
+
:edi, :uint,
|
74
|
+
:esi, :uint,
|
75
|
+
:ebp, :uint,
|
76
|
+
:esp, :uint,
|
77
|
+
:ss, :uint,
|
78
|
+
:eflags, :uint,
|
79
|
+
:eip, :uint,
|
80
|
+
:cs, :uint,
|
81
|
+
:ds, :uint,
|
82
|
+
:es, :uint,
|
83
|
+
:fs, :uint,
|
84
|
+
:gs, :uint
|
85
|
+
|
86
|
+
module Flags
|
87
|
+
CARRY = 0x1
|
88
|
+
X0 = 0x2
|
89
|
+
PARITY = 0x4
|
90
|
+
X1 = 0x8
|
91
|
+
ADJUST = 0x10
|
92
|
+
X2 = 0x20
|
93
|
+
ZERO = 0x40
|
94
|
+
SIGN = 0x80
|
95
|
+
TRAP = 0x100
|
96
|
+
INTERRUPT = 0x200
|
97
|
+
DIRECTION = 0x400
|
98
|
+
OVERFLOW = 0x800
|
99
|
+
IOPL1 = 0x1000
|
100
|
+
IOPL2 = 0x2000
|
101
|
+
NESTEDTASK = 0x4000
|
102
|
+
X3 = 0x8000
|
103
|
+
RESUME = 0x10000
|
104
|
+
V86MODE = 0x20000
|
105
|
+
ALIGNCHECK = 0x40000
|
106
|
+
VINT = 0x80000
|
107
|
+
VINTPENDING = 0x100000
|
108
|
+
CPUID = 0x200000
|
109
|
+
end
|
110
|
+
|
111
|
+
def dump(&block)
|
112
|
+
maybe_hex = lambda {|a| begin; "\n" + (" " * 9) + block.call(a, 16).hexdump(true)[10..-2]; rescue; ""; end }
|
113
|
+
maybe_dis = lambda {|a| begin; "\n" + block.call(a, 16).distorm.map {|i| " " + i.mnem}.join("\n"); rescue; ""; end }
|
114
|
+
|
115
|
+
string =<<EOM
|
116
|
+
-----------------------------------------------------------------------
|
117
|
+
CONTEXT:
|
118
|
+
EIP: #{self.eip.to_s(16).rjust(8, "0")} #{maybe_dis.call(self.eip)}
|
119
|
+
|
120
|
+
EAX: #{self.eax.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.eax)}
|
121
|
+
EBX: #{self.ebx.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.ebx)}
|
122
|
+
ECX: #{self.ecx.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.ecx)}
|
123
|
+
EDX: #{self.edx.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.edx)}
|
124
|
+
EDI: #{self.edi.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.edi)}
|
125
|
+
ESI: #{self.esi.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.esi)}
|
126
|
+
EBP: #{self.ebp.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.ebp)}
|
127
|
+
ESP: #{self.esp.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.esp)}
|
128
|
+
EFL: #{self.eflags.to_s(2).rjust(32, "0")} #{Flags.flag_dump(self.eflags)}
|
129
|
+
EOM
|
130
|
+
end
|
131
|
+
|
132
|
+
# sets/clears the TRAP flag
|
133
|
+
def single_step(v=true)
|
134
|
+
if v
|
135
|
+
self.eflags |= Flags::TRAP
|
136
|
+
else
|
137
|
+
self.eflags &= ~(Flags::TRAP)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
# _STRUCT_X86_THREAD_STATE64
|
143
|
+
# {
|
144
|
+
# __uint64_t rax;
|
145
|
+
# __uint64_t rbx;
|
146
|
+
# __uint64_t rcx;
|
147
|
+
# __uint64_t rdx;
|
148
|
+
# __uint64_t rdi;
|
149
|
+
# __uint64_t rsi;
|
150
|
+
# __uint64_t rbp;
|
151
|
+
# __uint64_t rsp;
|
152
|
+
# __uint64_t r8;
|
153
|
+
# __uint64_t r9;
|
154
|
+
# __uint64_t r10;
|
155
|
+
# __uint64_t r11;
|
156
|
+
# __uint64_t r12;
|
157
|
+
# __uint64_t r13;
|
158
|
+
# __uint64_t r14;
|
159
|
+
# __uint64_t r15;
|
160
|
+
# __uint64_t rip;
|
161
|
+
# __uint64_t rflags;
|
162
|
+
# __uint64_t cs;
|
163
|
+
# __uint64_t fs;
|
164
|
+
# __uint64_t gs;
|
165
|
+
# };
|
166
|
+
class State64 < FFI::Struct
|
167
|
+
include Ragweed::FFIStructInclude
|
168
|
+
FLAVOR = 4
|
169
|
+
layout :rax, :uint64,
|
170
|
+
:rbx, :uint64,
|
171
|
+
:rcx, :uint64,
|
172
|
+
:rdx, :uint64,
|
173
|
+
:rdi, :uint64,
|
174
|
+
:rsi, :uint64,
|
175
|
+
:rbp, :uint64,
|
176
|
+
:rsp, :uint64,
|
177
|
+
:r8, :uint64,
|
178
|
+
:r9, :uint64,
|
179
|
+
:r10, :uint64,
|
180
|
+
:r11, :uint64,
|
181
|
+
:r12, :uint64,
|
182
|
+
:r13, :uint64,
|
183
|
+
:r14, :uint64,
|
184
|
+
:r15, :uint64,
|
185
|
+
:rip, :uint64,
|
186
|
+
:rflags, :uint64,
|
187
|
+
:cs, :uint64,
|
188
|
+
:fs, :uint64,
|
189
|
+
:gs, :uint64,
|
190
|
+
|
191
|
+
module Flags
|
192
|
+
CARRY = 0x1
|
193
|
+
X0 = 0x2
|
194
|
+
PARITY = 0x4
|
195
|
+
X1 = 0x8
|
196
|
+
ADJUST = 0x10
|
197
|
+
X2 = 0x20
|
198
|
+
ZERO = 0x40
|
199
|
+
SIGN = 0x80
|
200
|
+
TRAP = 0x100
|
201
|
+
INTERRUPT = 0x200
|
202
|
+
DIRECTION = 0x400
|
203
|
+
OVERFLOW = 0x800
|
204
|
+
IOPL1 = 0x1000
|
205
|
+
IOPL2 = 0x2000
|
206
|
+
NESTEDTASK = 0x4000
|
207
|
+
X3 = 0x8000
|
208
|
+
RESUME = 0x10000
|
209
|
+
V86MODE = 0x20000
|
210
|
+
ALIGNCHECK = 0x40000
|
211
|
+
VINT = 0x80000
|
212
|
+
VINTPENDING = 0x100000
|
213
|
+
CPUID = 0x200000
|
214
|
+
end
|
215
|
+
|
216
|
+
def dump(&block)
|
217
|
+
maybe_hex = lambda {|a| begin; "\n" + (" " * 9) + block.call(a, 16).hexdump(true)[10..-2]; rescue; ""; end }
|
218
|
+
maybe_dis = lambda {|a| begin; "\n" + block.call(a, 16).distorm.map {|i| " " + i.mnem}.join("\n"); rescue; ""; end }
|
219
|
+
|
220
|
+
string =<<EOM
|
221
|
+
-----------------------------------------------------------------------
|
222
|
+
CONTEXT:
|
223
|
+
RIP: #{self.rip.to_s(16).rjust(16, "0")} #{maybe_dis.call(self.eip)}
|
224
|
+
|
225
|
+
RAX: #{self.rax.to_s(16).rjust(16, "0")} #{maybe_hex.call(self.eax)}
|
226
|
+
RBX: #{self.rbx.to_s(16).rjust(16, "0")} #{maybe_hex.call(self.ebx)}
|
227
|
+
RCX: #{self.rcx.to_s(16).rjust(16, "0")} #{maybe_hex.call(self.ecx)}
|
228
|
+
RDX: #{self.rdx.to_s(16).rjust(16, "0")} #{maybe_hex.call(self.edx)}
|
229
|
+
RDI: #{self.rdi.to_s(16).rjust(16, "0")} #{maybe_hex.call(self.edi)}
|
230
|
+
RSI: #{self.rsi.to_s(16).rjust(16, "0")} #{maybe_hex.call(self.esi)}
|
231
|
+
RBP: #{self.rbp.to_s(16).rjust(16, "0")} #{maybe_hex.call(self.ebp)}
|
232
|
+
RSP: #{self.rsp.to_s(16).rjust(16, "0")} #{maybe_hex.call(self.esp)}
|
233
|
+
RFL: #{(self.rflags & 0xffffffff).to_s(2).rjust(32, "0")} #{Flags.flag_dump(self.rflags & 0xffffffff)}
|
234
|
+
EOM
|
235
|
+
end
|
236
|
+
|
237
|
+
# sets/clears the TRAP flag
|
238
|
+
def single_step(v=true)
|
239
|
+
if v
|
240
|
+
@rflags |= Flags::TRAP
|
241
|
+
else
|
242
|
+
@rflags &= ~(Flags::TRAP)
|
243
|
+
end
|
59
244
|
end
|
60
245
|
end
|
61
246
|
|
62
|
-
|
63
|
-
|
247
|
+
class UnionThreadState < FFI::Union
|
248
|
+
include Ragweed::FFIStructInclude
|
249
|
+
layout :ts32, Ragweed::Wraposx::ThreadContext::State32,
|
250
|
+
:ts64, Ragweed::Wraposx::ThreadContext::State64
|
64
251
|
end
|
65
252
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
Wraposx::
|
70
|
-
|
253
|
+
class State < FFI::Struct
|
254
|
+
include Ragweed::FFIStructInclude
|
255
|
+
FLAVOR = 7
|
256
|
+
layout :tsh, Ragweed::Wraposx::ThreadContext::X86StateHdr,
|
257
|
+
:uts, Ragweed::Wraposx::ThreadContext::UnionThreadState
|
71
258
|
end
|
72
259
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
260
|
+
# _STRUCT_X86_DEBUG_STATE32
|
261
|
+
# {
|
262
|
+
# unsigned int dr0;
|
263
|
+
# unsigned int dr1;
|
264
|
+
# unsigned int dr2;
|
265
|
+
# unsigned int dr3;
|
266
|
+
# unsigned int dr4;
|
267
|
+
# unsigned int dr5;
|
268
|
+
# unsigned int dr6;
|
269
|
+
# unsigned int dr7;
|
270
|
+
# };
|
271
|
+
class Debug32 < FFI::Struct
|
272
|
+
include Ragweed::FFIStructInclude
|
273
|
+
FLAVOR = 10
|
274
|
+
layout :dr0, :uint,
|
275
|
+
:dr1, :uint,
|
276
|
+
:dr2, :uint,
|
277
|
+
:dr3, :uint,
|
278
|
+
:dr4, :uint,
|
279
|
+
:dr5, :uint,
|
280
|
+
:dr6, :uint,
|
281
|
+
:dr7, :uint
|
282
|
+
|
283
|
+
def dump(&block)
|
284
|
+
maybe_hex = lambda {|a| begin; "\n" + (" " * 9) + block.call(a, 16).hexdump(true)[10..-2]; rescue; ""; end }
|
285
|
+
maybe_dis = lambda {|a| begin; "\n" + block.call(a, 16).distorm.map {|i| " " + i.mnem}.join("\n"); rescue; ""; end }
|
286
|
+
|
287
|
+
string =<<EOM
|
288
|
+
-----------------------------------------------------------------------
|
289
|
+
CONTEXT:
|
290
|
+
DR0: #{self.dr0.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.dr0)}
|
291
|
+
DR1: #{self.dr1.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.dr1)}
|
292
|
+
DR2: #{self.dr2.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.dr2)}
|
293
|
+
DR3: #{self.dr3.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.dr3)}
|
294
|
+
DR4: #{self.dr4.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.dr4)}
|
295
|
+
DR5: #{self.dr5.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.dr5)}
|
296
|
+
DR6: #{self.dr6.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.dr6)}
|
297
|
+
DR7: #{self.dr7.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.dr7)}
|
298
|
+
EOM
|
299
|
+
end
|
78
300
|
end
|
79
301
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
302
|
+
# _STRUCT_X86_DEBUG_STATE64
|
303
|
+
# {
|
304
|
+
# __uint64_t dr0;
|
305
|
+
# __uint64_t dr1;
|
306
|
+
# __uint64_t dr2;
|
307
|
+
# __uint64_t dr3;
|
308
|
+
# __uint64_t dr4;
|
309
|
+
# __uint64_t dr5;
|
310
|
+
# __uint64_t dr6;
|
311
|
+
# __uint64_t dr7;
|
312
|
+
# };
|
313
|
+
class Debug64 < FFI::Struct
|
314
|
+
include Ragweed::FFIStructInclude
|
315
|
+
FLAVOR = 11
|
316
|
+
layout :dr0, :uint64,
|
317
|
+
:dr1, :uint64,
|
318
|
+
:dr2, :uint64,
|
319
|
+
:dr3, :uint64,
|
320
|
+
:dr4, :uint64,
|
321
|
+
:dr5, :uint64,
|
322
|
+
:dr6, :uint64,
|
323
|
+
:dr7, :uint64
|
324
|
+
|
325
|
+
def dump(&block)
|
326
|
+
maybe_hex = lambda {|a| begin; "\n" + (" " * 9) + block.call(a, 16).hexdump(true)[10..-2]; rescue; ""; end }
|
327
|
+
maybe_dis = lambda {|a| begin; "\n" + block.call(a, 16).distorm.map {|i| " " + i.mnem}.join("\n"); rescue; ""; end }
|
328
|
+
|
329
|
+
string =<<EOM
|
330
|
+
-----------------------------------------------------------------------
|
331
|
+
CONTEXT:
|
332
|
+
DR0: #{self.dr0.to_s(16).rjust(16, "0")} #{maybe_hex.call(self.dr0)}
|
333
|
+
DR1: #{self.dr1.to_s(16).rjust(16, "0")} #{maybe_hex.call(self.dr1)}
|
334
|
+
DR2: #{self.dr2.to_s(16).rjust(16, "0")} #{maybe_hex.call(self.dr2)}
|
335
|
+
DR3: #{self.dr3.to_s(16).rjust(16, "0")} #{maybe_hex.call(self.dr3)}
|
336
|
+
DR4: #{self.dr4.to_s(16).rjust(16, "0")} #{maybe_hex.call(self.dr4)}
|
337
|
+
DR5: #{self.dr5.to_s(16).rjust(16, "0")} #{maybe_hex.call(self.dr5)}
|
338
|
+
DR6: #{self.dr6.to_s(16).rjust(16, "0")} #{maybe_hex.call(self.dr6)}
|
339
|
+
DR7: #{self.dr7.to_s(16).rjust(16, "0")} #{maybe_hex.call(self.dr7)}
|
340
|
+
EOM
|
341
|
+
end
|
342
|
+
end
|
343
|
+
|
344
|
+
class UnionDebugState < FFI::Union
|
345
|
+
include Ragweed::FFIStructInclude
|
346
|
+
layout :ds32, Ragweed::Wraposx::ThreadContext::Debug32,
|
347
|
+
:ds64, Ragweed::Wraposx::ThreadContext::Debug64
|
348
|
+
end
|
349
|
+
|
350
|
+
class Debug < FFI::Struct
|
351
|
+
include Ragweed::FFIStructInclude
|
352
|
+
FLAVOR = 12
|
353
|
+
layout :dsh, Ragweed::Wraposx::ThreadContext::X86StateHdr,
|
354
|
+
:uds, Ragweed::Wraposx::ThreadContext::UnionDebugState
|
355
|
+
end
|
356
|
+
|
357
|
+
# _STRUCT_X86_EXCEPTION_STATE32
|
358
|
+
# {
|
359
|
+
# unsigned int trapno;
|
360
|
+
# unsigned int err;
|
361
|
+
# unsigned int faultvaddr;
|
362
|
+
# };
|
363
|
+
class Exception32 < FFI::Struct
|
364
|
+
include Ragweed::FFIStructInclude
|
365
|
+
FLAVOR = 3
|
366
|
+
layout :trapno, :uint,
|
367
|
+
:err, :uint,
|
368
|
+
:faltvaddr, :uint
|
369
|
+
|
370
|
+
def dump(&block)
|
371
|
+
maybe_hex = lambda {|a| begin; "\n" + (" " * 9) + block.call(a, 16).hexdump(true)[10..-2]; rescue; ""; end }
|
372
|
+
maybe_dis = lambda {|a| begin; "\n" + block.call(a, 16).distorm.map {|i| " " + i.mnem}.join("\n"); rescue; ""; end }
|
373
|
+
|
374
|
+
string =<<EOM
|
375
|
+
-----------------------------------------------------------------------
|
376
|
+
CONTEXT:
|
377
|
+
trapno: #{self.trapno.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.trapno)}
|
378
|
+
err: #{self.err.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.err)}
|
379
|
+
faultvaddr: #{self.faultvaddr.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.faultvaddr)}
|
380
|
+
EOM
|
381
|
+
end
|
85
382
|
end
|
86
383
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
384
|
+
# _STRUCT_X86_EXCEPTION_STATE64
|
385
|
+
# {
|
386
|
+
# unsigned int trapno;
|
387
|
+
# unsigned int err;
|
388
|
+
# __uint64_t faultvaddr;
|
389
|
+
# };
|
390
|
+
class Exception64 < FFI::Struct
|
391
|
+
include Ragweed::FFIStructInclude
|
392
|
+
FLAVOR = 6
|
393
|
+
layout :trapno, :uint,
|
394
|
+
:err, :uint,
|
395
|
+
:faltvaddr, :uint64
|
396
|
+
|
397
|
+
def dump(&block)
|
398
|
+
maybe_hex = lambda {|a| begin; "\n" + (" " * 9) + block.call(a, 16).hexdump(true)[10..-2]; rescue; ""; end }
|
399
|
+
maybe_dis = lambda {|a| begin; "\n" + block.call(a, 16).distorm.map {|i| " " + i.mnem}.join("\n"); rescue; ""; end }
|
400
|
+
|
401
|
+
string =<<EOM
|
402
|
+
-----------------------------------------------------------------------
|
403
|
+
CONTEXT:
|
404
|
+
trapno: #{self.trapno.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.trapno)}
|
405
|
+
err: #{self.err.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.err)}
|
406
|
+
faultvaddr: #{self.faultvaddr.to_s(16).rjust(16, "0")} #{maybe_hex.call(self.faultvaddr)}
|
407
|
+
EOM
|
92
408
|
end
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
409
|
+
end
|
410
|
+
|
411
|
+
class UnionExceptionState < FFI::Union
|
412
|
+
include Ragweed::FFIStructInclude
|
413
|
+
layout :es32, Ragweed::Wraposx::ThreadContext::Exception32,
|
414
|
+
:es64, Ragweed::Wraposx::ThreadContext::Exception64
|
415
|
+
end
|
416
|
+
|
417
|
+
class Exception < FFI::Struct
|
418
|
+
include Ragweed::FFIStructInclude
|
419
|
+
FLAVOR = 9
|
420
|
+
layout :esh, Ragweed::Wraposx::ThreadContext::X86StateHdr,
|
421
|
+
:ues, Ragweed::Wraposx::ThreadContext::UnionExceptionState
|
422
|
+
end
|
423
|
+
|
424
|
+
# _STRUCT_X86_FLOAT_STATE32
|
425
|
+
# {
|
426
|
+
# int fpu_reserved[2];
|
427
|
+
# _STRUCT_FP_CONTROL fpu_fcw; /* x87 FPU control word */
|
428
|
+
# _STRUCT_FP_STATUS fpu_fsw; /* x87 FPU status word */
|
429
|
+
# __uint8_t fpu_ftw; /* x87 FPU tag word */
|
430
|
+
# __uint8_t fpu_rsrv1; /* reserved */
|
431
|
+
# __uint16_t fpu_fop; /* x87 FPU Opcode */
|
432
|
+
# __uint32_t fpu_ip; /* x87 FPU Instruction Pointer offset */
|
433
|
+
# __uint16_t fpu_cs; /* x87 FPU Instruction Pointer Selector */
|
434
|
+
# __uint16_t fpu_rsrv2; /* reserved */
|
435
|
+
# __uint32_t fpu_dp; /* x87 FPU Instruction Operand(Data) Pointer offset */
|
436
|
+
# __uint16_t fpu_ds; /* x87 FPU Instruction Operand(Data) Pointer Selector */
|
437
|
+
# __uint16_t fpu_rsrv3; /* reserved */
|
438
|
+
# __uint32_t fpu_mxcsr; /* MXCSR Register state */
|
439
|
+
# __uint32_t fpu_mxcsrmask; /* MXCSR mask */
|
440
|
+
# _STRUCT_MMST_REG fpu_stmm0; /* ST0/MM0 */
|
441
|
+
# _STRUCT_MMST_REG fpu_stmm1; /* ST1/MM1 */
|
442
|
+
# _STRUCT_MMST_REG fpu_stmm2; /* ST2/MM2 */
|
443
|
+
# _STRUCT_MMST_REG fpu_stmm3; /* ST3/MM3 */
|
444
|
+
# _STRUCT_MMST_REG fpu_stmm4; /* ST4/MM4 */
|
445
|
+
# _STRUCT_MMST_REG fpu_stmm5; /* ST5/MM5 */
|
446
|
+
# _STRUCT_MMST_REG fpu_stmm6; /* ST6/MM6 */
|
447
|
+
# _STRUCT_MMST_REG fpu_stmm7; /* ST7/MM7 */
|
448
|
+
# _STRUCT_XMM_REG fpu_xmm0; /* XMM 0 */
|
449
|
+
# _STRUCT_XMM_REG fpu_xmm1; /* XMM 1 */
|
450
|
+
# _STRUCT_XMM_REG fpu_xmm2; /* XMM 2 */
|
451
|
+
# _STRUCT_XMM_REG fpu_xmm3; /* XMM 3 */
|
452
|
+
# _STRUCT_XMM_REG fpu_xmm4; /* XMM 4 */
|
453
|
+
# _STRUCT_XMM_REG fpu_xmm5; /* XMM 5 */
|
454
|
+
# _STRUCT_XMM_REG fpu_xmm6; /* XMM 6 */
|
455
|
+
# _STRUCT_XMM_REG fpu_xmm7; /* XMM 7 */
|
456
|
+
# char fpu_rsrv4[14*16]; /* reserved */
|
457
|
+
# int fpu_reserved1;
|
458
|
+
# };
|
459
|
+
class Float32 < FFI::Struct
|
460
|
+
include Ragweed::FFIStructInclude
|
461
|
+
FLAVOR = 2
|
462
|
+
layout :fpu_reserved, [:int, 2],
|
463
|
+
:fpu_fcw, Ragweed::Wraposx::FpControl,
|
464
|
+
:fpu_fsw, Ragweed::Wraposx::FpStatus,
|
465
|
+
:fpu_ftw, :uint8,
|
466
|
+
:fpu_rsrv1, :uint8,
|
467
|
+
:fpu_fop, :uint16,
|
468
|
+
:fpu_ip, :uint32,
|
469
|
+
:fpu_cs, :uint16,
|
470
|
+
:fpu_rsrv2, :uint16,
|
471
|
+
:fpu_dp, :uint32,
|
472
|
+
:fpu_ds, :uint16,
|
473
|
+
:fpu_rsrv3, :uint16,
|
474
|
+
:fpu_mxcsr, :uint32,
|
475
|
+
:fpu_mxcsrmask, :uint32,
|
476
|
+
:fpu_stmm0, Ragweed::Wraposx::MmstReg,
|
477
|
+
:fpu_stmm1, Ragweed::Wraposx::MmstReg,
|
478
|
+
:fpu_stmm2, Ragweed::Wraposx::MmstReg,
|
479
|
+
:fpu_stmm3, Ragweed::Wraposx::MmstReg,
|
480
|
+
:fpu_stmm4, Ragweed::Wraposx::MmstReg,
|
481
|
+
:fpu_stmm5, Ragweed::Wraposx::MmstReg,
|
482
|
+
:fpu_stmm6, Ragweed::Wraposx::MmstReg,
|
483
|
+
:fpu_stmm7, Ragweed::Wraposx::MmstReg,
|
484
|
+
:fpu_xmm0, Ragweed::Wraposx::XmmReg,
|
485
|
+
:fpu_xmm1, Ragweed::Wraposx::XmmReg,
|
486
|
+
:fpu_xmm2, Ragweed::Wraposx::XmmReg,
|
487
|
+
:fpu_xmm3, Ragweed::Wraposx::XmmReg,
|
488
|
+
:fpu_xmm4, Ragweed::Wraposx::XmmReg,
|
489
|
+
:fpu_xmm5, Ragweed::Wraposx::XmmReg,
|
490
|
+
:fpu_xmm6, Ragweed::Wraposx::XmmReg,
|
491
|
+
:fpu_xmm7, Ragweed::Wraposx::XmmReg,
|
492
|
+
:fpu_rsrv4, [:char, 14*16],
|
493
|
+
:fpu_reserved1, :int
|
494
|
+
|
495
|
+
def dump(&block)
|
496
|
+
maybe_hex = lambda {|a| begin; "\n" + (" " * 9) + block.call(a, 16).hexdump(true)[10..-2]; rescue; ""; end }
|
497
|
+
maybe_dis = lambda {|a| begin; "\n" + block.call(a, 16).distorm.map {|i| " " + i.mnem}.join("\n"); rescue; ""; end }
|
498
|
+
|
499
|
+
string =<<EOM
|
500
|
+
-----------------------------------------------------------------------
|
501
|
+
CONTEXT:
|
502
|
+
trapno: #{self.trapno.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.trapno)}
|
503
|
+
err: #{self.err.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.err)}
|
504
|
+
faultvaddr: #{self.faultvaddr.to_s(16).rjust(16, "0")} #{maybe_hex.call(self.faultvaddr)}
|
114
505
|
EOM
|
506
|
+
end
|
115
507
|
end
|
116
508
|
|
117
|
-
#
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
509
|
+
# _STRUCT_X86_FLOAT_STATE64
|
510
|
+
# {
|
511
|
+
# int fpu_reserved[2];
|
512
|
+
# _STRUCT_FP_CONTROL fpu_fcw; /* x87 FPU control word */
|
513
|
+
# _STRUCT_FP_STATUS fpu_fsw; /* x87 FPU status word */
|
514
|
+
# __uint8_t fpu_ftw; /* x87 FPU tag word */
|
515
|
+
# __uint8_t fpu_rsrv1; /* reserved */
|
516
|
+
# __uint16_t fpu_fop; /* x87 FPU Opcode */
|
517
|
+
# /* x87 FPU Instruction Pointer */
|
518
|
+
# __uint32_t fpu_ip; /* offset */
|
519
|
+
# __uint16_t fpu_cs; /* Selector */
|
520
|
+
# __uint16_t fpu_rsrv2; /* reserved */
|
521
|
+
# /* x87 FPU Instruction Operand(Data) Pointer */
|
522
|
+
# __uint32_t fpu_dp; /* offset */
|
523
|
+
# __uint16_t fpu_ds; /* Selector */
|
524
|
+
# __uint16_t fpu_rsrv3; /* reserved */
|
525
|
+
# __uint32_t fpu_mxcsr; /* MXCSR Register state */
|
526
|
+
# __uint32_t fpu_mxcsrmask; /* MXCSR mask */
|
527
|
+
# _STRUCT_MMST_REG fpu_stmm0; /* ST0/MM0 */
|
528
|
+
# _STRUCT_MMST_REG fpu_stmm1; /* ST1/MM1 */
|
529
|
+
# _STRUCT_MMST_REG fpu_stmm2; /* ST2/MM2 */
|
530
|
+
# _STRUCT_MMST_REG fpu_stmm3; /* ST3/MM3 */
|
531
|
+
# _STRUCT_MMST_REG fpu_stmm4; /* ST4/MM4 */
|
532
|
+
# _STRUCT_MMST_REG fpu_stmm5; /* ST5/MM5 */
|
533
|
+
# _STRUCT_MMST_REG fpu_stmm6; /* ST6/MM6 */
|
534
|
+
# _STRUCT_MMST_REG fpu_stmm7; /* ST7/MM7 */
|
535
|
+
# _STRUCT_XMM_REG fpu_xmm0; /* XMM 0 */
|
536
|
+
# _STRUCT_XMM_REG fpu_xmm1; /* XMM 1 */
|
537
|
+
# _STRUCT_XMM_REG fpu_xmm2; /* XMM 2 */
|
538
|
+
# _STRUCT_XMM_REG fpu_xmm3; /* XMM 3 */
|
539
|
+
# _STRUCT_XMM_REG fpu_xmm4; /* XMM 4 */
|
540
|
+
# _STRUCT_XMM_REG fpu_xmm5; /* XMM 5 */
|
541
|
+
# _STRUCT_XMM_REG fpu_xmm6; /* XMM 6 */
|
542
|
+
# _STRUCT_XMM_REG fpu_xmm7; /* XMM 7 */
|
543
|
+
# _STRUCT_XMM_REG fpu_xmm8; /* XMM 8 */
|
544
|
+
# _STRUCT_XMM_REG fpu_xmm9; /* XMM 9 */
|
545
|
+
# _STRUCT_XMM_REG fpu_xmm10; /* XMM 10 */
|
546
|
+
# _STRUCT_XMM_REG fpu_xmm11; /* XMM 11 */
|
547
|
+
# _STRUCT_XMM_REG fpu_xmm12; /* XMM 12 */
|
548
|
+
# _STRUCT_XMM_REG fpu_xmm13; /* XMM 13 */
|
549
|
+
# _STRUCT_XMM_REG fpu_xmm14; /* XMM 14 */
|
550
|
+
# _STRUCT_XMM_REG fpu_xmm15; /* XMM 15 */
|
551
|
+
# char fpu_rsrv4[6*16]; /* reserved */
|
552
|
+
# int fpu_reserved1;
|
553
|
+
# };
|
554
|
+
class Float64 < FFI::Struct
|
555
|
+
include Ragweed::FFIStructInclude
|
556
|
+
FLAVOR = 5
|
557
|
+
layout :fpu_reserved, [:int, 2],
|
558
|
+
:fpu_fcw, Ragweed::Wraposx::FpControl,
|
559
|
+
:fpu_fsw, Ragweed::Wraposx::FpStatus,
|
560
|
+
:fpu_ftw, :uint8,
|
561
|
+
:fpu_rsrv1, :uint8,
|
562
|
+
:fpu_fop, :uint16,
|
563
|
+
:fpu_ip, :uint32,
|
564
|
+
:fpu_cs, :uint16,
|
565
|
+
:fpu_rsrv2, :uint16,
|
566
|
+
:fpu_dp, :uint32,
|
567
|
+
:fpu_ds, :uint16,
|
568
|
+
:fpu_rsrv3, :uint16,
|
569
|
+
:fpu_mxcsr, :uint32,
|
570
|
+
:fpu_mxcsrmask, :uint32,
|
571
|
+
:fpu_stmm0, Ragweed::Wraposx::MmstReg,
|
572
|
+
:fpu_stmm1, Ragweed::Wraposx::MmstReg,
|
573
|
+
:fpu_stmm2, Ragweed::Wraposx::MmstReg,
|
574
|
+
:fpu_stmm3, Ragweed::Wraposx::MmstReg,
|
575
|
+
:fpu_stmm4, Ragweed::Wraposx::MmstReg,
|
576
|
+
:fpu_stmm5, Ragweed::Wraposx::MmstReg,
|
577
|
+
:fpu_stmm6, Ragweed::Wraposx::MmstReg,
|
578
|
+
:fpu_stmm7, Ragweed::Wraposx::MmstReg,
|
579
|
+
:fpu_xmm0, Ragweed::Wraposx::XmmReg,
|
580
|
+
:fpu_xmm1, Ragweed::Wraposx::XmmReg,
|
581
|
+
:fpu_xmm2, Ragweed::Wraposx::XmmReg,
|
582
|
+
:fpu_xmm3, Ragweed::Wraposx::XmmReg,
|
583
|
+
:fpu_xmm4, Ragweed::Wraposx::XmmReg,
|
584
|
+
:fpu_xmm5, Ragweed::Wraposx::XmmReg,
|
585
|
+
:fpu_xmm6, Ragweed::Wraposx::XmmReg,
|
586
|
+
:fpu_xmm7, Ragweed::Wraposx::XmmReg,
|
587
|
+
:fpu_xmm8, Ragweed::Wraposx::XmmReg,
|
588
|
+
:fpu_xmm9, Ragweed::Wraposx::XmmReg,
|
589
|
+
:fpu_xmm10, Ragweed::Wraposx::XmmReg,
|
590
|
+
:fpu_xmm11, Ragweed::Wraposx::XmmReg,
|
591
|
+
:fpu_xmm12, Ragweed::Wraposx::XmmReg,
|
592
|
+
:fpu_xmm13, Ragweed::Wraposx::XmmReg,
|
593
|
+
:fpu_xmm14, Ragweed::Wraposx::XmmReg,
|
594
|
+
:fpu_xmm15, Ragweed::Wraposx::XmmReg,
|
595
|
+
:fpu_rsrv4, [:char, 6*16],
|
596
|
+
:fpu_reserved1, :int
|
597
|
+
|
598
|
+
|
599
|
+
def dump(&block)
|
600
|
+
maybe_hex = lambda {|a| begin; "\n" + (" " * 9) + block.call(a, 16).hexdump(true)[10..-2]; rescue; ""; end }
|
601
|
+
maybe_dis = lambda {|a| begin; "\n" + block.call(a, 16).distorm.map {|i| " " + i.mnem}.join("\n"); rescue; ""; end }
|
602
|
+
|
603
|
+
string =<<EOM
|
604
|
+
-----------------------------------------------------------------------
|
605
|
+
CONTEXT:
|
606
|
+
trapno: #{self.trapno.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.trapno)}
|
607
|
+
err: #{self.err.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.err)}
|
608
|
+
faultvaddr: #{self.faultvaddr.to_s(16).rjust(16, "0")} #{maybe_hex.call(self.faultvaddr)}
|
609
|
+
EOM
|
123
610
|
end
|
124
611
|
end
|
612
|
+
|
613
|
+
class UnionFloatState < FFI::Union
|
614
|
+
include Ragweed::FFIStructInclude
|
615
|
+
layout :fs32, Ragweed::Wraposx::ThreadContext::Float32,
|
616
|
+
:fs64, Ragweed::Wraposx::ThreadContext::Float64
|
617
|
+
end
|
618
|
+
|
619
|
+
class Float < FFI::Struct
|
620
|
+
include Ragweed::FFIStructInclude
|
621
|
+
FLAVOR = 8
|
622
|
+
layout :fsh, Ragweed::Wraposx::ThreadContext::X86StateHdr,
|
623
|
+
:ufs, Ragweed::Wraposx::ThreadContext::UnionFloatState
|
624
|
+
end
|
625
|
+
|
626
|
+
FLAVORS = {
|
627
|
+
X86_THREAD_STATE32 => {:size => 64, :count =>16, :class => State32},
|
628
|
+
X86_FLOAT_STATE32 => {:size => 64, :count =>16, :class => Float32},
|
629
|
+
X86_EXCEPTION_STATE32 => {:size => 12, :count =>3, :class => Exception32},
|
630
|
+
X86_DEBUG_STATE32 => {:size => 64, :count =>8, :class => Debug32},
|
631
|
+
X86_THREAD_STATE64 => {:size => 168, :count =>42, :class => State64},
|
632
|
+
X86_FLOAT_STATE64 => {:size => 64, :count =>16, :class => Float64},
|
633
|
+
X86_EXCEPTION_STATE64 => {:size => 16, :count =>4, :class => Exception64},
|
634
|
+
X86_DEBUG_STATE64 => {:size => 128, :count =>16, :class => Debug64},
|
635
|
+
X86_THREAD_STATE => {:size => 176, :count =>44, :class => State},
|
636
|
+
X86_FLOAT_STATE => {:size => 64, :count =>16, :class => Float},
|
637
|
+
X86_EXCEPTION_STATE => {:size => 24, :count =>6, :class => Exception},
|
638
|
+
X86_DEBUG_STATE => {:size => 136, :count =>18, :class => Debug}
|
639
|
+
}
|
125
640
|
end
|
126
641
|
|
127
642
|
module Ragweed::Wraposx
|
128
643
|
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
REGISTER_SYMS = [:eax,:ebx,:ecx,:edx,:edi,:esi,:ebp,:esp,:ss,:eflags,:eip,:cs,:ds,:es,:fs,:gs]
|
644
|
+
module Libc
|
645
|
+
extend FFI::Library
|
646
|
+
ffi_lib FFI::Library::LIBC
|
647
|
+
attach_function :thread_get_state, [:thread_act_t, :thread_state_flavor_t, :pointer, :mach_msg_type_number_t], :kern_return_t
|
648
|
+
attach_function :thread_set_state, [:thread_act_t, :thread_state_flavor_t, :pointer, :mach_msg_type_number_t], :kern_return_t
|
649
|
+
end
|
136
650
|
|
137
651
|
class << self
|
138
|
-
|
139
|
-
# Returns a Hash of the thread's registers given a thread id.
|
652
|
+
# Returns a thread's registers for given a thread id
|
140
653
|
#
|
141
654
|
# kern_return_t thread_get_state
|
142
655
|
# (thread_act_t target_thread,
|
143
656
|
# thread_state_flavor_t flavor,
|
144
657
|
# thread_state_t old_state,
|
145
658
|
# mach_msg_type_number_t old_state_count);
|
146
|
-
def thread_get_state(thread)
|
147
|
-
|
148
|
-
count =
|
149
|
-
r =
|
659
|
+
def thread_get_state(thread,flavor)
|
660
|
+
state = FFI::MemoryPointer.new Ragweed::Wraposx::ThreadContext::FLAVOR[flavor][:class], 1
|
661
|
+
count = FFI::MemoryPointer.new(:int, 1).write_int Ragweed::Wraposx::ThreadContext::FLAVOR[flavor][:count]
|
662
|
+
r = Libc.thread_get_state(thread, flavor, state, count)
|
150
663
|
raise KernelCallError.new(:thread_get_state, r) if r != 0
|
151
|
-
|
152
|
-
regs = Hash.new
|
153
|
-
I386_THREAD_STATE_COUNT.times do |i|
|
154
|
-
regs[REGISTER_SYMS[i]] = r[i]
|
155
|
-
end
|
156
|
-
return regs
|
157
|
-
end
|
158
|
-
|
159
|
-
# Returns string representation of a thread's registers for unpacking given a thread id
|
160
|
-
#
|
161
|
-
# kern_return_t thread_get_state
|
162
|
-
# (thread_act_t target_thread,
|
163
|
-
# thread_state_flavor_t flavor,
|
164
|
-
# thread_state_t old_state,
|
165
|
-
# mach_msg_type_number_t old_state_count);
|
166
|
-
def thread_get_state_raw(thread)
|
167
|
-
state_arr = ("\x00"*SIZEOFINT*I386_THREAD_STATE_COUNT).to_ptr
|
168
|
-
count = ([I386_THREAD_STATE_COUNT].pack("I_")).to_ptr
|
169
|
-
r = CALLS["libc!thread_get_state:IIPP=I"].call(thread, I386_THREAD_STATE, state_arr, count).first
|
170
|
-
raise KernelCallError.new(:thread_get_state, r) if r != 0
|
171
|
-
return state_arr.to_s(I386_THREAD_STATE_COUNT*SIZEOFINT)
|
172
|
-
end
|
173
|
-
|
174
|
-
# Sets the register state of thread from a Hash containing it's values.
|
175
|
-
#
|
176
|
-
# kern_return_t thread_set_state
|
177
|
-
# (thread_act_t target_thread,
|
178
|
-
# thread_state_flavor_t flavor,
|
179
|
-
# thread_state_t new_state,
|
180
|
-
# target_thread new_state_count);
|
181
|
-
def thread_set_state(thread, state)
|
182
|
-
s = Array.new
|
183
|
-
I386_THREAD_STATE_COUNT.times do |i|
|
184
|
-
s << state[REGISTER_SYMS[i]]
|
185
|
-
end
|
186
|
-
s = s.pack("I_"*I386_THREAD_STATE_COUNT).to_ptr
|
187
|
-
r = CALLS["libc!thread_set_state:IIPI=I"].call(thread, I386_THREAD_STATE, s, I386_THREAD_STATE_COUNT).first
|
188
|
-
raise KernelCallError.new(:thread_set_state, r) if r!= 0
|
664
|
+
Ragweed::Wraposx::ThreadContext::FLAVOR[flavor][:class].new state
|
189
665
|
end
|
190
666
|
|
191
|
-
# Sets the register state of thread
|
667
|
+
# Sets the register state of thread.
|
192
668
|
#
|
193
669
|
# kern_return_t thread_set_state
|
194
670
|
# (thread_act_t target_thread,
|
195
671
|
# thread_state_flavor_t flavor,
|
196
672
|
# thread_state_t new_state,
|
197
|
-
#
|
198
|
-
def
|
199
|
-
r =
|
673
|
+
# mach_msg_number_t new_state_count);
|
674
|
+
def thread_set_state(thread, flavor, state)
|
675
|
+
r = Libc.thread_set_state(thread, flavor, state.to_ptr, ThreadContext::FLAVORS[flavor][:count])
|
200
676
|
raise KernelCallError.new(:thread_set_state, r) if r!= 0
|
677
|
+
Ragweed::Wraposx::ThreadContext::FLAVOR[flavor][:class].new state
|
201
678
|
end
|
202
679
|
end
|
203
680
|
end
|