反病毒工具之注册表监视器(VC DLL源码)

核心HOOK API类,理论上可以HOOK 任何使用STDCALL声明的API函数

// HookInfo.h: interface for the CHookInfo class. // //////////////////////////////////////////////////////////////////////

#if !defined(AFX_HOOKINFO_H__D44F115C_76F1_4CC7_BD61_4C393417DA10__INCLUDED_) #define AFX_HOOKINFO_H__D44F115C_76F1_4CC7_BD61_4C393417DA10__INCLUDED_

#if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000

typedef struct _HOOKSTRUCT {     FARPROC pfFunAddr; //用于保存API函数地址     BYTE    OldCode[5]; //保存原API前5个字节     BYTE    NewCode[5]; //JMP XXXX其中XXXXJMP的地址 }HOOKSTRUCT;

class CHookInfo  { public:  //HOOK 处理函数  CHookInfo(char *strDllName, char *strFunName, DWORD dwMyFunAddr);  virtual ~CHookInfo(); //析构函数  HOOKSTRUCT *pHook; //HOOK结构  void HookStatus(BOOL blnHook); //关闭/打开HOOK状态 };

CHookInfo::CHookInfo(char *strDllName, char *strFunName, DWORD dwMyFunAddr) {  pHook = new HOOKSTRUCT;     HMODULE hModule = LoadLibrary(strDllName);  //纪录函数地址     pHook->pfFunAddr = GetProcAddress(hModule,strFunName);  FreeLibrary(hModule);     if(pHook->pfFunAddr == NULL)         return ;  //备份原函数的前5个字节,一般的WIN32 API以__stdcall声明的API理论上都可以这样进行HOOK     memcpy(pHook->OldCode, pHook->pfFunAddr, 5);     pHook->NewCode[0] = 0xe9; //构造JMP     DWORD dwJmpAddr = dwMyFunAddr - (DWORD)pHook->pfFunAddr - 5; //计算JMP地址     memcpy(&pHook->NewCode[1], &dwJmpAddr, 4);  HookStatus(TRUE);//开始进行HOOK }

CHookInfo::~CHookInfo() {  //关闭HOOK恢复原函数  HookStatus(FALSE); }

void CHookInfo::HookStatus(BOOL blnHook) {  if(blnHook)   WriteProcessMemory((HANDLE)-1, pHook->pfFunAddr, pHook->NewCode, 5, 0);//替换函数地址  else   WriteProcessMemory((HANDLE)-1, pHook->pfFunAddr, pHook->OldCode, 5, 0);//还原函数地址 } #endif // !defined(AFX_HOOKINFO_H__1967D554_7A9F_40C5_9D86_5899019EB3CD__INCLUDED_)

DLL程序代码,消息传递使用了自定义消息的方式

// RegistryInfo.cpp : Defines the entry point for the DLL application. //

#include "stdafx.h" #include <stdlib.h> #include "HookInfo.h" #define STATUS_SUCCESS (0) #define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0) #define STATUS_ACCESS_DENIED ((NTSTATUS)0xC0000022L) #define ObjectNameInformation (1) #define BLOCKSIZE (0x1000) #define CurrentProcessHandle         ((HANDLE)(0xFFFFFFFF)) #define STATUS_INFO_LEN_MISMATCH       0xC0000004

typedef unsigned long NTSTATUS; typedef unsigned long SYSTEM_INFORMATION_CLASS; typedef unsigned long OBJECT_INFORMATION_CLASS;

typedef struct {  USHORT Length;  USHORT MaxLen;  USHORT *Buffer; }UNICODE_STRING, *PUNICODE_STRING;

typedef struct _OBJECT_NAME_INFORMATION { // Information Class 1  UNICODE_STRING Name; } OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION;

typedef struct _OBJECT_ATTRIBUTES {     ULONG Length;     HANDLE RootDirectory;     PUNICODE_STRING ObjectName;     ULONG Attributes;     PVOID SecurityDescriptor;     PVOID SecurityQualityOfService; } OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;

typedef NTSTATUS (WINAPI *NTSETVALUEKEY)(IN HANDLE KeyHandle,IN PUNICODE_STRING ValueName,IN ULONG TitleIndex,IN ULONG type1,IN PVOID Data,IN ULONG DataSize); NTSETVALUEKEY NtSetValueKey = NULL;

typedef NTSTATUS (WINAPI *NTDELETEVALUEKEY)(IN HANDLE KeyHandle,IN PUNICODE_STRING ValueName); NTDELETEVALUEKEY NtDeleteValueKey = NULL;

typedef NTSTATUS (WINAPI *NTDELETEKEY)(IN HANDLE KeyHandle); NTDELETEKEY NtDeleteKey = NULL;

typedef NTSTATUS (WINAPI *NTCREATEKEY)(OUT PHANDLE pKeyHandle,IN ACCESS_MASK DesiredAccess,  IN POBJECT_ATTRIBUTES ObjectAttributes,IN ULONG TitleIndex,IN PUNICODE_STRING Class OPTIONAL,  IN ULONG CreateOptions,OUT PULONG Disposition OPTIONAL); NTCREATEKEY NtCreateKey = NULL;

typedef NTSTATUS (WINAPI *NTQUERYOBJECT)(IN HANDLE ObjectHandle,IN OBJECT_INFORMATION_CLASS ObjectInformationClass,OUT PVOID ObjectInformation,IN ULONG ObjectInformationLength,OUT PULONG ReturnLength); NTQUERYOBJECT NtQueryObject = NULL; NTSTATUS WINAPI NtSetValueKeyCallback(IN HANDLE KeyHandle,IN PUNICODE_STRING ValueName,IN ULONG TitleIndex,IN ULONG type1,IN PVOID Data,IN ULONG DataSize); NTSTATUS WINAPI NtDeleteValueKeyCallback(IN HANDLE KeyHandle,IN PUNICODE_STRING ValueName); NTSTATUS WINAPI NtDeleteKeyCallback(IN HANDLE KeyHandle); NTSTATUS WINAPI NtCreateKeyCallback(OUT PHANDLE pKeyHandle,IN ACCESS_MASK DesiredAccess,  IN POBJECT_ATTRIBUTES ObjectAttributes,IN ULONG TitleIndex,IN PUNICODE_STRING Class OPTIONAL,  IN ULONG CreateOptions,OUT PULONG Disposition OPTIONAL); CHookInfo *ChookNtSetValueKey; CHookInfo *ChookNtDeleteKey; CHookInfo *ChookNtCreateKey; CHookInfo *ChookNtDeleteValueKey; HINSTANCE m_hinstDll; HWND m_hWnd; char *GetSidString(char *strUserName); char *mstrMachinePath="//registry//machine//software//microsoft//windows//currentversion//run"; char mstrUserPath[400]; char *mstrLogonPath="//registry//machine//software//microsoft//windows nt//currentversion//winlogon"; char mstrWinRegPath[260]; HHOOK m_hHook; DWORD m_ProcessId;

//初始NT系列的函数 VOID LoadNtDll() {  HMODULE hMod = LoadLibrary("ntdll.dll");  NtDeleteKey = (NTDELETEKEY)GetProcAddress(hMod,"NtDeleteKey");  NtSetValueKey = (NTSETVALUEKEY)GetProcAddress(hMod,"NtSetValueKey");  NtDeleteValueKey = (NTDELETEVALUEKEY)GetProcAddress(hMod,"NtDeleteValueKey");  NtCreateKey = (NTCREATEKEY)GetProcAddress(hMod,"NtCreateKey");  NtQueryObject = (NTQUERYOBJECT)GetProcAddress(hMod,"NtQueryObject");  FreeLibrary(hMod); }

//DLL入口点函数 BOOL APIENTRY DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) {  m_hinstDll=hInstance;  if (dwReason == DLL_PROCESS_ATTACH)  {   m_hWnd=FindWindow(NULL,"注册表监视");   if (!m_hWnd)    return FALSE;   GetWindowThreadProcessId(m_hWnd,&m_ProcessId);   char strUserName[260],strSID[200];   DWORD dwSize;   dwSize=260;   GetUserName(strUserName,&dwSize);   strcpy(mstrUserPath,"//registry//user//");   strcpy(strSID,GetSidString(strUserName));   strcat(mstrUserPath,strlwr(strSID));   strcat(mstrUserPath,"//");   strcpy(mstrWinRegPath,mstrUserPath);   strcat(mstrUserPath,"software//microsoft//windows//currentversion//run");   strcat(mstrWinRegPath,"software//microsoft//windows nt//currentversion//windows");   //初始NTDLL   LoadNtDll();   if (GetCurrentProcessId()!=m_ProcessId)   {    ChookNtSetValueKey = new CHookInfo("ntdll.dll","NtSetValueKey",(DWORD)NtSetValueKeyCallback);    ChookNtDeleteKey = new CHookInfo("ntdll.dll","NtDeleteKey",(DWORD)NtDeleteKeyCallback);    ChookNtCreateKey = new CHookInfo("ntdll.dll","NtCreateKey",(DWORD)NtCreateKeyCallback);    ChookNtDeleteValueKey = new CHookInfo("ntdll.dll","NtDeleteValueKey",(DWORD)NtDeleteValueKeyCallback);   }  }  else if (dwReason == DLL_PROCESS_DETACH)  {   if (GetCurrentProcessId()!=m_ProcessId)   {    delete ChookNtSetValueKey;    delete ChookNtDeleteKey;    delete ChookNtCreateKey;    delete ChookNtDeleteValueKey;   }  }  return TRUE;   // ok }

//卸载钩子 BOOL WINAPI UninstallRegHook()//输出卸在钩子函数 {  return(UnhookWindowsHookEx(m_hHook)); }

//钩子函数 LRESULT WINAPI Hook(int nCode,WPARAM wParam,LPARAM lParam)//空的钩子函数 {  return(CallNextHookEx(m_hHook,nCode,wParam,lParam)); }

//安装API钩子 BOOL WINAPI InstallRegHook(LPCTSTR strCheck) {  if (strcmpi(strCheck,"http://blog.csdn.net/chenhui530/")!=0)   return FALSE;  m_hHook=SetWindowsHookEx(WH_GETMESSAGE,(HOOKPROC)Hook,m_hinstDll,0);  if (!m_hHook)  {   MessageBoxA(NULL,"安装钩子失败","失败",MB_OK);   return FALSE;  }  return TRUE; }

//通过句柄获取注册表路径 void GetPath(char *strPath,HANDLE hHandle) {  HANDLE hHeap = GetProcessHeap();  DWORD dwSize = 0;  POBJECT_NAME_INFORMATION pName = (POBJECT_NAME_INFORMATION)HeapAlloc(hHeap, HEAP_ZERO_MEMORY, 0x1000);    NTSTATUS ns = NtQueryObject(hHandle, ObjectNameInformation, (PVOID)pName, 0x1000, &dwSize);  DWORD i = 1;  while(ns == STATUS_INFO_LEN_MISMATCH)  {   pName = (POBJECT_NAME_INFORMATION)HeapReAlloc(hHeap, HEAP_ZERO_MEMORY, (LPVOID)pName, 0x1000 * i);   ns = NtQueryObject(hHandle, ObjectNameInformation, (PVOID)pName, 0x1000, NULL);   i++;  }  wsprintf(strPath, "%S", pName->Name.Buffer);  HeapFree(hHeap,0,pName); }

NTSTATUS WINAPI NtSetValueKeyCallback(IN HANDLE KeyHandle,IN PUNICODE_STRING ValueName,IN ULONG TitleIndex,IN ULONG type1,IN PVOID Data,IN ULONG DataSize) {  char strName[512];  GetPath(strName,KeyHandle);  char strObjectPath[512] = {'/0'};  //获取注册表完整路径包括创建的键名  if(type1 == 4 || type1 == 5 || type1 == 11)   wsprintf(strObjectPath, "%s//%S*value:%d,0x%X", strName, ValueName->Buffer, *(DWORD*)Data, *(DWORD*)Data);  else if(type1 == 3)   wsprintf(strObjectPath, "%s//%S", strName, ValueName->Buffer);  else if(type1 == 8)   wsprintf(strObjectPath, "%s//%S", strName, ValueName->Buffer);  else   wsprintf(strObjectPath, "%s//%S*value:%S", strName, ValueName->Buffer, Data);  char strTmp[512];  strcpy(strTmp,strObjectPath);  char *strLwr=strlwr(strObjectPath);  //只监视启动项,这里大家可以自己设置  if (strstr(strLwr,mstrMachinePath) || strstr(strLwr,mstrUserPath) ||   strstr(strLwr,mstrLogonPath) || strstr(strLwr,mstrWinRegPath))  {   COPYDATASTRUCT cds;   //构造字符串好让监管程序分离,这里是按我自己特定的格式传过去的,大家可以根据自己的格式构造   char strInt[10];   itoa(type1,strInt,10);   char strMsg[512];   strcpy(strMsg,"设置值:");   strcat(strMsg,strTmp);   strcat(strMsg,"**");   strcat(strMsg,strInt);   strcat(strMsg,"^^");   char strPath[260];   GetModuleFileName(NULL,strPath,sizeof(strPath));   strcat(strMsg,strPath);   strcat(strMsg,"进程ID<");   itoa(::GetCurrentProcessId(),strInt,10);   strcat(strMsg,strInt);   strcat(strMsg,">");   cds.lpData = strMsg;   cds.cbData = sizeof(strMsg);   cds.dwData = 0;   //发送消息给监管程序,如果同意就执行   LRESULT l=::SendMessage(m_hWnd,WM_COPYDATA,0,(LPARAM)&cds);   if (l==1000)   {    ChookNtSetValueKey->HookStatus(FALSE);    NTSTATUS hReturn = NtSetValueKey(KeyHandle,ValueName,TitleIndex,type1,Data,DataSize);    ChookNtSetValueKey->HookStatus(TRUE);    return hReturn;   }  }  else  {   //没有监控的就让函数执行   ChookNtSetValueKey->HookStatus(FALSE);   NTSTATUS hReturn = NtSetValueKey(KeyHandle,ValueName,TitleIndex,type1,Data,DataSize);   ChookNtSetValueKey->HookStatus(TRUE);   return hReturn;  }  //不同意的返回拒绝访问  return STATUS_ACCESS_DENIED; }

//注册表删除键值代理函数 NTSTATUS WINAPI NtDeleteValueKeyCallback(IN HANDLE KeyHandle,IN PUNICODE_STRING ValueName) {  char strName[512];  GetPath(strName,KeyHandle);  char strObjectPath[512] = {'/0'};  //获取注册表完整路径包括创建的键名  wsprintf(strObjectPath, "%s//%S", strName, ValueName->Buffer);  char strTmp[512];  strcpy(strTmp,strObjectPath);  strlwr(strObjectPath);  //只监视启动项,这里大家可以自己设置  if (strstr(strObjectPath,mstrMachinePath) || strstr(strObjectPath,mstrUserPath) ||   strstr(strObjectPath,mstrLogonPath) || strstr(strObjectPath,mstrWinRegPath))  {   COPYDATASTRUCT cds;   //构造字符串好让监管程序分离,这里是按我自己特定的格式传过去的,大家可以根据自己的格式构造   char strMsg[512];   strcpy(strMsg,"删除值:");   strcat(strMsg,strTmp);   strcat(strMsg,"^^");   char strPath[260];   GetModuleFileName(NULL,strPath,sizeof(strPath));   strcat(strMsg,strPath);   strcat(strMsg,"进程ID<");   char strInt[10];   itoa(::GetCurrentProcessId(),strInt,10);   strcat(strMsg,strInt);   strcat(strMsg,">");   cds.lpData = strMsg;   cds.cbData = sizeof(strMsg);   cds.dwData = 0;   //发送消息给监管程序,如果同意就执行   LRESULT l=::SendMessage(m_hWnd,WM_COPYDATA,0,(LPARAM)&cds);   if (l==1000)   {    ChookNtDeleteValueKey->HookStatus(FALSE);    NTSTATUS hReturn = NtDeleteValueKey(KeyHandle,ValueName);    ChookNtDeleteValueKey->HookStatus(TRUE);    return hReturn;   }  }  else  {   //没有监控的就让函数执行   ChookNtDeleteValueKey->HookStatus(FALSE);   NTSTATUS hReturn = NtDeleteValueKey(KeyHandle,ValueName);   ChookNtDeleteValueKey->HookStatus(TRUE);   return hReturn;  }  //不同意的返回拒绝访问  return STATUS_ACCESS_DENIED; }

//注册表删除项代理函数 NTSTATUS WINAPI NtDeleteKeyCallback(IN HANDLE KeyHandle) {  char strObjectPath[512] = {'/0'};  GetPath(strObjectPath,KeyHandle);  char strTmp[512];  strcpy(strTmp,strObjectPath);  strlwr(strObjectPath);  //排除非启动项  if (strstr(strObjectPath,mstrMachinePath) || strstr(strObjectPath,mstrUserPath) ||   strstr(strObjectPath,mstrLogonPath) || strstr(strObjectPath,mstrWinRegPath))  {   COPYDATASTRUCT cds;   //构造字符串好让监管程序分离,这里是按我自己特定的格式传过去的,大家可以根据自己的格式构造   char strMsg[512];   strcpy(strMsg,"删除项:");   strcat(strMsg,strTmp);   strcat(strMsg,"^^");   char strPath[260];   GetModuleFileName(NULL,strPath,sizeof(strPath));   strcat(strMsg,strPath);   char strInt[10];   strcat(strMsg,"进程ID<");   itoa(::GetCurrentProcessId(),strInt,10);   strcat(strMsg,strInt);   strcat(strMsg,">");   cds.lpData = strMsg;   cds.cbData = sizeof(strMsg);   cds.dwData = 0;   //发送消息给监管程序,如果同意就执行   LRESULT l=::SendMessage(m_hWnd,WM_COPYDATA,0,(LPARAM)&cds);   if (l==1000)   {    ChookNtDeleteKey->HookStatus(FALSE);    NTSTATUS hReturn = NtDeleteKey(KeyHandle);    ChookNtDeleteKey->HookStatus(TRUE);    return hReturn;   }   }  else  {    //没有监控的让它继续执行   ChookNtDeleteKey->HookStatus(FALSE);   NTSTATUS hReturn = NtDeleteKey(KeyHandle);   ChookNtDeleteKey->HookStatus(TRUE);   return hReturn;  }  //不同意的返回拒绝访问  return STATUS_ACCESS_DENIED; }

//注册表创建项代理函数 NTSTATUS WINAPI NtCreateKeyCallback(OUT PHANDLE pKeyHandle,IN ACCESS_MASK DesiredAccess,  IN POBJECT_ATTRIBUTES ObjectAttributes,IN ULONG TitleIndex,IN PUNICODE_STRING Class OPTIONAL,  IN ULONG CreateOptions,OUT PULONG Disposition OPTIONAL) {  char strName[512];  //获取创建的路径  GetPath(strName,ObjectAttributes->RootDirectory);  char strObjectPath[512];  //获取注册表完整路径包括创建的键名  wsprintf(strObjectPath, "%s//%S",strName, ObjectAttributes->ObjectName->Buffer);  if (lstrcmpi(strObjectPath,mstrMachinePath)==0 || lstrcmpi(strObjectPath,mstrUserPath)==0 ||   lstrcmpi(strObjectPath,mstrLogonPath)==0 || lstrcmpi(strObjectPath,mstrWinRegPath)==0)  {   ChookNtCreateKey->HookStatus(FALSE);   NTSTATUS hReturn = hReturn = NtCreateKey(pKeyHandle,DesiredAccess,ObjectAttributes,TitleIndex,Class,CreateOptions,Disposition);   ChookNtCreateKey->HookStatus(TRUE);   return hReturn;  }  char strTmp[260];  strcpy(strTmp,strObjectPath);  strlwr(strObjectPath);  //只监视启动项,这里大家可以自己设置  if (strstr(strObjectPath,mstrMachinePath) || strstr(strObjectPath,mstrUserPath) ||   strstr(strObjectPath,mstrLogonPath) || strstr(strObjectPath,mstrWinRegPath))  {   COPYDATASTRUCT cds;   //构造字符串好让监管程序分离   char strMsg[512];   strcpy(strMsg,"新增项:");   strcat(strMsg,strTmp);   strcat(strMsg,"^^");   char strPath[260];   GetModuleFileName(NULL,strPath,sizeof(strPath));   strcat(strMsg,strPath);   strcat(strMsg,"进程ID<");   char strInt[10];   itoa(::GetCurrentProcessId(),strInt,10);   strcat(strMsg,strInt);   strcat(strMsg,">");   cds.lpData = strMsg;   cds.cbData = sizeof(strMsg);   cds.dwData = 0;   //发送消息给监管程序,当返回1000表示同意   LRESULT l=::SendMessage(m_hWnd,WM_COPYDATA,0,(LPARAM)&cds);   if (l==1000)   {    ChookNtCreateKey->HookStatus(FALSE);    NTSTATUS hReturn = NtCreateKey(pKeyHandle,DesiredAccess,ObjectAttributes,TitleIndex,Class,CreateOptions,Disposition);    ChookNtCreateKey->HookStatus(TRUE);    return hReturn;   }  }  else  {    //没有监控的就让函数执行   ChookNtCreateKey->HookStatus(FALSE);   NTSTATUS hReturn = hReturn = NtCreateKey(pKeyHandle,DesiredAccess,ObjectAttributes,TitleIndex,Class,CreateOptions,Disposition);   ChookNtCreateKey->HookStatus(TRUE);   return hReturn;  }  //不同意的返回拒绝访问  return STATUS_ACCESS_DENIED; }

//获取指定用户的SID char *GetSidString(char *strUserName) {  char szBuffer[200];     BYTE sidBuffer[100];     PSID pSid=(PSID)&sidBuffer;     DWORD sidBufferSize = 100;     char domainBuffer[80];     DWORD domainBufferSize = 80;     SID_NAME_USE snu;  LookupAccountName(NULL,strUserName,pSid,&sidBufferSize,domainBuffer,&domainBufferSize,&snu);

 SID_IDENTIFIER_AUTHORITY *psia = GetSidIdentifierAuthority(pSid);  DWORD dwTopAuthority = psia->Value[5];  wsprintf(szBuffer, "S-1-%lu", dwTopAuthority);  TCHAR szTemp[32];  int iSubAuthorityCount = *(GetSidSubAuthorityCount(pSid));  for (int i = 0; i<iSubAuthorityCount; i++)  {   DWORD dwSubAuthority = *(GetSidSubAuthority(pSid, i));   wsprintf(szTemp, "%lu", dwSubAuthority);   strcat(szBuffer, "-");   strcat(szBuffer, szTemp);  }  return &szBuffer[0]; }  

Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=2079118

你可能感兴趣的:(反病毒工具之注册表监视器(VC DLL源码))