3 * The Cheat - The legendary universal game trainer for Mac OS X.
4 * http://www.brokenzipper.com/trac/wiki/TheCheat
6 * Copyright (c) 2003-2011, Charles McGarvey et al.
8 * Distributable under the terms and conditions of the 2-clause BSD
9 * license; see the file COPYING for the legal text of the license.
13 #import "SearchContext.h"
16 @implementation SearchContext
19 #pragma mark Initialization
22 * There isn't really a designated initializer because the initialization of the types
23 * of searches vary way too much.
26 - (id)initWithPID
:(pid_t
)pid searchOperator
:(TCSearchOperator
)op value
:(Variable
*)val
36 valueSize
= [value valueSize
];
38 _variableType
= [value type
];
39 _integerSign
= [value integerSign
];
41 _searchType
= TCGivenValue
;
42 compareFunc
= [self compareFunction
];
44 // allocate the memory objects which will be used during the search
45 regionCount
= VMCountRegionsWithAttributes( process
, VMREGION_READABLE | VMREGION_WRITABLE
);
46 addresses
= TCMakeArray( TC_BUFFER_SIZE
/ sizeof(TCAddress
), sizeof(TCAddress
) );
47 values
= TCMakeArray( TC_BUFFER_SIZE
/ valueSize
, valueSize
);
48 regions
= TCMakeArray( 0, sizeof(TCAddress
) );
49 perRegion
= TCMakeArray( 0, sizeof(unsigned) );
50 addressPtr
= TCArrayBytes( addresses
);
51 valuePtr
= TCArrayBytes( values
);
53 ChazLog( @
"SearchContext: varType=%i, intSign=%i, op=%i, value=%@", _variableType
, _integerSign
, _operator
, [value stringValue
] );
58 - (id)initWithLastContext
:(SearchContext
*)context searchOperator
:(TCSearchOperator
)op
67 valueSize
= TCArrayElementSize(context
->values
);
68 process
= context
->process
;
69 _variableType
= [context variableType
];
70 _integerSign
= [context integerSign
];
72 _searchType
= TCLastValue
;
73 compareFunc
= [self compareFunction
];
75 regionCount
= TCArrayElementCount( context
->regions
);
76 addresses
= TCMakeArray( TC_BUFFER_SIZE
/ sizeof(TCAddress
), sizeof(TCAddress
) );
77 values
= TCMakeArray( TC_BUFFER_SIZE
/ valueSize
, valueSize
);
78 regions
= TCMakeArray( 0, sizeof(TCAddress
) );
79 perRegion
= TCMakeArray( 0, sizeof(unsigned) );
80 lastAddresses
= context
->addresses
;
81 lastValues
= context
->values
;
82 lastRegions
= context
->regions
;
83 lastPerRegion
= context
->perRegion
;
84 addressPtr
= TCArrayBytes( addresses
);
85 valuePtr
= TCArrayBytes( values
);
86 lastAddressPtr
= TCArrayBytes( lastAddresses
);
87 lastValuePtr
= TCArrayBytes( lastValues
);
88 lastRegionPtr
= TCArrayBytes( lastRegions
);
89 lastPerRegionPtr
= TCArrayBytes( lastPerRegion
);
91 ChazLog( @
"SearchContext: varType=%i, intSign=%i, op=%i", _variableType
, _integerSign
, _operator
);
96 - (id)initWithLastContext
:(SearchContext
*)context searchOperator
:(TCSearchOperator
)op value
:(Variable
*)val
100 if ( [super init
] ) {
101 if ( !context ||
!val ||
([val type
] != [context variableType
]) // and search values can't be bigger than the last time.
102 ||
(([context variableType
] == TCString
) && ([val valueSize
] > TCArrayElementSize(context
->values
))) ) {
106 value
= [val retain
];
107 valueSize
= [value valueSize
];
108 process
= context
->process
;
109 _variableType
= [context variableType
];
110 _integerSign
= [context integerSign
];
112 _searchType
= TCGivenValue
;
113 compareFunc
= [self compareFunction
];
115 regionCount
= TCArrayElementCount( context
->regions
);
116 addresses
= TCMakeArray( TC_BUFFER_SIZE
/ sizeof(TCAddress
), sizeof(TCAddress
) );
117 values
= TCMakeArray( TC_BUFFER_SIZE
/ valueSize
, valueSize
);
118 regions
= TCMakeArray( 0, sizeof(TCAddress
) );
119 perRegion
= TCMakeArray( 0, sizeof(unsigned) );
120 lastAddresses
= context
->addresses
;
121 lastValues
= context
->values
;
122 lastRegions
= context
->regions
;
123 lastPerRegion
= context
->perRegion
;
124 addressPtr
= TCArrayBytes( addresses
);
125 valuePtr
= TCArrayBytes( values
);
126 lastAddressPtr
= TCArrayBytes( lastAddresses
);
127 lastValuePtr
= TCArrayBytes( lastValues
);
128 lastRegionPtr
= TCArrayBytes( lastRegions
);
129 lastPerRegionPtr
= TCArrayBytes( lastPerRegion
);
131 ChazLog( @
"SearchContext: varType=%i, intSign=%i, op=%i, value=%@", _variableType
, _integerSign
, _operator
, [value stringValue
] );
138 ChazLog( @
"SearchContext %p dealloc", self );
139 TCReleaseArray( addresses
);
140 TCReleaseArray( values
);
141 TCReleaseArray( regions
);
142 TCReleaseArray( perRegion
);
153 #pragma mark Accessors
155 - (TCVariableType
)variableType
157 return _variableType
;
160 - (TCIntegerSign
)integerSign
165 - (TCSearchOperator
)searchOperator
171 - (BOOL (*)(void const *, void const *))compareFunction
173 // here begins a very pretty collection of switch and if statements. enjoy!
174 switch ( _operator
) {
176 switch ( _variableType
) {
177 case TCFloat
: return EqualFloat
;
178 case TCDouble
: return EqualDouble
;
180 if ( _integerSign
== TCSigned
) {
181 switch ( _variableType
) {
182 case TCInt64
: return EqualInt64
;
183 case TCInt32
: return EqualInt32
;
184 case TCInt16
: return EqualInt16
;
185 case TCInt8
: return EqualInt8
;
189 switch ( _variableType
) {
190 case TCInt64
: return EqualUInt64
;
191 case TCInt32
: return EqualUInt32
;
192 case TCInt16
: return EqualUInt16
;
193 case TCInt8
: return EqualUInt8
;
198 switch ( _variableType
) {
199 case TCFloat
: return NotEqualFloat
;
200 case TCDouble
: return NotEqualDouble
;
202 if ( _integerSign
== TCSigned
) {
203 switch ( _variableType
) {
204 case TCInt64
: return NotEqualInt64
;
205 case TCInt32
: return NotEqualInt32
;
206 case TCInt16
: return NotEqualInt16
;
207 case TCInt8
: return NotEqualInt8
;
211 switch ( _variableType
) {
212 case TCInt64
: return NotEqualUInt64
;
213 case TCInt32
: return NotEqualUInt32
;
214 case TCInt16
: return NotEqualUInt16
;
215 case TCInt8
: return NotEqualUInt8
;
220 switch ( _variableType
) {
221 case TCFloat
: return LessThanFloat
;
222 case TCDouble
: return LessThanDouble
;
224 if ( _integerSign
== TCSigned
) {
225 switch ( _variableType
) {
226 case TCInt64
: return LessThanInt64
;
227 case TCInt32
: return LessThanInt32
;
228 case TCInt16
: return LessThanInt16
;
229 case TCInt8
: return LessThanInt8
;
233 switch ( _variableType
) {
234 case TCInt64
: return LessThanUInt64
;
235 case TCInt32
: return LessThanUInt32
;
236 case TCInt16
: return LessThanUInt16
;
237 case TCInt8
: return LessThanUInt8
;
242 switch ( _variableType
) {
243 case TCFloat
: return GreaterThanFloat
;
244 case TCDouble
: return GreaterThanDouble
;
246 if ( _integerSign
== TCSigned
) {
247 switch ( _variableType
) {
248 case TCInt64
: return GreaterThanInt64
;
249 case TCInt32
: return GreaterThanInt32
;
250 case TCInt16
: return GreaterThanInt16
;
251 case TCInt8
: return GreaterThanInt8
;
255 switch ( _variableType
) {
256 case TCInt64
: return GreaterThanUInt64
;
257 case TCInt32
: return GreaterThanUInt32
;
258 case TCInt16
: return GreaterThanUInt16
;
259 case TCInt8
: return GreaterThanUInt8
;
267 - (int (*)(id, unsigned))iterationFunction
269 if ( _searchType
== TCGivenValue
) {
270 if ( !lastAddresses
) {
271 if ( _variableType
== TCString
) {
272 return SearchStringIteration
;
275 return SearchIteration
;
279 if ( _variableType
== TCString
) {
280 return SearchStringIterationAgain
;
283 return SearchIterationAgain
;
287 else if ( _searchType
== TCLastValue
) {
288 if ( _variableType
== TCString
) {
289 return SearchStringIterationLastValue
;
292 return SearchIterationLastValue
;