首页
社区
课程
招聘
[求助]如何校验内存中的dll是否被篡改?
发表于: 2013-7-10 09:40 16182

[求助]如何校验内存中的dll是否被篡改?

2013-7-10 09:40
16182
我们知道一个dll 静态的hash值,因为dll被加载的起始地址可能无法预料,所以某些汇编代码可能不同

难道是每次在载入的时候查找到dll的起始地址,计算一下,然后使用这个进行校验?
还是使用某些方式把编码固定下来?
或者是镜像一份到一个不太可能被人使用的起始地址,然后这个起始地址是我们预先定义好的,然后就可以确定了?
或者吧内存中的抠出来写到文件 对文件进行校验?
或者 自己查找当前加载的基址,然后把所有重定位的的部分按照标准的基址进行重新计算偏移
使用自己计算出来的十六进制值来计算hash值,而不是对程序加载的dll进行计算

对 内存中的dll 进行校验计算的过程中
遇到是 重定位的 汇编代码
我们根据 dll真实加载的基址 和标准的基址 进行重新计算 这句汇编指令
然后拿 这句我们自己计算的汇编指令 代替原始的汇编代码 输入 hash函数 进行计算
也就是  相当于 计算一份标准基址 加载的代码

我也不知道 这样的 校验 需要平衡那些因素

我的意思是dll 加载到内存之后和在硬盘上面的内容已经不一样了
你怎么确定加载到内存之后的dll 没有被篡改?
假如 你只知道 dll 在硬盘上面的一个校验值
一年前毕业时候面试的一个题目
我也记不太清自己当时的答案了不过好像面试官不是很满意我的答案

[课程]Linux pwn 探索篇!

收藏
免费 0
支持
分享
最新回复 (28)
雪    币: 110
活跃值: (522)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
2
简单说一下个人见解,内存校验如果DLL不大的话可以整个较验,采用一定的算法。。。

example:

......

viod Check()
{
    BaseDll=GetDLLBase("XX.dll",pid);
   for(int i=BaseDll,i<BaseDll+DllSize;i+=4)
  {
    int * p=(int *)BaseDll;
    int sum+=p;
  }
   if(sum!=OrginalSize)
    //Memory have been Writen
}
....

如果DLL很大的话建议分块较检
2013-7-10 10:43
0
雪    币: 275
活跃值: (51)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
3
你没看懂我的意思
我的意思是dll 加载到内存之后和在硬盘上面的内容已经不一样了
你怎么确定加载到内存之后的dll 没有被篡改?
假如 你只知道 dll 在硬盘上面的一个校验值
2013-7-10 16:38
0
雪    币: 615
活跃值: (530)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
4
对呀,同样的问题,游戏的CRC32是怎么做的?  就算是只检验代码的,有些偏移还是会因为机器不同,而改变呀,同求解
2013-7-10 16:42
0
雪    币: 2105
活跃值: (424)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
5
处理一下重定位就行了。
2013-7-10 20:45
0
雪    币: 275
活跃值: (51)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
6
怎么单独处理 、
2013-7-10 21:33
0
雪    币: 110
活跃值: (522)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
7
人家是说处理重定位。。代码段肯定还是一样的,,数据段这些肯定是不变的。
2013-7-11 13:42
0
雪    币: 126
活跃值: (169)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
8
检查重定位表,凡是重定位表中要修改的都不参与校验就行了
2013-7-14 12:04
0
雪    币: 228
活跃值: (115)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
9
非常简单  大概这样子
void  CRC(BYTE *pBase,DWORD size)
{
      BYTE *pCrc = LoadCrc(XXX.CRC)
      for(int i = 0;i < size;i++)
      {
            if(Check(pBase[i],pCrc[i]))
            {
                 被干了....
            }
      }
}

XXX.CRC 文件可以你在自己进程加载启动后用工具自己生成个,然后自己加密下.Check的时候解密.然后跟进程进行计算.
如果这样都没有给你足够的思绪,那就放弃吧.你不适合黑暗界
2013-7-14 12:57
0
雪    币: 275
活跃值: (51)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
10
要求都得校验啊
2013-7-15 09:15
0
雪    币: 275
活跃值: (51)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
11
不知道是没理解我的意思,还是我没理解你的意思
,我问的关键在于重定位导致的代码不同,
其他部分的思路都比较容易
2013-7-15 09:17
0
雪    币: 228
活跃值: (115)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
12
神一样的思维啊.你想用是原始的DLL作为CRC源啊.要RELOAD啊.然后再处理啊,目测也不复杂啊.就一个模块啊 整个CRC表啊.果然不适合黑暗界啊....
2013-7-15 15:30
0
雪    币: 220
活跃值: (117)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
13
按导出表扫描本地代码即可
本地导出表函数CRC 然后内存继续CRC
2013-7-17 11:20
0
雪    币: 1042
活跃值: (470)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
重定位很蛋疼啊~难道非得检测代码被修改?为何不换种思路,即使修改了也无用呢~
2013-7-17 21:01
0
雪    币: 112
活跃值: (57)
能力值: ( LV12,RANK:200 )
在线值:
发帖
回帖
粉丝
15
exediy 的方案真简洁~
2013-7-17 21:07
0
雪    币: 275
活跃值: (51)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
16
你说的 和我也没什么不同啊
我就是想问个问题本身 不涉及到代码实现 更没必要设计什么校验算法
我只是 很久没接触这个了 都忘了
而不是用什么方式来实现某个功能

我想知道的 我说的 是不是 有问题,

你说我不适合黑暗界,我也没说我就是想做黑暗界的
只不过是你更熟悉更了解 而我很久没接触都忘记了
不代表你的思维能力 会比我好

结贴吧 各位
2013-7-18 08:53
0
雪    币: 275
活跃值: (51)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
17
结贴 研究 还原声音去
2013-7-18 08:56
0
雪    币: 228
活跃值: (115)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
18
RELOAD满世界有代码啊.论坛一抓就三份代码了.而且如果是单个模块,或者只是进程部分,完全不需要RELOAD...
2013-7-18 13:43
0
雪    币: 267
活跃值: (438)
能力值: ( LV9,RANK:190 )
在线值:
发帖
回帖
粉丝
19
只要知道是哪个DLL文件位置,就可以模拟加载这个DLL,然后进行数据比较。模拟加载过程中,基地址就用已经加载的DLL基地址。这样只要不是dll运行过程中自己修改映像中的数据,那就可以校验dll代码是否被修改。正好我这几天也在想这个问题,不过我是想校验内核的代码。Ring3下的系统dll代码校验,我之前做过了。
2013-7-18 14:04
0
雪    币: 166
活跃值: (42)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
20
学习了,虽然一定能用代码写出来,但是思路清晰了解了
2013-7-18 14:38
0
雪    币: 267
活跃值: (438)
能力值: ( LV9,RANK:190 )
在线值:
发帖
回帖
粉丝
21
我觉得思路很简单,我们也就模拟加载一下PE文件甚至我不需要内存对齐,PE节也不用按PE映像内存对齐粒度对齐,我们只需要:把PE文件数据读入内存,然后直接可以用任何基地址模拟加载,当然为了代码检查,我们需要选择DLL被加载的基地址进行模拟加载咯!
2013-7-18 15:26
0
雪    币: 275
活跃值: (51)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
22
我的意思是对已经加载进内存的dll 判断他是否被篡改了
假设现在硬盘上的dll文件已经消失了
2013-7-19 16:28
0
雪    币: 275
活跃值: (51)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
23
模拟加载 ?是什么情况,不真正加载不会对已经加载到内存中的dll产生影响
2013-7-19 16:30
0
雪    币: 267
活跃值: (438)
能力值: ( LV9,RANK:190 )
在线值:
发帖
回帖
粉丝
24
如果现在硬盘上的dll文件已经消失了,那除非你知道系统或内存什么地方还有这个DLL文件数据的备份,不然似乎不太可能校验DLL代码是否被修改了!
2013-7-20 15:43
0
雪    币: 267
活跃值: (438)
能力值: ( LV9,RANK:190 )
在线值:
发帖
回帖
粉丝
25
我这里的模拟加载指的是: 把DLL的PE文件数据以普通方式或映射方式读进内存,(可以不用实施节数据按内存对齐,只要读入PE文件的原始数据)然后重定位PE文件数据,重定位选择的基地址为:PE加载器加载的DLL模块基地址。然后你就可以对DLL模块的代码进行校验的。当然如果你想模拟加载的更像一点,就把各个PE节移动到内存对齐,然后调用入口函数,最后再代码校验。
2013-7-20 15:51
0
游客
登录 | 注册 方可回帖
返回
//