2 // **********************************************************************
3 // The Cheat - A universal game cheater for Mac OS X
4 // (C) 2003-2005 Chaz McGarvey (BrokenZipper)
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 1, or (at your option)
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #import "SearchContext.h"
25 @implementation SearchContext
28 #pragma mark Initialization
31 * There isn't really a designated initializer because the initialization of the types
32 * of searches vary way too much.
35 - (id)initWithPID
:(pid_t
)pid searchOperator
:(TCSearchOperator
)op value
:(Variable
*)val
45 valueSize
= [value valueSize
];
47 _variableType
= [value type
];
48 _integerSign
= [value integerSign
];
50 _searchType
= TCGivenValue
;
51 compareFunc
= [self compareFunction
];
53 // allocate the memory objects which will be used during the search
54 regionCount
= VMCountRegionsWithAttributes( process
, VMREGION_READABLE | VMREGION_WRITABLE
);
55 addresses
= TCMakeArray( TC_BUFFER_SIZE
/ sizeof(TCAddress
), sizeof(TCAddress
) );
56 values
= TCMakeArray( TC_BUFFER_SIZE
/ valueSize
, valueSize
);
57 regions
= TCMakeArray( 0, sizeof(TCAddress
) );
58 perRegion
= TCMakeArray( 0, sizeof(unsigned) );
59 addressPtr
= TCArrayBytes( addresses
);
60 valuePtr
= TCArrayBytes( values
);
62 ChazLog( @
"SearchContext: varType=%i, intSign=%i, op=%i, value=%@", _variableType
, _integerSign
, _operator
, [value stringValue
] );
67 - (id)initWithLastContext
:(SearchContext
*)context searchOperator
:(TCSearchOperator
)op
76 valueSize
= TCArrayElementSize(context
->values
);
77 process
= context
->process
;
78 _variableType
= [context variableType
];
79 _integerSign
= [context integerSign
];
81 _searchType
= TCLastValue
;
82 compareFunc
= [self compareFunction
];
84 regionCount
= TCArrayElementCount( context
->regions
);
85 addresses
= TCMakeArray( TC_BUFFER_SIZE
/ sizeof(TCAddress
), sizeof(TCAddress
) );
86 values
= TCMakeArray( TC_BUFFER_SIZE
/ valueSize
, valueSize
);
87 regions
= TCMakeArray( 0, sizeof(TCAddress
) );
88 perRegion
= TCMakeArray( 0, sizeof(unsigned) );
89 lastAddresses
= context
->addresses
;
90 lastValues
= context
->values
;
91 lastRegions
= context
->regions
;
92 lastPerRegion
= context
->perRegion
;
93 addressPtr
= TCArrayBytes( addresses
);
94 valuePtr
= TCArrayBytes( values
);
95 lastAddressPtr
= TCArrayBytes( lastAddresses
);
96 lastValuePtr
= TCArrayBytes( lastValues
);
97 lastRegionPtr
= TCArrayBytes( lastRegions
);
98 lastPerRegionPtr
= TCArrayBytes( lastPerRegion
);
100 ChazLog( @
"SearchContext: varType=%i, intSign=%i, op=%i", _variableType
, _integerSign
, _operator
);
105 - (id)initWithLastContext
:(SearchContext
*)context searchOperator
:(TCSearchOperator
)op value
:(Variable
*)val
109 if ( [super init
] ) {
110 if ( !context ||
!val ||
([val type
] != [context variableType
]) // and search values can't be bigger than the last time.
111 ||
(([context variableType
] == TCString
) && ([val valueSize
] > TCArrayElementSize(context
->values
))) ) {
115 value
= [val retain
];
116 valueSize
= [value valueSize
];
117 process
= context
->process
;
118 _variableType
= [context variableType
];
119 _integerSign
= [context integerSign
];
121 _searchType
= TCGivenValue
;
122 compareFunc
= [self compareFunction
];
124 regionCount
= TCArrayElementCount( context
->regions
);
125 addresses
= TCMakeArray( TC_BUFFER_SIZE
/ sizeof(TCAddress
), sizeof(TCAddress
) );
126 values
= TCMakeArray( TC_BUFFER_SIZE
/ valueSize
, valueSize
);
127 regions
= TCMakeArray( 0, sizeof(TCAddress
) );
128 perRegion
= TCMakeArray( 0, sizeof(unsigned) );
129 lastAddresses
= context
->addresses
;
130 lastValues
= context
->values
;
131 lastRegions
= context
->regions
;
132 lastPerRegion
= context
->perRegion
;
133 addressPtr
= TCArrayBytes( addresses
);
134 valuePtr
= TCArrayBytes( values
);
135 lastAddressPtr
= TCArrayBytes( lastAddresses
);
136 lastValuePtr
= TCArrayBytes( lastValues
);
137 lastRegionPtr
= TCArrayBytes( lastRegions
);
138 lastPerRegionPtr
= TCArrayBytes( lastPerRegion
);
140 ChazLog( @
"SearchContext: varType=%i, intSign=%i, op=%i, value=%@", _variableType
, _integerSign
, _operator
, [value stringValue
] );
147 ChazLog( @
"SearchContext %p dealloc", self );
148 TCReleaseArray( addresses
);
149 TCReleaseArray( values
);
150 TCReleaseArray( regions
);
151 TCReleaseArray( perRegion
);
162 #pragma mark Accessors
164 - (TCVariableType
)variableType
166 return _variableType
;
169 - (TCIntegerSign
)integerSign
174 - (TCSearchOperator
)searchOperator
180 - (BOOL (*)(void const *, void const *))compareFunction
182 // here begins a very pretty collection of switch and if statements. enjoy!
183 switch ( _operator
) {
185 switch ( _variableType
) {
186 case TCFloat
: return EqualFloat
;
187 case TCDouble
: return EqualDouble
;
189 if ( _integerSign
== TCSigned
) {
190 switch ( _variableType
) {
191 case TCInt64
: return EqualInt64
;
192 case TCInt32
: return EqualInt32
;
193 case TCInt16
: return EqualInt16
;
194 case TCInt8
: return EqualInt8
;
198 switch ( _variableType
) {
199 case TCInt64
: return EqualUInt64
;
200 case TCInt32
: return EqualUInt32
;
201 case TCInt16
: return EqualUInt16
;
202 case TCInt8
: return EqualUInt8
;
207 switch ( _variableType
) {
208 case TCFloat
: return NotEqualFloat
;
209 case TCDouble
: return NotEqualDouble
;
211 if ( _integerSign
== TCSigned
) {
212 switch ( _variableType
) {
213 case TCInt64
: return NotEqualInt64
;
214 case TCInt32
: return NotEqualInt32
;
215 case TCInt16
: return NotEqualInt16
;
216 case TCInt8
: return NotEqualInt8
;
220 switch ( _variableType
) {
221 case TCInt64
: return NotEqualUInt64
;
222 case TCInt32
: return NotEqualUInt32
;
223 case TCInt16
: return NotEqualUInt16
;
224 case TCInt8
: return NotEqualUInt8
;
229 switch ( _variableType
) {
230 case TCFloat
: return LessThanFloat
;
231 case TCDouble
: return LessThanDouble
;
233 if ( _integerSign
== TCSigned
) {
234 switch ( _variableType
) {
235 case TCInt64
: return LessThanInt64
;
236 case TCInt32
: return LessThanInt32
;
237 case TCInt16
: return LessThanInt16
;
238 case TCInt8
: return LessThanInt8
;
242 switch ( _variableType
) {
243 case TCInt64
: return LessThanUInt64
;
244 case TCInt32
: return LessThanUInt32
;
245 case TCInt16
: return LessThanUInt16
;
246 case TCInt8
: return LessThanUInt8
;
251 switch ( _variableType
) {
252 case TCFloat
: return GreaterThanFloat
;
253 case TCDouble
: return GreaterThanDouble
;
255 if ( _integerSign
== TCSigned
) {
256 switch ( _variableType
) {
257 case TCInt64
: return GreaterThanInt64
;
258 case TCInt32
: return GreaterThanInt32
;
259 case TCInt16
: return GreaterThanInt16
;
260 case TCInt8
: return GreaterThanInt8
;
264 switch ( _variableType
) {
265 case TCInt64
: return GreaterThanUInt64
;
266 case TCInt32
: return GreaterThanUInt32
;
267 case TCInt16
: return GreaterThanUInt16
;
268 case TCInt8
: return GreaterThanUInt8
;
276 - (int (*)(id, unsigned))iterationFunction
278 if ( _searchType
== TCGivenValue
) {
279 if ( !lastAddresses
) {
280 if ( _variableType
== TCString
) {
281 return SearchStringIteration
;
284 return SearchIteration
;
288 if ( _variableType
== TCString
) {
289 return SearchStringIterationAgain
;
292 return SearchIterationAgain
;
296 else if ( _searchType
== TCLastValue
) {
297 if ( _variableType
== TCString
) {
298 return SearchStringIterationLastValue
;
301 return SearchIterationLastValue
;