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

Side by Side Diff: courgette/rel32_finder_x64.cc

Issue 2072093003: Courgette: Extend pointer detection in x64. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Correct Nits in comments Created 4 years, 5 months 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
« no previous file with comments | « courgette/encode_decode_unittest.cc ('k') | courgette/testdata/rel32_x64_01.txt » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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)) ||
61 ((p[0] == 0x89 || p[0] == 0x8B || p[0] == 0x8D) &&
62 (p[1] & 0xC7) == 0x05)) {
63 // 6-byte instructions:
64 // [2-byte opcode] [disp32]:
65 // Opcode
66 // FF 15: call QWORD PTR [rip+disp32]
67 // FF 25: jmp QWORD PTR [rip+disp32]
68 //
69 // [1-byte opcode] [ModR/M] [disp32]:
70 // Opcode
71 // 89: mov DWORD PTR [rip+disp32],reg
72 // 8B: mov reg,DWORD PTR [rip+disp32]
73 // 8D: lea reg,[rip+disp32]
74 // ModR/M : MMRRRMMM
75 // MM = 00 & MMM = 101 => rip+disp32
76 // RRR: selects reg operand from [eax|ecx|...|edi]
61 rel32 = p + 2; 77 rel32 = p + 2;
62 is_rip_relative = true; 78 is_rip_relative = true;
63 } 79 }
64 } 80 }
65 // TODO(etiennep): Many rip mov/lea variants are not detected. Experiment, 81 // TODO(huangs): Maybe skip checking prefixes,
66 // fix and combine logic. 82 // and let 6-byte instructions take care of this?
67 if (p + 7 <= end_pointer) { 83 if (p + 7 <= end_pointer) {
68 if ((p[0] & 0xFB) == 0x48 && // Dst reg : 48/4C [rax-rdi]/[r8-r15] 84 if (((p[0] & 0xF2) == 0x40 || p[0] == 0x66) &&
69 p[1] == 0x8D && // LEA 85 (p[1] == 0x89 || p[1] == 0x8B || p[1] == 0x8D) &&
70 (p[2] & 0xC7) == 0x05) { // Dst reg : [05,0D,...3D] = 86 (p[2] & 0xC7) == 0x05) {
71 // [rax,rbx,...,rdi]/[r8,r9,...,r15] 87 // 7-byte instructions:
72 // LEA dst, QWORD [rip + rel32] 88 // [REX.W prefix] [1-byte opcode] [ModR/M] [disp32]
73 rel32 = p + 3; 89 // REX Prefix : 0100WR0B
74 is_rip_relative = true; 90 // W: 0 = Default Operation Size
75 } else if ((p[0] & 0xFB) == 0x48 && // Dst reg : 48/4C [rax-rdi]/[r8-r15] 91 // 1 = 64 Bit Operand Size
76 p[1] == 0x8B && // MOV 92 // R: 0 = REG selects from [rax|rcx|...|rdi].
77 (p[2] & 0xC7) == 0x05) { // Dst reg : [05,0D,...3D] = 93 // 1 = REG selects from [r9|r10|...|r15].
78 // [rax,rbx,...,rdi]/[r8,r9,...,r15] 94 // B: ModR/M r/m field extension (not used).
79 // MOV dst, QWORD PTR[rip + rel32] 95 // Opcode
96 // 89: mov QWORD PTR [rip+disp32],reg
97 // 8B: mov reg,QWORD PTR [rip+disp32]
98 // 8D: lea reg,[rip+disp32]
99 // ModR/M : MMRRRMMM
100 // MM = 00 & MMM = 101 => rip+disp32
101 // RRR: selects reg operand
102 //
103 // 66 [1-byte opcode] [ModR/M] [disp32]
104 // Prefix
105 // 66: Operand size override
106 // Opcode
107 // 89: mov WORD PTR [rip+disp32],reg
108 // 8B: mov reg,WORD PTR [rip+disp32]
109 // 8D: lea reg,[rip+disp32]
110 // ModR/M : MMRRRMMM
111 // MM = 00 & MMM = 101 = rip+disp32
112 // RRR selects reg operand from [ax|cx|...|di]
80 rel32 = p + 3; 113 rel32 = p + 3;
81 is_rip_relative = true; 114 is_rip_relative = true;
82 } 115 }
83 } 116 }
84 117
85 if (rel32) { 118 if (rel32) {
86 RVA rel32_rva = static_cast<RVA>(rel32 - adjust_pointer_to_rva); 119 RVA rel32_rva = static_cast<RVA>(rel32 - adjust_pointer_to_rva);
87 120
88 // Is there an abs32 reloc overlapping the candidate? 121 // Is there an abs32 reloc overlapping the candidate?
89 while (abs32_pos != abs32_locations.end() && *abs32_pos < rel32_rva - 3) 122 while (abs32_pos != abs32_locations.end() && *abs32_pos < rel32_rva - 3)
(...skipping 22 matching lines...) Expand all
112 #endif 145 #endif
113 p = rel32 + 4; 146 p = rel32 + 4;
114 continue; 147 continue;
115 } 148 }
116 } 149 }
117 p += 1; 150 p += 1;
118 } 151 }
119 } 152 }
120 153
121 } // namespace courgette 154 } // namespace courgette
OLDNEW
« no previous file with comments | « courgette/encode_decode_unittest.cc ('k') | courgette/testdata/rel32_x64_01.txt » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698