【求助】WM6.1中,DLL加壳加载(成功后分析原因)

wendyliyanni 2009-01-09 10:40:25
最近解决了一个问题,是这样的

我们自己用arm-linux交叉方式编译生成四个库,
这四个库在WM5.0/6.0的几款手机上采用Loadlibary方式加载,加载成功可以正常使用,
在某些WM6.1中也是可以加载成功的

但有一款死活就是加载不上

首先怀疑是机子硬件和平台的问题
通过比较 内核都是一样的 wince5.0 只有cpu主频有差异

试了很多方法,最后给这是个DLL用UPX加了一层压缩壳,结果就加载成功了 。

表面来看 就是这层压缩壳起了作用?但是不知道这加了压缩壳的dll是怎么加载的?

望达人不吝赐教 先谢谢啦^^

......................................................................
压缩下来的程序,section会变成三个。UPX0,UPX1,UPX2。

其中UPX0是虚段,具备实际的段名称和段地址,但是RawDateSize是0。所以这个段在载入后是全0数据。

数据和解压代码合并在了UPX1段中,由UPX1的解压代码注入UPX0的段中。解压代码附在了最后,从入口点到段实际内容结束点之间的范围。

而UPX2的段是一个单独的ImportTable,仅仅导入了Kernel32.dll中ExitProcess,LoadLibrary和GetProcessAddr三个函数。UPX1在解压并且注入UPX0后,会调用这三个函数来分析和获得每个导入表项的地址,然后完成导入表的动作。

upx0 解压缩后是原数据部分
upx1 原始的dll的function名,然后是解压缩代码
upx2 resouce及重新构建的import table

以上是在网上看到的有关UPX 压缩后的dll的三个section的解释

...全文
333 点赞 收藏 12
写回复
12 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
文斌 2009-01-12
楼上的静态链接应该是指在编译期的static link,在运行期不需要DLL文件.
回复
wendyliyanni 2009-01-11
[Quote=引用 7 楼 navi_dx 的回复:]
其实很简单,就是因为DLL太大了,Slot0的地址空间不够,所以加载失败,CE上所有DLL的地址空间是共享的,其他程序已经加载了很多DLL,你这个DLL这么大加载不了也是正常
UPX不仅是加壳,把程序也压缩了,这样加载如要的地址空间就少一些,实际的DLL是解压到堆上
不过这么大的DLL在CE上是不合适的,MSDN专门强调过这个问题,最好是静态链接到EXE
[/Quote]

您这里所说的静态连接是指生成静态lib库 链接到exe中,还是指动态连接库中隐式连接DLL的意思?对生成的dll进行隐式连接 我们试过不行。。。
回复
wendyliyanni 2009-01-11
[Quote=引用 7 楼 navi_dx 的回复:]
其实很简单,就是因为DLL太大了,Slot0的地址空间不够,所以加载失败,CE上所有DLL的地址空间是共享的,其他程序已经加载了很多DLL,你这个DLL这么大加载不了也是正常
UPX不仅是加壳,把程序也压缩了,这样加载如要的地址空间就少一些,实际的DLL是解压到堆上
不过这么大的DLL在CE上是不合适的,MSDN专门强调过这个问题,最好是静态链接到EXE
[/Quote]

但是还是有一个疑问 同样大小的库 不压缩 为什么在有的机子上就可以呢 都是WM6.1 的版本~
回复
wendyliyanni 2009-01-11
[Quote=引用 7 楼 navi_dx 的回复:]
其实很简单,就是因为DLL太大了,Slot0的地址空间不够,所以加载失败,CE上所有DLL的地址空间是共享的,其他程序已经加载了很多DLL,你这个DLL这么大加载不了也是正常
UPX不仅是加壳,把程序也压缩了,这样加载如要的地址空间就少一些,实际的DLL是解压到堆上
不过这么大的DLL在CE上是不合适的,MSDN专门强调过这个问题,最好是静态链接到EXE
[/Quote]

大哥能不能给个连接 学习一下^^ 先谢谢了~
回复
xdkui 2009-01-10
[Quote=引用 7 楼 navi_dx 的回复:]
其实很简单,就是因为DLL太大了,Slot0的地址空间不够,所以加载失败,CE上所有DLL的地址空间是共享的,其他程序已经加载了很多DLL,你这个DLL这么大加载不了也是正常
UPX不仅是加壳,把程序也压缩了,这样加载如要的地址空间就少一些,实际的DLL是解压到堆上
不过这么大的DLL在CE上是不合适的,MSDN专门强调过这个问题,最好是静态链接到EXE
[/Quote]

不错,能给几个link学习下吗?
ce5及以前每个slot有32M. 我现在是基于ce6开发,其内核重写了,虚存空间已经是4G了
回复
ciahi 2009-01-09
重定位就是有个重定位表

当Dll加载的地址不是默认的基址时,要用这个表来定位Dll中的数据
回复
wendyliyanni 2009-01-09
[Quote=引用 2 楼 ultrapro 的回复:]
WM 下有Kernel32.dll么?好像是CoreDll.dll吧,没看到过Kernel32.dll。
[/Quote]

这个只是个例子
在WM中实际上是Coredll.dll, 不加壳之前,Coredll.dll中的函数用工具是可以看到的
加了壳之后,很多coredll.dll中的函数是隐藏起来的 能看到的只有LoadlibaryW GetProAddressA 和CacheSync
而这三个函数的作用是在壳运行的时候,负责显示加载 那些隐藏起来的API函数

据网上资料所言 加了壳之后 改变的地方主要有两处:
一处是输入表 正如我上面所说的 将coredll.dll改了 这一块没什么问题了
另一处是改变了重定位信息 这个还不清楚具体是怎么弄的 看到的只是简单的1、2、3。。
回复
儿大不由爷 2009-01-09
WM 下有Kernel32.dll么?好像是CoreDll.dll吧,没看到过Kernel32.dll。
回复
beyondma 2009-01-09
这个太深奥了,没有发言的实力,MARK一下,精彩的话加精:)
回复
navi_dx 2009-01-09
其实很简单,就是因为DLL太大了,Slot0的地址空间不够,所以加载失败,CE上所有DLL的地址空间是共享的,其他程序已经加载了很多DLL,你这个DLL这么大加载不了也是正常
UPX不仅是加壳,把程序也压缩了,这样加载如要的地址空间就少一些,实际的DLL是解压到堆上
不过这么大的DLL在CE上是不合适的,MSDN专门强调过这个问题,最好是静态链接到EXE
回复
88csdn 2009-01-09
这个太深奥了,没有发言的实力,MARK一下
回复
wendyliyanni 2009-01-09
补充一点 :
我们的这几个库 特别大:
加壳之前是8.21M
加了压缩壳后是4.28M
回复
相关推荐
发帖
Windows客户端开发
创建于2007-08-27

7553

社区成员

Windows Phone是微软发布的一款手机操作系统,它将微软旗下的Xbox LIVE游戏、Zune音乐与独特的视频体验整合至手机中。
申请成为版主
帖子事件
创建了帖子
2009-01-09 10:40
社区公告
暂无公告