找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 16395|回复: 13

TsSysKit深度分析

[复制链接]
发表于 2015-9-20 11:20:40 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有账号?立即注册→加入我们

×
本帖最后由 元始天尊 于 2015-9-27 13:07 编辑

TsSysKit.sys分析报告
        该驱动为qq管家穿透驱动,提供文件、注册表穿透,和解锁文件、驱动加载、句柄、进程等操作,导出接口给其他驱动使用,设备名\\Device\\TSSysKit,符号名\\DosDevices\\TSSysKit。加密手段:Rabbit算法、MD5算法。
目录
TsSysKit.sys分析报告        1
一、        驱动入口DriverEntry        2
1.1 检测加载者是否为Ntos        2
1.2 执行删除任务 DoDeleteJob        3
二、        驱动接口Interface        5
2.1 DeviceExtension接口        5
2.2 与WRK代码异同点        6
2.3 重置/保存注册表对象ObjectInitialzer例程        6
NtCreateKey        7
NtOpenKey        9
NtQueryValueKey        10
NtSetValueKeyEx        11
NtDeleteValueKey        12
NtDeleteKey        13
IopCreateFile        13
三、        控制码        17
0x221C00解锁文件        21
0x222004普通结束进程        21
0x22242C穿透创建服务加载驱动        22
四、        默认派遣例程        26
3.1 根据进程id结束进程        26
3.2 获取当前进程进程名        26
3.3 由进程ID获取进程设备名        27
3.4 设备名转DOS路径        28
3.5 得到EPROCESS对应ImageDosPath        29
3.6 随机化程序名机制        30
3.7 根据进程文件名获取进程信息        31
3.8 两种方式调用内核函数        31
3.9 获取对象类型        32
3.10 基础库功能——检测腾讯程序合法性        32
3.11 解锁文件        34
五、        获取ObjectInitializer        40
4.1 获取注册表OBJECT_TYPE,匹配对象类型        40
4.2获取ParseProcedure        42
4.3 获取GetCellRoutine偏移,Hook GetCellRoutine        43
4.4 Hook和UnHook GetCellRoutine        44
4.5 创建系统线程获取 Cm*函数        45
4.6 匹配结构        49
4.7 获取DeviceObject对象类型        59


一、        驱动入口DriverEntry
        获取系统版本_1
        获取EPROCESS的ObjectTypeIndex  (win7以前 0x1C  win8 0x1F  Win8.1 0x1E)
        创建\\Device\\TSSysKit设备和\\DosDevices\\TSSysKit符号链接
        设置DeviceExtension为通信接口(Interface函数指针)
        注册IRP_MJ_CREATE、IRP_MJ_CLOSE、IRP_MJ_DEVICE_CONTROL派遣例程为DefaultDispatch
        获取CmpKeyObject、DeviceObject的OBJECT_TYPE_INITIALIZER
GetCmpKeyObjectInitializerFunc        GetDeviceObjectInitializerFunc
        获取ZwQueryVirtualMemory、IoVolumeDeviceToDosName、PsGetProcessSectionBaseAddress地址和NtQueryVirtualMemory的index
        检测加载者是否为Ntos (CheckIopLoadDriver)
        执行开机删除操作(DoDeleteJob)  删除ShutdownRecord.ini指定的文件
  

1.1 检测加载者是否为Ntos
顺带保存IopLoadDriver
  1. int CheckIopLoadDriver()
  2. {
  3.         unsigned int IopLoadDriverNext; // esi@2
  4.         PRTL_PROCESS_MODULES modules; // ebx@5
  5.         int IopLoadDriver; // esi@8
  6.         PVOID Base; // eax@9
  7.         PVOID Callers[4]; // [sp+8h] [bp-18h]@1
  8.         BOOL ret; // [sp+18h] [bp-8h]@1
  9.         ULONG SystemInformationLength; // [sp+1Ch] [bp-4h]@1

  10.         Callers[0] = 0;
  11.         Callers[1] = 0;
  12.         Callers[2] = 0;
  13.         Callers[3] = 0;
  14.         ret = 0;
  15.         SystemInformationLength = 0;
  16.         ::IopLoadDriver = 0;
  17.         if ( RtlWalkFrameChain(Callers, 4u, 0) == 4 )
  18.                 // [0]=RtlWalkFrameChain next
  19.                 // [1]=DriverEntry
  20.                 // [2]=IopLoadDriver
  21.                 // [3]=IopInitializeSystemDrivers
  22.         {
  23.                 IopLoadDriverNext = Callers[3];
  24.                 if ( MmIsAddressValid(Callers[3]) )
  25.                 {
  26.                         if ( IopLoadDriverNext >= MmUserProbeAddress && *(IopLoadDriverNext - 5) == 0xE8u )// call ***
  27.                         {
  28.                                 SystemInformationLength = sizeof(SYSTEM_MODULE_INFORMATION) + 3 * sizeof(RTL_PROCESS_MODULE_INFORMATION);
  29.                                 modules = ExAllocatePoolWithTag(0, SystemInformationLength, '!KIT');
  30.                                 if ( modules )
  31.                                 {
  32.                                         memset(modules, 0, SystemInformationLength);
  33.                                         if ( ZwQuerySystemInformation(SystemModuleInformation,modules,SystemInformationLength,&SystemInformationLength) >= 0 )
  34.                                         {
  35.                                                 if ( modules->NumberOfModules )
  36.                                                 {
  37.                                                         IopLoadDriver = *(IopLoadDriverNext - 4) + IopLoadDriverNext;
  38.                                                         if ( MmIsAddressValid(IopLoadDriver) )
  39.                                                         {
  40.                                                                 Base = modules->Modules[0].ImageBase;
  41.                                                                 if ( IopLoadDriver >= Base && IopLoadDriver <= (Base + modules->Modules[0].ImageSize) )
  42.                                                                 {                               // 检测IopLoadDriver是否在ntos中
  43.                                                                         ::IopLoadDriver = IopLoadDriver;
  44.                                                                         ret = 1;
  45.                                                                 }
  46.                                                         }
  47.                                                 }
  48.                                         }
  49.                                         ExFreePool(modules);
  50.                                 }
  51.                         }
  52.                 }
  53.         }
  54.         return ret;
  55. }
复制代码

1.2 执行删除任务 DoDeleteJob
如果腾讯安装目录存在ShutdownRecord.ini文件则删除该文件,解析文件列表中指定的文件并逐个删除,其中解析ini的api、文件操作都是自己实现的。删除方式采用NtSetInformationFile 置FileDispositionInformation。

ShutdownRecord.ini格式:
[DELETEFILECOUNT]
Count=3
[DELETEFILELIST]
0=0.txt
1=1.txt
2=2.txt

enum
{
        WIN2000=1,
        WINXP=2,
        WINXPSP3=3,
        WINVISTA=4,
        WIN7=5,
        WIN8=7,
        WIN8_1=8,
        WIN10=9,
        UNKNOWN=10,
};

二、        驱动接口Interface
2.1 DeviceExtension接口
DeviceObject->DeviceExtension(=Interface)  通过制定序号返回对应函数指针,穿透函数内部在ObOpenObjectByName前后会保存和恢复注册表Objectinitializer:
FARPROC Interface(intindex)
{//注意下面的函数都是自己实现的穿透函数
    switch(index)
    {
    case 1:
        return NtOpenKey;
    case 2:
        return NtQueryValueKey;
    case 3:
        return NtSetValueKeyEx;
    case 4:
        return NtDeleteValueKey;
    case 5:
        return NtDeleteKey;
    case 20:
        return IopCreateFile;
    case 21:
        return NtReadFile;
    case 22:
        return NtWriteFile;
    case 23:
        return NtSetInformationFile;
    case 24:
        return NtQueryInformationFile;
    case 25:
        return NtQueryDirectoryFile;
    }
}

函数原型:
0:NTSTATUS __stdcall NtCreateKey(PHANDLE KeyHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, ULONG TitleIndex, PUNICODE_STRING Class, ULONG CreateOptions, PULONG Disposition)
1:NTSTATUS __stdcall NtOpenKey(PHANDLE KeyHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes)
2:NTSTATUS __stdcall NtQueryValueKey(HANDLE KeyHandle, PUNICODE_STRING ValueName, KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, PVOID KeyValueInformation, ULONG Length, PULONG ResultLength)
3:NTSTATUS __stdcall NtSetValueKeyEx(HANDLE Handle, PUNICODE_STRING ValueName, ULONG Type, PVOID Data, ULONG DataSize)
和NtSetValueKey的用法类似,只是没有TitleIndex这个参数
4:NTSTATUS __stdcall NtDeleteValueKey(HANDLE KeyHandle, PUNICODE_STRING ValueName)
5:NTSTATUS __stdcall NtDeleteKey(HANDLE KeyHandle)
20:NTSTATUS __stdcall IopCreateFile(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PIO_STATUS_BLOCK IoStatusBlock, PLARGE_INTEGER AllocationSize, ULONG FileAttributes, ULONG ShareAccess, ULONG Disposition, ULONG CreateOptions, PVOID EaBuffer, ULONG EaLength, CREATE_FILE_TYPE CreateFileType, PVOID ExtraCreateParameters, ULONG Options, ULONG InternalFlags, PVOID DeviceObject)
21:NTSTATUS __stdcall NtReadFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer, ULONG Length, PLARGE_INTEGER ByteOffset, PULONG Key)
22:NTSTATUS __stdcall NtWriteFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer, ULONG Length, PLARGE_INTEGER ByteOffset, PULONG Key)
23:NTSTATUS __stdcall NtSetInformationFile(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID FileInformation, ULONG Length, FILE_INFORMATION_CLASS FileInformationClass, BOOL DelCurrentFile)
24:NTSTATUS __stdcall NtQueryInformationFile(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID FileInformation, ULONG Length, FILE_INFORMATION_CLASS FileInformationClass, BOOL DelCurrentFile)
25:NTSTATUS __stdcall NtQueryDirectoryFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, PVOID FileInformation, ULONG Length, FILE_INFORMATION_CLASS FileInformationClass, BOOLEAN ReturnSingleEntry, PUNICODE_STRING FileName, BOOLEAN RestartScan)

2.2 与WRK代码异同点
注册表穿透操作是使用Cm*函数实现Nt*函数,而文件穿透操作则基本和WRK代码一致,Iop*函数最大程度的实现内联。
这些实现中和WRK主要区别在于:去掉了AccessMode=UserMode分支、和ObReferenceObjectByName调用前后重置ObjectInitializer
NtReadFile实现额外处理了IoCallDriver返回文件锁定(STATUS_FILE_LOCK_CONFLICT)的处理,此时通过创建文件映射实现读取

2.3 重置/保存注册表对象ObjectInitialzer例程

enum
{
        EClose,
        EDelete,
        EParse,
        ESecurtiy,
        EQueryName,
        EOpen,
};
  1. BOOLEAN ReplaceObjectinitializer(int Type,FARPROC* OutFunc,BOOLEAN ResetOrRestore)
  2. {
  3.         FARPROC* Initailier = NULL;
  4.         if(Type <0 || Type >= ECmMax)
  5.         {
  6.                 if(!RegObjectInitialzer[Type] || !CmpKeyObjectType || !OutFunc)
  7.                         return 0;
  8.         }
  9.         if(VersionIndex >= WIN2000 && VersionIndex <= WINXPSP3)
  10.         {
  11.                 switch(Type)
  12.                 {
  13.                         case EClose:
  14.                                 Initailier = &((POBJECT_TYPE_XP)CmpKeyObjectType)->TypeInfo.CloseProcedure;
  15.                                 break;
  16.                         case EDelete:
  17.                                 Initailier = &((POBJECT_TYPE_XP)CmpKeyObjectType)->TypeInfo.DeleteProcedure;
  18.                                 break;
  19.                         case EParse:
  20.                                 Initailier = &((POBJECT_TYPE_XP)CmpKeyObjectType)->TypeInfo.ParseProcedure;
  21.                                 break;
  22.                         case ESecurity:
  23.                                 Initailier = &((POBJECT_TYPE_XP)CmpKeyObjectType)->TypeInfo.SecurityProcedure;
  24.                                 break;
  25.                         case EQueryName:
  26.                                 Initailier = &((POBJECT_TYPE_XP)CmpKeyObjectType)->TypeInfo.QueryNameProcedure;
  27.                                 break;
  28.                         case EOpen:
  29.                                 Initailier = &((POBJECT_TYPE_XP)CmpKeyObjectType)->TypeInfo.OpenProcedure;
  30.                                 break;
  31.                 }
  32.         }
  33.         else if(VersionIndex >= WINVISTA && VersionIndex <= WIN10)
  34.         {
  35.                 switch(Type)
  36.                 {
  37.                 case EClose:
  38.                         Initailier = &((POBJECT_TYPE_WIN7)CmpKeyObjectType)->TypeInfo.CloseProcedure;
  39.                         break;
  40.                 case EDelete:
  41.                         Initailier = &((POBJECT_TYPE_WIN7)CmpKeyObjectType)->TypeInfo.DeleteProcedure;
  42.                         break;
  43.                 case EParse:
  44.                         Initailier = &((POBJECT_TYPE_WIN7)CmpKeyObjectType)->TypeInfo.ParseProcedure;
  45.                         break;
  46.                 case ESecurity:
  47.                         Initailier = &((POBJECT_TYPE_WIN7)CmpKeyObjectType)->TypeInfo.SecurityProcedure;
  48.                         break;
  49.                 case EQueryName:
  50.                         Initailier = &((POBJECT_TYPE_WIN7)CmpKeyObjectType)->TypeInfo.QueryNameProcedure;
  51.                         break;
  52.                 case EOpen:
  53.                         Initailier = &((POBJECT_TYPE_WIN7)CmpKeyObjectType)->TypeInfo.OpenProcedure;
  54.                         break;
  55.                 }
  56.         }
  57.         if(ResetOrRestore)
  58.         {//Get
  59.                 if(*Initailier != RegObjectInitialzer[Type])
  60.                 {
  61.                         *OutFunc = *Initailier;
  62.                         *Initailier = RegObjectInitialzer[Type];
  63.                         return TRUE;
  64.                 }
  65.         }
  66.         else
  67.         {//Set
  68.                 if(*OutFunc != *Initailier)
  69.                 {
  70.                         *Initailier = *OutFunc;
  71.                         return TRUE;
  72.                 }
  73.         }
  74.         return FALSE;
  75. }

  76. NtCreateKey
  77. NTSTATUS __stdcall NtCreateKey(PHANDLE KeyHandle,ACCESS_MASK DesiredAccess,POBJECT_ATTRIBUTES ObjectAttributes,
  78.         ULONG TitleIndex,PUNICODE_STRING Class,ULONG CreateOptions,PULONG Disposition)
  79. {
  80.         NTSTATUS            status;
  81.         KPROCESSOR_MODE     mode;
  82.         CM_PARSE_CONTEXT    ParseContext;
  83.         PCM_KEY_BODY        KeyBody = NULL;
  84.         HANDLE              Handle = 0;
  85.         UNICODE_STRING      CapturedObjectName = {0};
  86.         FARPROC                                SavedInitializer = NULL;
  87.         BOOL                                NeedRestore = FALSE;

  88.         RtlZeroMemory(&ParseContext,sizeof(ParseContext));
  89.         if (ARGUMENT_PRESENT(Class))
  90.         {
  91.                 ParseContext.Class = *Class;
  92.         }
  93.         if ((CreateOptions & (REG_LEGAL_OPTION | REG_OPTION_PREDEF_HANDLE)) != CreateOptions)
  94.         {
  95.                 return STATUS_INVALID_PARAMETER;
  96.         }
  97.         ParseContext.TitleIndex = 1;
  98.         ParseContext.CreateOptions = CreateOptions;
  99.         ParseContext.Disposition = 0L;
  100.         ParseContext.CreateLink = FALSE;
  101.         ParseContext.PredefinedHandle = NULL;
  102.         ParseContext.CreateOperation = TRUE;
  103.         ParseContext.OriginatingPoint = NULL;
  104.         if(ReplaceObjectinitializer(EParse,&SavedInitializer,1))//还原为系统默认值
  105.                 NeedRestore = TRUE;
  106.         status = ObOpenObjectByName(ObjectAttributes,CmpKeyObjectType,mode,NULL,DesiredAccess,(PVOID)&ParseContext,&Handle);
  107.         if(NeedRestore)
  108.                 ReplaceObjectinitializer(EParse,&SavedInitializer,0);
  109.         if (status==STATUS_PREDEFINED_HANDLE)
  110.         {
  111.                 if(VersionIndex < WINVISTA)
  112.                 {
  113.                         status = ObReferenceObjectByHandle(Handle,0,CmpKeyObjectType,KernelMode,(PVOID *)(&KeyBody),NULL);
  114.                         if (NT_SUCCESS(status))
  115.                         {
  116.                                 HANDLE TempHandle;
  117.                                 TempHandle = (HANDLE)LongToHandle(KeyBody->Type);
  118.                                 ObDereferenceObject(KeyBody);
  119.                                 ZwClose(Handle);
  120.                                 *KeyHandle = TempHandle;
  121.                                 status = STATUS_SUCCESS;
  122.                         }
  123.                 }
  124.                 else
  125.                 {
  126.                         TempHandle = (HANDLE)LongToHandle(KeyBody->Type);
  127.                         ObDereferenceObject((PVOID)KeyBody);
  128.                         NtClose(Handle);
  129.                         *KeyHandle = ParseContext.OriginatingPoint;
  130.                         status = STATUS_SUCCESS;
  131.                 }
  132.         }
  133.         if (ARGUMENT_PRESENT(Disposition))
  134.         {
  135.                 *Disposition = ParseContext.Disposition;
  136.         }
  137.         return status;
  138. }


  139. NtOpenKey
  140. NTSTATUS __stdcall NtOpenKey(PHANDLE KeyHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes)
  141. {
  142.         CM_PARSE_CONTEXT        ParseContext;
  143.         PVOID                                Context;
  144.         HANDLE                                Handle =0;
  145.         NTSTATUS                        status = STATUS_SUCCESS;
  146.         PCM_KEY_BODY                KeyBody;
  147.         FARPROC                                SavedInitializer = NULL;
  148.         BOOL                                NeedRestore = FALSE;
  149.         RtlZeroMemory(&ParseContext,sizeof(CM_PARSE_CONTEXT));
  150.         Context = VersionIndex!=WIN2000?&ParseContext:NULL;
  151.         ParseContext.CreateOperation = FALSE;
  152.         if(ReplaceObjectinitializer(EParse,&SavedInitializer,1))//还原为系统默认值
  153.                 NeedRestore = TRUE;
  154.         status = ObOpenObjectByName(ObjectAttributes,CmpKeyObjectType,KernelMode,NULL,DesiredAccess,(PVOID)&Context,&Handle);
  155.         if(NeedRestore)
  156.                 ReplaceObjectinitializer(EParse,&SavedInitializer,0);
  157.         if (status==STATUS_PREDEFINED_HANDLE)
  158.         {
  159.                 status = ObReferenceObjectByHandle(Handle,0,CmpKeyObjectType,KernelMode,(PVOID *)(&KeyBody),NULL);
  160.                 if (NT_SUCCESS(status))
  161.                 {
  162.                         *KeyHandle = (HANDLE)LongToHandle(KeyBody->Type);
  163.                         ObDereferenceObject((PVOID)KeyBody);
  164.                         if(*KeyHandle)
  165.                         {
  166.                                 status = STATUS_SUCCESS;
  167.                         }
  168.                         else
  169.                         {
  170.                                 status = STATUS_OBJECT_NAME_NOT_FOUND;
  171.                         }
  172.                 }
  173.                 ZwClose(Handle);
  174.         }
  175.         else if (NT_SUCCESS(status))
  176.         {
  177.                 *KeyHandle = Handle;
  178.         }
  179.         return status;
  180. }

  181. NtQueryValueKey
  182. NTSTATUS __stdcall NtQueryValueKey(HANDLE KeyHandle,PUNICODE_STRING ValueName,KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
  183.     PVOID KeyValueInformation,ULONG Length,PULONG ResultLength)
  184. {
  185.     NTSTATUS    status;
  186.     PCM_KEY_BODY   KeyBody = NULL;
  187.     KPROCESSOR_MODE mode;
  188.         UNICODE_STRING LocalValueName = {0};
  189.     if(!ValueName || (KeyValueInformationClass != KeyValueBasicInformation && KeyValueInformationClass != KeyValueFullInformation
  190.                 && KeyValueInformationClass != KeyValuePartialInformation && KeyValueInformationClass != KeyValueFullInformationAlign64 &&
  191.                 KeyValueInformationClass != KeyValuePartialInformationAlign64))
  192.                 return STATUS_INVALID_PARAMETER;
  193.         if(CmMatchData[VersionIndex][ECmQueryValueKey].InitFlag && CmMatchData[VersionIndex][ECmQueryValueKey].FuncAddr)
  194.         {
  195.                 mode = KeGetPreviousMode();
  196.                 status = ObReferenceObjectByHandle(KeyHandle,KEY_QUERY_VALUE,CmpKeyObjectType,mode,(PVOID *)(&KeyBody),NULL);
  197.                 LocalValueName = *ValueName;
  198.                 if (NT_SUCCESS(status))
  199.                 {
  200.                         switch(VersionIndex)
  201.                         {
  202.                         case WIN2000:
  203.                         case WINXP:
  204.                         case WINXPSP3:
  205.                                 CmMatchData[VersionIndex][ECmQueryValueKey].FuncAddr(KeyBody->KeyControlBlock,LocalValueName,
  206.                                         KeyValueInformationClass,KeyValueInformation,Length,ResultLength);
  207.                                 break;
  208.                         case WINVISTA:
  209.                         case WIN7:
  210.                         case WIN7_1:
  211.                                 CmMatchData[VersionIndex][ECmQueryValueKey].FuncAddr(KeyBody,KeyValueInformationClass,KeyValueInformation
  212.                                         Length,ResultLength,LocalValueName);
  213.                                 break;
  214.                         case WIN8:
  215.                                 CmMatchData[VersionIndex][ECmQueryValueKey].FuncAddr(KeyBody,LocalValueName,KeyValueInformationClass,
  216.                                         KeyValueInformation,Length,ResultLength);
  217.                                 break;
  218.                         case WIN8_1:
  219.                         case WIN10:
  220.                                 CmMatchData[VersionIndex][ECmQueryValueKey].FuncAddr(KeyBody,KeyValueInformationClass,KeyValueInformation,
  221.                                         Length,ResultLength,LocalValueName);
  222.                                 break;
  223.                         default:
  224.                                 status = STATUS_NOT_SUPPORTED;
  225.                                 break;
  226.                         }
  227.                 }
  228.         }
  229.         else
  230.         {
  231.                 status = STATUS_NOT_SUPPORTED;
  232.         }
  233.         if(KeyBody)
  234.                 ObDereferenceObject(KeyBody);
  235.         return status;
  236. }

  237. NtSetValueKeyEx
  238. NTSTATUS __stdcall NtSetValueKeyEx(HANDLE KeyHandle,PUNICODE_STRING ValueName,ULONG Type,PVOID Data,ULONG DataSize)
  239. {
  240.         NTSTATUS    status;
  241.         PCM_KEY_BODY   KeyBody = NULL;
  242.         KPROCESSOR_MODE mode;
  243.         UNICODE_STRING LocalValueName = {0};
  244.         PWSTR CapturedName=NULL;
  245.         OBJECT_HANDLE_INFORMATION HandleInformation = {0};
  246.         if(CmMatchData[VersionIndex][ECmQueryValueKey].InitFlag && CmMatchData[VersionIndex][ECmQueryValueKey].FuncAddr)
  247.         {
  248.                 mode = KeGetPreviousMode();
  249.                 status = ObReferenceObjectByHandle(KeyHandle,KEY_SET_VALUE,CmpKeyObjectType,mode,(PVOID *)(&KeyBody),&HandleInformation);
  250.                 LocalValueName = *ValueName;
  251.                 if (NT_SUCCESS(status))
  252.                 {
  253.                         switch(VersionIndex)
  254.                         {
  255.                                 switch(VersionIndex)
  256.                                 {
  257.                                 case WIN2000:
  258.                                 case WINXP:
  259.                                 case WINXPSP3:
  260.                                         CmMatchData[VersionIndex][ECmSetValueKey].FuncAddr(KeyBody->KeyControlBlock,&LocalValueName,Type,Data,DataSize);
  261.                                         break;
  262.                                 case WINVISTA:
  263.                                 case WIN7:
  264.                                 case WIN7_1:
  265.                                 case WIN8:
  266.                                 case WIN8_1:
  267.                                         CmMatchData[VersionIndex][ECmSetValueKey].FuncAddr(KeyBody,&LocalValueName,Type,Data,DataSize,0,
  268.                                                 HandleInformation.HandleAttributes & 4);
  269.                                         break;
  270.                                 case WIN10:
  271.                                         CmMatchData[VersionIndex][ECmSetValueKey].FuncAddr(KeyBody,&LocalValueName,Type,Data,DataSize,0,
  272.                                                 HandleInformation.HandleAttributes & 4);
  273.                                         break;
  274.                                 default:
  275.                                         status = STATUS_NOT_SUPPORTED;
  276.                                         break;
  277.                         }
  278.                 }
  279.         }
  280.         else
  281.         {
  282.                 status = STATUS_NOT_SUPPORTED;
  283.         }
  284.         if(KeyBody)
  285.                 ObDereferenceObject(KeyBody);
  286.         return status;
  287. }

  288. NtDeleteValueKey
  289. NTSTATUS __stdcall NtDeleteValueKey(HANDLE KeyHandle,PUNICODE_STRING ValueName)
  290. {
  291.         NTSTATUS    status;
  292.         PCM_KEY_BODY   KeyBody = NULL;
  293.         KPROCESSOR_MODE mode;
  294.         UNICODE_STRING LocalValueName = {0};
  295.         PWSTR CapturedName=NULL;
  296.         OBJECT_HANDLE_INFORMATION HandleInformation = {0};
  297.         if(CmMatchData[VersionIndex][ECmDeleteValueKey].InitFlag && CmMatchData[VersionIndex][ECmDeleteValueKey].FuncAddr)
  298.         {
  299.                 mode = KeGetPreviousMode();
  300.                 status = ObReferenceObjectByHandle(KeyHandle,KEY_SET_VALUE,CmpKeyObjectType,mode,(PVOID *)(&KeyBody),&HandleInformation);
  301.                 LocalValueName = *ValueName;
  302.                 if (NT_SUCCESS(status))
  303.                 {
  304.                         switch(VersionIndex)
  305.                         {
  306.                                 case WIN2000:
  307.                                 case WINXP:
  308.                                 case WINXPSP3:
  309.                                         CmMatchData[VersionIndex][ECmDeleteValueKey].FuncAddr(KeyBody->KeyControlBlock,LocalValueName);
  310.                                         break;
  311.                                 case WINVISTA:
  312.                                 case WIN7:
  313.                                 case WIN7_1:
  314.                                         CmMatchData[VersionIndex][ECmDeleteValueKey].FuncAddr(KeyBody,KeyHandle,HandleInformation.HandleAttributes & 4,LocalValueName);
  315.                                         break;
  316.                                 case WIN8:
  317.                                         CmMatchData[VersionIndex][ECmDeleteValueKey].FuncAddr(KeyBody,LocalValueName,KeyHandle,HandleInformation.HandleAttributes & 4);
  318.                                         break;
  319.                                 case WIN8_1:
  320.                                 case WIN10:
  321.                                         CmMatchData[VersionIndex][ECmDeleteValueKey].FuncAddr(KeyBody,&LocalValueName,Type,Data,DataSize,0,
  322.                                                 HandleInformation.HandleAttributes & 4);
  323.                                         break;
  324.                                 default:
  325.                                         status = STATUS_NOT_SUPPORTED;
  326.                                         break;
  327.                         }
  328.                 }
  329.         }
  330.         else
  331.         {
  332.                 status = STATUS_NOT_SUPPORTED;
  333.         }
  334.         if(KeyBody)
  335.                 ObDereferenceObject(KeyBody);
  336.         return status;
  337. }

  338. NtDeleteKey
  339. NTSTATUS __stdcall NtDeleteKey(HANDLE KeyHandle)
  340. {
  341.         NTSTATUS    status;
  342.         PCM_KEY_BODY   KeyBody = NULL;
  343.         KPROCESSOR_MODE mode;
  344.         UNICODE_STRING LocalValueName = {0};
  345.         PWSTR CapturedName=NULL;
  346.         OBJECT_HANDLE_INFORMATION HandleInformation = {0};
  347.         if(CmMatchData[VersionIndex][ECmDeleteKey].InitFlag && CmMatchData[VersionIndex][ECmDeleteKey].FuncAddr)
  348.         {
  349.                 mode = KeGetPreviousMode();
  350.                 status = ObReferenceObjectByHandle(KeyHandle,KEY_SET_VALUE,CmpKeyObjectType,mode,(PVOID *)(&KeyBody),&HandleInformation);
  351.                 LocalValueName = *ValueName;
  352.                 if (NT_SUCCESS(status))
  353.                 {
  354.                         switch(VersionIndex)
  355.                         {
  356.                         case WIN2000:
  357.                         case WINXP:
  358.                         case WINXPSP3:
  359.                         case WINVISTA:
  360.                         case WIN7:
  361.                         case WIN7_1:
  362.                         case WIN8:
  363.                         case WIN8_1:
  364.                         case WIN10:
  365.                                 CmMatchData[VersionIndex][ECmDeleteKey].FuncAddr(KeyBody);
  366.                                 break;
  367.                         default:
  368.                                 status = STATUS_NOT_SUPPORTED;
  369.                                 break;
  370.                         }
  371.                 }
  372.         }
  373.         else
  374.         {
  375.                 status = STATUS_NOT_SUPPORTED;
  376.         }
  377.         if(KeyBody)
  378.                 ObDereferenceObject(KeyBody);
  379.         return status;
  380. }
复制代码

IopCreateFile

代码基本和WRK一致,区别在于2点:
OPEN_PACKET结构不同  
ObOpenObjectByName调用之前会将IoFileObjectType的ObjectInitailier重置为系统初始值


// WIN2000
// WINXP
// WINXPSP3
#pragma pack(push)
#pragma pack(8)
typedef struct _OPEN_PACKET_XP
{
        CSHORT Type;
        CSHORT Size;
        PFILE_OBJECT FileObject;
        NTSTATUS FinalStatus;
        ULONG_PTR Information;
        ULONG ParseCheck;
        PFILE_OBJECT RelatedFileObject;
        LARGE_INTEGER AllocationSize;
        ULONG CreateOptions;
        USHORT FileAttributes;
        USHORT ShareAccess;
        PVOID EaBuffer;
        ULONG EaLength;
        ULONG Options;
        ULONG Disposition;
        PFILE_BASIC_INFORMATION BasicInformation;
        PFILE_NETWORK_OPEN_INFORMATION NetworkInformation;
        CREATE_FILE_TYPE CreateFileType;
        PVOID ExtraCreateParameters;
        BOOLEAN Override;
        BOOLEAN QueryOnly;
        BOOLEAN DeleteOnly;
        BOOLEAN FullAttributes;
        PDUMMY_FILE_OBJECT LocalFileObject;
        BOOLEAN TraversedMountPoint;
        ULONG           InternalFlags;
        PDEVICE_OBJECT  TopDeviceObjectHint;
} OPEN_PACKET_XP, *POPEN_PACKET_XP;
#pragma pack(pop)

// WINVISTA
// WIN7
// WIN7_1
#pragma pack(push)
#pragma pack(8)
typedef struct _OPEN_PACKET_WIN7
{
        CSHORT Type;
        CSHORT Size;
        PFILE_OBJECT FileObject;
        NTSTATUS FinalStatus;
        ULONG_PTR Information;
        ULONG ParseCheck;
        PFILE_OBJECT RelatedFileObject;
        POBJECT_ATTRIBUTES OriginalAttributes;
        LARGE_INTEGER AllocationSize;
        ULONG CreateOptions;
        USHORT FileAttributes;
        USHORT ShareAccess;
        PVOID EaBuffer;
        ULONG EaLength;
        ULONG Options;
        ULONG Disposition;
        PFILE_BASIC_INFORMATION BasicInformation;
        PFILE_NETWORK_OPEN_INFORMATION NetworkInformation;
        CREATE_FILE_TYPE CreateFileType;
        PVOID MailslotOrPipeParameters;
        BOOLEAN Override;
        BOOLEAN QueryOnly;
        BOOLEAN DeleteOnly;
        BOOLEAN FullAttributes;
        PDUMMY_FILE_OBJECT LocalFileObject;
        ULONG           InternalFlags;
        IO_DRIVER_CREATE_CONTEXT  DriverCreateContext;
} OPEN_PACKET_WIN7, *POPEN_PACKET_WIN7;
#pragma pack(pop)
// WIN8
// WIN8_1
// WIN10
#pragma pack(push)
#pragma pack(8)
typedef struct _OPEN_PACKET_WIN8
{
        CSHORT Type;
        CSHORT Size;
        PFILE_OBJECT FileObject;
        NTSTATUS FinalStatus;
        ULONG_PTR Information;
        ULONG ParseCheck;
        union
        {
                PFILE_OBJECT RelatedFileObject;
                PDEVICE_OBJECT ReferencedDeviceObject;
        };
        POBJECT_ATTRIBUTES OriginalAttributes;
        LARGE_INTEGER AllocationSize;
        ULONG CreateOptions;
        USHORT FileAttributes;
        USHORT ShareAccess;
        PVOID EaBuffer;
        ULONG EaLength;
        ULONG Options;
        ULONG Disposition;
        PFILE_BASIC_INFORMATION BasicInformation;
        PFILE_NETWORK_OPEN_INFORMATION NetworkInformation;
        CREATE_FILE_TYPE CreateFileType;
        PVOID MailslotOrPipeParameters;
        BOOLEAN Override;
        BOOLEAN QueryOnly;
        BOOLEAN DeleteOnly;
        BOOLEAN FullAttributes;
        PDUMMY_FILE_OBJECT LocalFileObject;
        ULONG           InternalFlags;
        KPROCESSOR_MODE AccessMode;
        IO_DRIVER_CREATE_CONTEXT  DriverCreateContext;
} OPEN_PACKET_WIN8, *POPEN_PACKET_WIN8;
#pragma pack(pop)

回复

使用道具 举报

 楼主| 发表于 2015-9-27 13:15:36 | 显示全部楼层
附件包含完整文档及idb文件,密码为我的qq

TsSysKit.rar

521.53 KB, 下载次数: 72

回复 赞! 1 靠! 0

使用道具 举报

 楼主| 发表于 2015-9-21 08:46:04 | 显示全部楼层
本帖最后由 元始天尊 于 2015-9-27 13:10 编辑

三、        控制码
        IRP_MJ_DEVICE_CONTROL        =>        调用DeviceIoControl派遣(DeviceIoControlDispatch)
能力:
解锁文件
驱动加载
句柄操作
进程打开、结束
注册表穿透操作

TSSysKit    IoControlCode对应表:
0x221C00
    解锁文件
    buffer=     sizeof=0x804
    +00 NTSTATUS status     out
    +04 WCHAR FileName[1024]    in
0x221C04
0x221C08
0x221C0C
0x221C10
0x221C14
    尚未实现
0x222004
    普通结束进程
    buffer=     sizeof=4
    +00 DWORD ProcessId
0x222008
    穿透NtDeleteKey
    buffer=     sizeof=8
    +00 NTSTATUS status     out
    +04 HANDLE  KeyHandle   in
0x22200C
    穿透NtDeleteValueKey        成员含义见NtDeleteValueKey
    buffer=     sizeof=0xC
    +00 NTSTATUS status     out
    +04 HANDLE  KeyHandle   in
    +08 PUNICODE_STRING ValueName   in
0x222010
    通过进程id或进程对象名(只能选一)穿透打开进程NtOpenProcess   成员含义见NtOpenProcess
    buffer=     sizeof=0x18
    +00 NTSTATUS status     out
    +04 HANDLE ProcessHandle    out
    +08 ACCESS_MASK DesiredAccess in
    +0C POBJECT_ATTRIBUTES ObjectAttributes in
    +10 PCLIENT_ID ClientId
0x222404
    普通关闭句柄NtClose
    buffer=     sizeof=8
    +00 NTSTATUS status     out
    +04 HANDLE Handle   in
0x222408
    穿透创建注册表项NtCreateKey         成员含义见NtCreateKey
    buffer=     sizeof=0x20
    +00 HANDLE  KeyHandle   out
    +04 NTSTATUS status     out     注意status不是第一成员了!!
    +08 ULONG Disposition   out
    +0C ACCESS_MASK DesiredAccess   in
    +10 POBJECT_ATTRIBUTES ObjectAttributes in
    +14 ULONG TitleIndex    in
    +18 PUNICODE_STRING Class   in
    +1C ULONG CreateOptions in
0x22240C
    穿透打开注册表项NtOpenKey           成员含义见NtOpenKey
    buffer=     sizeof=0x10
    +00 HANDLE  KeyHandle   out
    +04 NTSTATUS status     out     注意status不是第一成员了!!
    +08 ACCESS_MASK DesiredAccess   in
    +0C POBJECT_ATTRIBUTES ObjectAttributes in
0x222410
    同0x222008  NtDeleteKey
0x222414
    同0x222008  NtDeleteValueKey
0x222418
    穿透设置注册表项NtSetValueKeyEx     成员含义见NtSetValueKey
    buffer=     sizeof=0x1C
    +00 NTSTATUS status     out
    +04 HANDLE  KeyHandle   in
    +08 PUNICODE_STRING ValueName        in
    +0C ULONG TitleIndex        未使用
    +10 ULONG   Type        in
    +14 PVOID   Data        in
    +18 ULONG   DataSize        in
0x22241C
    穿透设置注册表项NtQueryValueKey     成员含义见NtQueryValueKey
    buffer=     sizeof=0x1C
    +00 DWORD ResultLength  out
    +04 NTSTATUS status     out     注意status不是第一成员了!!
    +08 HANDLE  KeyHandle   in
    +0C PUNICODE_STRING ValueName
    +10 ULONG Type          out     KeyValueInformation->DataLength
    +14 PVOID Data          out     KeyValueInformation->Data
    +18 ULONG DataLength    out     KeyValueInformation->DataLength
0x222420
    穿透枚举注册表项NtEnumerateKey      成员含义见NtEnumerateKey
    buffer=     sizeof=0x1C
    +00 NTSTATUS status     out
    +04 DWORD ResultLength  out
    +08 HANDLE KeyHandle        in
    +0C ULONG Index             in
    +10 KEY_INFORMATION_CLASS KeyInformationClass   in
    +14 PVOID KeyInformation    in
    +18 ULONG Length
0x222424
    NtEnumerateValueKey     成员含义见NtEnumerateValueKey
    buffer=
    +00 NTSTATUS status     out
    +04 ULONG ResultLength  out
    +08 HANDLE KeyHandle    in
    +0C ULONG Index     in
    +10 KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass    in
    +14 PVOID KeyValueInformation   out
    +18 ULONG Length    in
0x222428
    TsSysKit驱动是否初始化
    *(DWORD*)buffer => SomeFlag
    *(DWORD*)buffer <= IsTsSysKitInit
0x22242C
    穿透创建服务加载驱动
    buffer=     sizeof=0x91C
    +000    WCHAR ImagePath[260] 驱动文件路径
    +208    DWORD Type  驱动注册表Type项
    +20C    DWORD Start 驱动注册表项Start类型
    +210    DWORD flag  (决定是否设置注册表Tag和Group信息)
    +214    ???
    +468    DWORD Tag 驱动注册表Tag项
    +46C    WCHAR DisplayName[300] 驱动注册表项DisplayName
    +6C4    WCHAR ServiceName[300] 驱动服务名
0x222430
    获取操作系统版本
    buffer=RTL_OSVERSIONINFOEXW     sizeof=0x11C
0x222800
0x222804
    2个初始化TSSysKit的通道
0x224008
        更新Q管目录
+00        DWORD Tag=0x20120502
        +04        DWORD =0
0x22400C
        穿透创建文件
        Buffer=        sizeof=0x30        具体参数含义见NtCreateFile
+00        NTSTATUS status     out
        +04        PHANDLE FileHandle
        +08        ACCESS_MASK DesiredAccess
        +0C        POBJECT_ATTRIBUTES ObjectAttributes
        +10        PIO_STATUS_BLOCK IoStatusBloc
        +14        PLARGE_INTEGER AllocationSize
        +18        ULONG FileAttributes
        +1C        ULONG ShareAccess
        +20        ULONG CreateDisposition
        +24        ULONG CreateOptions
        +28        PVOID EaBuffer
        +2C        ULONG EaLength
0x224010
        穿透打开文件
Buffer=        sizeof=0x1C         具体参数含义见NtOpenFile
+00        NTSTATUS status     out
+04        PHANDLE FileHandle
+08        PHANDLE FileHandle
+0C        POBJECT_ATTRIBUTES ObjectAttributes
+10        PIO_STATUS_BLOCK IoStatusBlock
+14        ULONG ShareAccess
+18        ULONG OpenOptions
0x224014
穿透读取文件
Buffer=        sizeof=0x28                具体参数含义见NtReadFile
+00        NTSTATUS status     out
+04        HANDLE FileHandle        in
+08        HANDLE Event                in
+0C        ApcRoutine                in
+10        ApcContext                in
+14        PIO_STATUS_BLOCK IoStatusBlock        in
+18        PVOID Buffer                out
+1C        ULONG Length                in
+20        PLARGE_INTEGER ByteOffset       
+24        PULONG Key
0x224018
穿透写入文件
Buffer=        sizeof=0x28                具体参数含义见NtWriteFile
+00        NTSTATUS status     out
+04        HANDLE FileHandle        in
+08        HANDLE Event                in
+0C        ApcRoutine                in
+10        ApcContext                in
+14        PIO_STATUS_BLOCK IoStatusBlock        in
+18        PVOID Buffer                out
+1C        ULONG Length                in
+20        PLARGE_INTEGER ByteOffset       
+24        PULONG Key
0x22401C
    普通关闭句柄NtClose
    buffer=     sizeof=8
    +00 NTSTATUS status     out
    +04 HANDLE Handle   in
0x224020
        穿透设置文件
        Buffer=        sizeof=0x1C       具体参数含义见NtSetInformationFile
        +00        NTSTATUS status;
        +04        HANDLE FileHandle                        in
        +08        PIO_STATUS_BLOCK IoStatus                out       
        +0C        PVOID FileInformation                in
        +10        ULONG Length                        in
        +14        FILE_INFORMATION_CLASS FileInformationClass        in
        +18        BOOL DelCurrentFile                in
0x224024
        穿透查询文件
        Buffer=        sizeof=0x1C       具体参数含义见NtQueryInformationFile
        +00        NTSTATUS status                                out
        +04        HANDLE FileHandle                        in
        +08        PIO_STATUS_BLOCK IoStatus                out       
        +0C        PVOID FileInformation                in
        +10        ULONG Length                        in
        +14        FILE_INFORMATION_CLASS FileInformationClass        in
        +18        BOOL DelCurrentFile                in
0x224028
尚未实现
0x22402C
        穿透查询目录
        Buffer=        sizeof=0x30        具体参数含义见NtQueryDirectoryFile
        +00        NTSTATUS status                out
        +04        HANDLE FileHandle        in
        +08        HANDLE Event                in
        +0C         PIO_APC_ROUTINE ApcRoutine        未使用
        +10        PVOID ApcContext        未使用
        +14         PIO_STATUS_BLOCK IoStatus                out
        +18        PVOID FileInformation        in
        +1C        ULONG Length                in
        +20        FILE_INFORMATION_CLASS FileInformationClass        in
        +24        BOOLEAN ReturnSingleEntry                in
        +28        PUNICODE_STRING FileName        in
        +2C        BOOLEAN RestartScan        in
0x228404
        穿透查询文件属性
        Buffer=        sizeof=0xC                具体参数含义见NtQueryAttributesFile
                        +0        NTSTATUS status                out
                        +4        POBJECT_ATTRIBUTES ObjectAttributes                in                        路径前缀匹配\??\c:
+8        FILE_NETWORK_OPEN_INFORMATION networkInformation        out

0x221C00解锁文件
见3.13 解锁文件

0x222004普通结束进程
  1. BOOLEAN TerminateProcessById(HANDLE ProcessId)
  2. {
  3.         BOOLEAN Result = FALSE;
  4.         PEPROCESS Process = NULL;
  5.         HANDLE ProcessHandle = NULL;
  6.         if(NT_SUCCESS(PsLookupProcessByProcessId(ProcessId,&Process)) &&
  7.                 NT_SUCCESS(ObOpenObjectByPointer(Process,0,NULL,PROCESS_ALL_ACCESS,NULL,KernelMode,&ProcessHandle)) &&
  8.                 NT_SUCCESS(ZwTerminateProcess(ProcessHandle,0)))
  9.         {
  10.                 Result = TRUE;
  11.         }
  12.         if(Process)
  13.         {
  14.                 ObDereferenceObject(Process);
  15.                 Process = NULL;
  16.         }
  17.         if(ProcessHandle)
  18.                 ZwClose(ProcessHandle);
  19.         return Result;
  20. }

复制代码

0x22242C穿透创建服务加载驱动

struct LOADDRIVERSTRUCT
{
        WCHAR ImagePath[260]; //驱动文件路径
        DWORD Type;  //驱动注册表Type项
        DWORD Start; //驱动注册表项Start类型
        WCHAR Group[300];//驱动注册表Group名
        DWORD Tag; //驱动注册表Tag项
        WCHAR DisplayName[300]; //驱动注册表项DisplayName
        WCHAR ServiceName[300]; //驱动服务名
};

#define MakeUnicodeString(X) {sizeof(X),sizeof(X)+2,X}
UNICODE_STRING UImagePath=MakeUnicodeString(L"ImagePath");
UNICODE_STRING UType=MakeUnicodeString(L"Type");
UNICODE_STRING UStart=MakeUnicodeString(L"Start");
UNICODE_STRING UGroup=MakeUnicodeString(L"Group");
UNICODE_STRING UDisplayName=MakeUnicodeString(L"DisplayName");
UNICODE_STRING UErrorControl=MakeUnicodeString(L"ErrorControl");
UNICODE_STRING UTag=MakeUnicodeString(L"Tag");
UNICODE_STRING UZwLoadDriver=MakeUnicodeString(L"ZwLoadDriver");

struct LOADDRIVERPARAM
{
        WORK_QUEUE_ITEM WorkItem;
        KEVENT Event;
        ULONG mem1;
        PUNICODE_STRING DriverServiceName;
        NTSTATUS Status;
};

  1. void LoadDriverWorker(LOADDRIVERPARAM* WorkItem)
  2. {
  3.         NTSTATUS status = STATUS_UNSUCCESSFUL,outstatus;
  4.         HANDLE KeyHandle = NULL;
  5.         OBJECT_ATTRIBUTES Oa;
  6.         if(WorkItem)
  7.         {
  8.                 InitializeObjectAttributes(&Oa,WorkItem->DriverServiceName,OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE,NULL,NULL);
  9.                 status = NtOpenKey(&KeyHandle,KEY_READ,&Oa);//穿透
  10.                 if(NT_SUCCESS(status))
  11.                 {//xp win7的IopLoadDriver 为不同的调用方式
  12.                         if(VersionInfo < WINVISTA)
  13.                         {//NTSTATUS __stdcall IopLoadDriver(HANDLE KeyHandle, BOOLEAN CheckForSafeBoot, BOOLEAN IsFilter, NTSTATUS *DriverEntryStatus)
  14.                                 IopLoadDriver(KeyHandle,HANDLE_FLAG_INHERIT,FALSE,&outstatus);
  15.                                 if(status == STATUS_FAILED_DRIVER_ENTRY)
  16.                                         status = outstatus;
  17.                                 else if(status == STATUS_DRIVER_FAILED_PRIOR_UNLOAD)
  18.                                         status = STATUS_OBJECT_NAME_NOT_FOUND;
  19.                         }
  20.                         else
  21.                         {//NTSTATUS __userpurge IopLoadDriver<eax>(HANDLE KeyHandle<ecx>, BOOLEAN CheckForSafeBoot, BOOLEAN IsFilter, NTSTATUS *DriverEntryStatus)  第一参用ecx传值

  22.                                 status = IopLoadDriver(KeyHandle,HANDLE_FLAG_INHERIT,FALSE,&outstatus);////事先获取的函数指针,见1.1
  23.                         }
  24.                 }
  25.         }
  26.         WorkItem->Status = status;
  27.         KeSetEvent(WorkItem->Event,0,FALSE);
  28. }

  29. NTSTATUS LoadDriverEx(PUNICODE_STRING DriverServiceName)
  30. {
  31.         NTSTATUS status = STATUS_UNSUCCESSFUL;
  32.         LOADDRIVERPARAM LoadDriver;
  33.         if(IopLoadDriver)//事先获取的函数指针,见1.1
  34.         {
  35.                 LoadDriver.DriverServiceName = DriverServiceName;
  36.                 LoadDriver.mem1 = 0;
  37.                 KeInitializeEvent(&LoadDriver.Event,NotificationEvent,FALSE);
  38.                 ExInitializeWorkItem(&LoadDriver,LoadDriverWorker,&LoadDriver);
  39.                 ExQueueWorkItem(&LoadDriver.WorkItem,DelayedWorkQueue);
  40.                 KeWaitForSingleObject(&LoadDriver.Event,UserRequest,KernelMode,FALSE,NULL);
  41.                 return LoadDriver.Status;
  42.         }
  43.         else
  44.         {
  45.                 FARPROC ZwLoadDriver = MmGetSystemRoutineAddress(&UZwLoadDriver);
  46.                 if(ZwLoadDriver)
  47.                         return ZwLoadDriver(DriverServiceName);
  48.         }
  49.         return status;
  50. }

  51. NTSTATUS CreateServiceAndLoadDriver(DWORD InLen,LOADDRIVERSTRUCT* Data)
  52. {//InLen = IrpSp->Parameters.DeviceIoControl.InputBufferLength
  53.         NTSTATUS status = STATUS_UNSUCCESSFUL;
  54.         UNICODE_STRING DriverServicePath;
  55.         UNICODE_STRING ServiceName;
  56.         OBJECT_ATTRIBUTES Oa;
  57.         WCHAR* Buf = NULL;
  58.         HANDLE KeyHandle = NULL;
  59.         const int BufLen = 520;
  60.         ULONG ErrorControl = SERVICE_ERROR_NORMAL;
  61.         ULONG Disposition = REG_OPENED_EXISTING_KEY;
  62.         if(!SeSinglePrivilegeCheck(SE_LOAD_DRIVER_PRIVILEGE,UserMode))
  63.                 return STATUS_PRIVILEGE_NOT_HELD;
  64.         if(VersionInfo < WINXP)
  65.                 return STATUS_NOT_SUPPORTED;
  66.         if((Data->Type & SERVICE_DRIVER) && Data->ServiceName && Data->ImagePath && Data->DisplayName)
  67.         {
  68.                 RtlInitUnicodeString(&ServiceName,Data->ServiceName);
  69.                 Buf = (WCHAR*)ExAllocatePool(NonPagedPool,BufLen);
  70.                 RtlZeroMemory(Buf,BufLen);
  71.                 wcscpy(Buf,L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\");
  72.                 DriverServicePath.Length = 2*wcslen(Buf);
  73.                 DriverServicePath.MaximumLength = BufLen;
  74.                 DriverServicePath.Buffer = Buf;
  75.                 status = RtlAppendUnicodeStringToString(&DriverServicePath, &ServiceName);
  76.                 if(NT_SUCCESS(status))
  77.                 {
  78.                         InitializeObjectAttributes(&Oa,&DriverServicePath,OBJ_CASE_INSENSITIVE,NULL,NULL);
  79.                         status = ZwCreateKey(&KeyHandle,KEY_READ|KEY_SET_VALUE, &Oa, 0,NULL, 0, &Disposition);//穿透
  80.                 }
  81.                 if(NT_SUCCESS(status))
  82.                 {
  83.                         status = ZwSetValueKeyEx(KeyHandle,&UImagePath,REG_SZ,Data->ImagePath,2*wcslen(Data->ImagePath)+2);//穿透
  84.                 }
  85.                 if(NT_SUCCESS(status))
  86.                 {
  87.                         status = ZwSetValueKeyEx(KeyHandle,&UType,REG_DWORD,Data->Type,sizeof(DWORD));
  88.                 }
  89.                 if(NT_SUCCESS(status))
  90.                 {
  91.                         status = ZwSetValueKeyEx(KeyHandle,&UStart,REG_DWORD,Data->Start,sizeof(DWORD));
  92.                 }
  93.                 if(NT_SUCCESS(status))
  94.                 {
  95.                         status = ZwSetValueKeyEx(KeyHandle,&UDisplayName,REG_SZ,Data->DisplayName,2*wcslen(Data->DisplayName)+2);
  96.                 }
  97.                 if(NT_SUCCESS(status))
  98.                 {//此处q管源码有bug
  99.                         status = ZwSetValueKeyEx(KeyHandle,&UGroup,REG_SZ,Data->Group,2*wcslen(Data->Group)+2);
  100.                 }
  101.                 if(NT_SUCCESS(status))
  102.                 {
  103.                         status = ZwSetValueKeyEx(KeyHandle,&UTag,REG_DWORD,Data->Tag,sizeof(DWORD));
  104.                 }
  105.                 if(NT_SUCCESS(status))
  106.                 {
  107.                         status = ZwSetValueKeyEx(KeyHandle,&UErrorControl,REG_DWORD,ErrorControl,sizeof(DWORD));
  108.                 }
  109.                 if(NT_SUCCESS(status))
  110.                 {
  111.                         ZwFlushKey(KeyHandle);
  112.                         status = LoadDriverEx(&DriverServicePath);
  113.                 }
  114.         }
  115.         if(KeyHandle)
  116.         {
  117.                 ZwClose(KeyHandle);
  118.                 KeyHandle = NULL;
  119.         }
  120.         if(Buf)
  121.                 ExFreePool(Buf);
  122. }
复制代码


四、        默认派遣例程
        IRP_MJ_CREATE
检查当前所属进程是否有腾讯标记  (CheckDriverLoaderValid)
重置驱动注册表项信息 (ResetRegServiceInfo)
随机化EPROCESS的ImageFileName(RandomImageNameToHide)

3.1 根据进程id结束进程
  1. void TerminateProcessById(HANDLE ProcessId)
  2. {
  3.         PEPROCESS Process = NULL;
  4.         HANDLE ProcessHandle = NULL;
  5.         NTSTATUS status = PsLookupProcessByProcessId(ProcessId,&Process);
  6.         if(NT_SUCCESS(status))
  7.         {
  8.                 status = ObOpenObjectByPointer(Process,0,NULL,PROCESS_ALL_ACCESS,0,NULL,&ProcessHandle);
  9.                 if(NT_SUCCESS(status))
  10.                 {
  11.                         status = ZwTerminateProcess(ProcessHandle,0);
  12.                 }
  13.         }
  14.         if(Process)
  15.         {
  16.                 ObDereferenceObject(Process);
  17.                 Process = NULL;
  18.         }
  19.         if(ProcessHandle)
  20.                 ZwClose(ProcessHandle);


  21. 检测PE格式合法性

  22. bool CheckNtImageValid(LPVOID ImageAddress)
  23. {
  24.         if(ImageAddress && MmIsAddressValid(ImageAddress))
  25.         {
  26.                 PIMAGE_DOS_HEADER DosHeader = (IMAGE_DOS_HEADER)ImageAddress;
  27.                 if(MmIsAddressValid(&DosHeader->e_lfanew) && DosHeader->e_magic == 'ZM')
  28.                 {
  29.                         PIMAGE_NT_HEADERS NtHeader = (PIMAGE_NT_HEADERS)((BYTE*)DosHeader + DosHeader->e_lfanew);
  30.                         if(NtHeader && MmIsAddressValid(NtHeader) && NtHeader->Signature == 'EP')
  31.                                 return true;
  32.                 }
  33.         }
  34. }
复制代码

3.2 获取当前进程进程名

  1. typedef ULONG DWORD;
  2. typedef struct _MEMORY_BASIC_INFORMATION
  3. {
  4.         PVOID BaseAddress;
  5.         PVOID AllocationBase;
  6.         DWORD AllocationProtect;
  7.         SIZE_T RegionSize;
  8.         DWORD State;
  9.         DWORD Protect;
  10.         DWORD Type;
  11. } MEMORY_BASIC_INFORMATION, *PMEMORY_BASIC_INFORMATION;
  12. typedef struct _MEMORY_SECTION_NAME
  13. {
  14.         UNICODE_STRING SectionFileName;
  15.         WCHAR NameBuffer[0];
  16. } MEMORY_SECTION_NAME, *PMEMORY_SECTION_NAME;

  17. extern "C" PVOID __stdcall PsGetProcessSectionBaseAddress(PEPROCESS Process);
  18. extern "C" NTSTATUS __stdcall ZwQueryVirtualMemory(HANDLE ProcessHandle,PVOID BaseAddress,MEMORY_INFORMATION_CLASS MemoryInformationClass,
  19.         PVOID MemoryInformation,SIZE_T MemoryInformationLength,PSIZE_T ReturnLength);
  20. #define MEM_IMAGE 0x1000000

  21. bool GetCurrentProcessName(PVOID Buffer,SIZE_T Length)
  22. {
  23.          NTSTATUS status;
  24.         if(!Buffer || !Length)
  25.                 return;
  26.         UNICODE_STRING UIoVolumeDeviceToDosName;
  27.         PVOID ImageBase = PsGetProcessSectionBaseAddress(IoGetCurrentProcess());
  28.         PVOID SectionName = ExAllocatePool(NonPagedPool,Length + sizeof(MEMORY_SECTION_NAME));
  29.         if(!SectionName)
  30.                 return;
  31.         if(ImageBase)
  32.         {
  33.                 MEMORY_BASIC_INFORMATION BasicInfo;
  34.                 status = ZwQueryVirtualMemory(NtCurrentProcess(),ImageBase,MemoryBasicInformation,&BasicInfo,sizeof(BasicInfo),NULL);
  35.                 if(NT_SUCCESS(status) && BasicInfo.Type == MEM_IMAGE)
  36.                 {
  37.                         status = ZwQueryVirtualMemory(NtCurrentProcess(),ImageBase,MemorySectionName,SectionName,Length + sizeof(MEMORY_SECTION_NAME),NULL);
  38.                         if(NT_SUCCESS(status))
  39.                         {
  40.                                 wcsncpy((WCHAR*)Buffer,((PMEMORY_SECTION_NAME)SectionName)->SectionFileName.Buffer,Length);
  41.                                 return true;
  42.                         }
  43.                 }
  44.         }
  45.         return false;
  46. }
复制代码


3.3 由进程ID获取进程设备名

  1. bool GetProcessNameById(HANDLE ProcessId,PVOID Buffer,SIZE_T Length)
  2. {
  3.         NTSTATUS status;
  4.         if(ProcessId == (HANDLE)4)
  5.         {
  6.                 wcsncpy((WCHAR*)Buffer,L"System",Length);
  7.         }
  8.         else if(ProcessId == PsGetCurrentProcessId())
  9.         {
  10.                 GetCurrentProcessName(Buffer,Length);
  11.         }
  12.         else
  13.         {
  14.                 PEPROCESS Process = NULL;
  15.                 if(NT_SUCCESS(PsLookupProcessByProcessId(ProcessId,&Process)))
  16.                 {
  17.                         KAPC_STATE KApc;
  18.                         KeStackAttachProcess(Process,&KApc);
  19.                         GetCurrentProcessName(Buffer,Length);
  20.                         KeUnstackDetachProcess(&KApc);
  21.                         ObDereferenceObject(&Process);
  22.                 }
  23.                
  24.         }
  25.         return true;
  26. }
复制代码

3.4 设备名转DOS路径


  1. NTSTATUS GetDeviceDosName(WCHAR* DeviceName,WCHAR* DosName,DWORD Len)
  2. {
  3.         NTSTATUS status;
  4.         //检查设备路径
  5.         if(!DeviceName || !DosName)
  6.                 return STATUS_INVALID_PARAMETER;
  7.         if(wcsnicmp(DeviceName, L"\\Device\", 8u))
  8.                 return STATUS_INVALID_PARAMETER_1;
  9.         WCHAR* ptr = wcsstr(DeviceName + 8,L"\");
  10.         if(!ptr)
  11.                 return STATUS_UNSUCCESSFUL;
  12.         int len = ptr - DeviceName;
  13.         PVOID Buffer = ExAllocatePool(NonPagedPool,2*len+2);
  14.         if(!Buffer)
  15.                 return;
  16.         wcsncpy((WCHAR*)Buffer,DeviceName,len);
  17.         //根据设备名获取设备对象
  18.         PDEVICE_OBJECT DeviceObject;
  19.         UNICODE_STRING UDeviceName;
  20.         PFILE_OBJECT FileObject;
  21.         RtlInitUnicodeString(&UDeviceName,(WCHAR*)Buffer);
  22.         //GetDeviceObjectByName
  23.         status = IoGetDeviceObjectPointer(&UDeviceName,0,&FileObject,&DeviceObject);
  24.         if(NT_SUCCESS(status))
  25.         {
  26.                 if(DeviceObject->Type == FILE_DEVICE_DISK)
  27.                 {
  28.                         UNICODE_STRING RootDeviceDosName;
  29.                         status = IoVolumeDeviceToDosName(DeviceObject,&RootDeviceDosName);
  30.                         if(NT_SUCCESS(status))
  31.                         {
  32.                                 wcsncpy(DosName,RootDeviceDosName.Buffer,RootDeviceDosName.Length);
  33.                                 ExFreePool(RootDeviceDosName.Buffer);
  34.                                 int len2 = wcslen((WCHAR*)Buffer);//拼接全路径
  35.                                 wcsncat(DosName,DeviceName+len2,Len);
  36.                         }
  37.                 }
  38.                 else if(DeviceObject->Type == FILE_DEVICE_NETWORK_FILE_SYSTEM)
  39.                 {
  40.                         wcsncpy(DosName,L"\",Len);
  41.                         int len2 = wcslen((WCHAR*)Buffer);
  42.                         wcsncat(DosName,DeviceName+len2,Len);
  43.                 }
  44.                 else
  45.                 {
  46.                         status = STATUS_DEVICE_DATA_ERROR;
  47.                 }
  48.                 ObReferenceObject(FileObject);
  49.                 ObReferenceObject(DeviceObject);
  50.         }
  51.         ExFreePool(Buffer);
  52. }

复制代码

3.5 得到EPROCESS对应ImageDosPath

  1. void GetProcessDosPathByObject(PEPROCESS Process,LPVOID Buffer,ULONG Len)
  2. {
  3.         NTSTATUS status = STATUS_UNSUCCESSFUL;
  4.         HANDLE ProcessHandle = NULL;
  5.         HANDLE FileHandle = NULL;
  6.         const int FileBufSize = 4096;
  7.         PUNICODE_STRING pFilePath = ExAllocatePoolWithTag(NonPagedPool,FileBufSize);
  8.         if(!pFilePath)
  9.                 return;
  10.         status = ObOpenObjectByPointer(Process,OBJ_KERNEL_HANDLE,NULL,0,NULL,KernelMode,&ProcessHandle);
  11.         if(NT_SUCCESS(status))
  12.         {
  13.                 status = NtQueryInformationProcess(ProcessHandle,ProcessImageFileName,pFilePath,FileBufSize,NULL);
  14.                 if(NT_SUCCESS(status) && MmIsAddressValid(pFilePath->Buffer))
  15.                 {
  16.                         OBJECT_ATTRIBUTES oa;
  17.                         IO_STATUS_BLOCK IoStatusBlock;
  18.                         InitializeObjectAttributes(&oa,pFilePath,OBJ_CASE_INSENSITIVE |OBJ_KERNEL_HANDLE,NULL,NULL);
  19.                         status = IoCreateFile(&FileHandle,GENERIC_READ | SYNCHRONIZE,&oa,&IoStatusBlock,NULL,FILE_ATTRIBUTE_NORMAL,
  20.                                 FILE_SHARE_READ,FILE_OPEN,FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,NULL,0,CreateFileTypeNone,
  21.                                 NULL,IO_NO_PARAMETER_CHECKING);
  22.                         if(NT_SUCCESS(status))
  23.                         {// GetProcessDosPathByHandle
  24.                                 OBJECT_HANDLE_INFORMATION HandleInformation;
  25.                                 PFILE_OBJECT FileObject = NULL;
  26.                                 UNICODE_STRING DriveDosName = {0};
  27.                                 status = ObReferenceObjectByHandle(FileHandle,0,NULL,KernelMode,(PVOID*)&FileObject,&HandleInformation);
  28.                                 if(NT_SUCCESS(status) && FileObject != NULL && MmIsAddressValid(FileObject) && MmIsAddressValid(FileObject->FileName.Buffer))
  29.                                 {
  30.                                         if(IoGetRelatedDeviceObject(FileObject))
  31.                                         {
  32.                                                 status = RtlVolumeDeviceToDosName(FileObject->DeviceObject,&DriveDosName);//获取盘符
  33.                                                 if(NT_SUCCESS(status) && DriveDosName.Buffer && DriveDosName.Length + FileObject->FileName.Length < Len)
  34.                                                 {
  35.                                                         memcpy(Buffer,DriveDosName.Buffer,DriveDosName.Length);
  36.                                                         memcpy((char*)Buffer+DriveDosName.Length,FileObject->FileName.Buffer,FileObject->FileName.Length);
  37.                                                 }
  38.                                         }
  39.                                         ObDereferenceObject(FileObject);
  40.                                         if(DriveDosName.Buffer)
  41.                                                 ExFreePool(DriveDosName.Buffer);
  42.                                 }
  43.                         }
  44.                 }
  45.         }

  46.         if(FileHandle)
  47.                 NtClose(FileHandle);
  48.         if(ProcessHandle)
  49.                 NtClose(ProcessHandle);
  50.         ExFreePool(pFilePath);
  51. }

复制代码
3.6 随机化程序名机制

  1. Void RandomImageNameToHide()
  2. {
  3. ANSI_STRING QQEXEA,IMAGENAMEA;
  4.         char* ImageName;
  5.         RtlInitAnsiString(&QQEXEA,"QQPCRTP.EXE");
  6.         ImageName = PsGetProcessImageFileName(IoGetCurrentProcess());
  7.         RtlInitAnsiString(&IMAGENAMEA,ImageName);
  8.         if(!RtlCompareString(&IMAGENAMEA,&QQEXEA,TRUE))
  9.         {
  10.                 LARGE_INTEGER Time,LocalTime;
  11.                 TIME_FIELDS TimeFields;
  12.                 KeQuerySystemTime(&Time);
  13.                 ExSystemTimeToLocalTime(&Time,&LocalTime);
  14.                 RtlTimeToTimeFields(&LocalTime,&TimeFields);
  15.                 ImageName[TimeFields.Second % 5] = (TimeFields.Second % 26) + 'A';
  16.         }
  17. }

复制代码

3.7 根据进程文件名获取进程信息

  1. Bool GetProcessInfoByFileName(char* FileName, PVOID Buffer,int Size)
  2. {
  3.         ULONG InfoLen;
  4.         PVOID Modules;
  5.         NTSTATUS status;
  6.         BOOL Find = FALSE;
  7.         ZwQuerySystemInformation(SystemModuleInformation,&InfoLen,0,&InfoLen);
  8.         modules = ExAllocatePool(PagedPool,InfoLen);
  9.         If(!modules)
  10.                 Return FALSE;
  11.         status = ZwQuerySystemInformation(SystemModuleInformation, modules,InfoLen);
  12.         If(NT_SUCCESS(status))
  13.         {
  14.                 For(int i=0;i<modules-> NumberOfModules;i++)
  15.                 {
  16.                         Int offset = modules->Modules[i].OffsetToFileName;
  17.                         If(!stricmp(modules->Modules[i].FullPathName[offset],FileName)
  18.                         {
  19.                                 Memcpy(Buffer, &modules->Modules[i],Size);
  20.                                 Find = TRUE;
  21.                                 Break;
  22.                         }
  23.                 }
  24. }
  25. ExFreePool(modules);
  26. Return FALSE;
  27. }
复制代码

3.8 两种方式调用内核函数

法一:以ZwQueryVirtualMemory为例
UNICODE_STRING FuncName;
FARPROC fZwQueryVirtualMemory;
RtiInitUnicodeString(&FuncName, L”ZwQueryVirtualMemory”);
fZwQueryVirtualMemory = MmGetSystemRoutineAddress(&FuncName);

法二:
RTL_PROCESS_MODULE_INFORMATION ImageInfo;
RtlZeroMemory(&ImageInfo,sizeof(ImageInfo));
If(GetProcessInfoByFileName(“ntdll.dll”,&ImageInfo,sizeof(ImageInfo)))
NtQueryVirtualMemorySSDTIndex = GetSSDTApiIndex(ImageInfo.ImageBase,"NtQueryVirtualMemory");

用法:
ZwQueryVirtualMemoryEx(...)
{
        _asm
        {
                Push ebp
                Mov ebp,esp
                Mov eax, fZwQueryVirtualMemory
                Test eax,eax
                Jz $+3
                Pop ebp
                Jmp eax
                Cmp NtQueryVirtualMemorySSDTIndex,-1
                Jz $+6
                Pop ebp
                Jmp TAG
                Mov eax,C0000001h
                Pop ebp
                Retn 18h
TAG:
                Mov eax, NtQueryVirtualMemorySSDTIndex
                Lea edx,dword ptr [esp+4]
                Int 2Eh
                Retn 18h
        }
}

判断一段地址有效性
BOOLEAN  CheckAddressValid(PVOID VirtualAddress, int Length)
{
        int result;
        if ( VirtualAddress )
                result = MmIsAddressValid(VirtualAddress) && MmIsAddressValid(VirtualAddress + Length);
        else
                result = 0;
        return result;
}

3.9 获取对象类型
  1. POBJECT_TYPE GetTypeFromObject(PVOID Object)
  2. {//从对象获取对象类型
  3.         UNICODE_STRING UObGetObjectType;
  4.         POBJECT_TYPE ObjectType;
  5.         RtlInitUnicodeString(&UObGetObjectType,L"ObGetObjectType");
  6.         PVOID ObGetObjectType = MmGetSystemRoutineAddress(&UObGetObjectType);
  7.         if(ObGetObjectType)
  8.         {
  9.                 ObjectType = ((POBJECT_TYPE (__stdcall*)(PVOID ))ObGetObjectType)(Object);
  10.         }
  11.         else//Vista以前
  12.         {
  13.                 ObjectType = ((OBJECT_HEADER*)OBJECT_TO_OBJECT_HEADER(Object))->Type;
  14.         }
  15. }
复制代码

3.10 基础库功能——检测腾讯程序合法性
对当加载驱动的进程进行md5校验,如果校验失败则拒绝加载
从\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\TSKSP\\InstallDir获取q管安装目录

  1. void CheckTsFileValid(PEPROCESS Process)
  2. {
  3.         NTSTATUS status;
  4.         const int BufSize = 522;
  5.         WCHAR CurProcFileDosName[260];
  6.         WCHAR* FileDosName = (WCHAR*)ExAllocatePool(NonPagedPool,BufSize);
  7.         WCHAR* FileFullName = (WCHAR*)ExAllocatePool(NonPagedPool,520);
  8.         if(FileDosName && FileFullName)
  9.         {
  10.                 memset(FileDosName,0,BufSize);
  11.                 if(GetProcessDosPathByObject(Process,FileDosName,520))
  12.                 {
  13.                         status = GetProcessNameById(PsGetCurrentProcessId(),CurProcFileDosName,520);
  14.                         if(NT_SUCCESS(status) && !wcsicmp(CurProcFileDosName,FileDosName))
  15.                         {
  16.                                 UNICODE_STRING UFileFullName;
  17.                                 OBJECT_ATTRIBUTES oa;
  18.                                 HANDLE FileHandle;
  19.                                 IO_STATUS_BLOCK IoStatusBlock;
  20.                                 RtlZeroMemory(FileFullName,520);
  21.                                 wnsprintfW(FileFullName,259,L"\\??\\%ws",FileDosName);
  22.                                 InitializeObjectAttributes(&oa,FileFullName,OBJ_CASE_INSENSITIVE |OBJ_KERNEL_HANDLE,NULL,NULL);
  23.                                 status = IoCreateFile(&FileHandle,GENERIC_READ | SYNCHRONIZE,&oa,&IoStatusBlock,NULL,FILE_ATTRIBUTE_NORMAL,
  24.                                         FILE_SHARE_READ,FILE_OPEN,FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,NULL,0,CreateFileTypeNone,
  25.                                         NULL,IO_NO_PARAMETER_CHECKING);
  26.                                 if(NT_SUCCESS(status))
  27.                                 {
  28.                                         FILE_STANDARD_INFORMATION FileInformation;
  29.                                         status = ZwQueryInformationFile(FileHandle,&IoStatusBlock,&FileInformation,sizeof(FileInformation),FileStandardInformation);
  30.                                         if(NT_SUCCESS(status) && FileInformation.EndOfFile.LowPart < 0xA00000)
  31.                                         {
  32.                                                 PVOID Buffer = ExAllocatePool(NonPagedPool,FileInformation.EndOfFile.LowPart);
  33.                                                 if(Buffer)
  34.                                                 {
  35.                                                         status = ZwReadFile(FileHandle,NULL,NULL,NULL,&IoStatusBlock,Buffer,FileInformation.EndOfFile.LowPart,NULL,NULL);
  36.                                                         if(NT_SUCCESS(status) && CheckNtImageValid(Buffer))
  37.                                                         {
  38.                                                                 ULONG SecretDataOffset = *(ULONG*)((PIMAGE_DOS_HEADER)Buffer)->e_res2;
  39.                                                                 /************************************************************************/
  40.                                                                 /* 下面将Buffer+SecretDataOffset处的128字节数据进行md5校验,原始数据如下*/
  41.                                                                 // b8 92 77 ac 41 ee 20 b1-0d 0c ce d7 a2 95 b3 96
  42.                                                                 // 46 3f 16 ba 72 4d b9 df-2c 2f a5 f9 d2 63 3c 35
  43.                                                                 // 06 45 a2 dc bf 5c a7 6f-89 d5 45 e2 2b db 30 75
  44.                                                                 // d3 76 93 84 9b fc e4 62-ed 21 d5 6a db 90 84 df
  45.                                                                 // fc 1f ba 07 8d fd 7f 6d-f8 67 41 34 cc f3 e2 4a
  46.                                                                 // 04 73 8b 8a f6 7c 2c d5-10 21 cf 25 80 18 fc be
  47.                                                                 // 9f 5f c8 ea 47 c8 95 5a-79 07 be 54 9c 0d 12 36
  48.                                                                 // 0c f6 9a e6 71 0d c1 27-29 c2 9d e8 7e f0 b7 05
  49.                                                                 /************************************************************************/
  50.                                                                 //.........................省略md5计算过程
  51.                                                         }
  52.                                                         ExFreePool(Buffer);
  53.                                                 }
  54.                                         }
  55.                                         ZwClose(FileHandle);
  56.                                 }
  57.                         }
  58.                 }
  59.         }
  60.         if(FileDosName)
  61.                 ExFreePool(FileDosName);
  62.         if(FileFullName)
  63.                 ExFreePool(FileFullName);
  64. }
复制代码

3.11 解锁文件
设置文件属性为FILE_ATTRIBUTE_NORMAL
执行IopCloseFile  IRP_MJ_LOCK_CONTROL IRP_MN_UNLOCK_ALL
从句柄表中找到所有文件对象,如果路径匹配则关闭句柄CmCloseHandle

  1. typedef NTSTATUS EndSetFileAttributes ( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context )
  2. {
  3.         Irp->UserIosb->Status = Irp->IoStatus.Status;
  4.         Irp->UserIosb->Information = Irp->IoStatus.Information;
  5.         KeSetEvent(Irp->UserEvent, 0, FALSE);
  6.         IoFreeIrp(Irp);
  7.         return STATUS_MORE_PROCESSING_REQUIRED;
  8. }

  9. NTSTATUS ResetFileAttributes(HANDLE FileHandle)
  10. {
  11.         NTSTATUS status;
  12.         PDEVICE_OBJECT pDevObj = NULL;
  13.         PIRP pIrp = NULL;
  14.         KEVENT Event;
  15.         IO_STATUS_BLOCK ios = {0};
  16.         FILE_BASIC_INFORMATION BasicInfo;
  17.         PIO_STACK_LOCATION IrpSp;
  18.         status = ObReferenceObjectByHandle(FileHandle,0,*IoFileObjectType,KernelMode,&FileObject,NULL);
  19.         if(NT_SUCCESS(status))
  20.         {
  21.                 pDevObj = IoGetRelatedDeviceObject(FileObject);//穿透
  22.                 pIrp = IoAllocateIrp(pDevObj->StackSize,TRUE);
  23.                 if(pIrp)
  24.                 {
  25.                         KeInitializeEvent(&Event,SynchronizationEvent,FALSE);
  26.                         RtlZeroMemory(&BasicInfo,sizeof(BasicInfo));
  27.                         BasicInfo.FileAttributes = FILE_ATTRIBUTE_NORMAL;
  28.                         pIrp->AssociatedIrp.SystemBuffer = (PVOID)&BasicInfo;
  29.                         pIrp->UserEvent = &Event;
  30.                         pIrp->UserIosb = &ios;
  31.                         pIrp->Tail.Overlay.OriginalFileObject = FileObject;
  32.                         pIrp->Tail.Overlay.Thread = KeGetCurrentThread();
  33.                         pIrp->RequestorMode = 0;
  34.                         IrpSp = IoGetNextIrpStackLocation( pIrp );
  35.                         IrpSp->MajorFunction = IRP_MJ_SET_INFORMATION;
  36.                         IrpSp->DeviceObject = pDevObj;
  37.                         IrpSp->FileObject = FileObject;
  38.                         IrpSp->Parameters.SetFile.Length = sizeof(BasicInfo);
  39.                         IrpSp->Parameters.SetFile.FileInformationClass = FileBasicInformation;
  40.                         IrpSp->Parameters.SetFile.FileObject = FileObject;
  41.                         IrpSp->CompletionRoutine = EndSetFileAttributes;
  42.                         IrpSp->Context = NULL;
  43.                         IrpSp->Control = SL_INVOKE_ON_CANCEL|SL_INVOKE_ON_SUCCESS|SL_INVOKE_ON_ERROR;
  44.                         IoCallDriver(pDevObj,Irp);
  45.                         KeWaitForSingleObject(&Event,0,KernelMode,FALSE,NULL);
  46.                         ObDereferenceObject(FileObject);
  47.                 }
  48.                 else
  49.                 {
  50.                         status = STATUS_INSUFFICIENT_RESOURCES;
  51.                 }
  52.         }
  53.         if ( FileObject )
  54.                 ObDereferenceObject(FileObject);
  55.         return status;
  56. }

  57. void UnlockFileThread(PVOID StartContext)
  58. {
  59.         CmpSetHandleProtection(&Ohfi,FALSE);
  60.         if(StartContext)
  61.                 NtClose(StartContext);
  62.         PsTerminateSystemThread(0);
  63. }

  64. void TryUnlockFile(PFILE_OBJECT FileObject)
  65. {
  66.         SYSTEM_HANDLE_INFORMATION HandleInformation1;
  67.         ULONG RetLen = 0;
  68.         PVOID Buffer;
  69.         ZwQuerySystemInformation(SystemHandleInformation,&HandleInformation1,sizeof(HandleInformation1),&RetLen);
  70.         if(RetLen)
  71.         {
  72.                 POBJECT_NAME_INFORMATION ObjectNameInfo1 = (POBJECT_NAME_INFORMATION)ExAllocatePool(NonPagedPool,2056);
  73.                 POBJECT_NAME_INFORMATION ObjectNameInfo2 = (POBJECT_NAME_INFORMATION)ExAllocatePool(NonPagedPool,2056);
  74.                 ObjectNameInfo1->Name.Length = 2048;
  75.                 ObjectNameInfo2->Name.Length = 2048;
  76.                 Buffer = ExAllocatePool(PagedPool,RetLen+4096);

  77.                 status = ObQueryNameString(FileObject,ObjectNameInfo2,ObjectNameInfo2->Name.Length,&RetLen);
  78.                 if(NT_SUCCESS(status) && Buffer && ObjectNameInfo1)
  79.                 {
  80.                         status = ZwQuerySystemInformation(SystemHandleInformation,Buffer,RetLen+4096,&RetLen);
  81.                         if(NT_SUCCESS(status))
  82.                         {
  83.                                 UCHAR ObjectTypeIndex = 0;
  84.                                 PSYSTEM_HANDLE_INFORMATION HandleInformation2 = (PSYSTEM_HANDLE_INFORMATION)Buffer;
  85.                                 for(int i=0;i<HandleInformation2->NumberOfHandles;i++)
  86.                                 {
  87.                                         if(HandleInformation2->Handles[i].Object == FileObject)
  88.                                         {
  89.                                                 ObjectTypeIndex = HandleInformation2->Handles[i].ObjectTypeIndex;
  90.                                                 Break;
  91.                                         }
  92.                                 }
  93.                                 if(ObjectTypeIndex)
  94.                                 {
  95.                                         for(int i=0;i<HandleInformation2->NumberOfHandles;i++)
  96.                                         {
  97.                                                 if(HandleInformation2->Handles[i].ObjectTypeIndex == ObjectTypeIndex)
  98.                                                 {
  99.                                                         CLIENT_ID ClientId;
  100.                                                         HANDLE TargetProcessHandle = NULL;
  101.                                                         HANDLE CurrentProcessHandle = NULL;
  102.                                                         HANDLE TargetHandle = NULL;
  103.                                                         PVOID TargetFileObject = NULL;
  104.                                                         OBJECT_ATTRIBUTES oa;
  105.                                                         ULONG RetLen;
  106.                                                         InitializeObjectAttributes(&oa,NULL,OBJ_CASE_INSENSITIVE |OBJ_KERNEL_HANDLE,NULL,NULL);
  107.                                                         ClientId.UniqueProcess = HandleInformation2->Handles[i].UniqueProcessId;
  108.                                                         ClientId.UniqueThread = 0;
  109.                                                         status = ZwOpenProcess(&CurrentProcessHandle,PROCESS_ALL_ACCESS, &oa, &ClientId);
  110.                                                         if(NT_SUCCESS(status))
  111.                                                         {
  112.                                                                 InitializeObjectAttributes(&oa,NULL,OBJ_CASE_INSENSITIVE |OBJ_KERNEL_HANDLE,NULL,NULL);
  113.                                                                 ClientId.UniqueProcess = PsGetCurrentProcessId();
  114.                                                                 ClientId.UniqueThread = 0;
  115.                                                                 status = ZwOpenProcess(&TargetProcessHandle,PROCESS_ALL_ACCESS, &oa, &ClientId);
  116.                                                                 if(NT_SUCCESS(status))
  117.                                                                 {//从引用到该对象的进程复制一份句柄到当前进程
  118.                                                                         status = ZwDuplicateObject(CurrentProcessHandle,HandleInformation2->Handles[i].HandleValue,TargetProcessHandle,&TargetHandle,0,0,DUPLICATE_SAME_ACCESS);
  119.                                                                         if(NT_SUCCESS(status) && TargetHandle)
  120.                                                                         {
  121.                                                                                 status = ObReferenceObjectByHandle(TargetHandle,GENERIC_READ,IoFileObjectType,0,&TargetFileObject,0);
  122.                                                                                 if(NT_SUCCESS(status) && MmIsAddressValid(TargetFileObject) && TargetFileObject->DeviceObject->DeviceType == FILE_DEVICE_DISK)
  123.                                                                                 {
  124.                                                                                         status = ObQueryNameString(TargetFileObject,ObjectNameInfo1,ObjectNameInfo1->Name.Length,&RetLen);
  125.                                                                                         if(NT_SUCCESS(status))
  126.                                                                                         {
  127.                                                                                                 __try
  128.                                                                                                 {
  129.                                                                                                         if(RtlEqualUnicodeString(ObjectNameInfo1,ObjectNameInfo2,TRUE))
  130.                                                                                                         {
  131.                                                                                                                 PEPROCESS Process = NULL;
  132.                                                                                                                 KAPC_STATE ApcState;
  133.                                                                                                                 HANDLE ProcessId = HandleInformation2->Handles[i].UniqueProcessId;
  134.                                                                                                                 HANDLE ObjectHandle = HandleInformation2->Handles[i].HandleValue;
  135.                                                                                                                 OBJECT_HANDLE_FLAG_INFORMATION Ohfi;
  136.                                                                                                                 if(ProcessId != 0 && ProcessId != 4 && ProcessId != 8)
  137.                                                                                                                 {
  138.                                                                                                                         status = PsLookupProcessByProcessId(ProcessId,&Process);
  139.                                                                                                                         if(NT_SUCCESS(status))
  140.                                                                                                                         {
  141.                                                                                                                                 KeStackAttachProcess(Process,&ApcState);
  142.                                                                                                                                 CmpSetHandleProtection(&Ohfi,FALSE);
  143.                                                                                                                                 ZwClose(ObjectHandle);
  144.                                                                                                                                 KeUnstackDetachProcess(&ApcState);
  145.                                                                                                                                 if(Process)
  146.                                                                                                                                 {
  147.                                                                                                                                         ObDereferenceObject(Process);
  148.                                                                                                                                         Process = NULL;
  149.                                                                                                                                 }
  150.                                                                                                                         }
  151.                                                                                                                 }
  152.                                                                                                         }
  153.                                                                                                         else
  154.                                                                                                         {
  155.                                                                                                                 HANDLE ThreadHandle = DecodeKernelHandle(HandleInformation2->Handles[i].HandleValue);
  156.                                                                                                                 PsCreateSystemThread(&ThreadHandle,THREAD_ALL_ACCESS,NULL,NULL,NULL,UnlockFileThread,ThreadHandle);
  157.                                                                                                                 ZwWaitForSingleObject(ThreadHandle,FALSE,NULL);
  158.                                                                                                                 ZwClose(ThreadHandle);
  159.                                                                                                         }
  160.                                                                                                 }
  161.                                                                                                 __finally
  162.                                                                                                 {
  163.                                                                                                 }
  164.                                                                                         }
  165.                                                                                 }
  166.                                                                         }
  167.                                                                 }
  168.                                                         }


  169.                                                         if (TargetProcessHandle)
  170.                                                         {
  171.                                                                 ZwClose(TargetProcessHandle);
  172.                                                                 TargetProcessHandle = 0;
  173.                                                         }
  174.                                                         if ( CurrentProcessHandle )
  175.                                                         {
  176.                                                                 ZwClose(CurrentProcessHandle);
  177.                                                                 CurrentProcessHandle = 0;
  178.                                                         }
  179.                                                         if ( TargetHandle )
  180.                                                         {
  181.                                                                 ZwClose(TargetHandle);
  182.                                                                 TargetHandle = 0;
  183.                                                         }
  184.                                                         if ( TargetFileObject )
  185.                                                         {
  186.                                                                 ObfDereferenceObject(TargetFileObject);
  187.                                                                 TargetFileObject = 0;
  188.                                                         }
  189.                                                 }
  190.                                         }
  191.                                 }
  192.                         }
  193.                 }
  194.                 if(Buffer)
  195.                         ExFreePool(Buffer);
  196.                 if(ObjectNameInfo1)
  197.                         ExFreePool(ObjectNameInfo1);
  198.                 if(ObjectNameInfo2)
  199.                         ExFreePool(ObjectNameInfo2);
  200.         }
  201. }

  202. NTSTATUS UnlockFile(PUNICODE_STRING FileDosPath)
  203. {
  204.         IO_STATUS_BLOCK IoStatusBlock = {0};
  205.         OBJECT_ATTRIBUTES oa;
  206.         NTSTATUS status;
  207.         HANDLE FileHandle = NULL;
  208.         PFILE_OBJECT FileObject = NULL;
  209.         InitializeObjectAttributes(&oa,FileDosPath,OBJ_CASE_INSENSITIVE |OBJ_KERNEL_HANDLE,NULL,NULL);
  210.         //穿透IopCreateFile得到FileHandle
  211.         status = ResetFileAttributes(FileHandle);
  212.         if(NT_SUCCESS(status) )
  213.         {
  214.                 status = ObReferenceObjectByHandle(FileHandle,0,*IoFileObjectType,KernelMode,&FileObject,NULL);
  215.                 if(NT_SUCCESS(status))
  216.                 {
  217.                         IopDeleteFile(FileObject);
  218.                         TryUnlockFile(FileObject);
  219.                         FileHandle = NULL;
  220.                         ObDereferenceObject(FileObject);
  221.                 }
  222.         }
  223.         else if(status == STATUS_DELETE_PENDING)
  224.         {
  225.                 TryUnlockFile(FileObject);
  226.                 status = STATUS_SUCCESS;
  227.                 FileHandle = NULL;
  228.         }
  229.         if(FileHandle)
  230.                 ZwClose(FileHandle);
  231.         return status;
  232. }


复制代码
回复 赞! 靠!

使用道具 举报

 楼主| 发表于 2015-9-27 13:12:14 | 显示全部楼层
五、        获取ObjectInitializer
获取RegObjectInitializer:
1.        获取操作系统版本并转化为数组下标[0-9]
2.        获取\\Registry\\Machine\\SYSTEM对应KeyObject,得到其POBJECT_TYPE,判断是否为”Key”类型
3.        获取Ntos地址,获取CmpKeyObjectType的ParseProcedure,检测是否在Ntos中
4.        获取PCM_KEY_BODY->KeyControlBlock-> KeyHive的偏移,为获取GetCellRoutine
5.        Hook GetCellRoutine为NewGetCellRoutine
6.        创建线程依次执行ZwSetValueKey ZwQueryValueKey ZwEnumerateValueKey ZwEnumerateKey ZwDeleteValueKey ZwDeleteKey,触发GetCellRoutine
7.        NewGetCellRoutine中在回溯栈中查找对应Zw*匹配机器码,符合则取得相应Cm*地址
8.        解除Hook

获取DriverObjectInitializer和DeviceObjectInitializer:
1.        获取操作系统版本并转化为数组下标[0-9]
2.        获取DriverObject,得到其POBJECT_TYPE,判断是否为”Device”类型
3.        分别获取DriverObjectType和DeviceObjectType的ObjectInitializer

VersionIndex对照表
major   minor   build   out
*       *               10
5       1               1
5       2               2/3
5       *               10
6       0               4
6       1               5
6       2       8102    7
6       2       9200    8
6       2       *       10      
6       3       9600    9
6       3       *       10  

4.1 获取注册表OBJECT_TYPE,匹配对象类型
  使用\\Registry\\Machine\\SYSTEM注册表对象
  1. POBJECT_TYPE GetRegKeyType()
  2. {
  3.         UNICODE_STRING RegPath,FuncName;
  4.         OBJECT_ATTRIBUTES Oa;
  5.         HANDLE KeyHandle = NULL;
  6.         ULONG Disposition;
  7.         PCM_KEY_BODY KeyBody;
  8.         POBJECT_TYPE ObjType = NULL;
  9.         FARPROC ObGetObjectType;
  10.         NTSTATUS status;
  11.         RtlInitUnicodeString(&RegPath,L"\\Registry\\Machine\\SYSTEM");
  12.         InitializeObjectAttributes(&Oa,&RegPath,ExGetPreviousMode() != KernelMode?OBJ_CASE_INSENSITIVE :
  13.                 OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,NULL,NULL);               
  14.         status = ZwCreateKey(&KeyHandle,KEY_QUERY_VALUE,&Oa,0,NULL,REG_OPTION_NON_VOLATILE,&Disposition);
  15.         if(NT_SUCCESS(status))
  16.         {
  17.                 status = ObReferenceObjectByHandle(KeyHandle,GENERIC_READ,NULL,KernelMode,&KeyBody,NULL);
  18.                 if(NT_SUCCESS(status))
  19.                 {
  20.                         RtlInitUnicodeString(&FuncName,L"ObGetObjectType");
  21.                         ObGetObjectType = MmGetSystemRoutineAddress(&FuncName);
  22.                         if(ObGetObjectType)
  23.                         {
  24.                                 ObjType = ((POBJECT_TYPE (__stdcall*)(PVOID))ObGetObjectType)(KeyBody);
  25.                         }
  26.                         else if(VersionIndex < 5)//win7 之前
  27.                         {
  28.                                 ObjType = ((OBJECT_HEADER*)OBJECT_TO_OBJECT_HEADER(Object))->Type;
  29.                         }
  30.                         ObDereferenceObject(KeyBody);
  31.                 }
  32.                 ZwClose(KeyHandle);
  33.         }
  34.         return ObjType;
  35. }

  36. typedef struct _OBJECT_TYPE_XP
  37. {
  38.         ERESOURCE Mutex;
  39.         LIST_ENTRY TypeList;
  40.         UNICODE_STRING Name;  
  41.         PVOID DefaultObject;
  42.         ULONG Index;
  43.         ULONG TotalNumberOfObjects;
  44.         ULONG TotalNumberOfHandles;
  45.         ULONG HighWaterNumberOfObjects;
  46.         ULONG HighWaterNumberOfHandles;
  47.         OBJECT_TYPE_INITIALIZER TypeInfo;
  48.         ERESOURCE ObjectLocks[ OBJECT_LOCK_COUNT ];
  49. } OBJECT_TYPE_XP, *POBJECT_TYPE_XP;

  50. typedef struct _OBJECT_TYPE_WIN7
  51. {
  52.         LIST_ENTRY TypeList;
  53.         UNICODE_STRING Name;
  54.         PVOID DefaultObject;
  55.         ULONG Index;
  56.         ULONG TotalNumberOfObjects;
  57.         ULONG TotalNumberOfHandles;
  58.         ULONG HighWaterNumberOfObjects;
  59.         ULONG HighWaterNumberOfHandles;
  60.         OBJECT_TYPE_INITIALIZER TypeInfo;
  61.         EX_PUSH_LOCK TypeLock;
  62.         ULONG Key;
  63.         LIST_ENTRY CallbackList;
  64. } OBJECT_TYPE_WIN7, *POBJECT_TYPE_WIN7;

  65. BOOLEAN CmpRegKeyType(POBJECT_TYPE ObjType)
  66. {
  67.         UNICODE_STRING ObjTypeName;
  68.         RtlInitUnicodeString(&ObjTypeName,L"Key");
  69.         PUNICODE_STRING SrcTypeName;
  70.         if(VersionIndex >= 1 && VersionIndex <= 3)//xp 2000
  71.         {
  72.                 POBJECT_TYPE_XP _ObjType = (POBJECT_TYPE_XP)ObjType;
  73.                 if(!IsAddressRegionValid(&_ObjType->Name,sizeof(UNICODE_STRING)))
  74.                         return FALSE;
  75.                 SrcTypeName = &ObjType->Name;
  76.         }
  77.         else if(VersionIndex >= 4 && VersionIndex <= 9)//vista及之后
  78.         {
  79.                 POBJECT_TYPE_WIN7 _ObjType = (POBJECT_TYPE_WIN7)ObjType;
  80.                 if(!IsAddressRegionValid(&_ObjType->Name,sizeof(UNICODE_STRING)))
  81.                         return FALSE;
  82.                 SrcTypeName = &ObjType->Name;
  83.         }
  84.         else
  85.         {
  86.                 return FALSE;
  87.         }
  88.         if(IsAddressRegionValid(SrcTypeName->Buffer,SrcTypeName->Length))
  89.                 return RtlCompareUnicodeString(&ObjTypeName,SrcTypeName,TRUE) == 0;
  90.         return FALSE;
  91. }
复制代码

4.2获取ParseProcedure

  1. FARPROC RegObjectInitialzer[6];
  2. FARPROC FileObjectInitialzer[6];
  3. // 0 CloseProcedure
  4. // 1 DeleteProcedure
  5. // 2 ParseProcedure
  6. // 3 SecurityProcedure
  7. // 4 QueryNameProcedure
  8. // 5 OpenProcedure

  9. BOOLEAN GetParseProcedure(POBJECT_TYPE ObjectType)
  10. {
  11.         PVOID modules;
  12.         ULONG InfoLen = 0;
  13.         OB_PARSE_METHOD Proc = NULL;
  14.         ULONG_PTR NtosBegin = 0;
  15.         ULONG_PTR NtosEnd = 0;
  16.         RtlZeroMemory(RegObjectInitialzer,sizeof(RegObjectInitialzer));
  17.         if(!ObjectType)
  18.                 return FALSE;
  19.         ZwQuerySystemInformation(SystemModuleInformation,&InfoLen,0,&InfoLen);
  20.         if(InfoLen == 0)
  21.                 return FALSE;
  22.         modules = ExAllocatePool(PagedPool,InfoLen);
  23.         if(!modules)
  24.                 return FALSE;
  25.         status = ZwQuerySystemInformation(SystemModuleInformation,modules,&InfoLen);
  26.         if(NT_SUCCESS(status) && modules->NumberOfModules)
  27.         {
  28.                 NtosBegin = modules->Modules[0].ImageBase;
  29.                 NtosEnd = NtosBegin + modules->Modules[0].ImageSize;
  30.                 if(VersionIndex >= 1 && VersionIndex <= 3)//xp 2000
  31.                 {
  32.                         POBJECT_TYPE_XP _ObjType = (POBJECT_TYPE_XP)ObjType;
  33.                         Proc = _ObjType->TypeInfo.ParseProcedure;
  34.                 }
  35.                 else if(VersionIndex >= 4 && VersionIndex <= 9)//vista及之后
  36.                 {
  37.                         POBJECT_TYPE_WIN7 _ObjType = (POBJECT_TYPE_WIN7)ObjType;
  38.                         Proc = _ObjType->TypeInfo.ParseProcedure;
  39.                 }
  40.         }
  41.         ExFreePool(Modules);
  42.         if(Proc && Proc >= NtosBegin && Proc <= NtosEnd)
  43.         {
  44.                 RegObjectInitialzer[2] = Proc;
  45.                 return TRUE;
  46.         }
  47.         else
  48.         {
  49.                 return FALSE;
  50.         }
  51. }
复制代码

4.3 获取GetCellRoutine偏移,Hook GetCellRoutine
  1. BOOLEAN GetCellRoutineOffset()
  2. {
  3.   ULONG result = 0;
  4.   switch ( VersionIndex )
  5.   {
  6.     case WIN2000:
  7.     case WINXP:
  8.     case WINXPSP3:
  9.     case WINVISTA:
  10.     case 6:
  11.       CellRoutineOffset = 16;
  12.       Return true;
  13.     case WIN7:
  14.     case WIN8:
  15.     case WIN8_1:
  16.     case WIN10:
  17.       CellRoutineOffset = 20;
  18.         Return true;
  19.     default:
  20.       return result;
  21.   }
  22.   return result;
  23. }
复制代码



4.4 Hook和UnHook GetCellRoutine

  1. volatile ULONG HookCellRoutineRefCount = 0;
  2. volatile ULONG EnterCellRoutineRefCount = 0;
  3. ULONG_PTR OldGetCellRoutine = 0;
  4. BOOLEAN IsGetCell = FALSE;
  5. ULONG_PTR pGetCellRoutine = 0;

  6. BOOLEAN HookCellRoutine(BOOLEAN Hook)
  7. {

  8.         OBJECT_ATTRIBUTES Oa;
  9.         UNICODE_STRING RegPath;
  10.         NTSTATUS status;
  11.         HANDLE KeyHandle = NULL;
  12.         PCM_KEY_BODY KeyBody = NULL;
  13.         BOOLEAN success = FALSE;

  14.         while(InterlockedCompareExchange(&HookCellRoutineRefCount,1,0))//同步
  15.         {
  16.                 LARGE_INTEGER Interval;
  17.                 Interval.QuadPart = -10000i64 * 100;
  18.                 KeDelayExecutionThread(KernelMode,FALSE,&Interval);
  19.         }

  20.         if(Hook)
  21.         {
  22.                 if((CellRoutineBit & 0x111111) == 0x111111)
  23.                 {
  24.                         RtlInitUnicodeString(&RegPath);
  25.                         InitializeObjectAttributes(&Oa,&RegPath,OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,NULL,NULL);
  26.                         status = ZwOpenKey(&KeyHandle,KEY_ALL_ACCESS,&Oa);
  27.                         if(NT_SUCCESS(status))
  28.                         {
  29.                                 status = ObReferenceObjectByHandle(KeyHandle,KEY_SET_VALUE,*CmKeyObjectType,KernelMode,&KeyBody,NULL);
  30.                                 if(NT_SUCCESS(status))
  31.                                 {
  32.                                         ULONG_PTR pGetCellRoutine = (ULONG_PTR)&((HHIVE*)((BYTE*)KeyBody->KeyControlBlock + CellRoutineOffset))->GetCellRoutine;
  33.                                         OldGetCellRoutine = InterlockedExchange(pGetCellRoutine,NewGetCellRoutine);
  34.                                         IsGetCell = TRUE;
  35.                                         success = TRUE;
  36.                                 }
  37.                         }
  38.                         if(KeyBody)
  39.                                 ObReferenceObjectByHandle(KeyBody);
  40.                         if(KeyHandle)
  41.                                 ZwClose(KeyHandle);
  42.                 }
  43.         }
  44.         else//UnHook
  45.         {
  46.                 if(IsGetCell && OldGetCellRoutine && pGetCellRoutine)
  47.                 {
  48.                         int count = 0;
  49.                         InterlockedExchange(pGetCellRoutine,OldGetCellRoutine);
  50.                         do
  51.                         {
  52.                                 LARGE_INTEGER Interval;
  53.                                 Interval.QuadPart = -10000i64 * 50;
  54.                                 KeDelayExecutionThread(KernelMode,FALSE,&Interval);
  55.                                 InterlockedExchange(&count,EnterCellRoutineRefCount);
  56.                         } while (count);
  57.                         OldGetCellRoutine = 0;
  58.                         pGetCellRoutine = 0;
  59.                         IsGetCell = FALSE;
  60.                         success = TRUE;
  61.                 }
  62.         }
  63.         InterlockedExchange(&HookCellRoutineRefCount,0);
  64.         return success;
  65. }

复制代码
4.5 创建系统线程获取 Cm*函数






  1. int CmIndex;
  2. /*
  3.         CmQueryValueKey 0
  4.         CmSetValueKey 1
  5.         CmDeleteValueKey 2
  6.         CmDeleteKey 3
  7.         CmEnumerateKey 4
  8.         CmEnumerateValueKey 5
  9. */
  10. BOOLEAN SetCmTrap()
  11. {//通过注册表操作触发已经Hook的ObjectInitializer
  12.         WCHAR ValueName[] = L"100000";
  13.         WCHAR KeyPath[] = L"\\Registry\\Machine\\SYSTEM\\00000";
  14.         OBJECT_ATTRIBUTES Oa;
  15.         UNICODE_STRING UKeyPath,UValueName;
  16.         LARGE_INTEGER CurrentTime,LocalTime;
  17.         HANDLE KeyHandle = NULL;;
  18.         NTSTATUS status;
  19.         DWORD RetLen;
  20.         TIME_FIELDS TimeFields;
  21.         ULONG Disposition;
  22.         BOOLEAN result = FALSE;
  23.         KeQuerySystemTime(&CurrentTime);
  24.         ExSystemTimeToLocalTime(&CurrentTime,LocalTime);
  25.         RtlTimeToTimeFields(&LocalTime,&TimeFields);
  26.         ValueName[0] += TimeFields.Milliseconds % 9;
  27.         ValueName[1] += TimeFields.Second % 8;
  28.         ValueName[3] += TimeFields.Minute % 7;
  29.         ValueName[4] += TimeFields.Milliseconds % 9;
  30.         ValueName[5] += TimeFields.Second % 8;
  31.         KeyPath[25] += TimeFields.Second % 9;
  32.         KeyPath[26] += TimeFields.Milliseconds % 8;
  33.         KeyPath[27] += TimeFields.Second % 7;
  34.         KeyPath[28] += TimeFields.Milliseconds % 9;
  35.         KeyPath[29] += TimeFields.Minute % 8;
  36.         RtlInitUnicodeString(&UKeyPath,KeyPath);
  37.         InitializeObjectAttributes(&Oa,UKeyPath,OBJ_CASE_INSENSITIVE |OBJ_KERNEL_HANDLE,NULL,NULL);
  38.         status = ZwCreateKey(&KeyHandle,KEY_ALL_ACCESS,&Oa,0,NULL,REG_OPTION_NON_VOLATILE,&Disposition);
  39.         if(NT_SUCCESS(status))
  40.         {
  41.                 RtlInitUnicodeString(&UValueName,ValueName);
  42. //和NewGetCellRoutine配合使用
  43.                 CmIndex = ECmSetValueKey;
  44.                 ZwSetValueKey(KeyHandle,&UValueName,0,REG_SZ,ValueName,wcslen(ValueName)+2);
  45.                 CmIndex = ECmQueryValueKey;
  46.                 ZwQueryValueKey(KeyHandle,&UValueName,KeyValuePartialInformation,NULL,0,&RetLen);
  47.                 CmIndex = ECmEnumerateValueKey;
  48.                 ZwEnumerateValueKey(KeyHandle,0,KeyValueBasicInformation,NULL,0,&RetLen);
  49.                 CmIndex = ECmEnumerateKey;
  50.                 ZwEnumerateKey(KeyHandle,0,KeyValueBasicInformation,NULL,0,&RetLen);
  51.                 CmIndex = ECmDeleteValueKey;
  52.                 ZwDeleteValueKey(KeyHandle,&UValueName);
  53.                 CmIndex = ECmDeleteKey;
  54.                 ZwDeleteKey(KeyHandle);
  55.                 result = TRUE;
  56.         }
  57.         CmIndex = ECmMax;
  58.         if(KeyHandle)
  59.                 ZwClose(KeyHandle);
  60.         return result;
  61. }

  62. BOOLEAN CheckAndGetCmInnerFunc(ULONG Address,int CmIndex)
  63. {//通过回溯查找cm*地址
  64. /*
  65. 对比call   nt!CmSetValueKey之前偏移0x25的机器码:
  66. 80619a1f 7c1f            jl      nt!NtSetValueKey+0x234 (80619a40)
  67. 80619a21 53              push    ebx
  68. 80619a22 ff7518          push    dword ptr [ebp+18h]
  69. 80619a25 ff7514          push    dword ptr [ebp+14h]
  70. 80619a28 8d45c4          lea     eax,[ebp-3Ch]
  71. 80619a2b 50              push    eax
  72. 80619a2c ff7704          push    dword ptr [edi+4]
  73. 80619a2f e88e0b0100      call    nt!CmSetValueKey (8062a5c2)

  74. CmInnerFuncs
  75. b2e4c640  00 00 00 00 00 00 00 00-7c 00 53 ff 75 00 ff 75  ........|.S.u..u
  76. b2e4c650  00 8d 45 00 50 ff 77 00-01 00 00 00 02 00 00 00  ..
  77. */
  78.         UCHAR Code[32];
  79.         if(!Address || Address - 0x2F <= 0x7FFFFFFF || !IsAddressRegionValid(Address-0x2F,0x2F))
  80.                 return FALSE;
  81.         if(CmMatchData[VersionIndex][CmIndex].CodeMask)
  82.         {
  83.                 RtlCopyMemory(Code,Address-0x25,sizeof(Code));
  84.                 for(int i=31;i>=0;i--)
  85.                 {
  86.                         ULONG bit = CmMatchData[VersionIndex][CmIndex].CodeMask >> (31-i);
  87.                         if(bit & 1)
  88.                         {
  89.                                 if(CmMatchData[VersionIndex][CmIndex].ByteCode[i] != Code[i])
  90.                                         return FALSE;
  91.                         }
  92.                         else if(bit == 0)
  93.                         {
  94.                                 break;
  95.                         }
  96.                         CmMatchData[VersionIndex][CmIndex].FuncAddr = Address+*(ULONG_PTR*)(Address-1);
  97.                         CellRoutineBit |= CmMatchData[VersionIndex][CmIndex].CmFlag;
  98.                         CmMatchData[VersionIndex][CmIndex].InitFlag = TRUE;
  99.                         return TRUE;
  100.                 }
  101.         }

  102.         return FALSE;
  103. }

  104. BOOLEAN GetCmFuncsByIndex(ULONG Esp,int CmIndex)
  105. {
  106.         if(!Esp)
  107.                 return FALSE;
  108.         for(int i=0;i<100;i++)
  109.         {
  110.                 if(!IsAddressRegionValid(Esp,4))
  111.                         break;
  112.                 if(Esp >= NtosBegin && Esp <= NtosEnd && CheckAndGetCmInnerFunc(Esp,CmIndex))
  113.                         return TRUE;
  114.                 Esp += 4;
  115.         }
  116.         return FALSE;
  117. }

  118. NTSTATUS __stdcall NewGetCellRoutine(HHIVE Hive,HCELL Cell)
  119. {
  120.         NTSTATUS status;
  121.         ULONG_PTR _Esp = 0;
  122.         _asm
  123.         {
  124.                 mov _Esp,esp;
  125.         }
  126.         InterlockedExchangeAdd(&EnterCellRoutineRefCount,1);
  127.         if(PsGetCurrentThreadId() == GetCmRegFuncsThreadId && CmIndex < 6)
  128.         {
  129.                 if(CmMatchData[VersionIndex][CmIndex].InitFlag && CmMatchData[VersionIndex][CmIndex].FuncAddr)
  130.                 {
  131.                         if(!(CmMatchData[VersionIndex][CmIndex].CmFlag & CellRoutineBit))
  132.                                 CellRoutineBit |= CmMatchData[VersionIndex][CmIndex].CmFlag;
  133.                 }
  134.                 else
  135.                 {
  136.                         switch(CmIndex)
  137.                         {
  138.                         case ECmQueryValueKey:
  139.                                 GetCmFuncsByIndex();
  140.                                 break;
  141.                         case ECmSetValueKey:
  142.                                 GetCmFuncsByIndex();
  143.                                 break;
  144.                         case ECmDeleteValueKey:
  145.                                 GetCmFuncsByIndex();
  146.                                 break;
  147.                         case ECmDeleteKey:
  148.                                 GetCmFuncsByIndex();
  149.                                 break;
  150.                         case ECmEnumerateKey:
  151.                                 GetCmFuncsByIndex();
  152.                                 break;
  153.                         case ECmEnumerateValueKey:
  154.                                 GetCmFuncsByIndex();
  155.                                 break;
  156.                         }

  157.                 }
  158.         }
  159.         status = OldGetCellRoutine(Hive,Cell);
  160.         InterlockedExchangeAdd(&EnterCellRoutineRefCount,-1);
  161.         return status;
  162. }

复制代码
4.6 匹配结构

用于匹配cm*函数调用周围的机器码
#define MaxVersion 10
enum
{
        ECmQueryValueKey=0,
        ECmSetValueKey,
        ECmDeleteValueKey,
        ECmDeleteKey,
        ECmEnumerateKey,
        ECmEnumerateValueKey,
        ECmMax,
        NCmQueryValueKey=1,
        NCmSetValueKey=0x10,
        NCmDeleteValueKey=0x100,
        NCmDeleteKey=0x1000,
        NCmEnumerateKey=0x10000,
        NCmEnumerateValueKey=0x100000,
};

struct CM_MATCH_DATA
{
        ULONG InitFlag;//是否初始化
        ULONG FuncAddr;//获取到的cm函数地址
        ULONG CmFlag;//cm函数类型,1~0x100000 对应于各个cm函数
        ULONG CodeMask;//32bit对应于BYTE ByteCode[32]的掩码,决定是否比较
        UCHAR ByteCode[32];//用于比较cm函数的机器码
        UCHAR ByteCode_1[8];//用于比较cm函数的机器码
};

CM_MATCH_DATA CmMatchData[MaxVersion][ECmMax]=
{
        {//NON
                {
                        0, NULL, NCmQueryValueKey, 0,
                        {
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                        },
                        0, 1,
                },
                {
                        0, NULL, NCmSetValueKey, 0,
                        {
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                               
                        },
                        0, 2,
                },
                {
                        0, NULL, NCmDeleteValueKey, 0,
                        {
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
                        },
                        0, 3,
                },
                {
                        0, NULL, NCmDeleteKey, 0,
                        {
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
                        },
                        0, 4,
                },
                {
                        0, NULL, NCmEnumerateKey, 0,
                        {
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
                        },
                        0, 5,
                },
                {
                        0, NULL, NCmEnumerateValueKey, 0,
                        {
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
                        },
                        1, 0,
                },
        },
        {//WIN2000
                {
                        0, NULL , NCmQueryValueKey, 0x176DB6,
                        {
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x57, 0xFF, 0x75,
                                0x00, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0xFF, 0x76, 0x00,
                        },
                        1, 1,
                },
                {
                        0, NULL, NCmSetValueKey, 0xBB6E,
                        {
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                0x7C, 0x00, 0x53, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0x8D, 0x45, 0x00, 0x50, 0xFF, 0x77, 0x00,
                        },
                        1, 2,
                },
                {
                        0, NULL, NCmDeleteValueKey, 0x3DB6,
                        {
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                0x00, 0x00, 0x39, 0x75, 0xE4, 0x7C, 0x00, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0xFF, 0x77, 0x00,
                        },
                        1, 3,
                },
                {
                        0, NULL, NCmDeleteKey, 0x6DB6D,
                        {
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8B, 0x46, 0x00,
                                0xF6, 0x40, 0x00, 0x80, 0x75, 0x00, 0x8B, 0x40, 0x00, 0xF6, 0x40, 0x00, 0x80, 0x75, 0x00, 0x56,
                        },
                        1, 4,
                },
                {
                        0, NULL, NCmEnumerateKey, 1AEDB6h,
                        {
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x5D, 0x00, 0x7C, 0x00,
                                0x56, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0xFF, 0x77, 0x00,
                        },
                        1, 5,
                },
                {
                        0, NULL, NCmEnumerateValueKey, 1AEDB6,
                        {
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x5D, 0x00, 0x7C, 0x00,
                                0x56, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0xFF, 0x77, 0x00,
                        },
                        2, 0,
                },
        },
        {//WINXPSP1
                {
                        0, NULL , NCmQueryValueKey, 0x3B6DB6,
                        {
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, 0xFF, 0x75, 0x00, 0xFF, 0x75,
                                0x00, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0x8B, 0x7D, 0x00, 0xFF, 0x77, 0x00,
                        },
                        2, 1,
                },
                {
                        0, NULL, NCmSetValueKey, 0xBB6E,
                        {
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                0x7C, 0x00, 0x53, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0x8D, 0x45, 0x00, 0x50, 0xFF, 0x76, 0x00,
                        },
                        2, 2,
                },
                {
                        0, NULL, NCmDeleteValueKey, 0x1DB6,
                        {
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                0x00, 0x00, 0x00, 0x85, 0xF6, 0x7C, 0x00, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0xFF, 0x77, 0x00,
                        },
                        2, 3,
                },
                {
                        0, NULL, NCmDeleteKey, 0xDB6D,
                        {
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                0xF6, 0x40, 0x00, 0x80, 0x75, 0x00, 0x8B, 0x40, 0x00, 0xF6, 0x40, 0x00, 0x80, 0x75, 0x00, 0x56,
                        },
                        2, 4,
                },
                {
                        0, NULL, NCmEnumerateKey, 0xEEDB6,
                        {
                                0x00, 0x00, 0x00, 0x00, 0x85, 0xF6, 0x7C, 0x00, 0x53, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0xFF,
                                0x75, 0x00, 0xFF, 0x75, 0x00, 0xFF, 0x77, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00
                        },
                        2, 5,
                },
                {
                        0, NULL, NCmEnumerateValueKey, 0xEEDB6,
                        {
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x85, 0xF6, 0x7C, 0x00,
                                0x53, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0xFF, 0x77, 0x00,
                        },
                        3, 0,
                },
        },
        {//WINXPSP3
                {
                        0, NULL , NCmQueryValueKey, 0x176DB6,
                        {
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x56, 0xFF, 0x75,
                                0x00, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0xFF, 0x77, 0x00,
                        },
                        3, 1,
                },
                {
                        0, NULL, NCmSetValueKey, 0xBB6E,
                        {
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                0x7C, 0x00, 0x53, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0x8D, 0x45, 0x00, 0x50, 0xFF, 0x76, 0x00,
                        },
                        3, 2,
                },
                {
                        0, NULL, NCmDeleteValueKey, 0x1DB6,
                        {
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                0x00, 0x00, 0x00, 0x85, 0xF6, 0x7C, 0x00, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0xFF, 0x77, 0x00,
                        },
                        3, 3,
                },
                {
                        0, NULL, NCmDeleteKey, 0xDB6D, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
                        {
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                0xF6, 0x40, 0x00, 0x80, 0x75, 0x00, 0x8B, 0x40, 0x00, 0xF6, 0x40, 0x00, 0x80, 0x75, 0x00, 0x56,
                        },
                        3, 4,
                },
                {
                        0, NULL, NCmEnumerateKey, 0xEEDB6, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
                        {
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0xF6, 0x7C, 0x00,
                                0x53, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0xFF, 0x77, 0x00,
                        },
                        3, 5,
                },
                {
                        0, NULL, NCmEnumerateValueKey, 0xEEDB6, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
                        {
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0xF6, 0x7C, 0x00,
                                0x53, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0xFF, 0x77, 0x00,
                        },
                        4, 0,
                },
        },
        {//WINVISTA
                {
                        0, NULL , NCmQueryValueKey, 0x1DB6DB6,
                        {
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x7C, 0x00, 0xFF, 0x75, 0x00, 0xFF, 0x75,
                                0x00, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00,
                        },
                        4, 1,
                },
                {
                        0, NULL, NCmSetValueKey, 0x3BB6E,
                        {
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0xFF,
                                0x75, 0x00, 0x56, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0x8D, 0x45, 0x00, 0x50, 0xFF, 0x75, 0x00,
                        },
                        4, 2,
                },
                {
                        0, NULL, NCmDeleteValueKey, 0x37FF6,
                        {
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8B, 0x45,
                                0x00, 0xC1, 0xE8, 0x02, 0x25, 0x01, 0xFF, 0xFF, 0xFF, 0x50, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00,
                        },
                        4, 3,
                },
                {
                        0, NULL, NCmDeleteKey, 0x3FD,
                        {
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBB, 0x22, 0x00, 0x00, 0xC0, 0x3B, 0xDE, 0x7C, 0x00, 0x57,
                        },
                        4, 4,
                },
                {
                        0, NULL, NCmEnumerateKey, 0x16DBB6,
                        {
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x00, 0xFF, 0x75, 0x00,
                                0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0x57, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0x8B, 0x4D, 0x00,
                        },
                        4, 5,
                },
                {
                        0, NULL, NCmEnumerateValueKey, 0x2DB76,
                        {
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x75, 0x00,
                                0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0x57, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00,
                        },
                        5, 0,
                },
        },
        {//WIN7
                {
                        0, NULL , NCmQueryValueKey, 0x1DB6DB6,
                        {
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x7C, 0x00, 0xFF, 0x75, 0x00, 0xFF, 0x75,
                                0x00, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00,
                        },
                        5, 1,
                },
                {
                        0, NULL, NCmSetValueKey, 0x7FBB6E,
                        {
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x01, 0x0F, 0xB6, 0xC0, 0x50, 0xFF,
                                0x75, 0x00, 0x56, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0x8D, 0x45, 0x00, 0x50, 0xFF, 0x75, 0x00,
                        },
                        5, 2,
                },
                {
                        0, NULL, NCmDeleteValueKey, 0x7FF6,
                        {
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                0x00, 0xC1, 0xE8, 0x02, 0x24, 0x01, 0x0F, 0xB6, 0xC0, 0x50, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00,
                        },
                        5, 3,
                },
                {
                        0, NULL, NCmDeleteKey, 0x67E61,
                        {
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x44, 0x00,
                                0x00, 0x22, 0x00, 0x00, 0xC0, 0x39, 0x5C, 0x00, 0x00, 0x0F, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x57,
                        },
                        5, 4,
                },
                {
                        0, NULL, NCmEnumerateKey, 0x16DBB6,
                        {
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x00, 0xFF, 0x75, 0x00,
                                0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0x57, 0xFF, 0x75, 0x00, 0x8B, 0x4D, 0x00, 0x8B, 0x55, 0x00,
                        },
                        5, 5,
                },
                {
                        0, NULL, NCmEnumerateValueKey, 0x2DB76,
                        {
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x75, 0x00,
                                0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0x57, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00,
                        },
                        6, 0,
                },
        },
        {//??
                {
                        0, NULL , NCmQueryValueKey, 0x1DB6DB6,
                        {
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3B, 0xC7, 0x7C, 0x00, 0xFF, 0x75, 0x00, 0xFF, 0x75,
                                0x00, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00,
                        },
                        6, 1,
                },
                {
                        0, NULL, NCmSetValueKey, 0x3BB6E,
                        {
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0xFF,
                                0x75, 0x00, 0x56, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0x8D, 0x45, 0x00, 0x50, 0xFF, 0x75, 0x00,
                        },
                        6, 2,
                },
                {
                        0, NULL, NCmDeleteValueKey, 0x37FF6,
                        {
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8B, 0x45,
                                0x00, 0xC1, 0xE8, 0x02, 0x25, 0x01, 0xFF, 0xFF, 0xFF, 0x50, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00,
                        },
                        6, 3,
                },
                {
                        0, NULL, NCmDeleteKey, 0x3FD,
                        {
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBB, 0x22, 0x00, 0x00, 0xC0, 0x3B, 0xDE, 0x7C, 0x00, 0x57,
                        },
                        6, 4,
                },
                {
                        0, NULL, NCmEnumerateKey, 0x16DBB6,
                        {
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x00, 0xFF, 0x75, 0x00,
                                0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0x57, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0x8B, 0x4D, 0x00,
                        },
                        6, 5,
                },
                {
                        0, NULL, NCmEnumerateValueKey, 0x2DB76,
                        {
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x75, 0x00,
                                0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0x57, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00,
                        },
                        7, 0,
                },
        },
        {//WIN8
                {
                        0, NULL , NCmQueryValueKey, 0x1DA7A6,
                        {
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0xC0, 0x78, 0x00, 0xFF,
                                0x75, 0x00, 0xFF, 0x75, 0x00, 0x56, 0x57, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00,
                        },
                        7, 1,
                },
                {
                        0, NULL, NCmSetValueKey, 0xFFFB6E,
                        {
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC1, 0xE8, 0x02, 0x24, 0x01, 0x0F, 0xB6, 0xC0,
                                0x50, 0x56, 0x57, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0x8D, 0x45, 0x00, 0x50, 0xFF, 0x75, 0x00,
                        },
                        7, 2,
                },
                {
                        0, NULL, NCmDeleteValueKey, 0x1FFDB6,
                        {
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC1, 0xE8, 0x02, 0x24, 0x01,
                                0x0F, 0xB6, 0xC0, 0x50, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00,
                        },
                        7, 3,
                },
                {
                        0, NULL, NCmDeleteKey, 0x3FD,
                        {
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBB, 0x22, 0x00, 0x00, 0xC0, 0x85, 0xDB, 0x78, 0x00, 0x56,
                        },
                        7, 4,
                },
                {
                        0, NULL, NCmEnumerateKey, 0x7DB6DB6,
                        {
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x8B, 0xF0, 0x85, 0xF6, 0x78, 0x00, 0xFF, 0x75, 0x00, 0xFF, 0x75,
                                0x00, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0x8B, 0x45, 0x00,
                        },
                        7, 5,
                },
                {
                        0, NULL, NCmEnumerateValueKey, 0x36DB76,
                        {
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x7D, 0x00, 0x00, 0x75, 0x00,
                                0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0x57, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00,
                        },
                        8, 0,
                },
        },
        {//WIN8.1
                {
                        0, NULL , NCmQueryValueKey, 0x786DBE,
                        {
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0xC0, 0x0F, 0x85, 0x00, 0x00, 0x00,
                                0x00, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0x56, 0x57, 0x53, 0xFF, 0x75, 0x00,
                        },
                        8, 1,
                },
                {
                        0, NULL, NCmSetValueKey, 0xE1F76DD,
                        {
                                0x00, 0x00, 0x00, 0x00, 0x04, 0x0F, 0x85, 0x00, 0x00, 0x00, 0x00, 0x33, 0xC0, 0x50, 0xFF, 0x75,
                                0x00, 0x56, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0x8D, 0x45, 0x00, 0x50, 0x8B, 0x5D, 0x00, 0x53,
                        },
                        8, 2,
                },
                {
                        0, NULL, NCmDeleteValueKey, 0x1B87FB76,
                        {
                                0x00, 0x00, 0x00, 0x00, 0x5D, 0x00, 0x0F, 0xB6, 0x85, 0x00, 0x00, 0x00, 0x00, 0xC1, 0xE8, 0x02,
                                0x83, 0xE0, 0x01, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0x50, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00,
                        },
                        8, 3,
                },
                {
                        0, NULL, NCmDeleteKey, 0xF0F879C,
                        {
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x85, 0xC0, 0x0F,
                                0x84, 0x00, 0x00, 0x00, 0x00, 0x33, 0xDB, 0x8B, 0x74, 0x00, 0x00, 0x56, 0x88, 0x5C, 0x00, 0x00,
                        },
                        8, 4,
                },
                {
                        0, NULL, NCmEnumerateKey, 0x37876DBB,
                        {
                                0x00, 0x00 ,0x8B, 0x75, 0x00, 0x85, 0xDB, 0x0F, 0x88, 0x00, 0x00, 0x00, 0x00, 0x57, 0xFF, 0x75,
                                0x00, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0xFF, 0x75, 0x00, 0x56, 0x8B, 0x7D, 0x00, 0x8B, 0xC7,
                        },
                        8, 5,
                },
                {
                        0, NULL, NCmEnumerateValueKey, 0x3F0EEDDD,
                        {
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0xF6, 0x0F, 0x85, 0x00, 0x00, 0x00, 0x00,
                                0x57, 0xFF, 0x75, 0x00, 0x53, 0xFF, 0x75, 0x00, 0x8B, 0x5D, 0x00, 0x53, 0x8B, 0x7D, 0x00, 0x57,
                        },
                        9, 0,
                },
        },
        {//WIN10
                {
                        0, NULL , NCmQueryValueKey, 0xFFFFFFFF,
                        {
                                0x00, 0x00, 0x85, 0xF6, 0x0F, 0x85, 0x0A, 0xD7, 0x10, 0x00, 0x8B, 0x7D, 0xB8, 0xFF, 0x75, 0xCC,
                                0xFF, 0x75, 0xC8, 0xFF, 0x75, 0xB4, 0x53, 0x57, 0x8B, 0x5D, 0x10, 0x8B, 0xD3, 0x8B, 0x4D, 0xBC
                        },
                        9, 1,
                },
                {
                        0, NULL, NCmSetValueKey, 0xFFFFFFFF,
                        {
                                0x5D, 0xCB, 0x0F, 0xB6, 0x85, 0x74, 0xFF, 0xFF, 0xFF, 0xC1, 0xE8, 0x02, 0x83, 0xE0, 0x01, 0x50,
                                0xFF, 0x75, 0x88, 0x57, 0xFF, 0x75, 0xAC, 0xFF, 0x75, 0x14, 0x8D, 0x55, 0xB8, 0x8B, 0x4D, 0xB4
                        },
                        9, 2,
                },
                {
                        0, NULL, NCmDeleteValueKey, 0xFFFFFFFF,
                        {
                                0xC4, 0x0D, 0x00, 0x88, 0x5D, 0xCB, 0x0F, 0xB6, 0x85, 0x7C, 0xFF, 0xFF, 0xFF, 0xC1, 0xE8, 0x02,
                                0x83, 0xE0, 0x01, 0xFF, 0x75, 0xBC, 0xFF, 0x75, 0xB8, 0x50, 0x8B, 0x55, 0xA8, 0x8B, 0x4D, 0xB4
                        },
                        9, 3,
                },
                {
                        0, NULL, NCmDeleteKey, 0xFFFFFFFF,
                        {
                                0x01, 0x00, 0x00, 0x40, 0x66, 0x89, 0x81, 0x3C, 0x01, 0x00, 0x00, 0x66, 0x85, 0xC0, 0x0F, 0x84,
                                0x9E, 0x00, 0x00, 0x00, 0x33, 0xDB, 0x8B, 0x74, 0x24, 0x10, 0x8B, 0xCE, 0x88, 0x5C, 0x24, 0x2C
                        },
                        9, 4,
                },
                {
                        0, NULL, NCmEnumerateKey, 0xFFFFFFFF,
                        {
                                0xE8, 0x5A, 0xB1, 0xFF, 0xFF, 0x8B, 0xF0, 0x85, 0xF6, 0x78, 0x1C, 0xFF, 0x75, 0xB8, 0xFF, 0x75,
                                0x18, 0xFF, 0x75, 0xBC, 0xFF, 0x75, 0x10, 0xFF, 0x75, 0x0C, 0x8B, 0x55, 0xC4, 0x8B, 0x4D, 0xC8
                        },
                        9, 5,
                },
                {
                        0, NULL, NCmEnumerateValueKey, 0xFFFFFFFF,
                        {
                                0x8B, 0xF0, 0x85, 0xF6, 0x78, 0x21, 0x8B, 0x4D, 0xCC, 0x83, 0x7D, 0xC8, 0x00, 0x0F, 0x85, 0x84,
                                0xCA, 0x0D, 0x00, 0xFF, 0x75, 0xC0, 0xFF, 0x75, 0x18, 0xFF, 0x75, 0xC4, 0x57, 0x8B, 0x55, 0x0C
                        },
                        10, 0,
                },
        },
};

4.7 获取DeviceObject对象类型

  1. POBJECT_TYPE GetDeviceObjectType()
  2. {
  3.         UNICODE_STRING UAcpi;
  4.         UNICODE_STRING UFilePath;
  5.         NTSTATUS status;
  6.         PDRIVER_OBJECT pDrvObj = NULL;
  7.         PDEVICE_OBJECT pDevObj = NULL;
  8.         HANDLE FileHandle = NULL;
  9.         POBJECT_TYPE ObjectType = NULL;
  10.         RtlInitUnicodeString(&UAcpi,L"\\Driver\\ACPI");
  11.         status = ObReferenceObjectByName(&UAcpi,OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE,NULL,0,*IoDriverObjectType,KernelMode,NULL,&pDrvObj);
  12.         if(NT_SUCCESS(status) && pDrvObj && pDrvObj->DeviceObject)
  13.         {
  14.                 pDevObj = pDrvObj->DeviceObject;
  15.         }
  16.         if(pDevObj)
  17.         {
  18.                 ObjectType = (POBJECT_TYPE)((PUCHAR)pDevObj-16);
  19.         }
  20.         if(pDrvObj)
  21.         {
  22.                 ObDereferenceObject(pDrvObj);
  23.                 pDrvObj = NULL;
  24.         }
  25.         if(FileHandle)
  26.         {
  27.                 ZwClose(FileHandle);
  28.                 FileHandle = NULL;
  29.         }
  30.         return ObjectType;
  31. }
复制代码

回复 赞! 靠!

使用道具 举报

发表于 2015-9-27 13:32:33 | 显示全部楼层
这个是咋分析出了的?也忒牛了吧?
回复 赞! 靠!

使用道具 举报

发表于 2015-9-27 13:47:38 | 显示全部楼层
好帖!
回复

使用道具 举报

 楼主| 发表于 2015-10-2 15:17:20 | 显示全部楼层
TsFltMgr.sys 深度分析

TsFltMgr.sys分析报告
        该驱动为qq管家函数过滤驱动,提供SSDT、SSSDT、进程和线程回调等过滤操作,导出接口给TsKsp.sys使用,2者共同做函数过滤操作,TsFltMgr提供设置函数过滤的框架,而实际拦截过程在TsKsp中。设备名\\Device\\TsFltMgr ,符号名\\DosDevices\\TsFltMgr 。加密手段:Rabbit算法、MD5算法。通过InlineHook KifastCallEntry实现挂钩。
目录
TsFltMgr.sys分析报告        1
一、        驱动入口DriverEntry        2
1.1 过滤模型        3
1.2 检查当前系统是否为默认挂钩系统        3
1.3 打开TsFltMgr日志记录        4
1.4 控制信息        4
1.5 全局表        4
1.6 Proxy*函数模型        19
二、        驱动接口Interface        22
2.1 DeviceExtension接口        22
2.2 SetEvaluateTime        22
2.3 AddDisablePrevFilter        23
2.4 SetPostFilter        23
2.5 ExecOriginFromPacket        23
2.6 AddPrevFilter        23
2.7 RemovePrevFilter        24
2.8 GetCurrentHookInfo        25
2.9 GetDProxyTable        26
三、        控制码        27
四、        默认派遣例程        28
3.1 根据进程id结束进程        28
五、        基础库        29
5.1 获取注册表键值        29
5.2 通过进程名获取进程ID        31
六、        InlineHook KiFastCallEntry        32
6.1 获取SSDT/SSSDT/Hook点        33
6.2 从KiSystemService获取KiFastCallEntry        36
6.3 获取SSSDT信息        36
6.4 初始化InlineHook KiFastCallEntry跳转表        38
6.5 获取系统服务号的2种方式        41
6.6 InlineHook过程        42
6.7 构造InlineHook跳转后的执行语句        45
6.8 强制单核互斥执行指定Procedure        48
6.9 进行SSDT hook        49
6.10 对重要回调(进程回调、线程回调、映像加载回调)的挂钩        52
6.11 Hook KeUserModeCallback        54
6.12 交换内存        55
6.13 获取函数Iat偏移        55
6.14 另一种方式获取ShadowSSDT信息        56

一、        驱动入口DriverEntry
        创建\\Device\\TSSysKit设备和\\DosDevices\\TSSysKit符号链接
        设置DeviceExtension为通信接口(Interface函数指针)
        分别注册IRP_MJ_CREATE、IRP_MJ_CLOSE、IRP_MJ_DEVICE_CONTROL、IRP_MJ_SHUTDOWN(关机回调)派遣例程为,CreateCloseDispatch、DeviceIoControlDispatch、ShutdownDispatch
        注册”Boot驱动加载结束”回调DriverReinitializationRoutine
        为注册表日志记录分配资源RegLogSpace
        检查当前系统是否为注册表version键指定的系统,如果在列表中则在挂钩KiFastCallEntry时需要做额外工作
        设置注册表键IsBsod为1,用于检测该驱动是否引起蓝屏(正常关机置0)
        获取系统BuildNumber
        分配和设置”内核Api代理”结构
        挂钩KiFastCallEntry
        挂钩重要回调
        启动注册表日志记录
        挂钩KeUserModeCallback
        记录当前配置



1.1 过滤模型
















①        Ntdll.NtCreateFile通过Sysenter调用进入nt.KiFastCallEntry
②        在nt.KiFastCallEntry 执行call ebx(原始为nt.NtCreateFile)前跳到TsFltMgr. InlineKiFastCallEntry
③        执行进入TsFltMgr.HookFilter,在这里通过ServiceMapTable表映射到对应Dproxy元素,将Dproxy->ProxyNtCreateFile设置到ebx,将其设置为ebx
④        Nt.KiFastCallEntry执行call ebx,进入ProxyNtCreateFile
⑤        构造FilterPacket结构(用于承载参数、原始api和PostFilterFunc执行的所有过滤函数都用到),依次执行Dproxy->PrevFilterSlot的16个过滤函数(PrevFilter是Tsksp事先设置好的)
⑥        依次执行单个Tsksp.PrevFilter,进行真正的过滤或对packet. PostFilterSlot进行设置
⑦        返回TsFltMgr.ProxyNtCreateFile,执行nt.NtCreateFile
⑧        执行packet. PostFilterSlot的16个过滤函数(Tsksp)
⑨        返回nt.KiFastCallEntry

1.2 检查当前系统是否为默认挂钩系统
  1. BOOLEAN IsUnSupportedSystem()
  2. {
  3. /*注:\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services\\TSKS        version
  4.         存放没有预存 函数调用号ServiceIndex 的系统版本列表 格式:
  5. BuildNumber1;BuildNumber2;...
  6.         对于这些版本在进行SSDT Hook时,会临时取得服务号
  7. */
  8.         NTSTATUS status;
  9.         ULONG BuildNumber = 0,MajorVersion,MinorVersion;
  10.         const int BufSize = 1024;
  11.         ULONG Size,Type;
  12.         WCHAR BuildNumberStr[10] = {0};
  13.         BOOLEAN Match = FALSE;
  14.         UNICODE_STRING UBuildNumber;
  15.         WCHAR* Buffer = (WCHAR*)ExAllocatePool(NonPagedPool,BufSize);
  16.         status = GetRegDataWithSizeAndType(L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services\\TSKSP",L"version",
  17.                 Buffer,BufSize,&Size,&Type);
  18.         if(NT_SUCCESS(status) && Type == REG_SZ && Size)
  19.         {
  20.                 Buffer[510] = 0;
  21.                 RtlInitUnicodeString(&UBuildNumber,BuildNumberStr);
  22.                 PsGetVersion(&MajorVersion,&MinorVersion,&BuildNumber,NULL);
  23.                 RtlIntegerToUnicodeString(BuildNumber,10,&UBuildNumber);
  24.                 if(wcsstr((wchar_t*)Buffer,UBuildNumber.Buffer))
  25.                         Match = TRUE;
  26.         }
  27.         ExFreePool(Buffer);
  28.         return Match;
  29. }

复制代码
1.3 打开TsFltMgr日志记录
在无保护情况下为\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\TsFltMgr添加TsDbgLog键,内容设置为目标文件路径(例如\??\C:\TsDbgLog.txt),如果不存在会自动创建文件,重启生效。内容示例:
[0x00000000] 2015.09.27 20:05:24.109        TS TsFltMgr DbgHelper
[0x00000001] 2015.09.27 20:06:13.750        [Sysnap DbgLog] Block--> TableIndex 0, Process spoolsv.exe[1800]
[0x00000002] 2015.09.27 20:10:35.156        [Sysnap DbgLog] Block--> TableIndex 4, Process regedit.exe[2296]
[0x00000003] 2015.09.27 20:13:46.500        [Sysnap DbgLog] Block--> TableIndex 4, Process regedit.exe[2296]

DriverReinitializationRoutine中做初始化,此时最后一个boot驱动初始化完毕
在执行KiFastCallEntry hook时再次尝试启动打印日志线程
ExecPrevSlotFunc中,如果存在过滤函数进行了放行和拦截,都会打印日志

1.4 控制信息

禁止hook
\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\TsFltMgr dws=1
\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\services\\QQSysMon\\DWS dws!=0

强制SSDT hook
\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\TsFltMgr thm=1

关机回调
设置\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\TsFltMgr  IsBsod=0,以便下次启动检测是否TsFltMgr引起蓝屏

1.5 全局表
系统Build号与全局表索引对应关系
BuildNumber:
Win2000
    2195    1
WinXp
    2600    2
WinServer2003
    3790    3
WinVista
    6000    4
    6001    5
    6002    6
Win7
    7600    7
    7601    8
Win8
    8102    9
    8250    10
    8400    11
    8432    12
    8441    12
    8520    13
Win8.1
    9200    14
    9600    15
Win10
    9841    16
    9860    17
    9926    18
    10041   19
    10049   20
未知  0

  1. enum
  2. {
  3.         WIN2000=1,
  4.         WINXP,
  5.         WINXPSP3,
  6.         WINVISTA,
  7.         WINVISTASP1,
  8.         WINVISTASP2,
  9.         WIN7,
  10.         WIN7SP1,
  11.         WIN8_8102,
  12.         WIN8_8250,
  13.         WIN8_8400,
  14.         WIN8_8432,
  15.         WIN8_8441=WIN8_8432,
  16.         WIN8_8520,
  17.         WIN81_9200,
  18.         WIN81_9600,
  19.         WIN10_9841,
  20.         WIN10_9860,
  21.         WIN10_9926,
  22.         WIN10_10041,
  23.         WIN10_10049,
  24.         BUILDMAX,
  25. };
  26. enum
  27. {
  28.         SSDT=0,
  29.         SSSDT=1,
  30.         END=2,
  31.         CALLBACK=3,
  32. };

  33. #define APINUMBER 105

  34. struct SProxy
  35. {
  36.         ULONG ServiceTableType;//0:SSDT 1:Shadow SSDT 2:结束符
  37.         PWCHAR ApiName;//函数名
  38.         ULONG  ProxyFunc;//代理函数地址
  39.         ULONG ServiceIndex[BUILDMAX];
  40.         ULONG IndexInTable;//在全局表中的索引
  41. };

  42. struct DProxy
  43. {
  44.         ULONG ServiceTableType;//0:SSDT 1:Shadow SSDT 2:结束符 3:回调函数
  45.         ULONG ServiceIndex;//服务号
  46.         PWCHAR ApiName;//函数名
  47.         ULONG TableIndex;//自定义序号
  48.         BOOLEAN IsInitialized;
  49.         ULONG PrevFilterRefCount;//引用计数
  50.         ULONG PostFilterRefCount;//引用计数
  51.         ULONG OriginFuncAddr;//原始函数地址
  52.         ULONG ProxyFuncAddr;//代理函数地址
  53.         PVOID Log;//用于记录日志
  54.         KEVENT Lock;
  55.         BOOLEAN DisablePrevFilter;//关闭Filter
  56.         ULONG UsedSlotCount;// 当前使用的Slot个数
  57.         FILTER_SLOT PrevFilterSlot[16];//过滤函数结构
  58. };

  59. struct FILTER_SLOT
  60. {
  61.         ULONG Tag;
  62.         ULONG CallCount;
  63.         ULONG DeleteCount;
  64.         KTIMER Timer;
  65.         ULONG Filter;
  66. };

  67. struct FilterPacket
  68. {
  69.         ULONG CurrentSlot;//当前Filter序号
  70.         ULONG ParamNumber;//参数个数
  71.         ULONG Params[12];//参数
  72.         ULONG TagSlot[16];//标志过滤函数用,也可用于传递修改参数
  73.         NTSTATUS Status;//执行结果
  74.         ULONG OriginFuncAddr;//原始函数
  75.         ULONG IndexInTable;//在DProxyTable中的索引
  76.         ULONG Access;//访问权限
  77.         ULONG PostFilterSlot[16];//过滤函数
  78.         ULONG UsedSlotCount;//当前使用的Slot个数
  79. };
复制代码

TsFltMgr有3张表与函数过滤相关:
静态Api代理表SProxy        SProxyTable[APINUMBER+1]                用于初始化后面2个表
动态Api代理表DProxy*        DProxyTable[APINUMBER+1]        用于Proxy*函数中进行实际过滤操作   方便用SProxy指定的序号配置
DProxy* ServiceMapTable[2][1024]                用于InlineHook KiFastCallEntry改变ebx,映射ServiceIndex到Proxy*函数。函数前1024个用于存储SSDT函数,后1024用于存储SSSDT函数

可以用简单的python命令自动获取到g_ProxyApiTable内容
addr=0x25200
index=0
while index < 106:
if Dword(addr) == 0:
type="SSDT"
elif Dword(addr) == 1:
type="SSSDT"
else:
type="END"
ApiName=GetString(Dword(addr+4),-1,ASCSTR_UNICODE)
ProxyFunc="Proxy"+ApiName
print "{\n\t%s,L\"%s\",%s,\n\t{" %(type,ApiName,ProxyFunc)
print "\t\t%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d" %(Dword(addr+12),Dword(addr+16),Dword(addr+20),Dword(addr+24),Dword(addr+28),Dword(addr+32),Dword(addr+36),Dword(addr+40),Dword(addr+44),Dword(addr+48),Dword(addr+52),Dword(addr+56),Dword(addr+60),Dword(addr+64),Dword(addr+68),Dword(addr+72),Dword(addr+76),Dword(addr+80),Dword(addr+84),Dword(addr+88),Dword(addr+92))
print "\t},%d\n}," %(Dword(addr+96))
addr=addr+100
index=index+1

  1. struct SProxy        SProxyTable[APINUMBER+1] =
  2. {
  3.         {
  4.                 SSDT,L"ZwCreateKey",ProxyZwCreateKey,
  5.                 {
  6.                         1023,35,41,43,64,64,64,70,70,347,351,351,350,350,350,354,355,355,356,359,359
  7.                 },0
  8.         },
  9.         {
  10.                 SSDT,L"ZwTerminateProcess",ProxyZwTerminateProcess,
  11.                 {
  12.                         1023,224,257,266,338,334,334,370,370,35,35,35,35,35,35,35,36,36,36,36,36
  13.                 },1
  14.         },
  15.         {
  16.                 SSDT,L"ZwSetInformationFile",ProxyZwSetInformationFile,
  17.                 {
  18.                         1023,194,224,233,305,301,301,329,329,78,79,79,78,78,78,81,82,82,82,82,82
  19.                 },2
  20.         },
  21.         {
  22.                 SSDT,L"ZwWriteFile",ProxyZwWriteFile,
  23.                 {
  24.                         1023,237,274,284,359,355,355,396,396,4,5,5,5,5,5,6,7,7,7,7,7
  25.                 },3
  26.         },
  27.         {
  28.                 SSDT,L"ZwSetValueKey",ProxyZwSetValueKey,
  29.                 {
  30.                         1023,215,247,256,328,324,324,358,358,48,48,48,48,48,48,49,50,50,50,50,50
  31.                 },4
  32.         },
  33.         {
  34.                 SSDT,L"ZwWriteVirtualMemory",ProxyZwWriteVirtualMemory,
  35.                 {
  36.                         1023,240,277,287,362,358,358,399,399,1,2,2,2,2,2,3,4,4,4,4,4
  37.                 },5
  38.         },
  39.         {
  40.                 SSDT,L"ZwCreateFile",ProxyZwCreateFile,
  41.                 {
  42.                         1023,32,37,39,60,60,60,66,66,351,356,356,355,355,355,360,361,361,362,365,365
  43.                 },6
  44.         },
  45.         {
  46.                 SSDT,L"ZwOpenProcess",ProxyZwOpenProcess,
  47.                 {
  48.                         1023,106,122,128,194,194,194,190,190,220,222,222,221,221,221,224,225,225,226,227,227
  49.                 },7
  50.         },
  51.         {
  52.                 SSDT,L"ZwDeleteKey",ProxyZwDeleteKey,
  53.                 {
  54.                         1023,53,63,66,123,123,123,103,103,310,314,314,313,313,313,317,318,318,319,321,321
  55.                 },8
  56.         },
  57.         {
  58.                 SSDT,L"ZwDeleteValueKey",ProxyZwDeleteValueKey,
  59.                 {
  60.                         1023,55,65,68,126,126,126,106,106,307,311,311,310,310,310,314,315,315,316,318,318
  61.                 },9
  62.         },
  63.         {
  64.                 SSDT,L"ZwRequestWaitReplyPort",ProxyZwRequestWaitReplyPort,
  65.                 {
  66.                         1023,176,200,208,275,276,276,299,299,108,110,110,109,109,109,112,113,113,114,114,114
  67.                 },10
  68.         },
  69.         {
  70.                 SSDT,L"ZwQueryValueKey",ProxyZwQueryValueKey,
  71.                 {
  72.                         1023,155,177,185,252,252,252,266,266,143,145,145,144,144,144,147,148,148,149,149,149
  73.                 },11
  74.         },
  75.         {
  76.                 SSDT,L"ZwEnumerateValueKey",ProxyZwEnumerateValueKey,
  77.                 {
  78.                         1023,61,73,77,136,136,136,119,119,292,296,296,295,295,295,299,300,300,301,303,303
  79.                 },12
  80.         },
  81.         {
  82.                 SSDT,L"ZwCreateThread",ProxyZwCreateThread,
  83.                 {
  84.                         1023,46,53,55,78,78,78,87,87,330,334,334,333,333,333,337,338,338,339,342,342
  85.                 },13
  86.         },
  87.         {
  88.                 SSDT,L"ZwDuplicateObject",ProxyZwDuplicateObject,
  89.                 {
  90.                         1023,58,68,71,129,129,129,111,111,300,304,304,303,303,303,307,308,308,309,311,311
  91.                 },14
  92.         },
  93.         {
  94.                 SSDT,L"ZwLoadDriver",ProxyZwLoadDriver,
  95.                 {
  96.                         1023,85,97,101,165,165,165,155,155,255,257,257,256,256,256,259,260,260,261,263,263
  97.                 },15
  98.         },
  99.         {
  100.                 SSDT,L"ZwDeviceIoControlFile",ProxyZwDeviceIoControlFile,
  101.                 {
  102.                         1023,56,66,69,127,127,127,107,107,304,308,308,307,307,307,311,312,312,313,315,315
  103.                 },16
  104.         },
  105.         {
  106.                 SSDT,L"ZwAlpcSendWaitReceivePort",ProxyZwAlpcSendWaitReceivePort,
  107.                 {
  108.                         1023,1023,1023,1023,38,38,38,39,39,381,386,386,385,385,385,390,391,391,393,396,396
  109.                 },17
  110.         },
  111.         {
  112.                 SSDT,L"ZwSetSystemInformation",ProxyZwSetSystemInformation,
  113.                 {
  114.                         1023,208,240,249,321,317,317,350,350,56,56,56,56,56,56,57,58,58,58,58,58
  115.                 },18
  116.         },
  117.         {
  118.                 SSDT,L"ZwDeleteFile",ProxyZwDeleteFile,
  119.                 {
  120.                         1023,52,62,65,122,122,122,102,102,311,315,315,314,314,314,318,319,319,320,322,322
  121.                 },19
  122.         },
  123.         {
  124.                 SSDT,L"ZwOpenSection",ProxyZwOpenSection,
  125.                 {
  126.                         1023,108,125,131,197,197,197,194,194,216,218,218,217,217,217,220,221,221,222,222,222
  127.                 },20
  128.         },
  129.         {
  130.                 SSDT,L"ZwCreateSection",ProxyZwCreateSection,
  131.                 {
  132.                         1023,43,50,52,75,75,75,84,84,333,337,337,336,336,336,340,341,341,342,345,345
  133.                 },21
  134.         },
  135.         {
  136.                 SSDT,L"ZwSuspendThread",ProxyZwSuspendThread,
  137.                 {
  138.                         1023,221,254,263,335,331,331,367,367,38,38,38,38,38,38,38,39,39,39,39,39
  139.                 },22
  140.         },
  141.         {
  142.                 SSDT,L"ZwTerminateThread",ProxyZwTerminateThread,
  143.                 {
  144.                         1023,225,258,267,339,335,335,371,371,34,34,34,34,34,34,34,35,35,35,35,35
  145.                 },23
  146.         },
  147.         {
  148.                 SSDT,L"ZwSystemDebugControl",ProxyZwSystemDebugControl,
  149.                 {
  150.                         1023,222,255,264,336,332,332,368,368,37,37,37,37,37,37,37,38,38,38,38,38
  151.                 },24
  152.         },
  153.         {
  154.                 SSDT,L"ZwProtectVirtualMemory",ProxyZwProtectVirtualMemory,
  155.                 {
  156.                         1023,1023,137,143,210,210,210,215,215,194,196,196,195,195,195,198,199,199,200,200,200
  157.                 },38
  158.         },
  159.         {
  160.                 SSDT,L"ZwCreateSymbolicLinkObject",ProxyZwCreateSymbolicLinkObject,
  161.                 {
  162.                         1023,45,52,54,77,77,77,86,86,331,335,335,334,334,334,338,339,339,340,343,343
  163.                 },39
  164.         },
  165.         {
  166.                 SSDT,L"ZwSetContextThread",ProxyZwSetContextThread,
  167.                 {
  168.                         1023,1023,213,221,293,289,289,316,316,91,92,92,91,91,91,94,95,95,95,95,95
  169.                 },40
  170.         },
  171.         {
  172.                 SSDT,L"ZwRenameKey",ProxyZwRenameKey,
  173.                 {
  174.                         1023,1023,192,200,267,267,267,290,290,117,119,119,118,118,118,121,122,122,123,123,123
  175.                 },41
  176.         },
  177.         {
  178.                 SSDT,L"ZwOpenThread",ProxyZwOpenThread,
  179.                 {
  180.                         1023,111,128,134,201,201,201,198,198,214,214,214,213,213,213,216,217,217,218,218,218
  181.                 },42
  182.         },
  183.         {
  184.                 SSDT,L"ZwGetNextThread",ProxyZwGetNextThread,
  185.                 {
  186.                         1023,1023,1023,1023,372,368,368,140,140,271,271,271,270,270,270,273,274,274,275,277,277
  187.                 },43
  188.         },
  189.         {
  190.                 SSDT,L"ZwCreateThreadEx",ProxyZwCreateThreadEx,
  191.                 {
  192.                         1023,1023,1023,1023,388,382,382,88,88,333,333,333,332,332,332,336,337,337,338,341,341
  193.                 },44
  194.         },
  195.         {
  196.                 SSDT,L"ZwRestoreKey",ProxyZwRestoreKey,
  197.                 {
  198.                         1023,1023,204,212,279,280,280,302,302,105,107,107,106,106,106,109,110,110,111,111,111
  199.                 },55
  200.         },
  201.         {
  202.                 SSDT,L"ZwReplaceKey",ProxyZwReplaceKey,
  203.                 {
  204.                         1023,1023,193,201,268,268,268,292,292,115,117,117,116,116,116,119,120,120,121,121,121
  205.                 },56
  206.         },
  207.         {
  208.                 SSDT,L"ZwGetNextProcess",ProxyZwGetNextProcess,
  209.                 {
  210.                         1023,1023,1023,1023,371,367,367,139,139,270,272,272,271,271,271,274,275,275,276,278,278
  211.                 },45
  212.         },
  213.         {
  214.                 SSDT,L"ZwUnmapViewOfSection",ProxyZwUnmapViewOfSection,
  215.                 {
  216.                         1023,231,267,277,352,348,348,385,385,19,19,19,19,19,19,19,20,20,20,20,20
  217.                 },46
  218.         },
  219.         {
  220.                 SSDT,L"ZwAssignProcessToJobObject",ProxyZwAssignProcessToJobObject,
  221.                 {
  222.                         1023,18,19,21,42,42,42,43,43,377,382,382,381,381,381,386,387,387,389,392,392
  223.                 },47
  224.         },
  225.         {
  226.                 SSDT,L"ZwAllocateVirtualMemory",ProxyZwAllocateVirtualMemory,
  227.                 {
  228.                         1023,16,17,18,18,18,18,19,19,403,407,407,406,406,406,411,412,412,415,418,418
  229.                 },57
  230.         },
  231.         {
  232.                 SSDT,L"ZwFreeVirtualMemory",ProxyZwFreeVirtualMemory,
  233.                 {
  234.                         1023,71,83,87,147,147,147,131,131,278,281,281,280,280,280,284,285,285,286,288,288
  235.                 },58
  236.         },
  237.         {
  238.                 SSSDT,L"NtUserFindWindowEx",ProxyNtUserFindWindowEx,
  239.                 {
  240.                         1023,368,378,377,391,391,391,396,396,455,457,458,459,460,459,460,462,466,466,466,467
  241.                 },25
  242.         },
  243.         {
  244.                 SSSDT,L"NtUserBuildHwndList",ProxyNtUserBuildHwndList,
  245.                 {
  246.                         1023,302,312,311,322,322,322,323,323,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023
  247.                 },26
  248.         },
  249.         {
  250.                 SSSDT,L"NtUserQueryWindow",ProxyNtUserQueryWindow,
  251.                 {
  252.                         1023,466,483,481,504,504,504,515,515,478,480,481,482,483,482,483,485,489,489,489,490
  253.                 },27
  254.         },
  255.         {
  256.                 SSSDT,L"NtUserGetForegroundWindow",ProxyNtUserGetForegroundWindow,
  257.                 {
  258.                         1023,393,404,403,418,418,418,423,423,426,428,429,430,430,429,430,431,435,435,435,435
  259.                 },28
  260.         },
  261.         {
  262.                 SSSDT,L"NtUserWindowFromPoint",ProxyNtUserWindowFromPoint,
  263.                 {
  264.                         1023,568,592,588,617,617,617,629,629,640,643,646,648,650,649,652,658,664,665,666,667
  265.                 },29
  266.         },
  267.         {
  268.                 SSSDT,L"NtUserSetParent",ProxyNtUserSetParent,
  269.                 {
  270.                         1023,510,529,526,550,550,550,560,560,582,585,587,589,591,590,593,595,601,602,603,604
  271.                 },30
  272.         },
  273.         {
  274.                 SSSDT,L"NtUserSetWindowLong",ProxyNtUserSetWindowLong,
  275.                 {
  276.                         1023,525,544,540,566,566,566,578,578,560,562,564,566,567,566,569,571,575,576,576,577
  277.                 },31
  278.         },
  279.         {
  280.                 SSSDT,L"NtUserMoveWindow",ProxyNtUserMoveWindow,
  281.                 {
  282.                         1023,449,465,464,484,484,484,495,495,499,501,502,503,504,503,505,507,511,511,511,512
  283.                 },32
  284.         },
  285.         {
  286.                 SSSDT,L"NtUserSetWindowPos",ProxyNtUserSetWindowPos,
  287.                 {
  288.                         1023,527,546,542,568,568,568,580,580,558,560,562,564,565,564,567,569,573,574,574,575
  289.                 },33
  290.         },
  291.         {
  292.                 SSSDT,L"NtUserSetWindowPlacement",ProxyNtUserSetWindowPlacement,
  293.                 {
  294.                         1023,526,545,541,567,567,567,579,579,559,561,563,565,566,565,568,570,574,575,575,576
  295.                 },34
  296.         },
  297.         {
  298.                 SSSDT,L"NtUserShowWindow",ProxyNtUserShowWindow,
  299.                 {
  300.                         1023,536,555,551,579,579,579,591,591,547,549,551,553,554,553,556,558,562,563,563,564
  301.                 },35
  302.         },
  303.         {
  304.                 SSSDT,L"NtUserShowWindowAsync",ProxyNtUserShowWindowAsync,
  305.                 {
  306.                         1023,537,556,552,580,580,580,592,592,546,548,550,552,553,552,555,557,561,562,562,563
  307.                 },36
  308.         },
  309.         {
  310.                 SSSDT,L"NtUserSendInput",ProxyNtUserSendInput,
  311.                 {
  312.                         1023,481,502,500,525,525,525,536,536,606,609,611,613,615,614,617,619,625,626,627,628
  313.                 },37
  314.         },
  315.         {
  316.                 SSSDT,L"NtUserSetWinEventHook",ProxyNtUserSetWinEventHook,
  317.                 {
  318.                         1023,533,552,548,576,576,576,588,588,550,552,554,556,557,556,559,561,565,566,566,567
  319.                 },49
  320.         },
  321.         {
  322.                 SSSDT,L"NtUserClipCursor",ProxyNtUserClipCursor,
  323.                 {
  324.                         1023,0,330,329,343,343,343,348,348,333,334,335,335,335,335,337,338,342,342,342,342
  325.                 },48
  326.         },
  327.         {
  328.                 SSSDT,L"NtUserSetWindowsHookEx",ProxyNtUserSetWindowsHookEx,
  329.                 {
  330.                         1023,530,549,545,573,573,573,585,585,553,555,557,559,560,559,562,564,568,569,569,570
  331.                 },50
  332.         },
  333.         {
  334.                 SSDT,L"ZwMakeTemporaryObject",ProxyZwMakeTemporaryObject,
  335.                 {
  336.                         1023,1023,105,110,174,174,174,164,164,246,248,248,247,247,247,250,251,251,252,254,254
  337.                 },59
  338.         },
  339.         {
  340.                 SSDT,L"ZwCreateUserProcess",ProxyZwCreateUserProcess,
  341.                 {
  342.                         1023,1023,1023,1023,1023,383,383,93,93,322,326,326,325,325,325,329,330,330,331,334,334
  343.                 },60
  344.         },
  345.         {
  346.                 SSSDT,L"NtUserMessageCall",ProxyNtUserMessageCall,
  347.                 {
  348.                         1023,444,460,459,479,479,479,490,490,504,506,507,508,509,508,510,512,516,516,516,517
  349.                 },61
  350.         },
  351.         {
  352.                 SSSDT,L"NtUserPostMessage",ProxyNtUserPostMessage,
  353.                 {
  354.                         1023,459,475,474,497,497,497,508,508,486,488,489,490,491,490,492,494,498,498,498,499
  355.                 },62
  356.         },
  357.         {
  358.                 SSSDT,L"NtUserPostThreadMessage",ProxyNtUserPostThreadMessage,
  359.                 {
  360.                         1023,460,476,475,498,498,498,509,509,485,487,488,489,490,489,491,493,497,497,497,498
  361.                 },63
  362.         },
  363.         {
  364.                 SSSDT,L"NtUserBuildHwndList_WIN8",ProxyNtUserBuildHwndList_WIN8,
  365.                 {
  366.                         1023,1023,1023,1023,1023,1023,1023,1023,1023,358,359,360,360,360,360,362,363,367,367,367,367
  367.                 },64
  368.         },
  369.         {
  370.                 SSDT,L"ZwFsControlFile",ProxyZwFsControlFile,
  371.                 {
  372.                         1023,1023,84,1023,150,150,150,134,134,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023
  373.                 },65
  374.         },
  375.         {
  376.                 SSSDT,L"NtUserSetImeInfoEx",ProxyNtUserSetImeInfoEx,
  377.                 {
  378.                         1023,1023,517,1023,1023,1023,1023,550,550,1023,1023,1023,1023,1023,600,603,605,611,612,613,1023
  379.                 },66
  380.         },
  381.         {
  382.                 SSDT,L"ZwCreateProcessEx",ProxyZwCreateProcessEx,
  383.                 {
  384.                         1023,1023,48,50,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023
  385.                 },72
  386.         },
  387.         {
  388.                 SSSDT,L"NtUserGetRawInputData",ProxyNtUserGetRawInputData,
  389.                 {
  390.                         1023,1023,428,1023,1023,1023,1023,448,448,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023
  391.                 },67
  392.         },
  393.         {
  394.                 SSSDT,L"NtUserGetRawInputBuffer",ProxyNtUserGetRawInputBuffer,
  395.                 {
  396.                         1023,1023,427,1023,1023,1023,1023,447,447,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023
  397.                 },68
  398.         },
  399.         {
  400.                 SSSDT,L"NtUserGetAsyncKeyState",ProxyNtUserGetAsyncKeyState,
  401.                 {
  402.                         1023,1023,383,1023,1023,1023,1023,402,402,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023
  403.                 },69
  404.         },
  405.         {
  406.                 SSSDT,L"NtUserGetKeyState",ProxyNtUserGetKeyState,
  407.                 {
  408.                         1023,1023,416,1023,1023,1023,1023,436,436,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023
  409.                 },70
  410.         },
  411.         {
  412.                 SSSDT,L"NtUserGetKeyboardState",ProxyNtUserGetKeyboardState,
  413.                 {
  414.                         1023,1023,414,1023,1023,1023,1023,434,434,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023
  415.                 },71
  416.         },
  417.         {
  418.                 SSDT,L"ZwQueueApcThread",ProxyZwQueueApcThread,
  419.                 {
  420.                         1023,1023,180,1023,1023,1023,1023,269,269,1023,1023,1023,1023,1023,139,142,143,143,144,144,144
  421.                 },74
  422.         },
  423.         {
  424.                 SSDT,L"ZwSetSecurityObject",ProxyZwSetSecurityObject,
  425.                 {
  426.                         1023,1023,237,1023,1023,1023,1023,347,347,1023,1023,1023,1023,1023,59,60,61,61,61,61,61
  427.                 },75
  428.         },
  429.         {
  430.                 SSDT,L"ZwOpenFile",ProxyZwOpenFile,
  431.                 {
  432.                         1023,1023,116,1023,1023,1023,1023,179,179,1023,1023,1023,1023,1023,232,235,236,236,237,238,238
  433.                 },76
  434.         },
  435.         {
  436.                 SSDT,L"ZwQueueApcThreadEx",ProxyZwQueueApcThreadEx,
  437.                 {
  438.                         1023,1023,1023,1023,1023,1023,1023,270,270,1023,1023,1023,1023,1023,138,141,142,142,143,143,143
  439.                 },77
  440.         },
  441.         {
  442.                 SSDT,L"ZwCreateMutant",ProxyZwCreateMutant,
  443.                 {
  444.                         1023,1023,43,45,67,67,67,74,74,1023,1023,1023,1023,1023,346,350,351,351,352,355,355
  445.                 },78
  446.         },
  447.         {
  448.                 SSDT,L"ZwQuerySystemInformation",ProxyZwQuerySystemInformation,
  449.                 {
  450.                         1023,1023,173,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023
  451.                 },79
  452.         },
  453.         {
  454.                 SSDT,L"ZwQueryIntervalProfile",ProxyZwQueryIntervalProfile,
  455.                 {
  456.                         1023,1023,158,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023
  457.                 },80
  458.         },
  459.         {
  460.                 SSDT,L"ZwSetInformationProcess",ProxyZwSetInformationProcess,
  461.                 {
  462.                         1023,1023,228,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023
  463.                 },81
  464.         },
  465.         {
  466.                 SSSDT,L"NtGdiAddFontMemResourceEx",ProxyNtGdiAddFontMemResourceEx,
  467.                 {
  468.                         1023,1023,4,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023
  469.                 },82
  470.         },
  471.         {
  472.                 SSDT,L"ZwReplyWaitReceivePortEx",ProxyZwReplyWaitReceivePortEx,
  473.                 {
  474.                         1023,1023,196,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023
  475.                 },83
  476.         },
  477.         {
  478.                 END,L"KeUserModeCallback",ProxyKeUserModeCallback,
  479.                 {
  480.                         1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023
  481.                 },51
  482.         },
  483.         {
  484.                 SSDT,L"ZwOpenKey",ProxyZwOpenKey,
  485.                 {
  486.                         1023,1023,119,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023
  487.                 },84
  488.         },
  489.         {
  490.                 SSDT,L"ZwMapViewOfSection",ProxyZwMapViewOfSection,
  491.                 {
  492.                         1023,1023,108,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023
  493.                 },85
  494.         },
  495.         {
  496.                 SSDT,L"ZwSetIntervalProfile",ProxyZwSetIntervalProfile,
  497.                 {
  498.                         1023,1023,231,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023
  499.                 },86
  500.         },
  501.         {
  502.                 SSSDT,L"NtGdiAddFontResourceW",ProxyNtGdiAddFontResourceW,
  503.                 {
  504.                         1023,1023,2,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023
  505.                 },87
  506.         },
  507.         {
  508.                 SSSDT,L"NtGdiAddRemoteFontToDC",ProxyNtGdiAddRemoteFontToDC,
  509.                 {
  510.                         1023,1023,3,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023
  511.                 },88
  512.         },
  513.         {
  514.                 SSDT,L"ZwQueryInformationProcess",ProxyZwQueryInformationProcess,
  515.                 {
  516.                         1023,1023,154,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023
  517.                 },89
  518.         },
  519.         {
  520.                 SSDT,L"ZwQueryInformationThread",ProxyZwQueryInformationThread,
  521.                 {
  522.                         1023,1023,155,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023
  523.                 },90
  524.         },
  525.         {
  526.                 SSDT,L"ZwCreateProfile",ProxyZwCreateProfile,
  527.                 {
  528.                         1023,1023,49,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023
  529.                 },91
  530.         },
  531.         {
  532.                 SSDT,L"ZwVdmControl",ProxyZwVdmControl,
  533.                 {
  534.                         1023,1023,268,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023
  535.                 },92
  536.         },
  537.         {
  538.                 SSDT,L"ZwCreateProcess",ProxyZwCreateProcess,
  539.                 {
  540.                         1023,1023,47,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023
  541.                 },93
  542.         },
  543.         {
  544.                 SSSDT,L"NtGdiAddEmbFontToDC",ProxyNtGdiAddEmbFontToDC,
  545.                 {
  546.                         1023,1023,214,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023
  547.                 },94
  548.         },
  549.         {
  550.                 SSDT,L"NtDebugActiveProcess",ProxyNtDebugActiveProcess,
  551.                 {
  552.                         1023,1023,57,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023
  553.                 },95
  554.         },
  555.         {
  556.                 SSDT,L"NtAlpcCreatePort",ProxyNtAlpcCreatePort,
  557.                 {
  558.                         1023,1023,1023,1023,1023,1023,1023,23,23,1023,1023,1023,1023,1023,401,406,407,407,410,413,413
  559.                 },96
  560.         },
  561.         {
  562.                 SSDT,L"NtCreatePort",ProxyNtCreatePort,
  563.                 {
  564.                         1023,1023,46,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023
  565.                 },97
  566.         },
  567.         {
  568.                 SSDT,L"ZwAdjustPrivilegesToken",ProxyZwAdjustPrivilegesToken,
  569.                 {
  570.                         1023,1023,11,1023,1023,1023,1023,12,12,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023
  571.                 },98
  572.         },
  573.         {
  574.                 SSDT,L"ZwConnectPort",ProxyZwConnectPort,
  575.                 {
  576.                         1023,1023,31,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023
  577.                 },99
  578.         },
  579.         {
  580.                 SSDT,L"ZwSecureConnectPort",ProxyZwSecureConnectPort,
  581.                 {
  582.                         1023,1023,210,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023
  583.                 },100
  584.         },
  585.         {
  586.                 SSDT,L"ZwQueryKey",ProxyZwQueryKey,
  587.                 {
  588.                         1023,1023,160,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023
  589.                 },101
  590.         },
  591.         {
  592.                 SSDT,L"ZwEnumerateKey",ProxyZwEnumerateKey,
  593.                 {
  594.                         1023,1023,71,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023
  595.                 },102
  596.         },
  597.         {
  598.                 SSDT,L"ZwClose",ProxyZwClose,
  599.                 {
  600.                         1023,1023,25,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023
  601.                 },103
  602.         },
  603.         {
  604.                 SSSDT,L"NtUserSystemParametersInfo",ProxyNtUserSystemParametersInfo,
  605.                 {
  606.                         1023,1023,559,1023,1023,1023,1023,559,595,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023
  607.                 },104
  608.         },
  609.         {
  610.                 END,NULL,NULL,
  611.                 {
  612.                         -1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  613.                 },105
  614.         }
  615. };
复制代码
回复 赞! 靠!

使用道具 举报

 楼主| 发表于 2015-10-2 15:19:23 | 显示全部楼层
1.6 Proxy*函数模型
  1. NPAGED_LOOKASIDE_LIST FilterLookAside;
  2. BOOLEAN g_EvaluateTime;
  3. //Proxy*函数模型  3参数函数为例
  4. NTSTATUS __stdcall ProxyNtFunc(int param1,int param2,int param3)
  5. {
  6.         NTSTATUS status = STATUS_ACCESS_DENIED;
  7.         ULONG Result;//自定义结果
  8.         ULONGLONG Time = 0;
  9.         DProxy* proxydata = DProxyTable[ENtFunc];
  10.         FilterPacket* packet = ExAllocateFromNPagedLookasideList(&FilterLookAside);
  11.         if(g_EvaluateTime)
  12.                 Time = KeQueryInterruptTime();
  13.         if(!packet)
  14.         {
  15.                 if(!proxydata->OriginFuncAddr)
  16.                         return status;
  17.                 return proxydata->OriginFuncAddr(param1,param2,param3);
  18.         }
  19.         packet->Params[0] = param1;
  20.         packet->Params[1] = param2;
  21.         packet->Params[2] = param3;
  22.         packet->ParamNumber = 3;
  23.         packet->OriginFuncAddr = proxydata->OriginFuncAddr;
  24.         packet->IndexInTable = ENtFunc;
  25.         InterlockedIncrement(&proxydata->PrevFilterRefCount);
  26.         Result = ExecPrevFilter(packet,proxydata);//Prev过滤
  27.         InterlockedDecrement(&proxydata->PrevFilterRefCount);
  28.         if(Result == SYSMON_UNHANDLED)
  29.         {
  30.                 if(packet->OriginFuncAddr)
  31.                 {
  32.                         status = packet->OriginFuncAddr(param1,param2,param3);
  33.                         packet->Status = status;
  34.                         InterlockedIncrement(&proxydata->PostFilterRefCount);
  35.                         Result = ExecPostFilter(packet);//Post过滤
  36.                         InterlockedDecrement(&proxydata->PostFilterRefCount);
  37.                 }
  38.         }
  39.         if(Result == SYSMON_HANDLED)
  40.         {
  41.                 status = packet->Status;
  42.         }
  43.         if(g_EvaluateTime)
  44.                 EvaluateTime(proxydata,Time);
  45.         ExDeleteNPagedLookasideList(packet);
  46.         return status;
  47. }

  48. ULONG ExecPrevFilter(FilterPacket* packet,DProxy* proxydata)
  49. {
  50.         ULONG Result;
  51.         if(!proxydata || !packet || packet->DisablePrevFilter)
  52.                 return SYSMON_UNHANDLED;
  53.         for(int i=0;i<16;i++)
  54.         {
  55.                 if(!proxydata->PrevFilterSlot[i].DeleteCount && proxydata->PrevFilterSlot[i].Filter && proxydata->SlotNum != 0)
  56.                 {
  57.                         InterlockedIncrement(&proxydata->PrevFilterSlot[i].CallCount);
  58.                         packet->CurrentSlot = i;
  59.                         Result = proxydata->PrevFilterSlot[i].Filter(packet);
  60.                         InterlockedDecrement(&proxydata->PrevFilterSlot[i].CallCount);
  61.                         if(packet->Access & 0x10)//如果权限被设置为放行
  62.                         {
  63.                                 TsLogSprintfOutput(SysMonLogPt,"[Sysnap DbgLog] Modify--> TableIndex %d, Process %s[%d] ",
  64.                                         proxydata->TableIndex,PsGetProcessImageFileName(IoGetCurrentProcess()),PsGetCurrentProcessId());
  65.                         }
  66.                         switch(Result)
  67.                         {
  68.                         case SYSMON_FORBID:
  69.                                 TsLogSprintfOutput(SysMonLogPt,"[Sysnap DbgLog] Block--> TableIndex %d, Process %s[%d] ",
  70.                                         proxydata->TableIndex,PsGetProcessImageFileName(IoGetCurrentProcess()),PsGetCurrentProcessId());
  71.                                 return SYSMON_FORBID;
  72.                         case SYSMON_HANDLED:
  73.                                 return SYSMON_HANDLED;
  74.                         case SYSMON_PASS:
  75.                         case SYSMON_PASS1:
  76.                                 return SYSMON_UNHANDLED;
  77.                         default:
  78.                                 break;
  79.                         }
  80.                 }
  81.         }
  82. }

  83. ULONG ExecPostFilter(FilterPacket* packet)
  84. {
  85.         ULONG Result;
  86.         if(!packet)
  87.                 return SYSMON_UNHANDLED;
  88.         FILTER_SLOT* CurrentSlot = DProxyTable[packet->IndexInTable]->PrevFilterSlot;
  89.         for(int i=0;i<16;i++)
  90.         {
  91.                 if(!CurrentSlot [i].DeleteCount)
  92.                 {
  93.                         InterlockedIncrement(&CurrentSlot [i].CallCount);
  94.                         packet->CurrentSlot = i;
  95.                         Result = packet->PostFilterSlot(packet);
  96.                         InterlockedDecrement(&CurrentSlot [i].CallCount);
  97.                 }
  98.                 switch(Result)
  99.                 {
  100.                 case SYSMON_HANDLED:
  101.                         return SYSMON_HANDLED;
  102.                 case SYSMON_PASS:
  103.                 case SYSMON_PASS1:
  104.                 case SYSMON_FORBID:
  105.                         return SYSMON_UNHANDLED;
  106.                 default:
  107.                         break;
  108.                 }
  109.         }
  110. }
复制代码

二、        驱动接口Interface
2.1 DeviceExtension接口
DeviceObject->DeviceExtension结构:
+00h        TAG=’TSFL’
+14h        FARPROC Interface
FARPROC Interface(intindex)

  1. NTSTATUS Interface(int index,FARPROC* outfunc)
  2. {//注意下面的函数都是自己实现的穿透函数
  3.         If(!outfunc)
  4.                 Return STATUS_UNSUCCESSFUL;
  5.     switch(index)
  6.     {
  7.     case 0:
  8. *outfunc = SetEvaluateTime;
  9.                 Break;
  10.     case 1:
  11. *outfunc = AddDisablePrevFilter;
  12.                 Break;
  13.     case 2:
  14. *outfunc = SetPostFilter;
  15.                 Break;
  16.     case 3:
  17. *outfunc = ExecOriginFromPacket;
  18.                 Break;
  19.     case 4:
  20. *outfunc = AddPrevFilter;
  21.                 Break;
  22.     case 5:
  23. *outfunc = RemovePrevFilter;
  24.                 Break;
  25.     case 6:
  26. *outfunc = GetCurrentHookInfo;
  27.                 Break;
  28.     case 7:
  29. *outfunc = GetDProxyTable;
  30.                 Break;
  31. default:
  32.                 *outfunc = NULL;
  33.                 Break;
  34. }
  35. Return STATUS_SUCESS;
  36. }
复制代码

2.2 SetEvaluateTime
Void __stdcall SetEvaluateTime(bool EvaluateTime)
{//设置计算过滤函数执行耗时
        g_EvaluateTime = EvaluateTime;
}

2.3 AddDisablePrevFilter
Void __stdcall AddDisablePrevFilter(ULONG Index,BOOLEAN Disable)
{//设置是否执行PrevFilter(同时也是PostFilter)
        If(Index < APINUMBER)
{
        If(DProxyTable[Index])
                DProxyTable[Index]-> DisablePrevFilter = Disable;
}
}

2.4 SetPostFilter
Void __stdcall SetPostFilter(FilterPacket* Packet,FARPROC Filter,ULONG Tag)
{//设置PostFilter函数
        If(Packet)
{
        Packet->TagSlot[Packet->CurrentSlot] = Tag;//用于修改参数或区分Filter
        Packet->PostFilterSlot[Packet->CurrentSlot] = Filter;
        Packet->SlotCount++;
}
}

2.5 ExecOriginFromPacket
NTSTATUS __stdcall ExecOriginFromPacket(FilterPacket* Packet)
{//执行Nt*原始函数
        If(!Packet || !Packet->OriginFuncAddr)
                Return STATUS_UNSUCCESSFUL;
        _asm
        {
                Mov eax, Packet->ParamNumber
                Test eax,eax
                Jbe tag1
                Lea ecx,[eax-1]
                Test ecx,ecx
                Jl tag1
                Lea edx,Packet->Params[ecx]//参数逐个压栈
Tag1:
                Mov eax,[edx]
                Push eax
                Sub ecx,1
                Sub edx,4
                Test ecx,ecx
                Jge tag2
Tag2:
                Call Packet->OriginFuncAddr
        }
}

2.6 AddPrevFilter
NTSTATUS __stdcall AddPrevFilter(ULONG Index,FARPROC Filter,ULONG Tag,ULONG PreferSlot,PULONG OutSlot)
{
        /*
                Index :Nt函数在全局表DProxyTable中的索引
                Filter:要设置的过滤函数
                Tag:标志过滤函数(可用于保存参数)
                PreferSlot:优先选用的函数槽
                OutSlot:实际选用的函数槽
*/
        if(!Filter || Index >= APINUMBER || PreferSlot >= 16)
                return STATUS_UNSUCCESSFUL;
        if(!DProxyTable[Index] || !DProxyTable[Index]->IsInitialized)
                return STATUS_UNSUCCESSFUL;
        if(DProxyTable[Index]->PrevFilterSlot[PreferSlot].Filter)
        {//若函数槽已被占用
                for(int i=0;i<16;i++)
                {
                        if(!DProxyTable[Index]->PrevFilterSlot.Filter)
                        {
                                DProxyTable[Index]->PrevFilterSlot.Tag = Tag;
                                InterlockedExchange(&DProxyTable[Index]->PrevFilterSlot.Filter,Filter);
                                InterlockedIncrement(&DProxyTable[Index]->UsedSlotCount);
                                if(OutSlot)
                                        *OutSlot = i;
                                return STATUS_SUCCESS;
                        }
                }
        }
        else
        {
                DProxyTable[Index]->PrevFilterSlot.Tag = Tag;
                InterlockedExchange(&DProxyTable[Index]->PrevFilterSlot.Filter,Filter);
                InterlockedIncrement(&DProxyTable[Index]->UsedSlotCount);
                if(OutSlot)
                        *OutSlot = i;
                return STATUS_SUCCESS;
        }
        return STATUS_UNSUCCESSFUL;
}

2.7 RemovePrevFilter
void WaitStop(FILTER_SLOT* CurrentSlot)
{
        KeInitializeTimer(&CurrentSlot->Timer);
        Li.QuadPart = 1000000;
        while(CurrentSlot->CallCount)
        {
                KeSetTimer(&CurrentSlot->Timer,&Li,NULL);
                KeWaitForSingleObject(&CurrentSlot->Timer,Executive,KernelMode,FALSE,NULL);
        }
        KeCancelTimer(&CurrentSlot->Timer);
}

NTSTATUS __fastcall RemovePrevFilter(ULONG Index,FARPROC Filter)
{//从Index对应的函数过滤中查找删除Filter
        if(!Filter || Index >= APINUMBER)
                return STATUS_UNSUCCESSFUL;
        if(!DProxyTable[Index] || !DProxyTable[Index]->IsInitialized)
                return STATUS_UNSUCCESSFUL;
        for(int i=0;i<16;i++)
        {
                if(DProxyTable[Index]->PrevFilterSlot.Filter == Filter)
                {
                        LARGE_INTEGER Li;
                        FILTER_SLOT* CurrentSlot = &DProxyTable[Index]->PrevFilterSlot;
                        CurrentSlot->DeleteCount = FALSE;
                        InterlockedIncrement(&CurrentSlot->DeleteCount);
                        WaitStop(CurrentSlot);
                        InterlockedExchange(&CurrentSlot->Filter,NULL);
                        InterlockedDecrement(&DProxyTable[Index]->UsedSlotCount);
                        WaitStop(CurrentSlot);
                        InterlockedDecrement(&CurrentSlot->DeleteCount);
                        return STATUS_UNSUCCESSFUL;
                }
        }
        return STATUS_UNSUCCESSFUL;
}

2.8 GetCurrentHookInfo
NTSTATUS __stdcall GetCurrentHookInfo(PULONG pLastErrorCode,PULONG pserHookType,PULONG pOsVer,PULONG pHookErrorIndex)
{
        if(OsVer && !LastErrorCode && HookErrorIndex == -1)
        {
                if(pLastErrorCode)
                        *pLastErrorCode = 0;//获取系统buildnumber
                if(pserHookType)
                        *pserHookType = serHookType;
                if(pOsVer)
                        *pOsVer = OsVer;
                if(pHookErrorIndex)
                        *pHookErrorIndex = HookErrorIndex;
        }
        return STATUS_UNSUCCESSFUL;
}

LastErrorCode
0x01        ZwQuerySystemInformation获取失败
0x02        KeServiceDescriptorTable获取失败
0x04        KeAddSystemServiceTable获取失败
0x08        ShadowSSDT获取失败
0x10        MmUserProbeAddress获取失败
0x20        Int2E校验失败

InitState
0x01        ZwQuerySystemInformation获取成功
0x02        KeServiceDescriptorTable获取成功
0x04        ShadowSSDT获取成功
0x08        获取Inline Hook点成功

serHookType 对KiFastCallEntry做inline hook的类型
0.        Nonhook                        HOOKTYPE_NONE
1.        Inlinehook                        HOOKTYPE_INLINE
2.        SSDTHook                        HOOKTYPE_SSDT
3.        金山共存Inlinehook        HOOKTYPE_KSINLINE

OsVer
BuildNumber:
Win2000
2195                1
WinXp
2600                2
WinServer2003
3790                3
WinVista
6000                4
6001                5
6002                6
Win7
7600                7
7601                8
Win8
8102                9
8250                10
8400                11
8432                12
8441                12
8520                13
Win8.1
9200                14
9600                15
Win10
9841                16
9860                17
9926                18
10041        19
10049        20
?? 0

HookErrorIndex
        -1

IsBsod
        记录蓝屏

2.9 GetDProxyTable
Dproxy** GetDProxyTable()
{
        Return DProxyTable;
}

五、        基础库
5.1 获取注册表键值
  1. NTSTATUS GetRegDataWithType(PWCHAR RegPath,PWCHAR KeyName,PVOID OutData,ULONG BufSize,PULONG OutType)
  2. {
  3.         NTSTATUS status;
  4.         HANDLE KeyHandle = NULL;
  5.         ULONG ResultLength = 0;
  6.         OBJECT_ATTRIBUTES Oa;
  7.         UNICODE_STRING URegPath,UKeyName;
  8.         PVOID ValueInfo;
  9.         const int BufSize = sizeof(PKEY_VALUE_PARTIAL_INFORMATION) + sizeof(WCHAR[260]);
  10.         if(!RegPath || !KeyName)
  11.                 return STATUS_INVALID_PARAMETER;
  12.         InitializeObjectAttributes(&Oa,&URegPath,OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,NULL,NULL);
  13.         status = ZwOpenKey(&KeyHandle,KEY_EXECUTE,&Oa);
  14.         ValueInfo = ExAllocatePool(NonPagedPool,BufSize);
  15.         if(NT_SUCCESS(status) && ValueInfo)
  16.         {
  17.                 RtlZeroMemory(ValueInfo,BufSize);
  18.                 RtlInitUnicodeString(&UKeyName,KeyName);
  19.                 status = ZwQueryValueKey(KeyHandle,&UKeyName,KeyValuePartialInformation,ValueInfo,BufSize,&ResultLength);
  20.                 if(NT_SUCCESS(status))
  21.                 {
  22.                         PKEY_VALUE_PARTIAL_INFORMATION Info = (PKEY_VALUE_PARTIAL_INFORMATION)ValueInfo;
  23.                         if(OutType)
  24.                                 *OutType = Info->Type;
  25.                         if(OutData)
  26.                                 RtlCopyMemory(OutData,Info->Data,BufSize<Info->DataLength?BufSize:Info->DataLength);
  27.                 }
  28.         }
  29.         if(KeyHandle)
  30.                 ZwClose(KeyHandle);
  31.         if(ValueInfo)
  32.                 ExFreePool(ValueInfo);
  33.         return status;
  34. }

  35. NTSTATUS GetRegDataWithSize(PWCHAR RegPath,PWCHAR KeyName,PVOID OutData,ULONG BufSize,PULONG OutSize)
  36. {
  37.         NTSTATUS status;
  38.         HANDLE KeyHandle = NULL;
  39.         ULONG ResultLength = 0;
  40.         OBJECT_ATTRIBUTES Oa;
  41.         UNICODE_STRING URegPath,UKeyName;
  42.         PVOID ValueInfo;
  43.         const int BufSize = sizeof(PKEY_VALUE_PARTIAL_INFORMATION) + sizeof(WCHAR[260]);
  44.         if(!RegPath || !KeyName)
  45.                 return STATUS_INVALID_PARAMETER;
  46.         InitializeObjectAttributes(&Oa,&URegPath,OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,NULL,NULL);
  47.         status = ZwOpenKey(&KeyHandle,KEY_EXECUTE,&Oa);
  48.         ValueInfo = ExAllocatePool(NonPagedPool,BufSize);
  49.         if(NT_SUCCESS(status) && ValueInfo)
  50.         {
  51.                 RtlZeroMemory(ValueInfo,BufSize);
  52.                 RtlInitUnicodeString(&UKeyName,KeyName);
  53.                 status = ZwQueryValueKey(KeyHandle,&UKeyName,KeyValuePartialInformation,ValueInfo,BufSize,&ResultLength);
  54.                 if(NT_SUCCESS(status))
  55.                 {
  56.                         PKEY_VALUE_PARTIAL_INFORMATION Info = (PKEY_VALUE_PARTIAL_INFORMATION)ValueInfo;
  57.                         if(OutSize)
  58.                                 *OutSize = Info->DataLength;
  59.                         if(OutData)
  60.                                 RtlCopyMemory(OutData,Info->Data,BufSize<Info->DataLength?BufSize:Info->DataLength);
  61.                 }
  62.         }
  63.         if(KeyHandle)
  64.                 ZwClose(KeyHandle);
  65.         if(ValueInfo)
  66.                 ExFreePool(ValueInfo);
  67.         return status;
  68. }

  69. NTSTATUS GetRegDataWithSizeAndType(PWCHAR RegPath,PWCHAR KeyName,PVOID OutData,ULONG BufSize,PULONG OutSize,PULONG OutType)
  70. {
  71.         NTSTATUS status;
  72.         HANDLE KeyHandle = NULL;
  73.         ULONG ResultLength = 0;
  74.         OBJECT_ATTRIBUTES Oa;
  75.         UNICODE_STRING URegPath,UKeyName;
  76.         PVOID ValueInfo;
  77.         const int BufSize = sizeof(PKEY_VALUE_PARTIAL_INFORMATION) + sizeof(WCHAR[260]);
  78.         if(!RegPath || !KeyName)
  79.                 return STATUS_INVALID_PARAMETER;
  80.         InitializeObjectAttributes(&Oa,&URegPath,OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,NULL,NULL);
  81.         status = ZwOpenKey(&KeyHandle,KEY_EXECUTE,&Oa);
  82.         ValueInfo = ExAllocatePool(NonPagedPool,BufSize);
  83.         if(NT_SUCCESS(status) && ValueInfo)
  84.         {
  85.                 RtlZeroMemory(ValueInfo,BufSize);
  86.                 RtlInitUnicodeString(&UKeyName,KeyName);
  87.                 status = ZwQueryValueKey(KeyHandle,&UKeyName,KeyValuePartialInformation,ValueInfo,BufSize,&ResultLength);
  88.                 if(NT_SUCCESS(status))
  89.                 {
  90.                         PKEY_VALUE_PARTIAL_INFORMATION Info = (PKEY_VALUE_PARTIAL_INFORMATION)ValueInfo;
  91.                         if(OutSize)
  92.                                 *OutSize = Info->DataLength;
  93.                         if(OutType)
  94.                                 *OutType = Info->Type;
  95.                         if(OutData)
  96.                                 RtlCopyMemory(OutData,Info->Data,BufSize<Info->DataLength?BufSize:Info->DataLength);
  97.                 }
  98.         }
  99.         if(KeyHandle)
  100.                 ZwClose(KeyHandle);
  101.         if(ValueInfo)
  102.                 ExFreePool(ValueInfo);
  103.         return status;
  104. }
复制代码


5.2 通过进程名获取进程ID
  1. HANDLE GetProcessIdByName(PWCHAR ProcessName)
  2. {//根据进程名获取进程ID
  3.         HANDLE ProcessId = 0;
  4.         NTSTATUS status = STATUS_SUCCESS;
  5.         SIZE_T size = 512;
  6.         UNICODE_STRING UProcessName;
  7.         LPVOID Buffer;
  8.         RtlInitUnicodeString(&UProcessName,ProcessName);
  9.         while(true)
  10.         {
  11.                 Buffer = ExAllocatePool(PagedPool,size);
  12.                 if(!Buffer)
  13.                         return 0;
  14.                 status = ZwQuerySystemInformation(SystemProcessesAndThreadsInformation,Buffer,size,NULL);
  15.                 if(status != STATUS_INFO_LENGTH_MISMATCH)
  16.                         break;
  17.                 ExFreePool(Buffer);
  18.                 size *= 2;
  19.         }
  20.         if(!NT_SUCCESS(Buffer))
  21.                 ExFreePool(Buffer);
  22.         PSYSTEM_PROCESS_INFORMATION ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)Buffer;
  23.         while(ProcessInfo->NextEntryOffset)
  24.         {
  25.                 ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)((UCHAR*)ProcessInfo + ProcessInfo->NextEntryOffset);
  26.                 if(RtlEqualUnicodeString(&UProcessName,&ProcessInfo->ImageName,TRUE)
  27.                         ProcessId = ProcessInfo->UniqueProcessId;
  28.         }
  29.         ExFreePool(Buffer);
  30.         return ProcessId;
  31. }
复制代码




回复 赞! 靠!

使用道具 举报

 楼主| 发表于 2015-10-2 15:21:07 | 显示全部楼层
六、        InlineHook KiFastCallEntry
①        重置蓝屏死机计数  用于检测hook造成的蓝屏
②        获取SSDT/SSSDT/ hook点
③        分配跳转表ServiceMapTable
④        改写KiFastCallEntry使跳转表生效
⑤        Hook重要回调
⑥        开启日志记录
⑦        Hook KeUserModeCallback


6.1 获取SSDT/SSSDT/Hook点
ULONG InitState = 0;
ULONG LastErrorCode = 0;


  1. UCHAR int2Ecode1[10] = {0x8B, 0xFC, 0x3B, 0x35, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x83};
  2. UCHAR int2Ecode2[22] = {0x8B, 0xFC, 0xF6, 0x45, 0x72, 0x02, 0x75, 0x06, 0xF6, 0x45, 0x6C,
  3.                                                 0x01, 0x74, 0x0C, 0x3B, 0x35, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x83};

  4. ULONG GetHookPoint1()
  5. {//检测系统原始KiFastCallEntry
  6.         *(ULONG*)(int2Ecode2 + 4) = MmUserProbeAddress;//构造cmp esi,dword ptr ds:[MmUserProbeAddress]
  7.         if(!MmUserProbeAddress)
  8.                 return 0;
  9.         ULONG ptr = GetKiSystemServiceAddr();//KiFastCallEntry总在KiSystemService之后
  10.         if(ptr < NtosBase || ptr > NtosBase+NtosSize)
  11.                 return 0;
  12.         for(int offset = 0;offset < 1024;offset++,ptr++)
  13.         {
  14.                 /*
  15.                         mov edi,esp
  16.                         cmp esi,dword ptr ds:[MmUserProbeAddress]
  17.                         jae ??
  18.                 */
  19.                 if(RtlCompareMemory(ptr,int2Ecode1,sizeof(int2Ecode1)) == sizeof(int2Ecode1))
  20.                         return ptr;
  21.         }
  22.         return 0;
  23. }

  24. ULONG GetHookPoint2()
  25. {//检测是否被金山inline hook过得KiFastCallEntry
  26.         *(ULONG*)(int2Ecode2 + 16) = MmUserProbeAddress;//构造cmp esi,dword ptr ds:[MmUserProbeAddress]
  27.         if(!MmUserProbeAddress)
  28.                 return 0;
  29.         ULONG ptr = GetKiSystemServiceAddr();
  30.         if(ptr < NtosBase || ptr > NtosBase+NtosSize)
  31.                 return 0;
  32.         for(int offset = 0;offset < 1024;offset++,ptr++)
  33.         {
  34.                 /*
  35.                         mov edi,esp
  36.                         test byte ptr[ebp+72h],2
  37.                         jne $1
  38.                         test byte ptr[ebp+6Ch],1
  39.                         je ??
  40.                         $1:
  41.                         cmp esi,dword ptr ds:[MmUserProbeAddress]
  42.                         jae ??
  43.                 */
  44.                 if(RtlCompareMemory(ptr,int2Ecode2,sizeof(int2Ecode2)) == sizeof(int2Ecode2))
  45.                         return ptr;
  46.         }
  47.         return 0;
  48. }

  49. ULONG InitState = 0,LastErrorCode = 0,serHookType = 0;
  50. ULONG NtosBase,NtosSize,SSDTBase,SSDTLimit,ShadowSSDTBase,ShadowSSDTLimit,Win32kBase,Win32kSize;
  51. ULONG dwcsrssId;
  52. ULONG BuildIndex;
  53. PKSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTable;
  54. ULONG MmUserProbeAddress;

  55. struct HOOKINFO
  56. {
  57.         ULONG InlinePoint;
  58.         ULONG JmpBackPoint;
  59.         UCHAR OriginCode[8];
  60. };

  61. HOOKINFO HookInfo1={0},HookInfo2={0};
  62. /*
  63. KiFastCallEntry+0xde:
  64.         mov     ebx,dword ptr [edi+eax*4]
  65.         jmp     81f9e3e0
  66.         nop                                                                                                =>        InlinePoint
  67.         nop
  68.         nop
  69.         jmp     TsFltMgr+0x2300 (f8517300)
  70.         jae     nt!KiSystemCallExit2+0x9f (8053e7ec)        =>        JmpBackPoint
  71.         rep movs dword ptr es:[edi],dword ptr [esi]
  72.         call    ebx

  73.         OriginCode[8];
  74.         8bfc            mov     edi,esp
  75.         3b35549a5580    cmp     esi,dword ptr [nt!MmUserProbeAddress]
  76. */
  77. NTSTATUS PrepareHook()
  78. {
  79.         RTL_PROCESS_MODULE_INFORMATION Win32kInfo,NtosInfo;
  80.         NTSTATUS status = STATUS_UNSUCCESSFUL;
  81.         ULONG ReturnLength = 0;
  82.         ULONG OutData;
  83.         LPVOID Buffer = NULL;
  84.         RtlZeroMemory(&Win32kInfo,sizeof(Win32kInfo));
  85.         RtlZeroMemory(&NtosInfo,sizeof(NtosInfo));
  86.         InitState = 0;
  87.         LastErrorCode = 0;
  88.         status = GetRegDataWithType(L"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\TsFltMgr",
  89.                 L"thm", &OutData, 4, 0)
  90.         if(NT_SUCCESS(status) && OutData == 1)
  91.                 serHookType = HOOKTYPE_SSDT;
  92.         ZwQuerySystemInformation(SystemModuleInformation,&ReturnLength,0,&ReturnLength);
  93.         if(ReturnLength)
  94.                 Buffer = ExAllocatePool(PagedPool,ReturnLength);
  95.         if(Buffer)
  96.                 status = ZwQuerySystemInformation(SystemModuleInformation,Buffer,ReturnLength,NULL);
  97.         if(!NT_SUCCESS(status))
  98.         {
  99.                 ExFreePool(Buffer);
  100.                 Buffer = NULL;
  101.         }
  102.         if(Buffer)
  103.         {
  104.                 RtlCopyMemory(&NtosInfo,((PRTL_PROCESS_MODULES)Buffer)->Modules,sizeof(NtosInfo));
  105.                 ExFreePool(Buffer);
  106.                 NtosBase = NtosInfo.ImageBase;
  107.                 NtosSize = NtosInfo.ImageSize;
  108.                 ULONG FuncAddr = MiLocateExportName(NtosBase,"KeServiceDescriptorTable");
  109.                 if(FuncAddr && MmIsAddressValid(FuncAddr))
  110.                 {
  111.                         PKSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTable = (PKSERVICE_TABLE_DESCRIPTOR)FuncAddr;
  112.                         SSDTBase = KeServiceDescriptorTable[0].Base;
  113.                         SSDTLimit = KeServiceDescriptorTable[0].Limit;
  114.                         InitState |= 2;
  115.                         dwcsrssId = GetProcessIdByName(L"csrss.exe");
  116.                         if(GetProcessInfoByFileName("WIN32K.SYS",&Win32kInfo))
  117.                         {
  118.                                 Win32kBase = Win32kInfo.ImageBase;
  119.                                 Win32kSize = Win32kInfo.ImageSize;
  120.                                 if(NT_SUCCESS(GetShadowSSDTInfo()))
  121.                                         InitState |= 4;
  122.                         }
  123.                        
  124.                         UNICODE_STRING UMmUserProbeAddress;
  125.                         RtlInitUnicodeString(&UMmUserProbeAddress,L"MmUserProbeAddress");
  126.                         ULONG MmUserProbeAddress = MmGetSystemRoutineAddress(&UMmUserProbeAddress);
  127.                         if(MmUserProbeAddress && MmIsAddressValid(MmUserProbeAddress))
  128.                         {
  129.                                 HookInfo1.InlinePoint = GetHookPoint1();
  130.                                 if(HookInfo1.InlinePoint)
  131.                                         HookInfo1.JmpBackPoint = HookInfo1.InlinePoint + 8;
  132.                                 else
  133.                                 {
  134.                                         HookInfo2.InlinePoint = GetHookPoint2();
  135.                                         if(HookInfo2.InlinePoint)
  136.                                                 HookInfo2.JmpBackPoint = HookInfo2.InlinePoint + 6;
  137.                                 }
  138.                                 if(HookInfo1.InlinePoint == 0 && HookInfo2.InlinePoint == 0)
  139.                                 {
  140.                                         LastErrorCode |= 0x20;
  141.                                         return status;
  142.                                 }
  143.                                 InitState |= 8;
  144.                                 MmUserProbeAddress = *(ULONG*)MmUserProbeAddress;
  145.                                 status = STATUS_SUCCESS;
  146.                         }
  147.                         else
  148.                         {
  149.                                 LastErrorCode |= 0x10;
  150.                         }
  151.                 }
  152.                 else
  153.                 {
  154.                         LastErrorCode |= 2;
  155.                 }
  156.         }
  157.         else
  158.         {
  159.                 LastErrorCode |= 1;
  160.         }
  161.         return status;
  162. }
复制代码

6.2 从KiSystemService获取KiFastCallEntry
struct IDTR
{
        USHORT IDTLimit;
        PKIDTENTRY IDTBase;
};
ULONG GetKiSystemServiceAddr()
{
        IDTR idt = {0};
        RTL_PROCESS_MODULE_INFORMATION NtosInfo,Win32kInfo;
        RtlZeroMemory(&NtosInfo,sizeof(NtosInfo));
        __sidt(&idt);
        if(idt.IDTBase)
        {
                KIDTENTRY int2e = idt.IDTBase[0x2E];
                if(MmIsAddressValid(int2e))
                        return MAKEULONG(int2e.ExtendedOffset,int2e.Offset);
        }
        return 0;
}

6.3 获取SSSDT信息
  1. NTSTATUS GetShadowSSDTInfo()
  2. {
  3.         NTSTATUS status = STATUS_UNSUCCESSFUL;
  4.         PVOID pt = MiLocateExportName(NtosBase, "KeAddSystemServiceTable");
  5.         PMDL mdl = NULL;
  6.         if(pt && !MmIsAddressValid(pt))
  7.         {//页换出
  8.                 mdl = MmCreateMdl(NULL,pt,0x1000);
  9.                 if(mdl)
  10.                 {
  11.                         MmProbeAndLockPages(mdl,KernelMode,IoReadAccess);
  12.                 }
  13.         }
  14.         if(!pt || !MmIsAddressValid(pt))
  15.         {
  16.                 LastErrorCode |= 4;
  17.                 goto END;
  18.         }

  19.         switch(BuildIndex)
  20.         {
  21.         case WIN2000:
  22.         case WINXP:
  23.         case WINXPSP3:
  24.         case WINVISTA:
  25.         case WINVISTASP1:
  26.         case WINVISTASP2:
  27.         case WIN7:
  28.         case WIN7SP1:
  29.                 for(int i=0;i<256;i++)
  30.                 {
  31.                         if(MmIsAddressValid(pt) && *(USHORT*)pt == 0x888D)
  32.                         {//8d88603f5580    lea     ecx,nt!KeServiceDescriptorTableShadow
  33.                                 PKSERVICE_TABLE_DESCRIPTOR Table = *(ULONG*)(pt+2);
  34.                                 ShadowSSDTBase = Table[1].Base;
  35.                                 ShadowSSDTLimit = Table[1].Limit;
  36.                                 status = STATUS_SUCCESS;
  37.                         }
  38.                 }
  39.                 break;
  40.         case WIN8_8102:
  41.         case WIN8_8250:
  42.         case WIN81_9200:
  43.         case WIN81_9600:
  44.                 for(int i=0;i<256;i++)
  45.                 {
  46.                         if(MmIsAddressValid(pt) && *(USHORT*)pt == 0xB983)
  47.                         {//83b9603f558083  cmp     dword ptr nt!KeServiceDescriptorTableShadow
  48.                                 PKSERVICE_TABLE_DESCRIPTOR Table = *(ULONG*)(pt+2);
  49.                                 if(KeServiceDescriptorTable == Table)
  50.                                 {
  51.                                         ShadowSSDTBase = Table[1].Base;
  52.                                         ShadowSSDTLimit = Table[1].Limit;
  53.                                         status = STATUS_SUCCESS;
  54.                                 }
  55.                         }
  56.                 }
  57.                 break;
  58.         case WIN10_9841:
  59.         case WIN10_9860:
  60.         case WIN10_9926:
  61.         case WIN10_10041:
  62.         case WIN10_10049:
  63.                 for(int i=0;i<256;i++)
  64.                 {
  65.                         if(MmIsAddressValid(pt) && *(USHORT*)pt == 0x3D83)
  66.                         {//833d90d28d8100  cmp     dword ptr [nt!KeServiceDescriptorTableShadow+0x10],0
  67.                                 PKSERVICE_TABLE_DESCRIPTOR Table = *(ULONG*)(pt+2) - 16;
  68.                                 if(KeServiceDescriptorTable == Table)
  69.                                 {
  70.                                         ShadowSSDTBase = Table[1].Base;
  71.                                         ShadowSSDTLimit = Table[1].Limit;
  72.                                         status = STATUS_SUCCESS;
  73.                                 }
  74.                         }
  75.                 }
  76.                 break;
  77.         }
  78.         if(!ShadowSSDTBase)
  79.                 LastErrorCode |= 8;
  80. END:
  81.         if(mdl)
  82.         {
  83.                 MmUnlockPages(mdl);
  84.                 IoFreeMdl(mdl);
  85.         }
  86. }
复制代码


6.4 初始化InlineHook KiFastCallEntry跳转表
  1. BOOLEAN InitProxyTable()
  2. {
  3.         ULONG BuildIndex = GetBuildNumberAsIndex();
  4.         for(int i = 0;i < APINUMBER;i++)
  5.         {
  6.                 for(int j = 0;j < BUILDMAX;j++)
  7.                 {
  8.                         if(SProxyTable[i].ServiceIndex[j] == 0)
  9.                                 SProxyTable[i].ServiceIndex[j] = 1023;//置为无效
  10.                 }
  11.         }
  12.         if(GetServiceIndex("ZwCreateKey") == -1)
  13.         {//不能获取到服务号
  14.                 if(NtosBase)
  15.                 {
  16.                         for(int i = 0;i < APINUMBER;i++)
  17.                         {
  18.                                 if(SProxyTable[i].ServiceTableType == END)
  19.                                         break;
  20.                                 else if(SProxyTable[i].ServiceTableType == SSDT)
  21.                                 {
  22.                                         if(SProxyTable[i].ApiName)
  23.                                         {
  24.                                                 UNICODE_STRING UApiName;
  25.                                                 ANSI_STRING AApiName;
  26.                                                 RtlInitUnicodeString(&UApiName,SProxyTable[i].ApiName);
  27.                                                 if(NT_SUCCESS(RtlUnicodeStringToAnsiString(&AApiName,&UApiName,TRUE)))
  28.                                                 {
  29.                                                         GetServiceIndexFromNtos(AApiName.Buffer);
  30.                                                         RtlFreeAnsiString(AApiName);
  31.                                                 }
  32.                                         }                               
  33.                                 }
  34.                         }
  35.                 }
  36.         }
  37.         else
  38.         {//能获取到服务号   由于SProxyTable已存服务号,所以下面代码本身无效
  39.                 for(int i = 0;i < APINUMBER;i++)
  40.                 {
  41.                         if(SProxyTable[i].ServiceTableType == END)
  42.                                 break;
  43.                         if(SProxyTable[i].ServiceTableType == SSDT)
  44.                         {
  45.                                 if(SProxyTable[i].ApiName)
  46.                                 {
  47.                                         UNICODE_STRING UApiName;
  48.                                         ANSI_STRING AApiName;
  49.                                         RtlInitUnicodeString(&UApiName,SProxyTable[i].ApiName);
  50.                                         if(NT_SUCCESS(RtlUnicodeStringToAnsiString(&AApiName,&UApiName,TRUE)))
  51.                                         {
  52.                                                 ULONG Index = GetServiceIndexFromNtdll(AApiName.Buffer);
  53.                                                 if(Index != -1)
  54.                                                         SProxyTable[i].ServiceIndex[BuildIndex] = Index;
  55.                                                 RtlFreeAnsiString(AApiName);
  56.                                         }
  57.                                 }
  58.                         }
  59.                 }
  60.         }
  61.         return TRUE;
  62. }

  63. int AllocHookTable()
  64. {//已知系统情况下初始化代理表,直接使用ServiceIndex
  65.         ULONG BuildIndex = GetBuildNumberAsIndex();
  66.         DProxy* Proxydata = NULL;
  67.         ULONG Count = 0;//未成功布置的代理函数个数
  68.         if(BuildIndex >= 0 && BuildIndex < BUILDMAX)
  69.         {
  70.                 InitProxyTable();
  71.                 for(int i=0;i<APINUMBER;i++)
  72.                 {
  73.                         if(SProxyTable[i].ServiceTableType == END)
  74.                                 break;
  75.                         if(SProxyTable[i].ServiceIndex[BuildIndex] != 1023)
  76.                         {
  77.                                 if(SProxyTable[i].ApiName && SProxyTable[i].ProxyFunc && SProxyTable[i].IndexInTable < APINUMBER)
  78.                                 {
  79.                                         Proxydata = (DProxy*)ExAllocatePool(NonPagedPool,sizeof(DProxy));
  80.                                         if(Proxydata)
  81.                                         {
  82.                                                 Proxydata->IsInitialized = FALSE;
  83.                                                 Proxydata->ApiName = SProxyTable[i].ApiName;
  84.                                                 Proxydata->TableIndex = SProxyTable[i].IndexInTable;
  85.                                                 Proxydata->ProxyFuncAddr = SProxyTable[i].ProxyFunc;
  86.                                                 Proxydata->ServiceIndex = -1;
  87.                                                 KeInitializeEvent(Proxydata->Lock,SynchronizationEvent,FALSE);
  88.                                                 DProxyTable[SProxyTable[i].IndexInTable] = Proxydata;
  89.                                                 ULONG ServiceType = SProxyTable[i].ServiceTableType;
  90.                                                 ULONG ServiceIndex = SProxyTable[i].ServiceIndex[BuildIndex];
  91.                                                 if(ServiceType >= 2 ||  ServiceIndex== -1 || ServiceIndex >= 1024)
  92.                                                 {
  93.                                                         Count++;
  94.                                                 }
  95.                                                 else
  96.                                                 {
  97.                                                         ServiceMapTable[ServiceType][ServiceIndex] = Proxydata;
  98.                                                         Proxydata->ServiceTableType = ServiceType;
  99.                                                         Proxydata->ServiceIndex = ServiceIndex;
  100.                                                 }
  101.                                         }
  102.                                 }
  103.                         }
  104.                 }
  105.                 return Count;
  106.         }
  107.         return APINUMBER;//返回未成功代理的个数
  108. }

  109. int AllocHookTableU()
  110. {//未知系统情况下初始化代理表,临时从Ntos模块获取ServiceIndex
  111.        
  112.         if(!NtosBase)
  113.                 return 0;//返回成功布置代理的个数
  114.         for(int i=0;i<APINUMBER;i++)
  115.         {
  116.                 if(SProxyTable[i].ServiceTableType == END)
  117.                         break;
  118.                 else if(SProxyTable[i].ServiceTableType == SSDT)
  119.                 {
  120.                         if(SProxyTable[i].ApiName)
  121.                         {
  122.                                 PUNICODE_STRING UApiName;
  123.                                 ANSI_STRING AApiName;
  124.                                 ULONG Index = -1;
  125.                                 RtlInitUnicodeString(&UApiName,SProxyTable[i].ApiName);
  126.                                 if(NT_SUCCESS(RtlUnicodeStringToAnsiString(&AApiName,&UApiName,TRUE)))
  127.                                 {
  128.                                         Index = GetServiceIndexFromNtos(AApiName.Buffer);
  129.                                         RtlFreeAnsiString(&AApiName);
  130.                                 }
  131.                                 if(Index != -1)
  132.                                 {
  133.                                         if(SProxyTable[i].ApiName && SProxyTable[i].ProxyFunc && SProxyTable[i].IndexInTable < APINUMBER)
  134.                                         {
  135.                                                 Proxydata = (DProxy*)ExAllocatePool(NonPagedPool,sizeof(DProxy));
  136.                                                 if(Proxydata)
  137.                                                 {
  138.                                                         Proxydata->IsInitialized = FALSE;
  139.                                                         Proxydata->ApiName = SProxyTable[i].ApiName;
  140.                                                         Proxydata->TableIndex = SProxyTable[i].IndexInTable;
  141.                                                         Proxydata->ProxyFuncAddr = SProxyTable[i].ProxyFunc;
  142.                                                         Proxydata->ServiceIndex = -1;
  143.                                                         KeInitializeEvent(Proxydata->Lock,SynchronizationEvent,FALSE);
  144.                                                         DProxyTable[SProxyTable[i].IndexInTable] = Proxydata;
  145.                                                         ULONG ServiceType = SProxyTable[i].ServiceTableType;
  146.                                                         ULONG ServiceIndex = SProxyTable[i].ServiceIndex[BuildIndex];
  147.                                                         if(ServiceType >= 2 ||  ServiceIndex== -1 || ServiceIndex >= 1024)
  148.                                                         {
  149.                                                                 Count++;
  150.                                                                 ServiceMapTable[ServiceType][ServiceIndex] = Proxydata;
  151.                                                                 Proxydata->ServiceTableType = ServiceType;
  152.                                                                 Proxydata->ServiceIndex = ServiceIndex;
  153.                                                         }
  154.                                                 }
  155.                                         }
  156.                                 }
  157.                         }
  158.                 }
  159.         }
  160.         return Count;
  161. }

复制代码
6.5 获取系统服务号的2种方式
  1. ULONG GetServiceIndexFromNtdll(PCHAR ApiName)
  2. {
  3.         ULONG result = -1;
  4.         RTL_PROCESS_MODULE_INFORMATION ProcessInfo;
  5.         ULONG Index;
  6.         RtlZeroMemory(&ProcessInfo,sizeof(ProcessInfo));
  7.         if(GetProcessInfoByFileName("ntdll.dll",&ProcessInfo) && ProcessInfo.ImageBase && ApiName)
  8.         {
  9.                 Index = MiLocateExportName(ProcessInfo.ImageBase,ApiName);
  10.                 if(Index)
  11.                 {
  12.                         result = *(ULONG*)(Index+1);
  13.                 }
  14.         }
  15.         return result;
  16. }

  17. ULONG GetServiceIndexFromNtos(PCHAR ApiName)
  18. {
  19.         ULONG result = -1;
  20.         ULONG Index = MiLocateExportName(ProcessInfo.ImageBase,ApiName);
  21.         if(Index)
  22.         {
  23.                 result = *(ULONG*)(Index+1);
  24.         }
  25.         if(Index & 0xFFFFC000)
  26.         {
  27.                 result = -1;
  28.         }
  29.         return result;
  30. }

复制代码
6.6 InlineHook过程
  1. NTSTATUS DoInlineHook()
  2. {
  3.         NTSTATUS status = STATUS_UNSUCCESSFUL;
  4.         ULONG MajorVersion = 0,MinorVersion = 0,BuildNumber = 0;
  5.         PsGetVersion(&MajorVersion,&MinorVersion,&BuildNumber,NULL);
  6.         if(serHookType == HOOKTYPE_SSDT || !(InitState & 8))//外部hook或没找到hook挂载点
  7.                 return status;
  8.         if(HookInfo1.InlinePoint)
  9.         {//如果为默认方式hook
  10.                 if(GetBuildNumberAsIndex() >= WINVISTA)
  11.                         status = ModifyAndHook(HookInfo1.InlinePoint,InlineKiFastCallEntry1);
  12.                 else
  13.                         status = ModifyAndHook(HookInfo1.InlinePoint,InlineKiFastCallEntry2);
  14.                 if(NT_SUCCESS(status))
  15.                         serHookType = HOOKTYPE_INLINE;
  16.         }
  17.         else if(HookInfo2.InlinePoint)
  18.         {//如果为金山共存方式hook
  19.                 if(GetBuildNumberAsIndex() >= WINVISTA)
  20.                         status = ModifyAndHookK(HookInfo2.InlinePoint,InlineKiFastCallEntry3);
  21.                 else
  22.                         status = ModifyAndHookK(HookInfo2.InlinePoint,InlineKiFastCallEntry4);
  23.                 if(NT_SUCCESS(status))
  24.                         serHookType = HOOKTYPE_KSINLINE;
  25.         }
  26.         if(NT_SUCCESS(status))
  27.         {
  28.                 for(int i=0;i<APINUMBER;i++)
  29.                 {
  30.                         if(DProxyTable[i] != 0 && (DProxyTable[i]->ServiceTableType == SSDT || DProxyTable[i]->ServiceTableType == SSSDT))
  31.                                 DProxyTable[i]->IsInitialized = TRUE;
  32.                 }
  33.         }
  34. }

  35. NTSTATUS DoInlineHookU()
  36. {
  37.         NTSTATUS status = STATUS_UNSUCCESSFUL;
  38.         ULONG MajorVersion = 0,MinorVersion = 0,BuildNumber = 0;
  39.         PsGetVersion(&MajorVersion,&MinorVersion,&BuildNumber,NULL);
  40.         if(serHookType == HOOKTYPE_SSDT || !(InitState & 8))//采用外部hook或没找到hook挂载点
  41.                 return status;
  42.         if(HookInfo1.InlinePoint)
  43.         {//如果为默认方式hook
  44.                 if(GetBuildNumberAsIndex() >= WINVISTA)
  45.                         status = ModifyAndHook(HookInfo1.InlinePoint,InlineKiFastCallEntry1);
  46.                 else
  47.                         status = ModifyAndHook(HookInfo1.InlinePoint,InlineKiFastCallEntry2);
  48.                 if(NT_SUCCESS(status))
  49.                         serHookType = HOOKTYPE_INLINE;
  50.         }
  51.         else if(HookInfo2.InlinePoint)
  52.         {//如果为金山共存方式hook
  53.                 if(GetBuildNumberAsIndex() >= WINVISTA)
  54.                         status = ModifyAndHookK(HookInfo2.InlinePoint,InlineKiFastCallEntry3);
  55.                 else
  56.                         status = ModifyAndHookK(HookInfo2.InlinePoint,InlineKiFastCallEntry4);
  57.                 if(NT_SUCCESS(status))
  58.                         serHookType = HOOKTYPE_KSINLINE;
  59.         }
  60.         if(NT_SUCCESS(status))
  61.         {
  62.                 for(int i=0;i<APINUMBER;i++)
  63.                 {
  64.                         if(DProxyTable[i] != 0 && (DProxyTable[i]->ServiceTableType == SSDT || DProxyTable[i]->ServiceTableType == SSSDT))
  65.                                 DProxyTable[i]->IsInitialized = TRUE;
  66.                 }
  67.         }
  68. }

  69. NTSTATUS ModifyAndHook(ULONG InlinePoint,FARPROC JmpToFunc)
  70. {//HOOKTYPE_INLINE 更改KiFastCallEntry
  71.         NTSTATUS status;
  72.         PVOID MappedAddress = NULL;
  73.         if(!InlinePoint || !InlineHookFunc)
  74.                 return STATUS_UNSUCCESSFUL;
  75.         PMDL mdl = GetWritablePage(InlinePoint,16,&MappedAddress);
  76.         /*
  77.                 改写                                                为
  78.                 mov edi,esp                                                nop
  79.                 cmp esp,dword ptr ds:[?]                nop
  80.                                                                                 nop
  81.                                                                                 jmp ?
  82.         */
  83.         if(!mdl)
  84.                 return STATUS_UNSUCCESSFUL;
  85.         ULONG data[3] = {InlinePoint,JmpToFunc,MappedAddress};
  86.         status = MakeJmp(data,DoHook);
  87.         MmUnlockPages(mdl);
  88.         IoFreeMdl(mdl);
  89.         return status;
  90. }

  91. NTSTATUS ModifyAndHookK(ULONG InlinePoint,FARPROC JmpToFunc)
  92. {//HOOKTYPE_KSINLINE 更改KiFastCallEntry
  93.         NTSTATUS status;
  94.         PVOID MappedAddress = NULL;
  95.         if(!InlinePoint || !InlineHookFunc)
  96.                 return STATUS_UNSUCCESSFUL;
  97.         PMDL mdl = GetWritablePage(InlinePoint,16,&MappedAddress);
  98.         if(!mdl)
  99.                 return STATUS_UNSUCCESSFUL;
  100.         ULONG data[3] = {InlinePoint,JmpToFunc,MappedAddress};
  101.         status = MakeJmp(data,DoHookK);
  102.         MmUnlockPages(mdl);
  103.         IoFreeMdl(mdl);
  104.         return status;
  105. }

  106. NTSTATUS DoHook(ULONG* data)
  107. {//HOOKTYPE_INLINE
  108.         ULONGLONG shellcode;
  109.         if(!data)
  110.                 return STATUS_UNSUCCESSFUL;
  111.         *(ULONGLONG*)(HookInfo1.OriginCode) = *(ULONGLONG*)data[0];//保存原始8字节
  112.         *(ULONG*)((UCHAR*)&shellcode+4) = data[1] - data[0] - 8;//填写偏移 jmp offset
  113.         *(ULONG*)((UCHAR*)&shellcode) = 0xE9909090;//写入新8字节
  114.         /*
  115.                 构造
  116.                 nop
  117.                 nop
  118.                 nop
  119.                 jmp ????
  120.         */
  121.         InterlockedCompareExchange64((LONGLONG*)data[2],shellcode,*(LONGLONG*)data[2]);
  122.         return STATUS_SUCCESS;
  123. }

  124. NTSTATUS DoHookK(ULONG* data)
  125. {//HOOKTYPE_KSINLINE
  126.         ULONGLONG shellcode;
  127.         if(!data)
  128.                 return STATUS_UNSUCCESSFUL;
  129.         *(ULONGLONG*)(HookInfo1.OriginCode) = *(ULONGLONG*)data[0];//保存原始8字节
  130.         *(USHORT*)((UCHAR*)&shellcode+6) = 0x0675;
  131.         *(ULONG*)((UCHAR*)&shellcode+2) = data[1] - data[0] - 8;//填写偏移 jmp offset
  132.         *(ULONG*)((UCHAR*)&shellcode) = 0xE990;//写入新8字节
  133.         InterlockedCompareExchange64((LONGLONG*)data[2],shellcode,*(LONGLONG*)data[2]);
  134.         return STATUS_SUCCESS;
  135. }

  136. PMDL GetWritablePage(PVOID VirtualAddress,ULONG Length,PVOID* pMappedAddress)
  137. {
  138.         PMDL mdl = IoAllocateMdl(VirtualAddress,Length,FALSE,TRUE,NULL);
  139.         if(mdl)
  140.         {
  141.                 MmProbeAndLockPages(mdl,KernelMode,IoWriteAccess);
  142.                 PVOID NewAddr = MmGetSystemAddressForMdlSafe (Mdl, NormalPagePriority);
  143.                 if(!NewAddr)
  144.                 {
  145.                         MmUnlockPages(mdl);
  146.                         IoFreeMdl(mdl);
  147.                         mdl = NULL;
  148.                 }
  149.                 if(NewAddr)
  150.                         *pMappedAddress = NewAddr;
  151.         }
  152.         return mdl;
  153. }
复制代码
回复 赞! 靠!

使用道具 举报

 楼主| 发表于 2015-10-2 15:22:49 | 显示全部楼层
6.7 构造InlineHook跳转后的执行语句
  1. ULONG Filter(ULONG ServiceIndex,ULONG OriginFunc,ULONG Base)
  2. {
  3.         if(ServiceIndex >= 1024)
  4.                 return OriginFunc;
  5.         ULONG TableType;
  6.         if(Base == SSDTBase && ServiceIndex <= SSDTLimit)
  7.         {
  8.                 TableType = SSDT;
  9.         }
  10.         else if(KeServiceDescriptorTable && KeServiceDescriptorTable->Base == Base && ServiceIndex <= SSDTLimit)
  11.         {
  12.                 TableType = SSDT;
  13.         }
  14.         else if(Base == ShadowSSDTBase && ServiceIndex <= ShadowSSDTLimit)
  15.         {
  16.                 TableType = SSSDT;
  17.         }
  18.         else
  19.         {
  20.                 return OriginFunc;
  21.         }
  22.         if(ServiceMapTable[TableType][ServiceIndex])
  23.         {
  24.                 ULONG NewAddr = ServiceMapTable[TableType][ServiceIndex]->ProxyFuncAddr;
  25.                 if(NewAddr)
  26.                 {
  27.                         ServiceMapTable[TableType][ServiceIndex]->OriginFuncAddr = OriginFunc;
  28.                         return NewAddr;
  29.                 }
  30.         }
  31.         return OriginFunc;
  32. }

  33. void __declspec(naked) InlineKiFastCallEntry1()
  34. {
  35.         /*  HOOKTYPE_INLINE   >=VISTA
  36.                 输入
  37.                 eax=ServiceIndex
  38.                 edx=OriginFunc
  39.                 edi=SSDTBase
  40.                 输出
  41.                 edx=FuncAddr  最终函数调用地址
  42.         */
  43.         _asm
  44.         {
  45.                 pushf;
  46.                 pusha;
  47.                 push edi;
  48.                 push edx;
  49.                 push eax;
  50.                 call Filter;
  51.                 mov [esp+0x14],eax;//改栈中的edx
  52.                 popa;
  53.                 popf;
  54.                 mov edi,esp;
  55.                 cmp esi,MmUserProbeAddress;
  56.                 push dword ptr HookInfo1.JmpBackPoint;
  57.                 retn;//跳回JmpBackPoint
  58.         }
  59. }

  60. void __declspec(naked) InlineKiFastCallEntry2()
  61. {
  62.         /*  HOOKTYPE_INLINE   <VISTA
  63.                 输入
  64.                 eax=ServiceIndex
  65.                 edx=OriginFunc
  66.                 edi=SSDTBase
  67.                 输出
  68.                 ebx=FuncAddr  最终函数调用地址
  69.         */
  70.         _asm
  71.         {
  72.                 pushf;
  73.                 pusha;
  74.                 push edi;
  75.                 push edx;
  76.                 push eax;
  77.                 call Filter;
  78.                 mov [esp+0x10],eax;//改栈中的ebx
  79.                 popa;
  80.                 popf;
  81.                 mov edi,esp;
  82.                 cmp esi,MmUserProbeAddress;
  83.                 push dword ptr HookInfo1.JmpBackPoint;
  84.                 retn;
  85.         }
  86. }

  87. void __declspec(naked) InlineKiFastCallEntry3()
  88. {
  89.         /*  HOOKTYPE_KSINLINE   <VISTA
  90.                 输入
  91.                 eax=ServiceIndex
  92.                 edx=OriginFunc
  93.                 edi=SSDTBase
  94.                 输出
  95.                 edx=FuncAddr  最终函数调用地址    (KiFastCallEntry后面mov ebx,edx)
  96.         */
  97.         _asm
  98.         {
  99.                 pushf;
  100.                 pusha;
  101.                 push edi;
  102.                 push edx;
  103.                 push eax;
  104.                 call Filter;
  105.                 mov [esp+0x14],eax;//改栈中的edx
  106.                 popa;
  107.                 popf;
  108.                 mov edi,esp;
  109.                 test byte ptr [ebp+0x72],2;
  110.                 push dword ptr HookInfo2.JmpBackPoint;
  111.                 retn;//跳回JmpBackPoint
  112.         }
  113. }

  114. void __declspec(naked) InlineKiFastCallEntry4()
  115. {
  116.         /*  HOOKTYPE_KSINLINE   <VISTA
  117.                 输入
  118.                 eax=ServiceIndex
  119.                 edx=OriginFunc
  120.                 edi=SSDTBase
  121.                 输出
  122.                 ebx=FuncAddr  最终函数调用地址
  123.         */
  124.         _asm
  125.         {
  126.                 pushf;
  127.                 pusha;
  128.                 push edi;
  129.                 push edx;
  130.                 push eax;
  131.                 call Filter;
  132.                 mov [esp+0x14],eax;//改栈中的edx
  133.                 popa;
  134.                 popf;
  135.                 mov edi,esp;
  136.                 test byte ptr [ebp+0x72],2;
  137.                 push dword ptr HookInfo2.JmpBackPoint;
  138.                 retn;//跳回JmpBackPoint
  139.         }
  140. }
复制代码

6.8 强制单核互斥执行指定Procedure
  1. struct SpinData
  2. {
  3.         KSPIN_LOCK SpinLock;
  4.         ULONG SpinRefCount;
  5. }g_Spin = {0};
  6. KDPC Dpc[32];

  7. void DpcRoutine(PKDPC Dpc,PVOID DeferredContext,PVOID SystemArgument1,PVOID SystemArgument2)
  8. {
  9.         KIRQL OldIrql;
  10.         SpinData* spin = (SpinData*)DeferredContext;zh
  11.         _disable();
  12.         OldIrql = KeRaiseIrqlToDpcLevel();
  13.         InterlockedIncrement(spin->SpinRefCount);
  14.         KeAcquireSpinLockAtDpcLevel(spin->SpinLock);
  15.         KeReleaseSpinLockFromDpcLevel(spin->SpinLock);
  16.         KeLowerIrql(OldIrql);
  17.         _enable();
  18. }

  19. NTSTATUS MakeJmp(ULONG* data,FARPROC addr)
  20. {
  21.         NTSTATUS status = STATUS_UNSUCCESSFUL;
  22.         ULONG ulCurrentCpu = 0;
  23.         KIRQL OldIrql,NewIrql;
  24.         KAFFINITY CpuAffinity;
  25.         if(!addr)
  26.                 return status;
  27.         CpuAffinity = KeQueryActiveProcessors();
  28.         for(int i = 0;i < 32;i++)
  29.         {
  30.                 if((CpuAffinity >> i) & 1)
  31.                         ulCurrentCpu++;
  32.         }
  33.         if(ulCurrentCpu == 1)//单核
  34.         {
  35.                 _disable();
  36.                 OldIrql = KeRaiseIrqlToDpcLevel();
  37.                 status = addr(data);
  38.                 KeLowerIrql(OldIrql);
  39.                 _enable();
  40.         }
  41.         else//多核  将除当前cpu以外的cpu用自旋锁锁住
  42.         {
  43.                 SpinData* pSpinData = &g_Spin;
  44.                 ULONG ulNumberOfActiveCpu = 0;
  45.                 KeInitializeSpinLock(&g_Spin.SpinLock);
  46.                 for(int i = 0;i < 32;i++)
  47.                 {
  48.                         KeInitializeDpc(&Dpc[i],DpcRoutine,&pSpinData);
  49.                 }
  50.                 pSpinData->SpinRefCount = 0;
  51.                 _disable();
  52.                 NewIrql = KeAcquireSpinLock(&g_Spin.SpinLock);
  53.                 ulCurrentCpu = KeGetCurrentProcessorNumber();
  54.                 for(int i = 0;i < 32;i++)
  55.                 {
  56.                         if((CpuAffinity >> i) & 1)
  57.                                 ulNumberOfActiveCpu++;
  58.                         if(i != ulCurrentCpu)
  59.                         {
  60.                                 KeSetTargetProcessorDpc(Dpc[i],i);
  61.                                 KeSetImportanceDpc(Dpc[i],HighImportance);
  62.                                 KeInsertQueueDpc(Dpc[i],NULL,NULL);
  63.                         }
  64.                         KeInitializeDpc(&Dpc[i],DpcRoutine,&pSpinData);
  65.                 }
  66.                 //此时只有一个核在工作
  67.                 for(int i = 0;i < 16;i++)//尝试16次
  68.                 {
  69.                         for(int count = 1000000;count > 0;count--);//延时
  70.                         if(g_Spin.SpinRefCount == ulNumberOfActiveCpu - 1)//等待DpcRoutine全部执行到死锁
  71.                         {
  72.                                 status = addr(data);
  73.                                 break;
  74.                         }
  75.                 }
  76.                 KeReleaseSpinLock(&g_Spin.SpinLock,NewIrql);//恢复多核运行
  77.                 _enable();
  78.         }
  79.         return status;
  80. }
复制代码

6.9 进行SSDT hook
        在注册表Services\\TsFltMgr thm=1的情况下,或者Inline hook KiFastCallEntry失败的情况下,会进行SSDT表 hook
  1. NTSTATUS BeginSSDTHook()
  2. {
  3.         NTSTATUS status = STATUS_UNSUCCESSFUL;
  4.         int result = -1;
  5.         PVOID MappedAddress = NULL;
  6.         PMDL mdl = NULL;
  7.         if(serHookType == HOOKTYPE_INLINE || serHookType == HOOKTYPE_KSINLINE)//已成功inline hook
  8.                 return STATUS_UNSUCCESSFUL;
  9.         serHookType = HOOKTYPE_SSDT;
  10.         for(int i = 0;i <= APINUMBER;i++)
  11.         {
  12.                 if(DProxyTable[i] && DProxyTable[i]->ServiceIndex != -1 && !DProxyTable[i]->IsInitialized)
  13.                 {
  14.                         if(DProxyTable[i]->ServiceTableType == SSDT)
  15.                         {
  16.                                 int index = DProxyTable[i]->ServiceIndex;
  17.                                 if(index != 1023 && DProxyTable[i]->ProxyFunc && SSDTBase)
  18.                                 {
  19.                                         PVOID MappedAddress = NULL;
  20.                                         PMDL mdl = GetWritablePage(SSDTBase,4*SSDTLimit,&MappedAddress);
  21.                                         if(mdl)
  22.                                         {
  23.                                                 DProxyTable[i]->OriginFuncAddr = ((ULONG*)SSDTBase)[index];
  24.                                                 ((ULONG*)MappedAddress)[index] = DProxyTable[i]->ProxyFunc;
  25.                                                 MmUnlockPages(mdl);
  26.                                                 IoFreeMdl(mdl);
  27.                                                 result = index;
  28.                                         }
  29.                                 }
  30.                         }
  31.                         else if(DProxyTable[i]->ServiceTableType == SSSDT)
  32.                         {
  33.                                 int index = DProxyTable[i]->ServiceIndex;
  34.                                 if(index != 1023 && DProxyTable[i]->ProxyFunc && ShadowSSDTBase)
  35.                                 {
  36.                                         HANDLE CurProcessId = PsGetCurrentProcessId();
  37.                                         HANDLE SmssProcessId = GetProcessIdByName(L"smss.exe");
  38.                                         if(!dwcsrssId)//如果没有获取到csrss.exe的id
  39.                                         {
  40.                                                 if(CurProcessId == SmssProcessId)//使用smss.exe的SSSDT
  41.                                                 {
  42.                                                         mdl = GetWritablePage(ShadowSSDTBase,4*ShadowSSDTLimit,&MappedAddress);
  43.                                                         if(mdl)
  44.                                                         {
  45.                                                                 DProxyTable[i]->OriginFuncAddr = ((ULONG*)ShadowSSDTBase)[index];
  46.                                                                 ((ULONG*)MappedAddress)[index] = DProxyTable[i]->ProxyFunc;
  47.                                                                 MmUnlockPages(mdl);
  48.                                                                 IoFreeMdl(mdl);
  49.                                                                 result = index;
  50.                                                         }
  51.                                                 }
  52.                                         }
  53.                                         else
  54.                                         {//附加到csrss.exe
  55.                                                 PVOID attachobj = AttachDriverToProcess(dwcsrssId);
  56.                                                 if(attachobj)
  57.                                                 {
  58.                                                         mdl = GetWritablePage(ShadowSSDTBase,4*ShadowSSDTLimit,&MappedAddress);
  59.                                                         if(mdl)
  60.                                                         {
  61.                                                                 DProxyTable[i]->OriginFuncAddr = ((ULONG*)ShadowSSDTBase)[index];
  62.                                                                 ((ULONG*)MappedAddress)[index] = DProxyTable[i]->ProxyFunc;
  63.                                                                 MmUnlockPages(mdl);
  64.                                                                 IoFreeMdl(mdl);
  65.                                                                 result = index;
  66.                                                         }
  67.                                                         DetachDriverFromProcess(attachobj);
  68.                                                 }
  69.                                         }
  70.                                 }       
  71.                         }
  72.                         if(result != -1)
  73.                                 DProxyTable[i]->IsInitialized = TRUE;
  74.                 }
  75.         }
  76.         return STATUS_SUCCESS;
  77. }

  78. struct AttachData
  79. {
  80.         KAPC_STATE ApcState;
  81.         PVOID Process;
  82. };

  83. PVOID AttachDriverToProcess(HANDLE ProcessId)
  84. {
  85.         PVOID Process = NULL;
  86.         AttachData* Buffer = NULL;
  87.         if(ProcessId == PsGetCurrentProcessId())
  88.                 return 0xEEEEDDDD;//自身标识
  89.         if(ProcessId && NT_SUCCESS(PsLookupProcessByProcessId(ProcessId,&Process)))
  90.         {
  91.                 Buffer = (AttachData*)ExAllocatePool(PagedPool,sizeof(AttachData));
  92.                 if(!Buffer)
  93.                 {
  94.                         ObDereferenceObject(Process);
  95.                         return NULL;
  96.                 }
  97.                 Buffer->Process = Process;
  98.                 KeStackAttachProcess(Process,&Buffer->ApcState)
  99.         }
  100. }

  101. NTSTATUS DetachDriverFromProcess(PVOID Buffer)
  102. {
  103.         if(Buffer && (ULONG)Buffer != 0xEEEEDDDD)
  104.         {
  105.                 AttachData* data = (AttachData*)Buffer;
  106.                 KeUnstackDetachProcess(&data->ApcState);
  107.                 ObDereferenceObject(data->Process);
  108.                 ExFreePool(Buffer);
  109.         }
  110. }
复制代码


6.10 对重要回调(进程回调、线程回调、映像加载回调)的挂钩
  1. /*
  2.         Sproxy Index:
  3.         普通api使用index 0-0x33 0x37-0x48 0x4A-0x69
  4.         52    CreateNotifyRoutine
  5.         53    ThreadNofify
  6.         54    ImageNotify
  7.         73    CreateNotifyRoutine2
  8. */
  9. enum
  10. {
  11.         INDEX_KECALLBACK = 51,
  12.         INDEX_PROCESS = 52,
  13.         INDEX_THREAD = 53,
  14.         INDEX_IMAGE = 54,
  15.         INDEX_PROCESSEX = 73,
  16. };

  17. NTSTATUS HookImportantNotify()
  18. {
  19.         if(!DProxyTable[INDEX_PROCESS])
  20.         {
  21.                 DProxy* Proxydata = (DProxy*)ExAllocatePool(NonPagedPool,sizeof(DProxy));
  22.                 if(Proxydata)
  23.                 {
  24.                         Proxydata->IsInitialized = FALSE;
  25.                         Proxydata->ApiName = "ProcessNotify";
  26.                         Proxydata->TableIndex = INDEX_PROCESS;
  27.                         Proxydata->ProxyFuncAddr = CreateNotifyRoutine1;
  28.                         Proxydata->ServiceIndex = -1;
  29.                         KeInitializeEvent(&Proxydata->Lock,SynchronizationEvent,FALSE);
  30.                         DProxyTable[INDEX_PROCESS] = Proxydata;
  31.                 }
  32.         }
  33.         if(DProxyTable[INDEX_PROCESS] && !DProxyTable[INDEX_PROCESS]->IsInitialized)
  34.         {
  35.                 DProxyTable[INDEX_PROCESS]->ServiceTableType = CALLBACK;
  36.                 if(NT_SUCCESS(PsSetCreateProcessNotifyRoutine(CreateProcessNotify,FALSE)))
  37.                         DProxyTable[INDEX_PROCESS]->IsInitialized = TRUE;
  38.         }
  39.         if(!DProxyTable[INDEX_PROCESSEX])
  40.         {
  41.                 DProxy* Proxydata = (DProxy*)ExAllocatePool(NonPagedPool,sizeof(DProxy));
  42.                 if(Proxydata)
  43.                 {
  44.                         Proxydata->IsInitialized = FALSE;
  45.                         Proxydata->ApiName = "ProcessNotifyEx";
  46.                         Proxydata->TableIndex = INDEX_PROCESSEX;
  47.                         Proxydata->ProxyFuncAddr = CreateNotifyRoutine1Ex;
  48.                         Proxydata->ServiceIndex = -1;
  49.                         KeInitializeEvent(&Proxydata->Lock,SynchronizationEvent,FALSE);
  50.                         DProxyTable[INDEX_PROCESSEX] = Proxydata;
  51.                 }
  52.         }
  53.         if(DProxyTable[INDEX_PROCESSEX] && !DProxyTable[INDEX_PROCESSEX]->IsInitialized)
  54.         {
  55.                 DProxyTable[INDEX_PROCESSEX]->ServiceTableType = CALLBACK;
  56.                 if(NT_SUCCESS(PsSetCreateProcessNotifyRoutineEx(CreateProcessNotifyEx,FALSE)))
  57.                         DProxyTable[INDEX_PROCESSEX]->IsInitialized = TRUE;
  58.         }
  59.         if(!DProxyTable[INDEX_THREAD])
  60.         {
  61.                 DProxy* Proxydata = (DProxy*)ExAllocatePool(NonPagedPool,sizeof(DProxy));
  62.                 if(Proxydata)
  63.                 {
  64.                         Proxydata->IsInitialized = FALSE;
  65.                         Proxydata->ApiName = "ThreadNotify";
  66.                         Proxydata->TableIndex = INDEX_THREAD;
  67.                         Proxydata->ProxyFuncAddr = CreateThreadNotify;
  68.                         Proxydata->ServiceIndex = -1;
  69.                         KeInitializeEvent(&Proxydata->Lock,SynchronizationEvent,FALSE);
  70.                         DProxyTable[INDEX_THREAD] = Proxydata;
  71.                 }
  72.         }
  73.         if(DProxyTable[INDEX_THREAD] && !DProxyTable[INDEX_THREAD]->IsInitialized)
  74.         {
  75.                 DProxyTable[INDEX_THREAD]->ServiceTableType = CALLBACK;
  76.                 if(NT_SUCCESS(PsSetCreateThreadNotifyRoutine(CreateThreadNotify,FALSE)))
  77.                         DProxyTable[INDEX_THREAD]->IsInitialized = TRUE;
  78.         }
  79.         if(!DProxyTable[INDEX_IMAGE])
  80.         {
  81.                 DProxy* Proxydata = (DProxy*)ExAllocatePool(NonPagedPool,sizeof(DProxy));
  82.                 if(Proxydata)
  83.                 {
  84.                         Proxydata->IsInitialized = FALSE;
  85.                         Proxydata->ApiName = "ImageNotify";
  86.                         Proxydata->TableIndex = INDEX_IMAGE;
  87.                         Proxydata->ProxyFuncAddr = LoadImageNotify;
  88.                         Proxydata->ServiceIndex = -1;
  89.                         KeInitializeEvent(&Proxydata->Lock,SynchronizationEvent,FALSE);
  90.                         DProxyTable[INDEX_IMAGE] = Proxydata;
  91.                 }
  92.         }
  93.         if(DProxyTable[INDEX_IMAGE] && !DProxyTable[INDEX_IMAGE]->IsInitialized)
  94.         {
  95.                 DProxyTable[INDEX_IMAGE]->ServiceTableType = CALLBACK;
  96.                 if(NT_SUCCESS(PsSetLoadImageNotifyRoutine(LoadImageNotify,FALSE)))
  97.                         DProxyTable[INDEX_IMAGE]->IsInitialized = TRUE;
  98.         }
  99. }
复制代码

6.11 Hook KeUserModeCallback
  1. NTSTATUS HookKeUserModeCallback()
  2. {
  3.         NTSTATUS status = STATUS_UNSUCCESSFUL;
  4.         if(!Win32kBase)
  5.                 return status;
  6.         OBJECT_ATTRIBUTES Oa;
  7.         IO_STATUS_BLOCK IoStatusBlock;
  8.         HANDLE SectionHandle = NULL;
  9.         ULONG ViewSize = 0;
  10.         HANDLE FileHandle = NULL;
  11.         PVOID BaseAddress = 0x5000000;
  12.         UNICODE_STRING UKeUserModeCallback;
  13.         if(!DProxyTable[INDEX_KECALLBACK])
  14.         {
  15.                 DProxy* Proxydata = (DProxy*)ExAllocatePool(NonPagedPool,sizeof(DProxy));
  16.                 if(Proxydata)
  17.                 {
  18.                         Proxydata->IsInitialized = FALSE;
  19.                         Proxydata->ApiName = "ImageNotify";
  20.                         Proxydata->TableIndex = INDEX_KECALLBACK;
  21.                         Proxydata->ProxyFuncAddr = ProxyKeUserModeCallback;
  22.                         Proxydata->ServiceIndex = -1;
  23.                         KeInitializeEvent(&Proxydata->Lock,SynchronizationEvent,FALSE);
  24.                         DProxyTable[INDEX_KECALLBACK] = Proxydata;
  25.                 }
  26.         }
  27.         RtlInitUnicodeString(&UKeUserModeCallback,L"\\SystemRoot\\System32\\Win32k.sys");
  28.         InitializeObjectAttributes(&Oa,L"KeUserModeCallback",OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE,NULL,NULL);
  29.         status = ZwOpenFile(&FileHandle,GENERIC_READ,&Oa,&IoStatusBlock,FILE_SHARE_READ,FILE_SYNCHRONOUS_IO_NONALERT);
  30.         if(NT_SUCCESS(status))
  31.         {
  32.                 Oa.ObjectName = NULL;
  33.                 status = ZwCreateSection(&SectionHandle,SECTION_MAP_EXECUTE,&Oa,NULL,PAGE_WRITECOPY,SEC_IMAGE);
  34.                 if(NT_SUCCESS(status))
  35.                 {
  36.                         status = ZwMapViewOfSection(&SectionHandle,NtCurrentProcess(),&BaseAddress,0,0,NULL,&ViewSize,ViewUnmap,0,PAGE_EXECUTE);
  37.                         if(!NT_SUCCESS(status))
  38.                         {
  39.                                 BaseAddress = NULL;
  40.                                 ZwMapViewOfSection(&SectionHandle,NtCurrentProcess(),&BaseAddress,0,0,NULL,&ViewSize,ViewUnmap,0,PAGE_EXECUTE);
  41.                         }
  42.                 }
  43.         }
  44.         if(BaseAddress)
  45.         {
  46.                 if(!DProxyTable[INDEX_KECALLBACK]->IsInitialized)
  47.                 {
  48.                         ULONG IatOffset = GetProcOffsetFromIat(BaseAddress);
  49.                         DProxyTable[INDEX_KECALLBACK]->OriginFuncAddr = ExchangeMem(IatOffset,Win32kBase,ProxyKeUserModeCallback);
  50.                         if(DProxyTable[INDEX_KECALLBACK]->OriginFuncAddr)
  51.                         {
  52.                                 DProxyTable[INDEX_KECALLBACK]->IsInitialized;
  53.                                 status = STATUS_SUCCESS;
  54.                         }
  55.                 }
  56.                 ZwUnmapViewOfSection(NtCurrentProcess(),BaseAddress);
  57.         }
  58.         return status;
  59. }
复制代码

6.12 交换内存
  1. ULONG ExchangeMem(ULONG Offset,ULONG BaseAddress,ULONG NewValue)
  2. {//替换基址BaseAddress 偏移Offset 处的ULONG数据,返回原始数据
  3.         HANDLE CurProcessId = PsGetCurrentProcessId();
  4.         HANDLE SmssProcessId = GetProcessIdByName(L"smss.exe");
  5.         ULONG OriginValue = 0;
  6.         PMDL mdl = NULL;
  7.         if(!dwcsrssId)//如果没有获取到csrss.exe的id
  8.         {
  9.                 if(CurProcessId == SmssProcessId)//使用smss.exe的SSSDT
  10.                 {
  11.                         mdl = GetWritablePage(BaseAddress+Offset,16,&MappedAddress);
  12.                         if(mdl)
  13.                         {
  14.                                 OriginValue = InterlockedExchange(MappedAddress,NewValue);
  15.                                 MmUnlockPages(mdl);
  16.                                 IoFreeMdl(mdl);
  17.                         }
  18.                 }
  19.         }
  20.         else
  21.         {//附加到csrss.exe
  22.                 PVOID attachobj = AttachDriverToProcess(dwcsrssId);
  23.                 if(attachobj)
  24.                 {
  25.                         mdl = GetWritablePage(BaseAddress+Offset,4,&MappedAddress);
  26.                         if(mdl)
  27.                         {
  28.                                 OriginValue = InterlockedExchange(MappedAddress,NewValue);
  29.                                 MmUnlockPages(mdl);
  30.                                 IoFreeMdl(mdl);
  31.                         }
  32.                         DetachDriverFromProcess(attachobj);
  33.                 }
  34.         }
  35.         return OriginValue;
  36. }
复制代码

6.13 获取函数Iat偏移
  1. ULONG GetProcOffsetFromIat(PVOID ImageBase,PCHAR ModuleName,PCHAR ApiName)
  2. {//ImageBase当前进程映像基址  ModuleName导入模块映像基址  ApiName导入函数名
  3.         ANSI_STRING AApiName;
  4.         UNICODE_STRING UApiname;
  5.         PIMAGE_IMPORT_DESCRIPTOR ImportModuleDirectory;
  6.         ULONG ObjProcAddr;
  7.         ULONG Offset = 0;
  8.         PCHAR ImportedName;
  9.         PIMAGE_THUNK_DATA FunctionNameList;
  10.         RtlInitAnsiString(&AApiName,ApiName);
  11.         if(!NT_SUCCESS(RtlAnsiStringToUnicodeString(&UApiname,&AApiName,TRUE)))
  12.                 return 0;
  13.         ObjProcAddr = MmGetSystemRoutineAddress(&UApiname);
  14.         RtlFreeUnicodeString(&UApiname);
  15.         ImportModuleDirectory = (PIMAGE_IMPORT_DESCRIPTOR)RtlImageDirectoryEntryToData(ImageBase,TRUE,IMAGE_DIRECTORY_ENTRY_IMPORT);
  16.         if(!ImportModuleDirectory)
  17.                 return 0;
  18.         for (;(ImportModuleDirectory->Name != 0) && (ImportModuleDirectory->FirstThunk != 0);ImportModuleDirectory++)
  19.         {
  20.                 ImportedName = (PCHAR)ImageBase + ImportModuleDirectory->Name;
  21.                 if(!stricmp(ModuleName,ImportedName))
  22.                 {
  23.                         FunctionNameList = (PIMAGE_THUNK_DATA)((UCHAR*)ImageBase+ImportModuleDirectory->FirstThunk);
  24.                         while(*FunctionNameList != 0)
  25.                         {
  26.                                 if((*FunctionNameList) & 0x80000000)
  27.                                 {
  28.                                         if(FunctionNameList->u1.Function == ObjProcAddr)
  29.                                                 return (UCHAR*)FunctionNameList - (UCHAR*)ImageBase;
  30.                                 }
  31.                                 else
  32.                                 {
  33.                                         IMAGE_IMPORT_BY_NAME *pe_name = (IMAGE_IMPORT_BY_NAME*)((PCHAR)ImageBase + *FunctionNameList);
  34.                                         if(pe_name->Name[0] == 'K' && !stricmp(pe_name->Name,"KeUserModeCallback"))
  35.                                                 return (UCHAR*)FunctionNameList - (UCHAR*)ImageBase;
  36.                                 }
  37.                                 FunctionNameList++;
  38.                         }
  39.                 }
  40.         }
  41.         return 0;
  42. }
复制代码

6.14 另一种方式获取ShadowSSDT信息
当常规方式获取SSSDT失败时,会临时设置ZwSetSystemInformation的过滤函数捕获系统设置服务表(SYSTEM_INFORMATION_CLASS =SystemExtendServiceTableInformation),
  1. void TryAnotherWayToGetShadowSSDT()
  2. {
  3.         AddPrevFilter(EZwSetSystemInformation,ZwSetSystemInformationFilter1,0,0,NULL);
  4. }

  5. ULONG OldKeAddSystemServiceTable;

  6. ULONG __stdcall ZwSetSystemInformationFilter1(FilterPacket* Packet)
  7. {//改EAT以获取SSSDT
  8.         if(!ShadowSSDTBase && Packet->Params[0] == SystemExtendServiceTableInformation && !OldKeAddSystemServiceTable)
  9.         {
  10.                 OldKeAddSystemServiceTable = ExchangeEat(NtosBase,NewKeAddSystemServiceTable);
  11.                 if(OldKeAddSystemServiceTable)
  12.                 {
  13.                         Packet->TagSlot[Packet->CurrentSlot] = 0xABCDEEEE;//用于标记
  14.                         Packet->PostFilterSlot[Packet->CurrentSlot] = ZwSetSystemInformationFilter2;
  15.                         Packet->UsedSlotCount++;
  16.                 }
  17.         }
  18.         return SYSMON_PASSTONEXT;
  19. }

  20. ULONG __stdcall ZwSetSystemInformationFilter2(FilterPacket* Packet)
  21. {//获取之后恢复EAT
  22.         if(Packet->TagSlot[Packet->CurrentSlot] == 0xABCDEEEE)//检查标记
  23.         {
  24.                 if(serHookType != 1 && serHookType != 3)//是否SSDT型Hook
  25.                 {
  26.                         BeginSSDTHook();
  27.                 }
  28.         }
  29.         return SYSMON_PASSTONEXT;
  30. }

  31. BOOLEAN __stdcall KeAddSystemServiceTable(PULONG_PTR Base,PULONG Count,ULONG Limit,PUCHAR Number,ULONG Index)
  32. {//获取SSSDT
  33.         RTL_PROCESS_MODULE_INFORMATION ProcessInfo;
  34.         RtlZeroMemory(&ProcessInfo,sizeof(ProcessInfo));
  35.         if(!ShadowSSDTBase && GetProcessInfoByFileName("win32k.sys",&ProcessInfo) &&
  36.                 Base >= ProcessInfo.ImageBase && Base <= ProcessInfo.ImageBase+ProcessInfo.ImageSize)
  37.         {
  38.                 Win32kBase = ProcessInfo.ImageBase;
  39.                 Win32kSize = ProcessInfo.ImageSize;
  40.                 ShadowSSDTBase = Base;
  41.                 ShadowSSDTLimit = Limit;
  42.                 ExchangeEat(NtosBase,OldKeAddSystemServiceTable);
  43.         }
  44.         return  OldKeAddSystemServiceTable(Base,Count,Limit,Number,Index);
  45. }

  46. ULONG ExchangeEat(ULONG ImageBase,ULONG NewFunc)
  47. {
  48.         PVOID Address = MiLocateExportName(ImageBase,"KeAddSystemServiceTable");
  49.         if(Address)
  50.         {
  51.                 return ExchangeMem(0,Address,NewFunc);
  52.         }
  53.         return 0;
  54. }
复制代码
回复 赞! 靠!

使用道具 举报

发表于 2017-9-10 22:42:17 | 显示全部楼层
不知道能不能用
回复 赞! 靠!

使用道具 举报

发表于 2018-1-29 11:19:48 | 显示全部楼层
嗨 您好 下载了您的压缩包 但是需要您的QQ号码
回复 赞! 靠!

使用道具 举报

发表于 2018-8-10 16:10:28 | 显示全部楼层
想学习一下驱动的开发,下载了您的文档。请问你的qq是多少啊
回复 赞! 靠!

使用道具 举报

发表于 2019-1-14 15:29:54 | 显示全部楼层
想学习一下驱动的开发,下载了您的文档。请问你的qq是多少啊
回复 赞! 靠!

使用道具 举报

本版积分规则

QQ|Archiver|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2024-11-22 05:20 , Processed in 0.049050 second(s), 26 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表