Section addresses goes beyond the image region - Intel Pin

395 views Asked by At

I developed a simple pintool to list all the sections of the program's main executable image (iterating over all of its sections), and also its low and high limits using IMG_HighAddress and IMG_LowAddress; according to Pin, these return the definite limits of the image.

To my surprise, the sections went way beyond the low and high limits reported by these functions. Have I done something wrong, or are these functions inaccurate?

My image load function:

VOID ImageLoad(IMG img, VOID *v)
{

if (!IMG_IsMainExecutable(img))
    return;

ADDRINT mainExeImageLowAddr = IMG_LowAddress(img);
ADDRINT mainExeImageHighAddr = IMG_HighAddress(img);    

cout << "Image limits " << hex << mainExeImageLowAddr << " - " << mainExeImageHighAddr << endl;

for (SEC sec = IMG_SecHead(img); SEC_Valid(sec); sec = SEC_Next(sec))
{   
    cout << "Section " << SEC_Name(sec) << " at addresses 0x" << hex << SEC_Address(sec) << " - 0x" << SEC_Address(sec)+SEC_Size(sec)-1 << endl;
}

}

The results for running it on /bin/ls:

Image limits 400000 - 418b23
Section .interp at addresses 0x400200 - 0x40021b
Section .note.ABI-tag at addresses 0x40021c - 0x40023b
Section .note.gnu.build-id at addresses 0x40023c - 0x40025f
Section .dynsym at addresses 0x4002c8 - 0x400eaf
Section .rela.dyn at addresses 0x401618 - 0x4017c7
Section .rela.plt at addresses 0x4017c8 - 0x402157
Section .init at addresses 0x402158 - 0x40216f
Section .plt at addresses 0x402170 - 0x4027df
Section .text at addresses 0x4027e0 - 0x412347
Section .fini at addresses 0x412348 - 0x412355
Section .rodata at addresses 0x412360 - 0x415e86
Section .eh_frame_hdr at addresses 0x415e88 - 0x41653b
Section .eh_frame at addresses 0x416540 - 0x41851b
Section .dynstr at addresses 0x41851c - 0x418b23
Section .ctors at addresses 0x619000 - 0x61900f
Section .dtors at addresses 0x619010 - 0x61901f
Section .jcr at addresses 0x619020 - 0x619027
Section .data.rel.ro at addresses 0x619040 - 0x619a87
Section .dynamic at addresses 0x619a88 - 0x619c57
Section .got at addresses 0x619c58 - 0x619cef
Section .got.plt at addresses 0x619cf0 - 0x61a037
Section .data at addresses 0x61a040 - 0x61a23f
Section .bss at addresses 0x61a240 - 0x61af5f
Section .gnu.conflict at addresses 0x61af60 - 0x61b6f7
Section .gnu_debuglink at addresses 0x0 - 0xf
Section .gnu.prelink_undo at addresses 0x0 - 0x8ff
Section .shstrtab at addresses 0x0 - 0x12d
1

There are 1 answers

1
Employed Russian On BEST ANSWER

Have I done something wrong

Not necessarily.

It looks like Pin is trying to map ELF concepts to Windows-specific concepts, and there isn't a one-to-one mapping.

Intel documentation for IMG_HighAddress says:

Tells the highest address of any code or data loaded by the image.
This is the address of the last byte loaded by the image.

But what exactly does that mean?

ELF image loading is defined by PT_LOAD segments. You can see the segments, as well as section-to-segment mapping, in output from readelf -Wl a.out.

Usually there will be two LOAD segments: one with r-x protections covering .text, .rodata, and other read-only sections, and a second with rw- protections, covering .data, .bss and other writable sections.

It looks (from your output) like IMG_HighAddress is describing only the first LOAD segment.

You should also note that not all sections are LOADable, and the non-LOADable sections are usually not covered by any segment (and do not occupy memory at runtime). Various .debug* sections are usually not LOADable.