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 NSLog( @
"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 NSLog( @
"ERROR: getpeername() failed" );
110 if ( (addressCString
= inet_ntoa( addr.sin_addr
)) == NULL
)
112 NSLog( @
"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 NSLog( @
"ERROR: getpeername() failed" );
128 NSLog( @
"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 NSLog( @
"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 NSLog( @
"checksum failed" );
179 if ( header.size
!= 0 )
181 if ( (data
= (char *)malloc( header.size
)) == NULL
)
183 NSLog( @
"failed to allocate buffer for reading a network packet" );
187 if ( (result
= ReadBuffer( sockfd
, data
, header.size
)) != header.size
)
189 NSLog( @
"failed to read the data of a network packet" );
195 //NSLog( @"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 NSLog( @
"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 NSLog( @
"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 NSLog( @
"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 NSLog( @
"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 NSLog( @
"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 NSLog( @
"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 NSLog( @
"vm_read_overwrite returned error: %i", result
);
378 if ( result
== KERN_SUCCESS
)
382 if ( (results
= (TCaddress
*)realloc( results
, TCAddressSize
*resultsAmount
+ TCAddressSize
*dataLength
)) == NULL
)
384 NSLog( @
"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 NSLog( @
"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 NSLog( @
"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 NSLog( @
"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 NSLog( @
"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 NSLog( @
"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 NSLog( @"malloc_get_all_zones error: %i", result );
505 //address = zones[0];
509 for ( i = 0; i < 10; i++ )
511 NSLog( @"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 NSLog( @
"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 //NSLog( @"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 NSLog( @
"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 NSLog( @
"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 NSLog( @
"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 NSLog( @
"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 NSLog( @
"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 NSLog( @
"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 NSLog( @
"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 NSLog( @
"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 NSLog( @
"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 NSLog( @
"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 NSLog( @
"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 NSLog( @
"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 NSLog( @
"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 NSLog( @
"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 NSLog( @
"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 NSLog( @
"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 NSLog( @
"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 NSLog( @
"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 NSLog( @
"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 NSLog( @
"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 NSLog( @
"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 NSLog( @
"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 NSLog( @
"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 NSLog( @
"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 NSLog( @
"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 NSLog( @
"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 NSLog( @
"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 NSLog( @
"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 NSLog( @
"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 NSLog( @
"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 NSLog( @
"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 NSLog( @
"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 NSLog( @
"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 NSLog( @
"sendSearchFinished failed" );
1265 - (void)sendVariableList
:(TCaddress
const *)data amount
:(int)amount
1267 PacketHeader header
;
1273 header.checksum
= RandomChecksum();
1274 header.function
= 7;
1275 header.size
= sizeof(amount
) + sizeof(maxSearchResultsAmount
) + TCAddressSize
*maxSearchResultsAmount
;
1276 // AMOUNT MAX AMOUNT DATA
1278 lengthAfter
= length
= header.size
+ sizeof(header
);
1280 if ( (buffer
= (char *)malloc( length
)) == NULL
)
1282 NSLog( @
"sendVariableList:amount: failed" );
1288 COPY_TO_BUFFER( ptr
, &header
, sizeof(header
) );
1289 COPY_TO_BUFFER( ptr
, &amount
, sizeof(amount
) );
1290 COPY_TO_BUFFER( ptr
, &maxSearchResultsAmount
, sizeof(maxSearchResultsAmount
) );
1291 COPY_TO_BUFFER( ptr
, data
, TCAddressSize
*maxSearchResultsAmount
);
1293 if ( SendBuffer( sockfd
, buffer
, &length
) == -1 || lengthAfter
!= length
)
1295 NSLog( @
"sendVariableList:amount: failed" );
1301 - (void)sendChangeFinished
1303 PacketHeader header
;
1304 int length
= sizeof(header
);
1306 header.checksum
= RandomChecksum();
1307 header.function
= 9;
1310 if ( SendBuffer( sockfd
, (char *)(&header
), &length
) == -1 || length
!= sizeof(header
) )
1312 NSLog( @
"sendChangeFinished failed" );
1316 - (void)sendError
:(NSString
*)msg fatal
:(BOOL)fatal
1318 PacketHeader header
;
1322 u_int32_t type
= (fatal
)?
1:0;
1326 header.checksum
= RandomChecksum();
1327 header.function
= 11;
1328 header.size
= sizeof(type
) + [msg length
] + 1;
1331 lengthAfter
= length
= header.size
+ sizeof(header
);
1333 if ( (buffer
= (char *)malloc( length
)) == NULL
)
1335 NSLog( @
"sendError:fatal: failed" );
1341 COPY_TO_BUFFER( ptr
, &header
, sizeof(header
) );
1342 COPY_TO_BUFFER( ptr
, &type
, sizeof(type
) );
1343 COPY_TO_BUFFER( ptr
, [msg lossyCString
], [msg length
] + 1 );
1345 if ( SendBuffer( sockfd
, buffer
, &length
) == -1 || lengthAfter
!= length
)
1347 NSLog( @
"sendError:fatal: failed" );
1353 - (void)sendVariableValue
:(u_int32_t
)index
1358 - (void)sendUndoFinished
1360 PacketHeader header
;
1361 int length
= sizeof(header
);
1363 header.checksum
= RandomChecksum();
1364 header.function
= 15;
1367 if ( SendBuffer( sockfd
, (char *)(&header
), &length
) == -1 || length
!= sizeof(header
) )
1369 NSLog( @
"sendUndoFinished failed" );
1373 - (void)sendRedoFinished
1375 PacketHeader header
;
1376 int length
= sizeof(header
);
1378 header.checksum
= RandomChecksum();
1379 header.function
= 17;
1382 if ( SendBuffer( sockfd
, (char *)(&header
), &length
) == -1 || length
!= sizeof(header
) )
1384 NSLog( @
"sendRedoFinished failed" );
1388 - (void)sendUndoRedoStatus
1390 PacketHeader header
;
1394 u_int32_t undoCount
= (u_int32_t
)[searchResults count
];
1395 u_int32_t redoCount
= (u_int32_t
)[searchResultsUndone count
];
1399 header.checksum
= RandomChecksum();
1400 header.function
= 19;
1401 header.size
= 2 * sizeof(u_int32_t
);
1403 length
= lengthAfter
= sizeof(header
) + header.size
;
1405 if ( (buffer
= (char *)malloc( length
)) == NULL
)
1407 NSLog( @
"sendSetTargetPID: failed" );
1412 COPY_TO_BUFFER( ptr
, &header
, sizeof(header
) );
1413 COPY_TO_BUFFER( ptr
, &undoCount
, sizeof(undoCount
) );
1414 COPY_TO_BUFFER( ptr
, &redoCount
, sizeof(redoCount
) );
1416 if ( SendBuffer( sockfd
, buffer
, &lengthAfter
) == -1 || lengthAfter
!= length
)
1418 NSLog( @
"sendUndoRedoStatus: failed" );
1424 - (void)sendAppLaunched
:(NSDictionary
*)appInfo
1426 PacketHeader header
;
1433 u_int32_t pid
= [[appInfo objectForKey
:@
"NSApplicationProcessIdentifier"] unsignedLongValue
];
1434 NSString
*name
= [appInfo objectForKey
:@
"NSApplicationName"];
1437 length
+= sizeof(u_int32_t
) + [name length
] + 1;
1439 header.checksum
= RandomChecksum();
1440 header.function
= 21;
1441 header.size
= length
;
1443 length
+= sizeof(header
);
1446 if ( (buffer
= (char *)malloc( length
))==NULL
)
1448 NSLog( @
"sendAppLaunched: failed" );
1455 COPY_TO_BUFFER( ptr
, &header
, sizeof(header
) );
1456 COPY_TO_BUFFER( ptr
, &pid
, sizeof(pid
) );
1457 COPY_TO_BUFFER( ptr
, [name lossyCString
], [name length
] + 1 );
1459 lengthAfter
= length
;
1461 if ( SendBuffer( sockfd
, buffer
, &lengthAfter
) == -1 || lengthAfter
!= length
)
1463 NSLog( @
"sendAppLaunched: failed" );
1470 - (void)sendAppQuit
:(NSDictionary
*)appInfo
1472 PacketHeader header
;
1479 u_int32_t pid
= [[appInfo objectForKey
:@
"NSApplicationProcessIdentifier"] unsignedLongValue
];
1482 length
+= sizeof(pid
);
1484 header.checksum
= RandomChecksum();
1485 header.function
= 22;
1486 header.size
= length
;
1488 length
+= sizeof(header
);
1491 if ( (buffer
= (char *)malloc( length
))==NULL
)
1493 NSLog( @
"sendAppQuit: failed" );
1500 COPY_TO_BUFFER( ptr
, &header
, sizeof(header
) );
1501 COPY_TO_BUFFER( ptr
, &pid
, sizeof(pid
) );
1503 lengthAfter
= length
;
1505 if ( SendBuffer( sockfd
, buffer
, &lengthAfter
) == -1 || lengthAfter
!= length
)
1507 NSLog( @
"sendAppQuit: failed" );
1513 - (void)sendTargetAppQuit
1515 PacketHeader header
;
1516 int length
= sizeof(header
);
1518 header.checksum
= RandomChecksum();
1519 header.function
= 23;
1522 if ( SendBuffer( sockfd
, (char *)(&header
), &length
) == -1 || length
!= sizeof(header
) )
1524 NSLog( @
"sendTargetAppQuit failed" );
1528 - (void)sendPauseFinished
:(BOOL)paused
1530 PacketHeader header
;
1535 int length
= sizeof(paused
);
1538 header.checksum
= RandomChecksum();
1539 header.function
= 24;
1540 header.size
= length
;
1542 length
+= sizeof(header
);
1545 if ( (buffer
= (char *)malloc( length
))==NULL
)
1547 NSLog( @
"sendPauseFinished: failed" );
1554 COPY_TO_BUFFER( ptr
, &header
, sizeof(header
) );
1555 COPY_TO_BUFFER( ptr
, &paused
, sizeof(paused
) );
1557 lengthAfter
= length
;
1559 if ( SendBuffer( sockfd
, buffer
, &lengthAfter
) == -1 || lengthAfter
!= length
)
1561 NSLog( @
"sendPauseFinished: failed" );
1568 - (void)handleClearSearch
1570 [searchResults removeAllObjects
];
1571 [searchResultsUndone removeAllObjects
];
1576 - (void)handleSearch
:(char const *)data size
:(int)dataSize
1581 char *ptr
= (char *)data
;
1583 [self setAction
:@
"Searching"];
1585 COPY_FROM_BUFFER( &type
, ptr
, sizeof(type
) );
1586 COPY_FROM_BUFFER( &size
, ptr
, sizeof(size
) );
1588 COPY_FROM_BUFFER( &maxSearchResultsAmount
, ptr
, sizeof(maxSearchResultsAmount
) );
1590 if ( ![searchResults lastObject
] )
1600 [self firstSearchString8bit
:ptr size
:(dataSize
- (ptr
- data
) - 1)];
1615 COPY_FROM_BUFFER( &value
, ptr
, sizeof(value
) );
1616 [self firstSearchIntegerChar
:value
];
1624 COPY_FROM_BUFFER( &value
, ptr
, sizeof(value
) );
1625 [self firstSearchIntegerShort
:value
];
1633 COPY_FROM_BUFFER( &value
, ptr
, sizeof(value
) );
1634 [self firstSearchIntegerLong
:value
];
1649 COPY_FROM_BUFFER( &value
, ptr
, sizeof(value
) );
1650 [self firstSearchDecimalFloat
:value
];
1658 COPY_FROM_BUFFER( &value
, ptr
, sizeof(value
) );
1659 [self firstSearchDecimalDouble
:value
];
1677 [self searchString8bit
:ptr size
:(dataSize
- (ptr
- data
))];
1693 COPY_FROM_BUFFER( &value
, ptr
, sizeof(value
) );
1694 [self searchIntegerChar
:value
];
1703 COPY_FROM_BUFFER( &value
, ptr
, sizeof(value
) );
1704 [self searchIntegerShort
:value
];
1713 COPY_FROM_BUFFER( &value
, ptr
, sizeof(value
) );
1714 [self searchIntegerLong
:value
];
1730 COPY_FROM_BUFFER( &value
, ptr
, sizeof(value
) );
1731 [self searchDecimalFloat
:value
];
1739 COPY_FROM_BUFFER( &value
, ptr
, sizeof(value
) );
1740 [self searchDecimalDouble
:value
];
1749 [self sendVariableList
:[(SearchResults
*)[searchResults lastObject
] data
] amount
:[[searchResults lastObject
] amount
]];
1750 [self sendSearchFinished
];
1751 [self sendUndoRedoStatus
];
1753 [self setAction
:nil];
1756 - (void)handleChange
:(char const *)data size
:(int)dataSize
1761 TCaddress
*addresses
= NULL
;
1764 char *ptr
= (char *)data
;
1766 [self setAction
:@
"Changing"];
1768 // read out the type and size of the variable.
1769 COPY_FROM_BUFFER( &type
, ptr
, sizeof(type
) );
1770 COPY_FROM_BUFFER( &size
, ptr
, sizeof(size
) );
1772 // read the amount of addresses.
1773 COPY_FROM_BUFFER( &count
, ptr
, sizeof(count
) );
1775 // save the pointer to the addresses.
1776 addresses
= (TCaddress
*)ptr
;
1777 ptr
+= TCAddressSize
*count
;
1787 [self changeString8bit
:ptr size
:(dataSize
- (ptr
- data
)) addresses
:addresses count
:count
];
1802 COPY_FROM_BUFFER( &value
, ptr
, sizeof(value
) );
1803 [self changeIntegerChar
:value addresses
:addresses count
:count
];
1811 COPY_FROM_BUFFER( &value
, ptr
, sizeof(value
) );
1812 [self changeIntegerShort
:value addresses
:addresses count
:count
];
1820 COPY_FROM_BUFFER( &value
, ptr
, sizeof(value
) );
1821 [self changeIntegerLong
:value addresses
:addresses count
:count
];
1836 COPY_FROM_BUFFER( &value
, ptr
, sizeof(value
) );
1837 [self changeDecimalFloat
:value addresses
:addresses count
:count
];
1845 COPY_FROM_BUFFER( &value
, ptr
, sizeof(value
) );
1846 [self changeDecimalDouble
:value addresses
:addresses count
:count
];
1854 [self sendChangeFinished
];
1856 [self setAction
:nil];
1859 - (void)handlePauseTarget
1861 if ( !processPaused
)
1867 if ( ptrace( PT_ATTACH
, processID
, 0, 0 ) != -1 )
1869 if ( waitpid( processID
, &wait_status
, WUNTRACED
) == processID
)
1871 if ( WIFSTOPPED(wait_status
) )
1873 processPaused
= YES
;
1874 [self sendPauseFinished
:YES
];
1878 NSLog( @
"ERROR: process couldn't be paused" );
1879 [self sendPauseFinished
:NO
];
1880 [self sendError
:@
"Could not pause target because of an unknown error." fatal
:NO
];
1885 NSLog( @
"ERROR: process couldn't be paused" );
1886 [self sendPauseFinished
:NO
];
1887 [self sendError
:@
"Could not pause target because of an unknown error." fatal
:NO
];
1892 NSLog( @
"ERROR: process couldn't be paused" );
1893 [self sendPauseFinished
:NO
];
1898 [self sendError
:@
"Could not pause target because there is no valid target to pause." fatal
:NO
];
1902 [self sendError
:@
"Could not pause target because a process cannot pause itself." fatal
:NO
];
1906 [self sendError
:@
"Could not pause target because the target is being controlled by another instance or application." fatal
:NO
];
1910 [self sendError
:@
"Could not pause target because this type of application cannot be paused." fatal
:NO
];
1914 [self sendError
:@
"Could not pause target because of an unknown error." fatal
:NO
];
1921 [self sendPauseFinished
:NO
];
1922 [self sendError
:[NSString stringWithFormat
:@
"Could not pause target because an exception (%@) was raised: %@", [localException name
], [localException reason
]] fatal
:NO
];
1928 ptrace( PT_DETACH
, processID
, 0, 0 );
1931 [self sendPauseFinished
:NO
];
1937 SearchResults
*results
= [searchResults lastObject
];
1941 [searchResultsUndone addObject
:results
];
1942 [searchResults removeLastObject
];
1945 results
= [searchResults lastObject
];
1948 [self sendVariableList
:[results data
] amount
:[results amount
]];
1952 [self sendVariableList
:NULL amount
:0];
1955 [self sendUndoFinished
];
1956 [self sendUndoRedoStatus
];
1961 SearchResults
*results
= [searchResultsUndone lastObject
];
1965 [searchResults addObject
:results
];
1966 [searchResultsUndone removeLastObject
];
1969 results
= [searchResults lastObject
];
1972 [self sendVariableList
:[results data
] amount
:[results amount
]];
1976 [self sendVariableList
:NULL amount
:0];
1979 [self sendRedoFinished
];
1980 [self sendUndoRedoStatus
];
1983 - (void)handleSetTargetPID
:(char const *)data size
:(int)size
1985 char *ptr
= (char *)data
;
1989 COPY_FROM_BUFFER( &pid
, ptr
, sizeof(pid
) );
1997 if ( processPaused
)
1999 [self handlePauseTarget
];
2003 - (void)setPID
:(pid_t
)pid
2005 kern_return_t result
;
2011 if ( (result
= task_for_pid( current_task(), processID
, &processTask
)) != KERN_SUCCESS
)
2013 NSLog( @
"task_for_pid returned error: %i", result
);
2022 [[[NSWorkspace sharedWorkspace
] notificationCenter
] removeObserver
:self];
2024 [searchResults release
];
2025 [searchResultsUndone release
];
2031 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2032 %%%%%%%%%%%%%%%%%%%%%% NSWorkspaceDidLaunchApplicationNotification Notification
2033 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
2036 - (void)processListChanged
:(NSNotification
*)note
2038 pid_t pid
= [[[note userInfo
] objectForKey
:@
"NSApplicationProcessIdentifier"] intValue
];
2040 if ( /*pid != getpid()*/ sockfd
!= -1 )
2042 if ( [[note name
] isEqualToString
:@
"NSWorkspaceDidLaunchApplicationNotification"] )
2044 [self sendAppLaunched
:[note userInfo
]];
2048 [self sendAppQuit
:[note userInfo
]];
2050 if ( pid
== processID
)
2052 [self sendTargetAppQuit
];
2054 // we can't set the new target here because this method is not called
2055 // in the server thread. the client will have to change it.
2056 //[self setPID:[rootProxy serverFirstProcess]];
2067 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2068 %%%%%%%%%%%%%%%%%%%%%% Internal Functions
2069 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
2073 int bmsearch( char *pat
, int m
, char *text
, int n
, void *base
, void *loc
[] )
2076 int i
, j
, k
, skip
[ASIZE
];
2078 if( m
==0 ) return 0;
2079 for( k
=0; k
<ASIZE
; k
++ ) skip
[k
] = m
;
2080 for( k
=0; k
<m
-1; k
++ ) skip
[(int)pat
[k
]] = m
-k
-1;
2082 for( k
=m
-1; k
< n
; k
+= skip
[(int)text
[k
] & (ASIZE
-1)] ) {
2083 for( j
=m
-1, i
=k
; j
>=0 && text
[i
] == pat
[j
]; j
-- ) i
--;
2086 loc
[count
++] = (void *)( base
+i
+1 );
2087 //return( text+i+1 );
2093 BOOL compare_float( float a, float b )
2095 float const feps = 0.0001f;
2097 return feps > fabsf( a - b );
2100 BOOL compare_double( double a, double b )
2102 double const deps = 0.0000001;
2104 return deps > fabs( a - b );