Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: master
Fetching contributors…

Cannot retrieve contributors at this time

312 lines (274 sloc) 8.567 kb
/*
* The Cheat - The legendary universal game trainer for Mac OS X.
* http://www.brokenzipper.com/trac/wiki/TheCheat
*
* Copyright (c) 2003-2011, Charles McGarvey et al.
*
* Distributable under the terms and conditions of the 2-clause BSD
* license; see the file COPYING for the legal text of the license.
*/
#import "SearchContext.h"
@implementation SearchContext
#pragma mark Initialization
/*
* There isn't really a designated initializer because the initialization of the types
* of searches vary way too much.
*/
- (id)initWithPID:(pid_t)pid searchOperator:(TCSearchOperator)op value:(Variable *)val
{
unsigned valueSize;
if ( [super init] ) {
value = [val retain];
if ( !value ) {
[self release];
return nil;
}
valueSize = [value valueSize];
process = pid;
_variableType = [value type];
_integerSign = [value integerSign];
_operator = op;
_searchType = TCGivenValue;
compareFunc = [self compareFunction];
// allocate the memory objects which will be used during the search
regionCount = VMCountRegionsWithAttributes( process, VMREGION_READABLE | VMREGION_WRITABLE );
addresses = TCMakeArray( TC_BUFFER_SIZE / sizeof(TCAddress), sizeof(TCAddress) );
values = TCMakeArray( TC_BUFFER_SIZE / valueSize, valueSize );
regions = TCMakeArray( 0, sizeof(TCAddress) );
perRegion = TCMakeArray( 0, sizeof(unsigned) );
addressPtr = TCArrayBytes( addresses );
valuePtr = TCArrayBytes( values );
ChazLog( @"SearchContext: varType=%i, intSign=%i, op=%i, value=%@", _variableType, _integerSign, _operator, [value stringValue] );
}
return self;
}
- (id)initWithLastContext:(SearchContext *)context searchOperator:(TCSearchOperator)op
{
unsigned valueSize;
if ( [super init] ) {
if ( !context ) {
[self release];
return nil;
}
valueSize = TCArrayElementSize(context->values);
process = context->process;
_variableType = [context variableType];
_integerSign = [context integerSign];
_operator = op;
_searchType = TCLastValue;
compareFunc = [self compareFunction];
regionCount = TCArrayElementCount( context->regions );
addresses = TCMakeArray( TC_BUFFER_SIZE / sizeof(TCAddress), sizeof(TCAddress) );
values = TCMakeArray( TC_BUFFER_SIZE / valueSize, valueSize );
regions = TCMakeArray( 0, sizeof(TCAddress) );
perRegion = TCMakeArray( 0, sizeof(unsigned) );
lastAddresses = context->addresses;
lastValues = context->values;
lastRegions = context->regions;
lastPerRegion = context->perRegion;
addressPtr = TCArrayBytes( addresses );
valuePtr = TCArrayBytes( values );
lastAddressPtr = TCArrayBytes( lastAddresses );
lastValuePtr = TCArrayBytes( lastValues );
lastRegionPtr = TCArrayBytes( lastRegions );
lastPerRegionPtr = TCArrayBytes( lastPerRegion );
ChazLog( @"SearchContext: varType=%i, intSign=%i, op=%i", _variableType, _integerSign, _operator );
}
return self;
}
- (id)initWithLastContext:(SearchContext *)context searchOperator:(TCSearchOperator)op value:(Variable *)val
{
unsigned valueSize;
if ( [super init] ) {
if ( !context || !val || ([val type] != [context variableType]) // and search values can't be bigger than the last time.
|| (([context variableType] == TCString) && ([val valueSize] > TCArrayElementSize(context->values))) ) {
[self release];
return nil;
}
value = [val retain];
valueSize = [value valueSize];
process = context->process;
_variableType = [context variableType];
_integerSign = [context integerSign];
_operator = op;
_searchType = TCGivenValue;
compareFunc = [self compareFunction];
regionCount = TCArrayElementCount( context->regions );
addresses = TCMakeArray( TC_BUFFER_SIZE / sizeof(TCAddress), sizeof(TCAddress) );
values = TCMakeArray( TC_BUFFER_SIZE / valueSize, valueSize );
regions = TCMakeArray( 0, sizeof(TCAddress) );
perRegion = TCMakeArray( 0, sizeof(unsigned) );
lastAddresses = context->addresses;
lastValues = context->values;
lastRegions = context->regions;
lastPerRegion = context->perRegion;
addressPtr = TCArrayBytes( addresses );
valuePtr = TCArrayBytes( values );
lastAddressPtr = TCArrayBytes( lastAddresses );
lastValuePtr = TCArrayBytes( lastValues );
lastRegionPtr = TCArrayBytes( lastRegions );
lastPerRegionPtr = TCArrayBytes( lastPerRegion );
ChazLog( @"SearchContext: varType=%i, intSign=%i, op=%i, value=%@", _variableType, _integerSign, _operator, [value stringValue] );
}
return self;
}
- (void)dealloc
{
ChazLog( @"SearchContext %p dealloc", self );
TCReleaseArray( addresses );
TCReleaseArray( values );
TCReleaseArray( regions );
TCReleaseArray( perRegion );
if ( buffer ) {
free( buffer );
}
[value release];
[super dealloc];
}
#pragma mark Accessors
- (TCVariableType)variableType
{
return _variableType;
}
- (TCIntegerSign)integerSign
{
return _integerSign;
}
- (TCSearchOperator)searchOperator
{
return _operator;
}
- (BOOL (*)(void const *, void const *))compareFunction
{
// here begins a very pretty collection of switch and if statements. enjoy!
switch ( _operator ) {
case TCEqual:
switch ( _variableType ) {
case TCFloat: return EqualFloat;
case TCDouble: return EqualDouble;
}
if ( _integerSign == TCSigned ) {
switch ( _variableType ) {
case TCInt64: return EqualInt64;
case TCInt32: return EqualInt32;
case TCInt16: return EqualInt16;
case TCInt8: return EqualInt8;
case TCCiv5Int: return EqualCiv5;
}
}
else {
switch ( _variableType ) {
case TCInt64: return EqualUInt64;
case TCInt32: return EqualUInt32;
case TCInt16: return EqualUInt16;
case TCInt8: return EqualUInt8;
case TCCiv5Int: return EqualCiv5;
}
}
break;
case TCNotEqual:
switch ( _variableType ) {
case TCFloat: return NotEqualFloat;
case TCDouble: return NotEqualDouble;
}
if ( _integerSign == TCSigned ) {
switch ( _variableType ) {
case TCInt64: return NotEqualInt64;
case TCInt32: return NotEqualInt32;
case TCInt16: return NotEqualInt16;
case TCInt8: return NotEqualInt8;
case TCCiv5Int: return NotEqualCiv5;
}
}
else {
switch ( _variableType ) {
case TCInt64: return NotEqualUInt64;
case TCInt32: return NotEqualUInt32;
case TCInt16: return NotEqualUInt16;
case TCInt8: return NotEqualUInt8;
case TCCiv5Int: return NotEqualCiv5;
}
}
break;
case TCLessThan:
switch ( _variableType ) {
case TCFloat: return LessThanFloat;
case TCDouble: return LessThanDouble;
}
if ( _integerSign == TCSigned ) {
switch ( _variableType ) {
case TCInt64: return LessThanInt64;
case TCInt32: return LessThanInt32;
case TCInt16: return LessThanInt16;
case TCInt8: return LessThanInt8;
case TCCiv5Int: return LessThanCiv5;
}
}
else {
switch ( _variableType ) {
case TCInt64: return LessThanUInt64;
case TCInt32: return LessThanUInt32;
case TCInt16: return LessThanUInt16;
case TCInt8: return LessThanUInt8;
case TCCiv5Int: return LessThanCiv5;
}
}
break;
case TCGreaterThan:
switch ( _variableType ) {
case TCFloat: return GreaterThanFloat;
case TCDouble: return GreaterThanDouble;
}
if ( _integerSign == TCSigned ) {
switch ( _variableType ) {
case TCInt64: return GreaterThanInt64;
case TCInt32: return GreaterThanInt32;
case TCInt16: return GreaterThanInt16;
case TCInt8: return GreaterThanInt8;
case TCCiv5Int: return GreaterThanCiv5;
}
}
else {
switch ( _variableType ) {
case TCInt64: return GreaterThanUInt64;
case TCInt32: return GreaterThanUInt32;
case TCInt16: return GreaterThanUInt16;
case TCInt8: return GreaterThanUInt8;
case TCCiv5Int: return GreaterThanCiv5;
}
}
break;
}
return NULL;
}
- (int (*)(id, unsigned))iterationFunction
{
if ( _searchType == TCGivenValue ) {
if ( !lastAddresses ) {
if ( _variableType == TCString ) {
return SearchStringIteration;
}
else {
return SearchIteration;
}
}
else {
if ( _variableType == TCString ) {
return SearchStringIterationAgain;
}
else {
return SearchIterationAgain;
}
}
}
else if ( _searchType == TCLastValue ) {
if ( _variableType == TCString ) {
return SearchStringIterationLastValue;
}
else {
return SearchIterationLastValue;
}
}
return NULL;
}
@end
Jump to Line
Something went wrong with that request. Please try again.