mirror of
https://github.com/radareorg/r2ghidra.git
synced 2026-11-07 06:25:57 -10:00
130 lines
3.2 KiB
C++
130 lines
3.2 KiB
C++
// SPDX-FileCopyrightText: 2019-2026 pancake
|
|
// SPDX-License-Identifier: LGPL-3.0-only
|
|
|
|
#include "R2Architecture.h"
|
|
#include "R2LoadImage.h"
|
|
#include "R2Utils.h"
|
|
|
|
#include <cstring>
|
|
|
|
R2LoadImage::R2LoadImage(RCoreMutex *coreMutex, AddrSpaceManager *addr_space_manager) : LoadImage("radare2_program"),
|
|
coreMutex(coreMutex),
|
|
addr_space_manager(addr_space_manager)
|
|
{
|
|
// nothing to do
|
|
}
|
|
|
|
void R2LoadImage::loadFill(uint1 *ptr, int4 size, const Address &addr) {
|
|
RCoreLock core (coreMutex);
|
|
r_io_read_at (core->io, addr.getOffset(), ptr, size);
|
|
}
|
|
|
|
string R2LoadImage::getArchType() const {
|
|
return "radare2";
|
|
}
|
|
|
|
void R2LoadImage::adjustVma(long adjust) {
|
|
throw LowlevelError("Cannot adjust radare2 virtual memory");
|
|
}
|
|
static bool isptr(const ut8 *p, size_t remain) {
|
|
if (remain < sizeof(ut32)) {
|
|
return false;
|
|
}
|
|
ut32 ptr = 0;
|
|
memcpy (&ptr, p, sizeof(ptr));
|
|
if (ptr < 0x1000) {
|
|
return false;
|
|
}
|
|
return ptr != UT32_MAX;
|
|
}
|
|
|
|
static void addRangesWithPointers(RCoreLock &core, RangeList &list, AddrSpace *space) {
|
|
RIOMapRef *mapref;
|
|
RIO *io = core->io;
|
|
RIOBank *bank = r_io_bank_get (io, io->bank);
|
|
r_list_foreach_cpp<RIOMapRef>(bank->maprefs, [&](RIOMapRef *mapref) {
|
|
RIOMap *map = r_io_map_get (io, mapref->id);
|
|
ut64 begin = r_io_map_begin (map);
|
|
ut64 end = r_io_map_end (map);
|
|
if (map->perm & R_PERM_W) {
|
|
return;
|
|
}
|
|
ut64 fin = end - begin;
|
|
if (fin > 0xffffff) {
|
|
list.insertRange(space, begin, end);
|
|
return;
|
|
}
|
|
ut8 *buf = (ut8 *)malloc (fin);
|
|
if (!buf) {
|
|
list.insertRange(space, begin, end);
|
|
return;
|
|
}
|
|
r_io_read_at (io, begin, buf, fin);
|
|
ut64 base = begin;
|
|
ut64 basefin = begin;
|
|
ut8 *data = buf;
|
|
bool hasdata = false;
|
|
int inc = (core->rasm->config->bits == 64)? 8: 4;
|
|
for (ut64 i = 0; i < fin; i += inc) {
|
|
basefin = begin + i;
|
|
if (isptr (data + i, fin - i)) {
|
|
// eprintf ("valid %llx\n", data[i]);
|
|
hasdata = true;
|
|
} else {
|
|
if (hasdata) {
|
|
// eprintf ("0 append %llx %llx because of 0x%llx\n", base, basefin, *((ut64*)(data +i)));
|
|
if (base > 0) {
|
|
list.insertRange(space, base, basefin); // begin, end);
|
|
}
|
|
hasdata = false;
|
|
base = basefin;
|
|
}
|
|
}
|
|
}
|
|
free (buf);
|
|
if (hasdata) {
|
|
// eprintf ("1 append %llx %llx\n", base, basefin);
|
|
list.insertRange(space, base, basefin);
|
|
}
|
|
});
|
|
}
|
|
|
|
void R2LoadImage::getReadonly(RangeList &list) const {
|
|
RCoreLock core(coreMutex);
|
|
int roprop = r_config_get_i (core->config, "r2ghidra.roprop");
|
|
if (roprop > 0) {
|
|
auto space = addr_space_manager->getDefaultCodeSpace ();
|
|
switch (roprop) {
|
|
case 1:
|
|
break;
|
|
case 2:
|
|
// find ranges with pointers
|
|
addRangesWithPointers(core, list, space);
|
|
break;
|
|
case 3:
|
|
{
|
|
RIOMapRef *mapref;
|
|
RListIter *iter;
|
|
RIO *io = core->io;
|
|
RIOBank *bank = r_io_bank_get (io, io->bank);
|
|
r_list_foreach_cpp<RIOMapRef>(bank->maprefs, [&](RIOMapRef *mapref) {
|
|
RIOMap *map = r_io_map_get (io, mapref->id);
|
|
ut64 begin = r_io_map_begin (map);
|
|
ut64 end = r_io_map_end (map);
|
|
if (map->perm & R_PERM_W) {
|
|
return;
|
|
}
|
|
list.insertRange(space, begin, end);
|
|
});
|
|
}
|
|
break;
|
|
case 4:
|
|
list.insertRange(space, 0x1000, ST64_MAX - 1);
|
|
break;
|
|
default:
|
|
list.insertRange(space, 0, UT64_MAX - 1);
|
|
break;
|
|
}
|
|
}
|
|
}
|