看流星社区

 找回密码
 注册账号
查看: 29837|回复: 120

感谢看流星社区,我来说说找CALL的原理。

[复制链接]

该用户从未签到

发表于 2011-8-4 19:03:03 | 显示全部楼层 |阅读模式
游客,如果您要查看本帖隐藏内容请回复

该用户从未签到

发表于 2011-8-4 19:07:38 | 显示全部楼层
支持看流星社区

该用户从未签到

发表于 2011-8-4 22:59:26 | 显示全部楼层
看看看!!!!

该用户从未签到

发表于 2011-8-5 19:16:11 | 显示全部楼层
看看.........

该用户从未签到

发表于 2011-10-9 23:51:32 | 显示全部楼层
看看,谢谢楼主

该用户从未签到

发表于 2011-10-12 22:43:35 | 显示全部楼层
回复 1# 无限@感觉


        谢谢了    谢谢了

该用户从未签到

发表于 2011-11-2 10:02:58 | 显示全部楼层
非常不错 感谢分享

该用户从未签到

发表于 2011-11-6 18:54:32 | 显示全部楼层
#pragma once

#ifdef __cplusplus
extern "C"
{
#endif
#include <NTDDK.h>
#ifdef __cplusplus
}
#endif
#include <ntdef.h>
#include <windef.h>
#include <ntstatus.h>
#define PAGEDCODE code_seg("PAGE")
#define LOCKEDCODE code_seg()
#define INITCODE code_seg("INIT")

#define PAGEDDATA data_seg("PAGE")
#define LOCKEDDATA data_seg()
#define INITDATA data_seg("INIT")

#define arraysize(p) (sizeof(p)/sizeof((p)[0]))
#define FAILED_TO_OBTAIN_FUNCTION_ADDRESSES 0x1;
PEPROCESS processEPROCESS = NULL;//保存访问者的EPROCESS
PEPROCESS processEPROCESS1 = NULL;//保存访问者的EPROCESS
ANSI_STRING p_str1,p_str2,p_str3,p_str4;//保存进程名称
BYTE *ObOpenObjectByPointerAddress=NULL;//ObOpenObjectByPointer的地址
BYTE *ObOpenObjectByPointerAddress1=NULL;
BYTE *p_TpHookAddress=NULL;//Tp的HOOK函数地址
BYTE *p_ReturnAddress=NULL;//返回到的地址
BYTE *p_MyHookAddress=NULL;//自己的HOOK函数地址
BYTE *p_MyHookAddress1=NULL;//OpenThread自己的HOOK函数地址
BYTE *p_TpHookAddress1=NULL;//Tp的HOOK函数地址
BYTE *p_TpHookAddress3=NULL;//KiAttachProcess的地址
BYTE *p_ReturnAddress1=NULL;
#define DNF_EXE "DNF.exe" //DNF进程名
#pragma pack(1)
typedef struct _TOP5CODE       //前5字节自定义数据类型
{
  UCHAR  instruction;  //指令
  ULONG  address;    //地址
}TOP5CODE,*PTOP5CODE;
#pragma pack()
BYTE OldPOpen[6]={0,0,0,0,0,0};

VOID HelloDDKUnload (IN PDRIVER_OBJECT pDriverObject);
NTSTATUS HelloDDKDispatchRoutine(IN PDEVICE_OBJECT pDevObj,
                 IN PIRP pIrp);
typedef struct _ServiceDescriptorTable {
  PVOID ServiceTableBase; //System Service Dispatch Table 的基地址  
  PVOID ServiceCounterTable;//包含着 SSDT 中每个服务被调用次数的计数器。这个计数器一般由sysenter 更新。
  unsigned int NumberOfServices;//由 ServiceTableBase 描述的服务的数目。  
  PVOID ParamTableBase; //包含每个系统服务参数字节数表的基地址-系统服务参数表
}*PServiceDescriptorTable;  
//由SSDT索引号获取当前函数地址  
//NtOpenProcess  [[KeServiceDescriptorTable]+0x7A*4]  
extern "C" PServiceDescriptorTable KeServiceDescriptorTable;

PVOID MyGetFunAddress(IN PCWSTR FunctionName)
{
  UNICODE_STRING Old_NtAddr;
  RtlInitUnicodeString(&Old_NtAddr,FunctionName);
  return MmGetSystemRoutineAddress(&Old_NtAddr);
}

ULONG MyGetCurrentAddress(IN ULONG index)//获得当前地址
{
  ULONG SSDT_Cur_Addr;
  __asm
  {
    push ebx
      push eax
      mov ebx,KeServiceDescriptorTable
      mov ebx,[ebx]
    mov eax,index
      shl eax,2
      add ebx,eax
      mov ebx,[ebx]
    mov SSDT_Cur_Addr,ebx
      pop eax
      pop ebx
  }
  return SSDT_Cur_Addr;
}
VOID WPOFF()
{
  __asm //去掉页面保护
  {
    cli
      mov eax,cr0
      and eax,not 10000h //and eax,0FFFEFFFFh
      mov cr0,eax

  }
}

VOID WPON()
{
  __asm
  {
    mov eax,cr0
      or eax,10000h //or eax,not 0FFFEFFFFh
      mov cr0,eax
      sti
  }
}

VOID _declspec(naked) MyNtOpenProcess()
{

  processEPROCESS=IoGetCurrentProcess();//获得调用者的EPROCESS
  RtlInitAnsiString(&p_str1,(PCSZ)processEPROCESS+0x174);//将调用者的进程名保存到str1里
  RtlInitAnsiString(&p_str2,DNF_EXE);//将DNF进程名保存到str2里
  if(RtlCompareString(&p_str1,&p_str2,true)==0)
  {
    __asm
    {      
      push dword ptr [ebp-38h]
      push dword ptr [ebp-24h]
      push p_ReturnAddress
        mov  eax,p_TpHookAddress
        jmp  eax

    }
  }
  else
  {
    __asm
    {
      push dword ptr [ebp-38h]
      push dword ptr [ebp-24h]
      push p_ReturnAddress
        mov  eax,ObOpenObjectByPointerAddress
        jmp  eax
    }
  }

}
NTSTATUS My_RecoverHook_NtOpenProcess()
{

  BYTE *NtOpenProcessAddress=NULL;//NtOpenProcess地址
  BYTE JmpAddress[6]={0xE9,0,0,0,0,0x90};
  BYTE *p=NULL;
  TOP5CODE  *top5code = NULL;
  KIRQL Irql;

  NtOpenProcessAddress=(BYTE*)MyGetFunAddress(L"NtOpenProcess");  
  if (NtOpenProcessAddress==NULL)
  {
    KdPrint(("NtOpenProcess获取失败!\n"));
    return 0;
  }

  ObOpenObjectByPointerAddress=(BYTE*)MyGetFunAddress(L"ObOpenObjectByPointer");
  if (ObOpenObjectByPointerAddress==NULL)
  {
    KdPrint(("ObOpenObjectByPointer获取失败!\n"));
    return 0;
  }

  p = NtOpenProcessAddress;
  while (1)
  {
    if ((*(p-7)   == 0x50) &&
      (*(p-0xE)  == 0x56) &&
      (*(p+0xd)  == 0x50) &&
      (*(p+0x16) == 0x3b) &&
      (*(p+0x17) == 0xce) &&
      (*p        == 0xE8) &&
      (*(p+5)    == 0x8b) &&
      (*(p+6)    == 0xf8))
    {
      KdPrint(("P指针指向的地址%0X \n",(ULONG)p));
      break;
    }
    p++;
  }
  top5code = (TOP5CODE*)p;
  //被TX HOOK的地址,也就是call 后面的地址
  p_TpHookAddress = (BYTE*)((ULONG)p+5+top5code->address);
  p_MyHookAddress = p-6;
  p_ReturnAddress = p+5;
  *(ULONG *)(JmpAddress+1)=(ULONG)MyNtOpenProcess-((ULONG)p_MyHookAddress+5);   
  KdPrint(("Myhook地址=%0X \n",p_MyHookAddress));
  KdPrint(("TPhook地址=%0X \n",p_TpHookAddress));
  KdPrint(("返回地址=%0X \n",p_ReturnAddress));
  WPOFF();
  Irql=KeRaiseIrqlToDpcLevel();
  RtlCopyMemory((BYTE*)OldPOpen,(BYTE*)p_MyHookAddress,6);
    RtlCopyMemory(p_MyHookAddress,JmpAddress,6);
  KeLowerIrql(Irql);
  WPON();



  return STATUS_SUCCESS;
}

VOID recodeOpenProcess()
{
  KIRQL    Irql;
  WPOFF();  //清除CR0
  //提升IRQL中断级
  Irql=KeRaiseIrqlToDpcLevel();
  //写入
  if(OldPOpen[0]!=0)
  {
    RtlCopyMemory(p_MyHookAddress,OldPOpen,6);
  }
  //恢复Irql
  KeLowerIrql(Irql);
  WPON();    //恢复CR0
}

NTSTATUS My_RecoveryHook_ReadandWrite()
{
  BYTE  *NtReadVirtualMemoryAddress    = NULL;
  BYTE  *NtWriteVirtualMemoryAddress  = NULL;
  KIRQL  Irql;
  BYTE Read_data1[2]={0x6A,0x1C};            //机器硬编码
  BYTE Read_data2[5]={0x68,0xF0,0xAE,0x4D,0x80};    //机器硬编码
  BYTE Read_data3[5]={0x68,0x08,0xAF,0x4D,0x80};    //机器硬编码
  //从SSDT表中获取NtReadVirtualMemory函数地址
  NtReadVirtualMemoryAddress = (BYTE*)MyGetCurrentAddress(0xBA);
  if (NtReadVirtualMemoryAddress == NULL)
  {
    KdPrint(("NtReadVirtualMemory函数地址获取失败! \n"));
    return  FAILED_TO_OBTAIN_FUNCTION_ADDRESSES;
  }
  //从SSDT表中获取NtWriteVirtualMemory函数地址
  NtWriteVirtualMemoryAddress = (BYTE*)MyGetCurrentAddress(0x115);
  if (NtWriteVirtualMemoryAddress == NULL)
  {
    KdPrint(("NtWriteVirtualMemory函数地址获取失败! \n"));
    return  FAILED_TO_OBTAIN_FUNCTION_ADDRESSES;
  }
  WPOFF();  //清除CR0
  //提升IRQL中断级
  Irql=KeRaiseIrqlToDpcLevel();
  //写入
  RtlCopyMemory(NtReadVirtualMemoryAddress,Read_data1,2);
  RtlCopyMemory(NtReadVirtualMemoryAddress+2,Read_data2,5);
  RtlCopyMemory(NtWriteVirtualMemoryAddress,Read_data1,2);
  RtlCopyMemory(NtWriteVirtualMemoryAddress+2,Read_data3,5);
  //恢复Irql
  KeLowerIrql(Irql);
  WPON();    //恢复CR0
  return  STATUS_SUCCESS;
}

//////////////////////////////////////////////////////////////////////
//  名称:  RecoveryHook_KiAttachProcess
//  功能:  解除游戏保护对_KiAttachProcess函数的HOOK(DNF)
//  参数:  
//  返回:  状态
//////////////////////////////////////////////////////////////////////
NTSTATUS My_RecoveryHook_KiAttachProcess()
{
  BYTE  data[7]={0x8B,0xFF,0x55,0x8B,0xEC,0x53,0x56};
  BYTE    *KeAttachProcessAddress = NULL;  //KeAttachProcess函数地址
  BYTE    *p;
  KIRQL    Irql;
  TOP5CODE  *top5code = NULL;  //保存5字节内容

  //获得KeAttachProcess地址,然后通过特征码找到
  //KiAttachProcess的地址
  KeAttachProcessAddress = (BYTE*)MyGetFunAddress(L"KeAttachProcess");
  if (KeAttachProcessAddress == NULL)
  {
    KdPrint(("KeAttachProcess地址获取失败\n"));
    return  FAILED_TO_OBTAIN_FUNCTION_ADDRESSES;
  }
  //将p指向KeAttachProcess函数开始处
  p = KeAttachProcessAddress;
  while (1)
  {
    if ((*(p-1) == 0x56) &&
      (*(p-2) == 0x57) &&
      (*(p+5) == 0x5F) &&
      (*(p+6) == 0x5E) &&
      (*p     == 0xE8))
    {
      //定位成功后取地址
      //KiAttachProcessAddress = (BYTE*)((PULONG)(p+1))+((ULONG)(p+5));
      break;
    }

    //推动指针
    p++;
  }
  top5code = (TOP5CODE*)p;
  p_TpHookAddress3 = (BYTE*)((ULONG)p+5+top5code->address);
  KdPrint(("%0X \n",p_TpHookAddress3));
  WPOFF();  //清除CR0
  //提升IRQL中断级
  Irql=KeRaiseIrqlToDpcLevel();
  //写入
  RtlCopyMemory(p_TpHookAddress3,data,7);
  //恢复Irql
  KeLowerIrql(Irql);
  WPON();    //恢复CR0
  return  STATUS_SUCCESS;
}
VOID _declspec(naked) MyNtOpenThread()
{
  /*processEPROCESS1=IoGetCurrentProcess();//获得调用者的EPROCESS
  RtlInitAnsiString(&p_str3,(PCSZ)processEPROCESS+0x174);//将调用者的进程名保存到str1里
  RtlInitAnsiString(&p_str4,DNF_EXE);//将DNF进程名保存到str2里
  if(RtlCompareString(&p_str3,&p_str4,true)==0)
  {
   
    __asm
    {      
      push dword ptr [ebp-34h]
      push dword ptr [ebp-20h]
      push p_ReturnAddress1
        mov  eax,p_TpHookAddress1
        jmp  eax
    }
  }
  else
  {*/
    __asm
    {
      push dword ptr [ebp-34h]
      push dword ptr [ebp-20h]
      push p_ReturnAddress1
      mov  eax,ObOpenObjectByPointerAddress1
      jmp  eax
    }
  //}
}

该用户从未签到

发表于 2012-1-5 09:39:56 | 显示全部楼层
看看,学学

该用户从未签到

发表于 2012-1-14 00:20:39 | 显示全部楼层
喽喽喽,嘿嘿嘿
点击按钮快速添加回复内容: 支持 高兴 激动 给力 加油 苦寻 生气 回帖 路过 感恩
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

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

GMT+8, 2024-4-18 19:20

Powered by Kanliuxing X3.4

© 2010-2019 kanliuxing.com

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