首页
论坛
课程
招聘
[原创]驱动反调试----点softice死穴
2010-1-10 15:59 17867

[原创]驱动反调试----点softice死穴

2010-1-10 15:59
17867
驱动反调试----点softice死穴
       为表达对看雪论坛的支持,特把这两天研究驱动的一点心得变成文字,以作留念。实事求是地讲,这是我写得第一个驱动,希望大家喜欢。
     作为一个驱动菜鸟,首先恶补了一些驱动理论,像《Windows驱动开发技术详解》、《软件调试》、《从汇编语言到windows内核编程》等电子书网上都能下到。看书就要看好书,我可不想一上来就被误导,当然书上的东西我们还是不能全信。
     其次初步熟悉了驱动开发环境和各种调试工具的使用,windbg、softice我是都装电脑里了,就差熟练使用了。编译驱动,我是一键编译(ddk),当然只有懒人才想得出来。在论坛上我写过一篇相关文章,如果感兴趣的话,可以找出来看看。用vc++6.0编译也很简单,照《Windows驱动开发技术详解》一书里设置一下编译、调试选项即可,根本不需要装什么乱七八糟的软件。再用个能显示行号的记事本编辑源文件就ok了,有行号便于由编译出错信息中提示的行号定位源文件中出错的地方。用windbg的open crash dump菜单看看蓝屏后的系统生成的*.dmp文件也可以快速找到错误(默认不保存*.dmp文件,当然你要在windows里先设置一下)。
   
     

     废话这么多,下面讲点softice死穴。在调试驱动过程中,我发现了softice的一个敏感穴位,在这里我就不保密了。Softice对键盘中断进行了hook,见图hook,jpg,先push中断服务的真正入口,然后jmp到 softice的处理代码。在处理的开始先读取60端口的scan code
而后保存到某处。这里就是关键,如果这里不保存,那么将不会回显键盘输入的字符,其效果就是键盘无法输入。这样就可以被我们用来反调试,当我们的内核代码检测到softice后就把该处替换成垃圾指令,那么键盘就不起作用了,当然就无法继续调试。原理很简单,具体实现如下:
   
     
  
#include "ntddk.h"
#include <stdio.h>
#define MAKELONG(a, b) ((unsigned long) (((unsigned short) (a)) | ((unsigned long) ((unsigned short) (b))) << 16))
int        kb_int = 0;
#pragma pack(1)
typedef struct
{
        unsigned short LowOffset;
        unsigned short selector;
        unsigned char unused_lo;
        unsigned char segment_type:4;         
        unsigned char system_segment_flag:1;
        unsigned char DPL:2;         
        unsigned char P:1;
        unsigned short HiOffset;
} IDTENTRY;

typedef struct
{
        unsigned short IDTLimit;
        unsigned short LowIDTbase;
        unsigned short HiIDTbase;
} IDTINFO;

typedef struct
{
        unsigned char  E9_BYTE;
        unsigned long  JMP_ADDR;
} MYPATCH;

#pragma pack()
unsigned long ISR_pointer,tt;       
unsigned char ss,Sice_Protected;
MYPATCH*   k;

int irq1_svcnumber()
{
        unsigned char *pIoRegSel;
        unsigned char *pIoWin;
        unsigned char ch;
        PHYSICAL_ADDRESS        phys;
        PVOID                                pAddr;
        phys.u.LowPart = 0xFEC00000;  
        pAddr = MmMapIoSpace(phys, 0x14, MmNonCached);//读0x14字节即可,最后一个dword就是I/O WINDOW REGISTER
        if (pAddr == NULL)
                return 0;
        pIoRegSel = (unsigned char *)pAddr;
        pIoWin = (unsigned char *)(pAddr) + 0x10;

        *pIoRegSel = 0x12;         
        ch = *pIoWin;
        MmUnmapIoSpace(pAddr, 0x14);
        return (int)ch;
}
/*
The PIIX3 decodes the 82093AA(IOAPIC) in memory space.
Memory Address: FEC0xy00h (xy=See APICBASE Register in the PIIX3)
Typically, IOREGSEL Register is at 00h and IOWIN Register is at 10h.
interl 82093AA has 24 I/O Redirection Table entry registers.  IOREDTBL[0]-IOREDTBL[23]
Each register is a dedicated entry for each interrupt input.
IOREDTBL[1] is the entry for keyboard interrupt (IRQ1), which address offset is 12-13h.
Here IOWIN Register is used to read vector from the IOAPIC register(IOREDTBL[1])
specified by 0x12 which was written to the IOREGSEL Register.
Redirection table entries的低8位就是vector
*/
VOID OnUnload( IN PDRIVER_OBJECT DriverObject )
{                
         if (Sice_Protected==1) {
             __asm  cli
             k->E9_BYTE=ss;
             k->JMP_ADDR=tt;
             __asm sti
            DbgPrint("Anti_Softice end.");   
         };
            DbgPrint("Welcome! by 天易love 2010-1-10");       
}

NTSTATUS DriverEntry( IN PDRIVER_OBJECT theDriverObject, IN PUNICODE_STRING theRegistryPath )
{
        IDTINFO                idt_info;                 
        IDTENTRY*        idt_entries;         
        unsigned long         addr;
        unsigned long* addr1;       
        unsigned char*  ch;
       
        Sice_Protected=0;
       
        theDriverObject->DriverUnload  = OnUnload;
        kb_int = irq1_svcnumber();
        DbgPrint("kb_int = 0x%02X\n", kb_int);
       
        __asm        sidt        idt_info
        idt_entries = (IDTENTRY*) MAKELONG(idt_info.LowIDTbase,idt_info.HiIDTbase);
        ISR_pointer = MAKELONG(idt_entries[kb_int].LowOffset,idt_entries[kb_int].HiOffset);

          ch=(unsigned  char*)(ISR_pointer);  //68 表示push指令
          if (*ch!=0x68) {                       //判断是否运行softice 有无hook
            DbgPrint("There is no Softice.");
            return STATUS_SUCCESS;
           }
      addr1=(unsigned  long*)(ISR_pointer+6);
      
        __asm{              //定位patch的地方
            cli
            mov  eax,addr1
                mov  eax,[eax]
                add  eax,addr1
                add  eax,0x3d       
                mov  addr,eax  //          
            };
          
           k = (MYPATCH*) addr;
           ss=k->E9_BYTE;     //unload时需要
           tt=k->JMP_ADDR;
          
          k->E9_BYTE=0x83;         //83C0 00         ADD EAX,0  填上垃圾指令
          k->JMP_ADDR=0xc08b00c0; //8BC0           MOV EAX,EAX
       __asm sti
    Sice_Protected=1;
        DbgPrint("0x%08X is the address patched  within sice",addr);
    DbgPrint("Anti_Softice start....");
        return STATUS_SUCCESS;
}

     

代码在灵想技术GHOSTXPSP3电脑城装机版 V7.0 Build 20090820下测试通过,截图留念。
     
     
代码有些地方你不一定能看懂,必须要通过调试才有感性认识,我就不详细注释了。注意中断服务号即vector的取得也不是很简单,我参考了资料一并奉上。
最后感谢大家!
                                              By 天易love  2010-1-10

[2022冬季班]《安卓高级研修班(网课)》月薪两万班招生中~

上传的附件:
收藏
点赞0
打赏
分享
最新回复 (14)
雪    币: 356
活跃值: 活跃值 (58)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
未签收 活跃值 2010-1-10 20:43
2
0
留下记号.等基础知识学好了再回来学习此帖
雪    币: 200
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
ikeart 活跃值 2010-1-10 21:14
3
0
通过感性的调试竟然能有这样的认知,值得学习
雪    币: 244
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
liuxmzc 活跃值 2010-1-11 22:41
4
0
没想到《软件调试》也被人做成电子版啊。
雪    币: 1653
活跃值: 活跃值 (318)
能力值: ( LV12,RANK:1000 )
在线值:
发帖
回帖
粉丝
天易love 活跃值 18 2010-1-11 23:35
5
0
一千多页做成电子书也就一百兆多点,还是建议有钱人买正版书,穷人嘛花一块钱去网吧下载得了。
雪    币: 284
活跃值: 活跃值 (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
jerrynpc 活跃值 2010-1-12 10:00
6
0
支持楼主,努力学习
雪    币: 58
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
skybright 活跃值 2010-1-12 10:10
7
0
lz很强大,支持一个!
雪    币: 435
活跃值: 活跃值 (43)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
ucantseeme 活跃值 2010-1-13 15:03
8
0
那我的书钱白花了
雪    币: 105
活跃值: 活跃值 (259)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Fido 活跃值 2010-1-13 21:16
9
0
思路可以..........
雪    币: 293
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
onbadday 活跃值 2010-1-20 16:56
10
0
谢谢分享经验
雪    币: 4
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
asmbulls 活跃值 2010-1-20 21:30
11
0
恶补基础中。
雪    币: 125
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
yangchao忽忽 活跃值 2010-1-21 00:05
12
0
很好很强大
雪    币: 130
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
subme1 活跃值 2010-1-22 09:33
13
0
站个位以后继续看
雪    币: 135
活跃值: 活跃值 (75)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
wkaka 活跃值 2010-2-18 19:43
14
0
感谢分享,支持+学习楼主
雪    币: 11
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
贾宝玉 活跃值 2010-2-18 20:40
15
0
不明白楼主的驱动是做什么用的啊
游客
登录 | 注册 方可回帖
返回