ragweed 0.1.7.3 → 0.2.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,7 +2,8 @@ module Ragweed; end
2
2
  module Ragweed::Wraposx; end
3
3
  module Ragweed::Wraposx::Vm
4
4
  # these are flavor arguments for vm_region
5
- # more to be added as support for 64bit processes gets added
5
+ # only basic info is supported by apple
6
+ REGION_BASIC_INFO_64 = 9
6
7
  REGION_BASIC_INFO = 10
7
8
  REGION_EXTENDED_INFO = 11
8
9
  REGION_TOP_INFO = 12
@@ -23,232 +24,252 @@ module Ragweed::Wraposx::Vm
23
24
  INHERIT_DEFAULT = 1 # VM_INHERIT_COPY
24
25
  INHERIT_LAST_VALID = 2 # VM_INHERIT_NONE
25
26
 
26
- #define VM_REGION_BASIC_INFO_COUNT ((mach_msg_type_number_t) (sizeof(vm_region_basic_info_data_t)/sizeof(int)))
27
- #define VM_REGION_EXTENDED_INFO_COUNT ((mach_msg_type_number_t) (sizeof(vm_region_extended_info_data_t)/sizeof(int)))
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 => 8},
30
- REGION_EXTENDED_INFO => {:size => 32, :count => 8},
31
- REGION_TOP_INFO => {:size => 17,:count => 5}
32
- }
33
-
34
27
  module Pflags
35
28
  READ = 0x1 #read permission
36
29
  WRITE = 0x2 #write permission
37
30
  EXECUTE = 0x4 #execute permission
38
31
  end
39
- end
40
32
 
41
- # Memory region info base class.
42
- #
43
- # to change slightly in 0.2.0+
44
- #
45
- class Ragweed::Wraposx::RegionInfo
46
- def initialize(str=nil)
47
- refresh(str) if str
33
+ # Memory region info base class.
34
+ #
35
+ class RegionInfo < FFI::Struct
36
+ include Ragweed::FFIStructInclude
37
+ attr_accessor :region_size
38
+ attr_accessor :base_address
48
39
  end
49
40
 
50
- # (re)loads the data from str
51
- def refresh(str)
52
- fields = self.class.const_get :FIELDS
53
- if str and not str.empty?
54
- str.unpack(fields.map {|x| x[1]}.join("")).each_with_index do |val, i|
55
- raise "i is nil" if i.nil?
56
- instance_variable_set "@#{ fields[i][0] }".intern, val
57
- end
58
- end
59
- end
41
+ class RegionBasicInfo < RegionInfo
60
42
 
61
- def to_s
62
- fields = self.class.const_get :FIELDS
63
- fields.map {|f| send(f[0])}.pack(fields.map {|x| x[1]}.join(""))
64
- end
43
+ layout :protection, Ragweed::Wraposx::Libc.find_type(:vm_prot_t),
44
+ :max_protection, Ragweed::Wraposx::Libc.find_type(:vm_prot_t),
45
+ :inheritance, Ragweed::Wraposx::Libc.find_type(:vm_inherit_t),
46
+ :shared, Ragweed::Wraposx::Libc.find_type(:boolean_t),
47
+ :reserved, Ragweed::Wraposx::Libc.find_type(:boolean_t),
48
+ :offset, :uint32,
49
+ :behavior, Ragweed::Wraposx::Libc.find_type(:vm_behavior_t),
50
+ :user_wired_count, :ushort
65
51
 
66
- def self.get(t, a, flavor)
67
- self.new(Ragweed::Wraposx::vm_region_raw(t, a, flavor))
68
- end
69
52
 
70
- def get(t, a)
71
- refresh(Ragweed::Wraposx::vm_region_raw(t, a, self.class.const_get(:FLAVOR)))
72
- end
53
+ def dump(&block)
54
+ maybe_hex = lambda {|a| begin; "\n" + (" " * 9) + block.call(a, 16).hexdump(true)[10..-2]; rescue; ""; end }
55
+ maybe_dis = lambda {|a| begin; "\n" + block.call(a, 16).distorm.map {|i| " " + i.mnem}.join("\n"); rescue; ""; end }
73
56
 
74
- def inspect
75
- fields = self.class.const_get(:FIELDS)
76
- body = lambda do
77
- fields.map do |f|
78
- "#{f[0]}=#{send(f[0]).to_s}"
79
- end.join(", ")
57
+ string =<<EOM
58
+ -----------------------------------------------------------------------
59
+ BASIC INFO:
60
+ base address: #{self.base_address.to_s(16).rjust(8, "0")}
61
+
62
+ protection: #{self.protection.to_s(2).rjust(8, "0")} #{Ragweed::Wraposx::Vm::Pflags.flag_dump(self.protection)}
63
+ max_protection: #{self.max_protection.to_s(2).rjust(8, "0")} #{Ragweed::Wraposx::Vm::Pflags.flag_dump(self.max_protection)}
64
+ inheritance: #{self.inheritance.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.inheritance)}
65
+ shared: #{self.shared.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.shared)}
66
+ reserved: #{self.reserved.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.reserved)}
67
+ offset: #{self.offset.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.offset)}
68
+ behavior: #{self.behavior.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.behavior)}
69
+ user_wired_count: #{self.user_wired_count.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.user_wired_count)}
70
+ size: #{self.size.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.size)}
71
+ EOM
80
72
  end
81
- "#<#{self.class.name.split("::").last} #{body.call}>"
82
73
  end
83
74
 
84
- def dump(&block)
85
- maybe_hex = lambda {|a| begin; "\n" + (" " * 9) + block.call(a, 16).hexdump(true)[10..-2]; rescue; ""; end }
86
- maybe_dis = lambda {|a| begin; "\n" + block.call(a, 16).distorm.map {|i| " " + i.mnem}.join("\n"); rescue; ""; end }
87
-
88
- string =<<EOM
89
- -----------------------------------------------------------------------
90
- INFO:
91
- protection: #{self.protection.to_s(2).rjust(8, "0")} #{Ragweed::Wraposx::Vm::Pflags.flag_dump(self.protection)}
92
- max_protection: #{self.max_protection.to_s(2).rjust(8, "0")} #{Ragweed::Wraposx::Vm::Pflags.flag_dump(self.max_protection)}
93
- inheritance: #{self.inheritance.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.inheritance)}
94
- shared: #{self.shared.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.shared)}
95
- reserved: #{self.reserved.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.reserved)}
96
- offset: #{self.offset.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.offset)}
97
- behavior: #{self.behavior.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.behavior)}
98
- user_wired_count: #{self.user_wired_count.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.user_wired_count)}
99
- size: #{self.size.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.size)}
100
- EOM
101
- end
102
- end
75
+ class RegionBasicInfo64 < RegionInfo
103
76
 
104
- class Ragweed::Wraposx::RegionBasicInfo < Ragweed::Wraposx::RegionInfo
105
-
106
- FLAVOR = Ragweed::Wraposx::Vm::REGION_BASIC_INFO
107
-
108
- (FIELDS = [ [:protection, "i"], # The current protection for the region.
109
- [:max_protection, "i"], # The maximum protection allowed for the region.
110
- [:inheritance, "I"], # The inheritance attribute for the region.
111
- [:shared, "I"], # Shared indicator. If true, the region is shared by another task. If false, the region is not shared.
112
- [:reserved, "I"], # If true the region is protected from random allocation.
113
- [:offset, "L"], # The region's offset into the memory object. The region begins at this offset.
114
- [:behavior, "i"], # Expected reference pattern for the memory.
115
- [:user_wired_count, "S"],
116
- [:size, "I"], # size of memory region returned
117
- [:base_address, "L"]
118
- ]).each {|x| attr_accessor x[0]}
119
-
120
- def dump(&block)
121
- maybe_hex = lambda {|a| begin; "\n" + (" " * 9) + block.call(a, 16).hexdump(true)[10..-2]; rescue; ""; end }
122
- maybe_dis = lambda {|a| begin; "\n" + block.call(a, 16).distorm.map {|i| " " + i.mnem}.join("\n"); rescue; ""; end }
123
-
124
- string =<<EOM
125
- -----------------------------------------------------------------------
126
- BASIC INFO:
127
- base address: #{self.base_address.to_s(16).rjust(8, "0")}
128
-
129
- protection: #{self.protection.to_s(2).rjust(8, "0")} #{Ragweed::Wraposx::Vm::Pflags.flag_dump(self.protection)}
130
- max_protection: #{self.max_protection.to_s(2).rjust(8, "0")} #{Ragweed::Wraposx::Vm::Pflags.flag_dump(self.max_protection)}
131
- inheritance: #{self.inheritance.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.inheritance)}
132
- shared: #{self.shared.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.shared)}
133
- reserved: #{self.reserved.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.reserved)}
134
- offset: #{self.offset.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.offset)}
135
- behavior: #{self.behavior.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.behavior)}
136
- user_wired_count: #{self.user_wired_count.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.user_wired_count)}
137
- size: #{self.size.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.size)}
138
- EOM
139
- end
77
+ layout :protection, Ragweed::Wraposx::Libc.find_type(:vm_prot_t),
78
+ :max_protection, Ragweed::Wraposx::Libc.find_type(:vm_prot_t),
79
+ :inheritance, Ragweed::Wraposx::Libc.find_type(:vm_inherit_t),
80
+ :shared, Ragweed::Wraposx::Libc.find_type(:boolean_t),
81
+ :reserved, Ragweed::Wraposx::Libc.find_type(:boolean_t),
82
+ :offset, Ragweed::Wraposx::Libc.find_type(:memory_object_offset_t),
83
+ :behavior, Ragweed::Wraposx::Libc.find_type(:vm_behavior_t),
84
+ :user_wired_count, :ushort
140
85
 
141
- def self.get(t, a)
142
- self.new(Ragweed::Wraposx::vm_region_raw(t, a, FLAVOR))
143
- end
144
- end
86
+ def dump(&block)
87
+ maybe_hex = lambda {|a| begin; "\n" + (" " * 9) + block.call(a, 16).hexdump(true)[10..-2]; rescue; ""; end }
88
+ maybe_dis = lambda {|a| begin; "\n" + block.call(a, 16).distorm.map {|i| " " + i.mnem}.join("\n"); rescue; ""; end }
145
89
 
146
- class Ragweed::Wraposx::RegionExtendedInfo < Ragweed::Wraposx::RegionInfo
147
-
148
- FLAVOR = Ragweed::Wraposx::Vm::REGION_EXTENDED_INFO
149
- (FIELDS = [ [:protection, "i"],
150
- [:user_tag, "I"],
151
- [:pages_resident, "I"],
152
- [:pages_shared_now_private, "I"],
153
- [:pages_swapped_out, "I"],
154
- [:pages_dirtied, "I"],
155
- [:ref_count, "I"],
156
- [:shadow_depth, "S"],
157
- [:external_pager, "C"],
158
- [:share_mode, "C"],
159
- [:size, "I"],
160
- [:base_address, "I"] ]).each {|x| attr_accessor x[0]}
161
-
162
- def dump(&block)
163
- maybe_hex = lambda {|a| begin; "\n" + (" " * 9) + block.call(a, 16).hexdump(true)[10..-2]; rescue; ""; end }
164
- maybe_dis = lambda {|a| begin; "\n" + block.call(a, 16).distorm.map {|i| " " + i.mnem}.join("\n"); rescue; ""; end }
165
-
166
- string =<<EOM
167
- -----------------------------------------------------------------------
168
- EXTENDED INFO:
169
- base address: #{self.base_address.to_s(16).rjust(8, "0")}
90
+ string =<<EOM
91
+ -----------------------------------------------------------------------
92
+ BASIC INFO:
93
+ base address: #{self.base_address.to_s(16).rjust(8, "0")}
170
94
 
171
- protection: #{self.protection.to_s(2).rjust(8, "0")} #{Ragweed::Wraposx::Vm::Pflags.flag_dump(self.protection)}
172
- user_tag: #{self.user_tag.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.user_tag)}
173
- pages_resident: #{self.pages_resident.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.pages_resident)}
174
- pages_shared_now_private: #{self.pages_shared_now_private.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.pages_shared_now_private)}
175
- pages_swapped_out: #{self.pages_swapped_out.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.pages_swapped_out)}
176
- pages_dirtied: #{self.pages_dirtied.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.pages_dirtied)}
177
- ref_count: #{self.ref_count.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.ref_count)}
178
- shadow_depth: #{self.shadow_depth.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.shadow_depth)}
179
- external_pager: #{self.external_pager.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.external_pager)}
180
- share_mode: #{self.share_mode.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.share_mode)}
181
- size: #{self.size.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.size)}
95
+ protection: #{self.protection.to_s(2).rjust(8, "0")} #{Ragweed::Wraposx::Vm::Pflags.flag_dump(self.protection)}
96
+ max_protection: #{self.max_protection.to_s(2).rjust(8, "0")} #{Ragweed::Wraposx::Vm::Pflags.flag_dump(self.max_protection)}
97
+ inheritance: #{self.inheritance.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.inheritance)}
98
+ shared: #{self.shared.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.shared)}
99
+ reserved: #{self.reserved.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.reserved)}
100
+ offset: #{self.offset.to_s(16).rjust(16, "0")} #{maybe_hex.call(self.offset)}
101
+ behavior: #{self.behavior.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.behavior)}
102
+ user_wired_count: #{self.user_wired_count.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.user_wired_count)}
103
+ size: #{self.size.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.size)}
182
104
  EOM
105
+ end
183
106
  end
184
107
 
185
- def self.get(t, a)
186
- self.new(Ragweed::Wraposx::vm_region_raw(t, a, FLAVOR))
187
- end
188
- end
108
+ # struct vm_region_extended_info {
109
+ # vm_prot_t protection;
110
+ # unsigned int user_tag;
111
+ # unsigned int pages_resident;
112
+ # unsigned int pages_shared_now_private;
113
+ # unsigned int pages_swapped_out;
114
+ # unsigned int pages_dirtied;
115
+ # unsigned int ref_count;
116
+ # unsigned short shadow_depth;
117
+ # unsigned char external_pager;
118
+ # unsigned char share_mode;
119
+ # };
120
+ class RegionExtendedInfo < RegionInfo
121
+ layout :protection, Ragweed::Wraposx::Libc.find_type(:vm_prot_t),
122
+ :user_tag, :uint,
123
+ :pages_resident, :uint,
124
+ :pages_shared_now_private, :uint,
125
+ :pages_swapped_out, :uint,
126
+ :pages_dirtied, :uint,
127
+ :ref_count, :uint,
128
+ :shadow_depth, :ushort,
129
+ :external_pager, :uchar,
130
+ :share_mode, :uchar
189
131
 
190
- class Ragweed::Wraposx::RegionTopInfo < Ragweed::Wraposx::RegionInfo
132
+ def dump(&block)
133
+ maybe_hex = lambda {|a| begin; "\n" + (" " * 9) + block.call(a, 16).hexdump(true)[10..-2]; rescue; ""; end }
134
+ maybe_dis = lambda {|a| begin; "\n" + block.call(a, 16).distorm.map {|i| " " + i.mnem}.join("\n"); rescue; ""; end }
191
135
 
192
- FLAVOR = Ragweed::Wraposx::Vm::REGION_TOP_INFO
136
+ string =<<EOM
137
+ -----------------------------------------------------------------------
138
+ EXTENDED INFO:
139
+ base address: #{self.base_address.to_s(16).rjust(8, "0")}
140
+
141
+ protection: #{self.protection.to_s(2).rjust(8, "0")} #{Ragweed::Wraposx::Vm::Pflags.flag_dump(self.protection)}
142
+ user_tag: #{self.user_tag.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.user_tag)}
143
+ pages_resident: #{self.pages_resident.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.pages_resident)}
144
+ pages_shared_now_private: #{self.pages_shared_now_private.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.pages_shared_now_private)}
145
+ pages_swapped_out: #{self.pages_swapped_out.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.pages_swapped_out)}
146
+ pages_dirtied: #{self.pages_dirtied.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.pages_dirtied)}
147
+ ref_count: #{self.ref_count.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.ref_count)}
148
+ shadow_depth: #{self.shadow_depth.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.shadow_depth)}
149
+ external_pager: #{self.external_pager.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.external_pager)}
150
+ share_mode: #{self.share_mode.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.share_mode)}
151
+ size: #{self.size.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.size)}
152
+ EOM
153
+ end
154
+ end
193
155
 
194
- (FIELDS = [ [:obj_id, "I"],
195
- [:ref_count, "I"],
196
- [:private_pages_resident, "I"],
197
- [:shared_pages_resident, "I"],
198
- [:share_mode, "C"],
199
- [:size, "I"],
200
- [:base_address,"I"]]).each {|x| attr_accessor x[0]}
156
+ # struct vm_region_top_info {
157
+ # unsigned int obj_id;
158
+ # unsigned int ref_count;
159
+ # unsigned int private_pages_resident;
160
+ # unsigned int shared_pages_resident;
161
+ # unsigned char share_mode;
162
+ # };
163
+ class RegionTopInfo < RegionInfo
164
+ layout :obj_id, :uint,
165
+ :ref_count, :uint,
166
+ :private_pages_resident, :uint,
167
+ :shared_pages_resident, :uint,
168
+ :share_mode, :uchar
201
169
 
202
- def dump(&block)
203
- maybe_hex = lambda {|a| begin; "\n" + (" " * 9) + block.call(a, 16).hexdump(true)[10..-2]; rescue; ""; end }
204
- maybe_dis = lambda {|a| begin; "\n" + block.call(a, 16).distorm.map {|i| " " + i.mnem}.join("\n"); rescue; ""; end }
170
+ def dump(&block)
171
+ maybe_hex = lambda {|a| begin; "\n" + (" " * 9) + block.call(a, 16).hexdump(true)[10..-2]; rescue; ""; end }
172
+ maybe_dis = lambda {|a| begin; "\n" + block.call(a, 16).distorm.map {|i| " " + i.mnem}.join("\n"); rescue; ""; end }
205
173
 
206
- string =<<EOM
207
- -----------------------------------------------------------------------
208
- TOP INFO:
209
- base address: #{self.base_address.to_s(16).rjust(8, "0")}
174
+ string =<<EOM
175
+ -----------------------------------------------------------------------
176
+ TOP INFO:
177
+ base address: #{self.base_address.to_s(16).rjust(8, "0")}
210
178
 
211
- obj_id: #{self.obj_id.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.obj_id)}
212
- ref_count: #{self.ref_count.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.ref_count)}
213
- private_pages_resident: #{self.private_pages_resident.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.private_pages_resident)}
214
- shared_pages_resident: #{self.shared_pages_resident.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.shared_pages_resident)}
215
- share_mode: #{self.share_mode.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.share_mode)}
216
- size: #{self.size.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.size)}
179
+ obj_id: #{self.obj_id.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.obj_id)}
180
+ ref_count: #{self.ref_count.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.ref_count)}
181
+ private_pages_resident: #{self.private_pages_resident.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.private_pages_resident)}
182
+ shared_pages_resident: #{self.shared_pages_resident.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.shared_pages_resident)}
183
+ share_mode: #{self.share_mode.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.share_mode)}
184
+ size: #{self.size.to_s(16).rjust(8, "0")} #{maybe_hex.call(self.size)}
217
185
  EOM
186
+ end
218
187
  end
219
188
 
220
- def self.get(t, a)
221
- self.new(Ragweed::Wraposx::vm_region_raw(t, a, FLAVOR))
222
- end
189
+ #define VM_REGION_BASIC_INFO_COUNT ((mach_msg_type_number_t) (sizeof(vm_region_basic_info_data_t)/sizeof(int)))
190
+ #define VM_REGION_BASIC_INFO_COUNT_64 ((mach_msg_type_number_t) (sizeof(vm_region_basic_info_data_64_t)/sizeof(int)))
191
+ #define VM_REGION_EXTENDED_INFO_COUNT ((mach_msg_type_number_t) (sizeof(vm_region_extended_info_data_t)/sizeof(int)))
192
+ #define VM_REGION_TOP_INFO_COUNT ((mach_msg_type_number_t) (sizeof(vm_region_top_info_data_t)/sizeof(int)))
193
+ FLAVORS = { REGION_BASIC_INFO => {:size => 30, :count => 8, :class => RegionBasicInfo},
194
+ REGION_BASIC_INFO_64 => {:size => 30, :count => 9, :class => RegionBasicInfo64},
195
+ REGION_EXTENDED_INFO => {:size => 32, :count => 8, :class => RegionExtendedInfo},
196
+ REGION_TOP_INFO => {:size => 17,:count => 5, :class => RegionTopInfo}
197
+ }
223
198
  end
224
199
 
225
200
  module Ragweed::Wraposx
201
+ module Libc
202
+ extend FFI::Library
203
+ ffi_lib FFI::Library::LIBC
204
+
205
+ # determine if a function is defined in the attached libraries
206
+ def self.find_function func
207
+ ffi_libraries.detect{|lib| lib.find_function(func)}
208
+ end
209
+
210
+ attach_function :vm_region, [:vm_map_t, :pointer, :pointer, :vm_region_flavor_t, :pointer, :pointer, :pointer], :int if find_function "vm_region"
211
+ attach_function :vm_region_64, [:vm_map_t, :pointer, :pointer, :vm_region_flavor_t, :pointer, :pointer, :pointer], :int if find_function "vm_region_64"
212
+ end
213
+
226
214
  class << self
227
215
 
228
- # Returns a string containing the memory region information for task
229
- # at address.
216
+ # Returns the base address, size, and a pointer to the requested information
217
+ # about the memory region at address in the target_task.
230
218
  #
231
- # The order of the elements in the returned string will change in 0.2.0+
232
- # to match the argument order.
219
+ # Currently, only VM_REGION_BASIC_INFO is supported by Apple.
220
+ # Unless this is being run in 32bits, use vm_region_64 instead.
233
221
  #
234
222
  # kern_return_t vm_region
235
- # (vm_task_t target_task,
236
- # vm_address_t address,
237
- # vm_size_t size,
238
- # vm_region_flavor_t flavor,
239
- # vm_region_info_t info,
240
- # mach_msg_type_number_t info_count,
241
- # memory_object_name_t object_name);
242
- def vm_region_raw(task, address, flavor)
243
- info = ("\x00"*Vm::FLAVORS[flavor][:size]).to_ptr
244
- count = ([Vm::FLAVORS[flavor][:count]].pack("I_")).to_ptr
245
- address = ([address].pack("I_")).to_ptr
246
- objn = ([0].pack("I_")).to_ptr
247
- sz = ("\x00"*SIZEOFINT).to_ptr
248
- r = CALLS["libc!vm_region:IPPIPPP=I"].call(task, address, sz, flavor, info, count, objn).first
223
+ # (vm_map_t target_task,
224
+ # vm_address_t *address,
225
+ # vm_size_t *size,
226
+ # vm_region_flavor_t flavor,
227
+ # vm_region_info_t info,
228
+ # mach_msg_type_number_t *info_count,
229
+ # mach_port_t *object_name);
230
+ def vm_region(task, addr, flavor)
231
+ info = FFI::MemoryPointer.new(Vm::FLAVORS[flavor][:class], 1)
232
+ count = FFI::MemoryPointer.new(:int, 1).write_int(Vm::FLAVORS[flavor][:count])
233
+ address = FFI::MemoryPointer.new(:vm_address_t, 1).write_ulong(addr)
234
+ sz = FFI::MemoryPointer.new(:vm_size_t, 1)
235
+ objn = FFI::MemoryPointer.new(:mach_port_t, 1)
236
+
237
+ r = Libc.vm_region(task, address, sz, flavor, info, count, objn)
249
238
  raise KernelCallError.new(:vm_region, r) if r != 0
250
- # this
251
- return "#{info.to_s(Vm::FLAVORS[flavor][:size])}#{sz.to_s(SIZEOFINT)}#{address.to_s(SIZEOFINT)}"
252
- end
239
+ ret = Vm::Flavors[flavor][:class].new info
240
+ ret.region_size = size.read_ulong
241
+ ret.base_address = address.read_ulong
242
+ ret
243
+ end if Libc.find_function "vm_region"
244
+
245
+ # Returns the base address, size, and a pointer to the requested information
246
+ # about the memory region at address in the target_task.
247
+ #
248
+ # Currently, only VM_REGION_BASIC_INFO is supported by Apple.
249
+ #
250
+ # kern_return_t vm_region
251
+ # (vm_map_t target_task,
252
+ # vm_address_t *address,
253
+ # vm_size_t *size,
254
+ # vm_region_flavor_t flavor,
255
+ # vm_region_info_t info,
256
+ # mach_msg_type_number_t *info_count,
257
+ # mach_port_t *object_name);
258
+ def vm_region_64(task, addr, flavor)
259
+ # OSX does this as well, so we need to do it ourselves
260
+ flavor = Vm::REGION_BASIC_INFO_64 if flavor == Vm::REGION_BASIC_INFO
261
+ info = FFI::MemoryPointer.new(:uint8, Vm::FLAVORS[flavor][:size])
262
+ count = FFI::MemoryPointer.new(Libc.find_type(:mach_msg_type_number_t), 1).write_uint(Vm::FLAVORS[flavor][:count])
263
+ address = FFI::MemoryPointer.new(Libc.find_type(:vm_address_t), 1).write_ulong(addr)
264
+ sz = FFI::MemoryPointer.new(Libc.find_type(:vm_size_t), 1)
265
+ objn = FFI::MemoryPointer.new(Libc.find_type(:mach_port_t), 1)
266
+
267
+ r = Libc.vm_region_64(task, address, sz, flavor, info, count, objn)
268
+ raise KernelCallError.new(:vm_region_64, r) if r != 0
269
+ ret = Vm::Flavors[flavor][:class].new info
270
+ ret.region_size = size.read_ulong
271
+ ret.base_address = address.read_ulong
272
+ ret
273
+ end if Libc.find_function "vm_region_64"
253
274
  end
254
275
  end
@@ -0,0 +1,102 @@
1
+ # miscelaneous structs needed for other calls/structures
2
+
3
+ module Ragweed; end
4
+ module Ragweed::Wraposx
5
+ class FpControl < FFI::Struct
6
+ layout :value, :ushort
7
+
8
+ def invalid
9
+ self.value >> 15
10
+ end
11
+ def denorm
12
+ (self.value >> 14) & 1
13
+ end
14
+ def zdiv
15
+ (self.value >> 13) & 1
16
+ end
17
+ def ovrfl
18
+ (self.value >> 12) & 1
19
+ end
20
+ def undfl
21
+ (self.value >> 11) & 1
22
+ end
23
+ def precis
24
+ (self.value >> 10) & 1
25
+ end
26
+ def res0
27
+ (self.value >> 8) & 3
28
+ end
29
+ def pc
30
+ (self.value >> 6) & 3
31
+ end
32
+ def rc
33
+ (self.value >> 4) & 3
34
+ end
35
+ def res1
36
+ (self.value >> 3) & 1
37
+ end
38
+ def res2
39
+ self.value & 7
40
+ end
41
+ end
42
+
43
+ class FpStatus < FFI::Struct
44
+ layout :value, :ushort
45
+ def invalid
46
+ self.value >> 15
47
+ end
48
+ def denorm
49
+ (self.value >> 14) & 1
50
+ end
51
+ def zdiv
52
+ (self.value >> 13) & 1
53
+ end
54
+ def ovrfl
55
+ (self.value >> 12) & 1
56
+ end
57
+ def undfl
58
+ (self.value >> 11) & 1
59
+ end
60
+ def precis
61
+ (self.value >> 10) & 1
62
+ end
63
+ def stkflt
64
+ (self.value >> 9) & 1
65
+ end
66
+ def errsumm
67
+ (self.value >> 8) & 1
68
+ end
69
+ def c0
70
+ (self.value >> 7) & 1
71
+ end
72
+ def c1
73
+ (self.value >> 6) & 1
74
+ end
75
+ def c2
76
+ (self.value >> 5) & 1
77
+ end
78
+ def tos
79
+ (self.value >> 2) & 7
80
+ end
81
+ def c2
82
+ (self.value >> 1) & 1
83
+ end
84
+ def busy
85
+ self.value & 1
86
+ end
87
+ end
88
+
89
+ class MmstReg < FFI::Struct
90
+ layout :mmst_reg, [:char, 10],
91
+ :mmst_rsrv, [:char, 6]
92
+ end
93
+
94
+ class XmmReg < FFI::Struct
95
+ layout :xmm_reg, [:char, 16]
96
+ end
97
+
98
+ class TimeValue < FFI::Struct
99
+ layout :seconds, :int,
100
+ :microseconds, :int
101
+ end
102
+ end