据统计90%查看本帖的人,都已经注册本站了哦
您需要 登录 才可以下载或查看,没有账号?立即注册
×
写在最前:
这只是一份demo.朋友软件被通过注入的方式做了PJ,我就帮忙写了这份源码
实际上这只是一种治标不治本的方法,但是也有一定的可行性
就这种方法而言,我的这份demo并非完善,甚至还有很多很显而易见的漏洞
比如我没HOOK LoadLibraryEx,也没有hook 使用宽字符的函数,不过原理基本没啥变化,有心人可以自行完善和补充.
工作原理:
1.通过hook LoadLibrary拦截所加载的模块.
b.在LoadLibrary中插入自己的暗桩代码.同时自己再调用LoadLibrary,根据暗桩是否触发判断hook是否被恢复
c.通过模块路径,模块版权信息,数字签名判断模块是否为非法模块
代码说明:
如下是对LoadLibraryA Hook的代码
把LoadLibrary返回的hModule保存起来,并且插入了我们自己的暗桩代码,如果是调用我们自己的验证模块,则调用模块内的check函数
同时还用一个定时器调用LoadLibrary.以确保check函数被一直调用
变量名 | 类 型 | 静态 | 数组 | 备 注 | i | 整数型 | | | hModule | 整数型 | | | fileFullName | 文本型 | | | filePath | 文本型 | | | info | 文件版本信息 | | |
计次循环首 (loaded. size (), i ) hModule = GetModuleHandle (loaded. get (i ))  判断 (hModule = 0 )  编辑框1. 加入文本 (loaded. get (i ) + “.hModule=NULL” + #换行符 )  fileFullName = getModulePath (hModule )  判断 (fileFullName = “”)   编辑框1. 加入文本 (loaded. get (i ) + “.hModule=” + 到文本 (hModule ) + “ getPath=NULL” + #换行符 )   filePath = _全路径取 路径 (fileFullName )   判断 (-1 ≠ 寻找文本 (取运行目录 (), filePath, , 真))     判断 (whiteList. index (loaded. get (i )) = 0 )     编辑框1. 加入文本 (loaded. get (i ) + “.hModule=” + 到文本 (hModule ) + “ hackerModule” + #换行符 )     编辑框1. 加入文本 (loaded. get (i ) + “.hModule=” + 到文本 (hModule ) + “ whiteListModule” + #换行符 )        取文件版本信息 (fileFullName, info )    判断 (-1 ≠ 寻找文本 (info.合法版权, “Microsoft Corporation. All rights reserved”, , 真))      编辑框1. 加入文本 (loaded. get (i ) + “.hModule=” + 到文本 (hModule ) + “ Microsoft Corporation Library” + #换行符 )    判断 (VerifyEmbeddedSignature (A2W (fileFullName )) )     编辑框1. 加入文本 (loaded. get (i ) + “.hModule=” + 到文本 (hModule ) + “ userModule” + #换行符 )     编辑框1. 加入文本 (loaded. get (i ) + “.hModule=” + 到文本 (hModule ) + “ hackerModule” + #换行符 )              计次循环尾 ()
check函数:
check函数取得MessageBoxW函数的地址,并且修改头4字节的内存为timeGettime()
因为易语言用的都是ascii,所以MessageBoxW一般很少用到
当然后期的修改也可以对timegettime的值做加密再写入或者用pipedName等其他办法代替,还可以甚至加上你的心跳包
变量名 | 类 型 | 静态 | 数组 | 备 注 | i | 整数型 | | | hModule | 整数型 | | | fileFullName | 文本型 | | | filePath | 文本型 | | | info | 文件版本信息 | | |
计次循环首 (loaded. size (), i ) hModule = GetModuleHandle (loaded. get (i ))  判断 (hModule = 0 )  编辑框1. 加入文本 (loaded. get (i ) + “.hModule=NULL” + #换行符 )  fileFullName = getModulePath (hModule )  判断 (fileFullName = “”)   编辑框1. 加入文本 (loaded. get (i ) + “.hModule=” + 到文本 (hModule ) + “ getPath=NULL” + #换行符 )   filePath = _全路径取 路径 (fileFullName )   判断 (-1 ≠ 寻找文本 (取运行目录 (), filePath, , 真))     判断 (whiteList. index (loaded. get (i )) = 0 )     编辑框1. 加入文本 (loaded. get (i ) + “.hModule=” + 到文本 (hModule ) + “ hackerModule” + #换行符 )     编辑框1. 加入文本 (loaded. get (i ) + “.hModule=” + 到文本 (hModule ) + “ whiteListModule” + #换行符 )        取文件版本信息 (fileFullName, info )    判断 (-1 ≠ 寻找文本 (info.合法版权, “Microsoft Corporation. All rights reserved”, , 真))      编辑框1. 加入文本 (loaded. get (i ) + “.hModule=” + 到文本 (hModule ) + “ Microsoft Corporation Library” + #换行符 )    判断 (VerifyEmbeddedSignature (A2W (fileFullName )) )     编辑框1. 加入文本 (loaded. get (i ) + “.hModule=” + 到文本 (hModule ) + “ userModule” + #换行符 )     编辑框1. 加入文本 (loaded. get (i ) + “.hModule=” + 到文本 (hModule ) + “ hackerModule” + #换行符 )              计次循环尾 ()
钩子检查:
取出我们写入的时间值,和timeGetTime做比对,看看是否超过一定的范围,是的话则说明钩子被处理
变量名 | 类 型 | 静态 | 数组 | 备 注 | i | 整数型 | | | hModule | 整数型 | | | fileFullName | 文本型 | | | filePath | 文本型 | | | info | 文件版本信息 | | |
计次循环首 (loaded. size (), i ) hModule = GetModuleHandle (loaded. get (i ))  判断 (hModule = 0 )  编辑框1. 加入文本 (loaded. get (i ) + “.hModule=NULL” + #换行符 )  fileFullName = getModulePath (hModule )  判断 (fileFullName = “”)   编辑框1. 加入文本 (loaded. get (i ) + “.hModule=” + 到文本 (hModule ) + “ getPath=NULL” + #换行符 )   filePath = _全路径取 路径 (fileFullName )   判断 (-1 ≠ 寻找文本 (取运行目录 (), filePath, , 真))     判断 (whiteList. index (loaded. get (i )) = 0 )     编辑框1. 加入文本 (loaded. get (i ) + “.hModule=” + 到文本 (hModule ) + “ hackerModule” + #换行符 )     编辑框1. 加入文本 (loaded. get (i ) + “.hModule=” + 到文本 (hModule ) + “ whiteListModule” + #换行符 )        取文件版本信息 (fileFullName, info )    判断 (-1 ≠ 寻找文本 (info.合法版权, “Microsoft Corporation. All rights reserved”, , 真))      编辑框1. 加入文本 (loaded. get (i ) + “.hModule=” + 到文本 (hModule ) + “ Microsoft Corporation Library” + #换行符 )    判断 (VerifyEmbeddedSignature (A2W (fileFullName )) )     编辑框1. 加入文本 (loaded. get (i ) + “.hModule=” + 到文本 (hModule ) + “ userModule” + #换行符 )     编辑框1. 加入文本 (loaded. get (i ) + “.hModule=” + 到文本 (hModule ) + “ hackerModule” + #换行符 )              计次循环尾 ()
模块检查
a.首先我们判断是否有非白名单内的模块在根目录下加载,是的话判定为非法模块.这种办法可以预防一些挟持注入.当然可能这样写有点不合理
b.判断文件的版权信息,如果是白名单版权的则认定为有效文件
c.判定数字签名是否有效.
变量名 | 类 型 | 静态 | 数组 | 备 注 | i | 整数型 | | | hModule | 整数型 | | | fileFullName | 文本型 | | | filePath | 文本型 | | | info | 文件版本信息 | | |
计次循环首 (loaded. size (), i ) hModule = GetModuleHandle (loaded. get (i ))  判断 (hModule = 0 )  编辑框1. 加入文本 (loaded. get (i ) + “.hModule=NULL” + #换行符 )  fileFullName = getModulePath (hModule )  判断 (fileFullName = “”)   编辑框1. 加入文本 (loaded. get (i ) + “.hModule=” + 到文本 (hModule ) + “ getPath=NULL” + #换行符 )   filePath = _全路径取 路径 (fileFullName )   判断 (-1 ≠ 寻找文本 (取运行目录 (), filePath, , 真))     判断 (whiteList. index (loaded. get (i )) = 0 )     编辑框1. 加入文本 (loaded. get (i ) + “.hModule=” + 到文本 (hModule ) + “ hackerModule” + #换行符 )     编辑框1. 加入文本 (loaded. get (i ) + “.hModule=” + 到文本 (hModule ) + “ whiteListModule” + #换行符 )        取文件版本信息 (fileFullName, info )    判断 (-1 ≠ 寻找文本 (info.合法版权, “Microsoft Corporation. All rights reserved”, , 真))      编辑框1. 加入文本 (loaded. get (i ) + “.hModule=” + 到文本 (hModule ) + “ Microsoft Corporation Library” + #换行符 )    判断 (VerifyEmbeddedSignature (A2W (fileFullName )) )     编辑框1. 加入文本 (loaded. get (i ) + “.hModule=” + 到文本 (hModule ) + “ userModule” + #换行符 )     编辑框1. 加入文本 (loaded. get (i ) + “.hModule=” + 到文本 (hModule ) + “ hackerModule” + #换行符 )              计次循环尾 ()
写在最后:
本人搞了几年游戏了,也多少了解到一些PJ与反PJ,个人观点还是认为没必要太崇拜壳子
基本把关键代码VM一下也差不多了,壳子更多的是调试和一些相关的检测,这些其实网上很多资料了.
起码我这一两年来,我的验证系统都只用vmp1.22做了vm,没有任何其他的壳子的保护.
主要的还是自己的系统是否严谨,是否能有效的增加PJ的难度.
如果一个市面上销售的软件,个人更倾向于一个全局钩子,对一些敏感的api做处理,自身把用到的一些敏感的api自己做一个hook做处理,加上CRC可能效果未必比壳差
当然了,以上都是本人的愚见而已,希望大神们也不吝赐教.
|