首页
社区
课程
招聘
请教关于加壳程序的资源处理
发表于: 2004-5-15 19:19 7313

请教关于加壳程序的资源处理

2004-5-15 19:19
7313
如果在写加壳程序时要把.rsrc块压缩,就必须把其中第一个图标资源和版本信息资源保存到loader的数据中,以便操作系统识别图标并显示在资源管理器中。但是操作系统究竟是如何从exe文件中找到图标数据的,是根据IMAGE_DATA_DIRECTORY中的资源项RVA,还是块名(section name),为什么我修改了这两个数据以后,操作系统仍然能在资源管理器中正确显示图标?
    如果把图标资源提取出来放到loader的数据中,就要修改IMAGE_DATA_DIRECTORY中的资源项RVA,那么在loader中是否只能用VirtualProtect的方法改回来,有没有更好的处理办法?

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 6
支持
分享
最新回复 (12)
雪    币: 6075
活跃值: (2236)
能力值: (RANK:1060 )
在线值:
发帖
回帖
粉丝
2
不是section name...
从原文件copy出来图标组并修改data dir,loader还原这些,
不需要vprot吧...
2004-5-15 20:05
0
雪    币: 6075
活跃值: (2236)
能力值: (RANK:1060 )
在线值:
发帖
回帖
粉丝
3
Processing the Resource Directory
Processing the resource directory is a strictly optional task. It is a bit tedious. Benefits of processing include preserving the ever-important application icon and version information so that one's experience with Explorer can be gratifying and
fulfilling, but also so we can support various OLE features.
If you don't care about these things simply carry on. If you do care, then more 'fun' awaits.
The 'fun' that awaits is similar to what we did for exports earlier in that we walk a structure and optionally copy stuff over, adjusting the pointer when we do and leaving it pointing to the original data in the compressed section otherwise.
The difference is that this structure is more complex, with more objects and a more complex decision on what to keep. First let me briefly tell you what you want to keep uncompressed because that's the easy part to know and tedious part to figure out
experimentally. You will want to keep uncompressed the following resources:
* first RT_ICON should be kept
* first RT_GROUP_ICON should be kept
* first RT_VERSION should be kept
* first "TYPELIB" should be kept
* all "REGISTRY" should be kept
OK, that being said, keep in mind that resources are a multi-level tree of directories. You need to keep track of at what level you are to make your comparisons in order to determine whether to keep a resource or not. Also, as a perceived convenience,
all the fixed sized structures are coalesced at the beginning with variable length ones afterwards. This means all the directory structures are at the beginning, with things like string identifiers and resource data afterwards.
I do a similar thing as with the stub and build this section in memory with a managed array of bytes. Once it is constructed I write it out later.
You can walk the tree once to find where this boundary between fixed and variable sized data lays, then copy the fixed data verbatim. It's interesting to not that most of the pointers in this section are relative to the section itself, and thus do not
require translation. The exception to this is the pointers to the actual resource data, which is an RVA.
Walk the tree a second time and append all the string identifiers. Adjust the pointers to these strings keeping in mind that they are _not_ RVAs, but are rather relative offsets into the resource section.
Walk the tree a third time and copy over the resource chunks for the resources types of interest described above. Keep in mind that these actually _are_ RVAs, so you will need to add the RVA of the beginning this section. What is that? Well, it is the
RVA of the last section, plus its size, aligned up to the NT_HEADERS::OptionalHeader.SectionAlignment. The resource chunks should be aligned between appends.
Setup the section header for this additional section. It _must_ have the name .rsrc. Setup the VirtualAddress of this section to the RVA we just computed. Setup the PointerToRawData in a similar manner, except use the last sections PointerToRawData +
SizeOfRawData and align the result up by the value of IMAGE_NT_HEADERS::OptionalHeader.FileAlignment instead. Set the SizeOfRawData to the size of the resulting chunk, and the VirtualSize to the same. You can align these values up if you like.
Similar to what we did with the stub, seek to the PointerToRawData and write out the data in the buffer we've been building.
Finally, set:
IMAGE_NT_HEADERS::OptionalHeader.DataDirectoryIMAGE_DIRECTORY_ENTRY_RESOURCE.VirtualAddress
IMAGE_NT_HEADERS::OptionalHeader.DataDirectoryIMAGE_DIRECTORY_ENTRY_RESOURCE.Size
and we are done with that.
2004-5-15 20:06
0
雪    币: 392
活跃值: (909)
能力值: ( LV9,RANK:690 )
在线值:
发帖
回帖
粉丝
4
谢谢!我先好好学习一下!:)
2004-5-15 20:34
0
雪    币: 392
活跃值: (909)
能力值: ( LV9,RANK:690 )
在线值:
发帖
回帖
粉丝
5
还是不太明白,PE文件加载以后可以再修改映象文件头中data dir中资源项的RVA吗?难道此时文件头是可写的?另外资源的首访问是发生在加载时还是第一次调用资源相关API的时候?
我看了一下UPX压缩过的文件,它保存了资源项的目录结构,但是用exescope打开是不可访问的,然而资源管理器中却正确识别了图标。

上面的引文中提到copy出来的资源“必须”放在名为.rsrc的section中,这儿确实是必须吗?

谢谢!
2004-5-15 20:45
0
雪    币: 6075
活跃值: (2236)
能力值: (RANK:1060 )
在线值:
发帖
回帖
粉丝
6
哦,这个需要去掉pe header保护.
资源应该是api访问的.
.rsrc可能不是必须的,但是所有的壳都是这么做,具体我也不明白
2004-5-16 13:02
0
雪    币: 392
活跃值: (909)
能力值: ( LV9,RANK:690 )
在线值:
发帖
回帖
粉丝
7
谢谢,我想了另一个办法,就是压缩的时候跳过资源目录表,只压缩后面的资源数据,把图标资源保存到loader数据中,并修改原数据目录表中指向Icon的RVA到loader中,这样就不用修改文件头中的数据目录了,但是要识别出资源目录表的位置和大小似乎有点困难,一定要遍历所有目录吗?有没有什么简单的办法?
2004-5-16 14:10
0
雪    币: 6075
活跃值: (2236)
能力值: (RANK:1060 )
在线值:
发帖
回帖
粉丝
8
我是不会压缩目录表:D
2004-5-16 14:18
0
雪    币: 392
活跃值: (909)
能力值: ( LV9,RANK:690 )
在线值:
发帖
回帖
粉丝
9
forgot兄帮忙看一下这两个文件,em_notepad是加壳后的文件,用Loadpe可以看到资源目录,dump下来的二进制文件和notepad原文件dump下来的图标资源完全一样,但是在exescope中就是分析不出ico资源,在资源管理器中也不能正常显示,这是为什么?

loader部分我还没有处理,data dir中的资源项RVA指向loader中的数据,所以还不能运行。谢谢!

点击下载:98记事本和加壳后的文件em_notepad
2004-5-16 16:39
0
雪    币: 392
活跃值: (909)
能力值: ( LV9,RANK:690 )
在线值:
发帖
回帖
粉丝
10
找到原因了!
原来是资源的RVA和size忘记写了:)
2004-5-16 17:10
0
雪    币: 6075
活跃值: (2236)
能力值: (RANK:1060 )
在线值:
发帖
回帖
粉丝
11
并且一些资源软件必须是.rsrc才能识别.
2004-5-16 17:13
0
雪    币: 392
活跃值: (909)
能力值: ( LV9,RANK:690 )
在线值:
发帖
回帖
粉丝
12
修改过了还是有问题,lordpe和peditor都可以完全识别资源目录表了,但图标就是显示不出来,能不能麻烦帮我看一下?点击下载:附件
2004-5-16 20:35
0
雪    币: 392
活跃值: (909)
能力值: ( LV9,RANK:690 )
在线值:
发帖
回帖
粉丝
13
终于解决了,原来资源ID的设置也有讲究……
2004-5-16 23:21
0
游客
登录 | 注册 方可回帖
返回
//