]> Dogcows Code - chaz/thecheat/blob - Variable.m
The Cheat 1.2.4
[chaz/thecheat] / Variable.m
1
2 // **********************************************************************
3 // The Cheat - A universal game cheater for Mac OS X
4 // (C) 2003-2005 Chaz McGarvey (BrokenZipper)
5 //
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)
9 // any later version.
10 //
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.
15 //
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.
19 //
20
21 #import "Variable.h"
22
23 @interface Variable ( PrivateAPI )
24
25 - (void)_setType:(TCVariableType)type;
26 - (void)_setIntegerSign:(TCIntegerSign)sign;
27
28 @end
29
30
31 @implementation Variable
32
33
34 - (id)init
35 {
36 return [self initWithType:TCInt32 integerSign:TCSigned];
37 }
38
39 - (id)initWithType:(TCVariableType)type
40 {
41 return [self initWithType:type integerSign:TCSigned];
42 }
43
44 - (id)initWithType:(TCVariableType)type integerSign:(TCIntegerSign)sign // DESIGNATED
45 {
46 if ( self = [super init] ) {
47 _isValueValid = YES;
48 _enabled = YES;
49 [self _setType:type];
50 [self _setIntegerSign:sign];
51 }
52 return self;
53 }
54
55 - (void)setProcess:(Process *)newProcess
56 {
57 if (process != newProcess && [newProcess pid] > 0)
58 {
59 _isEmulated = [newProcess isEmulated];
60
61 [newProcess retain];
62 [process release];
63 process = newProcess;
64 }
65 }
66
67 - (Process *)process
68 {
69 return process;
70 }
71
72 - (BOOL)isEmulated
73 {
74 return _isEmulated;
75 }
76
77 - (void)dealloc
78 {
79 if ( _value ) {
80 free( _value );
81 }
82 [super dealloc];
83 }
84
85
86 // #############################################################################
87 #pragma mark NSCoding
88 // #############################################################################
89
90 - (id)initWithCoder:(NSCoder *)coder
91 {
92 if ( self = [super init] ) {
93 [coder decodeValueOfObjCType:@encode(TCVariableType) at:&_type];
94 [coder decodeValueOfObjCType:@encode(TCIntegerSign) at:&_integerSign];
95 [coder decodeValueOfObjCType:@encode(TCAddress) at:&_address];
96
97 void *value = [coder decodeBytesWithReturnedLength:&_size];
98
99 if (_type == TCString || _type == TCInt8)
100 {
101 [self setValue:value];
102 }
103 else if (_type == TCInt16)
104 {
105 int16_t newVariable = CFSwapInt16BigToHost(*((int16_t *)value));
106 [self setValue:&newVariable];
107 }
108 else if (_type == TCInt32)
109 {
110 int32_t newVariable = CFSwapInt32BigToHost(*((int32_t *)value));
111 [self setValue:&newVariable];
112 }
113 else if (_type == TCInt64)
114 {
115 int64_t newVariable = CFSwapInt64BigToHost(*((int64_t *)value));
116 [self setValue:&newVariable];
117 }
118 else if (_type == TCFloat)
119 {
120 #ifdef __LITTLE_ENDIAN__
121 CFSwappedFloat32 newVariable = CFConvertFloat32HostToSwapped(*((float *)value));
122 [self setValue:&(newVariable.v)];
123
124 #else
125 [self setValue:value];
126 #endif
127 }
128 else if (_type == TCDouble)
129 {
130 #ifdef __LITTLE_ENDIAN__
131 CFSwappedFloat64 newVariable = CFConvertDoubleHostToSwapped(*((double *)value));
132 [self setValue:&(newVariable.v)];
133 #else
134 [self setValue:value];
135 #endif
136 }
137
138 [coder decodeValueOfObjCType:@encode(BOOL) at:&_isValueValid];
139 [coder decodeValueOfObjCType:@encode(BOOL) at:&_enabled];
140 [coder decodeValueOfObjCType:@encode(int) at:&_tag];
141 }
142 return self;
143 }
144
145 - (void)encodeWithCoder:(NSCoder *)coder
146 {
147 [coder encodeValueOfObjCType:@encode(TCVariableType) at:&_type];
148 [coder encodeValueOfObjCType:@encode(TCIntegerSign) at:&_integerSign];
149 [coder encodeValueOfObjCType:@encode(TCAddress) at:&_address];
150
151 if (_type == TCString || _type == TCInt8)
152 {
153 [coder encodeBytes:_value length:_size];
154 }
155 else if (_type == TCInt16)
156 {
157 int16_t newVariable = CFSwapInt16HostToBig(*((int16_t *)_value));
158 [coder encodeBytes:&newVariable length:_size];
159 }
160 else if (_type == TCInt32)
161 {
162 int32_t newVariable = CFSwapInt32HostToBig(*((int32_t *)_value));
163 [coder encodeBytes:&newVariable length:_size];
164 }
165 else if (_type == TCInt64)
166 {
167 int64_t newVariable = CFSwapInt64HostToBig(*((int64_t *)_value));
168 [coder encodeBytes:&newVariable length:_size];
169 }
170 else if (_type == TCFloat)
171 {
172 #ifdef __LITTLE_ENDIAN__
173 CFSwappedFloat32 newVariable = CFConvertFloat32HostToSwapped(*((float *)_value));
174 [coder encodeBytes:&newVariable length:_size];
175 #else
176 [coder encodeBytes:&_value length:_size];
177 #endif
178 }
179 else if (_type == TCDouble)
180 {
181 #ifdef __LITTLE_ENDIAN__
182 CFSwappedFloat64 newVariable = CFConvertDoubleHostToSwapped(*((double *)_value));
183 [coder encodeBytes:&newVariable length:_size];
184 #else
185 [coder encodeBytes:_value length:_size];
186 #endif
187 }
188
189 [coder encodeValueOfObjCType:@encode(BOOL) at:&_isValueValid];
190 [coder encodeValueOfObjCType:@encode(BOOL) at:&_enabled];
191 [coder encodeValueOfObjCType:@encode(int) at:&_tag];
192 }
193
194
195 // #############################################################################
196 #pragma mark Accessors
197 // #############################################################################
198
199 - (TCVariableType)type
200 {
201 return _type;
202 }
203
204 - (void)_setType:(TCVariableType)type
205 {
206 _type = type;
207 // set the size of the value
208 switch ( _type ) {
209 case TCInt64:
210 case TCDouble: _size = 8;
211 break;
212 case TCInt32:
213 case TCFloat: _size = 4;
214 break;
215 case TCInt16: _size = 2;
216 break;
217 case TCInt8: _size = 1;
218 break;
219 }
220
221 if ( !_value ) {
222 _value = calloc( 1, _size );
223 }
224 }
225
226 - (TCIntegerSign)integerSign
227 {
228 return _integerSign;
229 }
230
231 - (void)_setIntegerSign:(TCIntegerSign)sign
232 {
233 _integerSign = sign;
234 }
235
236
237 - (NSString *)typeString
238 {
239 switch ( _type ) {
240 case TCDouble: return @"Double";
241 case TCFloat: return @"Float";
242 case TCString: return @"ASCII String";
243 }
244 if ( _integerSign == TCUnsigned ) {
245 switch ( _type ) {
246 case TCInt64: return @"64-bit Unsigned Integer";
247 case TCInt32: return @"32-bit Unsigned Integer";
248 case TCInt16: return @"16-bit Unsigned Integer";
249 case TCInt8: return @"08-bit Unsigned Integer";
250 }
251 }
252 else {
253 switch ( _type ) {
254 case TCInt64: return @"64-bit Integer";
255 case TCInt32: return @"32-bit Integer";
256 case TCInt16: return @"16-bit Integer";
257 case TCInt8: return @"08-bit Integer";
258 }
259 }
260 return @"";
261 }
262
263
264 - (TCAddress)address
265 {
266 return _address;
267 }
268
269 - (void)setAddress:(TCAddress)addr
270 {
271 _address = addr;
272 }
273
274
275 - (NSString *)addressString
276 {
277 return [NSString stringWithFormat:@"%0.8X", _address];
278 }
279
280 - (BOOL)setAddressString:(NSString *)string
281 {
282 NSScanner *scanner = [NSScanner scannerWithString:string];
283 TCAddress address;
284
285 if ( [scanner scanHexInt:(unsigned *)(&address)] ) {
286 [self setAddress:address];
287 return YES;
288 }
289 return NO;
290 }
291
292
293 - (void const *)value
294 {
295 return _value;
296 }
297
298 - (void)setValue:(void const *)value
299 {
300 if ( !_value ) {
301 _value = malloc( _size );
302 }
303
304 _isValueValid = YES;
305 memcpy( _value, value, _size );
306 }
307
308 - (void)setValue:(void const *)value size:(unsigned)size
309 {
310 // make sure the size doesn't exceed the maximum
311 size = MIN( size, TC_MAX_VAR_SIZE );
312 // only string variables can have the value size changed
313 if ( (_type == TCString) && (_size != size) && _value ) {
314 void *newValue = realloc( _value, size );
315 if ( newValue ) {
316 _value = newValue;
317 _size = size;
318 }
319 }
320 _size = MIN( _size, size );
321
322 [self setValue:value];
323 }
324
325
326 - (NSString *)stringValue
327 {
328 switch ( _type ) {
329 case TCDouble: return [NSString stringWithFormat:@"%.1lf", *(double *)[self value]];
330 case TCFloat: return [NSString stringWithFormat:@"%.1f", *(float *)[self value]];
331 case TCString: return [NSString stringWithCString:[self value] length:[self valueSize]];
332 }
333 if ( _integerSign == TCUnsigned ) {
334 switch ( _type ) {
335 case TCInt64: return [NSString stringWithFormat:@"%llu", *(UInt64 *)[self value]];
336 case TCInt32: return [NSString stringWithFormat:@"%u", *(UInt32 *)[self value]];
337 case TCInt16: return [NSString stringWithFormat:@"%u", *(UInt16 *)[self value]];
338 case TCInt8: return [NSString stringWithFormat:@"%u", *(UInt8 *)[self value]];
339 }
340 }
341 else {
342 switch ( _type ) {
343 case TCInt64: return [NSString stringWithFormat:@"%lli", *(SInt64 *)[self value]];
344 case TCInt32: return [NSString stringWithFormat:@"%i", *(SInt32 *)[self value]];
345 case TCInt16: return [NSString stringWithFormat:@"%i", *(SInt16 *)[self value]];
346 case TCInt8: return [NSString stringWithFormat:@"%i", *(SInt8 *)[self value]];
347 }
348 }
349 return @"foobar";
350 }
351
352 - (BOOL)setStringValue:(NSString *)string
353 {
354 NSScanner *scanner = [NSScanner scannerWithString:string];
355
356 // invalid until proven valid
357 _isValueValid = NO;
358
359 switch ( _type ) {
360 case TCInt64:
361 {
362 SInt64 value;
363 if ( [scanner scanLongLong:(long long *)(&value)] ) {
364 [self setValue:&value];
365 }
366 break;
367 }
368 case TCInt32:
369 {
370 SInt32 value;
371 if ( [scanner scanInt:(int *)(&value)] ) {
372 [self setValue:&value];
373 }
374 break;
375 }
376 case TCInt16:
377 {
378 int integer;
379 SInt16 value;
380 if ( [scanner scanInt:&integer] ) {
381 value = integer;
382 [self setValue:&value];
383 }
384 break;
385 }
386 case TCInt8:
387 {
388 int integer;
389 SInt8 value;
390 if ( [scanner scanInt:&integer] ) {
391 value = integer;
392 [self setValue:&value];
393 }
394 break;
395 }
396 case TCString:
397 {
398 char *str = (char *)[string lossyCString];
399 unsigned len = strlen( str );
400 [self setValue:str size:len];
401 break;
402 }
403 case TCFloat:
404 {
405 float value;
406 if ( [scanner scanFloat:&value] ) {
407 [self setValue:&value];
408 }
409 break;
410 }
411 case TCDouble:
412 {
413 double value;
414 if ( [scanner scanDouble:&value] ) {
415 [self setValue:&value];
416 }
417 break;
418 }
419 }
420 return [self isValueValid];
421 }
422
423 // this only converts the byte order of the value at buffer if the process is running under rosetta on an intel mac
424 // floats and double's byte ordering should not be changed when searching for values because they may be swapped to '0.0'
425 void bigEndianValue(void *buffer, Variable *variable)
426 {
427 if (variable->_isEmulated)
428 {
429 if (variable->_type == TCInt16)
430 {
431 int16_t newValue = CFSwapInt16HostToBig(*((int16_t *)buffer));
432 memcpy(buffer, &newValue, sizeof(int16_t));
433 }
434 else if (variable->_type == TCInt32)
435 {
436 int32_t newValue = CFSwapInt32HostToBig(*((int32_t *)buffer));
437 memcpy(buffer, &newValue, sizeof(int32_t));
438 }
439 else if (variable->_type == TCInt64)
440 {
441 int64_t newValue = CFSwapInt64HostToBig(*((int64_t *)buffer));
442 memcpy(buffer, &newValue, sizeof(int64_t));
443 }
444 else if (variable->_type == TCFloat)
445 {
446 CFSwappedFloat32 newValue = CFConvertFloat32HostToSwapped(*((float *)buffer));
447 memcpy(buffer, &(newValue.v), sizeof(float));
448 }
449 else if (variable->_type == TCDouble)
450 {
451 CFSwappedFloat64 newValue = CFConvertDoubleHostToSwapped(*((double *)buffer));
452 memcpy(buffer, &(newValue.v), sizeof(double));
453 }
454 }
455 }
456
457 - (unsigned)valueSize
458 {
459 return _size;
460 }
461
462 - (BOOL)isValueValid
463 {
464 return _isValueValid;
465 }
466
467
468 - (BOOL)isEnabled
469 {
470 return _enabled;
471 }
472
473 - (void)setEnabled:(BOOL)enabled
474 {
475 _enabled = enabled;
476 }
477
478
479 - (int)tag
480 {
481 return _tag;
482 }
483
484 - (void)setTag:(int)tag
485 {
486 _tag = tag;
487 }
488
489
490 @end
This page took 0.050502 seconds and 4 git commands to generate.