-
Notifications
You must be signed in to change notification settings - Fork 283
Expand file tree
/
Copy pathVirtualMemory.h
More file actions
142 lines (87 loc) · 3.5 KB
/
VirtualMemory.h
File metadata and controls
142 lines (87 loc) · 3.5 KB
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
#pragma once
#include "MappedFileRegion.h"
#include "Utility.h"
class UnmappedRegionException : public std::exception
{
uint64_t m_address;
public:
explicit UnmappedRegionException(uint64_t address) : m_address(address) {}
virtual const char* what() const throw()
{
thread_local std::string message;
message = fmt::format("Tried to access unmapped region using address {0:x}", m_address);
return message.c_str();
}
};
// A region within the virtual memory
struct VirtualMemoryRegion
{
uint64_t fileOffset;
std::shared_ptr<MappedFileRegion> file;
VirtualMemoryRegion(uint64_t offset, std::shared_ptr<MappedFileRegion> f)
: fileOffset(offset), file(std::move(f)) {}
};
// Contains information to handle mapping of multiple mapped files into a single memory space.
// This models how the loader of DYLD shared caches would operate, so that we can effectively query memory regions
// and map them into Binary Ninja.
class VirtualMemory
{
AddressRangeMap<VirtualMemoryRegion> m_regions;
uint64_t m_addressSize = 8;
public:
explicit VirtualMemory(uint64_t addressSize = 8) : m_addressSize(addressSize) {}
uint64_t GetAddressSize() const { return m_addressSize; }
void MapRegion(std::shared_ptr<MappedFileRegion> file, AddressRange mappedRange, uint64_t fileOffset);
const VirtualMemoryRegion* FindRegionAtAddress(uint64_t address, uint64_t& addressOffset) const;
const VirtualMemoryRegion* FindRegionAtAddress(uint64_t address) const;
bool IsAddressMapped(uint64_t address) const;
uint64_t ReadPointer(uint64_t address) const;
std::string ReadCString(uint64_t address) const;
uint8_t ReadUInt8(uint64_t address) const;
int8_t ReadInt8(uint64_t address) const;
uint16_t ReadUInt16(uint64_t address) const;
int16_t ReadInt16(uint64_t address) const;
uint32_t ReadUInt32(uint64_t address) const;
int32_t ReadInt32(uint64_t address) const;
uint64_t ReadUInt64(uint64_t address) const;
int64_t ReadInt64(uint64_t address) const;
BinaryNinja::DataBuffer ReadBuffer(uint64_t address, size_t length) const;
std::span<const uint8_t> ReadSpan(uint64_t address, size_t length) const;
void Read(void* dest, uint64_t address, size_t length) const;
};
class VirtualMemoryReader
{
std::shared_ptr<VirtualMemory> m_memory;
uint64_t m_cursor;
BNEndianness m_endianness = LittleEndian;
public:
explicit VirtualMemoryReader(std::shared_ptr<VirtualMemory> memory);
void SetEndianness(BNEndianness endianness) { m_endianness = endianness; }
BNEndianness GetEndianness() const { return m_endianness; }
void Seek(const uint64_t address) { m_cursor = address; };
void SeekRelative(const size_t offset) { m_cursor += offset; };
size_t GetOffset() const { return m_cursor; }
std::string ReadCString(uint64_t address, size_t maxLength = -1);
uint64_t ReadPointer();
uint64_t ReadPointer(uint64_t address);
uint8_t ReadUInt8();
uint8_t ReadUInt8(uint64_t address);
int8_t ReadInt8();
int8_t ReadInt8(uint64_t address);
uint16_t ReadUInt16();
uint16_t ReadUInt16(uint64_t address);
int16_t ReadInt16();
int16_t ReadInt16(uint64_t address);
uint32_t ReadUInt32();
uint32_t ReadUInt32(uint64_t address);
int32_t ReadInt32();
int32_t ReadInt32(uint64_t address);
uint64_t ReadUInt64();
uint64_t ReadUInt64(uint64_t address);
int64_t ReadInt64();
int64_t ReadInt64(uint64_t address);
BinaryNinja::DataBuffer ReadBuffer(size_t length);
BinaryNinja::DataBuffer ReadBuffer(uint64_t address, size_t length);
void Read(void* dest, size_t length);
void Read(void* dest, uint64_t address, size_t length);
};