News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

RTLImageRVAtoVA - updated

Started by guga, April 11, 2012, 03:30:27 AM

Previous topic - Next topic

guga

One more set. Feel free to convert to masm/fasm.
This function have exactly the same functionality as in ntdll.dll

In a matter of fact. this function can either be used as RVAtoOffset.
When you set the imagebase the function will return the xact VA of the RVA. Ex: 04091C4
When no imagebase is used (BaseAddress = 0), the function will retunr the offset of the inputed RVA. Ex: 085C4

Note: In ntdll.dll the function contains an error when you try to retrieve the VA. Even you setting a imagebase value, the resultant VA is incorrect.
On my function, i fixed that. Now it retunr the correct VA.
Updated: 11/04/2012

;;
    RTLImageRVAtoVA

    Locates a relative virtual address (RVA) within the image header of a file that is mapped as a file
    and returns the virtual address of the corresponding byte in the file.

    Parameters
        NtHeaders [in]: A pointer to an IMAGE_NT_HEADERS structure. This structure can be obtained by
                        calling the ImageNtHeader function. It is the 'PE' signature
        BaseAddress [in]:   The base address of an image that is mapped into memory through a call to
                            the MapViewOfFile function.
                            If this member is &NULL, the function will return the offset related to the RVA. Ex: 085C4
                            If the member is a image base value, the funtion it will return the VA related to the RVA. Ex: 04091C4
        Rva [in]:       The relative virtual address to be located.
        pLastRvaSection [in, optional]:  A pointer to an IMAGE_SECTION_HEADER structure that specifies
                                         the last RVA section. This is an optional parameter.
                                         When specified, it points to a variable that contains the last
                                         section value used for the specified image to translate an RVA to a VA.

    Return value:   If the function succeeds, the return value is the virtual address in the mapped file.
                    If the function fails, the return value is NULL. To retrieve extended error information,
                    call GetLastError.

    Examples:
                    1)
                        Proc XXXXX
                            Local @DiffAdded
                            (...)
                            mov edx D@PeOrigin
                            ; in case we have a PE with 03 sections we do this:
                            mov D@DiffAdded2 edx | add D@DiffAdded2 SizeOf_PeHeader | add D@DiffAdded2 SizeOf_SectionsHeaders | add D@DiffAdded2 SizeOf_SectionsHeaders
                            lea esi D@DiffAdded2 ; esi is a pointer to the last section of the PE
                            call RTLImageRVAtoVA edx, D$edx+PeHeader.OptionalHeader.ImageBaseDis, 01154, esi               

                    2)
                        mov edx D@PeOrigin
                        call RTLImageRVAtoVA edx, 0, 03012, 0

    Remarks:        The ImageRvaToVa function locates an RVA within the image header of a file that is mapped
                    as a file and returns the virtual address of the corresponding byte in the file.
                    All DbgHelp functions, such as this one, are single threaded. Therefore, calls from more
                    than one thread to this function will likely result in unexpected behavior or memory corruption.
                    To avoid this, you must synchronize all concurrent calls from more than one thread to this function.

;;

Proc RtlImageRvaToVa:
    Arguments @NtHeader, @BaseAddress, @Rva, @pLastRvaSection
    Local @FileAlignment
    Uses esi, edi, edx, ecx

    mov esi D@pLastRvaSection
    mov edi D@Rva
    mov edx D@NtHeader
    move D@FileAlignment D$edx+PeHeader.OptionalHeader.FileAlignmentDis

    If esi <> 0
        mov ecx D$esi
        mov eax D$ecx+SectionsHeaders.VirtualAddressDis
        mov edx D$ecx+SectionsHeaders.SizeOfRawDataDis
        Align_On_Variable D@FileAlignment edx | add edx eax
    End_If

    If_Or esi = 0, ecx = 0, edi < eax, edi >= edx
        call RTLImageRVAtoSection D@NtHeader, D@BaseAddress, edi
        mov ecx eax
    End_If
   
    xor eax eax
    On ecx = 0, ExitP

    If esi <> 0
        mov D$esi ecx
    End_if

    If D@BaseAddress = 0
        mov eax D$ecx+SectionsHeaders.PointerToRawDataDis
        sub eax D$ecx+SectionsHeaders.VirtualAddressDis
    End_If
    add eax D@BaseAddress
    add eax edi

EndP