vc++实现Ring3全局HOOK

  vc++实现Ring3全局HOOK 收藏
/***********************************************************************/
/*
实现全局hook模块基本完工,测试通过,没有发现异常。
         计划1:在hook前首先检验该程序是否已被hook
   计划2:添加枚举进程并hook功能
   计划3:在备份api时,只备份目标api函数,避免备份整个dll浪费空间
   计划4:给my_EventProcess_Thread加上垃圾回收机制

*/
/***********************************************************************/

#include
#include
#include
#include
#include
#include
#include
#pragma comment(lib,"psapi")
#include
#include
#include
#define WRITEBASE (12)

typedef struct
{
HMODULE  hModule;//句柄
LPVOID  lpNewBaseOfDll;//备份dll句柄
MODULEINFO modinfo;//MODULEINFO结构
}DLLINFO, *PDLLINFO;

typedef struct
{
HANDLE EventFar;
HANDLE ObjectProcessHandle;
DWORD WriteAddress;
}EventInfo,*PEventInfo;

void UpToDebug();//调整令牌提升至debug权限
BOOL InitDll(char *pszDll, PDLLINFO pDllInfo,HANDLE prochandle);
int HookNamedApi(PDLLINFO pDllInfo, char *ApiName, DWORD HookProc,HANDLE ObjectProcessHandle);
int HookProcess(HANDLE ObjectProcessHandle);
void FarStartUp(int Num);
void EditHookProc();
void __stdcall my_EventProcess_Thread(HANDLE EventFar);
DWORD __stdcall Hook_NtResumeThread(HANDLE ThreadHandle,PULONG PreviousSuspendCount OPTIONAL);

BYTE HookCode[]={0xb8,0x0,0x0,0x0,0x0,0xFF,0xE0};

void UpToDebug()//调整令牌提升至debug权限
{
HANDLE token;
OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,&token);
TOKEN_PRIVILEGES tp;
tp.PrivilegeCount =1;
LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&tp.Privileges[0].Luid);
tp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(token,0,&tp,sizeof(tp),0,0);
}

void main(int argc, char **argv)
{
UpToDebug();//提升至debug权限
HANDLE ObjectProcessHandle=OpenProcess(PROCESS_ALL_ACCESS,1,atoi(argv[1]));//打开目标进程
HookProcess(ObjectProcessHandle);

int wait=0;
scanf("%d",wait);
    return;
}

int HookProcess(HANDLE ObjectProcessHandle)
{
DLLINFO Object_dll;

if(!InitDll("ntdll.dll",&Object_dll,ObjectProcessHandle)) return 0;//备份目标dll
HookNamedApi(&Object_dll, "NtResumeThread", (DWORD)Hook_NtResumeThread,ObjectProcessHandle);//hook函数

//hook_api(&user32_dll, "NtQuerySystemInformation", (DWORD)hook_NtQuerySystemInformation, &new_temp,ObjectProcessHandle);//hook函数
//hook_api(&user32_dll, "NtQueryDirectoryFile", (DWORD)hook_NtQueryDirectoryFile, &new_temp,ObjectProcessHandle);//hook函数
//hook_api(&user32_dll, "FindFirstFileA", (DWORD)hook_FindFirstFileA, &new_FindFirstFileA,ObjectProcessHandle);//hook函数
//hook_api(&user32_dll, "FindNextFileA", (DWORD)hook_FindNextFileA, &new_FindFirstFileA,ObjectProcessHandle);
    return 0;
}

BOOL InitDll(char *pszDll, PDLLINFO pDllInfo,HANDLE prochandle)
{
pDllInfo->hModule = GetModuleHandle(pszDll);//得到目标dll句柄,因为是本地信息,所以要保证本程序加载此dll
if(!pDllInfo->hModule)
{
  printf("pDllInfo->hModule is null! in InitDll");
  return 0;
}
if(!GetModuleInformation(GetCurrentProcess(), pDllInfo->hModule, &pDllInfo->modinfo, sizeof(MODULEINFO)))//得到目标dll信息
{
  printf("Error:GetModuleInformation in InitDll");
  return 0;
}
pDllInfo->lpNewBaseOfDll = VirtualAllocEx(prochandle,0,pDllInfo->modinfo.SizeOfImage,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE);//申请空间并赋予相应权限(执行,读写)
if(!pDllInfo->lpNewBaseOfDll)
{
  printf("Error:VirtualAllocEx in InitDll");//错误处理
  return 0;
}
BYTE * buffer=(BYTE *)malloc(pDllInfo->modinfo.SizeOfImage);//分配缓冲,容纳目标dll
ReadProcessMemory(prochandle,pDllInfo->modinfo.lpBaseOfDll,buffer,pDllInfo->modinfo.SizeOfImage,0);//读出,远程dll内容
WriteProcessMemory(prochandle,pDllInfo->lpNewBaseOfDll,buffer,pDllInfo->modinfo.SizeOfImage,0);//写入备份dll
return 1;
}

int HookNamedApi(PDLLINFO pDllInfo, char *ApiName, DWORD HookProc,HANDLE ObjectProcessHandle)
{
DWORD      dw, NamedApiAddress,NewFunc;
MEMORY_BASIC_INFORMATION mbi;
static EventInfo myEventInfo;
static Num=0x676e696b;

NamedApiAddress = (DWORD)GetProcAddress(pDllInfo->hModule, ApiName);//目标api地址,每个进程的api地址都是一样的,只要找本进程的就可以了。
if(NamedApiAddress == NULL)
{
  printf("Error:GetProcAddress in hook_api");//错误处理
  return 0;
}

if(!VirtualQueryEx(ObjectProcessHandle,(void *)NamedApiAddress,&mbi,sizeof(MEMORY_BASIC_INFORMATION)))//获取api所在内存信息
{
  printf("Error:VirtualQueryEx in hook_api");
  return 0;
}

if(!VirtualProtectEx(ObjectProcessHandle,mbi.BaseAddress,mbi.RegionSize,PAGE_EXECUTE_READWRITE,&dw))//分配写和执行权限
{
  printf("Error:VirtualProtectEx in hook_api");
  return 0;
}
LPVOID WriteAddress=VirtualAllocEx(ObjectProcessHandle,0,1000,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE);//分配内存,写入hook函数

//计算原函数COPY的位置
NewFunc = NamedApiAddress - (DWORD)pDllInfo->modinfo.lpBaseOfDll + (DWORD)pDllInfo->lpNewBaseOfDll;
//修改原函数入口处内容

if(strcmp(ApiName,"NtResumeThread")==0)
{
  DWORD my_CreateEventA=(DWORD)GetProcAddress(GetModuleHandle("kernel32.dll"),"CreateEventA");
  HANDLE EventFar;
  __asm
  {
   pushad
   push 00000000h
      push Num
   push 0x676e696b
   push esp
   push 0
   push 0
   push 0
   call my_CreateEventA
   mov EventFar,eax
   pop eax
   pop eax
   pop eax
   popad
  }
  *(PDWORD)((DWORD)FarStartUp+9)=(DWORD)GetProcAddress(GetModuleHandle("kernel32.dll"),"OpenEventA");
     LPVOID StartUpAddr=VirtualAllocEx(ObjectProcessHandle,0,500,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE);//分配内存,写入StartUp函数
  WriteProcessMemory(ObjectProcessHandle,StartUpAddr,(LPVOID)FarStartUp,500,0);
  printf("%x/n",(DWORD)StartUpAddr);
  HANDLE FarThread=CreateRemoteThread(ObjectProcessHandle,0,0, (LPTHREAD_START_ROUTINE)StartUpAddr,(PVOID)Num,0,0);
  WaitForSingleObject(FarThread,-1);
  CloseHandle(FarThread);
  DWORD ReadBuf;
  ReadProcessMemory(ObjectProcessHandle,(LPVOID)((DWORD)StartUpAddr+21),&ReadBuf,4,0);
  VirtualFreeEx(ObjectProcessHandle,StartUpAddr,500,MEM_RELEASE);
  *(PDWORD)(HookProc+WRITEBASE+7)=ReadBuf;
  myEventInfo.EventFar=EventFar;
  myEventInfo.ObjectProcessHandle=ObjectProcessHandle;
  myEventInfo.WriteAddress=(DWORD)WriteAddress;
  CreateThread(0,0,(unsigned long (__stdcall *)(void *))my_EventProcess_Thread,&myEventInfo,0,0);
  Num++;
}
*(PDWORD)(HookProc+WRITEBASE)=NewFunc;
*(PDWORD)(HookProc+WRITEBASE+14)=(DWORD)GetProcAddress(GetModuleHandle("kernel32.dll"),"GetCurrentProcessId");
*(PDWORD)(HookProc+WRITEBASE+21)=(DWORD)GetProcAddress(GetModuleHandle("kernel32.dll"),"SetEvent");
*(PDWORD)(HookProc+WRITEBASE+28)=(DWORD)GetProcAddress(GetModuleHandle("kernel32.dll"),"WaitForSingleObject");
*(PDWORD)(HookProc+WRITEBASE+35)=(DWORD)GetProcAddress(GetModuleHandle("ntdll.dll"),"NtQueryInformationThread");
*(PDWORD)(HookProc+WRITEBASE+42)=(DWORD)GetProcAddress(GetModuleHandle("kernel32.dll"),"ResetEvent");

WriteProcessMemory(ObjectProcessHandle,WriteAddress,(void *)HookProc,1000,0);
*(PDWORD)(&HookCode[0]+1)=(DWORD)WriteAddress;
WriteProcessMemory(ObjectProcessHandle,(LPVOID)NamedApiAddress,&HookCode,7,0);

printf("func:%x/n",WriteAddress);//调试信息

return 1;
}

void  FarStartUp(int Num){
int myOpenEvent=0x10020000;
__asm call GetMyAddr;
DWORD myEventHandle=0x00220000;
DWORD FuncAddr;
__asm
{
  jmp run
GetMyAddr:
  pop eax
  mov FuncAddr,eax
  push eax
  ret
run:
  push 00000000
  push Num
  push 0x676e696b
  push esp
  push 0
  push EVENT_ALL_ACCESS
  call myOpenEvent
  mov myEventHandle,eax
}
*(PDWORD)(FuncAddr+3)=myEventHandle;
    return;
}

void __stdcall my_EventProcess_Thread(PVOID InEventInfo)
{
EventInfo myEventInfo;
PEventInfo Info=(PEventInfo)InEventInfo;
myEventInfo.EventFar=Info->EventFar;
myEventInfo.ObjectProcessHandle=Info->ObjectProcessHandle;
myEventInfo.WriteAddress=Info->WriteAddress;
while(true)
{
  WaitForSingleObject(myEventInfo.EventFar,-1);
  DWORD ReadBuf=0;
  ReadProcessMemory(myEventInfo.ObjectProcessHandle,(LPVOID)(myEventInfo.WriteAddress+67),&ReadBuf,4,0);
  HANDLE ObjectProcessHandle=OpenProcess(PROCESS_ALL_ACCESS,1,ReadBuf);
  HookProcess(ObjectProcessHandle);
  SetEvent(myEventInfo.EventFar);
  ResetEvent(myEventInfo.EventFar);
}
return;
}

DWORD __stdcall Hook_NtResumeThread(
        HANDLE ThreadHandle,
        PULONG PreviousSuspendCount OPTIONAL)
{
/*int OldNtResumeThread=0x11223344;//原NtQueryDirectoryFile函数
int EventHandle=0x11002200;
int my_GetCurrentProcessId=0x00224466;
int my_SetEnent=0x22447688;
int my_WaitForSingleObject=0x22556577;
int my_NtQueryInformationThread=0x99884756;*/
//int FarRead=0x00220044;

int OldNtResumeThread;//原NtQueryDirectoryFile函数
int EventHandle;
int my_GetCurrentProcessId;
int my_SetEnent;
int my_WaitForSingleObject;
int my_NtQueryInformationThread;
int my_ResetEvent;
__asm
{
  mov OldNtResumeThread,00112244h
  mov EventHandle,00225588h
  mov my_GetCurrentProcessId,22447799h
  mov my_SetEnent,55662244h
  mov my_WaitForSingleObject,55889966h
  mov my_NtQueryInformationThread,77554411h
  mov my_ResetEvent,55661188h
  pushad
}
__asm call GetAddr;
int FarRead;
__asm mov FarRead,22550011h;

DWORD myAddr;

__asm
{
  jmp start
GetAddr:
     pop eax
  mov myAddr,eax
  push eax
  ret
start:
}

DWORD myStatus;//存储返回变量

BYTE SystemInfo[60];
int infoaddr=(DWORD)&SystemInfo;
int CurrentProcess;

__asm
{
  push 0
     push 28
  push infoaddr
  push 0
  push ThreadHandle
     call my_NtQueryInformationThread
  mov myStatus,eax
}
DWORD id=*(DWORD *)(SystemInfo+8);

__asm
{
  call my_GetCurrentProcessId
  mov CurrentProcess,eax
}
if(id==(DWORD)CurrentProcess)
{
     __asm
  {
      push PreviousSuspendCount
      push ThreadHandle
      call OldNtResumeThread
      mov myStatus,eax
   popad
  }
     return myStatus;
}

if(myStatus==0)
{
  *(PDWORD)(myAddr+3)=id;
  __asm
  {
   push EventHandle
   call my_SetEnent
   push -1
   push EventHandle
   call my_WaitForSingleObject
   push EventHandle
   call my_ResetEvent
  }
}

__asm
{
  push PreviousSuspendCount
  push ThreadHandle
  call OldNtResumeThread
  mov myStatus,eax
  popad
}
return myStatus;
}

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/yincheng01/archive/2009/08/17/4455293.aspx

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值