看流星社区

 找回密码
 注册账号
查看: 4749|回复: 2

SSDT HOOK NtReadVirtualMemory(让CE读内存失效)

[复制链接]

该用户从未签到

发表于 2013-5-6 08:47:55 | 显示全部楼层 |阅读模式
是依据10年的进程保护修改的,这次是 内核里面替换函数地址,也就是 传说中的SSDT hook 。具体是 替换 NtReadVirtualMemory的函数地址。。。。
----------------------------------------------------------------
#include <ntddk.h>
typedef struct _SystemServiceDescriptorTable
{
    PVOID    ServiceTableBase; //SSDT表的基地址
    PULONG    ServiceCounterTableBase; //指向另一个索引表,该表包含了每个服务表项被调用的次数
    ULONG    NumberOfService; //当前系统所支持的服务个数
    ULONG    ParamTableBase; //包含了每个服务所需的参数字节数
}SystemServiceDescriptorTable,*PSystemServiceDescriptorTable;
extern PSystemServiceDescriptorTable KeServiceDescriptorTable; //导出函数,DDK的头文件中并未声明
//内核函数声明
typedef NTSTATUS  (*NtREADVIRTUALMEMORY)(
                                                                             IN HANDLE ProcessHandle,
                                   IN PVOID BaseAddress,
                                   OUT PVOID Buffer,
                                   IN ULONG BufferLength,
                                   OUT PULONG ReturnLength OPTIONAL);
//定义一个内核函数的数据类型
NtREADVIRTUALMEMORY pRealAddr;//用 NtREADVIRTUALMEMORY 定义 一个  真的 函数类型
ULONG RealServiceAddress;          //接受被hook的函数地址
CHAR *TerminateName = "Form1.exe";  //这里就是我们的记事本进程名
UCHAR* PsGetProcessImageFileName( IN PEPROCESS Process );  
BOOLEAN IsProtect(CHAR *temp)  //判断正在结束的进程是否是我们要保护的魔兽进程
{
  ULONG len = strcmp(TerminateName, temp);
  if(!len)
    return TRUE;
  return FALSE;
}
NTSTATUS MyNtReadVirtualMemory(IN HANDLE ProcessHandle,IN PVOID BaseAddress,OUT PVOID Buffer,IN ULONG BufferLength,OUT PULONG ReturnLength OPTIONAL)//ReturnLength 是参数

{
  PEPROCESS process; //接受通过ProcessHandle返回的进程

  NTSTATUS status;  
  CHAR *pName;  //接受进程的进程名
  status = ObReferenceObjectByHandle(ProcessHandle, FILE_READ_DATA,0, KernelMode,&process,NULL); //获取进程
  if(!NT_SUCCESS(status))//如果不是我们要保护的进程就放过它,让他正常访问内存  
  {
       return (NTSTATUS)(NtREADVIRTUALMEMORY)pRealAddr(ProcessHandle, BaseAddress,Buffer,BufferLength,ReturnLength);
  }
   pName = (CHAR*)PsGetProcessImageFileName(process);
//获取进程名。内核中居然可以这样依据 进程结构 获取进程名,很好,很方面
  if(IsProtect(pName))  //判断是否是我们要保护的进程,是则返回权限不足
  {
            DbgPrint(" 有进程正在访问 %s的内存,我让它访问不了! \n",pName); //嘿嘿,
       return STATUS_ACCESS_DENIED;//返回为STATUS_ACCESS_DENIED    CE就无法访问内存了
  }
  return (NTSTATUS)(NtREADVIRTUALMEMORY)pRealAddr(ProcessHandle, BaseAddress,Buffer,BufferLength,ReturnLength);
}
NTSTATUS Hook()
{
  ULONG Address;
  Address = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 277 * 4;
//可以用 xuetr查看。 win7上 序号为  277       xp上位186
  RealServiceAddress = *(ULONG*)Address;  
  pRealAddr = (NtREADVIRTUALMEMORY)RealServiceAddress;

  //开启SSDT 表为可写
  _asm
  {
    cli;
    mov  eax, cr0;
    and eax, not 10000h;
    mov  cr0, eax;
  }
  *((ULONG*)Address) = (ULONG)MyNtReadVirtualMemory; //替换为我们自己的NtTerminateProcess函数
    DbgPrint("完成HOOK内核函数");
//设置SSDT表位只读
  _asm
  {
    mov  eax, cr0;
    or  eax, 10000h;
    mov  cr0, eax;
    sti;  
  }
}
VOID UnHook()//把SSDT中的NtReadVirtualMemory函数还原
{
  ULONG Address;

  Address = (ULONG)KeServiceDescriptorTable->ServiceTableBase +277 * 4;
//可以用 xuetr查看。 win7上 序号为277        xp上位 186
  __asm
     {
       cli
       mov    eax, cr0;
       and    eax, not 10000h ;
       mov    cr0, eax ;
     }
     *((ULONG*)Address) = (ULONG)RealServiceAddress;
  __asm
     {
       mov    eax, cr0 ;
       or   eax, 10000h ;
       mov    cr0, eax ;
       sti ;
     }
}
VOID Unload(PDRIVER_OBJECT driver)
{
  UNREFERENCED_PARAMETER(driver);
  UnHook();
  DbgPrint("卸载驱动完成...");
}
NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING str)
{
  NTSTATUS status;
  UNREFERENCED_PARAMETER(str);
  driver->DriverUnload = Unload;
   DbgPrint("驱动加载完成");
  status = Hook();
  return STATUS_SUCCESS;
}

两个版本全部搞定,xp和win7 32 位,果断分享。

http://pan.baidu.com/share/link?shareid=520327&uk=3895950538

该用户从未签到

发表于 2013-5-6 18:17:41 | 显示全部楼层
- - 汗 透漏一下 !现在 win7 系统的机子 用OD CE 完全不非法的  写出来的软件都不非法!因为 win7系统写出来的 全是无驱动的! 把win7 写的软件 放在 XP  各种和谐蛋疼!SX !

该用户从未签到

发表于 2013-5-6 18:21:46 | 显示全部楼层
过了TP以后!OD附加硬件断点 CE 也可以附加访问地址 !很多人问 过了TP 老是不能访问 是因为没有处理Get/SetContextThread,硬件断点,DebugPort的清零就可以了!然后 即可找 基址!
点击按钮快速添加回复内容: 支持 高兴 激动 给力 加油 苦寻 生气 回帖 路过 感恩
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

小黑屋|手机版|Archiver|看流星社区 |网站地图

GMT+8, 2024-5-14 19:34

Powered by Kanliuxing X3.4

© 2010-2019 kanliuxing.com

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