反病毒工具之注册表监视器(VC DLL源码)
来源:互联网 发布:ingress是什么软件 编辑:程序博客网 时间:2024/06/05 16:49
核心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;}
//获取指定用户的SIDchar *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源码)
- 反病毒工具之注册表监视器(VC DLL源码) (chenhui530)
- 反病毒工具之注册表监视器(VC DLL源码)
- 反病毒工具之注册表监视器(VC DLL源码)
- 病毒工具之注册表监视器(VC DLL源码)
- 反病毒工具之注册表监视器
- 反病毒工具之注册表监视器
- 反病毒工具之注册表监视器
- 反病毒工具之病毒诊断程序
- 反病毒工具-VirtualKD
- 反病毒工具-PEiD
- 反病毒工具-ExeInfoPE
- 反病毒工具-C32ASM
- 反病毒工具-LordPE
- 反病毒工具-WinDBG
- 反病毒工具-X64Dbg
- 反病毒工具-IDA
- 反病毒工具-Wireshark
- OpenMP与C++:事半功倍地获得多线程的好处(下)
- 9种没结果的爱
- Ubuntu8.04 AMD64下MPlayer解码器路径
- OpenMP与C++:事半功倍地获得多线程的好处(上)
- Access 导入到SQL 2005
- 反病毒工具之注册表监视器(VC DLL源码)
- 平衡二叉树
- C#和硬件驱动交互编程
- UI界面设计闪烁问题的解决办法
- 开源Jabber(XMPP) IM服务器介绍
- 如何在windows下安装pygtk?
- RUP
- HTTP头协议
- 揭秘:成为最牛程序员的五大要诀