summaryrefslogtreecommitdiff
path: root/view/sharedcache/core/MappedFileAccessor.cpp
blob: 4f9f99a8299fcfddcff3d6cfd151b20ce7c2819c (plain)
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
#include "MappedFileAccessor.h"

std::shared_ptr<MappedFileAccessor> MappedFileAccessor::Open(const std::string& filePath)
{
	auto file = MappedFile::OpenFile(filePath);
	if (!file.has_value())
		return nullptr;
	if (file->Map() != MapStatus::Success)
		return nullptr;
	return std::make_shared<MappedFileAccessor>(std::move(*file));
}

// TODO: Will obviously not work on 32bit binaries, need to make WritePointer64 and 32 equiv.
void MappedFileAccessor::WritePointer(size_t address, size_t pointer)
{
	if (address + sizeof(size_t*) > Length())
		throw UnmappedAccessException(address + sizeof(size_t*), Length());
	m_dirty = true;
	*reinterpret_cast<size_t*>(&m_file._mmap[address]) = pointer;
}

std::string MappedFileAccessor::ReadNullTermString(size_t address, const size_t maxLength) const
{
	if (address > Length())
		return "";
	// If we are not given a maxLength (i.e. -1) than we will set the max address to the length of the file.
	const size_t maxAddr = (maxLength != -1) ? std::min(address + maxLength, Length()) : Length();
	// Read a null-terminated string manually to avoid errors related to string length on Linux.
	std::string str;
	str.reserve(140);
	for (size_t currAddr = address; currAddr < maxAddr; ++currAddr)
	{
		char c = m_file._mmap[currAddr];
		if (c == '\0')
			break;
		str += c;
	}
	str.shrink_to_fit();
	return str;
}

uint8_t MappedFileAccessor::ReadUInt8(size_t address) const
{
	return Read<uint8_t>(address);
}

int8_t MappedFileAccessor::ReadInt8(size_t address) const
{
	return Read<int8_t>(address);
}

uint16_t MappedFileAccessor::ReadUInt16(size_t address) const
{
	return Read<uint16_t>(address);
}

int16_t MappedFileAccessor::ReadInt16(size_t address) const
{
	return Read<int16_t>(address);
}


uint32_t MappedFileAccessor::ReadUInt32(size_t address) const
{
	return Read<uint32_t>(address);
}

int32_t MappedFileAccessor::ReadInt32(size_t address) const
{
	return Read<int32_t>(address);
}

uint64_t MappedFileAccessor::ReadUInt64(size_t address) const
{
	return Read<uint64_t>(address);
}

int64_t MappedFileAccessor::ReadInt64(size_t address) const
{
	return Read<int64_t>(address);
}

BinaryNinja::DataBuffer MappedFileAccessor::ReadBuffer(size_t addr, size_t length) const
{
	if (addr + length > Length())
		throw UnmappedAccessException(addr + length, Length());
	return {&m_file._mmap[addr], length};
}

std::pair<const uint8_t*, const uint8_t*> MappedFileAccessor::ReadSpan(size_t addr, size_t length)
{
	if (addr + length > Length())
		throw UnmappedAccessException(addr + length, Length());
	const uint8_t* data = &m_file._mmap[addr];
	return {data, data + length};
}

void MappedFileAccessor::Read(void* dest, size_t addr, size_t length) const
{
	if (addr + length > Length())
		throw UnmappedAccessException(addr + length, Length());
	memcpy(dest, &m_file._mmap[addr], length);
}

template <typename T>
T MappedFileAccessor::Read(size_t address) const
{
	T result;
	Read(&result, address, sizeof(T));
	return result;
}