首页
社区
课程
招聘
用OD学习LoadPE内存转存方法
发表于: 2008-11-21 00:22 12237

用OD学习LoadPE内存转存方法

2008-11-21 00:22
12237
标 题: 用OD学习LoadPE内存转存方法
作 者: lijingli
时 间: 2008-11-07,19:27
链 接: http://bbs.pediy.com/showthread.php?p=538856#post538856


【文章标题】: 用OD学习LoadPE内存转存方法
【文章作者】: lijingli
【作者邮箱】: [EMAIL="lijingli168@126.com"]lijingli168@126.com[/EMAIL]
【作者QQ号】: 35928252
【使用工具】: OD
【操作平台】: Xp+Sp2
【作者声明】: 没什么技术,只是觉得应该回报一下论坛,虽然一点技术含量都没有。

从开始不懂汇编,到现在从事的工作,真的在看雪学了不少东西,虽然我还是很无知,
但是努力去学习,去追求,也许又一天我会进步很多。
谢谢坛主和大家的无私奉献,我真的希望能回报论坛,尽我小小的绵薄之力。

最近又把PE结构看了一遍,觉得以前看的总是记忆的不是很深刻,于是想编一个PE查看器
又无从下手,就想看看LordPE是用的什么方法。我用OD跟的。
内存转存最后还是要保存到硬盘上的,所以我BP CreateFileA ,
然后可以往上面分析应该就可以找到LordPE的内存转存方法了。
随便选择一个来转存,OD中断在 CreateFileA,如下:

00406C3A /CALL 到 CreateFileA 来自 LordPE.00406C34
0012FB80 |FileName = "D:\Program Files\QQ2008\QQUpdateCenter.exe"
80000000 |Access = GENERIC_READ
00000001 |ShareMode = FILE_SHARE_READ
00000000 |pSecurity = NULL
00000003 |Mode = OPEN_EXISTING
00000080 |Attributes = NORMAL
00000000 \hTemplateFile = NULL


幸运的是我看见了这个文件的路径,我猛然想起以前在论坛的书里看见过,
LordPE是直接读取磁盘上文件的PE头的。但是当时并没有真正的理解。
现在断在了这里,我才明白了LordPE内存转存的方法了(运气占了很大的成分。。 )。

然后CTRL+F9返回。

往上分析,就看见了,LordPE通过:
00402C2C |. E8 4B560100   call <jmp.&procs.GetProcessPath>
00402C31 |. EB 17         jmp short 00402C4A
00402C33 |> 8B4C24 18     mov ecx, dword ptr [esp+18]
00402C37 |. 8B5424 30     mov edx, dword ptr [esp+30]
00402C3B |. 8D8424 B40100>lea eax, dword ptr [esp+1B4]
00402C42 |. 50            push eax
00402C43 |. 51            push ecx
00402C44 |. 52            push edx
00402C45 |. E8 3E560100   call <jmp.&procs.GetModulePath>


获取执行文件所在的路径,然后通过CreateFileA来打开磁盘上的文件,
然后通过ReadFile读取文件的DOS和PE头,并比较PE的标志:
|> push 0 ; /pOverlapped = NULL
|> push ecx ; |pBytesRead
|> lea edx,dword ptr [esp+1C] ; |
|> push 40 ; |BytesToRead = 40 (64.)
|> push edx ; |Buffer
|> push esi ; |hFile
|> call edi ; \ReadFile
|> test eax, eax
|> je 00406CFE
|> cmp word ptr [esp+14], 5A4D           ;比较MZ 
|> je short 00406C8C
]

然后比较PE标志:
|. 6A 00 push 0
|. 51 push ecx
|. 8D5424 5C lea edx, dword ptr [esp+5C]
|. 68 F8000000 push 0F8
|. 52 push edx
|. 56 push esi
|. FFD7 call edi ; ReadFile
|. 85C0 test eax, eax
|. 74 48 je short 00406CFE
|. 817C24 54 50450000 cmp dword ptr [esp+54], 4550    ; 比较PE标志
|. 75 3E jnz short 00406CFE


然后读取磁盘文件映像的前面的0x1000:
0012F9A0 00406CF5 /CALL 到 ReadFile 来自 LordPE.00406CF3
0012F9A4 00000150 |hFile = 00000150 (window)
0012F9A8 011A0020 |Buffer = 011A0020
0012F9AC 00001000 |BytesToRead = 1000 (4096.)
0012F9B0 0012F9C8 |pBytesRead = 0012F9C8
0012F9B4 00000000 \pOverlapped = NULL


然后通过ImageNtHeader获取内存中映像的指针。
call dword ptr [<&IMAGEHLP.ImageNtHea>; IMAGEHLP.ImageNtHeader
xor edx, edx                          ;测试获取的PE指针是否为0
cmp eax, edx
je short 0041640D
xor ecx, ecx
mov cx, word ptr [eax+14]             ;PE可选头的大小
lea ecx, dword ptr [ecx+eax+18]       ;代码段的起始RVA
mov dword ptr [ebp-4], edx
mov dword ptr [ebp-1C], edx
xor esi, esi
mov si, word ptr [eax+6]              ;块的数目
cmp edx, esi
jnb short 004163D5                    ;是否小于0
mov esi, dword ptr [ecx+C]            ;该块的RVA
mov dword ptr [ecx+14], esi           ;该块的RVA移到PointToRawData(在文件中的偏移)
mov esi, dword ptr [ecx+8]            ;[ecx+8]该块的真实长度
mov dword ptr [ecx+10], esi           ;[ecx+10]对齐后的长度,即修正文件对齐后的长度
add ecx, 28                           ;转到下一块
mov dword ptr [ebp-20], ecx
inc edx
jmp short 004163B3
mov dword ptr [ebp-4], -1
mov ecx, 1000
mov dword ptr [eax+3C], ecx           ;修正转存文件的文件对齐为0x1000
mov dword ptr [eax+54], ecx           ;修正部首+块表的大小为0x1000

然后修正转存文件的文件对齐为0x1000,修正RAW为RVA。

之后把DOS,PE头和内存中的块表和块的内容连接起来,写到磁盘上。
就完成了LordPe对内存文件的转存。

写完之后才发现,真的是一点技术含量都么有。
哎,希望能给大家一点启发吧。
第一次发表帖子,有不对的地方大家原谅吧。

[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

收藏
免费 7
支持
分享
最新回复 (9)
雪    币: 2110
活跃值: (21)
能力值: (RANK:260 )
在线值:
发帖
回帖
粉丝
2
鼓励原创,支持自己动手分析。

写得非常好,不要觉得技术含量低,总会对人有帮助的。
2008-11-21 00:24
0
雪    币: 44229
活跃值: (19960)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
3
能不能把图中的汇编代码再帖一份出来?这样整理到论坛精华集时,就收集文本了,精华集的何种会小些。
2008-11-21 09:09
0
雪    币: 236
活跃值: (16)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
4
谢谢老大的提醒 第一次写有点笨拙了  今天有时间整理一下
2008-11-21 23:21
0
雪    币: 236
活跃值: (16)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
5
谢谢! 我会努力的
2008-11-22 00:26
0
雪    币: 131
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
以下几处不懂
“往上分析,就看见了,LordPE通过”
都从00406c23到00402C2C了 ,还往上?翻多久才翻到啊.....
2008-11-22 13:38
0
雪    币: 236
活跃值: (16)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
7
前一个是堆栈
你返回之后可以分析程序的流程呀
2008-11-22 19:02
0
雪    币: 7906
活跃值: (3086)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
学习了,虽然看不懂,但是要收藏起来慢慢看
2008-11-22 19:12
0
雪    币: 236
活跃值: (16)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
9
其实没什么 就是又2个API :CreateFile 和ReadFile 知道了在两个函数 再对着PE结构就可以看懂了
2008-11-23 09:33
0
雪    币: 229
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
00406E22  |.  E8 55140100   call    <jmp.&procs.GetProcessPath>
00406E27  |.  85C0          test    eax, eax
00406E29  |.  74 30         je      short 00406E5B
00406E2B  |.  EB 17         jmp     short 00406E44
00406E2D  |>  8B8424 800100>mov     eax, dword ptr [esp+180]
00406E34  |.  8D5424 70     lea     edx, dword ptr [esp+70]
00406E38  |.  52            push    edx
00406E39  |.  50            push    eax
00406E3A  |.  53            push    ebx
00406E3B  |.  E8 48140100   call    <jmp.&procs.GetModulePath>

怎么分析到的是00406E22而不是00402C2C |. E8 4B560100   call <jmp.&procs.GetProcessPath>
虽然两处代码一样
2008-11-24 12:27
0
游客
登录 | 注册 方可回帖
返回
//