原理介绍:
Nt系统下用户层(Ring3)下写注册表的程序大都调用ntdll.dll导出的ZwSetValueKey,该API简单通过int 2e并传递一个服务号进入内核调用同名系统服务(NTSetValueKey)。所以在用户层(Ring3)下拦截写注册表的操作最后的也是最底层的方法便是拦截该API。
同时为了实时监控系统中当前运行的所有进程对该API的直接或者间接调用,需要对所有进程进行代码注入。对于新创建的进程,Xp系统下用户层最后一道入口是ZwCreateProcessEx,他也是由ntdll.dll导出。在枚举出系统中所有进程之后,便可以通过对该API的拦截第一时间对新创建的进程进行拦截。需要补充说明的是在用户层创建进程执行到这个API时,进程空间已经创建,且仅仅加载了ntdll.dll模块以及进程自身的映象。这时可以通过修改ntdll.dll中该API的入口实现对其创建的子进程拦截。
关于 API拦截的具体原理分析和简单实现,前面的文章已经说得很清楚了。这里只是给出大体流程图和代码。
测试方法:
程序运行后,输入你想要监视的进程ID,这时该进程,以及该进程所创建的任何进程都将被监视,并且在其修改注册表的时候弹出对话框询问是否允许进行该次注册表修改操作,点'y'允许操作,否则拒绝操作. (刚刚修改了一下,可以查看进程id和名称,同时从控制台接受进程id的输入,从而对指定的进程监控)
流程图:
源代码:
#include
<
stdio.h
>
#include < windows.h >
#define STATUS_SUCCESS (0)
#define ObjectNameInformation (1)
#define BLOCKSIZE (0x1000)
#define CurrentProcessHandle ((HANDLE)(0xFFFFFFFF))
#define NT_PROCESS_LIST 5
#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 _RemoteParam ... {
LPVOID lpFunAddr;
DWORD dwParamSize;
LPVOID lpHeapAlloc;
LPVOID lpGetProcessHeap;
LPVOID lpHeapReAlloc;
LPVOID lpHeapFree;
LPVOID lpwsprintf;
LPVOID lpZwQueryObject;
LPVOID lpMessageBox;
LPVOID lpWriteProcessMemory;
wchar_t wProcessName[36];
unsigned char szOldCode[12];
unsigned char szNewCode[12];
LPVOID lpResumeThread;
LPVOID lpCreateEvent;
LPVOID lpOpenEvent;
LPVOID lpOpenFileMapping;
LPVOID lpMapViewOfFile;
LPVOID lpUnMapViewOfFile;
LPVOID lpOpenMutex;
LPVOID lpWaitForSingleObject;
LPVOID lpSetEvent;
LPVOID lpReleaseMutex;
LPVOID lpCloseHandle;
LPVOID lpGetProcessId;
LPVOID lpGetLastError;
} RemoteParam, * PRemoteParam;
typedef struct _SYSTEM_PROCESSES ... {
ULONG NextEntryDelta; //构成结构序列的偏移量;
ULONG ThreadCount; //线程数目;
ULONG Reserved1[6];
LARGE_INTEGER CreateTime; //创建时间;
LARGE_INTEGER UserTime; //用户模式(Ring 3)的CPU时间;
LARGE_INTEGER KernelTime; //内核模式(Ring 0)的CPU时间;
UNICODE_STRING ProcessName; //进程名称;
ULONG BasePriority; //进程优先权;
ULONG ProcessId; //进程标识符;
} SYSTEM_PROCESSES, * PSYSTEM_PROCESSES;
typedef
NTSTATUS
(__stdcall * NTQUERYSYSTEMINFORMATION)(
IN SYSTEM_INFORMATION_CLASS,
OUT PVOID,
IN ULONG,
OUT PULONG);
typedef
BOOL
(__stdcall * PFN_WRITEPROCESSMEMORY)(
IN HANDLE hProcess,
IN LPVOID lpBaseAddress,
IN LPCVOID lpBuffer,
IN SIZE_T nSize,
OUT SIZE_T * lpNumberOfBytesWritten
);
typedef
int
(__stdcall * PFN_MESSAGEBOX)(
IN HWND hWnd,
IN LPCWSTR lpText,
IN LPCWSTR lpCaption,
IN UINT uType
);
typedef
int
(__cdecl * PFN_WSPRINTF)(
IN LPWSTR lpOut,
IN LPCWSTR lpFmt,
...);
typedef
HANDLE
(__stdcall * PFN_GETPROCESSHEAP)( void );
typedef
LPVOID
(__stdcall * PFN_HEAPALLOC)(
IN HANDLE hHeap,
IN DWORD dwFlags,
IN SIZE_T dwBytes
);
typedef
LPVOID
(__stdcall * PFN_HEAPREALLOC)(
IN HANDLE hHeap,
IN DWORD dwFlags,
IN LPVOID lpMem,
IN DWORD dwBytes
);
typedef
BOOL
(__stdcal
#include < windows.h >
#define STATUS_SUCCESS (0)
#define ObjectNameInformation (1)
#define BLOCKSIZE (0x1000)
#define CurrentProcessHandle ((HANDLE)(0xFFFFFFFF))
#define NT_PROCESS_LIST 5
#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 _RemoteParam ... {
LPVOID lpFunAddr;
DWORD dwParamSize;
LPVOID lpHeapAlloc;
LPVOID lpGetProcessHeap;
LPVOID lpHeapReAlloc;
LPVOID lpHeapFree;
LPVOID lpwsprintf;
LPVOID lpZwQueryObject;
LPVOID lpMessageBox;
LPVOID lpWriteProcessMemory;
wchar_t wProcessName[36];
unsigned char szOldCode[12];
unsigned char szNewCode[12];
LPVOID lpResumeThread;
LPVOID lpCreateEvent;
LPVOID lpOpenEvent;
LPVOID lpOpenFileMapping;
LPVOID lpMapViewOfFile;
LPVOID lpUnMapViewOfFile;
LPVOID lpOpenMutex;
LPVOID lpWaitForSingleObject;
LPVOID lpSetEvent;
LPVOID lpReleaseMutex;
LPVOID lpCloseHandle;
LPVOID lpGetProcessId;
LPVOID lpGetLastError;
} RemoteParam, * PRemoteParam;
typedef struct _SYSTEM_PROCESSES ... {
ULONG NextEntryDelta; //构成结构序列的偏移量;
ULONG ThreadCount; //线程数目;
ULONG Reserved1[6];
LARGE_INTEGER CreateTime; //创建时间;
LARGE_INTEGER UserTime; //用户模式(Ring 3)的CPU时间;
LARGE_INTEGER KernelTime; //内核模式(Ring 0)的CPU时间;
UNICODE_STRING ProcessName; //进程名称;
ULONG BasePriority; //进程优先权;
ULONG ProcessId; //进程标识符;
} SYSTEM_PROCESSES, * PSYSTEM_PROCESSES;
typedef
NTSTATUS
(__stdcall * NTQUERYSYSTEMINFORMATION)(
IN SYSTEM_INFORMATION_CLASS,
OUT PVOID,
IN ULONG,
OUT PULONG);
typedef
BOOL
(__stdcall * PFN_WRITEPROCESSMEMORY)(
IN HANDLE hProcess,
IN LPVOID lpBaseAddress,
IN LPCVOID lpBuffer,
IN SIZE_T nSize,
OUT SIZE_T * lpNumberOfBytesWritten
);
typedef
int
(__stdcall * PFN_MESSAGEBOX)(
IN HWND hWnd,
IN LPCWSTR lpText,
IN LPCWSTR lpCaption,
IN UINT uType
);
typedef
int
(__cdecl * PFN_WSPRINTF)(
IN LPWSTR lpOut,
IN LPCWSTR lpFmt,
...);
typedef
HANDLE
(__stdcall * PFN_GETPROCESSHEAP)( void );
typedef
LPVOID
(__stdcall * PFN_HEAPALLOC)(
IN HANDLE hHeap,
IN DWORD dwFlags,
IN SIZE_T dwBytes
);
typedef
LPVOID
(__stdcall * PFN_HEAPREALLOC)(
IN HANDLE hHeap,
IN DWORD dwFlags,
IN LPVOID lpMem,
IN DWORD dwBytes
);
typedef
BOOL
(__stdcal