首页
社区
课程
招聘
Hook CreateFile 时,为什么 notepad 保存文件时检测不到?
发表于: 2016-7-22 13:02 10160

Hook CreateFile 时,为什么 notepad 保存文件时检测不到?

2016-7-22 13:02
10160
这几天一直在做一个 Hook 的小项目,是基于 EasyHook 的,顺便自己学习一下,想做一个检测进程创建文件的工具,我 Hook 了 CreateFileA 和 CreateFileW 两个函数,当 notepad.exe 运行的时候可以看到它 CreateFile 检测了自身是否存在,dwCreationDisposition 参数为 0x00000003。如下图:



但当我用 notepad.exe 另存为一个新的文件时,却看不到它调用 CreateFile* 的信息。请问这是为什么?代码如下:

// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "stdafx.h"
#include "easyhook.h"
#include "DriverShared.h"

#ifndef _WIN64
#pragma comment(lib, "EasyHookLib.lib")
#else
#pragma comment(lib, "EasyHookLib64.lib")
#endif

EXTERN_C BOOL APIENTRY EASYHOOK_DllMain(HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved);

typedef HANDLE(WINAPI *pfnCREATEFILEA)(
	__in     LPCSTR lpFileName,
	__in     DWORD dwDesiredAccess,
	__in     DWORD dwShareMode,
	__in_opt LPSECURITY_ATTRIBUTES lpSecurityAttributes,
	__in     DWORD dwCreationDisposition,
	__in     DWORD dwFlagsAndAttributes,
	__in_opt HANDLE hTemplateFile
	);

typedef HANDLE(WINAPI *pfnCREATEFILEW)(
	__in     LPCWSTR lpFileName,
	__in     DWORD dwDesiredAccess,
	__in     DWORD dwShareMode,
	__in_opt LPSECURITY_ATTRIBUTES lpSecurityAttributes,
	__in     DWORD dwCreationDisposition,
	__in     DWORD dwFlagsAndAttributes,
	__in_opt HANDLE hTemplateFile
	);

HMODULE                 hKernel32 = LoadLibraryA("Kernel32.dll");
TRACED_HOOK_HANDLE      hCreateFileA = new HOOK_TRACE_INFO();
TRACED_HOOK_HANDLE      hCreateFileW = new HOOK_TRACE_INFO();
NTSTATUS                NtStatus;

ULONG                   ACLEntries[1] = { 0 };
ULONG                   HookCreateFileA_ACLEntries[1] = { 0 };
ULONG                   HookCreateFileW_ACLEntries[1] = { 0 };

UNICODE_STRING*         NameBuffer = NULL;
pfnCREATEFILEA			pfnCreateFileA = NULL;
pfnCREATEFILEW			pfnCreateFileW = NULL;

HANDLE WINAPI CreateFileAHook(
	__in     LPCSTR lpFileName,
	__in     DWORD dwDesiredAccess,
	__in     DWORD dwShareMode,
	__in_opt LPSECURITY_ATTRIBUTES lpSecurityAttributes,
	__in     DWORD dwCreationDisposition,
	__in     DWORD dwFlagsAndAttributes,
	__in_opt HANDLE hTemplateFile
)
{
	HANDLE hHandle = NULL;
	DWORD dwError = 0;

	// 执行钩子  
	if (pfnCreateFileA == NULL)
	{
		OutputDebugString(L"pfnCreateFileA is NULL\n");
		return INVALID_HANDLE_VALUE;
	}
	else
	{
		hHandle = (pfnCREATEFILEA)(lpFileName, dwDesiredAccess, dwShareMode,
			lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
		dwError = GetLastError();

		CString csOutput;
		csOutput.Format(_T("CreateFileAHook lpFileName = %s, dwCreationDisposition = 0x%08X"),
			lpFileName, dwCreationDisposition);
		OutputDebugString(csOutput);
	}

	return hHandle;
}

HANDLE WINAPI CreateFileWHook(
	__in     LPCWSTR lpFileName,
	__in     DWORD dwDesiredAccess,
	__in     DWORD dwShareMode,
	__in_opt LPSECURITY_ATTRIBUTES lpSecurityAttributes,
	__in     DWORD dwCreationDisposition,
	__in     DWORD dwFlagsAndAttributes,
	__in_opt HANDLE hTemplateFile)
{
	HANDLE hHandle = NULL;
	DWORD dwError = 0;

	if (pfnCreateFileW == NULL)
	{
		OutputDebugString(_T("pfnCreateFileW is NULL\n"));
		return INVALID_HANDLE_VALUE;
	}
	else
	{
		hHandle = (pfnCREATEFILEW)(lpFileName, dwDesiredAccess, dwShareMode,
			lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
		dwError = GetLastError();

		CString csOutput;
		csOutput.Format(_T("CreateFileWHook lpFileName = %s, dwCreationDisposition = 0x%08X"), 
			lpFileName, dwCreationDisposition);
		OutputDebugString(csOutput);
	}

	return hHandle;
}

BOOL InstallHook()
{
	TCHAR szCurrentProcessName[MAX_PATH] = { 0 };
	GetModuleFileName(NULL, szCurrentProcessName, _countof(szCurrentProcessName));
	OutputDebugString(szCurrentProcessName);

	pfnCreateFileA = (pfnCREATEFILEA)GetProcAddress(hKernel32, "CreateFileA");
	NtStatus = LhInstallHook(pfnCreateFileA, CreateFileAHook, NULL, hCreateFileA);
	if (!SUCCEEDED(NtStatus))
	{
		OutputDebugString(_T("LhInstallHook failed..."));
		return FALSE;
	}

	NtStatus = LhSetInclusiveACL(HookCreateFileA_ACLEntries, 1, hCreateFileA);
	if (!SUCCEEDED(NtStatus))
	{
		OutputDebugString(_T("LhSetInclusiveACL failed..."));
		LhUninstallAllHooks();
		LhUninstallHook(hCreateFileA);
		return FALSE;
	}

	pfnCreateFileW = (pfnCREATEFILEW)GetProcAddress(hKernel32, "CreateFileW");
	if (NULL == pfnCreateFileW)
	{
		OutputDebugString(_T("pfnCreateFileW is NULL"));
	}
	NtStatus = LhInstallHook(pfnCreateFileW, CreateFileWHook, NULL, hCreateFileW);
	if (!SUCCEEDED(NtStatus))
	{
		OutputDebugString(_T("LhInstallHook CreateFileWHook failed..."));
		return FALSE;
	}

	NtStatus = LhSetInclusiveACL(HookCreateFileW_ACLEntries, 1, hCreateFileW);
	if (!SUCCEEDED(NtStatus))
	{
		OutputDebugString(_T("LhSetInclusiveACL CreateFileWHook failed..."));
		LhUninstallAllHooks();
		LhUninstallHook(hCreateFileW);
		return FALSE;
	}

	HANDLE hOpenFile = (HANDLE)CreateFile(PathFindFileName(szCurrentProcessName), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL);
	if (hOpenFile == INVALID_HANDLE_VALUE)
	{
		hOpenFile = NULL;
	}

	return TRUE;
}

BOOL UninstallHook()
{
	LhUninstallAllHooks();

	if (NULL != hCreateFileA)
	{
		LhUninstallHook(hCreateFileA);
		delete hCreateFileA;
		hCreateFileA = NULL;
	}

	if (NULL != hCreateFileW)
	{
		LhUninstallHook(hCreateFileW);
		delete hCreateFileW;
		hCreateFileW = NULL;
	}

	LhWaitForPendingRemovals();
	return TRUE;
}

DWORD WINAPI HookThreadProc(LPVOID lpParamter)
{
	InstallHook();

	return 0;
}

void StartHookThread()
{
	DWORD dwThreadID = 0;
	HANDLE hThread = CreateThread(NULL, 0, HookThreadProc, NULL, 0, &dwThreadID);
	CloseHandle(hThread);
}

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
					 )
{
	switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:
		{
			OutputDebugString(_T("DLL_PROCESS_ATTACH"));
			EASYHOOK_DllMain(hModule, ul_reason_for_call, lpReserved);
			StartHookThread();
		}
		break;
	case DLL_THREAD_ATTACH:
		{
			EASYHOOK_DllMain(hModule, ul_reason_for_call, lpReserved);
		}
		break;
	case DLL_THREAD_DETACH:
		{
			EASYHOOK_DllMain(hModule, ul_reason_for_call, lpReserved);
		}
		break;
	case DLL_PROCESS_DETACH:
		{
			OutputDebugString(_T("DLL_PROCESS_DETACH"));
			UninstallHook();
			EASYHOOK_DllMain(hModule, ul_reason_for_call, lpReserved);
		}
		break;
	}
	return TRUE;
}

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 0
支持
分享
最新回复 (10)
雪    币: 98
活跃值: (79)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2


OD下断点,可以很清楚的看到是调用了CreateFileW函数。仔细检查检查代码。
上传的附件:
2016-7-22 13:29
0
雪    币: 69
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
[QUOTE=bakurise;1437975]

OD下断点,可以很清楚的看到是调用了CreateFileW函数。仔细检查检查代码。[/QUOTE]

是的,没错,的确是调的 CreateFileW 函数,可并没有拦截到,钩子也一直都在。
2016-7-22 13:55
0
雪    币: 69
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5


这两个钩子是在的,但是不工作。
上传的附件:
2016-7-22 14:43
0
雪    币: 878
活跃值: (496)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
6
挂钩后用OD跟
2016-7-22 15:02
0
雪    币: 69
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
OD实在是没用过。
2016-7-22 15:50
0
雪    币: 198
活跃值: (947)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
8
又想到我几年前遇到的这个问题,其实就是,内存映射文件!
2016-7-23 09:13
0
雪    币: 69
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
请教细节原因,能否给一些相关链接或者资料。
2016-7-23 12:43
0
雪    币: 69
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
终于成功了,换 Hook NtCreateFile 后,可以成功捕获到进程调用CreateFile的信息。声明要被Hook的函数原型的调用约定一定要与系统的一模一样。



以下是成功的代码:

// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "stdafx.h"
#include "easyhook.h"
#include "DriverShared.h"

#ifndef _WIN64
#pragma comment(lib, "EasyHookLib.lib")
#else
#pragma comment(lib, "EasyHookLib64.lib")
#endif

EASYHOOK_BOOL_EXPORT EasyHookDllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved);

// NtCreateFile 的函数指针
typedef NTSTATUS(NTAPI* pfnNTCREATEFILE) (
	OUT PHANDLE             FileHandle,
	IN ACCESS_MASK          DesiredAccess,
	IN POBJECT_ATTRIBUTES   ObjectAttributes,
	OUT PVOID               IoStatusBlock,
	IN PLARGE_INTEGER       AllocationSize OPTIONAL,
	IN ULONG                FileAttributes,
	IN ULONG                ShareAccess,
	IN ULONG                CreateDisposition,
	IN ULONG                CreateOptions,
	IN PVOID                EaBuffer OPTIONAL,
	IN ULONG                EaLength
	);

// 全局变量
pfnNTCREATEFILE			pfnNtCreateFile = (pfnNTCREATEFILE)GetProcAddress(GetModuleHandle(_T("ntdll.dll")), "NtCreateFile");
TRACED_HOOK_HANDLE      hHookNtCreateFile = new HOOK_TRACE_INFO();
ULONG                   HookNtCreateFile_ACLEntries[1] = { 0 };

NTSTATUS NTAPI NtCreateFileHook(OUT PHANDLE FileHandle,
	IN ACCESS_MASK DesiredAccess,
	IN POBJECT_ATTRIBUTES ObjectAttributes,
	OUT PIO_STATUS_BLOCK IoStatusBlock,
	IN PLARGE_INTEGER AllocationSize OPTIONAL,
	IN ULONG FileAttributes,
	IN ULONG ShareAccess,
	IN ULONG CreateDisposition,
	IN ULONG CreateOptions,
	IN PVOID EaBuffer OPTIONAL,
	IN ULONG EaLength)
{
	// 打印被打开的文件名参数
	OutputDebugString(ObjectAttributes->ObjectName->Buffer);
	// 调用系统原有的 NtCreateFile
	return pfnNtCreateFile(FileHandle, DesiredAccess, ObjectAttributes,
		IoStatusBlock, AllocationSize, FileAttributes, ShareAccess,
		CreateDisposition, CreateOptions, EaBuffer, EaLength);
}

BOOL InstallHook()
{
	NTSTATUS	status;
	TCHAR		szCurrentProcessName[MAX_PATH] = { 0 };

	GetModuleFileName(NULL, szCurrentProcessName, _countof(szCurrentProcessName));
	OutputDebugString(szCurrentProcessName);

	// 开始 Hook NtCreateFile 函数,使其跳转到自己的 NtCreateFileHook 函数中
	status = LhInstallHook(pfnNtCreateFile, NtCreateFileHook, NULL, hHookNtCreateFile);
	if (!SUCCEEDED(status))
	{
		OutputDebugString(_T("LhInstallHook failed.."));
		return FALSE;
	}

	// 开始 Hook,如果不调用这句,Hook 是不生效的
	status = LhSetExclusiveACL(HookNtCreateFile_ACLEntries, 1, hHookNtCreateFile);
	if (!SUCCEEDED(status))
	{
		OutputDebugString(_T("LhSetInclusiveACL failed.."));
		return FALSE;
	}

	OutputDebugString(_T("InstallHook success..."));

	return TRUE;
}

BOOL UnInstallHook()
{
	LhUninstallAllHooks();

	if (NULL != hHookNtCreateFile)
	{
		LhUninstallHook(hHookNtCreateFile);
		delete hHookNtCreateFile;
		hHookNtCreateFile = NULL;
	}

	LhWaitForPendingRemovals();

	OutputDebugString(_T("UninstallHook success..."));

	return TRUE;
}

DWORD WINAPI HookThreadProc(LPVOID lpParamter)
{
	InstallHook();
	return 0;
}

void StartHookThread()
{
	DWORD dwThreadID = 0;
	HANDLE hThread = CreateThread(NULL, 0, HookThreadProc, NULL, 0, &dwThreadID);
	CloseHandle(hThread);
}

BOOL APIENTRY DllMain(HMODULE hModule,
	DWORD  ul_reason_for_call,
	LPVOID lpReserved
)
{
	// 调用 EasyHook 的入口处理函数
	EasyHookDllMain(hModule, ul_reason_for_call, lpReserved);
	switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:
	{
		// 调用 InstallHook 的线程
		StartHookThread();
		OutputDebugString(_T("DLL_PROCESS_ATTACH"));
	}
	break;
	case DLL_THREAD_ATTACH:
		break;
	case DLL_THREAD_DETACH:
		break;
	case DLL_PROCESS_DETACH:
	{
		// 调用 UnInstallHook 的线程
		UnInstallHook();
		OutputDebugString(_T("DLL_PROCESS_DETACH"));
	}
	break;
	}
	return TRUE;
}
上传的附件:
2016-7-23 15:40
0
雪    币: 69
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
我参考了这篇文章,写的非常不错。
http://bbs.csdn.net/topics/360151840
2016-7-23 15:41
0
雪    币: 260
活跃值: (36)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
学习下这篇文章
2016-7-29 16:30
0
游客
登录 | 注册 方可回帖
返回
//