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.
23 @interface Variable ( PrivateAPI
)
25 - (void)_setType
:(TCVariableType
)type
;
26 - (void)_setIntegerSign
:(TCIntegerSign
)sign
;
31 @implementation Variable
36 return [self initWithType
:TCInt32 integerSign
:TCSigned
];
39 - (id)initWithType
:(TCVariableType
)type
41 return [self initWithType
:type integerSign
:TCSigned
];
44 - (id)initWithType
:(TCVariableType
)type integerSign
:(TCIntegerSign
)sign
// DESIGNATED
46 if ( self = [super init
] ) {
50 [self _setIntegerSign
:sign
];
55 - (void)setProcess
:(Process
*)newProcess
57 if (process
!= newProcess
&& [newProcess pid
] > 0)
59 _isEmulated
= [newProcess isEmulated
];
86 // #############################################################################
88 // #############################################################################
90 - (id)initWithCoder
:(NSCoder
*)coder
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
];
97 void *value
= [coder decodeBytesWithReturnedLength
:&_size
];
99 if (_type
== TCString || _type
== TCInt8
)
101 [self setValue
:value
];
103 else if (_type
== TCInt16
)
105 int16_t newVariable
= CFSwapInt16BigToHost(*((int16_t
*)value
));
106 [self setValue
:&newVariable
];
108 else if (_type
== TCInt32
)
110 int32_t newVariable
= CFSwapInt32BigToHost(*((int32_t
*)value
));
111 [self setValue
:&newVariable
];
113 else if (_type
== TCInt64
)
115 int64_t newVariable
= CFSwapInt64BigToHost(*((int64_t
*)value
));
116 [self setValue
:&newVariable
];
118 else if (_type
== TCFloat
)
120 #ifdef __LITTLE_ENDIAN__
121 CFSwappedFloat32 newVariable
= CFConvertFloat32HostToSwapped(*((float *)value
));
122 [self setValue
:&(newVariable.v
)];
125 [self setValue
:value
];
128 else if (_type
== TCDouble
)
130 #ifdef __LITTLE_ENDIAN__
131 CFSwappedFloat64 newVariable
= CFConvertDoubleHostToSwapped(*((double *)value
));
132 [self setValue
:&(newVariable.v
)];
134 [self setValue
:value
];
138 [coder decodeValueOfObjCType
:@encode(BOOL) at
:&_isValueValid
];
139 [coder decodeValueOfObjCType
:@encode(BOOL) at
:&_enabled
];
140 [coder decodeValueOfObjCType
:@encode(int) at
:&_tag
];
145 - (void)encodeWithCoder
:(NSCoder
*)coder
147 [coder encodeValueOfObjCType
:@encode(TCVariableType
) at
:&_type
];
148 [coder encodeValueOfObjCType
:@encode(TCIntegerSign
) at
:&_integerSign
];
149 [coder encodeValueOfObjCType
:@encode(TCAddress
) at
:&_address
];
151 if (_type
== TCString || _type
== TCInt8
)
153 [coder encodeBytes
:_value length
:_size
];
155 else if (_type
== TCInt16
)
157 int16_t newVariable
= CFSwapInt16HostToBig(*((int16_t
*)_value
));
158 [coder encodeBytes
:&newVariable length
:_size
];
160 else if (_type
== TCInt32
)
162 int32_t newVariable
= CFSwapInt32HostToBig(*((int32_t
*)_value
));
163 [coder encodeBytes
:&newVariable length
:_size
];
165 else if (_type
== TCInt64
)
167 int64_t newVariable
= CFSwapInt64HostToBig(*((int64_t
*)_value
));
168 [coder encodeBytes
:&newVariable length
:_size
];
170 else if (_type
== TCFloat
)
172 #ifdef __LITTLE_ENDIAN__
173 CFSwappedFloat32 newVariable
= CFConvertFloat32HostToSwapped(*((float *)_value
));
174 [coder encodeBytes
:&newVariable length
:_size
];
176 [coder encodeBytes
:&_value length
:_size
];
179 else if (_type
== TCDouble
)
181 #ifdef __LITTLE_ENDIAN__
182 CFSwappedFloat64 newVariable
= CFConvertDoubleHostToSwapped(*((double *)_value
));
183 [coder encodeBytes
:&newVariable length
:_size
];
185 [coder encodeBytes
:_value length
:_size
];
189 [coder encodeValueOfObjCType
:@encode(BOOL) at
:&_isValueValid
];
190 [coder encodeValueOfObjCType
:@encode(BOOL) at
:&_enabled
];
191 [coder encodeValueOfObjCType
:@encode(int) at
:&_tag
];
195 // #############################################################################
196 #pragma mark Accessors
197 // #############################################################################
199 - (TCVariableType
)type
204 - (void)_setType
:(TCVariableType
)type
207 // set the size of the value
210 case TCDouble
: _size
= 8;
213 case TCFloat
: _size
= 4;
215 case TCInt16
: _size
= 2;
217 case TCInt8
: _size
= 1;
222 _value
= calloc( 1, _size
);
226 - (TCIntegerSign
)integerSign
231 - (void)_setIntegerSign
:(TCIntegerSign
)sign
237 - (NSString
*)typeString
240 case TCDouble
: return @
"Double";
241 case TCFloat
: return @
"Float";
242 case TCString
: return @
"ASCII String";
244 if ( _integerSign
== TCUnsigned
) {
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";
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";
269 - (void)setAddress
:(TCAddress
)addr
275 - (NSString
*)addressString
277 return [NSString stringWithFormat
:@
"%0.8X", _address
];
280 - (BOOL)setAddressString
:(NSString
*)string
282 NSScanner
*scanner
= [NSScanner scannerWithString
:string
];
285 if ( [scanner scanHexInt
:(unsigned *)(&address
)] ) {
286 [self setAddress
:address
];
293 - (void const *)value
298 - (void)setValue
:(void const *)value
301 _value
= malloc( _size
);
305 memcpy( _value
, value
, _size
);
308 - (void)setValue
:(void const *)value size
:(unsigned)size
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
);
320 _size
= MIN( _size
, size
);
322 [self setValue
:value
];
326 - (NSString
*)stringValue
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
]];
333 if ( _integerSign
== TCUnsigned
) {
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
]];
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
]];
352 - (BOOL)setStringValue
:(NSString
*)string
354 NSScanner
*scanner
= [NSScanner scannerWithString
:string
];
356 // invalid until proven valid
363 if ( [scanner scanLongLong
:(long long *)(&value
)] ) {
364 [self setValue
:&value
];
371 if ( [scanner scanInt
:(int *)(&value
)] ) {
372 [self setValue
:&value
];
380 if ( [scanner scanInt
:&integer
] ) {
382 [self setValue
:&value
];
390 if ( [scanner scanInt
:&integer
] ) {
392 [self setValue
:&value
];
398 char *str
= (char *)[string lossyCString
];
399 unsigned len
= strlen( str
);
400 [self setValue
:str size
:len
];
406 if ( [scanner scanFloat
:&value
] ) {
407 [self setValue
:&value
];
414 if ( [scanner scanDouble
:&value
] ) {
415 [self setValue
:&value
];
420 return [self isValueValid
];
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
)
427 if (variable
->_isEmulated
)
429 if (variable
->_type
== TCInt16
)
431 int16_t newValue
= CFSwapInt16HostToBig(*((int16_t
*)buffer
));
432 memcpy(buffer
, &newValue
, sizeof(int16_t
));
434 else if (variable
->_type
== TCInt32
)
436 int32_t newValue
= CFSwapInt32HostToBig(*((int32_t
*)buffer
));
437 memcpy(buffer
, &newValue
, sizeof(int32_t
));
439 else if (variable
->_type
== TCInt64
)
441 int64_t newValue
= CFSwapInt64HostToBig(*((int64_t
*)buffer
));
442 memcpy(buffer
, &newValue
, sizeof(int64_t
));
444 else if (variable
->_type
== TCFloat
)
446 CFSwappedFloat32 newValue
= CFConvertFloat32HostToSwapped(*((float *)buffer
));
447 memcpy(buffer
, &(newValue.v
), sizeof(float));
449 else if (variable
->_type
== TCDouble
)
451 CFSwappedFloat64 newValue
= CFConvertDoubleHostToSwapped(*((double *)buffer
));
452 memcpy(buffer
, &(newValue.v
), sizeof(double));
457 - (unsigned)valueSize
464 return _isValueValid
;
473 - (void)setEnabled
:(BOOL)enabled
484 - (void)setTag
:(int)tag