ragweed 0.1.7.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. data/History.txt +32 -0
  2. data/README.rdoc +35 -0
  3. data/README.txt +9 -0
  4. data/Rakefile +34 -0
  5. data/examples/hittracertux.rb +49 -0
  6. data/examples/hittracerx.rb +63 -0
  7. data/examples/hook_notepad.rb +9 -0
  8. data/examples/snicker.rb +183 -0
  9. data/examples/tux-example.rb +23 -0
  10. data/lib/ragweed/arena.rb +55 -0
  11. data/lib/ragweed/blocks.rb +128 -0
  12. data/lib/ragweed/debugger32.rb +338 -0
  13. data/lib/ragweed/debuggerosx.rb +427 -0
  14. data/lib/ragweed/debuggertux.rb +346 -0
  15. data/lib/ragweed/detour.rb +223 -0
  16. data/lib/ragweed/ptr.rb +48 -0
  17. data/lib/ragweed/rasm/bblock.rb +73 -0
  18. data/lib/ragweed/rasm/isa.rb +1115 -0
  19. data/lib/ragweed/rasm.rb +59 -0
  20. data/lib/ragweed/sbuf.rb +197 -0
  21. data/lib/ragweed/trampoline.rb +103 -0
  22. data/lib/ragweed/utils.rb +156 -0
  23. data/lib/ragweed/wrap32/debugging.rb +163 -0
  24. data/lib/ragweed/wrap32/device.rb +49 -0
  25. data/lib/ragweed/wrap32/event.rb +50 -0
  26. data/lib/ragweed/wrap32/hooks.rb +23 -0
  27. data/lib/ragweed/wrap32/overlapped.rb +46 -0
  28. data/lib/ragweed/wrap32/process.rb +506 -0
  29. data/lib/ragweed/wrap32/process_token.rb +59 -0
  30. data/lib/ragweed/wrap32/thread_context.rb +208 -0
  31. data/lib/ragweed/wrap32/winx.rb +16 -0
  32. data/lib/ragweed/wrap32/wrap32.rb +526 -0
  33. data/lib/ragweed/wrap32.rb +59 -0
  34. data/lib/ragweed/wraposx/constants.rb +122 -0
  35. data/lib/ragweed/wraposx/kernelerrorx.rb +147 -0
  36. data/lib/ragweed/wraposx/region_info.rb +254 -0
  37. data/lib/ragweed/wraposx/thread_context.rb +203 -0
  38. data/lib/ragweed/wraposx/thread_info.rb +227 -0
  39. data/lib/ragweed/wraposx/wraposx.rb +433 -0
  40. data/lib/ragweed/wraposx.rb +59 -0
  41. data/lib/ragweed/wraptux/constants.rb +68 -0
  42. data/lib/ragweed/wraptux/threads.rb +7 -0
  43. data/lib/ragweed/wraptux/wraptux.rb +76 -0
  44. data/lib/ragweed/wraptux.rb +59 -0
  45. data/lib/ragweed.rb +84 -0
  46. data/ragweed.gemspec +34 -0
  47. data/spec/ragweed_spec.rb +7 -0
  48. data/spec/spec_helper.rb +16 -0
  49. data/tasks/ann.rake +80 -0
  50. data/tasks/bones.rake +20 -0
  51. data/tasks/gem.rake +201 -0
  52. data/tasks/git.rake +40 -0
  53. data/tasks/notes.rake +27 -0
  54. data/tasks/post_load.rake +34 -0
  55. data/tasks/rdoc.rake +51 -0
  56. data/tasks/rubyforge.rake +55 -0
  57. data/tasks/setup.rb +292 -0
  58. data/tasks/spec.rake +54 -0
  59. data/tasks/svn.rake +47 -0
  60. data/tasks/test.rake +40 -0
  61. data/tasks/zentest.rake +36 -0
  62. data/test/test_ragweed.rb +0 -0
  63. metadata +132 -0
@@ -0,0 +1,59 @@
1
+ module Ragweed::Wrap32
2
+ module TokenAccess
3
+ ADJUST_DEFAULT = 128
4
+ ADJUST_GROUPS = 64
5
+ ADJUST_PRIVILEGES = 32
6
+ ALL_ACCESS = 0xf00ff
7
+ ASSIGN_PRIMARY = 1
8
+ DUPLICATE = 2
9
+ EXECUTE = 0x20000
10
+ IMPERSONATE = 4
11
+ QUERY = 8
12
+ QUERY_SOURCE = 16
13
+ READ = 0x20008
14
+ WRITE = 0x200e0
15
+ end
16
+
17
+ module PrivilegeAttribute
18
+ ENABLED = 0x2
19
+ ENABLED_BY_DEFAULT = 0x1
20
+ USED_FOR_ACCESS = 0x80000000
21
+ end
22
+
23
+ class << self
24
+ def open_process_token(h, access=Ragweed::Wrap32::TokenAccess::ADJUST_PRIVILEGES)
25
+ outw = "\x00" * 4
26
+ r = CALLS["advapi32!OpenProcessToken:LLP=L"].call(h, access, outw)
27
+ raise WinX.new(:open_process_token) if r == 0
28
+ return outw.unpack("L").first
29
+ end
30
+
31
+ def adjust_token_privileges(t, disable, *args)
32
+ buf = [args.size].pack("L") + (args.map {|tup| tup.pack("QL") }.join(""))
33
+
34
+ r = CALLS["advapi32!AdjustTokenPrivileges:LLPLPP=L"].
35
+ call(t, disable, buf, buf.size, NULL, NULL)
36
+
37
+ raise WinX.new(:adjust_token_privileges) if r == 0
38
+ end
39
+
40
+ def lookup_privilege_value(name)
41
+ outw = "\x00" * 8
42
+ r = CALLS["advapi32!LookupPrivilegeValueA:PPP=L"].call(NULL, name, outw)
43
+ raise WinX.new(:lookup_privilege_value) if r == 0
44
+ return outw.unpack("Q").first
45
+ end
46
+ end
47
+ end
48
+
49
+ class Ragweed::Wrap32::ProcessToken
50
+ def initialize(p=nil)
51
+ p ||= Ragweed::Wrap32::open_process(Ragweed::Wrap32::get_current_process_id)
52
+ @h = Ragweed::Wrap32::open_process_token(p)
53
+ end
54
+
55
+ def grant(name)
56
+ luid = Ragweed::Wrap32::lookup_privilege_value(name)
57
+ Ragweed::Wrap32::adjust_token_privileges(@h, 0, [luid, Ragweed::Wrap32::PrivilegeAttribute::ENABLED])
58
+ end
59
+ end
@@ -0,0 +1,208 @@
1
+ module Ragweed::Wrap32
2
+ module EFlags
3
+ CARRY = (1<< 0)
4
+ X0 = (1<< 1)
5
+ PARITY = (1<< 2)
6
+ X1 = (1<< 3)
7
+ ADJUST = (1<< 4)
8
+ X2 = (1<< 5)
9
+ ZERO = (1<< 6)
10
+ SIGN = (1<< 7)
11
+ TRAP = (1<< 8)
12
+ INTERRUPT = (1<< 9)
13
+ DIRECTION = (1<< 10)
14
+ OVERFLOW = (1<< 11)
15
+ IOPL1 = (1<< 12)
16
+ IOPL2 = (1<< 13)
17
+ NESTEDTASK = (1<< 14)
18
+ X3 = (1<< 15)
19
+ RESUME = (1<< 16)
20
+ V86MODE = (1<< 17)
21
+ ALIGNCHECK = (1<< 18)
22
+ VINT = (1<< 19)
23
+ VINTPENDING = (1<< 20)
24
+ CPUID = (1<< 21)
25
+ end
26
+
27
+ module ContextFlags
28
+ I386 = 0x10000
29
+ CONTROL = 1
30
+ INTEGER = 2
31
+ SEGMENTS = 4
32
+ FLOATING_POINT = 8
33
+ DEBUG_REGISTERS = 0x10
34
+
35
+ FULL = (I386|CONTROL|INTEGER|SEGMENTS)
36
+ DEBUG = (FULL|DEBUG_REGISTERS)
37
+ end
38
+ end
39
+
40
+ class Ragweed::Wrap32::ThreadContext
41
+ (FIELDS = [ [:context_flags, "L"],
42
+ [:dr0, "L"],
43
+ [:dr1, "L"],
44
+ [:dr2, "L"],
45
+ [:dr3, "L"],
46
+ [:dr6, "L"],
47
+ [:dr7, "L"],
48
+ [:floating_save, "a112"],
49
+ [:seg_gs, "L"],
50
+ [:seg_gs, "L"],
51
+ [:seg_es, "L"],
52
+ [:seg_ds, "L"],
53
+ [:edi, "L"],
54
+ [:esi, "L"],
55
+ [:ebx, "L"],
56
+ [:edx, "L"],
57
+ [:ecx, "L"],
58
+ [:eax, "L"],
59
+ [:ebp, "L"],
60
+ [:eip, "L"],
61
+ [:seg_cs, "L"],
62
+ [:eflags, "L"],
63
+ [:esp, "L"],
64
+ [:seg_ss, "L"],
65
+ [:spill, "a1024"]]).each {|x| attr_accessor x[0]}
66
+
67
+ def initialize(str=nil)
68
+ refresh(str) if str
69
+ end
70
+
71
+ def refresh(str)
72
+ if str
73
+ str.unpack(FIELDS.map {|x| x[1]}.join("")).each_with_index do |val, i|
74
+ instance_variable_set "@#{ FIELDS[i][0] }".intern, val
75
+ end
76
+ end
77
+ end
78
+
79
+ def to_s
80
+ FIELDS.map {|f| send(f[0])}.pack(FIELDS.map {|x| x[1]}.join(""))
81
+ end
82
+
83
+ def self.get(h)
84
+ self.new(Ragweed::Wrap32::get_thread_context_raw(h))
85
+ end
86
+
87
+ def get(h)
88
+ refresh(Ragweed::Wrap32::get_thread_context_raw(h))
89
+ end
90
+
91
+ def set(h)
92
+ Ragweed::Wrap32::set_thread_context_raw(h, self.to_s)
93
+ end
94
+
95
+ def inspect
96
+ body = lambda do
97
+ FIELDS.map do |f|
98
+ val = send(f[0])
99
+ "#{f[0]}=#{val.to_s(16) rescue val.to_s.hexify}"
100
+ end.join(", ")
101
+ end
102
+ "#<ThreadContext #{body.call}>"
103
+ end
104
+
105
+ def dump(&block)
106
+ maybe_hex = lambda {|a| begin; "\n" + (" " * 9) + block.call(a, 16).hexdump(true)[10..-2]; rescue; ""; end }
107
+ maybe_dis = lambda {|a| begin; "\n" + block.call(a, 16).distorm.map {|i| " " + i.mnem}.join("\n"); rescue; ""; end }
108
+
109
+ string =<<EOM
110
+ -----------------------------------------------------------------------
111
+ CONTEXT:
112
+ EIP: #{self.eip.to_s(16).rjust(8, "0")} #{maybe_dis.call(self.eip)}
113
+
114
+ EAX: #{self.eax.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.eax)}
115
+ EBX: #{self.ebx.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.ebx)}
116
+ ECX: #{self.ecx.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.ecx)}
117
+ EDX: #{self.edx.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.edx)}
118
+ EDI: #{self.edi.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.edi)}
119
+ ESI: #{self.esi.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.esi)}
120
+ EBP: #{self.ebp.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.ebp)}
121
+ ESP: #{self.esp.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.esp)}
122
+ EFL: #{self.eflags.to_s(2).rjust(32, "0")} #{Ragweed::Wrap32::EFlags.flag_dump(self.eflags)}
123
+ EOM
124
+ end
125
+
126
+ def single_step(v=true)
127
+ if v
128
+ @eflags |= Ragweed::Wrap32::EFlags::TRAP
129
+ else
130
+ @eflags &= ~(Ragweed::Wrap32::EFlags::TRAP)
131
+ end
132
+ end
133
+ end
134
+
135
+ module Ragweed::Wrap32
136
+ class << self
137
+ def get_thread_context_raw(h)
138
+ ctx = [Ragweed::Wrap32::ContextFlags::DEBUG,0,0,0,0,0,0,"\x00"*112,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"\x00"*1024].pack("LLLLLLLa112LLLLLLLLLLLLLLLLa1024")
139
+ ret = CALLS["kernel32!GetThreadContext:LP=L"].call(h, ctx)
140
+ if ret != 0
141
+ return ctx
142
+ else
143
+ raise WinX.new(:get_thread_context)
144
+ end
145
+ end
146
+
147
+ def set_thread_context_raw(h, c)
148
+ buf = c.to_s
149
+ ret = CALLS["kernel32!SetThreadContext:LP=L"].call(h, buf)
150
+ raise WinX.new(:set_thread_context) if ret == 0
151
+ return ret
152
+ end
153
+
154
+ def str2context(str)
155
+ ret = OpenStruct.new
156
+ ret.ContextFlags,
157
+ ret.Dr0,
158
+ ret.Dr1,
159
+ ret.Dr2,
160
+ ret.Dr3,
161
+ ret.Dr6,
162
+ ret.Dr7,
163
+ ret.FloatControlWord,
164
+ ret.FloatStatusWord,
165
+ ret.FloatTagWord,
166
+ ret.FloatErrorOffset,
167
+ ret.FloatErrorSelector,
168
+ ret.FloatDataOffset,
169
+ ret.FloatDataSelector,
170
+ ret.FloatRegisterArea,
171
+ ret.FloatCr0NpxState,
172
+ ret.SegGs,
173
+ ret.SegFs,
174
+ ret.SegEs,
175
+ ret.SegDs,
176
+ ret.Edi,
177
+ ret.Esi,
178
+ ret.Ebx,
179
+ ret.Edx,
180
+ ret.Ecx,
181
+ ret.Eax,
182
+ ret.Ebp,
183
+ ret.Eip,
184
+ ret.SegCs,
185
+ ret.EFlags,
186
+ ret.Esp,
187
+ ret.SegSs,
188
+ ret.Spill = str.unpack("LLLLLLLLLLLLLLA80LLLLLLLLLLLLLLLLLA1024")
189
+ return ret
190
+ end
191
+
192
+ # Retrieve the running context of a thread given its handle, returning a
193
+ # struct that mostly contains register values. Note that this will suspend
194
+ # and then resume the thread. Useful (among many other things) to sample
195
+ # EIP values to see what the code is doing.
196
+ def get_thread_context(h)
197
+ ctx = [Ragweed::Wrap32::ContextFlags::DEBUG,0,0,0,0,0,0,"\x00"*112,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"\x00"*1024].pack("LLLLLLLa112LLLLLLLLLLLLLLLLa1024")
198
+ suspend_thread(h)
199
+ ret = CALLS["kernel32!GetThreadContext:LP=L"].call(h, ctx)
200
+ resume_thread(h)
201
+ if ret != 0
202
+ return str2context(ctx)
203
+ else
204
+ raise WinX.new(:get_thread_context)
205
+ end
206
+ end
207
+ end
208
+ end
@@ -0,0 +1,16 @@
1
+ %w[ostruct Win32API pp].each {|x| require x}
2
+
3
+ module Ragweed;end
4
+ module Ragweed::Wrap32
5
+ class WinX < StandardError
6
+ attr_reader :code
7
+ attr_reader :msg
8
+ attr_reader :call
9
+ def initialize(sym=nil)
10
+ @call = sym
11
+ @code = Ragweed::Wrap32::get_last_error()
12
+ @msg = "#{(@call ? @call.to_s + ": " : "")}(#{@code}) #{ Ragweed::Wrap32::format_message(@code) }"
13
+ super @msg
14
+ end
15
+ end
16
+ end