News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Is there such thing?

Started by hfheatherfox07, December 03, 2012, 06:03:38 PM

Previous topic - Next topic

hfheatherfox07

Hi,
I have found a source code for Converting Rva Address To Raw Offset

I am Getting an Error Here :

mov ax, word ptr [edi.3ch] ; offset 'PE'
mov dx, [edi.6h] ; number of sections
mov eax, [edi.0ch] ; virtual address

I have never seen "edi.0ch" ?

; RvaToRaw procedure
; ¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤
; ##################################################
; RvaToRaw() - Takes a rva and converts it to a raw offset.
; Returns : EAX=raw.
; it relies on you doing is passing a pointer to the PE header and the RVA you desire converting,
; (how you get the PE header is your business).
; ##################################################

RvaToRaw proc pe_header:DWORD, rva:DWORD

push ebp     
push ebx
push ecx
push edx
push esi
push edi

xor eax, eax
mov ecx, rva
cdq
mov edi, pe_header
mov ax, word ptr [edi.3ch] ; offset 'PE'
add edi, eax
mov dx, [edi.6h] ; number of sections
add edi, 0f8h ; start of sections

RvaToRawLoop:
mov eax, [edi.0ch] ; virtual address
cmp eax, ecx
ja RvaToRawDone
add edi, 28h ; next section
dec edx
jnz RvaToRawLoop ; last section drops out of the loop

RvaToRawDone:
mov eax, rva
mov ecx, [edi-1ch] ; previous sections virtual address
sub eax, ecx
mov ecx, [edi-14h] ; previous sections raw offset
add ecx, eax
xchg eax, ecx

RvaToRawEnd:

pop edi     
pop esi
pop edx
pop ecx
pop ebx
pop ebp

ret
RvaToRaw endp


Yes I know I should stop Cruising the Net at 2AM ......
Leads to this type of questions


Thank you !
Your code and your skills will be assimilated. Your programming language is irrelevant.
We are the ASM Borg and you will become part of us. Compile and be assembled.

TouEnMasm


Your code is just unreadable.
use a structure instead.

;lea edi,something
movzx eax,[edi].MYSTRUCTURE.value
Fa is a musical note to play with CL

japheth

Quote from: hfheatherfox07 on December 03, 2012, 06:03:38 PM
I am Getting an Error Here :

mov ax, word ptr [edi.3ch] ; offset 'PE'
mov dx, [edi.6h] ; number of sections
mov eax, [edi.0ch] ; virtual address

I have never seen "edi.0ch" ?

It's old Masm5-style syntax. Just replace the '.' with a '+'.

However, there a lots of problems/misconceptions in your source:

- the "pe_header" argument is in fact a MZ-header pointer
- the offset at 03Ch is a dword, not a word
- the value to "start to sections" is not always 0F8h (depends on 32-bit vs. 64-bit )
- no error handling
- ...


hfheatherfox07

Thank you for the answers ..... :biggrin:

I admit I was scratching my head with the MZ-header pointer (Icezlion PE tuts are showing how to get that, but I had no idea how to tie it in to this proc)
I found this source and I though of making a crude
Converter just for the fun of making one ....
Nothing more than open and map a PE and an edit box to enter RVA address
And a second box to display the result ....

.......
Thank you again  :greenclp:
Your code and your skills will be assimilated. Your programming language is irrelevant.
We are the ASM Borg and you will become part of us. Compile and be assembled.

hfheatherfox07

Still Having some trouble ...... I am getting error : error A2022: instruction operands must be the same size



I made a bare bone example to try and get the proc working ....
As I realized ..... Finding the Pointer to the PE header will be harder than I though LOL
I found one source that uses a snap shot ....

RVAtoRAWOffsetBareBones.asm
.386
.model flat,stdcall
option casemap:none

include  \masm32\include\windows.inc
include  \masm32\include\kernel32.inc
include  \masm32\include\masm32.inc
include  \masm32\include\user32.inc

includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
includelib  \masm32\lib\masm32.lib

; Prototype
RvaToRaw   PROTO :DWORD, :DWORD

.data
UserInput db "403007h",0  ; RVA Address:403007 Should give RAW Offset address: 807
Format    db "RAW Offset: %dh", 0 ; prefix
pehdr     db"00401000h",0  ;<- Not sure if this is right pointer to the PE header "ptrPEHdr DWORD ? ; pointer to the PE header..."
cpt db "RVA Address:403007" , 0
.data?
buffer   db 64 dup (?)
mybuffer db 4096 dup(?) ; total converted string
.code
start:
invoke RvaToRaw,addr UserInput,addr pehdr
invoke lstrcat, ADDR UserInput , ADDR mybuffer
invoke MessageBox, NULL, addr mybuffer, addr cpt, MB_OK

invoke ExitProcess, NULL
; RvaToRaw procedure
; ¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤
; ##################################################
; RvaToRaw() - Takes a rva and converts it to a raw offset.
; Returns : EAX=raw.
; it relies on you doing is passing a pointer to the PE header and the RVA you desire converting,
; (how you get the PE header is your business).
; ##################################################

RvaToRaw proc pe_header:DWORD, rva:DWORD

push ebp     
push ebx
push ecx
push edx
push esi
push edi

xor eax, eax
mov ecx, rva
cdq
mov edi, pe_header
;mov ax, dword ptr [edi+3ch] ; offset 'PE'
add edi, eax
;mov dx, [edi+6h] ; number of sections
add edi, 0f8h ; start of sections

RvaToRawLoop:
;mov eax, [edi+0ch] ; virtual address
cmp eax, ecx
ja RvaToRawDone
add edi, 28h ; next section
dec edx
jnz RvaToRawLoop ; last section drops out of the loop

RvaToRawDone:
mov eax, rva
;mov ecx, [edi-1ch] ; previous sections virtual address
sub eax, ecx
;mov ecx, [edi-14h] ; previous sections raw offset
add ecx, eax
xchg eax, ecx

RvaToRawEnd:

pop edi     
pop esi
pop edx
pop ecx
pop ebx
pop ebp

ret
RvaToRaw endp
end start

Target File : TestMASM.asm
include \masm32\include\masm32rt.inc

.data

   caption db "MASM32", 0
   text    db "It works!", 0

  .code

  Start:

invoke MessageBox, 0, addr text, addr caption,  MB_ICONQUESTION + MB_OKCANCEL
invoke ExitProcess, 0

end Start
Your code and your skills will be assimilated. Your programming language is irrelevant.
We are the ASM Borg and you will become part of us. Compile and be assembled.

dedndave

open the EXE and read it
verify the MZ marker (recommended, as it validates the next step)
at file offset 3Ch is a dword that is the file relative offset of the PE marker

it only gets harder after that   :biggrin:

Dubby

#6
I wrote such proc a while ago..
but Its not yet executed in my unfinished project.  :P

maybe you could give it a try:
RVAToOffset PROC uses edi esi edx ecx pFileMap:DWORD,RVA:DWORD
   mov esi,pFileMap
   assume esi:ptr IMAGE_DOS_HEADER
   add esi,[esi].e_lfanew
   assume esi:ptr IMAGE_NT_HEADERS
   mov edi,RVA ; edi == RVA
   mov edx,esi
   ; check the PE type first, before calling this proc, store it some where. I called PEFileType which is a global variable..
   ; also give a definition to PE32, PE64, and PEisNE. they are just the return value from checking PE type. 
   ; OR make them as the last param.
   .if PEFileType == PE32
    add edx,sizeof IMAGE_NT_HEADERS
   .elseif PEFileType == PE64
    add edx, sizeof IMAGE_NT_HEADER64 ; make a new one, i's not defined in windows.inc
   .elseif PEFileType == PEisNE
    Jmp RVAToOffset_zero;
   .endif
   mov cx,[esi].FileHeader.NumberOfSections
   movzx ecx,cx
   assume edx:ptr IMAGE_SECTION_HEADER
   .while ecx>0 ; check all sections
     .if edi>=[edx].VirtualAddress
       mov eax,[edx].VirtualAddress
       add eax,[edx].SizeOfRawData
       .if edi<eax ; The address is in this section
         mov eax,[edx].VirtualAddress
         sub edi,eax
         mov eax,[edx].PointerToRawData
         add eax,edi
         ; eax == file offset
         ret
       .endif
     .endif
     add edx,sizeof IMAGE_SECTION_HEADER
     dec ecx
   .endw
   assume edx:nothing
RVAToOffset_zero:
   assume esi:nothing
   xor eax, eax ; return zero if nothing found
   ret
RVAToOffset end


it's a reverse from Iczelion's proc if I'm not mistaken..
DUH, my apologies,  it's a modification from Iczelion tutorial..
I wrote the reverse, OffsetToRVA..

hfheatherfox07

Quote from: dedndave on December 04, 2012, 12:47:43 PM
open the EXE and read it
verify the MZ marker (recommended, as it validates the next step)
at file offset 3Ch is a dword that is the file relative offset of the PE marker

it only gets harder after that   :biggrin:

That is hilarious ....I found a source that I had laying around of an OEP find tool and I added a message box it poops up with "MZ"

I wonder how to modify this to give me PE header pointer
Your code and your skills will be assimilated. Your programming language is irrelevant.
We are the ASM Borg and you will become part of us. Compile and be assembled.

Dubby

I have modified my routine a bit,
so here is the invokeable procedure:


IMAGE_OPTIONAL_HEADER64 STRUCT
  Magic                         WORD       ?
  MajorLinkerVersion            BYTE       ?
  MinorLinkerVersion            BYTE       ?
  SizeOfCode                    DWORD      ?
  SizeOfInitializedData         DWORD      ?
  SizeOfUninitializedData       DWORD      ?
  AddressOfEntryPoint           DWORD      ?
  BaseOfCode                    DWORD      ?
  ImageBase                     QWORD      ?
  SectionAlignment              DWORD      ?
  FileAlignment                 DWORD      ?
  MajorOperatingSystemVersion   WORD       ?
  MinorOperatingSystemVersion   WORD       ?
  MajorImageVersion             WORD       ?
  MinorImageVersion             WORD       ?
  MajorSubsystemVersion         WORD       ?
  MinorSubsystemVersion         WORD       ?
  Win32VersionValue             DWORD      ?
  SizeOfImage                   DWORD      ?
  SizeOfHeaders                 DWORD      ?
  CheckSum                      DWORD      ?
  Subsystem                     WORD       ?
  DllCharacteristics            WORD       ?
  SizeOfStackReserve            QWORD      ?
  SizeOfStackCommit             QWORD      ?
  SizeOfHeapReserve             QWORD      ?
  SizeOfHeapCommit              QWORD      ?
  LoaderFlags                   DWORD      ?
  NumberOfRvaAndSizes           DWORD      ?
  DataDirectory                 IMAGE_DATA_DIRECTORY IMAGE_NUMBEROF_DIRECTORY_ENTRIES dup(<>)
IMAGE_OPTIONAL_HEADER64 ENDS

IMAGE_NT_HEADER64 STRUCT
  Signature         DWORD                   ?
  FileHeader        IMAGE_FILE_HEADER       <> 
  OptionalHeader    IMAGE_OPTIONAL_HEADER64 <> 
IMAGE_NT_HEADER64 ENDS 


RVAToOffset PROC uses edi esi pPEFileMap:DWORD,RVA:DWORD
   mov esi,pPEFileMap
   assume esi:ptr IMAGE_DOS_HEADER
      .if ( word ptr [esi] == 'ZM') ;DOSHEADER
         add esi, [esi].e_lfanew
         assume esi:ptr IMAGE_NT_HEADERS
         lea eax, (IMAGE_NT_HEADERS ptr [esi]).OptionalHeader
         mov ax, [( IMAGE_OPTIONAL_HEADER ptr [eax]).Magic]
         movzx eax, ax
         Mov edi, RVA
         Mov edx, esi
         .if ( word ptr [esi] == 'EP') ; PE HEADER
            .if ax == 010Bh
               ; x86
               add edx,sizeof IMAGE_NT_HEADERS
            .elseif ax == 020Bh
               ; x64
               add edx,sizeof IMAGE_NT_HEADERS64
            .endif
         .else
            ; NE header here
            jmp return_zero
         .endif
         mov cx,[esi].FileHeader.NumberOfSections
         movzx ecx,cx
         assume edx:ptr IMAGE_SECTION_HEADER
         .while ecx>0 ; check all sections
            .if edi>=[edx].VirtualAddress
               mov eax,[edx].VirtualAddress
               add eax,[edx].SizeOfRawData
               .if edi<eax ; The address is in this section
                  mov eax,[edx].VirtualAddress
                  sub edi,eax
                  mov eax,[edx].PointerToRawData
                  add eax,edi
                  ; eax == file offset
                  jmp  return_success
               .endif
            .endif
            add edx,sizeof IMAGE_SECTION_HEADER
            dec ecx
         .endw
         assume edx:nothing
      .endif
return_zero:
   assume esi:nothing
   xor eax, eax ; return zero if nothing found
return_success:
   ret
RVAToOffset endp


hfheatherfox07

EDIT....
I realized that I am having difficulty getting the PE header pointer

I was planing to make a bare bones trail .....I butchered  Iczelion's PE tutorial 2

this is for that Target File : TestMASM.asm


It would be nice to see the OffsetToRVA....

I will take another look at it

.386
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\comdlg32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\comdlg32.lib

; Prototype
RVAToOffset  PROTO :DWORD, :DWORD
IMAGE_OPTIONAL_HEADER64 STRUCT
  Magic                         WORD       ?
  MajorLinkerVersion            BYTE       ?
  MinorLinkerVersion            BYTE       ?
  SizeOfCode                    DWORD      ?
  SizeOfInitializedData         DWORD      ?
  SizeOfUninitializedData       DWORD      ?
  AddressOfEntryPoint           DWORD      ?
  BaseOfCode                    DWORD      ?
  ImageBase                     QWORD      ?
  SectionAlignment              DWORD      ?
  FileAlignment                 DWORD      ?
  MajorOperatingSystemVersion   WORD       ?
  MinorOperatingSystemVersion   WORD       ?
  MajorImageVersion             WORD       ?
  MinorImageVersion             WORD       ?
  MajorSubsystemVersion         WORD       ?
  MinorSubsystemVersion         WORD       ?
  Win32VersionValue             DWORD      ?
  SizeOfImage                   DWORD      ?
  SizeOfHeaders                 DWORD      ?
  CheckSum                      DWORD      ?
  Subsystem                     WORD       ?
  DllCharacteristics            WORD       ?
  SizeOfStackReserve            QWORD      ?
  SizeOfStackCommit             QWORD      ?
  SizeOfHeapReserve             QWORD      ?
  SizeOfHeapCommit              QWORD      ?
  LoaderFlags                   DWORD      ?
  NumberOfRvaAndSizes           DWORD      ?
  DataDirectory                 IMAGE_DATA_DIRECTORY IMAGE_NUMBEROF_DIRECTORY_ENTRIES dup(<>)
IMAGE_OPTIONAL_HEADER64 ENDS

IMAGE_NT_HEADERS64 STRUCT
  Signature         DWORD                   ?
  FileHeader        IMAGE_FILE_HEADER       <>
  OptionalHeader    IMAGE_OPTIONAL_HEADER64 <>
IMAGE_NT_HEADERS64 ENDS
SEH struct
PrevLink dd ? ; the address of the previous seh structure
CurrentHandler dd ? ; the address of the new exception handler
SafeOffset dd ? ; The offset where it's safe to continue execution
PrevEsp dd ? ; the old value in esp
PrevEbp dd ? ; The old value in ebp
SEH ends


.data
AppName db "PE tutorial no.2",0
ofn   OPENFILENAME <>
FilterString db "Executable Files (*.exe, *.dll)",0,"*.exe;*.dll",0
             db "All Files",0,"*.*",0,0
FileOpenError db "Cannot open the file for reading",0             
FileOpenMappingError db "Cannot open the file for memory mapping",0
FileMappingError db "Cannot map the file into memory",0
FileValidPE db "This file is a valid PE",0
FileInValidPE db "This file is not a valid PE",0

UserInput db "403007h",0  ; RVA Address:403007 Should give RAW Offset address: 807
Format    db "RAW Offset: %dh", 0 ; prefix
cpt       db "RVA Address:403007" , 0

.data?
buffer db 512 dup(?)
hFile dd ?
hMapping dd ?
pMapping dd ?
ValidPE dd ?

PEFileType dd ?
mybuffer  db 4096 dup(?) ; total converted string
ptrPEHdr DWORD ?
DD_addressOfIMAGE_SECTION_HEADER dd ?
.code
start proc
LOCAL seh:SEH
mov ofn.lStructSize,SIZEOF ofn
mov  ofn.lpstrFilter, OFFSET FilterString
mov  ofn.lpstrFile, OFFSET buffer
mov  ofn.nMaxFile,512
mov  ofn.Flags, OFN_FILEMUSTEXIST or \
                       OFN_PATHMUSTEXIST or OFN_LONGNAMES or\
                       OFN_EXPLORER or OFN_HIDEREADONLY
invoke GetOpenFileName, ADDR ofn
.if eax==TRUE
invoke CreateFile, addr buffer, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL
.if eax!=INVALID_HANDLE_VALUE
mov hFile, eax
invoke CreateFileMapping, hFile, NULL, PAGE_READONLY,0,0,0
.if eax!=NULL
mov hMapping, eax
invoke MapViewOfFile,hMapping,FILE_MAP_READ,0,0,0
.if eax!=NULL
mov pMapping,eax
assume fs:nothing
push fs:[0]
pop seh.PrevLink
mov seh.CurrentHandler,offset SEHHandler
mov seh.SafeOffset,offset FinalExit
lea eax,seh
mov fs:[0], eax
mov seh.PrevEsp,esp
mov seh.PrevEbp,ebp
mov edi, pMapping
assume edi:ptr IMAGE_DOS_HEADER
.if [edi].e_magic==IMAGE_DOS_SIGNATURE
add edi, [edi].e_lfanew
assume edi:ptr IMAGE_NT_HEADERS
.if [edi].Signature==IMAGE_NT_SIGNATURE
mov ValidPE, TRUE
.else
mov ValidPE, FALSE
.endif
.else
mov ValidPE,FALSE
.endif
FinalExit:
.if ValidPE==TRUE

      ; invoke MessageBox, 0, addr FileValidPE, addr AppName,MB_OK+MB_ICONINFORMATION

invoke RVAToOffset,addr UserInput,addr ptrPEHdr
invoke wsprintf, ADDR buffer, ADDR Format, eax ; buffer = 5dup(0)
invoke lstrcat, ADDR mybuffer, ADDR buffer ; mybuffer db 512 dup(0)
invoke MessageBox, NULL, addr mybuffer, addr cpt, MB_OK
.else
invoke MessageBox, 0, addr FileInValidPE, addr AppName,MB_OK+MB_ICONINFORMATION
.endif
push seh.PrevLink
pop fs:[0]
invoke UnmapViewOfFile, pMapping
.else
invoke MessageBox, 0, addr FileMappingError, addr AppName,MB_OK+MB_ICONERROR
.endif
invoke CloseHandle,hMapping
.else
invoke MessageBox, 0, addr FileOpenMappingError, addr AppName,MB_OK+MB_ICONERROR
.endif
invoke CloseHandle, hFile
.else
invoke MessageBox, 0, addr FileOpenError, addr AppName, MB_OK+MB_ICONERROR
.endif
.endif
invoke ExitProcess, 0
start endp
SEHHandler proc C uses edx pExcept:DWORD,pFrame:DWORD,pContext:DWORD,pDispatch:DWORD
mov edx,pFrame
assume edx:ptr SEH
mov eax,pContext
assume eax:ptr CONTEXT
push [edx].SafeOffset
pop [eax].regEip
push [edx].PrevEsp
pop [eax].regEsp
push [edx].PrevEbp
pop [eax].regEbp
mov ValidPE, FALSE
mov eax,ExceptionContinueExecution
ret
SEHHandler endp
; RvaToRaw procedure
; ¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤*¤

RVAToOffset PROC uses edi esi pPEFileMap:DWORD,RVA:DWORD
   mov esi,pPEFileMap
   assume esi:ptr IMAGE_DOS_HEADER
      .if ( word ptr [esi] == 'ZM') ;DOSHEADER
         add esi, [esi].e_lfanew
         assume esi:ptr IMAGE_NT_HEADERS
         lea eax, (IMAGE_NT_HEADERS ptr [esi]).OptionalHeader
         mov ax, [( IMAGE_OPTIONAL_HEADER ptr [eax]).Magic]
         movzx eax, ax
         Mov edi, RVA
         Mov edx, esi
         .if ( word ptr [esi] == 'EP') ; PE HEADER
            .if ax == 010Bh
               ; x86
               add edx,sizeof IMAGE_NT_HEADERS
            .elseif ax == 020Bh
               ; x64
               add edx,sizeof IMAGE_NT_HEADERS64
            .endif
         .else
            ; NE header here
            jmp return_zero
         .endif
         mov cx,[esi].FileHeader.NumberOfSections
         movzx ecx,cx
         assume edx:ptr IMAGE_SECTION_HEADER
         .while ecx>0 ; check all sections
            .if edi>=[edx].VirtualAddress
               mov eax,[edx].VirtualAddress
               add eax,[edx].SizeOfRawData
               .if edi<eax ; The address is in this section
                  mov eax,[edx].VirtualAddress
                  sub edi,eax
                  mov eax,[edx].PointerToRawData
                  add eax,edi
                  ; eax == file offset
                  jmp  return_success
               .endif
            .endif
            add edx,sizeof IMAGE_SECTION_HEADER
            dec ecx
         .endw
         assume edx:nothing
      .endif
return_zero:
   assume esi:nothing
   xor eax, eax ; return zero if nothing found
return_success:
   ret
RVAToOffset endp
end start
Your code and your skills will be assimilated. Your programming language is irrelevant.
We are the ASM Borg and you will become part of us. Compile and be assembled.

Dubby

try this:

.586
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\comdlg32.inc
include \masm32\include\user32.inc
include \masm32\macros\macros.asm
include \masm32\include\masm32.inc

includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\comdlg32.lib
includelib \masm32\lib\masm32.lib

IFNDEF IMAGE_OPTIONAL_HEADER64
IMAGE_OPTIONAL_HEADER64 STRUCT
  Magic                         WORD       ?
  MajorLinkerVersion            BYTE       ?
  MinorLinkerVersion            BYTE       ?
  SizeOfCode                    DWORD      ?
  SizeOfInitializedData         DWORD      ?
  SizeOfUninitializedData       DWORD      ?
  AddressOfEntryPoint           DWORD      ?
  BaseOfCode                    DWORD      ?
  ImageBase                     QWORD      ?
  SectionAlignment              DWORD      ?
  FileAlignment                 DWORD      ?
  MajorOperatingSystemVersion   WORD       ?
  MinorOperatingSystemVersion   WORD       ?
  MajorImageVersion             WORD       ?
  MinorImageVersion             WORD       ?
  MajorSubsystemVersion         WORD       ?
  MinorSubsystemVersion         WORD       ?
  Win32VersionValue             DWORD      ?
  SizeOfImage                   DWORD      ?
  SizeOfHeaders                 DWORD      ?
  CheckSum                      DWORD      ?
  Subsystem                     WORD       ?
  DllCharacteristics            WORD       ?
  SizeOfStackReserve            QWORD      ?
  SizeOfStackCommit             QWORD      ?
  SizeOfHeapReserve             QWORD      ?
  SizeOfHeapCommit              QWORD      ?
  LoaderFlags                   DWORD      ?
  NumberOfRvaAndSizes           DWORD      ?
  DataDirectory                 IMAGE_DATA_DIRECTORY IMAGE_NUMBEROF_DIRECTORY_ENTRIES dup(<>)
IMAGE_OPTIONAL_HEADER64 ENDS

IMAGE_NT_HEADERS64 STRUCT
  Signature         DWORD                   ?
  FileHeader        IMAGE_FILE_HEADER       <>
  OptionalHeader    IMAGE_OPTIONAL_HEADER64 <>
IMAGE_NT_HEADERS64 ENDS
ENDIF

; prototypes
WinMain Proto :HINSTANCE, :DWORD, :LPSTR,:DWORD

.code
RVAToOffset PROC uses edi esi pPEFileMap:DWORD,RVA:DWORD
   mov esi,pPEFileMap
   assume esi:ptr IMAGE_DOS_HEADER
      .if ( word ptr [esi] == 'ZM') ;DOSHEADER
         add esi, [esi].e_lfanew
         assume esi:ptr IMAGE_NT_HEADERS
         lea eax, (IMAGE_NT_HEADERS ptr [esi]).OptionalHeader
         mov ax, [( IMAGE_OPTIONAL_HEADER ptr [eax]).Magic]
         movzx eax, ax
         Mov edi, RVA
         Mov edx, esi
         .if ( word ptr [esi] == 'EP') ; PE HEADER
            .if ax == 010Bh
               ; x86
               add edx,sizeof IMAGE_NT_HEADERS
            .elseif ax == 020Bh
               ; x64
               add edx,sizeof IMAGE_NT_HEADERS64
            .endif
         .else
            ; NE header here
            jmp return_zero
         .endif
         mov cx,[esi].FileHeader.NumberOfSections
         movzx ecx,cx
         assume edx:ptr IMAGE_SECTION_HEADER
         .while ecx>0 ; check all sections
            .if edi>=[edx].VirtualAddress
               mov eax,[edx].VirtualAddress
               add eax,[edx].SizeOfRawData
               .if edi<eax ; The address is in this section
                  mov eax,[edx].VirtualAddress
                  sub edi,eax
                  mov eax,[edx].PointerToRawData
                  add eax,edi
                  ; eax == file offset
                  jmp  return_success
               .endif
            .endif
            add edx,sizeof IMAGE_SECTION_HEADER
            dec ecx
         .endw
         assume edx:nothing
      .endif
return_zero:
   assume esi:nothing
   xor eax, eax ; return zero if nothing found
return_success:
   ret
RVAToOffset endp

start:
Invoke GetModuleHandle, NULL
Mov Edx, Eax
Push Edx
Invoke GetCommandLine
Pop Edx
Invoke WinMain, Edx, NULL, Eax, SW_SHOW
invoke ExitProcess, 0

WinMain Proc hInstance: HINSTANCE, hPrevInstance:DWORD, lpCmdLine:  LPSTR,nCmdShow:DWORD
local LocalBuffer[512]:byte
.data
hFile dd ?
hMapping dd ?
pMapping dd ?
.code
STRING Format,"VA Address:403007", 0Ah, "RAW Offset: %xh"; x for asm number
STRING Explorer, "\Explorer.exe"
STRING cpt, "RVA to Offset"
Invoke GetWindowsDirectory, Addr LocalBuffer, 512
Invoke lstrcat, Addr LocalBuffer, Addr Explorer
invoke CreateFile, Addr LocalBuffer, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL
.if Eax != INVALID_HANDLE_VALUE
Mov hFile, Eax
Invoke CreateFileMapping, Eax, NULL, PAGE_READONLY,0,0,0
.if Eax != NULL
Mov hMapping, Eax
Invoke MapViewOfFile, Eax, FILE_MAP_READ,0,0,0
Mov pMapping, Eax
lea Ecx, LocalBuffer
Push Ecx
Invoke RtlZeroMemory, Ecx, sizeof LocalBuffer
Invoke RVAToOffset, pMapping, 2007h
Pop Ecx
invoke wsprintf, ADDR LocalBuffer, ADDR Format, eax
Invoke MessageBox, NULL, Addr LocalBuffer, Addr cpt, MB_OK
Invoke UnmapViewOfFile, pMapping
Invoke CloseHandle, hMapping
.endif
Invoke CloseHandle, hFile
.endif
ret
WinMain endp
end start

actually the expected parameters are:
1st Param == the starting address of loaded PE file in the memory
2nd Param == the number of RVA which wished to be converted, in DWORD value.

you might confuse between RVA and VA,

from "Microsoft Portable Executable and Common Object File Format Specification"
Quote
    RVA (relative virtual address). In an image file, 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.

    VA (virtual address). Same as RVA, except that the base address of the image file is not subtracted. The address is called a "VA" because Windows creates a distinct VA space for each process, independent of physical memory. For almost all purposes, a VA should be considered just an address. A VA is not as predictable as an RVA because the loader might not load the image at its preferred location.

see the bold words..
which is mean that the RVA is VA - Base Address (preferred address), thus the RVA of 403007h  is 403007h - 401000h = 2007h, it can be different or it can be read from the opened PE itself, but I assume the bas address 401000.

Please someone correct me if I'm wrong, it have been a year since the last time I dealt with PE file...

dedndave

i think 401000 is the default, but may be changed with linker switches or something like that

hfheatherfox07

@Dubby I have no Idea ? your bare bones example only works with Explorer So I can not test it  :(

Also I thought your proc included the subtraction in it (that can be added LOL)

http://www.tech-juice.org/2011/02/21/portable-executable-converting-rva-to-file-offset-and-back/

Here is Converting tool from  Iczelion done back in 1999 LOL

http://www.woodmann.com/RCE-CD-SITES/Protools/files/debuggers/pc_offset.zip

Your code and your skills will be assimilated. Your programming language is irrelevant.
We are the ASM Borg and you will become part of us. Compile and be assembled.

Dubby

you can always change it to accept return value from GetOpenFileName API.. just change 2 lines of code.. before CreateFile API, should be easy.. 
I'm feelin' lazy right now..  :P

better look at the Iczelion tutorial about PE.

also the official PECOFF specification  from MS. it's describe everything almost clearly..

anyway thank you for the links..  :t

hfheatherfox07

Quote from: Dubby on December 04, 2012, 08:32:42 PM

which is mean that the RVA is VA - Base Address (preferred address), thus the RVA of 403007h  is 403007h - 401000h = 2007h, it can be different or it can be read from the opened PE itself, but I assume the bas address 401000.

Please someone correct me if I'm wrong, it have been a year since the last time I dealt with PE file...

Actually I am getting 400000 as an imagebase

So now do we subtract 400000 or  get the actual imagebase  of the PE ?????
Here is a better
RVA Converter so you will see better than Iczelion's

So RVA of 403007h -400000h = 3007h gave me the correct offset of 807h in TestMASM.ASM

By the way ...Nice Work Dubby!!! :t


include \masm32\include\masm32rt.inc

.data

   caption db "MASM32", 0
   text    db "It works!", 0

  .code

  Start:

invoke MessageBox, 0, addr text, addr caption,  MB_ICONQUESTION + MB_OKCANCEL
invoke ExitProcess, 0

end Start


RVAToOffset.ASM

.586
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\comdlg32.inc
include \masm32\include\user32.inc
include \masm32\macros\macros.asm
include \masm32\include\masm32.inc

includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\comdlg32.lib
includelib \masm32\lib\masm32.lib

IFNDEF IMAGE_OPTIONAL_HEADER64
IMAGE_OPTIONAL_HEADER64 STRUCT
  Magic                         WORD       ?
  MajorLinkerVersion            BYTE       ?
  MinorLinkerVersion            BYTE       ?
  SizeOfCode                    DWORD      ?
  SizeOfInitializedData         DWORD      ?
  SizeOfUninitializedData       DWORD      ?
  AddressOfEntryPoint           DWORD      ?
  BaseOfCode                    DWORD      ?
  ImageBase                     QWORD      ?
  SectionAlignment              DWORD      ?
  FileAlignment                 DWORD      ?
  MajorOperatingSystemVersion   WORD       ?
  MinorOperatingSystemVersion   WORD       ?
  MajorImageVersion             WORD       ?
  MinorImageVersion             WORD       ?
  MajorSubsystemVersion         WORD       ?
  MinorSubsystemVersion         WORD       ?
  Win32VersionValue             DWORD      ?
  SizeOfImage                   DWORD      ?
  SizeOfHeaders                 DWORD      ?
  CheckSum                      DWORD      ?
  Subsystem                     WORD       ?
  DllCharacteristics            WORD       ?
  SizeOfStackReserve            QWORD      ?
  SizeOfStackCommit             QWORD      ?
  SizeOfHeapReserve             QWORD      ?
  SizeOfHeapCommit              QWORD      ?
  LoaderFlags                   DWORD      ?
  NumberOfRvaAndSizes           DWORD      ?
  DataDirectory                 IMAGE_DATA_DIRECTORY IMAGE_NUMBEROF_DIRECTORY_ENTRIES dup(<>)
IMAGE_OPTIONAL_HEADER64 ENDS

IMAGE_NT_HEADERS64 STRUCT
  Signature         DWORD                   ?
  FileHeader        IMAGE_FILE_HEADER       <>
  OptionalHeader    IMAGE_OPTIONAL_HEADER64 <>
IMAGE_NT_HEADERS64 ENDS
ENDIF

; prototypes
WinMain Proto :HINSTANCE, :DWORD, :LPSTR,:DWORD
.data
ofn   OPENFILENAME <>
FilterString   db "Executable Files (*.exe, *.dll)",0,"*.exe;*.dll",0
               db "All Files",0,"*.*",0,0
Format  db "VA Address:403007h", 0Ah, "RAW Offset: %xh",0; x for asm number
cpt     db "RVA to Offset",0
.data?
Buffer   db 32 dup(?) ; buffer
.code
RVAToOffset PROC uses edi esi pPEFileMap:DWORD,RVA:DWORD
   mov esi,pPEFileMap
   assume esi:ptr IMAGE_DOS_HEADER
      .if ( word ptr [esi] == 'ZM') ;DOSHEADER
         add esi, [esi].e_lfanew
         assume esi:ptr IMAGE_NT_HEADERS
         lea eax, (IMAGE_NT_HEADERS ptr [esi]).OptionalHeader
         mov ax, [( IMAGE_OPTIONAL_HEADER ptr [eax]).Magic]
         movzx eax, ax
         Mov edi, RVA
         Mov edx, esi
         .if ( word ptr [esi] == 'EP') ; PE HEADER
            .if ax == 010Bh
               ; x86
               add edx,sizeof IMAGE_NT_HEADERS
            .elseif ax == 020Bh
               ; x64
               add edx,sizeof IMAGE_NT_HEADERS64
            .endif
         .else
            ; NE header here
            jmp return_zero
         .endif
         mov cx,[esi].FileHeader.NumberOfSections
         movzx ecx,cx
         assume edx:ptr IMAGE_SECTION_HEADER
         .while ecx>0 ; check all sections
            .if edi>=[edx].VirtualAddress
               mov eax,[edx].VirtualAddress
               add eax,[edx].SizeOfRawData
               .if edi<eax ; The address is in this section
                  mov eax,[edx].VirtualAddress
                  sub edi,eax
                  mov eax,[edx].PointerToRawData
                  add eax,edi
                  ; eax == file offset
                  jmp  return_success
               .endif
            .endif
            add edx,sizeof IMAGE_SECTION_HEADER
            dec ecx
         .endw
         assume edx:nothing
      .endif
return_zero:
   assume esi:nothing
   xor eax, eax ; return zero if nothing found
return_success:
   ret
RVAToOffset endp

start:
Invoke GetModuleHandle, NULL
Mov Edx, Eax
Push Edx
Invoke GetCommandLine
Pop Edx
Invoke WinMain, Edx, NULL, Eax, SW_SHOW
invoke ExitProcess, 0

WinMain Proc hInstance: HINSTANCE, hPrevInstance:DWORD, lpCmdLine:  LPSTR,nCmdShow:DWORD
local LocalBuffer[512]:byte
.data
hFile dd ?
hMapping dd ?
pMapping dd ?
.code

mov ofn.lStructSize,SIZEOF ofn
mov  ofn.lpstrFilter, OFFSET FilterString
mov  ofn.lpstrFile, OFFSET Buffer
mov  ofn.nMaxFile,512
mov  ofn.Flags, OFN_FILEMUSTEXIST or \
                       OFN_PATHMUSTEXIST or OFN_LONGNAMES or\
                       OFN_EXPLORER or OFN_HIDEREADONLY               
invoke GetOpenFileName, ADDR ofn

.if eax==TRUE
invoke CreateFile, Addr Buffer, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL
.if Eax != INVALID_HANDLE_VALUE
Mov hFile, Eax
Invoke CreateFileMapping, Eax, NULL, PAGE_READONLY,0,0,0
.if Eax != NULL
Mov hMapping, Eax
Invoke MapViewOfFile, Eax, FILE_MAP_READ,0,0,0
Mov pMapping, Eax
lea Ecx, Buffer
Push Ecx
Invoke RtlZeroMemory, Ecx, sizeof Buffer
Invoke RVAToOffset, pMapping, 3007h
Pop Ecx
invoke wsprintf, ADDR Buffer, ADDR Format, eax
Invoke MessageBox, NULL, Addr Buffer, Addr cpt, MB_OK
Invoke UnmapViewOfFile, pMapping
Invoke CloseHandle, hMapping
.endif
Invoke CloseHandle, hFile
.endif
.endif
ret
WinMain endp
end start
Your code and your skills will be assimilated. Your programming language is irrelevant.
We are the ASM Borg and you will become part of us. Compile and be assembled.