]> Dogcows Code - chaz/thecheat/blobdiff - CheatServer.m
The Cheat 1.0b3
[chaz/thecheat] / CheatServer.m
diff --git a/CheatServer.m b/CheatServer.m
new file mode 100644 (file)
index 0000000..2a8ed8c
--- /dev/null
@@ -0,0 +1,2035 @@
+
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Project:   The Cheat
+//
+// File:      CheatServer.m
+// Created:   Sun Sep 07 2003
+//
+// Copyright: 2003 Chaz McGarvey.  All rights reserved.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+#import "CheatServer.h"
+
+#import "SearchResults.h"
+
+#include <string.h>
+#include <math.h>
+
+
+// Internal Functions
+BOOL inline compare_float( float a, float b );
+BOOL inline compare_double( double a, double b );
+
+
+@implementation CheatServer
+
+
++ (NSConnection *)serverWithDelegate:(id)delegate socket:(int)sock
+{
+       NSPort                          *rPort = [NSPort port], *sPort = [NSPort port];
+       NSConnection            *connection;
+       NSArray                         *array;
+
+       connection = [[NSConnection alloc] initWithReceivePort:rPort sendPort:sPort];
+       [connection setRootObject:delegate];
+
+       array = [NSArray arrayWithObjects:sPort, rPort, [NSNumber numberWithInt:sock], nil];
+       [NSThread detachNewThreadSelector:@selector(serverThread:) toTarget:self withObject:array];
+
+       return [connection autorelease];
+}
+
++ (void)serverThread:(NSArray *)array
+{
+       NSAutoreleasePool       *pool = [[NSAutoreleasePool alloc] init];
+    NSConnection               *connection = [NSConnection connectionWithReceivePort:[array objectAtIndex:0] sendPort:[array objectAtIndex:1]];
+    CheatServer                        *object = [[self alloc] initWithRootProxy:[connection rootProxy]];
+
+       [object handleSocket:[[array objectAtIndex:2] intValue]];
+       [object run];
+
+    [object release];
+    [pool release];
+}
+
+
+- (id)initWithRootProxy:(id)proxy
+{
+       if ( self = [super init] )
+       {
+               NSNotificationCenter    *nc = [[NSWorkspace sharedWorkspace] notificationCenter];
+
+               rootProxy = proxy;
+
+               [nc addObserver:self selector:@selector(processListChanged:) name:@"NSWorkspaceDidLaunchApplicationNotification" object:nil];
+               [nc addObserver:self selector:@selector(processListChanged:) name:@"NSWorkspaceDidTerminateApplicationNotification" object:nil];
+
+               [self setPID:[rootProxy serverFirstProcess]];
+
+               processPaused = NO;
+
+               searchResults = [[NSMutableArray alloc] init];
+               searchResultsUndone = [[NSMutableArray alloc] init];
+       }
+
+       return self;
+}
+
+
+- (void)handleSocket:(int)sock
+{
+       struct sockaddr                 identifier;
+       int                                             addrLen = sizeof(identifier);
+
+       NSString                                *address;
+       char                                    *addressCString;
+
+       sockfd = sock;
+
+       if ( getpeername( sockfd, &identifier, &addrLen ) == -1 )
+       {
+               NSLog( @"ERROR: getpeername() failed" );
+       }
+
+       if ( identifier.sa_family == AF_INET )
+       {
+               struct sockaddr_in              addr;
+
+               addrLen = sizeof(addr);
+
+               if ( getpeername( sockfd, (struct sockaddr *)(&addr), &addrLen ) == -1 )
+               {
+                       NSLog( @"ERROR: getpeername() failed" );
+               }
+
+               if ( (addressCString = inet_ntoa( addr.sin_addr )) == NULL )
+               {
+                       NSLog( @"ERROR: inet_ntoa() failed" );
+               }
+
+               address = [NSString stringWithCString:addressCString];
+       }
+       else
+       {
+               struct sockaddr_un              addr;
+
+               addrLen = sizeof(addr);
+
+               if ( getpeername( sockfd, (struct sockaddr *)(&addr), &addrLen ) == -1 )
+               {
+                       NSLog( @"ERROR: getpeername() failed" );
+               }
+
+               NSLog( @"client connection: %s", addr.sun_path );
+               
+               address = [NSString stringWithString:@"127.0.0.1"];
+       }
+
+       [rootProxy server:self connectedWithSocket:sockfd];
+
+       [self setAddress:address];
+       [self setAction:nil];
+}
+
+- (void)run
+{
+       struct timeval          tv;
+       fd_set                          fdset, master;
+       int                                     numfds;
+
+       int                                     result;
+
+       PacketHeader            header;
+       char                            *data = NULL;
+
+       tv.tv_sec = 2;
+       tv.tv_usec = 0;
+
+       FD_ZERO( &fdset );
+       FD_ZERO( &master );
+       FD_SET( sockfd, &master );
+
+       numfds = sockfd + 1;
+
+       NSLog( @"SERVER start" );
+
+       for (;;)
+       {
+               fdset = master;
+
+               select( numfds, &fdset, NULL, NULL, &tv );
+
+               if ( FD_ISSET( sockfd, &fdset ) )
+               {
+                       if ( (result = ReadBuffer( sockfd, (char *)(&header), sizeof(header) )) != sizeof(header) )
+                       {
+                               break;
+                       }
+
+                       if ( !VerifyChecksum( header.checksum ) )
+                       {
+                               NSLog( @"checksum failed" );
+                       }
+
+                       if ( header.size != 0 )
+                       {
+                               if ( (data = (char *)malloc( header.size )) == NULL )
+                               {
+                                       NSLog( @"failed to allocate buffer for reading a network packet" );
+                                       break;
+                               }
+
+                               if ( (result = ReadBuffer( sockfd, data, header.size )) != header.size )
+                               {
+                                       NSLog( @"failed to read the data of a network packet" );
+                                       free( data );
+                                       break;
+                               }
+                       }
+
+                       NSLog( @"SERVER message %i/%i/%i", header.checksum, header.function, header.size );
+
+                       switch ( header.function )
+                       {
+                               case 1:
+                                       [self sendProcessList];
+                                       break;
+                                       
+                               case 3:
+                                       [self handleClearSearch];
+                                       break;
+
+                               case 5:
+                                       [self handleSearch:data size:header.size];
+                                       break;
+
+                               case 8:
+                                       [self handleChange:data size:header.size];
+                                       break;
+
+                               case 10:
+                                       [self handlePauseTarget];
+                                       break;
+
+                               case 14:
+                                       [self handleUndo];
+                                       break;
+
+                               case 16:
+                                       [self handleRedo];
+                                       break;
+
+                               case 18:
+                                       [self handleSetTargetPID:data size:header.size];
+                                       break;
+
+                       }
+
+                       if ( header.size != 0 )
+                       {
+                               free( data );
+                       }
+               }
+       }
+
+       close( sockfd );
+
+       NSLog( @"SERVER close" );
+
+       [rootProxy serverDisconnected:self];
+}
+
+
+- (void)setAddress:(NSString *)address
+{
+       [rootProxy server:self changedAddress:address];
+}
+
+- (void)setAction:(NSString *)action
+{
+       if ( action == nil )
+       {
+               [rootProxy server:self changedAction:@"Idle"];
+       }
+       else
+       {
+               [rootProxy server:self changedAction:action];
+       }
+}
+
+- (void)firstSearchString8bit:(char const *)value size:(int)vsize
+{
+       kern_return_t                           result;
+       
+       vm_address_t                            address = 0x0;
+       vm_size_t                                       size = 0;
+       vm_region_basic_info_data_t     info;
+       mach_msg_type_number_t          infoCnt = 8;
+       mach_port_t                                     object_name = 0;
+       
+       char                                            *data;
+       vm_size_t                                       dataLength;
+       
+       TCaddress                                       *results = NULL;
+       int                                                     resultsAmount = 0;
+       
+       NSLog( @"string search: %s", value );
+       
+       for (;;)
+       {
+               if ( (result = vm_region( processTask, &address, &size, VM_REGION_BASIC_INFO, (vm_region_info_t)(&info), &infoCnt, &object_name )) != KERN_SUCCESS )
+               {
+                       if ( result != KERN_INVALID_ADDRESS )
+                       {
+                               NSLog( @"vm_region returned error: %i", result );
+                       }
+                       break;
+               }
+               
+               if ( (info.protection & VM_PROT_READ) && (info.protection & VM_PROT_WRITE))
+               {
+                       data = (char *)malloc( size );
+                       dataLength = size;
+                       
+                       if ( (result = vm_read_overwrite( processTask, address, size, (vm_address_t)data, &dataLength )) != KERN_SUCCESS && result != KERN_PROTECTION_FAILURE )
+                       {
+                               NSLog( @"vm_read_overwrite returned error: %i", result );
+                               free( data );
+                               break;
+                       }
+                       
+                       if ( result == KERN_SUCCESS )
+                       {
+                               int                             i, top = dataLength - vsize;
+                               
+                               if ( (results = realloc( results, TCAddressSize*resultsAmount + dataLength )) == NULL )
+                               {
+                                       NSLog( @"ERROR: could not expand buffer" );
+                                       exit(0);
+                               }
+                               
+                               for ( i = 0; i < top; i++ )
+                               {
+                                       if ( strncmp( value, data+i, vsize ) == 0 )
+                                       {
+                                               results[resultsAmount++] = (TCaddress)address + i;
+                                       }
+                               }
+                       }
+                       
+                       free( data );
+               }
+               
+               address += size;
+       }
+       
+       realloc( results, TCAddressSize*resultsAmount );
+       [searchResults addObject:[SearchResults resultsWithType:TYPE_INTEGER size:SIZE_8_BIT data:results amount:resultsAmount]];
+       
+       NSLog( @"found %i of %i", resultsAmount, value );
+}
+
+- (void)firstSearchIntegerChar:(int8_t)value
+{
+       kern_return_t                           result;
+       
+       vm_address_t                            address = 0x0;
+       vm_size_t                                       size = 0;
+       vm_region_basic_info_data_t     info;
+       mach_msg_type_number_t          infoCnt = 8;
+       mach_port_t                                     object_name = 0;
+       
+       int8_t                                          *data;
+       vm_size_t                                       dataLength;
+       
+       TCaddress                                       *results = NULL;
+       int                                                     resultsAmount = 0;
+       
+       for (;;)
+       {
+               if ( (result = vm_region( processTask, &address, &size, VM_REGION_BASIC_INFO, (vm_region_info_t)(&info), &infoCnt, &object_name )) != KERN_SUCCESS )
+               {
+                       if ( result != KERN_INVALID_ADDRESS )
+                       {
+                               NSLog( @"vm_region returned error: %i", result );
+                       }
+                       break;
+               }
+               
+               if ( (info.protection & VM_PROT_READ) && (info.protection & VM_PROT_WRITE))
+               {
+                       data = (int8_t *)malloc( size );
+                       dataLength = size;
+                       
+                       if ( (result = vm_read_overwrite( processTask, address, size, (vm_address_t)data, &dataLength )) != KERN_SUCCESS && result != KERN_PROTECTION_FAILURE )
+                       {
+                               NSLog( @"vm_read_overwrite returned error: %i", result );
+                               free( data );
+                               break;
+                       }
+                       
+                       if ( result == KERN_SUCCESS )
+                       {
+                               int                             i;
+                               
+                               if ( (results = (TCaddress *)realloc( results, TCAddressSize*resultsAmount + TCAddressSize*dataLength )) == NULL )
+                               {
+                                       NSLog( @"ERROR: could not expand buffer" );
+                                       exit(0);
+                               }
+                               
+                               for ( i = 0; i < dataLength; i++ )
+                               {
+                                       if ( *(data+i) == value )
+                                       {
+                                               results[resultsAmount++] = (TCaddress)address + i;
+                                       }
+                               }
+                       }
+                       
+                       free( data );
+               }
+               
+               address += size;
+       }
+       
+       realloc( results, TCAddressSize*resultsAmount );
+       [searchResults addObject:[SearchResults resultsWithType:TYPE_INTEGER size:SIZE_8_BIT data:results amount:resultsAmount]];
+       
+       NSLog( @"found %i of %i", resultsAmount, value );
+}
+
+- (void)firstSearchIntegerShort:(int16_t)value
+{
+       kern_return_t                           result;
+       
+       vm_address_t                            address = 0x0;
+       vm_size_t                                       size = 0;
+       vm_region_basic_info_data_t     info;
+       mach_msg_type_number_t          infoCnt = 8;
+       mach_port_t                                     object_name = 0;
+       
+       int16_t                                         *data;
+       vm_size_t                                       dataLength;
+       
+       TCaddress                                       *results = NULL;
+       int                                                     resultsAmount = 0;
+       
+       for (;;)
+       {
+               if ( (result = vm_region( processTask, &address, &size, VM_REGION_BASIC_INFO, (vm_region_info_t)(&info), &infoCnt, &object_name )) != KERN_SUCCESS )
+               {
+                       if ( result != KERN_INVALID_ADDRESS )
+                       {
+                               NSLog( @"vm_region returned error: %i", result );
+                       }
+                       break;
+               }
+               
+               if ( (info.protection & VM_PROT_READ) && (info.protection & VM_PROT_WRITE))
+               {
+                       data = (int16_t *)malloc( size );
+                       dataLength = size;
+                       
+                       if ( (result = vm_read_overwrite( processTask, address, size, (vm_address_t)data, &dataLength )) != KERN_SUCCESS && result != KERN_PROTECTION_FAILURE )
+                       {
+                               NSLog( @"vm_read_overwrite returned error: %i", result );
+                               free( data );
+                               break;
+                       }
+                       
+                       if ( result == KERN_SUCCESS )
+                       {
+                               int                             i, top = dataLength / sizeof(value);
+                               
+                               if ( (results = (TCaddress *)realloc( results, TCAddressSize*resultsAmount + 2*dataLength )) == NULL )
+                               {
+                                       NSLog( @"ERROR: could not expand buffer" );
+                                       exit(0);
+                               }
+                               
+                               for ( i = 0; i < top; i++ )
+                               {
+                                       if ( *(data+i) == value )
+                                       {
+                                               results[resultsAmount++] = (TCaddress)address + i * sizeof(value);
+                                       }
+                               }
+                       }
+                       
+                       free( data );
+               }
+               
+               address += size;
+       }
+       
+       realloc( results, TCAddressSize*resultsAmount );
+       [searchResults addObject:[SearchResults resultsWithType:TYPE_INTEGER size:SIZE_16_BIT data:results amount:resultsAmount]];
+       
+       NSLog( @"found %i of %i", resultsAmount, value );
+}
+
+- (void)firstSearchIntegerLong:(int32_t)value
+{
+       kern_return_t                           result;
+       
+       vm_address_t                            address = 0x0;
+       vm_size_t                                       size = 0;
+       vm_region_basic_info_data_t     info;
+       mach_msg_type_number_t          infoCnt = 8;
+       mach_port_t                                     object_name = 0;
+       
+       int32_t                                         *data;
+       vm_size_t                                       dataLength;
+       
+       TCaddress                                       *results = NULL;
+       int                                                     resultsAmount = 0;
+       
+       unsigned                                        zone_count = 10;
+       vm_address_t                            *zones = (vm_address_t *)malloc( zone_count * sizeof(vm_address_t) );
+       //memory_reader_t                               reader;
+       
+       if ( (result = malloc_get_all_zones( processTask, NULL, &zones, &zone_count )) != KERN_SUCCESS )
+       {
+               NSLog( @"malloc_get_all_zones error: %i", result );
+       }
+       else
+       {
+               //address = zones[0];
+               
+               /*int                   i;
+               
+               for ( i = 0; i < 10; i++ )
+               {
+                       NSLog( @"malloc_get_all_zones[%i] = %X", i, (vm_address_t)zones[i] );
+               }*/
+       }
+       
+       for (;;)
+       {
+               if ( (result = vm_region( processTask, &address, &size, VM_REGION_BASIC_INFO, (vm_region_info_t)(&info), &infoCnt, &object_name )) != KERN_SUCCESS )
+               {
+                       if ( result != KERN_INVALID_ADDRESS )
+                       {
+                               NSLog( @"vm_region returned error: %i", result );
+                       }
+                       break;
+               }
+               
+               if ( (info.protection & VM_PROT_READ) && (info.protection & VM_PROT_WRITE) )
+               {
+                       data = (int32_t *)malloc( size );
+                       dataLength = size;
+                       
+                       NSLog( @"address: %.8X size: %i", address, size );
+                       
+                       if ( (result = vm_read_overwrite( processTask, address, size, (vm_address_t)data, &dataLength )) != KERN_SUCCESS && result != KERN_PROTECTION_FAILURE )
+                       {
+                               NSLog( @"vm_read_overwrite returned error: %i", result );
+                               free( data );
+                               break;
+                       }
+                       
+                       if ( result == KERN_SUCCESS )
+                       {
+                               int                             i, top = dataLength / sizeof(value);
+                               
+                               if ( (results = (TCaddress *)realloc( results, TCAddressSize*resultsAmount + dataLength )) == NULL )
+                               {
+                                       NSLog( @"ERROR: could not expand buffer" );
+                                       exit(0);
+                               }
+                               
+                               for ( i = 0; i < top; i++ )
+                               {
+                                       if ( *(data+i) == value )
+                                       {
+                                               results[resultsAmount++] = (TCaddress)address + i * sizeof(value);
+                                       }
+                               }
+                       }
+                       
+                       free( data );
+               }
+               
+               address += size;
+       }
+       
+       realloc( results, TCAddressSize*resultsAmount );
+       [searchResults addObject:[SearchResults resultsWithType:TYPE_INTEGER size:SIZE_32_BIT data:results amount:resultsAmount]];
+       
+       NSLog( @"found %i of %i", resultsAmount, value );
+}
+
+
+- (void)firstSearchDecimalFloat:(float)value
+{
+       kern_return_t                           result;
+       
+       vm_address_t                            address = 0x0;
+       vm_size_t                                       size = 0;
+       vm_region_basic_info_data_t     info;
+       mach_msg_type_number_t          infoCnt = 8;
+       mach_port_t                                     object_name = 0;
+       
+       float                                           *data;
+       vm_size_t                                       dataLength;
+       
+       TCaddress                                       *results = NULL;
+       int                                                     resultsAmount = 0;
+       
+       for (;;)
+       {
+               if ( (result = vm_region( processTask, &address, &size, VM_REGION_BASIC_INFO, (vm_region_info_t)(&info), &infoCnt, &object_name )) != KERN_SUCCESS )
+               {
+                       if ( result != KERN_INVALID_ADDRESS )
+                       {
+                               NSLog( @"vm_region returned error: %i", result );
+                       }
+                       break;
+               }
+               
+               if ( (info.protection & VM_PROT_READ) && (info.protection & VM_PROT_WRITE))
+               {
+                       data = (float *)malloc( size );
+                       dataLength = size;
+                       
+                       if ( (result = vm_read_overwrite( processTask, address, size, (vm_address_t)data, &dataLength )) != KERN_SUCCESS && result != KERN_PROTECTION_FAILURE )
+                       {
+                               NSLog( @"vm_read_overwrite returned error: %i", result );
+                               free( data );
+                               break;
+                       }
+                       
+                       if ( result == KERN_SUCCESS )
+                       {
+                               int                             i, top = dataLength / sizeof(value);
+                               
+                               if ( (results = realloc( results, TCAddressSize*resultsAmount + dataLength )) == NULL )
+                               {
+                                       NSLog( @"ERROR: could not expand buffer" );
+                                       exit(0);
+                               }
+                               
+                               for ( i = 0; i < top; i++ )
+                               {
+                                       if ( compare_float( *(data+i), value ) )
+                                       {
+                                               results[resultsAmount++] = (TCaddress)address + i * sizeof(value);
+                                       }
+                               }
+                       }
+                       
+                       free( data );
+               }
+               
+               address += size;
+       }
+       
+       realloc( results, TCAddressSize*resultsAmount );
+       [searchResults addObject:[SearchResults resultsWithType:TYPE_DECIMAL size:SIZE_32_BIT data:results amount:resultsAmount]];
+       
+       NSLog( @"found %i of %i", resultsAmount, value );
+}
+
+- (void)firstSearchDecimalDouble:(double)value
+{
+       kern_return_t                           result;
+       
+       vm_address_t                            address = 0x0;
+       vm_size_t                                       size = 0;
+       vm_region_basic_info_data_t     info;
+       mach_msg_type_number_t          infoCnt = 8;
+       mach_port_t                                     object_name = 0;
+       
+       double                                          *data;
+       vm_size_t                                       dataLength;
+       
+       TCaddress                                       *results = NULL;
+       int                                                     resultsAmount = 0;
+       
+       NSLog( @"float search" );
+       
+       for (;;)
+       {
+               if ( (result = vm_region( processTask, &address, &size, VM_REGION_BASIC_INFO, (vm_region_info_t)(&info), &infoCnt, &object_name )) != KERN_SUCCESS )
+               {
+                       if ( result != KERN_INVALID_ADDRESS )
+                       {
+                               NSLog( @"vm_region returned error: %i", result );
+                       }
+                       break;
+               }
+               
+               if ( (info.protection & VM_PROT_READ) && (info.protection & VM_PROT_WRITE))
+               {
+                       data = (double *)malloc( size );
+                       dataLength = size;
+                       
+                       if ( (result = vm_read_overwrite( processTask, address, size, (vm_address_t)data, &dataLength )) != KERN_SUCCESS && result != KERN_PROTECTION_FAILURE )
+                       {
+                               NSLog( @"vm_read_overwrite returned error: %i", result );
+                               free( data );
+                               break;
+                       }
+                       
+                       if ( result == KERN_SUCCESS )
+                       {
+                               int                             i, top = dataLength / sizeof(value);
+                               
+                               if ( (results = realloc( results, TCAddressSize*resultsAmount + dataLength )) == NULL )
+                               {
+                                       NSLog( @"ERROR: could not expand buffer" );
+                                       exit(0);
+                               }
+                               
+                               for ( i = 0; i < top; i++ )
+                               {
+                                       if ( compare_double( *(data+i), value ) )
+                                       {
+                                               results[resultsAmount++] = (TCaddress)address + i * sizeof(value);
+                                       }
+                               }
+                       }
+                       
+                       free( data );
+               }
+               
+               address += size;
+       }
+       
+       realloc( results, TCAddressSize*resultsAmount );
+       [searchResults addObject:[SearchResults resultsWithType:TYPE_DECIMAL size:SIZE_64_BIT data:results amount:resultsAmount]];
+       
+       NSLog( @"found %i of %i", resultsAmount, value );
+}
+
+
+- (void)searchString8bit:(char const *)value size:(int)vsize
+{
+       kern_return_t                           result;
+       
+       int8_t                                          data;
+       vm_size_t                                       dataLength;
+       
+       TCaddress                                       *results;
+       int                                                     resultsAmount = 0;
+       
+       SearchResults                           *lastResults = [searchResults lastObject];
+       TCaddress                                       *lastResultsData = [lastResults data];
+       int                                                     i, lastResultsAmount = [lastResults amount];
+       
+       if ( [lastResults type] != TYPE_INTEGER || [lastResults size] != SIZE_8_BIT )
+       {
+               [self sendError:@"This search is incompatible with the previous search." fatal:NO];
+               return;
+       }
+       
+       if ( (results = (TCaddress *)malloc( TCAddressSize*lastResultsAmount )) == NULL )
+       {
+               NSLog( @"ERROR: could not create buffer" );
+               
+               [self sendError:@"The server cancelled the search because it ran out of memory." fatal:NO];
+               return;
+       }
+       
+       for ( i = 0; i < lastResultsAmount; i++ )
+       {
+               TCaddress               address = lastResultsData[i];
+               
+               dataLength = sizeof(data);
+               
+               if ( (result = vm_read_overwrite( processTask, address, sizeof(data), (vm_address_t)(&data), &dataLength )) == KERN_SUCCESS )
+               {
+                       if ( data == value[0] )
+                       {
+                               results[resultsAmount++] = address;
+                       }
+               }
+               else
+               {
+                       if ( result != KERN_PROTECTION_FAILURE )
+                       {
+                               NSLog( @"vm_read_overwrite returned error: %i", result );
+                               break;
+                       }
+               }
+       }
+       
+       realloc( results, TCAddressSize*resultsAmount );
+       [searchResults addObject:[SearchResults resultsWithType:TYPE_INTEGER size:SIZE_8_BIT data:results amount:resultsAmount]];
+       
+       NSLog( @"found %i of %i", resultsAmount, value );
+}
+
+- (void)searchIntegerChar:(int8_t)value
+{
+       kern_return_t                           result;
+       
+       int8_t                                          data;
+       vm_size_t                                       dataLength;
+       
+       TCaddress                                       *results;
+       int                                                     resultsAmount = 0;
+       
+       SearchResults                           *lastResults = [searchResults lastObject];
+       TCaddress                                       *lastResultsData = [lastResults data];
+       int                                                     i, lastResultsAmount = [lastResults amount];
+       
+       if ( [lastResults type] != TYPE_INTEGER || [lastResults size] != SIZE_8_BIT )
+       {
+               [self sendError:@"This search is incompatible with the previous search." fatal:NO];
+               return;
+       }
+       
+       if ( (results = (TCaddress *)malloc( TCAddressSize*lastResultsAmount )) == NULL )
+       {
+               NSLog( @"ERROR: could not create buffer" );
+               
+               [self sendError:@"The server cancelled the search because it ran out of memory." fatal:NO];
+               return;
+       }
+       
+       for ( i = 0; i < lastResultsAmount; i++ )
+       {
+               TCaddress               address = lastResultsData[i];
+               
+               dataLength = sizeof(data);
+               
+               if ( (result = vm_read_overwrite( processTask, address, sizeof(data), (vm_address_t)(&data), &dataLength )) == KERN_SUCCESS )
+               {
+                       if ( data == value )
+                       {
+                               results[resultsAmount++] = address;
+                       }
+               }
+               else
+               {
+                       if ( result != KERN_PROTECTION_FAILURE )
+                       {
+                               NSLog( @"vm_read_overwrite returned error: %i", result );
+                               break;
+                       }
+               }
+       }
+       
+       realloc( results, TCAddressSize*resultsAmount );
+       [searchResults addObject:[SearchResults resultsWithType:TYPE_INTEGER size:SIZE_8_BIT data:results amount:resultsAmount]];
+       
+       NSLog( @"found %i of %i", resultsAmount, value );
+}
+
+- (void)searchIntegerShort:(int16_t)value
+{
+       kern_return_t                           result;
+       
+       int16_t                                         data;
+       vm_size_t                                       dataLength;
+       
+       TCaddress                                       *results;
+       int                                                     resultsAmount = 0;
+       
+       SearchResults                           *lastResults = [searchResults lastObject];
+       TCaddress                                       *lastResultsData = [lastResults data];
+       int                                                     i, lastResultsAmount = [lastResults amount];
+       
+       if ( [lastResults type] != TYPE_INTEGER || [lastResults size] != SIZE_16_BIT )
+       {
+               [self sendError:@"This search is incompatible with the previous search." fatal:NO];
+               return;
+       }
+       
+       if ( (results = (TCaddress *)malloc( TCAddressSize*lastResultsAmount )) == NULL )
+       {
+               NSLog( @"ERROR: could not create buffer" );
+               
+               [self sendError:@"The server cancelled the search because it ran out of memory." fatal:NO];
+               return;
+       }
+       
+       for ( i = 0; i < lastResultsAmount; i++ )
+       {
+               TCaddress               address = lastResultsData[i];
+               
+               dataLength = sizeof(data);
+               
+               if ( (result = vm_read_overwrite( processTask, address, sizeof(data), (vm_address_t)(&data), &dataLength )) == KERN_SUCCESS )
+               {
+                       if ( data == value )
+                       {
+                               results[resultsAmount++] = address;
+                       }
+               }
+               else
+               {
+                       if ( result != KERN_PROTECTION_FAILURE )
+                       {
+                               NSLog( @"vm_read_overwrite returned error: %i", result );
+                               break;
+                       }
+               }
+       }
+       
+       realloc( results, TCAddressSize*resultsAmount );
+       [searchResults addObject:[SearchResults resultsWithType:TYPE_INTEGER size:SIZE_16_BIT data:results amount:resultsAmount]];
+       
+       NSLog( @"found %i of %i", resultsAmount, value );
+}
+
+- (void)searchIntegerLong:(int32_t)value
+{
+       kern_return_t                           result;
+       
+       int32_t                                         data;
+       vm_size_t                                       dataLength;
+       
+       TCaddress                                       *results;
+       int                                                     resultsAmount = 0;
+       
+       SearchResults                           *lastResults = [searchResults lastObject];
+       TCaddress                                       *lastResultsData = [lastResults data];
+       int                                                     i, lastResultsAmount = [lastResults amount];
+       
+       if ( [lastResults type] != TYPE_INTEGER || [lastResults size] != SIZE_32_BIT )
+       {
+               [self sendError:@"This search is incompatible with the previous search." fatal:NO];
+               return;
+       }
+       
+       if ( (results = (TCaddress *)malloc( TCAddressSize*lastResultsAmount )) == NULL )
+       {
+               NSLog( @"ERROR: could not create buffer" );
+               
+               [self sendError:@"The server cancelled the search because it ran out of memory." fatal:NO];
+               return;
+       }
+       
+       for ( i = 0; i < lastResultsAmount; i++ )
+       {
+               TCaddress               address = lastResultsData[i];
+               
+               dataLength = sizeof(data);
+               
+               if ( (result = vm_read_overwrite( processTask, address, sizeof(data), (vm_address_t)(&data), &dataLength )) == KERN_SUCCESS )
+               {
+                       if ( data == value )
+                       {
+                               results[resultsAmount++] = address;
+                       }
+               }
+               else
+               {
+                       if ( result != KERN_PROTECTION_FAILURE )
+                       {
+                               NSLog( @"vm_read_overwrite returned error: %i", result );
+                               break;
+                       }
+               }
+       }
+       
+       realloc( results, TCAddressSize*resultsAmount );
+       [searchResults addObject:[SearchResults resultsWithType:TYPE_INTEGER size:SIZE_32_BIT data:results amount:resultsAmount]];
+       
+       NSLog( @"found %i of %i", resultsAmount, value );
+}
+
+- (void)searchDecimalFloat:(float)value
+{
+       kern_return_t                           result;
+       
+       float                                           data;
+       vm_size_t                                       dataLength;
+       
+       TCaddress                                       *results;
+       int                                                     resultsAmount = 0;
+       
+       SearchResults                           *lastResults = [searchResults lastObject];
+       TCaddress                                       *lastResultsData = [lastResults data];
+       int                                                     i, lastResultsAmount = [lastResults amount];
+       
+       if ( [lastResults type] != TYPE_DECIMAL || [lastResults size] != SIZE_32_BIT )
+       {
+               [self sendError:@"This search is incompatible with the previous search." fatal:NO];
+               return;
+       }
+       
+       if ( (results = (TCaddress *)malloc( TCAddressSize*lastResultsAmount )) == NULL )
+       {
+               NSLog( @"ERROR: could not create buffer" );
+               
+               [self sendError:@"The server cancelled the search because it ran out of memory." fatal:NO];
+               return;
+       }
+       
+       for ( i = 0; i < lastResultsAmount; i++ )
+       {
+               TCaddress               address = lastResultsData[i];
+               
+               dataLength = sizeof(data);
+               
+               if ( (result = vm_read_overwrite( processTask, address, sizeof(data), (vm_address_t)(&data), &dataLength )) == KERN_SUCCESS )
+               {
+                       if ( compare_float( data, value ) )
+                       {
+                               results[resultsAmount++] = address;
+                       }
+               }
+               else
+               {
+                       if ( result != KERN_PROTECTION_FAILURE )
+                       {
+                               NSLog( @"vm_read_overwrite returned error: %i", result );
+                               break;
+                       }
+               }
+       }
+       
+       realloc( results, TCAddressSize*resultsAmount );
+       [searchResults addObject:[SearchResults resultsWithType:TYPE_DECIMAL size:SIZE_32_BIT data:results amount:resultsAmount]];
+       
+       NSLog( @"found %i of %i", resultsAmount, value );
+}
+
+- (void)searchDecimalDouble:(double)value
+{
+       kern_return_t                           result;
+       
+       double                                          data;
+       vm_size_t                                       dataLength;
+       
+       TCaddress                                       *results;
+       int                                                     resultsAmount = 0;
+       
+       SearchResults                           *lastResults = [searchResults lastObject];
+       TCaddress                                       *lastResultsData = [lastResults data];
+       int                                                     i, lastResultsAmount = [lastResults amount];
+       
+       if ( [lastResults type] != TYPE_DECIMAL || [lastResults size] != SIZE_64_BIT )
+       {
+               [self sendError:@"This search is incompatible with the previous search." fatal:NO];
+               return;
+       }
+       
+       if ( (results = (TCaddress *)malloc( TCAddressSize*lastResultsAmount )) == NULL )
+       {
+               NSLog( @"ERROR: could not create buffer" );
+               
+               [self sendError:@"The server cancelled the search because it ran out of memory." fatal:NO];
+               return;
+       }
+       
+       for ( i = 0; i < lastResultsAmount; i++ )
+       {
+               TCaddress               address = lastResultsData[i];
+               
+               dataLength = sizeof(data);
+               
+               if ( (result = vm_read_overwrite( processTask, address, sizeof(data), (vm_address_t)(&data), &dataLength )) == KERN_SUCCESS )
+               {
+                       if ( compare_double( data, value ) )
+                       {
+                               results[resultsAmount++] = address;
+                       }
+               }
+               else
+               {
+                       if ( result != KERN_PROTECTION_FAILURE )
+                       {
+                               NSLog( @"vm_read_overwrite returned error: %i", result );
+                               break;
+                       }
+               }
+       }
+       
+       realloc( results, TCAddressSize*resultsAmount );
+       [searchResults addObject:[SearchResults resultsWithType:TYPE_DECIMAL size:SIZE_64_BIT data:results amount:resultsAmount]];
+       
+       NSLog( @"found %i of %i", resultsAmount, value );
+}
+
+
+- (void)changeString8bit:(char const *)value size:(int)vsize addresses:(TCaddress *)addresses count:(int)count
+{
+       int                                     failCount = 0;
+       int                                     i;
+       
+       NSLog( @"change string: %s", value );
+       
+       for ( i = 0; i < count; i++ )
+       {
+               if ( vm_write( processTask, (vm_address_t)addresses[i], (vm_offset_t)value, vsize ) != KERN_SUCCESS )
+               {
+                       failCount++;
+               }
+       }
+       
+       if ( failCount > 0 )
+       {
+               [self sendError:[NSString stringWithFormat:@"%i of the selected variables could not be changed.", failCount] fatal:NO];
+       }
+}
+
+- (void)changeIntegerChar:(int8_t)value addresses:(TCaddress *)addresses count:(int)count
+{
+       int                                     failCount = 0;
+       int                                     i;
+       
+       for ( i = 0; i < count; i++ )
+       {
+               if ( vm_write( processTask, (vm_address_t)addresses[i], (vm_offset_t)(&value), sizeof(value) ) != KERN_SUCCESS )
+               {
+                       failCount++;
+               }
+       }
+       
+       if ( failCount > 0 )
+       {
+               [self sendError:[NSString stringWithFormat:@"%i of the selected variables could not be changed.", failCount] fatal:NO];
+       }
+}
+
+- (void)changeIntegerShort:(int16_t)value addresses:(TCaddress *)addresses count:(int)count
+{
+       int                                     failCount = 0;
+       int                                     i;
+       
+       for ( i = 0; i < count; i++ )
+       {
+               if ( vm_write( processTask, (vm_address_t)addresses[i], (vm_offset_t)(&value), sizeof(value) ) != KERN_SUCCESS )
+               {
+                       failCount++;
+               }
+       }
+       
+       if ( failCount > 0 )
+       {
+               [self sendError:[NSString stringWithFormat:@"%i of the selected variables could not be changed.", failCount] fatal:NO];
+       }
+}
+
+- (void)changeIntegerLong:(int32_t)value addresses:(TCaddress *)addresses count:(int)count
+{
+       int                                     failCount = 0;
+       int                                     i;
+       
+       for ( i = 0; i < count; i++ )
+       {
+               if ( vm_write( processTask, (vm_address_t)addresses[i], (vm_offset_t)(&value), sizeof(value) ) != KERN_SUCCESS )
+               {
+                       failCount++;
+               }
+       }
+       
+       if ( failCount > 0 )
+       {
+               [self sendError:[NSString stringWithFormat:@"%i of the selected variables could not be changed.", failCount] fatal:NO];
+       }
+}
+
+- (void)changeDecimalFloat:(float)value addresses:(TCaddress *)addresses count:(int)count
+{
+       int                                     failCount = 0;
+       int                                     i;
+       
+       for ( i = 0; i < count; i++ )
+       {
+               if ( vm_write( processTask, (vm_address_t)addresses[i], (vm_offset_t)(&value), sizeof(value) ) != KERN_SUCCESS )
+               {
+                       failCount++;
+               }
+       }
+       
+       if ( failCount > 0 )
+       {
+               [self sendError:[NSString stringWithFormat:@"%i of the selected variables could not be changed.", failCount] fatal:NO];
+       }
+}
+
+- (void)changeDecimalDouble:(double)value addresses:(TCaddress *)addresses count:(int)count
+{
+       int                                     failCount = 0;
+       int                                     i;
+       
+       for ( i = 0; i < count; i++ )
+       {
+               if ( vm_write( processTask, (vm_address_t)addresses[i], (vm_offset_t)(&value), sizeof(value) ) != KERN_SUCCESS )
+               {
+                       failCount++;
+               }
+       }
+       
+       if ( failCount > 0 )
+       {
+               [self sendError:[NSString stringWithFormat:@"%i of the selected variables could not be changed.", failCount] fatal:NO];
+       }
+}
+
+
+- (void)sendProcessList
+{
+       NSArray                 *processList = [rootProxy serverProcessList];
+       
+       NSNumber                *pid;
+       u_int32_t               pidNum;
+       NSString                *name;
+
+       PacketHeader    header;
+
+       char                    *buffer, *ptr;
+
+       //                       PROCESS COUNT
+       int                             length = sizeof(u_int32_t);
+       int                             lengthAfter;
+
+       u_int32_t               processCount = [processList count];
+
+       int                             i, max = processCount;
+
+       header.checksum = RandomChecksum();
+       header.function = 2;
+
+       for ( i = 0; i < max; i++ )
+       {
+               pid = [[processList objectAtIndex:i] objectForKey:@"NSApplicationProcessIdentifier"];
+               name = [[processList objectAtIndex:i] objectForKey:@"NSApplicationName"];
+
+               //        PID                 NAME
+               length += sizeof(u_int32_t) + [name length] + 1;
+       }
+
+       header.size = length;
+       length += sizeof(header);
+       //        HEADER
+
+       if ( (buffer = (char *)malloc( length ))==NULL )
+       {
+               NSLog( @"sendProcessList failed" );
+               return;
+       }
+
+       ptr = buffer;
+
+       COPY_TO_BUFFER( ptr, &header, sizeof(header) );
+       COPY_TO_BUFFER( ptr, &processCount, sizeof(processCount) );
+
+       for ( i = 0; i < max; i++ )
+       {
+               pidNum = [[[processList objectAtIndex:i] objectForKey:@"NSApplicationProcessIdentifier"] unsignedLongValue];
+               name = [[processList objectAtIndex:i] objectForKey:@"NSApplicationName"];
+
+               COPY_TO_BUFFER( ptr, &pidNum, sizeof(pid) );
+               COPY_TO_BUFFER( ptr, [name lossyCString], [name length] + 1 );
+       }
+
+       lengthAfter = length;
+
+       if ( SendBuffer( sockfd, buffer, &lengthAfter ) == -1 || lengthAfter != length )
+       {
+               NSLog( @"sendProcessList failed" );
+       }
+
+       free( buffer );
+}
+
+
+- (void)sendSearchFinished
+{
+       PacketHeader    header;
+       int                             length = sizeof(header);
+
+       header.checksum = RandomChecksum();
+       header.function = 6;
+       header.size = 0;
+
+       if ( SendBuffer( sockfd, (char *)(&header), &length ) == -1 || length != sizeof(header) )
+       {
+               NSLog( @"sendSearchFinished failed" );
+       }
+}
+
+- (void)sendVariableList:(TCaddress const *)data amount:(int)amount
+{
+       PacketHeader    header;
+       int                             length;
+       int                             lengthAfter;
+
+       char                    *buffer, *ptr;
+
+       header.checksum = RandomChecksum();
+       header.function = 7;
+       header.size = sizeof(amount) + TCAddressSize*amount;
+       //            AMOUNT           DATA
+
+       lengthAfter = length = header.size + sizeof(header);
+
+       if ( (buffer = (char *)malloc( length )) == NULL )
+       {
+               NSLog( @"sendVariableList:amount: failed" );
+               return;
+       }
+
+       ptr = buffer;
+
+       COPY_TO_BUFFER( ptr, &header, sizeof(header) );
+       COPY_TO_BUFFER( ptr, &amount, sizeof(amount) );
+       COPY_TO_BUFFER( ptr, data, TCAddressSize*amount );
+
+       if ( SendBuffer( sockfd, buffer, &length ) == -1 || lengthAfter != length )
+       {
+               NSLog( @"sendVariableList:amount: failed" );
+       }
+
+       free( buffer );
+}
+
+- (void)sendChangeFinished
+{
+       PacketHeader    header;
+       int                             length = sizeof(header);
+
+       header.checksum = RandomChecksum();
+       header.function = 9;
+       header.size = 0;
+
+       if ( SendBuffer( sockfd, (char *)(&header), &length ) == -1 || length != sizeof(header) )
+       {
+               NSLog( @"sendChangeFinished failed" );
+       }
+}
+
+- (void)sendError:(NSString *)msg fatal:(BOOL)fatal
+{
+       PacketHeader    header;
+       int                             length;
+       int                             lengthAfter;
+
+       u_int32_t               type = (fatal)? 1:0;
+
+       char                    *buffer, *ptr;
+
+       header.checksum = RandomChecksum();
+       header.function = 11;
+       header.size = sizeof(type) + [msg length] + 1;
+       //            FATAL          STRING
+
+       lengthAfter = length = header.size + sizeof(header);
+
+       if ( (buffer = (char *)malloc( length )) == NULL )
+       {
+               NSLog( @"sendError:fatal: failed" );
+               return;
+       }
+
+       ptr = buffer;
+
+       COPY_TO_BUFFER( ptr, &header, sizeof(header) );
+       COPY_TO_BUFFER( ptr, &type, sizeof(type) );
+       COPY_TO_BUFFER( ptr, [msg lossyCString], [msg length] + 1 );
+
+       if ( SendBuffer( sockfd, buffer, &length ) == -1 || lengthAfter != length )
+       {
+               NSLog( @"sendError:fatal: failed" );
+       }
+
+       free( buffer );
+}
+
+- (void)sendVariableValue:(u_int32_t)index
+{
+
+}
+
+- (void)sendUndoFinished
+{
+       PacketHeader    header;
+       int                             length = sizeof(header);
+
+       header.checksum = RandomChecksum();
+       header.function = 15;
+       header.size = 0;
+
+       if ( SendBuffer( sockfd, (char *)(&header), &length ) == -1 || length != sizeof(header) )
+       {
+               NSLog( @"sendUndoFinished failed" );
+       }
+}
+
+- (void)sendRedoFinished
+{
+       PacketHeader    header;
+       int                             length = sizeof(header);
+
+       header.checksum = RandomChecksum();
+       header.function = 17;
+       header.size = 0;
+
+       if ( SendBuffer( sockfd, (char *)(&header), &length ) == -1 || length != sizeof(header) )
+       {
+               NSLog( @"sendRedoFinished failed" );
+       }
+}
+
+- (void)sendUndoRedoStatus
+{
+       PacketHeader    header;
+       int                             length;
+       int                             lengthAfter;
+       
+       u_int32_t               undoCount = (u_int32_t)[searchResults count];
+       u_int32_t               redoCount = (u_int32_t)[searchResultsUndone count];
+       
+       char                    *buffer, *ptr;
+       
+       header.checksum = RandomChecksum();
+       header.function = 19;
+       header.size = 2 * sizeof(u_int32_t);
+       
+       length = lengthAfter = sizeof(header) + header.size;
+       
+       if ( (buffer = (char *)malloc( length )) == NULL )
+       {
+               NSLog( @"sendSetTargetPID: failed" );
+       }
+       
+       ptr = buffer;
+       
+       COPY_TO_BUFFER( ptr, &header, sizeof(header) );
+       COPY_TO_BUFFER( ptr, &undoCount, sizeof(undoCount) );
+       COPY_TO_BUFFER( ptr, &redoCount, sizeof(redoCount) );
+       
+       if ( SendBuffer( sockfd, buffer, &lengthAfter ) == -1 || lengthAfter != length )
+       {
+               NSLog( @"sendUndoRedoStatus: failed" );
+       }
+       
+       free( buffer );
+}
+
+- (void)sendAppLaunched:(NSDictionary *)appInfo
+{
+       PacketHeader    header;
+
+       char                    *buffer, *ptr;
+
+       int                             length = 0;
+       int                             lengthAfter;
+
+       u_int32_t               pid = [[appInfo objectForKey:@"NSApplicationProcessIdentifier"] unsignedLongValue];
+       NSString                *name = [appInfo objectForKey:@"NSApplicationName"];
+
+       //        PID                 NAME
+       length += sizeof(u_int32_t) + [name length] + 1;
+
+       header.checksum = RandomChecksum();
+       header.function = 21;
+       header.size = length;
+
+       length += sizeof(header);
+       //        HEADER
+
+       if ( (buffer = (char *)malloc( length ))==NULL )
+       {
+               NSLog( @"sendAppLaunched: failed" );
+
+               return;
+       }
+
+       ptr = buffer;
+
+       COPY_TO_BUFFER( ptr, &header, sizeof(header) );
+       COPY_TO_BUFFER( ptr, &pid, sizeof(pid) );
+       COPY_TO_BUFFER( ptr, [name lossyCString], [name length] + 1 );
+
+       lengthAfter = length;
+
+       if ( SendBuffer( sockfd, buffer, &lengthAfter ) == -1 || lengthAfter != length )
+       {
+               NSLog( @"sendAppLaunched: failed" );
+       }
+
+       free( buffer );
+}
+
+
+- (void)sendAppQuit:(NSDictionary *)appInfo
+{
+       PacketHeader    header;
+
+       char                    *buffer, *ptr;
+
+       int                             length = 0;
+       int                             lengthAfter;
+
+       u_int32_t               pid = [[appInfo objectForKey:@"NSApplicationProcessIdentifier"] unsignedLongValue];
+
+       //        PID
+       length += sizeof(pid);
+
+       header.checksum = RandomChecksum();
+       header.function = 22;
+       header.size = length;
+
+       length += sizeof(header);
+       //        HEADER
+
+       if ( (buffer = (char *)malloc( length ))==NULL )
+       {
+               NSLog( @"sendAppQuit: failed" );
+
+               return;
+       }
+
+       ptr = buffer;
+
+       COPY_TO_BUFFER( ptr, &header, sizeof(header) );
+       COPY_TO_BUFFER( ptr, &pid, sizeof(pid) );
+
+       lengthAfter = length;
+
+       if ( SendBuffer( sockfd, buffer, &lengthAfter ) == -1 || lengthAfter != length )
+       {
+               NSLog( @"sendAppQuit: failed" );
+       }
+
+       free( buffer );
+}
+
+- (void)sendTargetAppQuit
+{
+       PacketHeader    header;
+       int                             length = sizeof(header);
+
+       header.checksum = RandomChecksum();
+       header.function = 23;
+       header.size = 0;
+
+       if ( SendBuffer( sockfd, (char *)(&header), &length ) == -1 || length != sizeof(header) )
+       {
+               NSLog( @"sendTargetAppQuit failed" );
+       }
+}
+
+- (void)sendPauseFinished:(BOOL)paused
+{
+       PacketHeader    header;
+
+       char                    *buffer, *ptr;
+
+       //                       PAUSED
+       int                             length = sizeof(paused);
+       int                             lengthAfter;
+
+       header.checksum = RandomChecksum();
+       header.function = 24;
+       header.size = length;
+
+       length += sizeof(header);
+       //        HEADER
+
+       if ( (buffer = (char *)malloc( length ))==NULL )
+       {
+               NSLog( @"sendPauseFinished: failed" );
+
+               return;
+       }
+
+       ptr = buffer;
+
+       COPY_TO_BUFFER( ptr, &header, sizeof(header) );
+       COPY_TO_BUFFER( ptr, &paused, sizeof(paused) );
+
+       lengthAfter = length;
+
+       if ( SendBuffer( sockfd, buffer, &lengthAfter ) == -1 || lengthAfter != length )
+       {
+               NSLog( @"sendPauseFinished: failed" );
+       }
+
+       free( buffer );
+}
+
+
+- (void)handleClearSearch
+{
+       [searchResults removeAllObjects];
+       [searchResultsUndone removeAllObjects];
+       
+       [self unpause];
+}
+
+- (void)handleSearch:(char const *)data size:(int)dataSize
+{
+       TCtype                  type;
+       TCsize                  size;
+       
+       char                    *ptr = (char *)data;
+
+       [self setAction:@"Searching"];
+
+       COPY_FROM_BUFFER( &type, ptr, sizeof(type) );
+       COPY_FROM_BUFFER( &size, ptr, sizeof(size) );
+
+       if ( ![searchResults lastObject] )
+       {
+               switch ( type )
+               {
+                       case TYPE_STRING:
+                       {
+                               switch ( size )
+                               {
+                                       case SIZE_8_BIT:
+                                       {
+                                               [self firstSearchString8bit:ptr size:(dataSize - (ptr - data))];
+                                       }
+                                               break;
+                               }
+                       }
+                               break;
+
+                       case TYPE_INTEGER:
+                       {
+                               switch ( size )
+                               {
+                                       case SIZE_8_BIT:
+                                       {
+                                               int8_t                  value;
+
+                                               COPY_FROM_BUFFER( &value, ptr, sizeof(value) );
+                                               [self firstSearchIntegerChar:value];
+                                       }
+                                               break;
+
+                                       case SIZE_16_BIT:
+                                       {
+                                               int16_t                 value;
+
+                                               COPY_FROM_BUFFER( &value, ptr, sizeof(value) );
+                                               [self firstSearchIntegerShort:value];
+                                       }
+                                               break;
+
+                                       case SIZE_32_BIT:
+                                       {
+                                               int32_t                 value;
+
+                                               COPY_FROM_BUFFER( &value, ptr, sizeof(value) );
+                                               [self firstSearchIntegerLong:value];
+                                       }
+                                               break;
+                               }
+                       }
+                               break;
+
+                       case TYPE_DECIMAL:
+                       {
+                               switch ( size )
+                               {
+                                       case SIZE_32_BIT:
+                                       {
+                                               float                   value;
+
+                                               COPY_FROM_BUFFER( &value, ptr, sizeof(value) );
+                                               [self firstSearchDecimalFloat:value];
+                                       }
+                                               break;
+
+                                       case SIZE_64_BIT:
+                                       {
+                                               double                  value;
+
+                                               COPY_FROM_BUFFER( &value, ptr, sizeof(value) );
+                                               [self firstSearchDecimalDouble:value];
+                                       }
+                                               break;
+                               }
+                       }
+                               break;
+               }
+       }
+       else
+       {
+               switch ( type )
+               {
+                       case TYPE_STRING:
+                       {
+                               switch ( size )
+                               {
+                                       case SIZE_8_BIT:
+                                       {
+                                               [self searchString8bit:ptr size:(dataSize - (ptr - data))];
+                                               
+                                               break;
+                                       }
+                               }
+                       }
+                               break;
+
+                       case TYPE_INTEGER:
+                       {
+                               switch ( size )
+                               {
+                                       case SIZE_8_BIT:
+                                       {
+                                               int8_t                  value;
+
+                                               COPY_FROM_BUFFER( &value, ptr, sizeof(value) );
+                                               [self searchIntegerChar:value];
+                                               
+                                               break;
+                                       }
+
+                                       case SIZE_16_BIT:
+                                       {
+                                               int16_t                 value;
+
+                                               COPY_FROM_BUFFER( &value, ptr, sizeof(value) );
+                                               [self searchIntegerShort:value];
+                                               
+                                               break;
+                                       }
+
+                                       case SIZE_32_BIT:
+                                       {
+                                               int32_t                 value;
+
+                                               COPY_FROM_BUFFER( &value, ptr, sizeof(value) );
+                                               [self searchIntegerLong:value];
+                                               
+                                               break;
+                                       }
+                               }
+                       }
+                               break;
+
+                       case TYPE_DECIMAL:
+                       {
+                               switch ( size )
+                               {
+                                       case SIZE_32_BIT:
+                                       {
+                                               float                   value;
+                                               
+                                               COPY_FROM_BUFFER( &value, ptr, sizeof(value) );
+                                               [self searchDecimalFloat:value];
+                                       }
+                                               break;
+
+                                       case SIZE_64_BIT:
+                                       {
+                                               double                  value;
+
+                                               COPY_FROM_BUFFER( &value, ptr, sizeof(value) );
+                                               [self searchDecimalDouble:value];
+                                       }
+                                               break;
+                               }
+                       }
+                               break;
+               }
+       }
+
+       [self sendVariableList:[(SearchResults *)[searchResults lastObject] data] amount:[[searchResults lastObject] amount]];
+       [self sendSearchFinished];
+       [self sendUndoRedoStatus];
+
+       [self setAction:nil];
+}
+
+- (void)handleChange:(char const *)data size:(int)dataSize
+{
+       TCtype                  type;
+       TCsize                  size;
+       
+       TCaddress               *addresses = NULL;
+       int                             count;
+       
+       char                    *ptr = (char *)data;
+       
+       [self setAction:@"Changing"];
+       
+       // read out the type and size of the variable.
+       COPY_FROM_BUFFER( &type, ptr, sizeof(type) );
+       COPY_FROM_BUFFER( &size, ptr, sizeof(size) );
+       
+       // read the amount of addresses.
+       COPY_FROM_BUFFER( &count, ptr, sizeof(count) );
+       
+       // save the pointer to the addresses.
+       addresses = (TCaddress *)ptr;
+       ptr += TCAddressSize*count;
+       
+       switch ( type )
+       {
+               case TYPE_STRING:
+               {
+                       switch ( size )
+                       {
+                               case SIZE_8_BIT:
+                               {
+                                       [self changeString8bit:ptr size:(dataSize - (ptr - data)) addresses:addresses count:count];
+                               }
+                                       break;
+                       }
+               }
+                       break;
+                       
+               case TYPE_INTEGER:
+               {
+                       switch ( size )
+                       {
+                               case SIZE_8_BIT:
+                               {
+                                       int8_t                  value;
+                                       
+                                       COPY_FROM_BUFFER( &value, ptr, sizeof(value) );
+                                       [self changeIntegerChar:value addresses:addresses count:count];
+                               }
+                                       break;
+                                       
+                               case SIZE_16_BIT:
+                               {
+                                       int16_t                 value;
+                                       
+                                       COPY_FROM_BUFFER( &value, ptr, sizeof(value) );
+                                       [self changeIntegerShort:value addresses:addresses count:count];
+                               }
+                                       break;
+                                       
+                               case SIZE_32_BIT:
+                               {
+                                       int32_t                 value;
+                                       
+                                       COPY_FROM_BUFFER( &value, ptr, sizeof(value) );
+                                       [self changeIntegerLong:value addresses:addresses count:count];
+                               }
+                                       break;
+                       }
+               }
+                       break;
+                       
+               case TYPE_DECIMAL:
+               {
+                       switch ( size )
+                       {
+                               case SIZE_32_BIT:
+                               {
+                                       float                   value;
+                                       
+                                       COPY_FROM_BUFFER( &value, ptr, sizeof(value) );
+                                       [self changeDecimalFloat:value addresses:addresses count:count];
+                               }
+                                       break;
+                                       
+                               case SIZE_64_BIT:
+                               {
+                                       double                  value;
+                                       
+                                       COPY_FROM_BUFFER( &value, ptr, sizeof(value) );
+                                       [self changeDecimalDouble:value addresses:addresses count:count];
+                               }
+                                       break;
+                       }
+               }
+                       break;
+       }
+       
+       [self sendChangeFinished];
+       
+       [self setAction:nil];
+}
+
+- (void)handlePauseTarget
+{
+       if ( !processPaused )
+       {
+               int                     wait_status;
+               
+               if ( ptrace( PT_ATTACH, processID, 0, 0 ) != -1 )
+               {
+                       if ( waitpid( processID, &wait_status, WUNTRACED ) == processID )
+                       {
+                               if ( WIFSTOPPED(wait_status) )
+                               {
+                                       processPaused = YES;
+                                       [self sendPauseFinished:YES];
+                               }
+                               else
+                               {
+                                       NSLog( @"ERROR: process couldn't be paused" );
+                                       [self sendPauseFinished:NO];
+                                       [self sendError:@"Process couldn't be paused." fatal:NO];
+                               }
+                       }
+                       else
+                       {
+                               NSLog( @"ERROR: process couldn't be paused" );
+                               [self sendPauseFinished:NO];
+                               [self sendError:@"Process couldn't be paused." fatal:NO];
+                       }
+               }
+               else
+               {
+                       NSLog( @"ERROR: process couldn't be paused" );
+                       [self sendPauseFinished:NO];
+                       [self sendError:@"Process couldn't be paused." fatal:NO];
+               }
+       }
+       else
+       {
+               ptrace( PT_DETACH, processID, 0, 0 );
+
+               processPaused = NO;
+               [self sendPauseFinished:NO];
+       }
+}
+
+- (void)handleUndo
+{
+       SearchResults           *results = [searchResults lastObject];
+       
+       if ( results )
+       {
+               [searchResultsUndone addObject:results];
+               [searchResults removeLastObject];
+       }
+
+       results = [searchResults lastObject];
+       if ( results )
+       {
+               [self sendVariableList:[results data] amount:[results amount]];
+       }
+       else
+       {
+               [self sendVariableList:NULL amount:0];
+       }
+       
+       [self sendUndoFinished];
+       [self sendUndoRedoStatus];
+}
+
+- (void)handleRedo
+{
+       SearchResults           *results = [searchResultsUndone lastObject];
+       
+       if ( results )
+       {
+               [searchResults addObject:results];
+               [searchResultsUndone removeLastObject];
+       }
+
+       results = [searchResults lastObject];
+       if ( results )
+       {
+               [self sendVariableList:[results data] amount:[results amount]];
+       }
+       else
+       {
+               [self sendVariableList:NULL amount:0];
+       }
+       
+       [self sendRedoFinished];
+       [self sendUndoRedoStatus];
+}
+
+- (void)handleSetTargetPID:(char const *)data size:(int)size
+{
+       char                    *ptr = (char *)data;
+
+       pid_t                   pid;
+
+       COPY_FROM_BUFFER( &pid, ptr, sizeof(pid) );
+
+       [self setPID:pid];
+}
+
+
+- (void)unpause
+{
+       if ( processPaused )
+       {
+               [self handlePauseTarget];
+       }
+}
+
+- (void)setPID:(pid_t)pid
+{
+       kern_return_t                           result;
+
+       [self unpause];
+       
+       processID = pid;
+
+       if ( (result = task_for_pid( current_task(), processID, &processTask)) != KERN_SUCCESS )
+       {
+               NSLog( @"task_for_pid returned error: %i", result );
+       }
+}
+
+
+- (void)dealloc
+{
+       [self unpause];
+
+       [[[NSWorkspace sharedWorkspace] notificationCenter] removeObserver:self];
+
+       [searchResults release];
+       [searchResultsUndone release];
+
+       [super dealloc];
+}
+
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%   NSWorkspaceDidLaunchApplicationNotification Notification
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+
+- (void)processListChanged:(NSNotification *)note
+{
+       pid_t                   pid = [[[note userInfo] objectForKey:@"NSApplicationProcessIdentifier"] intValue];
+
+       if ( /*pid != getpid()*/ sockfd != -1 )
+       {
+               if ( [[note name] isEqualToString:@"NSWorkspaceDidLaunchApplicationNotification"] )
+               {
+                       [self sendAppLaunched:[note userInfo]];
+               }
+               else
+               {
+                       [self sendAppQuit:[note userInfo]];
+
+                       if ( pid == processID )
+                       {
+                               [self sendTargetAppQuit];
+
+                               // we can't set the new target here because this method is not called
+                               // in the server thread.  the client will have to change it.
+                               //[self setPID:[rootProxy serverFirstProcess]];
+                               processPaused = NO;
+                       }
+               }
+       }
+}
+
+
+@end
+
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%   Internal Functions
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+
+BOOL compare_float( float a, float b )
+{
+       float const             feps = 0.0001f;
+       
+       return feps > fabsf( a - b );
+}
+
+BOOL compare_double( double a, double b )
+{
+       double const    deps = 0.0000001;
+       
+       return deps > fabs( a - b );
+}
\ No newline at end of file
This page took 0.062092 seconds and 4 git commands to generate.