tduehr-ragweed 0.1.6 → 0.1.7

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/History.txt CHANGED
@@ -1,3 +1,7 @@
1
+ == 0.1.7 / 2009-08-03
2
+
3
+ * bug fixes (Wraposx#RegionInfo should now fully work)
4
+
1
5
  == 0.1.6 / 2009-07-13
2
6
 
3
7
  * bug fixes and API work
data/Rakefile CHANGED
@@ -19,11 +19,13 @@ require 'ragweed'
19
19
  task :default => 'spec:run'
20
20
 
21
21
  PROJ.name = 'ragweed'
22
+ PROJ.ignore_file = '.gitignore'
22
23
  PROJ.authors = 'tduehr, tqbf, struct'
23
24
  PROJ.email = 'td@matasano.com'
24
- PROJ.url = 'github.com/tduehr/ragweed'
25
+ PROJ.description = 'General debugging tool written in Ruby for OSX/Win32/Linux'
26
+ PROJ.url = 'http://github.com/tduehr/ragweed/tree/master'
25
27
  PROJ.version = Ragweed::VERSION
26
- PROJ.rubyforge.name = 'ragweed'
28
+ # PROJ.rubyforge.name = 'ragweed'
27
29
 
28
30
  PROJ.spec.opts << '--color'
29
31
 
@@ -4,21 +4,20 @@
4
4
 
5
5
  require 'pp'
6
6
  require 'ragweed'
7
- require 'debuggertux'
8
- include Ragweed
9
7
 
10
8
  pid = Ragweed::Debuggertux.find_by_regex(/gcalctool/)
11
9
 
12
- #begin
10
+ begin
13
11
  t = Ragweed::Debuggertux.threads(pid)
14
- puts "Which thread do you want to attach to?"
12
+ puts "Available pid/tdpids\n"
15
13
  t.each do |h| puts h end
14
+ puts "Which thread do you want to attach to?"
16
15
  pid = STDIN.gets.chomp.to_i
17
16
 
18
17
  d = Ragweed::Debuggertux.new(pid)
19
18
  d.attach
20
19
  d.continue
21
20
  catch(:throw) { d.loop }
22
- #rescue
23
- # puts "Maybe your PID is wrong?"
24
- #end
21
+ rescue
22
+ puts "Maybe your PID is wrong?"
23
+ end
@@ -1,4 +1,4 @@
1
- require 'ragweed/rasm'
1
+ require ::File.join(::File.dirname(__FILE__),'rasm')
2
2
 
3
3
  pushv = $VERBOSE
4
4
  $VERBOSE = nil
@@ -1,4 +1,4 @@
1
- require 'ragweed/wrap32'
1
+ require ::File.join(::File.dirname(__FILE__),'wrap32')
2
2
 
3
3
  # I am not particularly proud of this code, which I basically debugged
4
4
  # into existence, but it does work.
@@ -1,4 +1,4 @@
1
- require 'ragweed/wraposx'
1
+ require ::File.join(::File.dirname(__FILE__),'wraposx')
2
2
 
3
3
  module Ragweed; end
4
4
 
@@ -397,10 +397,10 @@ class Ragweed::Debuggerosx
397
397
  # Extended and Top info flavors are included in case Apple re implements them
398
398
  when :extended
399
399
  warn "VM Region Extended Info not implemented by Apple. Returning RegionBasicInfo"
400
- return Ragweed::Wraposx::RegionBasicInfo.get(@task, addr)
400
+ return Ragweed::Wraposx::RegionExtendedInfo.get(@task, addr)
401
401
  when :top
402
402
  warn "VM Region Top Info not implemented be Apple. Returning RegionBasicInfo"
403
- return Ragweed::Wraposx::RegionBasicInfo.get(@task, addr)
403
+ return Ragweed::Wraposx::RegionTopInfo.get(@task, addr)
404
404
  else
405
405
  warn "Unknown flavor requested. Returning RegionBasicInfo."
406
406
  return Ragweed::Wraposx::RegionBasicInfo.get(@task, addr)
@@ -1,5 +1,4 @@
1
- require 'ragweed/wraptux'
2
-
1
+ require ::File.join(::File.dirname(__FILE__),'wraptux')
3
2
  ## Modeled after wraposx written by tduehr
4
3
 
5
4
  module Ragweed; end
@@ -3,12 +3,13 @@
3
3
  # Rasm: a half-assed X86 assembler.
4
4
  #
5
5
  # Rasm implements a small subset of the X86 instruction set, and only in
6
- # simple encodings.
6
+ # simple encodings.
7
7
  #
8
8
  # However, Rasm implements enough X86 to do interesting things. I wrote it
9
9
  # to inject trampoline functions and detours into remote processes. This
10
- # is Ruby code; you'd never use it where performance matters. It's not
10
+ # is Ruby code; you'd never use it where performance matters. It's not
11
11
  # enough to write a decent compiler, but it's enough to fuck up programs.
12
+ module Ragweed; end
12
13
  module Ragweed::Rasm
13
14
  class NotImp < RuntimeError; end
14
15
  class Insuff < RuntimeError; end
@@ -39,6 +40,8 @@ module Ragweed::Rasm
39
40
  (rc1 << 8|rc2)
40
41
  end
41
42
 
43
+ def scaled?; @scale and @scale > 0; end
44
+ def combined?; @combined; end
42
45
  def reg1
43
46
  if combined?
44
47
  self.class.new((code>>8)&0xff)
@@ -68,7 +71,7 @@ module Ragweed::Rasm
68
71
  elsif x.kind_of? Register
69
72
  ret = clone
70
73
  ret.combined = true
71
- ret.indir = 1
74
+ ret.indir = 1
72
75
  ret.scale = x.scale
73
76
  ret.code = self.class.comb(ret.code, x.code)
74
77
  return ret
@@ -101,19 +104,16 @@ module Ragweed::Rasm
101
104
  end
102
105
 
103
106
  return self
104
- end
105
-
106
- def scaled?; @scale and @scale > 0; end
107
- def combined?; @combined; end
107
+ end
108
108
 
109
- def self.eax(opts={}); Eax.clone.regopts opts; end
110
- def self.ecx(opts={}); Ecx.clone.regopts opts; end
111
- def self.edx(opts={}); Edx.clone.regopts opts; end
112
- def self.ebx(opts={}); Ebx.clone.regopts opts; end
113
- def self.esp(opts={}); Esp.clone.regopts opts; end
114
- def self.ebp(opts={}); Ebp.clone.regopts opts; end
115
- def self.esi(opts={}); Esi.clone.regopts opts; end
116
- def self.edi(opts={}); Edi.clone.regopts opts; end
109
+ def self.eax(opts={}); Eax.clone.regopts opts; end
110
+ def self.ecx(opts={}); Ecx.clone.regopts opts; end
111
+ def self.edx(opts={}); Edx.clone.regopts opts; end
112
+ def self.ebx(opts={}); Ebx.clone.regopts opts; end
113
+ def self.esp(opts={}); Esp.clone.regopts opts; end
114
+ def self.ebp(opts={}); Ebp.clone.regopts opts; end
115
+ def self.esi(opts={}); Esi.clone.regopts opts; end
116
+ def self.edi(opts={}); Edi.clone.regopts opts; end
117
117
 
118
118
  def initialize(code, opts={})
119
119
  @combined = false
@@ -132,7 +132,7 @@ module Ragweed::Rasm
132
132
  @disp = disp
133
133
  @indir = true
134
134
  end
135
- end
135
+ end
136
136
 
137
137
  ## ------------------------------------------------------------------------
138
138
 
@@ -146,7 +146,7 @@ module Ragweed::Rasm
146
146
  Esp = Register.new(Register::ESP)
147
147
  Ebp = Register.new(Register::EBP)
148
148
  Esi = Register.new(Register::ESI)
149
- Edi = Register.new(Register::EDI)
149
+ Edi = Register.new(Register::EDI)
150
150
  def eax(opts={}); Register.eax opts; end
151
151
  def ecx(opts={}); Register.ecx opts; end
152
152
  def edx(opts={}); Register.edx opts; end
@@ -167,14 +167,14 @@ module Ragweed::Rasm
167
167
  ## ------------------------------------------------------------------------
168
168
 
169
169
  # A code fragment. Push instructions into it. You can push Label
170
- # objects to create jump targets.
170
+ # objects to create jump targets.
171
171
  class Subprogram < Array
172
172
 
173
173
  # Patch code offsets into the instructions to replace abstract
174
174
  # labels. Produces raw instruction stream.
175
175
  def assemble
176
176
  patches = {}
177
- buf = Ragweed::Sbuf.new
177
+ buf = Sbuf.new
178
178
 
179
179
  each do |i|
180
180
  if i.kind_of? Instruction
@@ -183,11 +183,11 @@ module Ragweed::Rasm
183
183
  else
184
184
  patches[i] = buf.size
185
185
  end
186
- end
187
-
186
+ end
187
+
188
188
  select {|i| i.kind_of? Instruction}.each {|i| i.patch(patches)}
189
189
  buf.clear!
190
- select {|i| i.kind_of? Instruction}.each {|i|
190
+ select {|i| i.kind_of? Instruction}.each {|i|
191
191
  buf.straw(i.to_s)
192
192
  }
193
193
 
@@ -197,12 +197,12 @@ module Ragweed::Rasm
197
197
  # Produce an array of insns. This is pretty much broken, because
198
198
  # it doesn't pre-patch the instructions.
199
199
  def disassemble
200
- select {|i| i.kind_of? Rasm::Intruction}.map {|i| i.decode}
200
+ select {|i| i.kind_of? Rasm::Instruction}.map {|i| i.decode}
201
201
  end
202
202
 
203
203
  def dump_disassembly
204
- disassemble.each do |insn|
205
- puts "#{ insn.off.to_x } #{ insn.mnem }"
204
+ disassemble.each_with_index do |insn, i|
205
+ puts "#{ i } #{ insn.mnem }"
206
206
  end
207
207
  end
208
208
  end
@@ -256,21 +256,21 @@ module Ragweed::Rasm
256
256
  v = Immed.new(v) if v.number?
257
257
  end
258
258
  v
259
- end
259
+ end
260
260
 
261
261
  def src=(v); @src = coerce(v); end
262
262
  def dst=(v); @dst = coerce(v); end
263
263
 
264
- # Never called directly (see subclasses below)
264
+ # Never called directly (see subclasses below)
265
265
  def initialize(x=nil, y=nil)
266
- @buf = Ragweed::Sbuf.new
266
+ @buf = Sbuf.new
267
267
  self.src = y
268
268
  self.dst = x
269
269
  @loc = nil
270
270
  end
271
271
 
272
272
  # Disassemble the instruction (mostly for testing)
273
- def decode; Frasm::DistormDecoder.new.decode(self.to_s)[0]; end
273
+ # def decode; Frasm::DistormDecoder.new.decode(self.to_s)[0]; end
274
274
 
275
275
  # What Subprogram#assemble uses to patch instruction locations.
276
276
  # Not user-servicable
@@ -287,7 +287,7 @@ module Ragweed::Rasm
287
287
  end
288
288
  end
289
289
  end
290
-
290
+
291
291
  # Calculate ModR/M bits for the instruction; this is
292
292
  # the source/destination operand encoding.
293
293
  def modrm(op1, op2)
@@ -320,7 +320,7 @@ module Ragweed::Rasm
320
320
  return 0xc0 + (op2.code << 3) + op1.code
321
321
  end
322
322
  end
323
-
323
+
324
324
  def sib(indir, alt, base)
325
325
  modpart = (base+4) + (alt.code << 3)
326
326
 
@@ -340,7 +340,7 @@ module Ragweed::Rasm
340
340
  end
341
341
 
342
342
  col = indir.reg1.code
343
-
343
+
344
344
  if indir.combined?
345
345
  row = indir.reg2.code
346
346
  else
@@ -350,7 +350,7 @@ module Ragweed::Rasm
350
350
  pp [col,row,sbase]
351
351
 
352
352
  sibpart = sbase + (row << 3) + (col)
353
-
353
+
354
354
  return (modpart.chr) + (sibpart.chr)
355
355
  end
356
356
 
@@ -382,7 +382,7 @@ module Ragweed::Rasm
382
382
  end
383
383
 
384
384
  ## ------------------------------------------------------------------------
385
-
385
+
386
386
  # Jump to a relative offset (pos or neg), a register, or an address
387
387
  # in memory. Can take Labels instead of values, let patch figure out
388
388
  # the rest.
@@ -393,7 +393,7 @@ module Ragweed::Rasm
393
393
  # no far yet
394
394
 
395
395
  def initialize(x=nil); super x; end
396
-
396
+
397
397
  def to_s
398
398
  raise Insuff if not @dst
399
399
  if dst_imm? or dst_lab?
@@ -441,7 +441,7 @@ module Ragweed::Rasm
441
441
 
442
442
  # Push a register, register-addressed memory location, or immediate
443
443
  # onto the stack.
444
- class Push < Instruction
444
+ class Push < Instruction
445
445
  # ff r/m
446
446
  # 50+ r
447
447
  # 6a imm8
@@ -456,7 +456,7 @@ module Ragweed::Rasm
456
456
  if @dst.indir
457
457
  add(0xff)
458
458
  add(modrm(@dst, Esi.clone))
459
- add(@dst.disp)
459
+ add(@dst.disp)
460
460
  else
461
461
  add(0x50 + @dst.code)
462
462
  end
@@ -485,7 +485,7 @@ module Ragweed::Rasm
485
485
 
486
486
  def to_s
487
487
  raise Insuff if not @dst
488
-
488
+
489
489
  if dst_reg?
490
490
  add(0xff)
491
491
  add(modrm(@dst, Edx.clone))
@@ -501,7 +501,7 @@ module Ragweed::Rasm
501
501
 
502
502
  # Return; provide immediate for stack adjustment if you want.
503
503
  class Ret < Instruction
504
- # c3
504
+ # c3
505
505
  # c2 imm16
506
506
 
507
507
  def initialize( dst=nil); super dst; end
@@ -543,7 +543,7 @@ module Ragweed::Rasm
543
543
  if @src.val < 0x100
544
544
  add(@imp8)
545
545
  add(@src.val)
546
- else
546
+ else
547
547
  add(@imp)
548
548
  add(@src.val)
549
549
  end
@@ -587,9 +587,10 @@ module Ragweed::Rasm
587
587
  @x = Eax.clone
588
588
  end
589
589
  end
590
+ Addl = Add
590
591
 
591
592
  ## ------------------------------------------------------------------------
592
-
593
+
593
594
  # SUB
594
595
  class Sub < Arith
595
596
  def initialize(*args)
@@ -670,7 +671,7 @@ module Ragweed::Rasm
670
671
 
671
672
  # CMP is SUB + condition code
672
673
  class Cmp < Instruction
673
- # 3c imm8
674
+ # 3c imm8
674
675
  # 3d imm
675
676
  # 80/7 r/m8, imm8
676
677
  # 81/7 r/m, imm
@@ -725,16 +726,16 @@ module Ragweed::Rasm
725
726
 
726
727
  # Wrapper for INC and DEC, not called directly.
727
728
  class IncDec < Instruction
728
- # fe/0 r/m8
729
- # ff/0 r/m
730
- # 40+ (reg)
731
-
729
+ # fe/0 r/m8
730
+ # ff/0 r/m
731
+ # 40+ (reg)
732
+
732
733
  def initialize( dst=nil); super dst; end
733
734
 
734
735
  def to_s
735
736
  raise Insuff if not @dst
736
737
  raise(BadArg, "need a register") if not dst_reg?
737
-
738
+
738
739
  if @dst.indir
739
740
  add(0xff)
740
741
  add(modrm(@dst, @var))
@@ -748,7 +749,7 @@ module Ragweed::Rasm
748
749
  ## ------------------------------------------------------------------------
749
750
 
750
751
  # INC memory or register
751
- class Inc < IncDec
752
+ class Inc < IncDec
752
753
  def initialize(*args)
753
754
  super *args
754
755
  @var = Eax.clone
@@ -759,7 +760,7 @@ module Ragweed::Rasm
759
760
  ## ------------------------------------------------------------------------
760
761
 
761
762
  # DEC memory or register
762
- class Dec < IncDec
763
+ class Dec < IncDec
763
764
  def initialize(*args)
764
765
  super *args
765
766
  @var = Ecx.clone
@@ -916,7 +917,7 @@ module Ragweed::Rasm
916
917
  # Wrapper for conditional jumps, see below
917
918
  class Jcc < Instruction
918
919
 
919
- def m; [nil,nil]; end
920
+ def m; [nil,nil]; end
920
921
  def initialize( dst)
921
922
  super dst
922
923
  @short, @near = m()
@@ -1012,9 +1013,33 @@ module Ragweed::Rasm
1012
1013
  class Js < Jcc; def m; [0x78, 0x88]; end; end
1013
1014
  # Zero
1014
1015
  class Jz < Jcc; def m; [0x74, 0x84]; end; end
1015
-
1016
+
1017
+ ## ------------------------------------------------------------------------
1018
+
1019
+ class Pushf < Instruction
1020
+ # 9c pushfd
1021
+
1022
+ def initialize; end
1023
+ def to_s
1024
+ raise(TooMan, "too many arguments") if @src or @dst
1025
+ add(0x9c)
1026
+ end
1027
+ end
1028
+
1016
1029
  ## ------------------------------------------------------------------------
1017
-
1030
+
1031
+ class Popf < Instruction
1032
+ # 9d popfd
1033
+
1034
+ def initialize; end
1035
+ def to_s
1036
+ raise(TooMan, "too many arguments") if @src or @dst
1037
+ add(0x9d)
1038
+ end
1039
+ end
1040
+
1041
+ ## ------------------------------------------------------------------------
1042
+
1018
1043
  # INT 3, mostly, but will do INT X
1019
1044
  class Int < Instruction
1020
1045
  ## cc int 3
data/lib/ragweed/rasm.rb CHANGED
@@ -5,7 +5,7 @@ module Ragweed; end
5
5
  module Ragweed::Rasm
6
6
 
7
7
  # :stopdoc:
8
- VERSION = '0.1.6'
8
+ VERSION = '0.1.7'
9
9
  LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
10
10
  PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
11
11
  # :startdoc:
data/lib/ragweed/utils.rb CHANGED
@@ -21,6 +21,19 @@ class Object
21
21
  def mymethods
22
22
  (self.methods - self.class.superclass.methods).sort
23
23
  end
24
+ # self-evident
25
+ def callable?; respond_to? :call; end
26
+ def number?; kind_of? Numeric; end
27
+
28
+ # while X remains callable, keep calling it to get its value
29
+ def derive
30
+ # also, don't drink and derive
31
+ x = self
32
+ while x.callable?
33
+ x = x()
34
+ end
35
+ return x
36
+ end
24
37
  end
25
38
  include ObjectExtensions
26
39
  end
@@ -41,6 +54,19 @@ class String
41
54
  return self if count == 0
42
55
  slice! 0..(count-1)
43
56
  end
57
+
58
+ # Convert a string into hex characters
59
+ def hexify
60
+ l = []
61
+ each_byte{|b| l << "%02x" % b}
62
+ l.join
63
+ end
64
+
65
+ # Convert a string of raw hex characters (no %'s or anything) into binary
66
+ def dehexify
67
+ (ret||="") << (me||=clone).shift(2).to_i(16).chr while not (me||=clone).empty?
68
+ return ret
69
+ end
44
70
  end
45
71
 
46
72
  class Integer
@@ -5,7 +5,7 @@ module Ragweed; end
5
5
  module Ragweed::Wrap32
6
6
 
7
7
  # :stopdoc:
8
- VERSION = '0.1.6'
8
+ VERSION = '0.1.7'
9
9
  LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
10
10
  PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
11
11
  # :startdoc:
@@ -23,7 +23,9 @@ module Ragweed::Wraposx::Ptrace
23
23
  end
24
24
 
25
25
  module Ragweed::Wraposx::Signal
26
- #the Ruby module Signal also has this information
26
+ # the Ruby module Signal also has this information.
27
+ # in reality, that is a better source since it's based on the signals
28
+ # available at the time ruby was compiled.
27
29
  SIGHUP = 1 # hangup
28
30
  SIGINT = 2 # interrupt
29
31
  SIGQUIT = 3 # quit
@@ -77,13 +79,32 @@ end
77
79
 
78
80
  module Ragweed::Wraposx::Vm; end
79
81
  module Ragweed::Wraposx::Vm::Prot
80
- #vm_protect permission flags for memory spaces
82
+ # vm_protect permission flags for memory spaces
81
83
  READ = 0x1 #read permission
82
84
  WRITE = 0x2 #write permission
83
85
  EXECUTE = 0x4 #execute permission
84
86
  NONE = 0x0 #no rights
85
87
  ALL = 0x7 #all permissions
86
88
  end
89
+ module Ragweed::Wraposx::Vm::Sm
90
+ # share mode constants
91
+ COW = 1
92
+ PRIVATE = 2
93
+ EMPTY = 3
94
+ SHARED = 4
95
+ TRUESHARED = 5
96
+ PRIVATE_ALIASED = 6
97
+ SHARED_ALIASED = 7
98
+ end
99
+
100
+ # this should be moved to an include for all wrappers
101
+ module Ragweed::Wraposx::SizeOf
102
+ INT = [1].pack("I_").size
103
+ SHORT = [1].pack("S_").size
104
+ LONG = [1].pack("L_").size
105
+ DOUBLE = [1].pack("D").size
106
+ FLOAT = [1].pack("F").size
107
+ end
87
108
 
88
109
  module Ragweed::Wraposx::Dl
89
110
  RTLD_LAZY = 0x1
@@ -26,9 +26,9 @@ module Ragweed::Wraposx::Vm
26
26
  #define VM_REGION_BASIC_INFO_COUNT ((mach_msg_type_number_t) (sizeof(vm_region_basic_info_data_t)/sizeof(int)))
27
27
  #define VM_REGION_EXTENDED_INFO_COUNT ((mach_msg_type_number_t) (sizeof(vm_region_extended_info_data_t)/sizeof(int)))
28
28
  #define VM_REGION_TOP_INFO_COUNT ((mach_msg_type_number_t) (sizeof(vm_region_top_info_data_t)/sizeof(int)))
29
- FLAVORS = { REGION_BASIC_INFO => {:size => 30, :count => 9},
30
- REGION_EXTENDED_INFO => {:size => 32, :count => 9},
31
- REGION_TOP_INFO => {:size => 17,:count => 9}
29
+ FLAVORS = { REGION_BASIC_INFO => {:size => 30, :count => 8},
30
+ REGION_EXTENDED_INFO => {:size => 32, :count => 8},
31
+ REGION_TOP_INFO => {:size => 17,:count => 5}
32
32
  }
33
33
 
34
34
  module Pflags
@@ -39,8 +39,8 @@ module Ragweed::Wraposx::Vm
39
39
  end
40
40
 
41
41
  # Memory region info base class.
42
- # Currently Apple only supports the basic flavor. The other two flavors
43
- # are included for completeness.
42
+ #
43
+ # to change slightly in 0.2.0+
44
44
  #
45
45
  class Ragweed::Wraposx::RegionInfo
46
46
  def initialize(str=nil)
@@ -113,7 +113,8 @@ class Ragweed::Wraposx::RegionBasicInfo < Ragweed::Wraposx::RegionInfo
113
113
  [:offset, "L"], # The region's offset into the memory object. The region begins at this offset.
114
114
  [:behavior, "i"], # Expected reference pattern for the memory.
115
115
  [:user_wired_count, "S"],
116
- [:size, "I"] # size of memory region returned
116
+ [:size, "I"], # size of memory region returned
117
+ [:base_address, "L"]
117
118
  ]).each {|x| attr_accessor x[0]}
118
119
 
119
120
  def dump(&block)
@@ -122,7 +123,9 @@ class Ragweed::Wraposx::RegionBasicInfo < Ragweed::Wraposx::RegionInfo
122
123
 
123
124
  string =<<EOM
124
125
  -----------------------------------------------------------------------
125
- INFO:
126
+ BASIC INFO:
127
+ base address: #{self.base_address.to_s(16).rjust(8, "0")}
128
+
126
129
  protection: #{self.protection.to_s(2).rjust(8, "0")} #{Ragweed::Wraposx::Vm::Pflags.flag_dump(self.protection)}
127
130
  max_protection: #{self.max_protection.to_s(2).rjust(8, "0")} #{Ragweed::Wraposx::Vm::Pflags.flag_dump(self.max_protection)}
128
131
  inheritance: #{self.inheritance.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.inheritance)}
@@ -153,7 +156,8 @@ class Ragweed::Wraposx::RegionExtendedInfo < Ragweed::Wraposx::RegionInfo
153
156
  [:shadow_depth, "S"],
154
157
  [:external_pager, "C"],
155
158
  [:share_mode, "C"],
156
- [:size, "I"] ]).each {|x| attr_accessor x[0]}
159
+ [:size, "I"],
160
+ [:base_address, "I"] ]).each {|x| attr_accessor x[0]}
157
161
 
158
162
  def dump(&block)
159
163
  maybe_hex = lambda {|a| begin; "\n" + (" " * 9) + block.call(a, 16).hexdump(true)[10..-2]; rescue; ""; end }
@@ -161,7 +165,9 @@ class Ragweed::Wraposx::RegionExtendedInfo < Ragweed::Wraposx::RegionInfo
161
165
 
162
166
  string =<<EOM
163
167
  -----------------------------------------------------------------------
164
- INFO:
168
+ EXTENDED INFO:
169
+ base address: #{self.base_address.to_s(16).rjust(8, "0")}
170
+
165
171
  protection: #{self.protection.to_s(2).rjust(8, "0")} #{Ragweed::Wraposx::Vm::Pflags.flag_dump(self.protection)}
166
172
  user_tag: #{self.user_tag.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.user_tag)}
167
173
  pages_resident: #{self.pages_resident.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.pages_resident)}
@@ -190,7 +196,8 @@ class Ragweed::Wraposx::RegionTopInfo < Ragweed::Wraposx::RegionInfo
190
196
  [:private_pages_resident, "I"],
191
197
  [:shared_pages_resident, "I"],
192
198
  [:share_mode, "C"],
193
- [:size, "I"]]).each {|x| attr_accessor x[0]}
199
+ [:size, "I"],
200
+ [:base_address,"I"]]).each {|x| attr_accessor x[0]}
194
201
 
195
202
  def dump(&block)
196
203
  maybe_hex = lambda {|a| begin; "\n" + (" " * 9) + block.call(a, 16).hexdump(true)[10..-2]; rescue; ""; end }
@@ -198,7 +205,9 @@ class Ragweed::Wraposx::RegionTopInfo < Ragweed::Wraposx::RegionInfo
198
205
 
199
206
  string =<<EOM
200
207
  -----------------------------------------------------------------------
201
- INFO:
208
+ TOP INFO:
209
+ base address: #{self.base_address.to_s(16).rjust(8, "0")}
210
+
202
211
  obj_id: #{self.obj_id.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.obj_id)}
203
212
  ref_count: #{self.ref_count.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.ref_count)}
204
213
  private_pages_resident: #{self.private_pages_resident.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.private_pages_resident)}
@@ -218,8 +227,9 @@ module Ragweed::Wraposx
218
227
 
219
228
  # Returns a string containing the memory region information for task
220
229
  # at address.
221
- # Currently Apple only supports the basic flavor. The other two flavors
222
- # are included for completeness.
230
+ #
231
+ # The order of the elements in the returned string will change in 0.2.0+
232
+ # to match the argument order.
223
233
  #
224
234
  # kern_return_t vm_region
225
235
  # (vm_task_t target_task,
@@ -230,14 +240,15 @@ module Ragweed::Wraposx
230
240
  # mach_msg_type_number_t info_count,
231
241
  # memory_object_name_t object_name);
232
242
  def vm_region_raw(task, address, flavor)
233
- info = ("\x00"*64).to_ptr
243
+ info = ("\x00"*Vm::FLAVORS[flavor][:size]).to_ptr
234
244
  count = ([Vm::FLAVORS[flavor][:count]].pack("I_")).to_ptr
235
245
  address = ([address].pack("I_")).to_ptr
236
246
  objn = ([0].pack("I_")).to_ptr
237
247
  sz = ("\x00"*SIZEOFINT).to_ptr
238
- r = CALLS["libc!vm_region:IPPIPPP=I"].call(task, address, sz, Vm::FLAVORS[flavor][:count], info, count, objn).first
248
+ r = CALLS["libc!vm_region:IPPIPPP=I"].call(task, address, sz, flavor, info, count, objn).first
239
249
  raise KernelCallError.new(:vm_region, r) if r != 0
240
- return "#{info.to_s(Vm::FLAVORS[flavor][:size])}#{sz.to_s(SIZEOFINT)}"
250
+ # this
251
+ return "#{info.to_s(Vm::FLAVORS[flavor][:size])}#{sz.to_s(SIZEOFINT)}#{address.to_s(SIZEOFINT)}"
241
252
  end
242
253
  end
243
254
  end
@@ -209,17 +209,19 @@ module Ragweed::Wraposx
209
209
  class << self
210
210
 
211
211
  # Returns the packed string representation of the thread_info_t struct for later parsing.
212
+ #
212
213
  # kern_return_t thread_info
213
214
  # (thread_act_t target_thread,
214
215
  # thread_flavor_t flavor,
215
216
  # thread_info_t thread_info,
216
217
  # mach_msg_type_number_t thread_info_count);
217
218
  def thread_info_raw(thread, flavor)
218
- info = ("\x00"*1024).to_ptr
219
+ raise KErrno::INVALID_ARGUMENT if ThreadInfo::FLAVORS[flavor].nil?
220
+ info = ("\x00"*ThreadInfo::FLAVORS[flavor][:size]).to_ptr
219
221
  count = ([Ragweed::Wraposx::ThreadInfo::FLAVORS[flavor][:count]].pack("I_")).to_ptr
220
222
  r = CALLS["libc!thread_info:IIPP=I"].call(thread,flavor,info,Ragweed::Wraposx::ThreadInfo::FLAVORS[flavor][:count]).first
221
223
  raise KernelCallError.new(r) if r != 0
222
- return info.to_s(Ragweed::Wraposx::ThreadInfo::FLAVORS[flavor][:size])
224
+ return "#{info.to_s(ThreadInfo::FLAVORS[flavor][:size])}#{count.to_s(SizeOf::INT)}"
223
225
  end
224
226
  end
225
227
  end
@@ -5,7 +5,7 @@ module Ragweed; end
5
5
  module Ragweed::Wraposx
6
6
 
7
7
  # :stopdoc:
8
- VERSION = '0.1.6'
8
+ VERSION = '0.1.7'
9
9
  LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
10
10
  PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
11
11
  # :startdoc:
@@ -42,7 +42,7 @@ module Ragweed::Wraposx
42
42
  search_me = ::File.expand_path(
43
43
  ::File.join(::File.dirname(fname), dir, '**', '*.rb'))
44
44
 
45
- Dir.glob(search_me).sort.each {|rb| require rb}
45
+ Dir.glob(search_me).reject{|rb| rb =~ /#{__FILE__}/}.sort.each {|rb| require rb}
46
46
  # require File.dirname(File.basename(__FILE__)) + "/#{x}"
47
47
 
48
48
  end
@@ -5,7 +5,7 @@ module Ragweed; end
5
5
  module Ragweed::Wraptux
6
6
 
7
7
  # :stopdoc:
8
- VERSION = '0.1.6'
8
+ VERSION = '0.1.7'
9
9
  LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
10
10
  PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
11
11
  # :startdoc:
data/lib/ragweed.rb CHANGED
@@ -2,7 +2,7 @@
2
2
  module Ragweed
3
3
 
4
4
  # :stopdoc:
5
- VERSION = '0.1.6'
5
+ VERSION = '0.1.7'
6
6
  LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
7
7
  PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
8
8
  # :startdoc:
@@ -40,7 +40,7 @@ module Ragweed
40
40
  ::File.join(::File.dirname(fname), dir, '**', '*.rb'))
41
41
 
42
42
  # Don't want to load wrapper or debugger here.
43
- Dir.glob(search_me).sort.reject{|rb| rb =~ /(wrap|debugger|rasm[^.])/}.each {|rb| require rb}
43
+ Dir.glob(search_me).sort.reject{|rb| rb =~ /(wrap|debugger|rasm[^\.])/}.each {|rb| require rb}
44
44
  # require File.dirname(File.basename(__FILE__)) + "/#{x}"d
45
45
  end
46
46
 
@@ -62,8 +62,8 @@ module Ragweed
62
62
  end
63
63
 
64
64
  if not pkgs.empty?
65
- search_me = File.expand_path(File.join(File.dirname(fname), dir,"**", "*#{pkgs}.rb"))
66
- Dir.glob(search_me).sort.each {|rb| require rb}
65
+ search_me = File.expand_path(File.join(File.dirname(fname), dir, "*#{pkgs}.rb"))
66
+ Dir.glob(search_me).sort.reverse.each {|rb| require rb}
67
67
  end
68
68
  end
69
69
  end # module Ragweed
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tduehr-ragweed
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6
4
+ version: 0.1.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - tduehr, tqbf, struct
@@ -52,7 +52,6 @@ files:
52
52
  - lib/ragweed/ptr.rb
53
53
  - lib/ragweed/rasm.rb
54
54
  - lib/ragweed/rasm/isa.rb
55
- - lib/ragweed/rasm/util.rb
56
55
  - lib/ragweed/sbuf.rb
57
56
  - lib/ragweed/trampoline.rb
58
57
  - lib/ragweed/utils.rb
@@ -1,26 +0,0 @@
1
- # Cheating; monkeypatching Object is evil.
2
- class Object
3
- # self-evident
4
- def callable?; respond_to? :call; end
5
- def number?; kind_of? Numeric; end
6
-
7
- # while X remains callable, keep calling it to get its value
8
- def derive
9
- x = self
10
- while x.callable?
11
- x = x()
12
- end
13
- return x
14
- end
15
- end
16
-
17
- # class String
18
- # # this is just horrible
19
- # def distorm
20
- # Frasm::DistormDecoder.new.decode(self)
21
- # end
22
- #
23
- # def disasm
24
- # distorm.each {|i| puts i.mnem}
25
- # end
26
- # end