// SPDX-FileCopyrightText: 2019-2026 pancake // SPDX-License-Identifier: LGPL-3.0-only #include "R2Architecture.h" #include "R2LoadImage.h" #include "R2Utils.h" #include 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(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(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; } } }