易语言教程_易语言源码_易语言写挂_易语言论坛_看流星社区

 找回密码
 注册
零基础辅助入门教学 原创 高清 专业课程售后(每日解答)
零基础辅助入门教学 原创 高清 专业课程售后(每日解答)
零基础辅助入门教学 原创 高清 专业课程售后(每日解答)
零基础辅助入门教学 原创 高清 专业课程售后(每日解答)
零基础辅助入门教学 原创 高清 专业课程售后(每日解答)
零基础辅助入门教学 原创 高清 专业课程售后(每日解答)
赞助广告位 请点击这里联系站长 QQ20209081
赞助广告位 请点击这里联系站长 QQ20209081
赞助广告位 请点击这里联系站长 QQ20209081
查看: 5869|回复: 97

感谢看流星社区,我来说说找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, 2018-6-23 02:34 易语言论坛 易语言导航

Powered by 看流星社区 X3.2

©2011-2016 最好的辅助编程技术论坛

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