| OLD | NEW | 
|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include "courgette/disassembler_win32_x64.h" | 5 #include "courgette/disassembler_win32_x64.h" | 
| 6 | 6 | 
| 7 #include <algorithm> | 7 #include <algorithm> | 
| 8 #include <string> | 8 #include <string> | 
| 9 #include <vector> | 9 #include <vector> | 
| 10 | 10 | 
| (...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 455       } | 455       } | 
| 456     } | 456     } | 
| 457 | 457 | 
| 458     //while (abs32_pos != abs32_locations_.end() && *abs32_pos < current_rva) | 458     //while (abs32_pos != abs32_locations_.end() && *abs32_pos < current_rva) | 
| 459     //  ++abs32_pos; | 459     //  ++abs32_pos; | 
| 460 | 460 | 
| 461     // Heuristic discovery of rel32 locations in instruction stream: are the | 461     // Heuristic discovery of rel32 locations in instruction stream: are the | 
| 462     // next few bytes the start of an instruction containing a rel32 | 462     // next few bytes the start of an instruction containing a rel32 | 
| 463     // addressing mode? | 463     // addressing mode? | 
| 464     const uint8* rel32 = NULL; | 464     const uint8* rel32 = NULL; | 
|  | 465     bool is_rip_relative = false; | 
| 465 | 466 | 
| 466     if (p + 5 <= end_pointer) { | 467     if (p + 5 <= end_pointer) { | 
| 467       if (*p == 0xE8 || *p == 0xE9) {  // jmp rel32 and call rel32 | 468       if (*p == 0xE8 || *p == 0xE9)  // jmp rel32 and call rel32 | 
| 468         rel32 = p + 1; | 469         rel32 = p + 1; | 
|  | 470     } | 
|  | 471     if (p + 6 <= end_pointer) { | 
|  | 472       if (*p == 0x0F && (*(p + 1) & 0xF0) == 0x80) {  // Jcc long form | 
|  | 473         if (p[1] != 0x8A && p[1] != 0x8B)  // JPE/JPO unlikely | 
|  | 474           rel32 = p + 2; | 
|  | 475       } else if (*p == 0xFF && (*(p + 1) == 0x15 || *(p + 1) == 0x25)) { | 
|  | 476         // rip relative call/jmp | 
|  | 477         rel32 = p + 2; | 
|  | 478         is_rip_relative = true; | 
| 469       } | 479       } | 
| 470     } | 480     } | 
| 471     if (p + 6 <= end_pointer) { | 481     if (p + 7 <= end_pointer) { | 
| 472       if (*p == 0x0F  &&  (*(p+1) & 0xF0) == 0x80) {  // Jcc long form | 482       if ((*p & 0xFB) == 0x48 && *(p + 1) == 0x8D && | 
| 473         if (p[1] != 0x8A && p[1] != 0x8B)  // JPE/JPO unlikely | 483           (*(p + 2) & 0xC7) == 0x05) { | 
| 474           rel32 = p + 2; | 484         // rip relative lea | 
|  | 485         rel32 = p + 3; | 
|  | 486         is_rip_relative = true; | 
|  | 487       } else if ((*p & 0xFB) == 0x48 && *(p + 1) == 0x8B && | 
|  | 488                  (*(p + 2) & 0xC7) == 0x05) { | 
|  | 489         // rip relative mov | 
|  | 490         rel32 = p + 3; | 
|  | 491         is_rip_relative = true; | 
| 475       } | 492       } | 
| 476     } | 493     } | 
|  | 494 | 
| 477     if (rel32) { | 495     if (rel32) { | 
| 478       RVA rel32_rva = static_cast<RVA>(rel32 - adjust_pointer_to_rva); | 496       RVA rel32_rva = static_cast<RVA>(rel32 - adjust_pointer_to_rva); | 
| 479 | 497 | 
| 480       // Is there an abs32 reloc overlapping the candidate? | 498       // Is there an abs32 reloc overlapping the candidate? | 
| 481       while (abs32_pos != abs32_locations_.end() && *abs32_pos < rel32_rva - 3) | 499       while (abs32_pos != abs32_locations_.end() && *abs32_pos < rel32_rva - 3) | 
| 482         ++abs32_pos; | 500         ++abs32_pos; | 
| 483       // Now: (*abs32_pos > rel32_rva - 4) i.e. the lowest addressed 4-byte | 501       // Now: (*abs32_pos > rel32_rva - 4) i.e. the lowest addressed 4-byte | 
| 484       // region that could overlap rel32_rva. | 502       // region that could overlap rel32_rva. | 
| 485       if (abs32_pos != abs32_locations_.end()) { | 503       if (abs32_pos != abs32_locations_.end()) { | 
| 486         if (*abs32_pos < rel32_rva + 4) { | 504         if (*abs32_pos < rel32_rva + 4) { | 
| 487           // Beginning of abs32 reloc is before end of rel32 reloc so they | 505           // Beginning of abs32 reloc is before end of rel32 reloc so they | 
| 488           // overlap.  Skip four bytes past the abs32 reloc. | 506           // overlap.  Skip four bytes past the abs32 reloc. | 
| 489           p += (*abs32_pos + 4) - current_rva; | 507           p += (*abs32_pos + 4) - current_rva; | 
| 490           continue; | 508           continue; | 
| 491         } | 509         } | 
| 492       } | 510       } | 
| 493 | 511 | 
| 494       RVA target_rva = rel32_rva + 4 + Read32LittleEndian(rel32); | 512       RVA target_rva = rel32_rva + 4 + Read32LittleEndian(rel32); | 
| 495       // To be valid, rel32 target must be within image, and within this | 513       // To be valid, rel32 target must be within image, and within this | 
| 496       // section. | 514       // section. | 
| 497       if (IsValidRVA(target_rva) && | 515       if (IsValidRVA(target_rva) && | 
| 498           start_rva <= target_rva && target_rva < end_rva) { | 516           (is_rip_relative || | 
|  | 517            (start_rva <= target_rva && target_rva < end_rva))) { | 
| 499         rel32_locations_.push_back(rel32_rva); | 518         rel32_locations_.push_back(rel32_rva); | 
| 500 #if COURGETTE_HISTOGRAM_TARGETS | 519 #if COURGETTE_HISTOGRAM_TARGETS | 
| 501         ++rel32_target_rvas_[target_rva]; | 520         ++rel32_target_rvas_[target_rva]; | 
| 502 #endif | 521 #endif | 
| 503         p = rel32 + 4; | 522         p = rel32 + 4; | 
| 504         continue; | 523         continue; | 
| 505       } | 524       } | 
| 506     } | 525     } | 
| 507     p += 1; | 526     p += 1; | 
| 508   } | 527   } | 
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 720     directory->size_ = static_cast<uint32>(size); | 739     directory->size_ = static_cast<uint32>(size); | 
| 721     return true; | 740     return true; | 
| 722   } else { | 741   } else { | 
| 723     directory->address_ = 0; | 742     directory->address_ = 0; | 
| 724     directory->size_ = 0; | 743     directory->size_ = 0; | 
| 725     return true; | 744     return true; | 
| 726   } | 745   } | 
| 727 } | 746 } | 
| 728 | 747 | 
| 729 }  // namespace courgette | 748 }  // namespace courgette | 
| OLD | NEW | 
|---|