首页
社区
课程
招聘
[原创]某反XX系统驱动部分逆向(连载)
发表于: 2007-7-13 00:50 19644

[原创]某反XX系统驱动部分逆向(连载)

2007-7-13 00:50
19644

近段时间国内游戏行业发展一片大好,其衍生产品也是数不剩数.近日拿到一反XX系统的驱动,偷得闲看来玩玩 稍有心得,于此与大家共享

所逆的代码力求尽量忠于源码,驱动某几部分中几个逻辑比较复杂的地方仍然没有做优化,照葫芦画飘的写了出来.如有疏漏 敬请指正

此驱动的大致工作流程就是在DriverDispatch时通过应用层控制Hook SSDT两张表(此部分做的有些问题,貌似在某些情况下对第二张较少使用的表的HOOK会因为没有使用Shadow而无效) HOOK 中断,以及一些其他的反调试技术.

今日贴出其DriverEntry部分代码,其他函数将在近日内贴出.因涉及敏感问题,所以某些重要字符串以及代码作了些修改和省略 重在学习

ULONG  OSVesion=0;
#define OS_WIN2K  0x01
#define OS_WINXP  0x02
#define OS_WIN2K3  0x03
#define OS_WINVISTA  0x04
inline  VOID SetOSVersion(INT  MajorVer,INT  MinorVer);

LARGE_INTEGER  CurrentTime;

//定义几个WIN32KSSDT表里函数的对应INDEX.具体函数名字省略
ULONG  NtFuntion1  ;
ULONG  NtFuntion2  ;
ULONG  NtFuntion3  ;
ULONG  NtFuntion4  ;
ULONG  NtFuntion5  ;
ULONG  NtFuntion6  ;

//HOOK校验 ,检测有没被脱钩或者2次挂钩
BYTE  m_INTHookCheck[20];
PVOID  AllocSec;
_declspec(naked) INTHook(VOID);
//此函数功能为检测DR6状态,看是否是由于硬件断点引起

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, 
                IN PUNICODE_STRING RegistryPath)
{
  NTSTATUS  ntStatus;

  ULONG  MajorVersion=0;
  ULONG  DeviceObject=0;
  ULONG  MinorVersion=0;
  ULONG  BuildNumber=0;
      
  PUNICODE_STRING  DeviceNameString;
  PUNICODE_STRING  SymbolicLinkName;
  PUNICODE_STRING  NTDeviceName="\\Device\\DeviceName";
  PUNICODE_STRING  DosDeviceName="\\DosDevices\\DosDeviceName";
  
  PsGetVersion(&MajorVersion,&MinorVersion,&BuildNumber,NULL);
  SetOSVersion(MajorVersion,MinorVersion);

  if((OSVesion==0)||(OSVersion>4))  ntStatus=STATUS_NOT_SUPPORTED;
  else 
  {    
    //可识别的OS,首先保存自身断点Hook Handle头DWORD,后边用于检测是否被修改
    memcpy(m_INT1HookCheck,INT1Hook,20);
    switch(OSVersion)
    {
      case 1: //Win2K
        {
        //这里就是对那几个INDEX对应的操作系统里的INDEX硬编码,代码省略.下同
        }
        break;
      case 2://WinXP
        {

        }
        break;
      case 3://Win2003
        {

        }
        break;
      case 4://Vista
        {

        }
        break;
    }
    KeQuerySystemTime(&CurrentTime);
    AllocSec=MmAllocateNonCachedMemory(0x2000);
    if(AllocSec!=NULL) memset(AllocSec,0,0x800);
    RtlInitUnicodeString(&DeviceNameString, NTDeviceName);

    //安装驱动程序
    ntStatus = IoCreateDevice(DriverObject, 0, &DeviceNameString, ????, 0, TRUE, &DeviceObject);
     if ( NT_SUCCESS(ntStatus) )
     {
      // 创建符号链,Win32 apps将其导入链表允许其通过驱动器/驱动程序
      RtlInitUnicodeString(&DeviceNameString,DosDeviceName);
      ntStatus = IoCreateSymbolicLink(&SymbolicLinkName, &DeviceNameString);
      //.... 
      // 创建指针用以驱动程序的控制和创建
      DriverObject->MajorFunction[IRP_MJ_CREATE]      =  DrvDispatch
      DriverObject->MajorFunction[IRP_MJ_CLOSE]      =  DrvDispatch;
      DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]  =  DrvDispatch;
      DriverObject->DriverUnload = DrvUnload;
      
      if  (  NT_SUCESS(nStatus)  )  KeLowerIrql(KeRaiseIrqlToDpcLevel());
      else
      {
        if(  DeviceObject   !=  NULL)
        {
          IoDeleteSymbolicLink(&SymbolicLinkName);
          DeleteDevice(&DeviceObject);
        }
      }
    }
     ntStatus  =  DeviceObject;
  };
  return nStatus;
}

Dispatch函数在11楼.


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 7
支持
分享
最新回复 (31)
雪    币: 198
活跃值: (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
ULONG  NtFuntion1  ;->NtGdiGetPixel
ULONG  NtFuntion2  ;->NtUserSendInput
ULONG  NtFuntion3  ;->NtUserCallNextHookEx
ULONG  NtFuntion4  ;->NtUserPostMessage
ULONG  NtFuntion5  ;->NtUserTranslateMessage
ULONG  NtFuntion6  ;->NtUserMapVirtualKeyEx

补充int1proxyproc还有2个计数。分别记录r0和r3层引起的int1 异常。

对应的index是
win2k:
0BBh,1E1h,137h,1CBh,224h,1BAh
winxp:
0BFh,1F6h,141h,1DBh,239h,1CAh
win2k3:
0BEh,1F4h,140h,1DAh,235h,1C9h
winvista:
0C6h,20Dh,14Bh,1F1h,251h,1DDh
2007-7-13 09:46
0
雪    币: 398
活跃值: (343)
能力值: (RANK:650 )
在线值:
发帖
回帖
粉丝
3
上面两个
不是我马甲
2007-7-13 09:47
0
雪    币: 208
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
4
此帖应改名为sh连载
2007-7-13 10:04
0
雪    币: 331
活跃值: (56)
能力值: ( LV13,RANK:410 )
在线值:
发帖
回帖
粉丝
5
sh系列
2007-7-13 10:06
0
雪    币: 192
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
6
sh0000 shaaaa shbbbb shjjjj shpppp shzzzz sh....
2007-7-13 10:15
0
雪    币: 218
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
NaX
7
要放就放全啦,遮遮掩掩干什么呢?
传说中的XDva..... ?
2007-7-13 10:17
0
雪    币: 398
活跃值: (343)
能力值: (RANK:650 )
在线值:
发帖
回帖
粉丝
8
PUNICODE_STRING  NTDeviceName="\\Device\\DeviceName";
  PUNICODE_STRING  DosDeviceName="\\DosDevices\\DosDeviceName";

这样写是不对的
2007-7-13 10:18
0
雪    币: 331
活跃值: (56)
能力值: ( LV13,RANK:410 )
在线值:
发帖
回帖
粉丝
9
等待lz连载
UNICODE_STRING是个结构。不能这样写。或者把帖子标题改成伪码。

难道是故意的。。。?
2007-7-13 10:18
0
雪    币: 218
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
NaX
10
嗯 看来楼主还没有把代码编译一下
2007-7-13 10:19
0
雪    币: 208
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
11
//这里用到的几个全局变量和结构定义
typedef struct HookStruct
{
        ULONG        Index;
        ULONG        Original_Fun_Addr;
        ULONG        Hook_Fun_Addr;
}SSDTHook;
VOID        UnHookNtkrSSDT(INT        Index,PVOID        OriginalAdd,PVOID        HookAddr);
BOOLEN        UnknowFlag1;
BOOLEN        ReSendKeyFlag;

NTSTATUS DrvDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{

    PIO_STACK_LOCATION  irpStack;
    PVOID               ioBuffer;
    ULONG               inputBufferLength;
    ULONG               outputBufferLength;
    ULONG               ControlCode;
    NTSTATUS            ntStatus;
       
    Irp->IoStatus.Status      = STATUS_SUCCESS;
    Irp->IoStatus.Information = 0;

    // 获取当前irp当前栈空间
    irpStack = IoGetCurrentIrpStackLocation(Irp);

    // Get the pointer to the input/output buffer and it's length
    inputBufferLength  = irpStack->Parameters.DeviceIoControl.InputBufferLength;
    outputBufferLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;

    // ....
    switch(irpStack->MajorFunction)
    {
    case IRP_MJ_CLOSE:
                {
                        if(* pSystemServiceDeorTable->ServiceTableBase        !=        NULL)
                        {
                                UnHookNtkrSSDT(NtkrSSDT_HOOK[0].Index,NtOpenProcess_Hook);
                                ..
                                ..
                                ..
                        };
                        if(* (pSystemServiceDeorTable+0x10)        !=        NULL) //这里貌似有问题 米有用Shadow? 在我的电脑上是0x0O0O0O
                        {
                                UnHookWin32KSSDT(Win32KSSDT_HOOK[0].Index, NtGdiGetPixel_Hook);
                                ..
                                ..
                        }
                        if(UnknowFlag1)        UnknowFlagw1        =        false;
                        if(ReSendKeyFlag)
                                _asm
                                {
                                        cli
                                        push    0FEh            ; Value
                                        push    64h             ; Port
                                        call    ds:WRITE_PORT_UCHAR ; 重发键盘按键到i8042 Output寄存器
                                        hlt        //这里这个HLT难道不会死掉??请大家指教一下
                                }
        break;
                }
    case IRP_MJ_DEVICE_CONTROL:
                {
                    ControlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;
                        switch (ControlCode&0x03)
                        {        // ioctl开始过滤,其实也没做别的什么,就是根据不同模式选择与APP交互用的Buffer
                        case METHOD_NEITHER:
                                ioBuffer        =        Irp->UserBuffer;
                                break;
                        default:
                                ioBuffer        =        Irp->AssociatedIrp.SystemBuffer;
                                break;
                        }       
                        ntStatus        =        DirverDispatch        (Irp,FileObject,1,Irp->AssociatedIrp.SystemBuffer,
                                                                                        inputBufferLength,ioBuffer,outputBufferLength,ControlCode,
                                                                                PVOID pIO_STATUS_BLOCK,DeviceObject);       
                        return nStatus;
                }
        case  IRP_MJ_CLEANUP:
                  {
                                ntStatus        =        STATUS_SUCCESS;
                                break;
                  }
        default:
                  ntStatus        =        STATUS_INVALID_DEVICE_REQUEST;
                  Irp->IoStatus.Status        =        ntStatus;

        }
    //没有错误的操作,返回状态
        IoCompleteRequest(Irp, IO_NO_INCREMENT);  
    return ntStatus;
}
2007-7-13 14:14
0
雪    币: 218
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
NaX
12
果然是XDva.....
向0x64端口写0xFE 本来就是“GameOver”的
2007-7-13 14:57
0
雪    币: 208
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
13
明白!谢谢  好个"GameOver"
2007-7-13 14:59
0
雪    币: 331
活跃值: (56)
能力值: ( LV13,RANK:410 )
在线值:
发帖
回帖
粉丝
14
关注,建议加精
2007-7-13 15:16
0
雪    币: 207
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
15
这个反XX的代码真粗劣...
游戏厂商胆子也蛮大的...
2007-7-13 15:32
0
雪    币: 210
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
16
楼主故意的??
2007-7-13 17:16
0
雪    币: 208
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
17
居然米人关注..汗 没有发IoControl的动力了
2007-7-13 19:41
0
雪    币: 331
活跃值: (56)
能力值: ( LV13,RANK:410 )
在线值:
发帖
回帖
粉丝
18
可能因为太简单了。发NP的肯定有人
2007-7-13 20:00
0
雪    币: 2575
活跃值: (502)
能力值: ( LV2,RANK:85 )
在线值:
发帖
回帖
粉丝
19
我关注哟。
这个是NP的驱动部分吧?
2007-7-13 20:11
0
雪    币: 331
活跃值: (56)
能力值: ( LV13,RANK:410 )
在线值:
发帖
回帖
粉丝
20
是Np早就100楼了。
2007-7-13 20:14
0
雪    币: 2575
活跃值: (502)
能力值: ( LV2,RANK:85 )
在线值:
发帖
回帖
粉丝
21

那是什么?
2007-7-13 20:18
0
雪    币: 331
活跃值: (56)
能力值: ( LV13,RANK:410 )
在线值:
发帖
回帖
粉丝
22
不是NP不是HS
2007-7-13 20:21
0
雪    币: 208
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
23
是传说中的某某某
2007-7-13 20:40
0
雪    币: 8835
活跃值: (2404)
能力值: ( LV12,RANK:760 )
在线值:
发帖
回帖
粉丝
24
被逆了
2007-7-13 21:31
0
雪    币: 208
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
支持楼主~^_^
2007-7-13 23:51
0
游客
登录 | 注册 方可回帖
返回
//