-
Notifications
You must be signed in to change notification settings - Fork 13
/
VMRegion.h
187 lines (145 loc) · 5.61 KB
/
VMRegion.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
//
// VMRegion 0.1
// Virtual Memory Wrapper
//
// Copyright (c) 2004, Charles McGarvey
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list
// of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this
// list of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
// SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
// DAMAGE.
//
#import <Cocoa/Cocoa.h>
#include <mach/mach_vm.h>
#include <mach/vm_map.h>
/* Compiler macros */
#if defined( __cplusplus )
#define VMREGION_EXPORT extern "C"
#define VMREGION_IMPORT extern "C"
#else
#define VMREGION_EXPORT extern
#define VMREGION_IMPORT extern
#endif
#if !defined( VMREGION_STATIC_INLINE )
#define VMREGION_STATIC_INLINE static __inline__
#endif
#if !defined( VMREGION_EXTERN_INLINE )
#define VMREGION_EXTERN_INLINE extern __inline__
#endif
// attributes of memory regions
enum _VMRegionAttributes
{
VMREGION_READABLE = 1,
VMREGION_WRITABLE = 2,
VMREGION_EXECUTABLE = 4
};
#pragma mark -
#pragma mark VMRegion
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
typedef struct _VMRegion
{
// process information
pid_t _process;
// region information
mach_vm_address_t _address;
mach_vm_size_t _size;
unsigned _attributes;
} VMRegion;
// common regions
VMREGION_EXPORT const VMRegion VMNullRegion; /* <0,0,0> */
#pragma mark -
#pragma mark Utility VM Functions
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
// get the number of regions a process has.
unsigned VMCountRegions( pid_t process );
unsigned VMCountRegionsWithAttributes( pid_t process, unsigned attribs );
// these functions return allocated VMRegion objects.
// use VMReleaseRegion(1) to free up used memory.
// returns nil on error or if there is no region after prevRegion.
// pass nil for prevRegion to access the first region.
VMRegion VMNextRegion( pid_t process, VMRegion previous );
VMRegion VMNextRegionWithAttributes( pid_t process, VMRegion previous, unsigned attribs );
// UTILITY functions - stop/resume processes
// returns YES on success, NO on failure
VMREGION_STATIC_INLINE BOOL VMStopProcess( pid_t process ) { return (kill( process, SIGSTOP ) == 0); }
VMREGION_STATIC_INLINE BOOL VMContinueProcess( pid_t process ) { return (kill( process, SIGCONT ) == 0); }
// lower-level reading/writing functions
// the returned NSData object should be retained by the caller.
NSData *VMReadData( pid_t process, mach_vm_address_t address, mach_vm_size_t size );
BOOL VMReadBytes( pid_t process, mach_vm_address_t address, void *bytes, mach_vm_size_t *size ); // size is # bytes read after call
BOOL VMWriteData( pid_t process, mach_vm_address_t address, NSData *data ); // returns YES on success, NO on failure
BOOL VMWriteBytes( pid_t process, mach_vm_address_t address, const void *bytes, mach_vm_size_t size );
#pragma mark -
#pragma mark Exported VM Functions
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
VMREGION_EXPORT VMRegion VMMakeRegion( pid_t process, mach_vm_address_t address, mach_vm_size_t size );
VMREGION_EXPORT BOOL VMRegionSetData( VMRegion region, NSData *data );
VMREGION_EXPORT NSString *VMStringFromRegion( VMRegion region );
#pragma mark -
#pragma mark Imported VM Functions
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
VMREGION_STATIC_INLINE mach_vm_address_t VMRegionProcess( VMRegion region )
{
return region._process;
}
VMREGION_STATIC_INLINE mach_vm_address_t VMRegionAddress( VMRegion region )
{
return region._address;
}
VMREGION_STATIC_INLINE mach_vm_size_t VMRegionSize( VMRegion region )
{
return region._size;
}
VMREGION_STATIC_INLINE unsigned VMRegionAttributes( VMRegion region )
{
return region._attributes;
}
VMREGION_STATIC_INLINE BOOL VMRegionReadable( VMRegion region )
{
return region._attributes & VMREGION_READABLE;
}
VMREGION_STATIC_INLINE BOOL VMRegionWritable( VMRegion region )
{
return region._attributes & VMREGION_WRITABLE;
}
VMREGION_STATIC_INLINE BOOL VMRegionExecutable( VMRegion region )
{
return region._attributes & VMREGION_EXECUTABLE;
}
VMREGION_STATIC_INLINE NSData *VMRegionData( VMRegion region )
{
return VMReadData( region._process, region._address, region._size );
}
VMREGION_STATIC_INLINE BOOL VMRegionBytes( VMRegion region, void *bytes, mach_vm_size_t *size )
{
*size = region._size;
return VMReadBytes( region._process, region._address, bytes, size );
}
VMREGION_STATIC_INLINE BOOL VMRegionIsNotNull( VMRegion region )
{
return (region._process != 0);
}
VMREGION_STATIC_INLINE BOOL VMEqualRegions( VMRegion region1, VMRegion region2 )
{
return (region1._process == region2._process &&
region1._address == region2._address &&
region1._size == region2._size &&
region1._attributes == region2._attributes);
}