OLD | NEW |
---|---|
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/rel32_finder_x64.h" | 5 #include "courgette/rel32_finder_x64.h" |
6 | 6 |
7 namespace courgette { | 7 namespace courgette { |
8 | 8 |
9 Rel32FinderX64::Rel32FinderX64(RVA relocs_start_rva, | 9 Rel32FinderX64::Rel32FinderX64(RVA relocs_start_rva, |
10 RVA relocs_end_rva, | 10 RVA relocs_end_rva, |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
49 bool is_rip_relative = false; | 49 bool is_rip_relative = false; |
50 | 50 |
51 if (p + 5 <= end_pointer) { | 51 if (p + 5 <= end_pointer) { |
52 if (p[0] == 0xE8 || p[0] == 0xE9) // jmp rel32 and call rel32 | 52 if (p[0] == 0xE8 || p[0] == 0xE9) // jmp rel32 and call rel32 |
53 rel32 = p + 1; | 53 rel32 = p + 1; |
54 } | 54 } |
55 if (p + 6 <= end_pointer) { | 55 if (p + 6 <= end_pointer) { |
56 if (p[0] == 0x0F && (p[1] & 0xF0) == 0x80) { // Jcc long form | 56 if (p[0] == 0x0F && (p[1] & 0xF0) == 0x80) { // Jcc long form |
57 if (p[1] != 0x8A && p[1] != 0x8B) // JPE/JPO unlikely | 57 if (p[1] != 0x8A && p[1] != 0x8B) // JPE/JPO unlikely |
58 rel32 = p + 2; | 58 rel32 = p + 2; |
59 } else if (p[0] == 0xFF && (p[1] == 0x15 || p[1] == 0x25)) { | 59 } else if ((p[0] == 0xFF && |
60 // rip relative CALL/JMP | 60 (p[1] == 0x15 || p[1] == 0x25)) || // CALL / JMP |
61 ((p[0] == 0x89 || p[0] == 0x8B || | |
62 p[0] == 0x8D) && // MOV / LEA | |
huangs
2016/06/17 18:05:51
I think this is sufficient complex to warrant more
etiennep
2016/06/27 19:41:21
Done.
| |
63 (p[1] & 0xC7) == 0x05)) { // Dst reg : [05,0D,...3D] = | |
64 // [rax,rbx,...,rdi]/[r8,r9,...,r15] | |
61 rel32 = p + 2; | 65 rel32 = p + 2; |
62 is_rip_relative = true; | 66 is_rip_relative = true; |
63 } | 67 } |
64 } | 68 } |
65 // TODO(etiennep): Many rip mov/lea variants are not detected. Experiment, | |
66 // fix and combine logic. | |
67 if (p + 7 <= end_pointer) { | 69 if (p + 7 <= end_pointer) { |
huangs
2016/06/17 18:05:51
// 7-byte instructions:
// [48/4C] 89 [05|0D|...
etiennep
2016/06/27 19:41:21
Done.
| |
68 if ((p[0] & 0xFB) == 0x48 && // Dst reg : 48/4C [rax-rdi]/[r8-r15] | 70 if ((p[0] & 0xFB) == 0x48 && // Dst reg : 48/4C [rax-rdi]/[r8-r15] |
69 p[1] == 0x8D && // LEA | 71 (p[1] == 0x89 || p[1] == 0x8B || p[1] == 0x8D) && // MOV / LEA |
70 (p[2] & 0xC7) == 0x05) { // Dst reg : [05,0D,...3D] = | 72 (p[2] & 0xC7) == 0x05) { // Dst reg : [05,0D,...3D] = |
71 // [rax,rbx,...,rdi]/[r8,r9,...,r15] | 73 // [rax,rbx,...,rdi]/[r8,r9,...,r15] |
72 // LEA dst, QWORD [rip + rel32] | |
73 rel32 = p + 3; | |
74 is_rip_relative = true; | |
75 } else if ((p[0] & 0xFB) == 0x48 && // Dst reg : 48/4C [rax-rdi]/[r8-r15] | |
76 p[1] == 0x8B && // MOV | |
77 (p[2] & 0xC7) == 0x05) { // Dst reg : [05,0D,...3D] = | |
78 // [rax,rbx,...,rdi]/[r8,r9,...,r15] | |
79 // MOV dst, QWORD PTR[rip + rel32] | |
80 rel32 = p + 3; | 74 rel32 = p + 3; |
81 is_rip_relative = true; | 75 is_rip_relative = true; |
82 } | 76 } |
83 } | 77 } |
84 | 78 |
85 if (rel32) { | 79 if (rel32) { |
86 RVA rel32_rva = static_cast<RVA>(rel32 - adjust_pointer_to_rva); | 80 RVA rel32_rva = static_cast<RVA>(rel32 - adjust_pointer_to_rva); |
87 | 81 |
88 // Is there an abs32 reloc overlapping the candidate? | 82 // Is there an abs32 reloc overlapping the candidate? |
89 while (abs32_pos != abs32_locations.end() && *abs32_pos < rel32_rva - 3) | 83 while (abs32_pos != abs32_locations.end() && *abs32_pos < rel32_rva - 3) |
(...skipping 22 matching lines...) Expand all Loading... | |
112 #endif | 106 #endif |
113 p = rel32 + 4; | 107 p = rel32 + 4; |
114 continue; | 108 continue; |
115 } | 109 } |
116 } | 110 } |
117 p += 1; | 111 p += 1; |
118 } | 112 } |
119 } | 113 } |
120 | 114 |
121 } // namespace courgette | 115 } // namespace courgette |
OLD | NEW |