PeRvaToOffset
Description
Convert an RVA (offset from ImageBase) to a file offset by finding the section whose [VirtualAddress, VirtualAddress + VirtualSize) contains rva, then adding the in-section delta to the section’s PointerToRawData.
Success
Returns true; *out_offset is set.
Failure
Returns false when no section covers rva or the result would point past BufLength(&self->data).
Usage example (Cross-references)
Usage examples (Cross-references)
- In
Pe.c:430:
u64 dir_offset;
if (!PeRvaToOffset(ctx->out, (u32)ctx->debug_dir_rva, &dir_offset)) {
LOG_ERROR("PE: debug directory RVA not in any section");
return;- In
Pe.c:595:
}
bool PeRvaToOffset(const Pe *self, u32 rva, u64 *out_offset) {
if (!self || !out_offset)
return false;- In
Pe.c:520:
// The CodeView record sits at RVA 0x1020 -> file offset 0x420.
u64 off = 0;
bool ok = PeRvaToOffset(&pe, CV_REC_RVA, &off) && off == CV_REC_RAW_OFF;
// RVA outside any section should fail cleanly.
- In
Pe.c:524:
// RVA outside any section should fail cleanly.
u64 garbage = 0;
ok = ok && !PeRvaToOffset(&pe, 0xdead0000, &garbage);
PeDeinit(&pe);- In
Pe.c:586:
// Inside the section maps to raw_offset + delta.
u64 off = 0;
bool ok = PeRvaToOffset(&pe, SECTION_VA + 0x10, &off) && off == DEBUG_RAW_OFF + 0x10;
// RVA == VirtualAddress + VirtualSize is one past the end -> not covered.
u64 end_off = 0;- In
Pe.c:589:
// RVA == VirtualAddress + VirtualSize is one past the end -> not covered.
u64 end_off = 0;
ok = ok && !PeRvaToOffset(&pe, SECTION_VA + SECTION_VSIZE, &end_off);
// RVA below the first section -> not covered.
u64 low = 0;- In
Pe.c:592:
// RVA below the first section -> not covered.
u64 low = 0;
ok = ok && !PeRvaToOffset(&pe, 0x100, &low);
PeDeinit(&pe);- In
Pe.c:1408:
// RVA 0x2040 is inside section 1 only -> offset 0x300 + 0x40.
u64 off = 0;
bool ok = PeRvaToOffset(&pe, 0x2040, &off) && off == 0x340;
PeDeinit(&pe);
DefaultAllocatorDeinit(&alloc);- In
Pe.c:1442:
u64 off = 0;
bool ok = PeRvaToOffset(&pe, 0x1000, &off) && off == 0x200; // start
ok = ok && PeRvaToOffset(&pe, 0x10FF, &off) && off == 0x2FF; // last in-range
u64 tmp = 0xdead;- In
Pe.c:1443:
u64 off = 0;
bool ok = PeRvaToOffset(&pe, 0x1000, &off) && off == 0x200; // start
ok = ok && PeRvaToOffset(&pe, 0x10FF, &off) && off == 0x2FF; // last in-range
u64 tmp = 0xdead;
ok = ok && !PeRvaToOffset(&pe, 0x1100, &tmp); // one past end
- In
Pe.c:1445:
ok = ok && PeRvaToOffset(&pe, 0x10FF, &off) && off == 0x2FF; // last in-range
u64 tmp = 0xdead;
ok = ok && !PeRvaToOffset(&pe, 0x1100, &tmp); // one past end
ok = ok && !PeRvaToOffset(&pe, 0x0FFF, &tmp); // just below start
- In
Pe.c:1446:
u64 tmp = 0xdead;
ok = ok && !PeRvaToOffset(&pe, 0x1100, &tmp); // one past end
ok = ok && !PeRvaToOffset(&pe, 0x0FFF, &tmp); // just below start
PeDeinit(&pe);- In
Pe.c:1482:
// rva-va == 0xF -> off == total-1 (last valid byte) -> accepted.
u64 off = 0;
bool ok = PeRvaToOffset(&pe, 0x100F, &off) && off == (u64)total - 1;
// rva-va == 0x10 -> off == total (one past last) -> rejected.
u64 past = 0xdead;- In
Pe.c:1485:
// rva-va == 0x10 -> off == total (one past last) -> rejected.
u64 past = 0xdead;
ok = ok && !PeRvaToOffset(&pe, 0x1010, &past);
PeDeinit(&pe);- In
Pe.c:1512:
}
u64 off = 0xdead;
bool ok = !PeRvaToOffset(&pe, 0x9000, &off);
PeDeinit(&pe);
DefaultAllocatorDeinit(&alloc);
Last updated on