Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(506)

Side by Side Diff: third_party/mach_override/mach_override.c

Issue 61273002: Update mach_override to upstream 1a1bb352 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « third_party/mach_override/mach_override.h ('k') | third_party/mach_override/mach_override.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /******************************************************************************* 1 // mach_override.c semver:1.2.0
Mark Mentovai 2013/11/05 23:35:37 This patch set contains our local changes merged b
2 » mach_override.c 2 // Copyright (c) 2003-2012 Jonathan 'Wolf' Rentzsch: http://rentzsch.com
3 » » Copyright (c) 2003-2009 Jonathan 'Wolf' Rentzsch: <http://rentzs ch.com> 3 // Some rights reserved: http://opensource.org/licenses/mit
4 » » Some rights reserved: <http://opensource.org/licenses/mit-licens e.php> 4 // https://github.com/rentzsch/mach_override
5 5
6 ************************************************************************ ***/
7
8 #include "mach_override.h" 6 #include "mach_override.h"
7 #if defined(__i386__) || defined(__x86_64__)
8 #include "udis86.h"
9 #endif
9 10
10 #include <mach-o/dyld.h> 11 #include <mach-o/dyld.h>
11 #include <mach/mach_host.h> 12 #include <mach/mach_host.h>
12 #include <mach/mach_init.h> 13 #include <mach/mach_init.h>
13 #include <mach/vm_map.h> 14 #include <mach/vm_map.h>
14 #include <mach/vm_statistics.h> 15 #include <mach/vm_statistics.h>
15 #include <sys/mman.h> 16 #include <sys/mman.h>
16 17
17 #include <CoreServices/CoreServices.h> 18 #include <CoreServices/CoreServices.h>
18 19
19 /************************** 20 /**************************
20 * 21 *
21 * Constants 22 * Constants
22 * 23 *
23 **************************/ 24 **************************/
24 #pragma mark - 25 #pragma mark -
25 #pragma mark (Constants) 26 #pragma mark (Constants)
26 27
27 #define kPageSize 4096
28 #if defined(__ppc__) || defined(__POWERPC__) 28 #if defined(__ppc__) || defined(__POWERPC__)
29 29
30 long kIslandTemplate[] = { 30 long kIslandTemplate[] = {
31 0x9001FFFC, // stw r0,-4(SP) 31 0x9001FFFC, // stw r0,-4(SP)
32 0x3C00DEAD, // lis r0,0xDEAD 32 0x3C00DEAD, // lis r0,0xDEAD
33 0x6000BEEF, // ori r0,r0,0xBEEF 33 0x6000BEEF, // ori r0,r0,0xBEEF
34 0x7C0903A6, // mtctr r0 34 0x7C0903A6, // mtctr r0
35 0x8001FFFC, // lwz r0,-4(SP) 35 0x8001FFFC, // lwz r0,-4(SP)
36 0x60000000, // nop ; optionally replaced 36 0x60000000, // nop ; optionally replaced
37 0x4E800420 // bctr 37 0x4E800420 // bctr
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
71 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 71 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
72 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 72 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
73 // Now the real jump instruction 73 // Now the real jump instruction
74 0xFF, 0x25, 0x00, 0x00, 0x00, 0x00, 74 0xFF, 0x25, 0x00, 0x00, 0x00, 0x00,
75 0x00, 0x00, 0x00, 0x00, 75 0x00, 0x00, 0x00, 0x00,
76 0x00, 0x00, 0x00, 0x00 76 0x00, 0x00, 0x00, 0x00
77 }; 77 };
78 78
79 #endif 79 #endif
80 80
81 #define kAllocateHigh 1
82 #define kAllocateNormal 0
83
81 /************************** 84 /**************************
82 * 85 *
83 * Data Types 86 * Data Types
84 * 87 *
85 **************************/ 88 **************************/
86 #pragma mark - 89 #pragma mark -
87 #pragma mark (Data Types) 90 #pragma mark (Data Types)
88 91
89 typedef struct { 92 typedef struct {
90 char instructions[sizeof(kIslandTemplate)]; 93 char instructions[sizeof(kIslandTemplate)];
94 int allocatedHigh;
91 } BranchIsland; 95 } BranchIsland;
92 96
93 /************************** 97 /**************************
94 * 98 *
95 * Funky Protos 99 * Funky Protos
96 * 100 *
97 **************************/ 101 **************************/
98 #pragma mark - 102 #pragma mark -
99 #pragma mark (Funky Protos) 103 #pragma mark (Funky Protos)
100 104
101 mach_error_t 105 mach_error_t
102 allocateBranchIsland( 106 allocateBranchIsland(
103 BranchIsland **island, 107 BranchIsland **island,
108 int allocateHigh,
104 void *originalFunctionAddress); 109 void *originalFunctionAddress);
105 110
106 mach_error_t 111 mach_error_t
107 freeBranchIsland( 112 freeBranchIsland(
108 BranchIsland *island ); 113 BranchIsland *island );
109 114
110 #if defined(__ppc__) || defined(__POWERPC__) 115 #if defined(__ppc__) || defined(__POWERPC__)
111 mach_error_t 116 mach_error_t
112 setBranchIslandTarget( 117 setBranchIslandTarget(
113 BranchIsland *island, 118 BranchIsland *island,
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
148 * 153 *
149 * Interface 154 * Interface
150 * 155 *
151 *******************************************************************************/ 156 *******************************************************************************/
152 #pragma mark - 157 #pragma mark -
153 #pragma mark (Interface) 158 #pragma mark (Interface)
154 159
155 #if defined(__i386__) || defined(__x86_64__) 160 #if defined(__i386__) || defined(__x86_64__)
156 mach_error_t makeIslandExecutable(void *address) { 161 mach_error_t makeIslandExecutable(void *address) {
157 mach_error_t err = err_none; 162 mach_error_t err = err_none;
158 uintptr_t page = (uintptr_t)address & ~(uintptr_t)(kPageSize-1); 163 vm_size_t pageSize;
164 host_page_size( mach_host_self(), &pageSize );
165 uintptr_t page = (uintptr_t)address & ~(uintptr_t)(pageSize-1);
159 int e = err_none; 166 int e = err_none;
160 e |= mprotect((void *)page, kPageSize, PROT_EXEC | PROT_READ); 167 e |= mprotect((void *)page, pageSize, PROT_EXEC | PROT_READ);
161 e |= msync((void *)page, kPageSize, MS_INVALIDATE ); 168 e |= msync((void *)page, pageSize, MS_INVALIDATE );
162 if (e) { 169 if (e) {
163 err = err_cannot_override; 170 err = err_cannot_override;
164 } 171 }
165 return err; 172 return err;
166 } 173 }
167 #endif 174 #endif
168 175
169 mach_error_t 176 mach_error_t
170 mach_override_ptr( 177 mach_override_ptr(
171 void *originalFunctionAddress, 178 void *originalFunctionAddress,
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 if( err ) 236 if( err )
230 err = vm_protect( mach_task_self(), 237 err = vm_protect( mach_task_self(),
231 (vm_address_t) originalFunctionPtr, 8, f alse, 238 (vm_address_t) originalFunctionPtr, 8, f alse,
232 (VM_PROT_DEFAULT | VM_PROT_COPY) ); 239 (VM_PROT_DEFAULT | VM_PROT_COPY) );
233 } 240 }
234 if (err) fprintf(stderr, "err = %x %s:%d\n", err, __FILE__, __LINE__); 241 if (err) fprintf(stderr, "err = %x %s:%d\n", err, __FILE__, __LINE__);
235 242
236 // Allocate and target the escape island to the overriding function . 243 // Allocate and target the escape island to the overriding function .
237 BranchIsland *escapeIsland = NULL; 244 BranchIsland *escapeIsland = NULL;
238 if( !err ) 245 if( !err )
239 » » err = allocateBranchIsland( &escapeIsland, originalFunctionAddre ss ); 246 » » err = allocateBranchIsland( &escapeIsland, kAllocateHigh, origin alFunctionAddress );
240 if (err) fprintf(stderr, "err = %x %s:%d\n", err, __FILE__, __LI NE__); 247 if (err) fprintf(stderr, "err = %x %s:%d\n", err, __FILE__, __LI NE__);
241 248
242 249
243 #if defined(__ppc__) || defined(__POWERPC__) 250 #if defined(__ppc__) || defined(__POWERPC__)
244 if( !err ) 251 if( !err )
245 err = setBranchIslandTarget( escapeIsland, overrideFunctionAddre ss, 0 ); 252 err = setBranchIslandTarget( escapeIsland, overrideFunctionAddre ss, 0 );
246 253
247 // Build the branch absolute instruction to the escape island. 254 // Build the branch absolute instruction to the escape island.
248 long branchAbsoluteInstruction = 0; // Set to 0 just to silence warni ng. 255 long branchAbsoluteInstruction = 0; // Set to 0 just to silence warni ng.
249 if( !err ) { 256 if( !err ) {
(...skipping 21 matching lines...) Expand all
271 jumpRelativeInstruction = OSSwapInt64(jumpRelativeInstruction); 278 jumpRelativeInstruction = OSSwapInt64(jumpRelativeInstruction);
272 } 279 }
273 #endif 280 #endif
274 281
275 // Optionally allocate & return the reentry island. This may contai n relocated 282 // Optionally allocate & return the reentry island. This may contai n relocated
276 // jmp instructions and so has all the same addressing reachability req uirements 283 // jmp instructions and so has all the same addressing reachability req uirements
277 // the escape island has to the original function, except the escape is land is 284 // the escape island has to the original function, except the escape is land is
278 // technically our original function. 285 // technically our original function.
279 BranchIsland *reentryIsland = NULL; 286 BranchIsland *reentryIsland = NULL;
280 if( !err && originalFunctionReentryIsland ) { 287 if( !err && originalFunctionReentryIsland ) {
281 » » err = allocateBranchIsland( &reentryIsland, escapeIsland); 288 » » err = allocateBranchIsland( &reentryIsland, kAllocateHigh, escap eIsland);
282 if( !err ) 289 if( !err )
283 *originalFunctionReentryIsland = reentryIsland; 290 *originalFunctionReentryIsland = reentryIsland;
284 } 291 }
285 292
286 #if defined(__ppc__) || defined(__POWERPC__) 293 #if defined(__ppc__) || defined(__POWERPC__)
287 // Atomically: 294 // Atomically:
288 // o If the reentry island was allocated: 295 // o If the reentry island was allocated:
289 // o Insert the original instruction into the reentry islan d. 296 // o Insert the original instruction into the reentry islan d.
290 // o Target the reentry island at the 2nd instruction of th e 297 // o Target the reentry island at the 2nd instruction of th e
291 // original function. 298 // original function.
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
357 } 364 }
358 365
359 /******************************************************************************* 366 /*******************************************************************************
360 * 367 *
361 * Implementation 368 * Implementation
362 * 369 *
363 *******************************************************************************/ 370 *******************************************************************************/
364 #pragma mark - 371 #pragma mark -
365 #pragma mark (Implementation) 372 #pragma mark (Implementation)
366 373
367 /***************************************************************************//** 374 /*******************************************************************************
368 Implementation: Allocates memory for a branch island. 375 Implementation: Allocates memory for a branch island.
369 376
370 @param island <- The allocated island. 377 @param island <- The allocated island.
378 @param allocateHigh -> Whether to allocate the island at the en d of the
379 address space (f or use with the branch absolute
380 instruction).
371 @result <- mach_error_t 381 @result <- mach_error_t
372 382
373 ************************************************************************ ***/ 383 ************************************************************************ ***/
374 384
375 mach_error_t 385 mach_error_t
376 allocateBranchIsland( 386 allocateBranchIsland(
377 BranchIsland **island, 387 BranchIsland **island,
388 int allocateHigh,
378 void *originalFunctionAddress) 389 void *originalFunctionAddress)
379 { 390 {
380 assert( island ); 391 assert( island );
381 392
382 » assert( sizeof( BranchIsland ) <= kPageSize ); 393 » mach_error_t» err = err_none;
394 »
395 » if( allocateHigh ) {
396 » » vm_size_t pageSize;
397 » » err = host_page_size( mach_host_self(), &pageSize );
398 » » if( !err ) {
399 » » » assert( sizeof( BranchIsland ) <= pageSize );
383 #if defined(__i386__) 400 #if defined(__i386__)
384 » vm_address_t page = 0; 401 » » » vm_address_t page = 0;
385 » mach_error_t err = vm_allocate( mach_task_self(), &page, kPageSize, VM_F LAGS_ANYWHERE ); 402 » » » mach_error_t err = vm_allocate( mach_task_self(), &page, pageSize, VM_FLAGS_ANYWHERE );
386 » if( err == err_none ) { 403 » » » if( err == err_none ) {
387 » » *island = (BranchIsland*) page; 404 » » » » *island = (BranchIsland*) page;
388 » » return err_none; 405 » » » » return err_none;
389 » } 406 » » » }
390 » return err; 407 » » » return err;
391 #else 408 #else
392 409
393 #if defined(__ppc__) || defined(__POWERPC__) 410 #if defined(__ppc__) || defined(__POWERPC__)
394 » vm_address_t first = 0xfeffffff; 411 » » » vm_address_t first = 0xfeffffff;
395 » vm_address_t last = 0xfe000000 + kPageSize; 412 » » » vm_address_t last = 0xfe000000 + pageSize;
396 #elif defined(__x86_64__) 413 #elif defined(__x86_64__)
397 » vm_address_t first = ((uint64_t)originalFunctionAddress & ~(uint64_t)((( uint64_t)1 << 31) - 1)) | ((uint64_t)1 << 31); // start in the middle of the pag e? 414 » » » vm_address_t first = ((uint64_t)originalFunctionAddress & ~(uint64_t)(((uint64_t)1 << 31) - 1)) | ((uint64_t)1 << 31); // start in the m iddle of the page?
398 » vm_address_t last = 0x0; 415 » » » vm_address_t last = 0x0;
399 #endif 416 #endif
400 417
401 » vm_address_t page = first; 418 » » » vm_address_t page = first;
402 » vm_map_t task_self = mach_task_self(); 419 » » » int allocated = 0;
420 » » » vm_map_t task_self = mach_task_self();
421 » » »
422 » » » while( !err && !allocated && page != last ) {
403 423
404 » while( page != last ) { 424 » » » » err = vm_allocate( task_self, &page, pageSize, 0 );
405 » » mach_error_t err = vm_allocate( task_self, &page, kPageSize, 0 ) ; 425 » » » » if( err == err_none )
406 » » if( err == err_none ) { 426 » » » » » allocated = 1;
407 » » » *island = (BranchIsland*) page; 427 » » » » else if( err == KERN_NO_SPACE ) {
408 » » » return err_none;
409 }
410 » » if( err != KERN_NO_SPACE )
411 » » » return err;
412 #if defined(__x86_64__) 428 #if defined(__x86_64__)
413 » » page -= kPageSize; 429 » » » » » page -= pageSize;
414 #else 430 #else
415 » » page += kPageSize; 431 » » » » » page += pageSize;
416 #endif 432 #endif
417 » » err = err_none; 433 » » » » » err = err_none;
434 » » » » }
435 » » » }
436 » » » if( allocated )
437 » » » » *island = (BranchIsland*) page;
438 » » » else if( !allocated && !err )
439 » » » » err = KERN_NO_SPACE;
440 #endif
441 » » }
442 » } else {
443 » » void *block = malloc( sizeof( BranchIsland ) );
444 » » if( block )
445 » » » *island = block;
446 » » else
447 » » » err = KERN_NO_SPACE;
418 } 448 }
419 449 » if( !err )
420 » return KERN_NO_SPACE; 450 » » (**island).allocatedHigh = allocateHigh;
421 #endif 451 »
452 » return err;
422 } 453 }
423 454
424 /***************************************************************************//** 455 /*******************************************************************************
425 Implementation: Deallocates memory for a branch island. 456 Implementation: Deallocates memory for a branch island.
426 457
427 @param island -> The island to deallocate. 458 @param island -> The island to deallocate.
428 @result <- mach_error_t 459 @result <- mach_error_t
429 460
430 ************************************************************************ ***/ 461 ************************************************************************ ***/
431 462
432 mach_error_t 463 mach_error_t
433 freeBranchIsland( 464 freeBranchIsland(
434 BranchIsland *island ) 465 BranchIsland *island )
435 { 466 {
436 assert( island ); 467 assert( island );
437 assert( (*(long*)&island->instructions[0]) == kIslandTemplate[0] ); 468 assert( (*(long*)&island->instructions[0]) == kIslandTemplate[0] );
438 » assert( sizeof( BranchIsland ) <= kPageSize ); 469 » assert( island->allocatedHigh );
439 » return vm_deallocate( mach_task_self(), (vm_address_t) island, 470 »
440 » » » kPageSize ); 471 » mach_error_t» err = err_none;
472 »
473 » if( island->allocatedHigh ) {
474 » » vm_size_t pageSize;
475 » » err = host_page_size( mach_host_self(), &pageSize );
476 » » if( !err ) {
477 » » » assert( sizeof( BranchIsland ) <= pageSize );
478 » » » err = vm_deallocate(
479 » » » » » mach_task_self(),
480 » » » » » (vm_address_t) island, pageSize );
481 » » }
482 » } else {
483 » » free( island );
484 » }
485 »
486 » return err;
441 } 487 }
442 488
443 /***************************************************************************//** 489 /*******************************************************************************
444 Implementation: Sets the branch island's target, with an optional 490 Implementation: Sets the branch island's target, with an optional
445 instruction. 491 instruction.
446 492
447 @param island -> The branch island to insert target into. 493 @param island -> The branch island to insert target into.
448 @param branchTo -> The address of the target. 494 @param branchTo -> The address of the target.
449 @param instruction -> Optional instruction to execute prior to branch. Set 495 @param instruction -> Optional instruction to execute prior to branch. Set
450 to zero for nop. 496 to zero for nop.
451 @result <- mach_error_t 497 @result <- mach_error_t
452 498
453 ************************************************************************ ***/ 499 ************************************************************************ ***/
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
523 // Fill in the address. 569 // Fill in the address.
524 *((uint64_t *)(island->instructions + kJumpAddress)) = (uint64_t)branchTo; 570 *((uint64_t *)(island->instructions + kJumpAddress)) = (uint64_t)branchTo;
525 msync( island->instructions, sizeof( kIslandTemplate ), MS_INVALIDATE ); 571 msync( island->instructions, sizeof( kIslandTemplate ), MS_INVALIDATE );
526 572
527 return err_none; 573 return err_none;
528 } 574 }
529 #endif 575 #endif
530 576
531 577
532 #if defined(__i386__) || defined(__x86_64__) 578 #if defined(__i386__) || defined(__x86_64__)
533 // simplistic instruction matching
534 typedef struct {
535 unsigned int length; // max 15
536 unsigned char mask[15]; // sequence of bytes in memory order
537 unsigned char constraint[15]; // sequence of bytes in memory order
538 } AsmInstructionMatch;
539
540 #if defined(__i386__)
541 static AsmInstructionMatch possibleInstructions[] = {
542 { 0x5, {0xFF, 0x00, 0x00, 0x00, 0x00}, {0xE9, 0x00, 0x00, 0x00, 0x00} }, // jmp 0x????????
543 { 0x5, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, {0x55, 0x89, 0xe5, 0xc9, 0xc3} }, // push %ebp; mov %esp,%ebp; leave; ret
544 { 0x1, {0xFF}, {0x90} }, // nop
545 { 0x1, {0xFF}, {0x55} }, // push %esp
546 { 0x2, {0xFF, 0xFF}, {0x89, 0xE5} }, // mov %esp,%ebp
547 { 0x1, {0xFF}, {0x53} }, // push %ebx
548 { 0x3, {0xFF, 0xFF, 0x00}, {0x83, 0xEC, 0x00} }, // sub 0x??, %esp
549 { 0x6, {0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00}, {0x81, 0xEC, 0x00, 0x00, 0x 00, 0x00} }, // sub 0x??, %esp with 32bit immediate
550 { 0x1, {0xFF}, {0x57} }, // push %edi
551 { 0x1, {0xFF}, {0x56} }, // push %esi
552 { 0x2, {0xFF, 0xFF}, {0x31, 0xC0} }, // xor %eax, %eax
553 { 0x3, {0xFF, 0x4F, 0x00}, {0x8B, 0x45, 0x00} }, // mov $imm(%ebp), %re g
554 { 0x3, {0xFF, 0x4C, 0x00}, {0x8B, 0x40, 0x00} }, // mov $imm(%eax-%edx) , %reg
555 { 0x4, {0xFF, 0xFF, 0xFF, 0x00}, {0x8B, 0x4C, 0x24, 0x00} }, // mov $im m(%esp), %ecx
556 { 0x5, {0xFF, 0x00, 0x00, 0x00, 0x00}, {0xB8, 0x00, 0x00, 0x00, 0x00} }, // mov $imm, %eax
557 { 0x0 }
558 };
559 #elif defined(__x86_64__)
560 static AsmInstructionMatch possibleInstructions[] = {
561 { 0x5, {0xFF, 0x00, 0x00, 0x00, 0x00}, {0xE9, 0x00, 0x00, 0x00, 0x00} }, // jmp 0x????????
562 { 0x1, {0xFF}, {0x90} }, // nop
563 { 0x1, {0xF8}, {0x50} }, // push %rX
564 { 0x3, {0xFF, 0xFF, 0xFF}, {0x48, 0x89, 0xE5} }, // mov %rsp,%rbp
565 { 0x4, {0xFF, 0xFF, 0xFF, 0x00}, {0x48, 0x83, 0xEC, 0x00} }, // sub 0x??, %rsp
566 { 0x4, {0xFB, 0xFF, 0x00, 0x00}, {0x48, 0x89, 0x00, 0x00} }, // move onto rbp
567 { 0x2, {0xFF, 0x00}, {0x41, 0x00} }, // push %rXX
568 { 0x2, {0xFF, 0x00}, {0x85, 0x00} }, // test %rX,%rX
569 { 0x5, {0xF8, 0x00, 0x00, 0x00, 0x00}, {0xB8, 0x00, 0x00, 0x00, 0x00} }, // mov $imm, %reg
570 { 0x3, {0xFF, 0xFF, 0x00}, {0xFF, 0x77, 0x00} }, // pushq $imm(%rdi)
571 { 0x2, {0xFF, 0xFF}, {0x31, 0xC0} }, // xor %eax, %eax
572 { 0x2, {0xFF, 0xFF}, {0x89, 0xF8} }, // mov %edi, %ea x
573 { 0x0 }
574 };
575 #endif
576
577 static Boolean codeMatchesInstruction(unsigned char *code, AsmInstructionMatch* instruction)
578 {
579 Boolean match = true;
580
581 size_t i;
582 for (i=0; i<instruction->length; i++) {
583 unsigned char mask = instruction->mask[i];
584 unsigned char constraint = instruction->constraint[i];
585 unsigned char codeValue = code[i];
586
587 match = ((codeValue & mask) == constraint);
588 if (!match) break;
589 }
590
591 return match;
592 }
593
594 #if defined(__i386__) || defined(__x86_64__)
595 static Boolean 579 static Boolean
596 eatKnownInstructions( 580 eatKnownInstructions(
597 unsigned char *code, 581 unsigned char *code,
598 uint64_t *newInstruction, 582 uint64_t *newInstruction,
599 int *howManyEaten, 583 int *howManyEaten,
600 char *originalInstructions, 584 char *originalInstructions,
601 int *originalInstructionCount, 585 int *originalInstructionCount,
602 uint8_t *originalInstructionSizes ) 586 uint8_t *originalInstructionSizes )
603 { 587 {
604 Boolean allInstructionsKnown = true; 588 Boolean allInstructionsKnown = true;
605 int totalEaten = 0; 589 int totalEaten = 0;
606 unsigned char* ptr = code;
607 int remainsToEat = 5; // a JMP instruction takes 5 bytes 590 int remainsToEat = 5; // a JMP instruction takes 5 bytes
608 int instructionIndex = 0; 591 int instructionIndex = 0;
592 ud_t ud_obj;
609 593
610 if (howManyEaten) *howManyEaten = 0; 594 if (howManyEaten) *howManyEaten = 0;
611 if (originalInstructionCount) *originalInstructionCount = 0; 595 if (originalInstructionCount) *originalInstructionCount = 0;
596 ud_init(&ud_obj);
597 #if defined(__i386__)
598 ud_set_mode(&ud_obj, 32);
599 #else
600 ud_set_mode(&ud_obj, 64);
601 #endif
602 ud_set_input_buffer(&ud_obj, code, 64); // Assume that 'code' points to at least 64bytes of data.
612 while (remainsToEat > 0) { 603 while (remainsToEat > 0) {
613 » » Boolean curInstructionKnown = false; 604 » » if (!ud_disassemble(&ud_obj)) {
614 » » 605 » » allInstructionsKnown = false;
615 » » // See if instruction matches one we know 606 » » fprintf(stderr, "mach_override: some instructions unknown! N eed to update libudis86\n");
616 » » AsmInstructionMatch* curInstr = possibleInstructions; 607 » » break;
617 » » do {
618 » » » if ((curInstructionKnown = codeMatchesInstruction(ptr, c urInstr))) break;
619 » » » curInstr++;
620 » » } while (curInstr->length > 0);
621 » »
622 » » // if all instruction matches failed, we don't know current inst ruction then, stop here
623 » » if (!curInstructionKnown) {
624 » » » allInstructionsKnown = false;
625 » » » fprintf(stderr, "mach_override: some instructions unknow n! Need to update mach_override.c\n");
626 » » » break;
627 } 608 }
628 609
629 // At this point, we've matched curInstr 610 // At this point, we've matched curInstr
630 » » int eaten = curInstr->length; 611 » » int eaten = ud_insn_len(&ud_obj);
631 » » ptr += eaten;
632 remainsToEat -= eaten; 612 remainsToEat -= eaten;
633 totalEaten += eaten; 613 totalEaten += eaten;
634 614
635 if (originalInstructionSizes) originalInstructionSizes[instructi onIndex] = eaten; 615 if (originalInstructionSizes) originalInstructionSizes[instructi onIndex] = eaten;
636 instructionIndex += 1; 616 instructionIndex += 1;
637 if (originalInstructionCount) *originalInstructionCount = instru ctionIndex; 617 if (originalInstructionCount) *originalInstructionCount = instru ctionIndex;
638 } 618 }
639 619
640 620
641 if (howManyEaten) *howManyEaten = totalEaten; 621 if (howManyEaten) *howManyEaten = totalEaten;
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
682 uint32_t offset = (uintptr_t)originalFunction - (uintptr _t)escapeIsland; 662 uint32_t offset = (uintptr_t)originalFunction - (uintptr _t)escapeIsland;
683 uint32_t *jumpOffsetPtr = (uint32_t*)((uintptr_t)instruc tionsToFix + 1); 663 uint32_t *jumpOffsetPtr = (uint32_t*)((uintptr_t)instruc tionsToFix + 1);
684 *jumpOffsetPtr += offset; 664 *jumpOffsetPtr += offset;
685 } 665 }
686 666
687 originalFunction = (void*)((uintptr_t)originalFunction + instruc tionSizes[index]); 667 originalFunction = (void*)((uintptr_t)originalFunction + instruc tionSizes[index]);
688 escapeIsland = (void*)((uintptr_t)escapeIsland + instructionSize s[index]); 668 escapeIsland = (void*)((uintptr_t)escapeIsland + instructionSize s[index]);
689 instructionsToFix = (void*)((uintptr_t)instructionsToFix + instr uctionSizes[index]); 669 instructionsToFix = (void*)((uintptr_t)instructionsToFix + instr uctionSizes[index]);
690 } 670 }
691 } 671 }
692 #endif
693 672
694 #if defined(__i386__) 673 #if defined(__i386__)
695 __asm( 674 __asm(
696 ".text;" 675 ".text;"
697 ".align 2, 0x90;" 676 ".align 2, 0x90;"
698 "_atomic_mov64:;" 677 "_atomic_mov64:;"
699 " pushl %ebp;" 678 " pushl %ebp;"
700 " movl %esp, %ebp;" 679 " movl %esp, %ebp;"
701 " pushl %esi;" 680 " pushl %esi;"
702 " pushl %ebx;" 681 " pushl %ebx;"
(...skipping 25 matching lines...) Expand all
728 ); 707 );
729 #elif defined(__x86_64__) 708 #elif defined(__x86_64__)
730 void atomic_mov64( 709 void atomic_mov64(
731 uint64_t *targetAddress, 710 uint64_t *targetAddress,
732 uint64_t value ) 711 uint64_t value )
733 { 712 {
734 *targetAddress = value; 713 *targetAddress = value;
735 } 714 }
736 #endif 715 #endif
737 #endif 716 #endif
OLDNEW
« no previous file with comments | « third_party/mach_override/mach_override.h ('k') | third_party/mach_override/mach_override.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698