1 #ifndef ROSE_BinaryAnalysis_MemoryMap_H
2 #define ROSE_BinaryAnalysis_MemoryMap_H
3 #include <featureTests.h>
4 #ifdef ROSE_ENABLE_BINARY_ANALYSIS
6 #include <Rose/BinaryAnalysis/BasicTypes.h>
9 #include <Combinatorics.h>
10 #include <Rose/Exception.h>
12 #include <Sawyer/Access.h>
13 #include <Sawyer/AddressMap.h>
14 #include <Sawyer/AllocatingBuffer.h>
15 #include <Sawyer/MappedBuffer.h>
16 #include <Sawyer/NullBuffer.h>
17 #include <Sawyer/Optional.h>
18 #include <Sawyer/StaticBuffer.h>
20 #include <boost/config.hpp>
21 #include <boost/utility/enable_if.hpp>
22 #include <boost/serialization/access.hpp>
23 #include <boost/serialization/base_object.hpp>
24 #include <boost/serialization/export.hpp>
25 #include <boost/type_traits/is_integral.hpp>
28 namespace BinaryAnalysis {
35 template<
typename T,
typename U>
36 typename boost::enable_if_c<boost::is_integral<T>::value && boost::is_integral<U>::value, T>::type
38 ASSERT_require(alignment > 0);
39 T almt =
static_cast<T
>(alignment);
40 return ((address + almt - 1) / almt) * almt;
48 template<
typename T,
typename U>
49 typename boost::enable_if_c<boost::is_integral<T>::value && boost::is_integral<U>::value, T>::type
51 ASSERT_require(alignment > 0);
52 T almt =
static_cast<T
>(alignment);
53 return (address / almt) * almt;
117 typedef rose_addr_t Address;
118 typedef uint8_t Value;
138 ByteOrder::Endianness endianness_;
140 #ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
142 friend class boost::serialization::access;
145 void serialize(S &s,
const unsigned ) {
146 s.template register_type<AllocatingBuffer>();
147 s.template register_type<MappedBuffer>();
148 s.template register_type<NullBuffer>();
149 s.template register_type<StaticBuffer>();
150 s & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Super);
151 s & BOOST_SERIALIZATION_NVP(endianness_);
158 # if defined(READABLE) || defined(WRITABLE) || defined(EXECUTABLE) || defined(IMMUTABLE) || defined(PRIVATE)
160 # pragma message("Undefining common words from the global namespace: READABLE, WRITABLE, EXECUTABLE, IMMUTABLE, PRIVATE")
162 # warning "Undefining common words from the global namespace: READABLE, WRITABLE, EXECUTABLE, IMMUTABLE, PRIVATE"
172 static const unsigned NO_ACCESS = 0;
173 static const unsigned READABLE = Sawyer::Access::READABLE;
174 static const unsigned WRITABLE = Sawyer::Access::WRITABLE;
175 static const unsigned EXECUTABLE = Sawyer::Access::EXECUTABLE;
176 static const unsigned IMMUTABLE = Sawyer::Access::IMMUTABLE;
177 static const unsigned PRIVATE = Sawyer::Access::PRIVATE;
178 static const unsigned INITIALIZED = 0x00000200;
181 static const unsigned READ_WRITE = READABLE | WRITABLE;
182 static const unsigned READ_EXECUTE = READABLE | EXECUTABLE;
183 static const unsigned READ_WRITE_EXECUTE = READABLE | WRITABLE | EXECUTABLE;
186 static const unsigned RESERVED_ACCESS_BITS = 0x0000ffff;
195 virtual std::string
leader(std::string dflt=
"memory map problem")
const;
196 virtual std::string
details(
bool)
const;
197 virtual void print(std::ostream&,
bool verbose=
true)
const;
198 friend std::ostream& operator<<(std::ostream&,
const Exception&);
212 new_range(new_range), old_range(old_range),
213 new_segment(new_segment), old_segment(old_segment) {}
215 virtual void print(std::ostream&,
bool verbose=
true)
const;
216 friend std::ostream& operator<<(std::ostream&,
const Inconsistent&);
218 Segment new_segment, old_segment;
226 virtual void print(std::ostream&,
bool verbose=
true)
const;
227 friend std::ostream& operator<<(std::ostream&,
const NotMapped&);
236 virtual void print(std::ostream&,
bool verbose=
true)
const;
237 friend std::ostream& operator<<(std::ostream&,
const NoFreeSpace&);
247 virtual void print(std::ostream&,
bool verbose=
true)
const;
248 friend std::ostream& operator<<(std::ostream&,
const SyntaxError&);
278 ByteOrder::Endianness
byteOrder()
const {
return endianness_; }
279 void byteOrder(ByteOrder::Endianness order) { endianness_ = order; }
301 std::string segmentName =
"");
418 void adjustMap(
const std::string &locatorString);
434 : accessibility(0), fileOffset(0), inode(0) {}
493 size_t readQuick(
void *buf, rose_addr_t startVa,
size_t desired)
const {
494 return at(startVa).limit(desired).require(READABLE).read((uint8_t*)buf).size();
509 std::string
readString(rose_addr_t startVa,
size_t desired,
int(*validChar)(
int)=NULL,
int(*invalidChar)(
int)=NULL,
510 unsigned requiredPerms=READABLE,
unsigned prohibitedPerms=0,
char terminator=
'\0')
const;
520 if (
at(startVa).
limit(
sizeof val).
read((uint8_t*)&val).
size() !=
sizeof val)
522 ByteOrder::convert((
void*)&val,
sizeof val, endianness_, ByteOrder::host_order());
533 if (
at(startVa).
limit(
sizeof val).
read((uint8_t*)&val).
size() !=
sizeof val)
535 ByteOrder::convert((
void*)&val,
sizeof val, endianness_, ByteOrder::host_order());
544 return at(startVa).limit(
sizeof(uint32_t)).write((
const uint8_t*)(&value)).size();
552 return at(startVa).limit(
sizeof(uint64_t)).write((
const uint8_t*)(&value)).size();
561 SgUnsignedCharList
readVector(rose_addr_t startVa,
size_t desired,
unsigned requiredPerms=READABLE)
const;
564 size_t writeQuick(
const void *buf, rose_addr_t startVa,
size_t desired) {
565 return at(startVa).limit(desired).require(WRITABLE).write((
const uint8_t*)buf).size();
576 unsigned requiredPerms=READABLE,
unsigned prohibitedPerms=0)
const;
578 unsigned requiredPerms=READABLE,
unsigned prohibitedPerms=0)
const;
591 void dump(FILE*,
const char *prefix=
"")
const;
592 void dump(std::ostream&, std::string prefix=
"")
const;
593 void print(std::ostream &o, std::string prefix=
"")
const {
dump(o, prefix); }
616 friend std::ostream& operator<<(std::ostream&,
const MemoryMap&);
623 #ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
Exception thrown by find_free() when there's not enough free space left.
int colnum
Optional column number (0-origin; negative if unknown).
Sawyer::Optional< uint8_t > readByte(rose_addr_t) const
Read a byte from memory.
Sawyer::Optional< uint64_t > readLongUnsinged(rose_addr_t startVa) const
Read a long unsigned value.
static std::string adjustMapDocumentation()
Documentation string for adjustMap.
Exception thrown by load() when there's a syntax error in the index file.
virtual std::string leader(std::string dflt="memory map problem") const
Leading part of the error message.
static std::pair< Buffer::Ptr, std::string > copyFromFile(int fd, const AddressInterval &)
Copy part of a file into a buffer.
void print(std::ostream &o, std::string prefix="") const
Prints the contents of the map for debugging.
virtual std::string details(bool) const
Details emitted on following lines, indented two spaces.
AddressMapConstraints< const AddressMap > at(Address x) const
Constraint: anchor point.
static std::string insertFileDocumentation()
Documentation string for insertFile.
size_t insertFile(const std::string &fileName, rose_addr_t va, InsertFileMapMode mode=MAP_PRIVATE, std::string segmentName="")
Insert file contents into memory map.
A contiguous range of values.
InsertFileMapMode
Mapping mode for insertFile.
rose_addr_t fileOffset
The accessibility flags.
MemoryMap()
Constructs an empty memory map.
Holds a value or nothing.
MemoryMap::Ptr map
Map that caused the exception if available, null otherwise.
Attach with ptrace, get memory, then detach.
AddressSegment< rose_addr_t, uint8_t > Segment
Type of segments stored by this map.
AddressInterval insertData(const std::string &locatorString)
Insert data into a memory map.
Main namespace for the ROSE library.
Information about a process map.
Interval::Value size() const
Returns the number of values represented by this container.
ProcessMapRecord()
Optional comment.
File is mapped with read-only permission.
Sawyer::SharedPointer< MemoryMap > MemoryMapPtr
Reference counting pointer.
Allocates memory as needed.
std::string filename
Name of index file where error occurred.
Combinatorics::Hasher & hash(Combinatorics::Hasher &) const
Compute a hash of the entire memory contents.
MemoryMapPtr Ptr
Reference counting pointer.
static Ptr instance()
Construct an empty memory map.
void byteOrder(ByteOrder::Endianness order)
Property: byte order.
Sawyer::Container::Interval< Address > read(Value *buf, const AddressMapConstraints< const AddressMap > &c, MatchFlags flags=0) const
Reads data into the supplied buffer.
File is mapped with read and write permission.
size_t readQuick(void *buf, rose_addr_t startVa, size_t desired) const
Read data into buffer.
void insertProcess(pid_t pid, Attach::Boolean attach)
Insert the memory of some other process into this memory map.
size_t inode
The device from which the data is mapped, or "00:00".
Exception for when we try to access a virtual address that isn't mapped.
A mapping from address space to values.
unsigned accessibility
Mapped virtual addresses.
Base class for all buffers.
An efficient mapping from an address space to stored data.
size_t writeUnsigned(uint32_t value, rose_addr_t startVa)
Write an unsigned value.
bool insertProcessMemory(int memFile, const AddressInterval &where, unsigned accessibility, std::string name)
Insert part of another process's memory into this memory map.
boost::enable_if_c< boost::is_integral< T >::value &&boost::is_integral< U >::value, T >::type alignDown(T address, U alignment)
Align address upward to boundary.
boost::enable_if_c< boost::is_integral< T >::value &&boost::is_integral< U >::value, T >::type alignUp(T address, U alignment)
Align address downward to boundary.
unsigned linenum
Line number (1 origin) where error occurred.
Constraints are used to select addresses from a memory map.
Sawyer::Optional< rose_addr_t > findSequence(const AddressInterval &interval, const std::vector< uint8_t > &sequence) const
Search for a byte sequence.
void adjustMap(const std::string &locatorString)
Adjusts a memory map according to the locator string.
static std::vector< ProcessMapRecord > readProcessMap(pid_t)
Obtain the memory map information for a process.
void linkTo(const MemoryMap::Ptr &other, const AddressIntervalSet &parts)
Insert part of another map by reference.
std::string readString(rose_addr_t startVa, size_t desired, int(*validChar)(int)=NULL, int(*invalidChar)(int)=NULL, unsigned requiredPerms=READABLE, unsigned prohibitedPerms=0, char terminator='\0') const
Reads a NUL-terminated string from the memory map.
Base class for reference counted objects.
Exception for an inconsistent mapping.
std::string deviceName
Starting byte offset in the file.
File is mapped privately.
size_t writeUnsigned(uint64_t value, rose_addr_t startVa)
Write a long unsigned value.
void eraseZeros(size_t minsize)
Erases regions of zero bytes that are executable and readable and at least minsize in size...
bool insertProcessPid(pid_t, const AddressInterval &where, unsigned accessibility, const std::string &name)
Insert part of another process's memory into this memory map.
SgUnsignedCharList readVector(rose_addr_t startVa, size_t desired, unsigned requiredPerms=READABLE) const
Read quickly into a vector.
Attach with ptrace first when reading a process?
std::string comment
Inode on the device, or zero.
bool shrinkUnshare()
Shrink buffers and remove sharing.
ByteOrder::Endianness byteOrder() const
Property: byte order.
void dump() const
Prints the contents of the map for debugging.
static std::string insertDataDocumentation()
Documentation string for insertData.
Sawyer::Optional< rose_addr_t > findAny(const Extent &limits, const std::vector< uint8_t > &bytesToFind, unsigned requiredPerms=READABLE, unsigned prohibitedPerms=0) const
Search for any byte.
static std::string segmentTitle(const Segment &)
Title of a segment when printing the map.
Base class for all ROSE exceptions.
static std::string insertProcessDocumentation()
Documentation string for insertProcess.
AddressMapConstraints< const AddressMap > limit(size_t x) const
Constraint: limit matched size.
size_t writeQuick(const void *buf, rose_addr_t startVa, size_t desired)
Write data from buffer.
Sawyer::Optional< U > readUnsigned(rose_addr_t startVa) const
Read an unsigned value.
Exception for MemoryMap operations.
Assume ptrace is attached and process is stopped.
Ptr shallowCopy()
Create a new copy of the memory map.