vc++实现Ring3全局HOOK

来源:互联网 发布:无线网怎么转有线网络 编辑:程序博客网 时间:2024/05/29 04:53

 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; 
}

原创粉丝点击