2 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
6 // Created: Sun Sep 07 2003
8 // Copyright: 2003 Chaz McGarvey. All rights reserved.
9 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
11 #import "CheatServer.h"
13 #import "SearchResults.h"
15 // for comparing floats
24 int bmsearch( char *pat
, int m
, char *text
, int n
, void *base
, void *loc
[] );
25 //BOOL inline compare_float( float a, float b );
26 //BOOL inline compare_double( double a, double b );
29 @implementation CheatServer
32 + (NSConnection
*)serverWithDelegate
:(id)delegate socket
:(int)sock
34 NSPort
*rPort
= [NSPort port
], *sPort
= [NSPort port
];
35 NSConnection
*connection
;
38 connection
= [[NSConnection alloc
] initWithReceivePort
:rPort sendPort
:sPort
];
39 [connection setRootObject
:delegate
];
41 array
= [NSArray arrayWithObjects
:sPort
, rPort
, [NSNumber numberWithInt
:sock
], nil];
42 [NSThread detachNewThreadSelector
:@selector(serverThread
:) toTarget
:self withObject
:array
];
44 return [connection autorelease
];
47 + (void)serverThread
:(NSArray
*)array
49 NSAutoreleasePool
*pool
= [[NSAutoreleasePool alloc
] init
];
50 NSConnection
*connection
= [NSConnection connectionWithReceivePort
:[array objectAtIndex
:0] sendPort
:[array objectAtIndex
:1]];
51 CheatServer
*object
= [[self alloc
] initWithRootProxy
:[connection rootProxy
]];
53 [object handleSocket
:[[array objectAtIndex
:2] intValue
]];
61 - (id)initWithRootProxy
:(id)proxy
63 if ( self = [super init
] )
65 NSNotificationCenter
*nc
= [[NSWorkspace sharedWorkspace
] notificationCenter
];
69 [nc addObserver
:self selector
:@selector(processListChanged
:) name
:@
"NSWorkspaceDidLaunchApplicationNotification" object
:nil];
70 [nc addObserver
:self selector
:@selector(processListChanged
:) name
:@
"NSWorkspaceDidTerminateApplicationNotification" object
:nil];
72 [self setPID
:[rootProxy serverFirstProcess
]];
76 searchResults
= [[NSMutableArray alloc
] init
];
77 searchResultsUndone
= [[NSMutableArray alloc
] init
];
84 - (void)handleSocket
:(int)sock
86 struct sockaddr identifier
;
87 int addrLen
= sizeof(identifier
);
94 if ( getpeername( sockfd
, &identifier
, &addrLen
) == -1 )
96 CMLog( @
"ERROR: getpeername() failed" );
99 if ( identifier.sa_family
== AF_INET
)
101 struct sockaddr_in addr
;
103 addrLen
= sizeof(addr
);
105 if ( getpeername( sockfd
, (struct sockaddr
*)(&addr
), &addrLen
) == -1 )
107 CMLog( @
"ERROR: getpeername() failed" );
110 if ( (addressCString
= inet_ntoa( addr.sin_addr
)) == NULL
)
112 CMLog( @
"ERROR: inet_ntoa() failed" );
115 address
= [NSString stringWithCString
:addressCString
];
119 struct sockaddr_un addr
;
121 addrLen
= sizeof(addr
);
123 if ( getpeername( sockfd
, (struct sockaddr
*)(&addr
), &addrLen
) == -1 )
125 CMLog( @
"ERROR: getpeername() failed" );
128 CMLog( @
"client connection: %s", addr.sun_path
);
130 address
= [NSString stringWithString
:@
"127.0.0.1"];
133 [rootProxy server
:self connectedWithSocket
:sockfd
];
135 [self setAddress
:address
];
136 [self setAction
:nil];
142 fd_set fdset
, master
;
155 FD_SET( sockfd
, &master
);
159 CMLog( @
"SERVER start" );
165 select( numfds
, &fdset
, NULL
, NULL
, &tv
);
167 if ( FD_ISSET( sockfd
, &fdset
) )
169 if ( (result
= ReadBuffer( sockfd
, (char *)(&header
), sizeof(header
) )) != sizeof(header
) )
174 if ( !VerifyChecksum( header.checksum
) )
176 CMLog( @
"checksum failed" );
179 if ( header.size
!= 0 )
181 if ( (data
= (char *)malloc( header.size
)) == NULL
)
183 CMLog( @
"failed to allocate buffer for reading a network packet" );
187 if ( (result
= ReadBuffer( sockfd
, data
, header.size
)) != header.size
)
189 CMLog( @
"failed to read the data of a network packet" );
195 //CMLog( @"SERVER message %i/%i/%i", header.checksum, header.function, header.size );
197 switch ( header.function
)
200 [self sendProcessList
];
204 [self handleClearSearch
];
208 [self handleSearch
:data size
:header.size
];
212 [self handleChange
:data size
:header.size
];
216 [self handlePauseTarget
];
228 [self handleSetTargetPID
:data size
:header.size
];
233 if ( header.size
!= 0 )
242 CMLog( @
"SERVER close" );
244 [rootProxy serverDisconnected
:self];
248 - (void)setAddress
:(NSString
*)address
250 [rootProxy server
:self changedAddress
:address
];
253 - (void)setAction
:(NSString
*)action
257 [rootProxy server
:self changedAction
:@
"Idle"];
261 [rootProxy server
:self changedAction
:action
];
265 - (void)firstSearchString8bit
:(char const *)value size
:(int)vsize
267 kern_return_t result
;
269 vm_address_t address
= 0x0;
271 vm_region_basic_info_data_t info
;
272 mach_msg_type_number_t infoCnt
= 8;
273 mach_port_t object_name
= 0;
276 vm_size_t dataLength
;
278 TCaddress
*results
= NULL
;
279 int resultsAmount
= 0;
283 if ( (result
= vm_region( processTask
, &address
, &size
, VM_REGION_BASIC_INFO
, (vm_region_info_t
)(&info
), &infoCnt
, &object_name
)) != KERN_SUCCESS
)
285 if ( result
!= KERN_INVALID_ADDRESS
)
287 CMLog( @
"vm_region returned error: %i", result
);
292 if ( (info.protection
& VM_PROT_READ
) && (info.protection
& VM_PROT_WRITE
))
294 data
= (char *)malloc( size
);
297 if ( (result
= vm_read_overwrite( processTask
, address
, size
, (vm_address_t
)data
, &dataLength
)) != KERN_SUCCESS
&& result
!= KERN_PROTECTION_FAILURE
)
299 CMLog( @
"vm_read_overwrite returned error: %i", result
);
304 if ( result
== KERN_SUCCESS
)
306 //int i, top = dataLength - vsize;
308 if ( (results
= realloc( results
, TCAddressSize
*resultsAmount
+ dataLength
)) == NULL
)
310 CMLog( @
"ERROR: could not expand buffer" );
314 resultsAmount
+= bmsearch( (char *)value
, vsize
, (char *)data
, dataLength
, (void *)address
, (void **)((char *)results
+TCAddressSize
*resultsAmount
) );
315 //resultsAmount += TBM( (char *)value, vsize, data, dataLength, (void **)((char *)results+TCAddressSize*resultsAmount) );
316 //resultsAmount += SMITH( data, dataLength, (char *)value, vsize, (void **)((char *)results+TCAddressSize*resultsAmount) );
318 /*for ( i = 0; i < top; i++ )
320 if ( strncmp( value, data+i, vsize ) == 0 )
322 results[resultsAmount++] = (TCaddress)address + i;
333 realloc( results
, TCAddressSize
*resultsAmount
);
334 [searchResults addObject
:[SearchResults resultsWithType
:TYPE_INTEGER size
:SIZE_8_BIT data
:results amount
:resultsAmount
]];
336 CMLog( @
"found %i of %i", resultsAmount
, value
);
339 - (void)firstSearchIntegerChar
:(int8_t
)value
341 kern_return_t result
;
343 vm_address_t address
= 0x0;
345 vm_region_basic_info_data_t info
;
346 mach_msg_type_number_t infoCnt
= 8;
347 mach_port_t object_name
= 0;
350 vm_size_t dataLength
;
352 TCaddress
*results
= NULL
;
353 int resultsAmount
= 0;
357 if ( (result
= vm_region( processTask
, &address
, &size
, VM_REGION_BASIC_INFO
, (vm_region_info_t
)(&info
), &infoCnt
, &object_name
)) != KERN_SUCCESS
)
359 if ( result
!= KERN_INVALID_ADDRESS
)
361 CMLog( @
"vm_region returned error: %i", result
);
366 if ( (info.protection
& VM_PROT_READ
) && (info.protection
& VM_PROT_WRITE
))
368 data
= (int8_t
*)malloc( size
);
371 if ( (result
= vm_read_overwrite( processTask
, address
, size
, (vm_address_t
)data
, &dataLength
)) != KERN_SUCCESS
&& result
!= KERN_PROTECTION_FAILURE
)
373 CMLog( @
"vm_read_overwrite returned error: %i", result
);
378 if ( result
== KERN_SUCCESS
)
382 if ( (results
= (TCaddress
*)realloc( results
, TCAddressSize
*resultsAmount
+ TCAddressSize
*dataLength
)) == NULL
)
384 CMLog( @
"ERROR: could not expand buffer" );
388 for ( i
= 0; i
< dataLength
; i
++ )
390 if ( *(data
+i
) == value
)
392 results
[resultsAmount
++] = (TCaddress
)address
+ i
;
403 realloc( results
, TCAddressSize
*resultsAmount
);
404 [searchResults addObject
:[SearchResults resultsWithType
:TYPE_INTEGER size
:SIZE_8_BIT data
:results amount
:resultsAmount
]];
406 CMLog( @
"found %i of %i", resultsAmount
, value
);
409 - (void)firstSearchIntegerShort
:(int16_t
)value
411 kern_return_t result
;
413 vm_address_t address
= 0x0;
415 vm_region_basic_info_data_t info
;
416 mach_msg_type_number_t infoCnt
= 8;
417 mach_port_t object_name
= 0;
420 vm_size_t dataLength
;
422 TCaddress
*results
= NULL
;
423 int resultsAmount
= 0;
427 if ( (result
= vm_region( processTask
, &address
, &size
, VM_REGION_BASIC_INFO
, (vm_region_info_t
)(&info
), &infoCnt
, &object_name
)) != KERN_SUCCESS
)
429 if ( result
!= KERN_INVALID_ADDRESS
)
431 CMLog( @
"vm_region returned error: %i", result
);
436 if ( (info.protection
& VM_PROT_READ
) && (info.protection
& VM_PROT_WRITE
))
438 data
= (int16_t
*)malloc( size
);
441 if ( (result
= vm_read_overwrite( processTask
, address
, size
, (vm_address_t
)data
, &dataLength
)) != KERN_SUCCESS
&& result
!= KERN_PROTECTION_FAILURE
)
443 CMLog( @
"vm_read_overwrite returned error: %i", result
);
448 if ( result
== KERN_SUCCESS
)
450 int i
, top
= dataLength
/ sizeof(value
);
452 if ( (results
= (TCaddress
*)realloc( results
, TCAddressSize
*resultsAmount
+ 2*dataLength
)) == NULL
)
454 CMLog( @
"ERROR: could not expand buffer" );
458 for ( i
= 0; i
< top
; i
++ )
460 if ( *(data
+i
) == value
)
462 results
[resultsAmount
++] = (TCaddress
)address
+ i
* sizeof(value
);
473 realloc( results
, TCAddressSize
*resultsAmount
);
474 [searchResults addObject
:[SearchResults resultsWithType
:TYPE_INTEGER size
:SIZE_16_BIT data
:results amount
:resultsAmount
]];
476 CMLog( @
"found %i of %i", resultsAmount
, value
);
479 - (void)firstSearchIntegerLong
:(int32_t
)value
481 kern_return_t result
;
483 vm_address_t address
= 0x0;
485 vm_region_basic_info_data_t info
;
486 mach_msg_type_number_t infoCnt
= 8;
487 mach_port_t object_name
= 0;
490 vm_size_t dataLength
;
492 TCaddress
*results
= NULL
;
493 int resultsAmount
= 0;
495 /*unsigned zone_count = 10;
496 vm_address_t *zones = (vm_address_t *)malloc( zone_count * sizeof(vm_address_t) );
497 //memory_reader_t reader;
499 if ( (result = malloc_get_all_zones( processTask, NULL, &zones, &zone_count )) != KERN_SUCCESS )
501 CMLog( @"malloc_get_all_zones error: %i", result );
505 //address = zones[0];
509 for ( i = 0; i < 10; i++ )
511 CMLog( @"malloc_get_all_zones[%i] = %X", i, (vm_address_t)zones[i] );
517 if ( (result
= vm_region( processTask
, &address
, &size
, VM_REGION_BASIC_INFO
, (vm_region_info_t
)(&info
), &infoCnt
, &object_name
)) != KERN_SUCCESS
)
519 if ( result
!= KERN_INVALID_ADDRESS
)
521 CMLog( @
"vm_region returned error: %i", result
);
526 if ( (info.protection
& VM_PROT_READ
) && (info.protection
& VM_PROT_WRITE
) )
528 data
= (int32_t
*)malloc( size
);
531 //CMLog( @"address: %.8X size: %i", address, size );
533 if ( (result
= vm_read_overwrite( processTask
, address
, size
, (vm_address_t
)data
, &dataLength
)) != KERN_SUCCESS
&& result
!= KERN_PROTECTION_FAILURE
)
535 CMLog( @
"vm_read_overwrite returned error: %i", result
);
540 if ( result
== KERN_SUCCESS
)
542 int i
, top
= dataLength
/ sizeof(value
);
544 if ( (results
= (TCaddress
*)realloc( results
, TCAddressSize
*resultsAmount
+ dataLength
)) == NULL
)
546 CMLog( @
"ERROR: could not expand buffer" );
550 for ( i
= 0; i
< top
; i
++ )
552 if ( *(data
+i
) == value
)
554 results
[resultsAmount
++] = (TCaddress
)address
+ i
* sizeof(value
);
565 realloc( results
, TCAddressSize
*resultsAmount
);
566 [searchResults addObject
:[SearchResults resultsWithType
:TYPE_INTEGER size
:SIZE_32_BIT data
:results amount
:resultsAmount
]];
568 CMLog( @
"found %i of %i", resultsAmount
, value
);
571 - (void)firstSearchDecimalFloat
:(float)value
573 kern_return_t result
;
575 vm_address_t address
= 0x0;
577 vm_region_basic_info_data_t info
;
578 mach_msg_type_number_t infoCnt
= 8;
579 mach_port_t object_name
= 0;
582 vm_size_t dataLength
;
584 TCaddress
*results
= NULL
;
585 int resultsAmount
= 0;
589 if ( (result
= vm_region( processTask
, &address
, &size
, VM_REGION_BASIC_INFO
, (vm_region_info_t
)(&info
), &infoCnt
, &object_name
)) != KERN_SUCCESS
)
591 if ( result
!= KERN_INVALID_ADDRESS
)
593 CMLog( @
"vm_region returned error: %i", result
);
598 if ( (info.protection
& VM_PROT_READ
) && (info.protection
& VM_PROT_WRITE
))
600 data
= (float *)malloc( size
);
603 if ( (result
= vm_read_overwrite( processTask
, address
, size
, (vm_address_t
)data
, &dataLength
)) != KERN_SUCCESS
&& result
!= KERN_PROTECTION_FAILURE
)
605 CMLog( @
"vm_read_overwrite returned error: %i", result
);
610 if ( result
== KERN_SUCCESS
)
612 int i
, top
= dataLength
/ sizeof(value
);
614 if ( (results
= realloc( results
, TCAddressSize
*resultsAmount
+ dataLength
)) == NULL
)
616 CMLog( @
"ERROR: could not expand buffer" );
620 for ( i
= 0; i
< top
; i
++ )
622 if ( CMCompareFloatsWithEpsilon( *(data
+i
), value
, 0.1f
) == 0 )
624 results
[resultsAmount
++] = (TCaddress
)address
+ i
* sizeof(value
);
635 realloc( results
, TCAddressSize
*resultsAmount
);
636 [searchResults addObject
:[SearchResults resultsWithType
:TYPE_DECIMAL size
:SIZE_32_BIT data
:results amount
:resultsAmount
]];
638 CMLog( @
"found %i of %i", resultsAmount
, value
);
641 - (void)firstSearchDecimalDouble
:(double)value
643 kern_return_t result
;
645 vm_address_t address
= 0x0;
647 vm_region_basic_info_data_t info
;
648 mach_msg_type_number_t infoCnt
= 8;
649 mach_port_t object_name
= 0;
652 vm_size_t dataLength
;
654 TCaddress
*results
= NULL
;
655 int resultsAmount
= 0;
657 CMLog( @
"float search" );
661 if ( (result
= vm_region( processTask
, &address
, &size
, VM_REGION_BASIC_INFO
, (vm_region_info_t
)(&info
), &infoCnt
, &object_name
)) != KERN_SUCCESS
)
663 if ( result
!= KERN_INVALID_ADDRESS
)
665 CMLog( @
"vm_region returned error: %i", result
);
670 if ( (info.protection
& VM_PROT_READ
) && (info.protection
& VM_PROT_WRITE
))
672 data
= (double *)malloc( size
);
675 if ( (result
= vm_read_overwrite( processTask
, address
, size
, (vm_address_t
)data
, &dataLength
)) != KERN_SUCCESS
&& result
!= KERN_PROTECTION_FAILURE
)
677 CMLog( @
"vm_read_overwrite returned error: %i", result
);
682 if ( result
== KERN_SUCCESS
)
684 int i
, top
= dataLength
/ sizeof(value
);
686 if ( (results
= realloc( results
, TCAddressSize
*resultsAmount
+ dataLength
)) == NULL
)
688 CMLog( @
"ERROR: could not expand buffer" );
692 for ( i
= 0; i
< top
; i
++ )
694 if ( CMCompareDoublesWithEpsilon( *(data
+i
), value
, 0.1 ) == 0 )
696 results
[resultsAmount
++] = (TCaddress
)address
+ i
* sizeof(value
);
707 realloc( results
, TCAddressSize
*resultsAmount
);
708 [searchResults addObject
:[SearchResults resultsWithType
:TYPE_DECIMAL size
:SIZE_64_BIT data
:results amount
:resultsAmount
]];
710 CMLog( @
"found %i of %i", resultsAmount
, value
);
714 - (void)searchString8bit
:(char const *)value size
:(int)vsize
716 kern_return_t result
;
719 vm_size_t dataLength
;
722 int resultsAmount
= 0;
724 SearchResults
*lastResults
= [searchResults lastObject
];
725 TCaddress
*lastResultsData
= [lastResults data
];
726 int i
, lastResultsAmount
= [lastResults amount
];
728 if ( [lastResults type
] != TYPE_INTEGER ||
[lastResults size
] != SIZE_8_BIT
)
730 [self sendError
:@
"This search is incompatible with the previous search." fatal
:NO
];
734 if ( (data
= (char *)malloc( vsize
)) == NULL
)
736 CMLog( @
"ERROR: could not create buffer" );
738 [self sendError
:@
"The server cancelled the search because it ran out of memory." fatal
:NO
];
742 if ( (results
= (TCaddress
*)malloc( TCAddressSize
*lastResultsAmount
)) == NULL
)
744 CMLog( @
"ERROR: could not create buffer" );
746 [self sendError
:@
"The server cancelled the search because it ran out of memory." fatal
:NO
];
751 for ( i
= 0; i
< lastResultsAmount
; i
++ )
753 TCaddress address
= lastResultsData
[i
];
755 //dataLength = sizeof(data);
757 if ( (result
= vm_read_overwrite( processTask
, address
, vsize
, (vm_address_t
)(data
), &dataLength
)) == KERN_SUCCESS
)
759 if ( memcmp( data
, value
, dataLength
) == 0 )
761 results
[resultsAmount
++] = address
;
766 if ( result
!= KERN_PROTECTION_FAILURE
)
768 CMLog( @
"vm_read_overwrite returned error: %i", result
);
774 realloc( results
, TCAddressSize
*resultsAmount
);
775 [searchResults addObject
:[SearchResults resultsWithType
:TYPE_INTEGER size
:SIZE_8_BIT data
:results amount
:resultsAmount
]];
779 CMLog( @
"found %i of %i", resultsAmount
, value
);
782 - (void)searchIntegerChar
:(int8_t
)value
784 kern_return_t result
;
787 vm_size_t dataLength
;
790 int resultsAmount
= 0;
792 SearchResults
*lastResults
= [searchResults lastObject
];
793 TCaddress
*lastResultsData
= [lastResults data
];
794 int i
, lastResultsAmount
= [lastResults amount
];
796 if ( [lastResults type
] != TYPE_INTEGER ||
[lastResults size
] != SIZE_8_BIT
)
798 [self sendError
:@
"This search is incompatible with the previous search." fatal
:NO
];
802 if ( (results
= (TCaddress
*)malloc( TCAddressSize
*lastResultsAmount
)) == NULL
)
804 CMLog( @
"ERROR: could not create buffer" );
806 [self sendError
:@
"The server cancelled the search because it ran out of memory." fatal
:NO
];
810 for ( i
= 0; i
< lastResultsAmount
; i
++ )
812 TCaddress address
= lastResultsData
[i
];
814 dataLength
= sizeof(data
);
816 if ( (result
= vm_read_overwrite( processTask
, address
, sizeof(data
), (vm_address_t
)(&data
), &dataLength
)) == KERN_SUCCESS
)
820 results
[resultsAmount
++] = address
;
825 if ( result
!= KERN_PROTECTION_FAILURE
)
827 CMLog( @
"vm_read_overwrite returned error: %i", result
);
833 realloc( results
, TCAddressSize
*resultsAmount
);
834 [searchResults addObject
:[SearchResults resultsWithType
:TYPE_INTEGER size
:SIZE_8_BIT data
:results amount
:resultsAmount
]];
836 CMLog( @
"found %i of %i", resultsAmount
, value
);
839 - (void)searchIntegerShort
:(int16_t
)value
841 kern_return_t result
;
844 vm_size_t dataLength
;
847 int resultsAmount
= 0;
849 SearchResults
*lastResults
= [searchResults lastObject
];
850 TCaddress
*lastResultsData
= [lastResults data
];
851 int i
, lastResultsAmount
= [lastResults amount
];
853 if ( [lastResults type
] != TYPE_INTEGER ||
[lastResults size
] != SIZE_16_BIT
)
855 [self sendError
:@
"This search is incompatible with the previous search." fatal
:NO
];
859 if ( (results
= (TCaddress
*)malloc( TCAddressSize
*lastResultsAmount
)) == NULL
)
861 CMLog( @
"ERROR: could not create buffer" );
863 [self sendError
:@
"The server cancelled the search because it ran out of memory." fatal
:NO
];
867 for ( i
= 0; i
< lastResultsAmount
; i
++ )
869 TCaddress address
= lastResultsData
[i
];
871 dataLength
= sizeof(data
);
873 if ( (result
= vm_read_overwrite( processTask
, address
, sizeof(data
), (vm_address_t
)(&data
), &dataLength
)) == KERN_SUCCESS
)
877 results
[resultsAmount
++] = address
;
882 if ( result
!= KERN_PROTECTION_FAILURE
)
884 CMLog( @
"vm_read_overwrite returned error: %i", result
);
890 realloc( results
, TCAddressSize
*resultsAmount
);
891 [searchResults addObject
:[SearchResults resultsWithType
:TYPE_INTEGER size
:SIZE_16_BIT data
:results amount
:resultsAmount
]];
893 CMLog( @
"found %i of %i", resultsAmount
, value
);
896 - (void)searchIntegerLong
:(int32_t
)value
898 kern_return_t result
;
901 vm_size_t dataLength
;
904 int resultsAmount
= 0;
906 SearchResults
*lastResults
= [searchResults lastObject
];
907 TCaddress
*lastResultsData
= [lastResults data
];
908 int i
, lastResultsAmount
= [lastResults amount
];
910 if ( [lastResults type
] != TYPE_INTEGER ||
[lastResults size
] != SIZE_32_BIT
)
912 [self sendError
:@
"This search is incompatible with the previous search." fatal
:NO
];
916 if ( (results
= (TCaddress
*)malloc( TCAddressSize
*lastResultsAmount
)) == NULL
)
918 CMLog( @
"ERROR: could not create buffer" );
920 [self sendError
:@
"The server cancelled the search because it ran out of memory." fatal
:NO
];
924 for ( i
= 0; i
< lastResultsAmount
; i
++ )
926 TCaddress address
= lastResultsData
[i
];
928 dataLength
= sizeof(data
);
930 if ( (result
= vm_read_overwrite( processTask
, address
, sizeof(data
), (vm_address_t
)(&data
), &dataLength
)) == KERN_SUCCESS
)
934 results
[resultsAmount
++] = address
;
939 if ( result
!= KERN_PROTECTION_FAILURE
)
941 CMLog( @
"vm_read_overwrite returned error: %i", result
);
947 realloc( results
, TCAddressSize
*resultsAmount
);
948 [searchResults addObject
:[SearchResults resultsWithType
:TYPE_INTEGER size
:SIZE_32_BIT data
:results amount
:resultsAmount
]];
950 CMLog( @
"found %i of %i", resultsAmount
, value
);
953 - (void)searchDecimalFloat
:(float)value
955 kern_return_t result
;
958 vm_size_t dataLength
;
961 int resultsAmount
= 0;
963 SearchResults
*lastResults
= [searchResults lastObject
];
964 TCaddress
*lastResultsData
= [lastResults data
];
965 int i
, lastResultsAmount
= [lastResults amount
];
967 if ( [lastResults type
] != TYPE_DECIMAL ||
[lastResults size
] != SIZE_32_BIT
)
969 [self sendError
:@
"This search is incompatible with the previous search." fatal
:NO
];
973 if ( (results
= (TCaddress
*)malloc( TCAddressSize
*lastResultsAmount
)) == NULL
)
975 CMLog( @
"ERROR: could not create buffer" );
977 [self sendError
:@
"The server cancelled the search because it ran out of memory." fatal
:NO
];
981 for ( i
= 0; i
< lastResultsAmount
; i
++ )
983 TCaddress address
= lastResultsData
[i
];
985 dataLength
= sizeof(data
);
987 if ( (result
= vm_read_overwrite( processTask
, address
, sizeof(data
), (vm_address_t
)(&data
), &dataLength
)) == KERN_SUCCESS
)
989 if ( CMCompareFloatsWithEpsilon( data
, value
, 0.1f
) == 0 )
991 results
[resultsAmount
++] = address
;
996 if ( result
!= KERN_PROTECTION_FAILURE
)
998 CMLog( @
"vm_read_overwrite returned error: %i", result
);
1004 realloc( results
, TCAddressSize
*resultsAmount
);
1005 [searchResults addObject
:[SearchResults resultsWithType
:TYPE_DECIMAL size
:SIZE_32_BIT data
:results amount
:resultsAmount
]];
1007 CMLog( @
"found %i of %i", resultsAmount
, value
);
1010 - (void)searchDecimalDouble
:(double)value
1012 kern_return_t result
;
1015 vm_size_t dataLength
;
1018 int resultsAmount
= 0;
1020 SearchResults
*lastResults
= [searchResults lastObject
];
1021 TCaddress
*lastResultsData
= [lastResults data
];
1022 int i
, lastResultsAmount
= [lastResults amount
];
1024 if ( [lastResults type
] != TYPE_DECIMAL ||
[lastResults size
] != SIZE_64_BIT
)
1026 [self sendError
:@
"This search is incompatible with the previous search." fatal
:NO
];
1030 if ( (results
= (TCaddress
*)malloc( TCAddressSize
*lastResultsAmount
)) == NULL
)
1032 CMLog( @
"ERROR: could not create buffer" );
1034 [self sendError
:@
"The server cancelled the search because it ran out of memory." fatal
:NO
];
1038 for ( i
= 0; i
< lastResultsAmount
; i
++ )
1040 TCaddress address
= lastResultsData
[i
];
1042 dataLength
= sizeof(data
);
1044 if ( (result
= vm_read_overwrite( processTask
, address
, sizeof(data
), (vm_address_t
)(&data
), &dataLength
)) == KERN_SUCCESS
)
1046 if ( CMCompareDoublesWithEpsilon( data
, value
, 0.1 ) == 0 )
1048 results
[resultsAmount
++] = address
;
1053 if ( result
!= KERN_PROTECTION_FAILURE
)
1055 CMLog( @
"vm_read_overwrite returned error: %i", result
);
1061 realloc( results
, TCAddressSize
*resultsAmount
);
1062 [searchResults addObject
:[SearchResults resultsWithType
:TYPE_DECIMAL size
:SIZE_64_BIT data
:results amount
:resultsAmount
]];
1064 CMLog( @
"found %i of %i", resultsAmount
, value
);
1068 - (void)changeString8bit
:(char const *)value size
:(int)vsize addresses
:(TCaddress
*)addresses count
:(int)count
1073 for ( i
= 0; i
< count
; i
++ )
1075 if ( vm_write( processTask
, (vm_address_t
)addresses
[i
], (vm_offset_t
)value
, vsize
) != KERN_SUCCESS
)
1081 if ( failCount
> 0 )
1083 [self sendError
:[NSString stringWithFormat
:@
"%i of the selected variables could not be changed.", failCount
] fatal
:NO
];
1087 - (void)changeIntegerChar
:(int8_t
)value addresses
:(TCaddress
*)addresses count
:(int)count
1092 for ( i
= 0; i
< count
; i
++ )
1094 if ( vm_write( processTask
, (vm_address_t
)addresses
[i
], (vm_offset_t
)(&value
), sizeof(value
) ) != KERN_SUCCESS
)
1100 if ( failCount
> 0 )
1102 [self sendError
:[NSString stringWithFormat
:@
"%i of the selected variables could not be changed.", failCount
] fatal
:NO
];
1106 - (void)changeIntegerShort
:(int16_t
)value addresses
:(TCaddress
*)addresses count
:(int)count
1111 for ( i
= 0; i
< count
; i
++ )
1113 if ( vm_write( processTask
, (vm_address_t
)addresses
[i
], (vm_offset_t
)(&value
), sizeof(value
) ) != KERN_SUCCESS
)
1119 if ( failCount
> 0 )
1121 [self sendError
:[NSString stringWithFormat
:@
"%i of the selected variables could not be changed.", failCount
] fatal
:NO
];
1125 - (void)changeIntegerLong
:(int32_t
)value addresses
:(TCaddress
*)addresses count
:(int)count
1130 for ( i
= 0; i
< count
; i
++ )
1132 if ( vm_write( processTask
, (vm_address_t
)addresses
[i
], (vm_offset_t
)(&value
), sizeof(value
) ) != KERN_SUCCESS
)
1138 if ( failCount
> 0 )
1140 [self sendError
:[NSString stringWithFormat
:@
"%i of the selected variables could not be changed.", failCount
] fatal
:NO
];
1144 - (void)changeDecimalFloat
:(float)value addresses
:(TCaddress
*)addresses count
:(int)count
1149 for ( i
= 0; i
< count
; i
++ )
1151 if ( vm_write( processTask
, (vm_address_t
)addresses
[i
], (vm_offset_t
)(&value
), sizeof(value
) ) != KERN_SUCCESS
)
1157 if ( failCount
> 0 )
1159 [self sendError
:[NSString stringWithFormat
:@
"%i of the selected variables could not be changed.", failCount
] fatal
:NO
];
1163 - (void)changeDecimalDouble
:(double)value addresses
:(TCaddress
*)addresses count
:(int)count
1168 for ( i
= 0; i
< count
; i
++ )
1170 if ( vm_write( processTask
, (vm_address_t
)addresses
[i
], (vm_offset_t
)(&value
), sizeof(value
) ) != KERN_SUCCESS
)
1176 if ( failCount
> 0 )
1178 [self sendError
:[NSString stringWithFormat
:@
"%i of the selected variables could not be changed.", failCount
] fatal
:NO
];
1183 - (void)sendProcessList
1185 NSArray
*processList
= [rootProxy serverProcessList
];
1191 PacketHeader header
;
1196 int length
= sizeof(u_int32_t
);
1199 u_int32_t processCount
= [processList count
];
1201 int i
, max
= processCount
;
1203 header.checksum
= RandomChecksum();
1204 header.function
= 2;
1206 for ( i
= 0; i
< max
; i
++ )
1208 pid
= [[processList objectAtIndex
:i
] objectForKey
:@
"NSApplicationProcessIdentifier"];
1209 name
= [[processList objectAtIndex
:i
] objectForKey
:@
"NSApplicationName"];
1212 length
+= sizeof(u_int32_t
) + [name length
] + 1;
1215 header.size
= length
;
1216 length
+= sizeof(header
);
1219 if ( (buffer
= (char *)malloc( length
))==NULL
)
1221 CMLog( @
"sendProcessList failed" );
1227 COPY_TO_BUFFER( ptr
, &header
, sizeof(header
) );
1228 COPY_TO_BUFFER( ptr
, &processCount
, sizeof(processCount
) );
1230 for ( i
= 0; i
< max
; i
++ )
1232 pidNum
= [[[processList objectAtIndex
:i
] objectForKey
:@
"NSApplicationProcessIdentifier"] unsignedLongValue
];
1233 name
= [[processList objectAtIndex
:i
] objectForKey
:@
"NSApplicationName"];
1235 COPY_TO_BUFFER( ptr
, &pidNum
, sizeof(pid
) );
1236 COPY_TO_BUFFER( ptr
, [name lossyCString
], [name length
] + 1 );
1239 lengthAfter
= length
;
1241 if ( SendBuffer( sockfd
, buffer
, &lengthAfter
) == -1 || lengthAfter
!= length
)
1243 CMLog( @
"sendProcessList failed" );
1250 - (void)sendSearchFinished
1252 PacketHeader header
;
1253 int length
= sizeof(header
);
1255 header.checksum
= RandomChecksum();
1256 header.function
= 6;
1259 if ( SendBuffer( sockfd
, (char *)(&header
), &length
) == -1 || length
!= sizeof(header
) )
1261 CMLog( @
"sendSearchFinished failed" );
1265 - (void)sendVariableList
:(TCaddress
const *)data amount
:(int)amount
1267 PacketHeader header
;
1270 int displayAmount
= ( searchResultsAmountDisplayed
> amount
)? amount
: searchResultsAmountDisplayed
;
1271 int resultsLength
= TCAddressSize
* displayAmount
;
1275 header.checksum
= RandomChecksum();
1276 header.function
= 7;
1277 header.size
= sizeof(amount
) + sizeof(displayAmount
) + resultsLength
;
1278 // AMOUNT DISPLAY AMOUNT DATA
1280 lengthAfter
= length
= header.size
+ sizeof(header
);
1282 if ( (buffer
= (char *)malloc( length
)) == NULL
)
1284 CMLog( @
"sendVariableList:amount: failed" );
1290 COPY_TO_BUFFER( ptr
, &header
, sizeof(header
) );
1291 COPY_TO_BUFFER( ptr
, &amount
, sizeof(amount
) );
1292 COPY_TO_BUFFER( ptr
, &displayAmount
, sizeof(displayAmount
) );
1293 COPY_TO_BUFFER( ptr
, data
, resultsLength
);
1295 if ( SendBuffer( sockfd
, buffer
, &length
) == -1 || lengthAfter
!= length
)
1297 CMLog( @
"sendVariableList:amount: failed" );
1302 CMLog( @
"SERVER sending %i out of %i results", displayAmount
, amount
);
1305 - (void)sendChangeFinished
1307 PacketHeader header
;
1308 int length
= sizeof(header
);
1310 header.checksum
= RandomChecksum();
1311 header.function
= 9;
1314 if ( SendBuffer( sockfd
, (char *)(&header
), &length
) == -1 || length
!= sizeof(header
) )
1316 CMLog( @
"sendChangeFinished failed" );
1320 - (void)sendError
:(NSString
*)msg fatal
:(BOOL)fatal
1322 PacketHeader header
;
1326 u_int32_t type
= (fatal
)?
1:0;
1330 header.checksum
= RandomChecksum();
1331 header.function
= 11;
1332 header.size
= sizeof(type
) + [msg length
] + 1;
1335 lengthAfter
= length
= header.size
+ sizeof(header
);
1337 if ( (buffer
= (char *)malloc( length
)) == NULL
)
1339 CMLog( @
"sendError:fatal: failed" );
1345 COPY_TO_BUFFER( ptr
, &header
, sizeof(header
) );
1346 COPY_TO_BUFFER( ptr
, &type
, sizeof(type
) );
1347 COPY_TO_BUFFER( ptr
, [msg lossyCString
], [msg length
] + 1 );
1349 if ( SendBuffer( sockfd
, buffer
, &length
) == -1 || lengthAfter
!= length
)
1351 CMLog( @
"sendError:fatal: failed" );
1357 - (void)sendVariableValue
:(u_int32_t
)index
1362 - (void)sendUndoFinished
1364 PacketHeader header
;
1365 int length
= sizeof(header
);
1367 header.checksum
= RandomChecksum();
1368 header.function
= 15;
1371 if ( SendBuffer( sockfd
, (char *)(&header
), &length
) == -1 || length
!= sizeof(header
) )
1373 CMLog( @
"sendUndoFinished failed" );
1377 - (void)sendRedoFinished
1379 PacketHeader header
;
1380 int length
= sizeof(header
);
1382 header.checksum
= RandomChecksum();
1383 header.function
= 17;
1386 if ( SendBuffer( sockfd
, (char *)(&header
), &length
) == -1 || length
!= sizeof(header
) )
1388 CMLog( @
"sendRedoFinished failed" );
1392 - (void)sendUndoRedoStatus
1394 PacketHeader header
;
1398 u_int32_t undoCount
= (u_int32_t
)[searchResults count
];
1399 u_int32_t redoCount
= (u_int32_t
)[searchResultsUndone count
];
1403 header.checksum
= RandomChecksum();
1404 header.function
= 19;
1405 header.size
= 2 * sizeof(u_int32_t
);
1407 length
= lengthAfter
= sizeof(header
) + header.size
;
1409 if ( (buffer
= (char *)malloc( length
)) == NULL
)
1411 CMLog( @
"sendSetTargetPID: failed" );
1416 COPY_TO_BUFFER( ptr
, &header
, sizeof(header
) );
1417 COPY_TO_BUFFER( ptr
, &undoCount
, sizeof(undoCount
) );
1418 COPY_TO_BUFFER( ptr
, &redoCount
, sizeof(redoCount
) );
1420 if ( SendBuffer( sockfd
, buffer
, &lengthAfter
) == -1 || lengthAfter
!= length
)
1422 CMLog( @
"sendUndoRedoStatus: failed" );
1428 - (void)sendAppLaunched
:(NSDictionary
*)appInfo
1430 PacketHeader header
;
1437 u_int32_t pid
= [[appInfo objectForKey
:@
"NSApplicationProcessIdentifier"] unsignedLongValue
];
1438 NSString
*name
= [appInfo objectForKey
:@
"NSApplicationName"];
1441 length
+= sizeof(u_int32_t
) + [name length
] + 1;
1443 header.checksum
= RandomChecksum();
1444 header.function
= 21;
1445 header.size
= length
;
1447 length
+= sizeof(header
);
1450 if ( (buffer
= (char *)malloc( length
))==NULL
)
1452 CMLog( @
"sendAppLaunched: failed" );
1459 COPY_TO_BUFFER( ptr
, &header
, sizeof(header
) );
1460 COPY_TO_BUFFER( ptr
, &pid
, sizeof(pid
) );
1461 COPY_TO_BUFFER( ptr
, [name lossyCString
], [name length
] + 1 );
1463 lengthAfter
= length
;
1465 if ( SendBuffer( sockfd
, buffer
, &lengthAfter
) == -1 || lengthAfter
!= length
)
1467 CMLog( @
"sendAppLaunched: failed" );
1474 - (void)sendAppQuit
:(NSDictionary
*)appInfo
1476 PacketHeader header
;
1483 u_int32_t pid
= [[appInfo objectForKey
:@
"NSApplicationProcessIdentifier"] unsignedLongValue
];
1486 length
+= sizeof(pid
);
1488 header.checksum
= RandomChecksum();
1489 header.function
= 22;
1490 header.size
= length
;
1492 length
+= sizeof(header
);
1495 if ( (buffer
= (char *)malloc( length
))==NULL
)
1497 CMLog( @
"sendAppQuit: failed" );
1504 COPY_TO_BUFFER( ptr
, &header
, sizeof(header
) );
1505 COPY_TO_BUFFER( ptr
, &pid
, sizeof(pid
) );
1507 lengthAfter
= length
;
1509 if ( SendBuffer( sockfd
, buffer
, &lengthAfter
) == -1 || lengthAfter
!= length
)
1511 CMLog( @
"sendAppQuit: failed" );
1517 - (void)sendTargetAppQuit
1519 PacketHeader header
;
1520 int length
= sizeof(header
);
1522 header.checksum
= RandomChecksum();
1523 header.function
= 23;
1526 if ( SendBuffer( sockfd
, (char *)(&header
), &length
) == -1 || length
!= sizeof(header
) )
1528 CMLog( @
"sendTargetAppQuit failed" );
1532 - (void)sendPauseFinished
:(BOOL)paused
1534 PacketHeader header
;
1539 int length
= sizeof(paused
);
1542 header.checksum
= RandomChecksum();
1543 header.function
= 24;
1544 header.size
= length
;
1546 length
+= sizeof(header
);
1549 if ( (buffer
= (char *)malloc( length
))==NULL
)
1551 CMLog( @
"sendPauseFinished: failed" );
1558 COPY_TO_BUFFER( ptr
, &header
, sizeof(header
) );
1559 COPY_TO_BUFFER( ptr
, &paused
, sizeof(paused
) );
1561 lengthAfter
= length
;
1563 if ( SendBuffer( sockfd
, buffer
, &lengthAfter
) == -1 || lengthAfter
!= length
)
1565 CMLog( @
"sendPauseFinished: failed" );
1572 - (void)handleClearSearch
1574 [searchResults removeAllObjects
];
1575 [searchResultsUndone removeAllObjects
];
1580 - (void)handleSearch
:(char const *)data size
:(int)dataSize
1585 char *ptr
= (char *)data
;
1587 [self setAction
:@
"Searching"];
1589 COPY_FROM_BUFFER( &type
, ptr
, sizeof(type
) );
1590 COPY_FROM_BUFFER( &size
, ptr
, sizeof(size
) );
1592 // receive the amount of results to return
1593 COPY_FROM_BUFFER( &searchResultsAmountDisplayed
, ptr
, sizeof(searchResultsAmountDisplayed
) );
1595 if ( ![searchResults lastObject
] )
1605 [self firstSearchString8bit
:ptr size
:(dataSize
- (ptr
- data
) - 1)];
1620 COPY_FROM_BUFFER( &value
, ptr
, sizeof(value
) );
1621 [self firstSearchIntegerChar
:value
];
1629 COPY_FROM_BUFFER( &value
, ptr
, sizeof(value
) );
1630 [self firstSearchIntegerShort
:value
];
1638 COPY_FROM_BUFFER( &value
, ptr
, sizeof(value
) );
1639 [self firstSearchIntegerLong
:value
];
1654 COPY_FROM_BUFFER( &value
, ptr
, sizeof(value
) );
1655 [self firstSearchDecimalFloat
:value
];
1663 COPY_FROM_BUFFER( &value
, ptr
, sizeof(value
) );
1664 [self firstSearchDecimalDouble
:value
];
1682 [self searchString8bit
:ptr size
:(dataSize
- (ptr
- data
))];
1698 COPY_FROM_BUFFER( &value
, ptr
, sizeof(value
) );
1699 [self searchIntegerChar
:value
];
1708 COPY_FROM_BUFFER( &value
, ptr
, sizeof(value
) );
1709 [self searchIntegerShort
:value
];
1718 COPY_FROM_BUFFER( &value
, ptr
, sizeof(value
) );
1719 [self searchIntegerLong
:value
];
1735 COPY_FROM_BUFFER( &value
, ptr
, sizeof(value
) );
1736 [self searchDecimalFloat
:value
];
1744 COPY_FROM_BUFFER( &value
, ptr
, sizeof(value
) );
1745 [self searchDecimalDouble
:value
];
1754 [self sendVariableList
:[(SearchResults
*)[searchResults lastObject
] data
] amount
:[[searchResults lastObject
] amount
]];
1755 [self sendSearchFinished
];
1756 [self sendUndoRedoStatus
];
1758 [self setAction
:nil];
1761 - (void)handleChange
:(char const *)data size
:(int)dataSize
1766 TCaddress
*addresses
= NULL
;
1769 char *ptr
= (char *)data
;
1771 [self setAction
:@
"Changing"];
1773 // read out the type and size of the variable.
1774 COPY_FROM_BUFFER( &type
, ptr
, sizeof(type
) );
1775 COPY_FROM_BUFFER( &size
, ptr
, sizeof(size
) );
1777 // read the amount of addresses.
1778 COPY_FROM_BUFFER( &count
, ptr
, sizeof(count
) );
1780 // save the pointer to the addresses.
1781 addresses
= (TCaddress
*)ptr
;
1782 ptr
+= TCAddressSize
*count
;
1792 [self changeString8bit
:ptr size
:(dataSize
- (ptr
- data
)) addresses
:addresses count
:count
];
1807 COPY_FROM_BUFFER( &value
, ptr
, sizeof(value
) );
1808 [self changeIntegerChar
:value addresses
:addresses count
:count
];
1816 COPY_FROM_BUFFER( &value
, ptr
, sizeof(value
) );
1817 [self changeIntegerShort
:value addresses
:addresses count
:count
];
1825 COPY_FROM_BUFFER( &value
, ptr
, sizeof(value
) );
1826 [self changeIntegerLong
:value addresses
:addresses count
:count
];
1841 COPY_FROM_BUFFER( &value
, ptr
, sizeof(value
) );
1842 [self changeDecimalFloat
:value addresses
:addresses count
:count
];
1850 COPY_FROM_BUFFER( &value
, ptr
, sizeof(value
) );
1851 [self changeDecimalDouble
:value addresses
:addresses count
:count
];
1859 [self sendChangeFinished
];
1861 [self setAction
:nil];
1864 - (void)handlePauseTarget
1866 if ( !processPaused
)
1872 if ( ptrace( PT_ATTACH
, processID
, 0, 0 ) != -1 )
1874 if ( waitpid( processID
, &wait_status
, WUNTRACED
) == processID
)
1876 if ( WIFSTOPPED(wait_status
) )
1878 processPaused
= YES
;
1879 [self sendPauseFinished
:YES
];
1883 CMLog( @
"ERROR: process couldn't be paused" );
1884 [self sendPauseFinished
:NO
];
1885 [self sendError
:@
"Could not pause target because of an unknown error." fatal
:NO
];
1890 CMLog( @
"ERROR: process couldn't be paused" );
1891 [self sendPauseFinished
:NO
];
1892 [self sendError
:@
"Could not pause target because of an unknown error." fatal
:NO
];
1897 CMLog( @
"ERROR: process couldn't be paused" );
1898 [self sendPauseFinished
:NO
];
1903 [self sendError
:@
"Could not pause target because there is no valid target to pause." fatal
:NO
];
1907 [self sendError
:@
"Could not pause target because a process cannot pause itself." fatal
:NO
];
1911 [self sendError
:@
"Could not pause target because the target is being controlled by another instance or application." fatal
:NO
];
1915 [self sendError
:@
"Could not pause target because this type of application cannot be paused." fatal
:NO
];
1919 [self sendError
:@
"Could not pause target because of an unknown error." fatal
:NO
];
1926 [self sendPauseFinished
:NO
];
1927 [self sendError
:[NSString stringWithFormat
:@
"Could not pause target because an exception (%@) was raised: %@", [localException name
], [localException reason
]] fatal
:NO
];
1933 ptrace( PT_DETACH
, processID
, 0, 0 );
1936 [self sendPauseFinished
:NO
];
1942 SearchResults
*results
= [searchResults lastObject
];
1946 [searchResultsUndone addObject
:results
];
1947 [searchResults removeLastObject
];
1950 results
= [searchResults lastObject
];
1953 [self sendVariableList
:[results data
] amount
:[results amount
]];
1957 [self sendVariableList
:NULL amount
:0];
1960 [self sendUndoFinished
];
1961 [self sendUndoRedoStatus
];
1966 SearchResults
*results
= [searchResultsUndone lastObject
];
1970 [searchResults addObject
:results
];
1971 [searchResultsUndone removeLastObject
];
1974 results
= [searchResults lastObject
];
1977 [self sendVariableList
:[results data
] amount
:[results amount
]];
1981 [self sendVariableList
:NULL amount
:0];
1984 [self sendRedoFinished
];
1985 [self sendUndoRedoStatus
];
1988 - (void)handleSetTargetPID
:(char const *)data size
:(int)size
1990 char *ptr
= (char *)data
;
1994 COPY_FROM_BUFFER( &pid
, ptr
, sizeof(pid
) );
2002 if ( processPaused
)
2004 [self handlePauseTarget
];
2008 - (void)setPID
:(pid_t
)pid
2010 kern_return_t result
;
2016 if ( (result
= task_for_pid( current_task(), processID
, &processTask
)) != KERN_SUCCESS
)
2018 CMLog( @
"task_for_pid returned error: %i", result
);
2027 [[[NSWorkspace sharedWorkspace
] notificationCenter
] removeObserver
:self];
2029 [searchResults release
];
2030 [searchResultsUndone release
];
2036 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2037 %%%%%%%%%%%%%%%%%%%%%% NSWorkspaceDidLaunchApplicationNotification Notification
2038 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
2041 - (void)processListChanged
:(NSNotification
*)note
2043 pid_t pid
= [[[note userInfo
] objectForKey
:@
"NSApplicationProcessIdentifier"] intValue
];
2045 if ( /*pid != getpid()*/ sockfd
!= -1 )
2047 if ( [[note name
] isEqualToString
:@
"NSWorkspaceDidLaunchApplicationNotification"] )
2049 [self sendAppLaunched
:[note userInfo
]];
2053 [self sendAppQuit
:[note userInfo
]];
2055 if ( pid
== processID
)
2057 [self sendTargetAppQuit
];
2059 // we can't set the new target here because this method is not called
2060 // in the server thread. the client will have to change it.
2061 //[self setPID:[rootProxy serverFirstProcess]];
2072 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2073 %%%%%%%%%%%%%%%%%%%%%% Internal Functions
2074 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
2078 int bmsearch( char *pat
, int m
, char *text
, int n
, void *base
, void *loc
[] )
2081 int i
, j
, k
, skip
[ASIZE
];
2083 if( m
==0 ) return 0;
2084 for( k
=0; k
<ASIZE
; k
++ ) skip
[k
] = m
;
2085 for( k
=0; k
<m
-1; k
++ ) skip
[(int)pat
[k
]] = m
-k
-1;
2087 for( k
=m
-1; k
< n
; k
+= skip
[(int)text
[k
] & (ASIZE
-1)] ) {
2088 for( j
=m
-1, i
=k
; j
>=0 && text
[i
] == pat
[j
]; j
-- ) i
--;
2091 loc
[count
++] = (void *)( base
+i
+1 );
2092 //return( text+i+1 );
2098 BOOL compare_float( float a, float b )
2100 float const feps = 0.0001f;
2102 return feps > fabsf( a - b );
2105 BOOL compare_double( double a, double b )
2107 double const deps = 0.0000001;
2109 return deps > fabs( a - b );