Relocating PE Resource

Vd3 21 Reputation points
2021-02-07T06:35:40.807+00:00

I've spent hours trying to understand how windows PE resource structure works. and I cannot figure this out, I think this should be easy for people who have worked with pe resource table. I found this code snippet

void RelocateRSRC(PBYTE prsrc, PIMAGE_RESOURCE_DIRECTORY pird, LONG Delta)
{
    if (DWORD NumberOfEntries = pird->NumberOfNamedEntries + pird->NumberOfIdEntries)
    {
        PIMAGE_RESOURCE_DIRECTORY_ENTRY pirde = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pird + 1);

        do 
        {
            if (pirde->DataIsDirectory)
            {
                RelocateRSRC(prsrc,
                    (PIMAGE_RESOURCE_DIRECTORY)(prsrc + pirde->OffsetToDirectory),
                    Delta);
            } 
            else 
            {
                PIMAGE_RESOURCE_DATA_ENTRY data = 
                    (PIMAGE_RESOURCE_DATA_ENTRY)(prsrc + pirde->OffsetToData);

                data->OffsetToData += Delta;
            }

        } while (pirde++, --NumberOfEntries);
    }
}

from: https://stackoverflow.com/questions/49066842/resourceentries-rvas-of-a-resource-table-need-relocation-upon-copying-it-to-a-di

for an executable to be able to load it's resource after it's relocated, the resource table needs to be modified. but I cannot figure out what the Delta (third parameter) is, at first I thought that it is the difference between base address of the mapped executable and the base address DWORD delta = (DWORD)image - nt->OptionalHeader.ImageBase; but it doesn't work.

I have read the pe resource structure and cannot figure out what the post author meant by DWORD Diff = newRVA - oldRVA; // calc once OffsetToData += Diff;

what is newRVA and oldRVA is referring to? How do I get those values?

Windows API - Win32
Windows API - Win32
A core set of Windows application programming interfaces (APIs) for desktop and server applications. Previously known as Win32 API.
2,440 questions
C++
C++
A high-level, general-purpose programming language, created as an extension of the C programming language, that has object-oriented, generic, and functional features in addition to facilities for low-level memory manipulation.
3,554 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Strive Sun-MSFT 426 Reputation points
    2021-02-07T09:51:11.187+00:00

    Hello, @Vd3

    what is newRVA and oldRVA?

    From PE Format,

    RVA: In an image file, this is the address of an item after it is loaded into memory, with the base address of the image file subtracted from it. The RVA of an item almost always differs from its position within the file on disk (file pointer).
    In an object file, an RVA is less meaningful because memory locations are not assigned. In this case, an RVA would be an address within a section (described later in this table), to which a relocation is later applied during linking. For simplicity, a compiler should just set the first RVA in each section to zero.

    The link you provided also explain,

    oldRVA - rva where rsrc placed in current image.

    newRVA - rva where rsrc will be placed in new image.

    but I cannot figure out what the Delta (third parameter) is,

    Actually, Delta is newRVA - oldRVA

    Because RtlPointerToOffset returns the offset from a given base address of a given pointer.

    You can pass newRVA into the CopyRSRC function to get Delta.

    ----------

    Thank you!

    If the answer is helpful, please click "Accept Answer" and upvote it.

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.