能力值:
( LV9,RANK:490 )
|
-
-
2 楼
这里面有个对齐的问题。
一般文件中的对齐是0x200,而加载之后内存中的对齐一般是0x1000。
如果文件中第一个节从0x600开始,其中有个数据地址是0x612,那么它载入之后位于内存中的什么位置呢?
再假设文件被加载到了0x400000(基址),文件中的第一个节被加载到了0x1000,只有知道了这些,这样我们才能确定内存中的地址为0x401012。
所以,仅仅给一个文件中的偏移和加载基址是不能确定他在内存中的地址的。
不知道我说得有没有错误,反正我是这么理解的,仅供参考吧。
|
能力值:
( LV2,RANK:10 )
|
-
-
3 楼
如楼上说,那就是0x612只是在文件里面直接打开的时候看到到地址
而虚拟地址==文件加载的基址+节加载的基址+数据在节中的偏移
例如0x401012=0x400000+0x1000+12??即使是这样,不过还是有点迷糊
希望有哪个朋友能结合个实例,例如用PE加载工具后看到有一地址,然后就算出这地址用OD打开在哪里,用winhex这些工具打开会在哪里,
哪个高手厉害,就做个专题给我等菜鸟吧,谢谢了
|
能力值:
( LV9,RANK:490 )
|
-
-
4 楼
罗云彬的win32汇编里有详细的介绍。给你个RVAtoFileOffset的源码,希望对你有帮助。
注:此源码来自附带光盘。
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Sample code for < Win32ASM Programming 2nd Edition>
; by 罗云彬, http://asm.yeah.net
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.const
szNotFound db '无法查找',0
.code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 将 RVA 转换成实际的数据位置
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_RVAToOffset proc _lpFileHead,_dwRVA
local @dwReturn
pushad
mov esi,_lpFileHead
assume esi:ptr IMAGE_DOS_HEADER
add esi,[esi].e_lfanew
assume esi:ptr IMAGE_NT_HEADERS
mov edi,_dwRVA
mov edx,esi
add edx,sizeof IMAGE_NT_HEADERS
assume edx:ptr IMAGE_SECTION_HEADER
movzx ecx,[esi].FileHeader.NumberOfSections
;********************************************************************
; 扫描每个节区并判断 RVA 是否位于这个节区内
;********************************************************************
.repeat
mov eax,[edx].VirtualAddress
add eax,[edx].SizeOfRawData ;eax = Section End
.if (edi >= [edx].VirtualAddress) && (edi < eax)
mov eax,[edx].VirtualAddress ;eax= Section start
sub edi,eax ;edi = offset in section
mov eax,[edx].PointerToRawData
add eax,edi ;eax = file offset
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
_RVAToOffset endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 查找 RVA 所在的节区
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_GetRVASection proc _lpFileHead,_dwRVA
local @dwReturn
pushad
mov esi,_lpFileHead
assume esi:ptr IMAGE_DOS_HEADER
add esi,[esi].e_lfanew
assume esi:ptr IMAGE_NT_HEADERS
mov edi,_dwRVA
mov edx,esi
add edx,sizeof IMAGE_NT_HEADERS
assume edx:ptr IMAGE_SECTION_HEADER
movzx ecx,[esi].FileHeader.NumberOfSections
;********************************************************************
; 扫描每个节区并判断 RVA 是否位于这个节区内
;********************************************************************
.repeat
mov eax,[edx].VirtualAddress
add eax,[edx].SizeOfRawData ;eax = Section End
.if (edi >= [edx].VirtualAddress) && (edi < eax)
mov eax,edx ;eax= Section Name
jmp @F
.endif
add edx,sizeof IMAGE_SECTION_HEADER
.untilcxz
assume edx:nothing
assume esi:nothing
mov eax,offset szNotFound
@@:
mov @dwReturn,eax
popad
mov eax,@dwReturn
ret
_GetRVASection endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
能力值:
( LV2,RANK:10 )
|
-
-
5 楼
。。。。汇编吃力了点。。
|
能力值:
(RANK:350 )
|
-
-
6 楼
http://bbs.pediy.com/showthread.php?t=31840
看看4.2 虚拟地址和偏移量转换
|
能力值:
( LV2,RANK:10 )
|
-
-
7 楼
谢谢坛主啊,哈哈
|
能力值:
( LV2,RANK:10 )
|
-
-
8 楼
最重要是是看雪老大里面发的一个对齐的图。再次感谢老大
希望不懂的朋友和我一样去看看那个图。。
|
能力值:
( LV2,RANK:10 )
|
-
-
9 楼
这些东西也只能看懂一部份,学校没教。
|
能力值:
( LV2,RANK:10 )
|
-
-
10 楼
直接用16进制编辑器打开查看的时候,虚拟偏移、虚拟地址、原始偏移、原始地址和特征值都是逆序的,记得还原回来!如 00050000 -> 00000500
|
能力值:
( LV2,RANK:10 )
|
-
-
11 楼
不是吧,统一是这样转换吗?不太明白楼上的。
不过通过看雪大哥的那个图我已经看懂那些地址的转换了
|
能力值:
( LV2,RANK:10 )
|
-
-
12 楼
嗯,都是这样,其实在跟踪软件的时候你也会发现字符串是逆序的
|
能力值:
( LV2,RANK:10 )
|
-
-
13 楼
从右向左一个字(就是两位)一个字的读取就可以了
|