]> Dogcows Code - chaz/thecheat/blob - CheatServer.m
The Cheat 1.1.2
[chaz/thecheat] / CheatServer.m
1
2 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3 // Project: The Cheat
4 //
5 // File: CheatServer.m
6 // Created: Sun Sep 07 2003
7 //
8 // Copyright: 2003 Chaz McGarvey. All rights reserved.
9 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10
11 #import "CheatServer.h"
12
13 #import "SearchResults.h"
14
15 // for comparing floats
16 #import <Chaz/Misc.h>
17
18 #include <string.h>
19 #include <math.h>
20 #include <errno.h>
21
22
23 // Internal Functions
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 );
27
28
29 @implementation CheatServer
30
31
32 + (NSConnection *)serverWithDelegate:(id)delegate socket:(int)sock
33 {
34 NSPort *rPort = [NSPort port], *sPort = [NSPort port];
35 NSConnection *connection;
36 NSArray *array;
37
38 connection = [[NSConnection alloc] initWithReceivePort:rPort sendPort:sPort];
39 [connection setRootObject:delegate];
40
41 array = [NSArray arrayWithObjects:sPort, rPort, [NSNumber numberWithInt:sock], nil];
42 [NSThread detachNewThreadSelector:@selector(serverThread:) toTarget:self withObject:array];
43
44 return [connection autorelease];
45 }
46
47 + (void)serverThread:(NSArray *)array
48 {
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]];
52
53 [object handleSocket:[[array objectAtIndex:2] intValue]];
54 [object run];
55
56 [object release];
57 [pool release];
58 }
59
60
61 - (id)initWithRootProxy:(id)proxy
62 {
63 if ( self = [super init] )
64 {
65 NSNotificationCenter *nc = [[NSWorkspace sharedWorkspace] notificationCenter];
66
67 rootProxy = proxy;
68
69 [nc addObserver:self selector:@selector(processListChanged:) name:@"NSWorkspaceDidLaunchApplicationNotification" object:nil];
70 [nc addObserver:self selector:@selector(processListChanged:) name:@"NSWorkspaceDidTerminateApplicationNotification" object:nil];
71
72 [self setPID:[rootProxy serverFirstProcess]];
73
74 processPaused = NO;
75
76 searchResults = [[NSMutableArray alloc] init];
77 searchResultsUndone = [[NSMutableArray alloc] init];
78 }
79
80 return self;
81 }
82
83
84 - (void)handleSocket:(int)sock
85 {
86 struct sockaddr identifier;
87 int addrLen = sizeof(identifier);
88
89 NSString *address;
90 char *addressCString;
91
92 sockfd = sock;
93
94 if ( getpeername( sockfd, &identifier, &addrLen ) == -1 )
95 {
96 CMLog( @"ERROR: getpeername() failed" );
97 }
98
99 if ( identifier.sa_family == AF_INET )
100 {
101 struct sockaddr_in addr;
102
103 addrLen = sizeof(addr);
104
105 if ( getpeername( sockfd, (struct sockaddr *)(&addr), &addrLen ) == -1 )
106 {
107 CMLog( @"ERROR: getpeername() failed" );
108 }
109
110 if ( (addressCString = inet_ntoa( addr.sin_addr )) == NULL )
111 {
112 CMLog( @"ERROR: inet_ntoa() failed" );
113 }
114
115 address = [NSString stringWithCString:addressCString];
116 }
117 else
118 {
119 struct sockaddr_un addr;
120
121 addrLen = sizeof(addr);
122
123 if ( getpeername( sockfd, (struct sockaddr *)(&addr), &addrLen ) == -1 )
124 {
125 CMLog( @"ERROR: getpeername() failed" );
126 }
127
128 CMLog( @"client connection: %s", addr.sun_path );
129
130 address = [NSString stringWithString:@"127.0.0.1"];
131 }
132
133 [rootProxy server:self connectedWithSocket:sockfd];
134
135 [self setAddress:address];
136 [self setAction:nil];
137 }
138
139 - (void)run
140 {
141 struct timeval tv;
142 fd_set fdset, master;
143 int numfds;
144
145 int result;
146
147 PacketHeader header;
148 char *data = NULL;
149
150 tv.tv_sec = 2;
151 tv.tv_usec = 0;
152
153 FD_ZERO( &fdset );
154 FD_ZERO( &master );
155 FD_SET( sockfd, &master );
156
157 numfds = sockfd + 1;
158
159 CMLog( @"SERVER start" );
160
161 for (;;)
162 {
163 fdset = master;
164
165 select( numfds, &fdset, NULL, NULL, &tv );
166
167 if ( FD_ISSET( sockfd, &fdset ) )
168 {
169 if ( (result = ReadBuffer( sockfd, (char *)(&header), sizeof(header) )) != sizeof(header) )
170 {
171 break;
172 }
173
174 if ( !VerifyChecksum( header.checksum ) )
175 {
176 CMLog( @"checksum failed" );
177 }
178
179 if ( header.size != 0 )
180 {
181 if ( (data = (char *)malloc( header.size )) == NULL )
182 {
183 CMLog( @"failed to allocate buffer for reading a network packet" );
184 break;
185 }
186
187 if ( (result = ReadBuffer( sockfd, data, header.size )) != header.size )
188 {
189 CMLog( @"failed to read the data of a network packet" );
190 free( data );
191 break;
192 }
193 }
194
195 //CMLog( @"SERVER message %i/%i/%i", header.checksum, header.function, header.size );
196
197 switch ( header.function )
198 {
199 case 1:
200 [self sendProcessList];
201 break;
202
203 case 3:
204 [self handleClearSearch];
205 break;
206
207 case 5:
208 [self handleSearch:data size:header.size];
209 break;
210
211 case 8:
212 [self handleChange:data size:header.size];
213 break;
214
215 case 10:
216 [self handlePauseTarget];
217 break;
218
219 case 14:
220 [self handleUndo];
221 break;
222
223 case 16:
224 [self handleRedo];
225 break;
226
227 case 18:
228 [self handleSetTargetPID:data size:header.size];
229 break;
230
231 }
232
233 if ( header.size != 0 )
234 {
235 free( data );
236 }
237 }
238 }
239
240 close( sockfd );
241
242 CMLog( @"SERVER close" );
243
244 [rootProxy serverDisconnected:self];
245 }
246
247
248 - (void)setAddress:(NSString *)address
249 {
250 [rootProxy server:self changedAddress:address];
251 }
252
253 - (void)setAction:(NSString *)action
254 {
255 if ( action == nil )
256 {
257 [rootProxy server:self changedAction:@"Idle"];
258 }
259 else
260 {
261 [rootProxy server:self changedAction:action];
262 }
263 }
264
265 - (void)firstSearchString8bit:(char const *)value size:(int)vsize
266 {
267 kern_return_t result;
268
269 vm_address_t address = 0x0;
270 vm_size_t size = 0;
271 vm_region_basic_info_data_t info;
272 mach_msg_type_number_t infoCnt = 8;
273 mach_port_t object_name = 0;
274
275 char *data;
276 vm_size_t dataLength;
277
278 TCaddress *results = NULL;
279 int resultsAmount = 0;
280
281 for (;;)
282 {
283 if ( (result = vm_region( processTask, &address, &size, VM_REGION_BASIC_INFO, (vm_region_info_t)(&info), &infoCnt, &object_name )) != KERN_SUCCESS )
284 {
285 if ( result != KERN_INVALID_ADDRESS )
286 {
287 CMLog( @"vm_region returned error: %i", result );
288 }
289 break;
290 }
291
292 if ( (info.protection & VM_PROT_READ) && (info.protection & VM_PROT_WRITE))
293 {
294 data = (char *)malloc( size );
295 dataLength = size;
296
297 if ( (result = vm_read_overwrite( processTask, address, size, (vm_address_t)data, &dataLength )) != KERN_SUCCESS && result != KERN_PROTECTION_FAILURE )
298 {
299 CMLog( @"vm_read_overwrite returned error: %i", result );
300 free( data );
301 break;
302 }
303
304 if ( result == KERN_SUCCESS )
305 {
306 //int i, top = dataLength - vsize;
307
308 if ( (results = realloc( results, TCAddressSize*resultsAmount + dataLength )) == NULL )
309 {
310 CMLog( @"ERROR: could not expand buffer" );
311 exit(0);
312 }
313
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) );
317
318 /*for ( i = 0; i < top; i++ )
319 {
320 if ( strncmp( value, data+i, vsize ) == 0 )
321 {
322 results[resultsAmount++] = (TCaddress)address + i;
323 }
324 }*/
325 }
326
327 free( data );
328 }
329
330 address += size;
331 }
332
333 realloc( results, TCAddressSize*resultsAmount );
334 [searchResults addObject:[SearchResults resultsWithType:TYPE_INTEGER size:SIZE_8_BIT data:results amount:resultsAmount]];
335
336 CMLog( @"found %i of %i", resultsAmount, value );
337 }
338
339 - (void)firstSearchIntegerChar:(int8_t)value
340 {
341 kern_return_t result;
342
343 vm_address_t address = 0x0;
344 vm_size_t size = 0;
345 vm_region_basic_info_data_t info;
346 mach_msg_type_number_t infoCnt = 8;
347 mach_port_t object_name = 0;
348
349 int8_t *data;
350 vm_size_t dataLength;
351
352 TCaddress *results = NULL;
353 int resultsAmount = 0;
354
355 for (;;)
356 {
357 if ( (result = vm_region( processTask, &address, &size, VM_REGION_BASIC_INFO, (vm_region_info_t)(&info), &infoCnt, &object_name )) != KERN_SUCCESS )
358 {
359 if ( result != KERN_INVALID_ADDRESS )
360 {
361 CMLog( @"vm_region returned error: %i", result );
362 }
363 break;
364 }
365
366 if ( (info.protection & VM_PROT_READ) && (info.protection & VM_PROT_WRITE))
367 {
368 data = (int8_t *)malloc( size );
369 dataLength = size;
370
371 if ( (result = vm_read_overwrite( processTask, address, size, (vm_address_t)data, &dataLength )) != KERN_SUCCESS && result != KERN_PROTECTION_FAILURE )
372 {
373 CMLog( @"vm_read_overwrite returned error: %i", result );
374 free( data );
375 break;
376 }
377
378 if ( result == KERN_SUCCESS )
379 {
380 int i;
381
382 if ( (results = (TCaddress *)realloc( results, TCAddressSize*resultsAmount + TCAddressSize*dataLength )) == NULL )
383 {
384 CMLog( @"ERROR: could not expand buffer" );
385 exit(0);
386 }
387
388 for ( i = 0; i < dataLength; i++ )
389 {
390 if ( *(data+i) == value )
391 {
392 results[resultsAmount++] = (TCaddress)address + i;
393 }
394 }
395 }
396
397 free( data );
398 }
399
400 address += size;
401 }
402
403 realloc( results, TCAddressSize*resultsAmount );
404 [searchResults addObject:[SearchResults resultsWithType:TYPE_INTEGER size:SIZE_8_BIT data:results amount:resultsAmount]];
405
406 CMLog( @"found %i of %i", resultsAmount, value );
407 }
408
409 - (void)firstSearchIntegerShort:(int16_t)value
410 {
411 kern_return_t result;
412
413 vm_address_t address = 0x0;
414 vm_size_t size = 0;
415 vm_region_basic_info_data_t info;
416 mach_msg_type_number_t infoCnt = 8;
417 mach_port_t object_name = 0;
418
419 int16_t *data;
420 vm_size_t dataLength;
421
422 TCaddress *results = NULL;
423 int resultsAmount = 0;
424
425 for (;;)
426 {
427 if ( (result = vm_region( processTask, &address, &size, VM_REGION_BASIC_INFO, (vm_region_info_t)(&info), &infoCnt, &object_name )) != KERN_SUCCESS )
428 {
429 if ( result != KERN_INVALID_ADDRESS )
430 {
431 CMLog( @"vm_region returned error: %i", result );
432 }
433 break;
434 }
435
436 if ( (info.protection & VM_PROT_READ) && (info.protection & VM_PROT_WRITE))
437 {
438 data = (int16_t *)malloc( size );
439 dataLength = size;
440
441 if ( (result = vm_read_overwrite( processTask, address, size, (vm_address_t)data, &dataLength )) != KERN_SUCCESS && result != KERN_PROTECTION_FAILURE )
442 {
443 CMLog( @"vm_read_overwrite returned error: %i", result );
444 free( data );
445 break;
446 }
447
448 if ( result == KERN_SUCCESS )
449 {
450 int i, top = dataLength / sizeof(value);
451
452 if ( (results = (TCaddress *)realloc( results, TCAddressSize*resultsAmount + 2*dataLength )) == NULL )
453 {
454 CMLog( @"ERROR: could not expand buffer" );
455 exit(0);
456 }
457
458 for ( i = 0; i < top; i++ )
459 {
460 if ( *(data+i) == value )
461 {
462 results[resultsAmount++] = (TCaddress)address + i * sizeof(value);
463 }
464 }
465 }
466
467 free( data );
468 }
469
470 address += size;
471 }
472
473 realloc( results, TCAddressSize*resultsAmount );
474 [searchResults addObject:[SearchResults resultsWithType:TYPE_INTEGER size:SIZE_16_BIT data:results amount:resultsAmount]];
475
476 CMLog( @"found %i of %i", resultsAmount, value );
477 }
478
479 - (void)firstSearchIntegerLong:(int32_t)value
480 {
481 kern_return_t result;
482
483 vm_address_t address = 0x0;
484 vm_size_t size = 0;
485 vm_region_basic_info_data_t info;
486 mach_msg_type_number_t infoCnt = 8;
487 mach_port_t object_name = 0;
488
489 int32_t *data;
490 vm_size_t dataLength;
491
492 TCaddress *results = NULL;
493 int resultsAmount = 0;
494
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;
498
499 if ( (result = malloc_get_all_zones( processTask, NULL, &zones, &zone_count )) != KERN_SUCCESS )
500 {
501 CMLog( @"malloc_get_all_zones error: %i", result );
502 }
503 else
504 {
505 //address = zones[0];
506
507 int i;
508
509 for ( i = 0; i < 10; i++ )
510 {
511 CMLog( @"malloc_get_all_zones[%i] = %X", i, (vm_address_t)zones[i] );
512 }
513 }*/
514
515 for (;;)
516 {
517 if ( (result = vm_region( processTask, &address, &size, VM_REGION_BASIC_INFO, (vm_region_info_t)(&info), &infoCnt, &object_name )) != KERN_SUCCESS )
518 {
519 if ( result != KERN_INVALID_ADDRESS )
520 {
521 CMLog( @"vm_region returned error: %i", result );
522 }
523 break;
524 }
525
526 if ( (info.protection & VM_PROT_READ) && (info.protection & VM_PROT_WRITE) )
527 {
528 data = (int32_t *)malloc( size );
529 dataLength = size;
530
531 //CMLog( @"address: %.8X size: %i", address, size );
532
533 if ( (result = vm_read_overwrite( processTask, address, size, (vm_address_t)data, &dataLength )) != KERN_SUCCESS && result != KERN_PROTECTION_FAILURE )
534 {
535 CMLog( @"vm_read_overwrite returned error: %i", result );
536 free( data );
537 break;
538 }
539
540 if ( result == KERN_SUCCESS )
541 {
542 int i, top = dataLength / sizeof(value);
543
544 if ( (results = (TCaddress *)realloc( results, TCAddressSize*resultsAmount + dataLength )) == NULL )
545 {
546 CMLog( @"ERROR: could not expand buffer" );
547 exit(0);
548 }
549
550 for ( i = 0; i < top; i++ )
551 {
552 if ( *(data+i) == value )
553 {
554 results[resultsAmount++] = (TCaddress)address + i * sizeof(value);
555 }
556 }
557 }
558
559 free( data );
560 }
561
562 address += size;
563 }
564
565 realloc( results, TCAddressSize*resultsAmount );
566 [searchResults addObject:[SearchResults resultsWithType:TYPE_INTEGER size:SIZE_32_BIT data:results amount:resultsAmount]];
567
568 CMLog( @"found %i of %i", resultsAmount, value );
569 }
570
571 - (void)firstSearchDecimalFloat:(float)value
572 {
573 kern_return_t result;
574
575 vm_address_t address = 0x0;
576 vm_size_t size = 0;
577 vm_region_basic_info_data_t info;
578 mach_msg_type_number_t infoCnt = 8;
579 mach_port_t object_name = 0;
580
581 float *data;
582 vm_size_t dataLength;
583
584 TCaddress *results = NULL;
585 int resultsAmount = 0;
586
587 for (;;)
588 {
589 if ( (result = vm_region( processTask, &address, &size, VM_REGION_BASIC_INFO, (vm_region_info_t)(&info), &infoCnt, &object_name )) != KERN_SUCCESS )
590 {
591 if ( result != KERN_INVALID_ADDRESS )
592 {
593 CMLog( @"vm_region returned error: %i", result );
594 }
595 break;
596 }
597
598 if ( (info.protection & VM_PROT_READ) && (info.protection & VM_PROT_WRITE))
599 {
600 data = (float *)malloc( size );
601 dataLength = size;
602
603 if ( (result = vm_read_overwrite( processTask, address, size, (vm_address_t)data, &dataLength )) != KERN_SUCCESS && result != KERN_PROTECTION_FAILURE )
604 {
605 CMLog( @"vm_read_overwrite returned error: %i", result );
606 free( data );
607 break;
608 }
609
610 if ( result == KERN_SUCCESS )
611 {
612 int i, top = dataLength / sizeof(value);
613
614 if ( (results = realloc( results, TCAddressSize*resultsAmount + dataLength )) == NULL )
615 {
616 CMLog( @"ERROR: could not expand buffer" );
617 exit(0);
618 }
619
620 for ( i = 0; i < top; i++ )
621 {
622 if ( CMCompareFloatsWithEpsilon( *(data+i), value, 0.1f ) == 0 )
623 {
624 results[resultsAmount++] = (TCaddress)address + i * sizeof(value);
625 }
626 }
627 }
628
629 free( data );
630 }
631
632 address += size;
633 }
634
635 realloc( results, TCAddressSize*resultsAmount );
636 [searchResults addObject:[SearchResults resultsWithType:TYPE_DECIMAL size:SIZE_32_BIT data:results amount:resultsAmount]];
637
638 CMLog( @"found %i of %i", resultsAmount, value );
639 }
640
641 - (void)firstSearchDecimalDouble:(double)value
642 {
643 kern_return_t result;
644
645 vm_address_t address = 0x0;
646 vm_size_t size = 0;
647 vm_region_basic_info_data_t info;
648 mach_msg_type_number_t infoCnt = 8;
649 mach_port_t object_name = 0;
650
651 double *data;
652 vm_size_t dataLength;
653
654 TCaddress *results = NULL;
655 int resultsAmount = 0;
656
657 CMLog( @"float search" );
658
659 for (;;)
660 {
661 if ( (result = vm_region( processTask, &address, &size, VM_REGION_BASIC_INFO, (vm_region_info_t)(&info), &infoCnt, &object_name )) != KERN_SUCCESS )
662 {
663 if ( result != KERN_INVALID_ADDRESS )
664 {
665 CMLog( @"vm_region returned error: %i", result );
666 }
667 break;
668 }
669
670 if ( (info.protection & VM_PROT_READ) && (info.protection & VM_PROT_WRITE))
671 {
672 data = (double *)malloc( size );
673 dataLength = size;
674
675 if ( (result = vm_read_overwrite( processTask, address, size, (vm_address_t)data, &dataLength )) != KERN_SUCCESS && result != KERN_PROTECTION_FAILURE )
676 {
677 CMLog( @"vm_read_overwrite returned error: %i", result );
678 free( data );
679 break;
680 }
681
682 if ( result == KERN_SUCCESS )
683 {
684 int i, top = dataLength / sizeof(value);
685
686 if ( (results = realloc( results, TCAddressSize*resultsAmount + dataLength )) == NULL )
687 {
688 CMLog( @"ERROR: could not expand buffer" );
689 exit(0);
690 }
691
692 for ( i = 0; i < top; i++ )
693 {
694 if ( CMCompareDoublesWithEpsilon( *(data+i), value, 0.1 ) == 0 )
695 {
696 results[resultsAmount++] = (TCaddress)address + i * sizeof(value);
697 }
698 }
699 }
700
701 free( data );
702 }
703
704 address += size;
705 }
706
707 realloc( results, TCAddressSize*resultsAmount );
708 [searchResults addObject:[SearchResults resultsWithType:TYPE_DECIMAL size:SIZE_64_BIT data:results amount:resultsAmount]];
709
710 CMLog( @"found %i of %i", resultsAmount, value );
711 }
712
713
714 - (void)searchString8bit:(char const *)value size:(int)vsize
715 {
716 kern_return_t result;
717
718 char *data;
719 vm_size_t dataLength;
720
721 TCaddress *results;
722 int resultsAmount = 0;
723
724 SearchResults *lastResults = [searchResults lastObject];
725 TCaddress *lastResultsData = [lastResults data];
726 int i, lastResultsAmount = [lastResults amount];
727
728 if ( [lastResults type] != TYPE_INTEGER || [lastResults size] != SIZE_8_BIT )
729 {
730 [self sendError:@"This search is incompatible with the previous search." fatal:NO];
731 return;
732 }
733
734 if ( (data = (char *)malloc( vsize )) == NULL )
735 {
736 CMLog( @"ERROR: could not create buffer" );
737
738 [self sendError:@"The server cancelled the search because it ran out of memory." fatal:NO];
739 return;
740 }
741
742 if ( (results = (TCaddress *)malloc( TCAddressSize*lastResultsAmount )) == NULL )
743 {
744 CMLog( @"ERROR: could not create buffer" );
745
746 [self sendError:@"The server cancelled the search because it ran out of memory." fatal:NO];
747 free( data );
748 return;
749 }
750
751 for ( i = 0; i < lastResultsAmount; i++ )
752 {
753 TCaddress address = lastResultsData[i];
754
755 //dataLength = sizeof(data);
756
757 if ( (result = vm_read_overwrite( processTask, address, vsize, (vm_address_t)(data), &dataLength )) == KERN_SUCCESS )
758 {
759 if ( memcmp( data, value, dataLength ) == 0 )
760 {
761 results[resultsAmount++] = address;
762 }
763 }
764 else
765 {
766 if ( result != KERN_PROTECTION_FAILURE )
767 {
768 CMLog( @"vm_read_overwrite returned error: %i", result );
769 break;
770 }
771 }
772 }
773
774 realloc( results, TCAddressSize*resultsAmount );
775 [searchResults addObject:[SearchResults resultsWithType:TYPE_INTEGER size:SIZE_8_BIT data:results amount:resultsAmount]];
776
777 free( data );
778
779 CMLog( @"found %i of %i", resultsAmount, value );
780 }
781
782 - (void)searchIntegerChar:(int8_t)value
783 {
784 kern_return_t result;
785
786 int8_t data;
787 vm_size_t dataLength;
788
789 TCaddress *results;
790 int resultsAmount = 0;
791
792 SearchResults *lastResults = [searchResults lastObject];
793 TCaddress *lastResultsData = [lastResults data];
794 int i, lastResultsAmount = [lastResults amount];
795
796 if ( [lastResults type] != TYPE_INTEGER || [lastResults size] != SIZE_8_BIT )
797 {
798 [self sendError:@"This search is incompatible with the previous search." fatal:NO];
799 return;
800 }
801
802 if ( (results = (TCaddress *)malloc( TCAddressSize*lastResultsAmount )) == NULL )
803 {
804 CMLog( @"ERROR: could not create buffer" );
805
806 [self sendError:@"The server cancelled the search because it ran out of memory." fatal:NO];
807 return;
808 }
809
810 for ( i = 0; i < lastResultsAmount; i++ )
811 {
812 TCaddress address = lastResultsData[i];
813
814 dataLength = sizeof(data);
815
816 if ( (result = vm_read_overwrite( processTask, address, sizeof(data), (vm_address_t)(&data), &dataLength )) == KERN_SUCCESS )
817 {
818 if ( data == value )
819 {
820 results[resultsAmount++] = address;
821 }
822 }
823 else
824 {
825 if ( result != KERN_PROTECTION_FAILURE )
826 {
827 CMLog( @"vm_read_overwrite returned error: %i", result );
828 break;
829 }
830 }
831 }
832
833 realloc( results, TCAddressSize*resultsAmount );
834 [searchResults addObject:[SearchResults resultsWithType:TYPE_INTEGER size:SIZE_8_BIT data:results amount:resultsAmount]];
835
836 CMLog( @"found %i of %i", resultsAmount, value );
837 }
838
839 - (void)searchIntegerShort:(int16_t)value
840 {
841 kern_return_t result;
842
843 int16_t data;
844 vm_size_t dataLength;
845
846 TCaddress *results;
847 int resultsAmount = 0;
848
849 SearchResults *lastResults = [searchResults lastObject];
850 TCaddress *lastResultsData = [lastResults data];
851 int i, lastResultsAmount = [lastResults amount];
852
853 if ( [lastResults type] != TYPE_INTEGER || [lastResults size] != SIZE_16_BIT )
854 {
855 [self sendError:@"This search is incompatible with the previous search." fatal:NO];
856 return;
857 }
858
859 if ( (results = (TCaddress *)malloc( TCAddressSize*lastResultsAmount )) == NULL )
860 {
861 CMLog( @"ERROR: could not create buffer" );
862
863 [self sendError:@"The server cancelled the search because it ran out of memory." fatal:NO];
864 return;
865 }
866
867 for ( i = 0; i < lastResultsAmount; i++ )
868 {
869 TCaddress address = lastResultsData[i];
870
871 dataLength = sizeof(data);
872
873 if ( (result = vm_read_overwrite( processTask, address, sizeof(data), (vm_address_t)(&data), &dataLength )) == KERN_SUCCESS )
874 {
875 if ( data == value )
876 {
877 results[resultsAmount++] = address;
878 }
879 }
880 else
881 {
882 if ( result != KERN_PROTECTION_FAILURE )
883 {
884 CMLog( @"vm_read_overwrite returned error: %i", result );
885 break;
886 }
887 }
888 }
889
890 realloc( results, TCAddressSize*resultsAmount );
891 [searchResults addObject:[SearchResults resultsWithType:TYPE_INTEGER size:SIZE_16_BIT data:results amount:resultsAmount]];
892
893 CMLog( @"found %i of %i", resultsAmount, value );
894 }
895
896 - (void)searchIntegerLong:(int32_t)value
897 {
898 kern_return_t result;
899
900 int32_t data;
901 vm_size_t dataLength;
902
903 TCaddress *results;
904 int resultsAmount = 0;
905
906 SearchResults *lastResults = [searchResults lastObject];
907 TCaddress *lastResultsData = [lastResults data];
908 int i, lastResultsAmount = [lastResults amount];
909
910 if ( [lastResults type] != TYPE_INTEGER || [lastResults size] != SIZE_32_BIT )
911 {
912 [self sendError:@"This search is incompatible with the previous search." fatal:NO];
913 return;
914 }
915
916 if ( (results = (TCaddress *)malloc( TCAddressSize*lastResultsAmount )) == NULL )
917 {
918 CMLog( @"ERROR: could not create buffer" );
919
920 [self sendError:@"The server cancelled the search because it ran out of memory." fatal:NO];
921 return;
922 }
923
924 for ( i = 0; i < lastResultsAmount; i++ )
925 {
926 TCaddress address = lastResultsData[i];
927
928 dataLength = sizeof(data);
929
930 if ( (result = vm_read_overwrite( processTask, address, sizeof(data), (vm_address_t)(&data), &dataLength )) == KERN_SUCCESS )
931 {
932 if ( data == value )
933 {
934 results[resultsAmount++] = address;
935 }
936 }
937 else
938 {
939 if ( result != KERN_PROTECTION_FAILURE )
940 {
941 CMLog( @"vm_read_overwrite returned error: %i", result );
942 break;
943 }
944 }
945 }
946
947 realloc( results, TCAddressSize*resultsAmount );
948 [searchResults addObject:[SearchResults resultsWithType:TYPE_INTEGER size:SIZE_32_BIT data:results amount:resultsAmount]];
949
950 CMLog( @"found %i of %i", resultsAmount, value );
951 }
952
953 - (void)searchDecimalFloat:(float)value
954 {
955 kern_return_t result;
956
957 float data;
958 vm_size_t dataLength;
959
960 TCaddress *results;
961 int resultsAmount = 0;
962
963 SearchResults *lastResults = [searchResults lastObject];
964 TCaddress *lastResultsData = [lastResults data];
965 int i, lastResultsAmount = [lastResults amount];
966
967 if ( [lastResults type] != TYPE_DECIMAL || [lastResults size] != SIZE_32_BIT )
968 {
969 [self sendError:@"This search is incompatible with the previous search." fatal:NO];
970 return;
971 }
972
973 if ( (results = (TCaddress *)malloc( TCAddressSize*lastResultsAmount )) == NULL )
974 {
975 CMLog( @"ERROR: could not create buffer" );
976
977 [self sendError:@"The server cancelled the search because it ran out of memory." fatal:NO];
978 return;
979 }
980
981 for ( i = 0; i < lastResultsAmount; i++ )
982 {
983 TCaddress address = lastResultsData[i];
984
985 dataLength = sizeof(data);
986
987 if ( (result = vm_read_overwrite( processTask, address, sizeof(data), (vm_address_t)(&data), &dataLength )) == KERN_SUCCESS )
988 {
989 if ( CMCompareFloatsWithEpsilon( data, value, 0.1f ) == 0 )
990 {
991 results[resultsAmount++] = address;
992 }
993 }
994 else
995 {
996 if ( result != KERN_PROTECTION_FAILURE )
997 {
998 CMLog( @"vm_read_overwrite returned error: %i", result );
999 break;
1000 }
1001 }
1002 }
1003
1004 realloc( results, TCAddressSize*resultsAmount );
1005 [searchResults addObject:[SearchResults resultsWithType:TYPE_DECIMAL size:SIZE_32_BIT data:results amount:resultsAmount]];
1006
1007 CMLog( @"found %i of %i", resultsAmount, value );
1008 }
1009
1010 - (void)searchDecimalDouble:(double)value
1011 {
1012 kern_return_t result;
1013
1014 double data;
1015 vm_size_t dataLength;
1016
1017 TCaddress *results;
1018 int resultsAmount = 0;
1019
1020 SearchResults *lastResults = [searchResults lastObject];
1021 TCaddress *lastResultsData = [lastResults data];
1022 int i, lastResultsAmount = [lastResults amount];
1023
1024 if ( [lastResults type] != TYPE_DECIMAL || [lastResults size] != SIZE_64_BIT )
1025 {
1026 [self sendError:@"This search is incompatible with the previous search." fatal:NO];
1027 return;
1028 }
1029
1030 if ( (results = (TCaddress *)malloc( TCAddressSize*lastResultsAmount )) == NULL )
1031 {
1032 CMLog( @"ERROR: could not create buffer" );
1033
1034 [self sendError:@"The server cancelled the search because it ran out of memory." fatal:NO];
1035 return;
1036 }
1037
1038 for ( i = 0; i < lastResultsAmount; i++ )
1039 {
1040 TCaddress address = lastResultsData[i];
1041
1042 dataLength = sizeof(data);
1043
1044 if ( (result = vm_read_overwrite( processTask, address, sizeof(data), (vm_address_t)(&data), &dataLength )) == KERN_SUCCESS )
1045 {
1046 if ( CMCompareDoublesWithEpsilon( data, value, 0.1 ) == 0 )
1047 {
1048 results[resultsAmount++] = address;
1049 }
1050 }
1051 else
1052 {
1053 if ( result != KERN_PROTECTION_FAILURE )
1054 {
1055 CMLog( @"vm_read_overwrite returned error: %i", result );
1056 break;
1057 }
1058 }
1059 }
1060
1061 realloc( results, TCAddressSize*resultsAmount );
1062 [searchResults addObject:[SearchResults resultsWithType:TYPE_DECIMAL size:SIZE_64_BIT data:results amount:resultsAmount]];
1063
1064 CMLog( @"found %i of %i", resultsAmount, value );
1065 }
1066
1067
1068 - (void)changeString8bit:(char const *)value size:(int)vsize addresses:(TCaddress *)addresses count:(int)count
1069 {
1070 int failCount = 0;
1071 int i;
1072
1073 for ( i = 0; i < count; i++ )
1074 {
1075 if ( vm_write( processTask, (vm_address_t)addresses[i], (vm_offset_t)value, vsize ) != KERN_SUCCESS )
1076 {
1077 failCount++;
1078 }
1079 }
1080
1081 if ( failCount > 0 )
1082 {
1083 [self sendError:[NSString stringWithFormat:@"%i of the selected variables could not be changed.", failCount] fatal:NO];
1084 }
1085 }
1086
1087 - (void)changeIntegerChar:(int8_t)value addresses:(TCaddress *)addresses count:(int)count
1088 {
1089 int failCount = 0;
1090 int i;
1091
1092 for ( i = 0; i < count; i++ )
1093 {
1094 if ( vm_write( processTask, (vm_address_t)addresses[i], (vm_offset_t)(&value), sizeof(value) ) != KERN_SUCCESS )
1095 {
1096 failCount++;
1097 }
1098 }
1099
1100 if ( failCount > 0 )
1101 {
1102 [self sendError:[NSString stringWithFormat:@"%i of the selected variables could not be changed.", failCount] fatal:NO];
1103 }
1104 }
1105
1106 - (void)changeIntegerShort:(int16_t)value addresses:(TCaddress *)addresses count:(int)count
1107 {
1108 int failCount = 0;
1109 int i;
1110
1111 for ( i = 0; i < count; i++ )
1112 {
1113 if ( vm_write( processTask, (vm_address_t)addresses[i], (vm_offset_t)(&value), sizeof(value) ) != KERN_SUCCESS )
1114 {
1115 failCount++;
1116 }
1117 }
1118
1119 if ( failCount > 0 )
1120 {
1121 [self sendError:[NSString stringWithFormat:@"%i of the selected variables could not be changed.", failCount] fatal:NO];
1122 }
1123 }
1124
1125 - (void)changeIntegerLong:(int32_t)value addresses:(TCaddress *)addresses count:(int)count
1126 {
1127 int failCount = 0;
1128 int i;
1129
1130 for ( i = 0; i < count; i++ )
1131 {
1132 if ( vm_write( processTask, (vm_address_t)addresses[i], (vm_offset_t)(&value), sizeof(value) ) != KERN_SUCCESS )
1133 {
1134 failCount++;
1135 }
1136 }
1137
1138 if ( failCount > 0 )
1139 {
1140 [self sendError:[NSString stringWithFormat:@"%i of the selected variables could not be changed.", failCount] fatal:NO];
1141 }
1142 }
1143
1144 - (void)changeDecimalFloat:(float)value addresses:(TCaddress *)addresses count:(int)count
1145 {
1146 int failCount = 0;
1147 int i;
1148
1149 for ( i = 0; i < count; i++ )
1150 {
1151 if ( vm_write( processTask, (vm_address_t)addresses[i], (vm_offset_t)(&value), sizeof(value) ) != KERN_SUCCESS )
1152 {
1153 failCount++;
1154 }
1155 }
1156
1157 if ( failCount > 0 )
1158 {
1159 [self sendError:[NSString stringWithFormat:@"%i of the selected variables could not be changed.", failCount] fatal:NO];
1160 }
1161 }
1162
1163 - (void)changeDecimalDouble:(double)value addresses:(TCaddress *)addresses count:(int)count
1164 {
1165 int failCount = 0;
1166 int i;
1167
1168 for ( i = 0; i < count; i++ )
1169 {
1170 if ( vm_write( processTask, (vm_address_t)addresses[i], (vm_offset_t)(&value), sizeof(value) ) != KERN_SUCCESS )
1171 {
1172 failCount++;
1173 }
1174 }
1175
1176 if ( failCount > 0 )
1177 {
1178 [self sendError:[NSString stringWithFormat:@"%i of the selected variables could not be changed.", failCount] fatal:NO];
1179 }
1180 }
1181
1182
1183 - (void)sendProcessList
1184 {
1185 NSArray *processList = [rootProxy serverProcessList];
1186
1187 NSNumber *pid;
1188 u_int32_t pidNum;
1189 NSString *name;
1190
1191 PacketHeader header;
1192
1193 char *buffer, *ptr;
1194
1195 // PROCESS COUNT
1196 int length = sizeof(u_int32_t);
1197 int lengthAfter;
1198
1199 u_int32_t processCount = [processList count];
1200
1201 int i, max = processCount;
1202
1203 header.checksum = RandomChecksum();
1204 header.function = 2;
1205
1206 for ( i = 0; i < max; i++ )
1207 {
1208 pid = [[processList objectAtIndex:i] objectForKey:@"NSApplicationProcessIdentifier"];
1209 name = [[processList objectAtIndex:i] objectForKey:@"NSApplicationName"];
1210
1211 // PID NAME
1212 length += sizeof(u_int32_t) + [name length] + 1;
1213 }
1214
1215 header.size = length;
1216 length += sizeof(header);
1217 // HEADER
1218
1219 if ( (buffer = (char *)malloc( length ))==NULL )
1220 {
1221 CMLog( @"sendProcessList failed" );
1222 return;
1223 }
1224
1225 ptr = buffer;
1226
1227 COPY_TO_BUFFER( ptr, &header, sizeof(header) );
1228 COPY_TO_BUFFER( ptr, &processCount, sizeof(processCount) );
1229
1230 for ( i = 0; i < max; i++ )
1231 {
1232 pidNum = [[[processList objectAtIndex:i] objectForKey:@"NSApplicationProcessIdentifier"] unsignedLongValue];
1233 name = [[processList objectAtIndex:i] objectForKey:@"NSApplicationName"];
1234
1235 COPY_TO_BUFFER( ptr, &pidNum, sizeof(pid) );
1236 COPY_TO_BUFFER( ptr, [name lossyCString], [name length] + 1 );
1237 }
1238
1239 lengthAfter = length;
1240
1241 if ( SendBuffer( sockfd, buffer, &lengthAfter ) == -1 || lengthAfter != length )
1242 {
1243 CMLog( @"sendProcessList failed" );
1244 }
1245
1246 free( buffer );
1247 }
1248
1249
1250 - (void)sendSearchFinished
1251 {
1252 PacketHeader header;
1253 int length = sizeof(header);
1254
1255 header.checksum = RandomChecksum();
1256 header.function = 6;
1257 header.size = 0;
1258
1259 if ( SendBuffer( sockfd, (char *)(&header), &length ) == -1 || length != sizeof(header) )
1260 {
1261 CMLog( @"sendSearchFinished failed" );
1262 }
1263 }
1264
1265 - (void)sendVariableList:(TCaddress const *)data amount:(int)amount
1266 {
1267 PacketHeader header;
1268 int length;
1269 int lengthAfter;
1270 int displayAmount = ( searchResultsAmountDisplayed > amount )? amount : searchResultsAmountDisplayed;
1271 int resultsLength = TCAddressSize * displayAmount;
1272
1273 char *buffer, *ptr;
1274
1275 header.checksum = RandomChecksum();
1276 header.function = 7;
1277 header.size = sizeof(amount) + sizeof(displayAmount) + resultsLength;
1278 // AMOUNT DISPLAY AMOUNT DATA
1279
1280 lengthAfter = length = header.size + sizeof(header);
1281
1282 if ( (buffer = (char *)malloc( length )) == NULL )
1283 {
1284 CMLog( @"sendVariableList:amount: failed" );
1285 return;
1286 }
1287
1288 ptr = buffer;
1289
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 );
1294
1295 if ( SendBuffer( sockfd, buffer, &length ) == -1 || lengthAfter != length )
1296 {
1297 CMLog( @"sendVariableList:amount: failed" );
1298 }
1299
1300 free( buffer );
1301
1302 CMLog( @"SERVER sending %i out of %i results", displayAmount, amount );
1303 }
1304
1305 - (void)sendChangeFinished
1306 {
1307 PacketHeader header;
1308 int length = sizeof(header);
1309
1310 header.checksum = RandomChecksum();
1311 header.function = 9;
1312 header.size = 0;
1313
1314 if ( SendBuffer( sockfd, (char *)(&header), &length ) == -1 || length != sizeof(header) )
1315 {
1316 CMLog( @"sendChangeFinished failed" );
1317 }
1318 }
1319
1320 - (void)sendError:(NSString *)msg fatal:(BOOL)fatal
1321 {
1322 PacketHeader header;
1323 int length;
1324 int lengthAfter;
1325
1326 u_int32_t type = (fatal)? 1:0;
1327
1328 char *buffer, *ptr;
1329
1330 header.checksum = RandomChecksum();
1331 header.function = 11;
1332 header.size = sizeof(type) + [msg length] + 1;
1333 // FATAL STRING
1334
1335 lengthAfter = length = header.size + sizeof(header);
1336
1337 if ( (buffer = (char *)malloc( length )) == NULL )
1338 {
1339 CMLog( @"sendError:fatal: failed" );
1340 return;
1341 }
1342
1343 ptr = buffer;
1344
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 );
1348
1349 if ( SendBuffer( sockfd, buffer, &length ) == -1 || lengthAfter != length )
1350 {
1351 CMLog( @"sendError:fatal: failed" );
1352 }
1353
1354 free( buffer );
1355 }
1356
1357 - (void)sendVariableValue:(u_int32_t)index
1358 {
1359
1360 }
1361
1362 - (void)sendUndoFinished
1363 {
1364 PacketHeader header;
1365 int length = sizeof(header);
1366
1367 header.checksum = RandomChecksum();
1368 header.function = 15;
1369 header.size = 0;
1370
1371 if ( SendBuffer( sockfd, (char *)(&header), &length ) == -1 || length != sizeof(header) )
1372 {
1373 CMLog( @"sendUndoFinished failed" );
1374 }
1375 }
1376
1377 - (void)sendRedoFinished
1378 {
1379 PacketHeader header;
1380 int length = sizeof(header);
1381
1382 header.checksum = RandomChecksum();
1383 header.function = 17;
1384 header.size = 0;
1385
1386 if ( SendBuffer( sockfd, (char *)(&header), &length ) == -1 || length != sizeof(header) )
1387 {
1388 CMLog( @"sendRedoFinished failed" );
1389 }
1390 }
1391
1392 - (void)sendUndoRedoStatus
1393 {
1394 PacketHeader header;
1395 int length;
1396 int lengthAfter;
1397
1398 u_int32_t undoCount = (u_int32_t)[searchResults count];
1399 u_int32_t redoCount = (u_int32_t)[searchResultsUndone count];
1400
1401 char *buffer, *ptr;
1402
1403 header.checksum = RandomChecksum();
1404 header.function = 19;
1405 header.size = 2 * sizeof(u_int32_t);
1406
1407 length = lengthAfter = sizeof(header) + header.size;
1408
1409 if ( (buffer = (char *)malloc( length )) == NULL )
1410 {
1411 CMLog( @"sendSetTargetPID: failed" );
1412 }
1413
1414 ptr = buffer;
1415
1416 COPY_TO_BUFFER( ptr, &header, sizeof(header) );
1417 COPY_TO_BUFFER( ptr, &undoCount, sizeof(undoCount) );
1418 COPY_TO_BUFFER( ptr, &redoCount, sizeof(redoCount) );
1419
1420 if ( SendBuffer( sockfd, buffer, &lengthAfter ) == -1 || lengthAfter != length )
1421 {
1422 CMLog( @"sendUndoRedoStatus: failed" );
1423 }
1424
1425 free( buffer );
1426 }
1427
1428 - (void)sendAppLaunched:(NSDictionary *)appInfo
1429 {
1430 PacketHeader header;
1431
1432 char *buffer, *ptr;
1433
1434 int length = 0;
1435 int lengthAfter;
1436
1437 u_int32_t pid = [[appInfo objectForKey:@"NSApplicationProcessIdentifier"] unsignedLongValue];
1438 NSString *name = [appInfo objectForKey:@"NSApplicationName"];
1439
1440 // PID NAME
1441 length += sizeof(u_int32_t) + [name length] + 1;
1442
1443 header.checksum = RandomChecksum();
1444 header.function = 21;
1445 header.size = length;
1446
1447 length += sizeof(header);
1448 // HEADER
1449
1450 if ( (buffer = (char *)malloc( length ))==NULL )
1451 {
1452 CMLog( @"sendAppLaunched: failed" );
1453
1454 return;
1455 }
1456
1457 ptr = buffer;
1458
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 );
1462
1463 lengthAfter = length;
1464
1465 if ( SendBuffer( sockfd, buffer, &lengthAfter ) == -1 || lengthAfter != length )
1466 {
1467 CMLog( @"sendAppLaunched: failed" );
1468 }
1469
1470 free( buffer );
1471 }
1472
1473
1474 - (void)sendAppQuit:(NSDictionary *)appInfo
1475 {
1476 PacketHeader header;
1477
1478 char *buffer, *ptr;
1479
1480 int length = 0;
1481 int lengthAfter;
1482
1483 u_int32_t pid = [[appInfo objectForKey:@"NSApplicationProcessIdentifier"] unsignedLongValue];
1484
1485 // PID
1486 length += sizeof(pid);
1487
1488 header.checksum = RandomChecksum();
1489 header.function = 22;
1490 header.size = length;
1491
1492 length += sizeof(header);
1493 // HEADER
1494
1495 if ( (buffer = (char *)malloc( length ))==NULL )
1496 {
1497 CMLog( @"sendAppQuit: failed" );
1498
1499 return;
1500 }
1501
1502 ptr = buffer;
1503
1504 COPY_TO_BUFFER( ptr, &header, sizeof(header) );
1505 COPY_TO_BUFFER( ptr, &pid, sizeof(pid) );
1506
1507 lengthAfter = length;
1508
1509 if ( SendBuffer( sockfd, buffer, &lengthAfter ) == -1 || lengthAfter != length )
1510 {
1511 CMLog( @"sendAppQuit: failed" );
1512 }
1513
1514 free( buffer );
1515 }
1516
1517 - (void)sendTargetAppQuit
1518 {
1519 PacketHeader header;
1520 int length = sizeof(header);
1521
1522 header.checksum = RandomChecksum();
1523 header.function = 23;
1524 header.size = 0;
1525
1526 if ( SendBuffer( sockfd, (char *)(&header), &length ) == -1 || length != sizeof(header) )
1527 {
1528 CMLog( @"sendTargetAppQuit failed" );
1529 }
1530 }
1531
1532 - (void)sendPauseFinished:(BOOL)paused
1533 {
1534 PacketHeader header;
1535
1536 char *buffer, *ptr;
1537
1538 // PAUSED
1539 int length = sizeof(paused);
1540 int lengthAfter;
1541
1542 header.checksum = RandomChecksum();
1543 header.function = 24;
1544 header.size = length;
1545
1546 length += sizeof(header);
1547 // HEADER
1548
1549 if ( (buffer = (char *)malloc( length ))==NULL )
1550 {
1551 CMLog( @"sendPauseFinished: failed" );
1552
1553 return;
1554 }
1555
1556 ptr = buffer;
1557
1558 COPY_TO_BUFFER( ptr, &header, sizeof(header) );
1559 COPY_TO_BUFFER( ptr, &paused, sizeof(paused) );
1560
1561 lengthAfter = length;
1562
1563 if ( SendBuffer( sockfd, buffer, &lengthAfter ) == -1 || lengthAfter != length )
1564 {
1565 CMLog( @"sendPauseFinished: failed" );
1566 }
1567
1568 free( buffer );
1569 }
1570
1571
1572 - (void)handleClearSearch
1573 {
1574 [searchResults removeAllObjects];
1575 [searchResultsUndone removeAllObjects];
1576
1577 [self unpause];
1578 }
1579
1580 - (void)handleSearch:(char const *)data size:(int)dataSize
1581 {
1582 TCtype type;
1583 TCsize size;
1584
1585 char *ptr = (char *)data;
1586
1587 [self setAction:@"Searching"];
1588
1589 COPY_FROM_BUFFER( &type, ptr, sizeof(type) );
1590 COPY_FROM_BUFFER( &size, ptr, sizeof(size) );
1591
1592 // receive the amount of results to return
1593 COPY_FROM_BUFFER( &searchResultsAmountDisplayed, ptr, sizeof(searchResultsAmountDisplayed) );
1594
1595 if ( ![searchResults lastObject] )
1596 {
1597 switch ( type )
1598 {
1599 case TYPE_STRING:
1600 {
1601 switch ( size )
1602 {
1603 case SIZE_8_BIT:
1604 {
1605 [self firstSearchString8bit:ptr size:(dataSize - (ptr - data) - 1)];
1606 }
1607 break;
1608 }
1609 }
1610 break;
1611
1612 case TYPE_INTEGER:
1613 {
1614 switch ( size )
1615 {
1616 case SIZE_8_BIT:
1617 {
1618 int8_t value;
1619
1620 COPY_FROM_BUFFER( &value, ptr, sizeof(value) );
1621 [self firstSearchIntegerChar:value];
1622 }
1623 break;
1624
1625 case SIZE_16_BIT:
1626 {
1627 int16_t value;
1628
1629 COPY_FROM_BUFFER( &value, ptr, sizeof(value) );
1630 [self firstSearchIntegerShort:value];
1631 }
1632 break;
1633
1634 case SIZE_32_BIT:
1635 {
1636 int32_t value;
1637
1638 COPY_FROM_BUFFER( &value, ptr, sizeof(value) );
1639 [self firstSearchIntegerLong:value];
1640 }
1641 break;
1642 }
1643 }
1644 break;
1645
1646 case TYPE_DECIMAL:
1647 {
1648 switch ( size )
1649 {
1650 case SIZE_32_BIT:
1651 {
1652 float value;
1653
1654 COPY_FROM_BUFFER( &value, ptr, sizeof(value) );
1655 [self firstSearchDecimalFloat:value];
1656 }
1657 break;
1658
1659 case SIZE_64_BIT:
1660 {
1661 double value;
1662
1663 COPY_FROM_BUFFER( &value, ptr, sizeof(value) );
1664 [self firstSearchDecimalDouble:value];
1665 }
1666 break;
1667 }
1668 }
1669 break;
1670 }
1671 }
1672 else
1673 {
1674 switch ( type )
1675 {
1676 case TYPE_STRING:
1677 {
1678 switch ( size )
1679 {
1680 case SIZE_8_BIT:
1681 {
1682 [self searchString8bit:ptr size:(dataSize - (ptr - data))];
1683
1684 break;
1685 }
1686 }
1687 }
1688 break;
1689
1690 case TYPE_INTEGER:
1691 {
1692 switch ( size )
1693 {
1694 case SIZE_8_BIT:
1695 {
1696 int8_t value;
1697
1698 COPY_FROM_BUFFER( &value, ptr, sizeof(value) );
1699 [self searchIntegerChar:value];
1700
1701 break;
1702 }
1703
1704 case SIZE_16_BIT:
1705 {
1706 int16_t value;
1707
1708 COPY_FROM_BUFFER( &value, ptr, sizeof(value) );
1709 [self searchIntegerShort:value];
1710
1711 break;
1712 }
1713
1714 case SIZE_32_BIT:
1715 {
1716 int32_t value;
1717
1718 COPY_FROM_BUFFER( &value, ptr, sizeof(value) );
1719 [self searchIntegerLong:value];
1720
1721 break;
1722 }
1723 }
1724 }
1725 break;
1726
1727 case TYPE_DECIMAL:
1728 {
1729 switch ( size )
1730 {
1731 case SIZE_32_BIT:
1732 {
1733 float value;
1734
1735 COPY_FROM_BUFFER( &value, ptr, sizeof(value) );
1736 [self searchDecimalFloat:value];
1737 }
1738 break;
1739
1740 case SIZE_64_BIT:
1741 {
1742 double value;
1743
1744 COPY_FROM_BUFFER( &value, ptr, sizeof(value) );
1745 [self searchDecimalDouble:value];
1746 }
1747 break;
1748 }
1749 }
1750 break;
1751 }
1752 }
1753
1754 [self sendVariableList:[(SearchResults *)[searchResults lastObject] data] amount:[[searchResults lastObject] amount]];
1755 [self sendSearchFinished];
1756 [self sendUndoRedoStatus];
1757
1758 [self setAction:nil];
1759 }
1760
1761 - (void)handleChange:(char const *)data size:(int)dataSize
1762 {
1763 TCtype type;
1764 TCsize size;
1765
1766 TCaddress *addresses = NULL;
1767 int count;
1768
1769 char *ptr = (char *)data;
1770
1771 [self setAction:@"Changing"];
1772
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) );
1776
1777 // read the amount of addresses.
1778 COPY_FROM_BUFFER( &count, ptr, sizeof(count) );
1779
1780 // save the pointer to the addresses.
1781 addresses = (TCaddress *)ptr;
1782 ptr += TCAddressSize*count;
1783
1784 switch ( type )
1785 {
1786 case TYPE_STRING:
1787 {
1788 switch ( size )
1789 {
1790 case SIZE_8_BIT:
1791 {
1792 [self changeString8bit:ptr size:(dataSize - (ptr - data)) addresses:addresses count:count];
1793 }
1794 break;
1795 }
1796 }
1797 break;
1798
1799 case TYPE_INTEGER:
1800 {
1801 switch ( size )
1802 {
1803 case SIZE_8_BIT:
1804 {
1805 int8_t value;
1806
1807 COPY_FROM_BUFFER( &value, ptr, sizeof(value) );
1808 [self changeIntegerChar:value addresses:addresses count:count];
1809 }
1810 break;
1811
1812 case SIZE_16_BIT:
1813 {
1814 int16_t value;
1815
1816 COPY_FROM_BUFFER( &value, ptr, sizeof(value) );
1817 [self changeIntegerShort:value addresses:addresses count:count];
1818 }
1819 break;
1820
1821 case SIZE_32_BIT:
1822 {
1823 int32_t value;
1824
1825 COPY_FROM_BUFFER( &value, ptr, sizeof(value) );
1826 [self changeIntegerLong:value addresses:addresses count:count];
1827 }
1828 break;
1829 }
1830 }
1831 break;
1832
1833 case TYPE_DECIMAL:
1834 {
1835 switch ( size )
1836 {
1837 case SIZE_32_BIT:
1838 {
1839 float value;
1840
1841 COPY_FROM_BUFFER( &value, ptr, sizeof(value) );
1842 [self changeDecimalFloat:value addresses:addresses count:count];
1843 }
1844 break;
1845
1846 case SIZE_64_BIT:
1847 {
1848 double value;
1849
1850 COPY_FROM_BUFFER( &value, ptr, sizeof(value) );
1851 [self changeDecimalDouble:value addresses:addresses count:count];
1852 }
1853 break;
1854 }
1855 }
1856 break;
1857 }
1858
1859 [self sendChangeFinished];
1860
1861 [self setAction:nil];
1862 }
1863
1864 - (void)handlePauseTarget
1865 {
1866 if ( !processPaused )
1867 {
1868 int wait_status;
1869
1870 NS_DURING
1871 {
1872 if ( ptrace( PT_ATTACH, processID, 0, 0 ) != -1 )
1873 {
1874 if ( waitpid( processID, &wait_status, WUNTRACED ) == processID )
1875 {
1876 if ( WIFSTOPPED(wait_status) )
1877 {
1878 processPaused = YES;
1879 [self sendPauseFinished:YES];
1880 }
1881 else
1882 {
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];
1886 }
1887 }
1888 else
1889 {
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];
1893 }
1894 }
1895 else
1896 {
1897 CMLog( @"ERROR: process couldn't be paused" );
1898 [self sendPauseFinished:NO];
1899
1900 switch ( errno )
1901 {
1902 case ESRCH:
1903 [self sendError:@"Could not pause target because there is no valid target to pause." fatal:NO];
1904 break;
1905
1906 case EINVAL:
1907 [self sendError:@"Could not pause target because a process cannot pause itself." fatal:NO];
1908 break;
1909
1910 case EBUSY:
1911 [self sendError:@"Could not pause target because the target is being controlled by another instance or application." fatal:NO];
1912 break;
1913
1914 case EPERM:
1915 [self sendError:@"Could not pause target because this type of application cannot be paused." fatal:NO];
1916 break;
1917
1918 default:
1919 [self sendError:@"Could not pause target because of an unknown error." fatal:NO];
1920 break;
1921 }
1922 }
1923 }
1924 NS_HANDLER
1925 {
1926 [self sendPauseFinished:NO];
1927 [self sendError:[NSString stringWithFormat:@"Could not pause target because an exception (%@) was raised: %@", [localException name], [localException reason]] fatal:NO];
1928 }
1929 NS_ENDHANDLER
1930 }
1931 else
1932 {
1933 ptrace( PT_DETACH, processID, 0, 0 );
1934
1935 processPaused = NO;
1936 [self sendPauseFinished:NO];
1937 }
1938 }
1939
1940 - (void)handleUndo
1941 {
1942 SearchResults *results = [searchResults lastObject];
1943
1944 if ( results )
1945 {
1946 [searchResultsUndone addObject:results];
1947 [searchResults removeLastObject];
1948 }
1949
1950 results = [searchResults lastObject];
1951 if ( results )
1952 {
1953 [self sendVariableList:[results data] amount:[results amount]];
1954 }
1955 else
1956 {
1957 [self sendVariableList:NULL amount:0];
1958 }
1959
1960 [self sendUndoFinished];
1961 [self sendUndoRedoStatus];
1962 }
1963
1964 - (void)handleRedo
1965 {
1966 SearchResults *results = [searchResultsUndone lastObject];
1967
1968 if ( results )
1969 {
1970 [searchResults addObject:results];
1971 [searchResultsUndone removeLastObject];
1972 }
1973
1974 results = [searchResults lastObject];
1975 if ( results )
1976 {
1977 [self sendVariableList:[results data] amount:[results amount]];
1978 }
1979 else
1980 {
1981 [self sendVariableList:NULL amount:0];
1982 }
1983
1984 [self sendRedoFinished];
1985 [self sendUndoRedoStatus];
1986 }
1987
1988 - (void)handleSetTargetPID:(char const *)data size:(int)size
1989 {
1990 char *ptr = (char *)data;
1991
1992 pid_t pid;
1993
1994 COPY_FROM_BUFFER( &pid, ptr, sizeof(pid) );
1995
1996 [self setPID:pid];
1997 }
1998
1999
2000 - (void)unpause
2001 {
2002 if ( processPaused )
2003 {
2004 [self handlePauseTarget];
2005 }
2006 }
2007
2008 - (void)setPID:(pid_t)pid
2009 {
2010 kern_return_t result;
2011
2012 [self unpause];
2013
2014 processID = pid;
2015
2016 if ( (result = task_for_pid( current_task(), processID, &processTask)) != KERN_SUCCESS )
2017 {
2018 CMLog( @"task_for_pid returned error: %i", result );
2019 }
2020 }
2021
2022
2023 - (void)dealloc
2024 {
2025 [self unpause];
2026
2027 [[[NSWorkspace sharedWorkspace] notificationCenter] removeObserver:self];
2028
2029 [searchResults release];
2030 [searchResultsUndone release];
2031
2032 [super dealloc];
2033 }
2034
2035
2036 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2037 %%%%%%%%%%%%%%%%%%%%%% NSWorkspaceDidLaunchApplicationNotification Notification
2038 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
2039
2040
2041 - (void)processListChanged:(NSNotification *)note
2042 {
2043 pid_t pid = [[[note userInfo] objectForKey:@"NSApplicationProcessIdentifier"] intValue];
2044
2045 if ( /*pid != getpid()*/ sockfd != -1 )
2046 {
2047 if ( [[note name] isEqualToString:@"NSWorkspaceDidLaunchApplicationNotification"] )
2048 {
2049 [self sendAppLaunched:[note userInfo]];
2050 }
2051 else
2052 {
2053 [self sendAppQuit:[note userInfo]];
2054
2055 if ( pid == processID )
2056 {
2057 [self sendTargetAppQuit];
2058
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]];
2062 processPaused = NO;
2063 }
2064 }
2065 }
2066 }
2067
2068
2069 @end
2070
2071
2072 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2073 %%%%%%%%%%%%%%%%%%%%%% Internal Functions
2074 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
2075
2076
2077 #define ASIZE 256
2078 int bmsearch( char *pat, int m, char *text, int n, void *base, void *loc[] )
2079 {
2080 int count = 0;
2081 int i, j, k, skip[ASIZE];
2082
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;
2086
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--;
2089 if( j == (-1) )
2090 /* SAVE LOCATION */
2091 loc[count++] = (void *)( base+i+1 );
2092 //return( text+i+1 );
2093 }
2094 return count;
2095 }
2096
2097 /*
2098 BOOL compare_float( float a, float b )
2099 {
2100 float const feps = 0.0001f;
2101
2102 return feps > fabsf( a - b );
2103 }
2104
2105 BOOL compare_double( double a, double b )
2106 {
2107 double const deps = 0.0000001;
2108
2109 return deps > fabs( a - b );
2110 }*/
This page took 0.140123 seconds and 5 git commands to generate.