-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathvirt_to_phys.c
142 lines (125 loc) · 2.92 KB
/
virt_to_phys.c
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/* from https://github.com/cgvwzq/evsets/blob/master/micro.c */
#include <stdio.h>
#include <stdbool.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#define PAGE_BITS 12
#define LINE_BITS 6
#define SLICE_BITS 3
#define SET_BITS 10
#define PAGE_SIZE2 (1 << PAGE_BITS)
#define LINE_SIZE (1 << LINE_BITS)
#define CACHE_SLICES (1 << SLICE_BITS)
#define CACHE_SETS (1 << SET_BITS)
unsigned long long
vtop(unsigned pid, unsigned long long vaddr)
{
char path[1024];
sprintf (path, "/proc/%u/pagemap", pid);
int fd = open (path, O_RDONLY);
if (fd < 0)
{
return -1;
}
unsigned long long paddr = -1;
unsigned long long index = (vaddr / PAGE_SIZE2) * sizeof(paddr);
if (pread (fd, &paddr, sizeof(paddr), index) != sizeof(paddr))
{
return -1;
}
close (fd);
paddr &= 0x7fffffffffffff;
return (paddr << PAGE_BITS) | (vaddr & (PAGE_SIZE2-1));
}
unsigned int
count_bits(unsigned long long n)
{
unsigned int count = 0;
while (n)
{
n &= (n-1) ;
count++;
}
return count;
}
unsigned int
nbits(unsigned long long n)
{
unsigned int ret = 0;
n = n >> 1;
while (n > 0)
{
n >>= 1;
ret++;
}
return ret;
}
unsigned long long
ptos(unsigned long long paddr, unsigned long long bits)
{
unsigned long long ret = 0;
unsigned long long mask[3] = {0x1b5f575440ULL, 0x2eb5faa880ULL, 0x3cccc93100ULL}; // according to Maurice et al.
switch (bits)
{
case 3:
ret = (ret << 1) | (unsigned long long)(count_bits(mask[2] & paddr) % 2);
case 2:
ret = (ret << 1) | (unsigned long long)(count_bits(mask[1] & paddr) % 2);
case 1:
ret = (ret << 1) | (unsigned long long)(count_bits(mask[0] & paddr) % 2);
default:
break;
}
return ret;
}
void
check(unsigned int pid, unsigned long long *virtual_addresses, unsigned int length)
{
unsigned long long paddrs[length];
bool ignore = false;
for (unsigned int i = 0; i < length; i++)
{
unsigned long long paddr = vtop (pid, virtual_addresses[i]);
paddrs[i] = paddr;
if (paddr >> PAGE_BITS == 0) {
ignore = true;
}
}
if (ignore) {
printf("Zero-mapped address, skipping...\n");
} else {
for (unsigned int i = 0; i < length; i++)
{
unsigned long long paddr = paddrs[i];
unsigned long long cacheset = (paddr >> LINE_BITS) & (CACHE_SETS - 1);
unsigned long long slice = ptos (paddr, SLICE_BITS);
printf(" - virtual: 0x%llx\telement pfn: 0x%09llx\tcache set: 0x%03llx\tslice: 0x%llx\n", virtual_addresses[i], paddr, cacheset, slice);
}
}
}
int
main(int argc, char **argv)
{
unsigned int i = 0;
if (argc < 3)
{
printf ("[!] Use: %s pid 0x1 0x2 0x3 ...\n", argv[0]);
return 1;
}
unsigned int pid = atoi (argv[1]);
unsigned int len = argc - 2;
unsigned long long *addrs = malloc (sizeof(unsigned long long)*len);
char *eos = argv[argc-1] + strlen(argv[argc-1]);
if (!addrs)
{
printf ("[!] Err: allocate\n");
return 1;
}
for (i = 2; i < argc; i++)
{
addrs[i-2] = strtoull (argv[i], &eos, 16);
}
check (pid, addrs, len);
}