最近在学习PE文件, 被RVA和文件偏移搞的非常郁闷, 非常之纠结… 不过还好… 总算整明白了, 现整理下… 理下思路…. 就从罗云彬的教材中的例子说起吧…
.const
szNotFound db ‘无法查找’, 0
.code
;>>>>>>>>>>>>>>>>>
;将RVA转换为文件偏移
;>>>>>>>>>>>>>>>>>
_RVAToOffset proc _lpFileHead, _dwRVA
Local @dwReturn
Pushad
Mov esi, _lpFileHead
Assume esi : ptr IMAGE_DOS_HEADER ; esi指向DOS MZ文件头
Add esi, [esi].e_lfanew ;esi指向IMAGE_NT_HEADERS结构
;***************************************
;得到PE文件头的位置, 这个位置加上文件头长度就是节表的位置
;***************************************
Assume esi: ptr IMAGE_NT_HEADERS
Mov edi, _dwRVA ; edi中存在数据在内存中的RVA
Mov edx, esi
Add edx, sizeof IMAGE_NT_HEADERS
;ebx指向IMAGE_SECTION_HEADER结构
Assume edx: ptr IMAGE_SECTION_HEADER
Mozx ecx, [esi].FileHeader.NumberOfSections ;ecx存放节的数量
;************************************************
;扫描每个节并判断RVA是否存在于这个节内
;********************************************************
.repeat
Mov eax, [edx].VirtualAddress
;每个节的数据的起始位置相对于节的起始位置是不变的, 不管节是在文件中还是在文件中
Add [ebx].SizeOfRawData ; 节的大小
.if (edi >= [ebx].VirtualAddress) && (edi < eax) ;数据在该节内
Mov eax, [ebx].VirtualAddress
Sub edi, eax ;数据相对于节的起始地址的偏移地址RVA’
Mov eax, [ebx].PointerToRawData
Add eax, edi ;数据在文件中的偏移地址
Jmp @F
.endif
Add edx, sizeof IMAGE_SECTION_HEADER
.untilcxz
Assume edx:nothing
Assume esi: nothing
Mov eax, -1
@@:
Mov @dwReturn, eax
Popad
Mov eax, @dwReturn
Ret
_RVATOffset endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>