• Kill Safengine Shadow Dll(附源码)


                                            Kill Safengine Shadow Dll(OD插件)

     

    /**************************************
    /* 作者:半斤八兩
    /* 博客:http://cnblogs.com/bjblcracked
    /* 日期:2013-06-21  01:01
    /**************************************

     

    只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!

     

      端午回来在宿舍无聊上网,有一网友问se的shadow怎么绕过.之前就想研究的,正好刚放假回来无聊,就下载了个最新版 2.2.0.0 版本的加了一个壳看看 :)

     

    0x1. 分析如何下断?

    0x2. 分析如何shadow system function?

    0x3. 分析为何要alloc memory 2次, 多此一举?

    0x4. 分析用哪种方法处理shadow最好?

     

     

     

    0x1. 分析如何下断?

      得第一次分析SE的时候,无论怎样下断都下不下来.后面就下到了可能是shadow了.于是就想到一个最麻烦,但又最管用的方法,搜索特征码. 比如函数 User32.MessageBoxA 就把Msg头部,的特征码复制下来,到OD的内存窗口里面去搜索.这样就能下断了.虽然方法很管用.但是,如果我们要下的断点很多的话,那样就会显得相当麻烦.下面我们来分析看看她是如何shadow的.

     

    加壳时 [反内联API挂钩] 勾上即可 :)

     

    0x2. 分析如何shadow system function?

      规则,首先OD载入.然后我们想一下,他shadow 无非就是重载 或者重写.我们先以作者是重载的思路来分析看看:)

    重载常规的手段大概就两种. 

     

    1. 1种是读取system32 下的 DLL.

    2. 另一种就是读取已加载的模块内存.

     

    我们先试试第1种,读取 system32 的DLL,那么我们首先就是想到了 file 的那几个操作函数.

    Createfile readfile. 等.

    这里可能有的同学会问了,我们本身就是处理shadow的. 那file的这几个操作函数会不会是也已经shadow了?

    答案是 还没有. 因为我们刚OD载入.他的程序还没来的及处理呢.所以 file 操作的这几个函数,他还是用的原始的系统函数.这点大家可以放心.

     

    下面我们先对 createfilea/w readfile 下断. F9运行.

     

    断下回显:

     

    1 0012F604   0049C938  /CALL to CreateFileW from Shadow.0049C936
    2 0012F608   0012FC54  |FileName = "C:WindowsSystem32
    tdll.dll"
    3 0012F60C   80000000  |Access = GENERIC_READ
    4 0012F610   00000001  |ShareMode = FILE_SHARE_READ
    5 0012F614   00000000  |pSecurity = NULL
    6 0012F618   00000003  |Mode = OPEN_EXISTING
    7 0012F61C   00000080  |Attributes = NORMAL
    8 0012F620   00000000  hTemplateFile = NULL

     

     

    (为了方便,我们就以user32.messagebox 为例子讲解.)

     

    Createfilew 断下来了,第一个参数显示

    "C:WindowsSystem32 tdll.dll"

    我们不管它,继续 F9 运行.

     

    断下回显:

     

    1 0012FC28   00465FA9  /CALL to CreateFileW
    2 0012FC2C   0012FC54  |FileName = "C:WindowsSystem32
    tdll.dll"
    3 0012FC30   80000000  |Access = GENERIC_READ
    4 0012FC34   00000001  |ShareMode = FILE_SHARE_READ
    5 0012FC38   00000000  |pSecurity = NULL
    6 0012FC3C   00000003  |Mode = OPEN_EXISTING
    7 0012FC40   00000080  |Attributes = NORMAL
    8 0012FC44   00000000  hTemplateFile = NULL

     

     

     

    我们看见SE调用两次.先不管它,继续运行.

     

    断下回显:

     

    1 0012FC30   00465FC7  /CALL to ReadFile from Shadow.00465FC2
    2 0012FC34   000000A4  |hFile = 000000A4 (window)
    3 0012FC38   01480020  |Buffer = 01480020
    4 0012FC3C   0013AD40  |BytesToRead = 13AD40 (1289536.)
    5 0012FC40   0012FE5C  |pBytesRead = 0012FE5C
    6 0012FC44   00000000  pOverlapped = NULL

     

     

     

    Readfile 断下来了,第三个参数是 文件大小我们去系统文件夹下看一下 user32.dll 有多大.?

     

    User32 大小

    792 KB (811,520 字节)

     

    现在断下来的大小 13AD40 (1289536.) ntdll.dll .我们不用管它.继续运行.

    直到是 user32的大小的时候,才停下.

     

    在经过读取了 ntdll.dll kernelbase.dll kernel32.dll ,现在终于在user32.dll 下断下来了.

     

    断下回显:

    1 0012FBE8   0182D53F  /CALL to ReadFile from 0182D53A
    2 0012FBEC   000000A4  |hFile = 000000A4 (window)
    3 0012FBF0   01370020  |Buffer = 01370020
    4 0012FBF4   000C6200  |BytesToRead = C6200 (811520.)
    5 0012FBF8   0012FE5C  |pBytesRead = 0012FE5C
    6 0012FBFC   00000000  pOverlapped = NULL

     

     

     

    我们让他把文件读取出来,我们在 retn 0x14 处下 F2 断点. F9运行.

    我们能看到user32.dll 已经读取出来了.

     

    断下回显:

     

     1 013C0020  4D 5A 90 00 03 00 00 00 04 00 00 00 FF FF 00 00  MZ?........
     2 013C0030  B8 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00  ?......@.......
     3 013C0040  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
     4 013C0050  00 00 00 00 00 00 00 00 00 00 00 00 F0 00 00 00  ............?..
     5 013C0060  0E 1F BA 0E 00 B4 09 CD 21 B8 01 4C CD 21 54 68  
     6 013C0070  69 73 20 70 72 6F 67 72 61 6D 20 63 61 6E 6E 6F  is program canno
     7 013C0080  74 20 62 65 20 72 75 6E 20 69 6E 20 44 4F 53 20  t be run in DOS
     8 013C0090  6D 6F 64 65 2E 0D 0D 0A 24 00 00 00 00 00 00 00  mode....$.......
     9 013C00A0  2E 8D 3F 12 6A EC 51 41 6A EC 51 41 6A EC 51 41  .?j霶Aj霶Aj霶A
    10 013C00B0  63 94 D5 41 6B EC 51 41 6A EC 50 41 35 ED 51 41  c斦Ak霶Aj霵A5鞶A
    11 013C00C0  63 94 C2 41 6D EC 51 41 63 94 C3 41 6B EC 51 41  c斅Am霶Ac斆Ak霶A
    12 013C00D0  63 94 C4 41 6D EC 51 41 63 94 D2 41 17 EC 51 41  c斈Am霶Ac斠A霶A
    13 013C00E0  63 94 C5 41 6B EC 51 41 63 94 C0 41 6B EC 51 41  c斉Ak霶Ac斃Ak霶A
    14 013C00F0  52 69 63 68 6A EC 51 41 00 00 00 00 00 00 00 00  Richj霶A........
    15 013C0100  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
    16 013C0110  50 45 00 00 4C 01 04 00 2F DB 5B 4A 00 00 00 00  PE..L./踇J....
    17 013C0120  00 00 00 00 E0 00 02 21 0B 01 09 00 00 78 06 00  ....?!
    18 013C0130  00 E6 05 00 00 00 00 00 C9 F7 01 00 00 10 00 00  .?.....慎....

     

     

     

    我们还用0x1 的方法,现在来定位mesageboxa 的地方定位到后,

    我们在命令窗口处输入da  回车. (汇编格式显示数据再下个F2断点.然后F9跑起来.

    我们点demo上的 messagebox 按钮 .

     

    特征码:

    1 user32.MessageBoxA:
    2 8BFF558BEC??????????????742464A1180000006A00FF7024??????????????????????85C0750A????????????????????6A00FF7514FF7510FF750CFF7508??????????5DC21000

     

     

    刚按F9运行,OD就弹了一个类似如下的提示:

    Unable to read memory of debugged process (0141DE94..0141DE97).

     

    这是因为我们刚刚下的断点,已经不见了.为何不见了?

    这不是SE的反调试,也不是OD出问题了.而是我们刚刚下断点的那块内存已经free掉了.

     

    所以,这证实了,这一次读取的内存,还只是一个 shadow. 那么真正的实现函数在哪里?

    还有,现在读取出来的已经是shadow 的函数了.他为何又要free ?

     

     

    0x3. 分析为何要alloc memory 2次, 多此一举?

      分析几次,我们可以发现一个规律.第一次readfile 的数据.imagebase是固定不变的

    但是rva 始终固定不变,而且同user32.dll 的导出函数的 rva 保持一致.

    但是程序真正跑起来后的数据的 imagebase 和  rva 都是变化的 动态的

     

    我个人理解的是作者这样做,就是为了让imagebase and rva 动态让用户更难下断.

     

    知道了这些,那么我们只人对第一次readfile 的数据做处理至于第二次,他并没有readfile. 而是 new 了一内存,把第一次readfile 的数据拷贝进去但是这些我们都不用管它是怎么处理的呢.

    因为我们只要处理他第一次shadow 数据,即可因为第一次的数据虽然会free.但是他后面真正跑起来的shadow 是完全原封不动的拷贝第一次的shadow 数据.所以...你懂的...

     

    0x4. 分析用哪种方法处理shadow最好?

      信大家都知道 jmp xxx 的处理方法.我们只要在每个函数首部写上 jmp xxxx 这样即可.

    但是这样就会有一个问题了.什么问题?

    因为我们分析知道 rva 是固定的,但是imagebase 是动态的我们如何 jmp xxx?

    jmp xxx 的算法是 target- current- 5 ,但是我们当前的 imagebase 是动态的

    所以 jmp xxx 想法就泡汤了.

     

    X86 除了jcc这类直接式的转移指令,还有许多其他有意思的”间接”转移指令.

    如 push xxx /retn . 我们用这条指令,就可以解决 动态 imagebase 的问题因为 push xxxx 不用考虑重定位.所以 我们只要打开每个函数的入口,都写上 push xxxx / retn 就可恢复 se  的 shadow了 :)

     

    最后来个处女之作--OD插件图 -_-~

     

      具体的实现细节,我在文章中就不说了,大家看码吧~

     

    此插件是本人的第一个处女作.之前没有写过OD插件写了之后才发现OD的插件接口真是非常丰富.写起来毫无压力.但是在处理combobox 消息时,花了80%的时间 太久没有玩SDK 都不会写了 :(

     

    本插件仅支持win7. Xp 上有些不同,此版本插件没有处理.

    另外听朋友说有的OD使用此插件无效,但是朋友说换了个OD就能用了.具体原因我还没有时间看.~

     

    源码 插件 文档 下载地址:

    http://bbs.pediy.com/showthread.php?t=174005

  • 相关阅读:
    8皇后问题
    初级8皇后问题
    某个集合的子集问题
    n全排列输出和 n个数的组合(数字范围a~b)
    (转)李明博:我的12年等于24年 快速提升的秘诀是什么 别人以为我早起是先天的,事实靠的是努力 训练,除了反复的努力之外没有什么别的秘诀 像企业主一样去思考,一样查找问题,一同去解决它,并且还要制定出比企业主要求更高的目标。李明博像我一样,不,他比我更把公司当成自己的
    (转)当别人努力的时候,你在做什么? 评论事情的一种态度 当你在抱怨的时候,为什么不想想我做了什么? 把简单的原则坚持贯彻下去 消极的心态,养成了惯性的思维,一切都是不好的。 也许这就是人性的弱点,不经意的习惯,却逐渐腐蚀了你的人生。
    对于保险的看法和如何拒绝保险推销 保险应该主要是有2个主要作用: 1. 分担风险 2. 投资 保险的常用推销方法和该保险的卖点 拒绝保险的方法
    业务、架构、技术,我们应该关注什么 Java和.Net的优势劣势简单看法 市场经济决定,商业之道即是软件之道,市场的需求决定着软件技术的发展 利益决定着选择应用新技术
    我的学习工作经历,一个园林专业中专毕业生的IT之路 学习编程 创业
    “医疗信息化行业之中的联发科”- 我们在医疗行业中的定位及目标 想做一个面对中小企业的专业上游软件供应商 台湾联发科技颠覆掉的是一个封闭的手机产业系统 解决方案,即AgileHIS.NET数字化医院基础方案
  • 原文地址:https://www.cnblogs.com/BjblCracked/p/3148488.html
Copyright © 2020-2023  润新知