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.
21 #import "RemoteCheater.h"
24 @interface RemoteCheater ( PrivateAPI
)
26 - (void)_handlePacket
;
32 @implementation RemoteCheater
42 - (BOOL)connectToHostWithData
:(NSData
*)data
47 _socket
= [[MySocket alloc
] initWithDelegate
:self];
48 if ( ![_socket connectToAddressWithData
:data
] ) {
52 // start reading from the socket
53 [_socket readDataToLength
:sizeof(TCPacketHeader
) tag
:0];
58 - (NSString
*)hostAddress
60 return [_socket remoteHost
];
64 // #############################################################################
65 #pragma mark Cheater Override
66 // #############################################################################
70 NSData
*params
= [NSArchiver archivedDataWithRootObject
:[NSString stringWithFormat
:@
"%@ %@", ChazAppName(), ChazAppVersion()]];
71 TCPacketHeader header
= { TC_NIFTY
, [params length
], "connect" };
72 [_socket writeBytes
:&header length
:sizeof(header
) tag
:0];
73 [_socket writeData
:params tag
:0];
78 [_socket setDelegate
:nil];
81 //[_delegate cheaterDidDisconnect:self];
84 - (void)authenticateWithPassword
:(NSString
*)password
86 NSData
*params
= [NSArchiver archivedDataWithRootObject
:password
];
87 TCPacketHeader header
= { TC_NIFTY
, [params length
], "authenticate" };
88 [_socket writeBytes
:&header length
:sizeof(header
) tag
:0];
89 [_socket writeData
:params tag
:0];
93 - (void)getProcessList
95 TCPacketHeader header
= { TC_NIFTY
, 0, "getproclist" };
96 ChazLog( @
"SENT getproclist" );
97 [_socket writeBytes
:&header length
:sizeof(header
) tag
:0];
101 - (void)setTarget
:(Process
*)target
103 NSData
*params
= [NSArchiver archivedDataWithRootObject
:target
];
104 TCPacketHeader header
= { TC_NIFTY
, [params length
], "settarget" };
105 [_socket writeBytes
:&header length
:sizeof(header
) tag
:0];
106 [_socket writeData
:params tag
:0];
111 TCPacketHeader header
= { TC_NIFTY
, 0, "pausetarget" };
112 [_socket writeBytes
:&header length
:sizeof(header
) tag
:0];
117 TCPacketHeader header
= { TC_NIFTY
, 0, "resumetarget" };
118 [_socket writeBytes
:&header length
:sizeof(header
) tag
:0];
122 - (void)limitReturnedResults
:(unsigned)limit
124 NSData
*params
= [NSArchiver archivedDataWithRootObject
:[NSNumber numberWithUnsignedInt
:limit
]];
125 TCPacketHeader header
= { TC_NIFTY
, [params length
], "limitresults" };
126 [_socket writeBytes
:&header length
:sizeof(header
) tag
:0];
127 [_socket writeData
:params tag
:0];
130 - (void)searchForVariable
:(Variable
*)data comparison
:(TCSearchOperator
)op
132 NSData
*params
= [NSArchiver archivedDataWithRootObject
:[NSArray arrayWithObjects
:data
, [NSNumber numberWithUnsignedChar
:op
], nil]];
133 TCPacketHeader header
= { TC_NIFTY
, [params length
], "search" };
134 [_socket writeBytes
:&header length
:sizeof(header
) tag
:0];
135 [_socket writeData
:params tag
:0];
138 - (void)searchLastValuesComparison
:(TCSearchOperator
)op
140 NSData
*params
= [NSArchiver archivedDataWithRootObject
:[NSNumber numberWithUnsignedChar
:op
]];
141 TCPacketHeader header
= { TC_NIFTY
, [params length
], "lastsearch" };
142 [_socket writeBytes
:&header length
:sizeof(header
) tag
:0];
143 [_socket writeData
:params tag
:0];
148 TCPacketHeader header
= { TC_NIFTY
, 0, "cancelsearch" };
149 [_socket writeBytes
:&header length
:sizeof(header
) tag
:0];
154 TCPacketHeader header
= { TC_NIFTY
, 0, "clearsearch" };
155 [_socket writeBytes
:&header length
:sizeof(header
) tag
:0];
158 - (void)getMemoryDump
160 TCPacketHeader header
= { TC_NIFTY
, 0, "dump" };
161 [_socket writeBytes
:&header length
:sizeof(header
) tag
:0];
164 - (void)cancelMemoryDump
166 TCPacketHeader header
= { TC_NIFTY
, 0, "canceldump" };
167 [_socket writeBytes
:&header length
:sizeof(header
) tag
:0];
171 - (void)makeVariableChanges
:(NSArray
*)variables repeat
:(BOOL)doRepeat interval
:(NSTimeInterval
)repeatInterval
173 NSData
*params
= [NSArchiver archivedDataWithRootObject
:[NSArray arrayWithObjects
:variables
,
174 [NSNumber numberWithBool
:doRepeat
], [NSNumber numberWithDouble
:repeatInterval
], nil]];
175 TCPacketHeader header
= { TC_NIFTY
, [params length
], "changevars" };
176 [_socket writeBytes
:&header length
:sizeof(header
) tag
:0];
177 [_socket writeData
:params tag
:0];
180 - (void)stopChangingVariables
182 TCPacketHeader header
= { TC_NIFTY
, 0, "stopchange" };
183 [_socket writeBytes
:&header length
:sizeof(header
) tag
:0];
189 TCPacketHeader header
= { TC_NIFTY
, 0, "undo" };
190 [_socket writeBytes
:&header length
:sizeof(header
) tag
:0];
195 TCPacketHeader header
= { TC_NIFTY
, 0, "redo" };
196 [_socket writeBytes
:&header length
:sizeof(header
) tag
:0];
200 - (void)watchVariablesAtIndex
:(unsigned)index count
:(unsigned)count interval
:(NSTimeInterval
)checkInterval
202 NSData
*params
= [NSArchiver archivedDataWithRootObject
:[NSArray arrayWithObjects
:[NSNumber numberWithUnsignedInt
:index
],
203 [NSNumber numberWithUnsignedInt
:count
], [NSNumber numberWithDouble
:checkInterval
], nil]];
204 TCPacketHeader header
= { TC_NIFTY
, [params length
], "watchvars" };
205 [_socket writeBytes
:&header length
:sizeof(header
) tag
:0];
206 [_socket writeData
:params tag
:0];
209 - (void)stopWatchingVariables
211 TCPacketHeader header
= { TC_NIFTY
, 0, "stopwatching" };
212 [_socket writeBytes
:&header length
:sizeof(header
) tag
:0];
216 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
217 #pragma mark MySocketDelegate
218 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
220 - (void)socket
:(MySocket
*)mySocket didReadData
:(NSData
*)theData tag
:(int)tag
222 if ( tag
== 0 && [theData length
] == sizeof(TCPacketHeader
) ) {
223 // got a packet header
224 memcpy( &_header
, [theData bytes
], sizeof(TCPacketHeader
) );
225 if ( _header.size
> 0 ) {
226 // request the rest of the packet
227 [mySocket readDataToLength
:_header.size tag
:1];
230 [self _handlePacket
];
231 // start reading the next packet
232 [mySocket readDataToLength
:sizeof(TCPacketHeader
) tag
:0];
235 else if ( tag
== 1 && [theData length
] == _header.size
) {
236 // got packet parameter data
237 _parameters
= [theData retain
];
238 [self _handlePacket
];
239 // start reading the next packet
240 [mySocket readDataToLength
:sizeof(TCPacketHeader
) tag
:0];
243 ChazLog( @
"RemoteCheater - read expected data, disconnecting..." );
248 - (void)socketDidDisconnect
:(MySocket
*)mySocket
253 [_delegate cheaterDidDisconnect
:self];
257 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
258 #pragma mark PrivateAPI
259 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
261 - (void)_handlePacket
263 if ( strncmp( "connected", _header.name
, sizeof(_header.name
) ) == 0 ) {
264 ChazLog( @
"RemoteCheater - connected" );
265 [_delegate cheaterDidConnect
:self];
267 else if ( strncmp( "requireauth", _header.name
, sizeof(_header.name
) ) == 0 ) {
268 [_delegate cheaterRequiresAuthentication
:self];
270 else if ( strncmp( "rejectedauth", _header.name
, sizeof(_header.name
) ) == 0 ) {
271 [_delegate cheaterRejectedPassword
:self];
273 else if ( strncmp( "authenticated", _header.name
, sizeof(_header.name
) ) == 0 ) {
274 [_delegate cheaterAcceptedPassword
:self];
276 else if ( strncmp( "proclist", _header.name
, sizeof(_header.name
) ) == 0 ) {
277 [_delegate cheater
:self didFindProcesses
:[NSUnarchiver unarchiveObjectWithData
:_parameters
]];
279 else if ( strncmp( "addprocess", _header.name
, sizeof(_header.name
) ) == 0 ) {
280 [_delegate cheater
:self didAddProcess
:[NSUnarchiver unarchiveObjectWithData
:_parameters
]];
282 else if ( strncmp( "removeprocess", _header.name
, sizeof(_header.name
) ) == 0 ) {
283 [_delegate cheater
:self didRemoveProcess
:[NSUnarchiver unarchiveObjectWithData
:_parameters
]];
285 else if ( strncmp( "didsettarget", _header.name
, sizeof(_header.name
) ) == 0 ) {
286 [_delegate cheater
:self didSetTarget
:[NSUnarchiver unarchiveObjectWithData
:_parameters
]];
288 else if ( strncmp( "didpausetarget", _header.name
, sizeof(_header.name
) ) == 0 ) {
289 [_delegate cheaterPausedTarget
:self];
291 else if ( strncmp( "didresumetarget", _header.name
, sizeof(_header.name
) ) == 0 ) {
292 [_delegate cheaterResumedTarget
:self];
294 else if ( strncmp( "vars", _header.name
, sizeof(_header.name
) ) == 0 ) {
302 varInfo
= (struct varInfo
*)[_parameters bytes
];
303 bytes
= (void *)[_parameters bytes
] + sizeof(*varInfo
);
304 variables
= TCMakeArrayWithBytes( varInfo
->varCount
, varInfo
->varSize
, bytes
);
305 [_delegate cheater
:self didFindVariables
:variables actualAmount
:varInfo
->count
];
307 else if ( strncmp( "values", _header.name
, sizeof(_header.name
) ) == 0 ) {
314 varInfo
= (struct varInfo
*)[_parameters bytes
];
315 bytes
= (void *)[_parameters bytes
] + sizeof(*varInfo
);
316 values
= TCMakeArrayWithBytes( varInfo
->varCount
, varInfo
->varSize
, bytes
);
317 [_delegate cheater
:self didFindValues
:values
];
319 else if ( strncmp( "didcancelsearch", _header.name
, sizeof(_header.name
) ) == 0 ) {
320 [_delegate cheaterDidCancelSearch
:self];
322 else if ( strncmp( "didclearsearch", _header.name
, sizeof(_header.name
) ) == 0 ) {
323 [_delegate cheaterDidClearSearch
:self];
325 else if ( strncmp( "memdump", _header.name
, sizeof(_header.name
) ) == 0 ) {
326 [_delegate cheater
:self didDumpMemory
:_parameters
];
328 else if ( strncmp( "didcanceldump", _header.name
, sizeof(_header.name
) ) == 0 ) {
329 [_delegate cheaterDidCancelMemoryDump
:self];
331 else if ( strncmp( "changedvars", _header.name
, sizeof(_header.name
) ) == 0 ) {
332 [_delegate cheater
:self didChangeVariables
:[[NSUnarchiver unarchiveObjectWithData
:_parameters
] unsignedIntValue
]];
334 else if ( strncmp( "didstopchanging", _header.name
, sizeof(_header.name
) ) == 0 ) {
335 [_delegate cheaterDidStopChangingVariables
:self];
337 else if ( strncmp( "progress", _header.name
, sizeof(_header.name
) ) == 0 ) {
338 [_delegate cheater
:self didReportProgress
:[[NSUnarchiver unarchiveObjectWithData
:_parameters
] intValue
]];
340 else if ( strncmp( "revertedto", _header.name
, sizeof(_header.name
) ) == 0 ) {
348 varInfo
= (struct varInfo
*)[_parameters bytes
];
349 bytes
= (void *)[_parameters bytes
] + sizeof(*varInfo
);
350 variables
= TCMakeArrayWithBytes( varInfo
->varCount
, varInfo
->varSize
, bytes
);
351 [_delegate cheater
:self didRevertToVariables
:variables actualAmount
:varInfo
->count
];
353 else if ( strncmp( "didundo", _header.name
, sizeof(_header.name
) ) == 0 ) {
354 [_delegate cheaterDidUndo
:self];
356 else if ( strncmp( "didredo", _header.name
, sizeof(_header.name
) ) == 0 ) {
357 [_delegate cheaterDidRedo
:self];
359 else if ( strncmp( "varchanged", _header.name
, sizeof(_header.name
) ) == 0 ) {
360 NSArray
*params
= [NSUnarchiver unarchiveObjectWithData
:_parameters
];
361 [_delegate cheater
:self variableAtIndex
:[[params objectAtIndex
:0] unsignedIntValue
] didChangeTo
:[params objectAtIndex
:1]];
363 else if ( strncmp( "failed", _header.name
, sizeof(_header.name
) ) == 0 ) {
364 [_delegate cheater
:self didFailLastRequest
:[NSUnarchiver unarchiveObjectWithData
:_parameters
]];
366 else if ( strncmp( "echo", _header.name
, sizeof(_header.name
) ) == 0 ) {
367 [_delegate cheater
:self echo
:[NSUnarchiver unarchiveObjectWithData
:_parameters
]];
370 [_parameters release
];