首页
社区
课程
招聘
[求助]关于PE里面的地址,弄几天了,快搞死我了
发表于: 2008-2-3 17:14 4111

[求助]关于PE里面的地址,弄几天了,快搞死我了

2008-2-3 17:14
4111
PE里面的结构我已经弄清楚了,不过关于PE里面那些地址,真晕死我了,用16进制打开从0000000开始的这些是文件offset嘛,然后在里面内容读到的地址有些人说是虚拟地址,不过我又在看http://bbs.pediy.com/showthread.php?t=19618这里面构造一个pe的时候,里面的地址又是直接写 在文件中的偏移。我快晕死了,有个转换工具又说到VA-RVA-OFFSET这三个地址的转换,晕哦,又跑出了三个地址,不是有一个文件中从0000000开始这样的偏移和一个加载到内存里面+虚拟基址就够了吗(例如用OD打开一个文件后显示的地址减去0040000后的地址)?

也许我说不够好,不过我真的很想搞清楚,
不知道有没朋友在哪看到学得比较通俗易懂的文章,或者是你怎么理解清楚的

麻烦贴出来,谢谢。感激不尽!

[课程]Linux pwn 探索篇!

收藏
免费 0
支持
分享
最新回复 (12)
雪    币: 485
活跃值: (12)
能力值: ( LV9,RANK:490 )
在线值:
发帖
回帖
粉丝
2
这里面有个对齐的问题。
一般文件中的对齐是0x200,而加载之后内存中的对齐一般是0x1000。
如果文件中第一个节从0x600开始,其中有个数据地址是0x612,那么它载入之后位于内存中的什么位置呢?
再假设文件被加载到了0x400000(基址),文件中的第一个节被加载到了0x1000,只有知道了这些,这样我们才能确定内存中的地址为0x401012。
所以,仅仅给一个文件中的偏移和加载基址是不能确定他在内存中的地址的。

不知道我说得有没有错误,反正我是这么理解的,仅供参考吧。
2008-2-3 18:14
0
雪    币: 254
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
如楼上说,那就是0x612只是在文件里面直接打开的时候看到到地址

而虚拟地址==文件加载的基址+节加载的基址+数据在节中的偏移
例如0x401012=0x400000+0x1000+12??即使是这样,不过还是有点迷糊

希望有哪个朋友能结合个实例,例如用PE加载工具后看到有一地址,然后就算出这地址用OD打开在哪里,用winhex这些工具打开会在哪里,

哪个高手厉害,就做个专题给我等菜鸟吧,谢谢了
2008-2-3 18:48
0
雪    币: 485
活跃值: (12)
能力值: ( 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
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
2008-2-3 18:55
0
雪    币: 254
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
。。。。汇编吃力了点。。
2008-2-3 22:20
0
雪    币: 44229
活跃值: (19965)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
6
http://bbs.pediy.com/showthread.php?t=31840

看看4.2 虚拟地址和偏移量转换
2008-2-4 09:31
0
雪    币: 254
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
谢谢坛主啊,哈哈
2008-2-4 13:48
0
雪    币: 254
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
最重要是是看雪老大里面发的一个对齐的图。再次感谢老大

希望不懂的朋友和我一样去看看那个图。。
2008-2-10 15:18
0
雪    币: 6
活跃值: (18)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
这些东西也只能看懂一部份,学校没教。
2008-2-10 17:00
0
雪    币: 252
活跃值: (14)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
直接用16进制编辑器打开查看的时候,虚拟偏移、虚拟地址、原始偏移、原始地址和特征值都是逆序的,记得还原回来!如 00050000 -> 00000500
2008-2-10 19:18
0
雪    币: 254
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
不是吧,统一是这样转换吗?不太明白楼上的。
不过通过看雪大哥的那个图我已经看懂那些地址的转换了
2008-2-11 15:14
0
雪    币: 252
活跃值: (14)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
嗯,都是这样,其实在跟踪软件的时候你也会发现字符串是逆序的
2008-2-12 09:47
0
雪    币: 252
活跃值: (14)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
从右向左一个字(就是两位)一个字的读取就可以了
2008-2-12 09:48
0
游客
登录 | 注册 方可回帖
返回
//