大家好,我已经通过挂钩两个函数开发了一个版本,即 1) NtCreateFile 和 2) NtSetInformationFile 用于监视 File Raname、Delete、Create。它在安装了 Visual Studio 的 Windows-7 32 和 64 位上工作正常,但如果没有安装 Visual Studio,它就不能正常工作。请帮助我。我的代码如下
#include "stdafx.h"
#include <windows.h>
#include "MinHook.h"
#include <Winternl.h>
#include <stdio.h>
#include <shlwapi.h>
#include <tchar.h>
#include <string.h>
#if defined _M_X64
#pragma comment(lib, "libMinHook.x64.lib")
#elif defined _M_IX86
#pragma comment(lib, "libMinHook.x86.lib")
#endif
#define FILE_SUPERSEDED 0x00000000
#define FILE_OPENED 0x00000001
#define FILE_CREATED 0x00000002
#define FILE_OVERWRITTEN 0x00000003
#define FILE_EXISTS 0x00000004
#define FILE_DOES_NOT_EXIST 0x00000005
#define FILE_RENAMED 10
#define FILE_DELETED 13
#define FILE_MODIFIED 19
enum OBJECT_INFORMATION_CLASS
{
ObjectNameInformation = 1
};
struct MOUNTMGR_TARGET_NAME
{
USHORT DeviceNameLength;
WCHAR DeviceName[1];
};
struct MOUNTMGR_VOLUME_PATHS
{
ULONG MultiSzLength;
WCHAR MultiSz[1];
};
struct FILE_NAME_INFORMATION
{
ULONG FileNameLength;
WCHAR FileName[1];
};
union ANY_BUFFER
{
WCHAR Buffer[USHRT_MAX];
MOUNTMGR_TARGET_NAME TargetName;
MOUNTMGR_VOLUME_PATHS TargetPaths;
FILE_NAME_INFORMATION NameInfo;
UNICODE_STRING UnicodeString;
};
typedef struct _FILE_RENAME_INFORMATION
{
BOOLEAN ReplaceIfExists;
HANDLE RootDirectory;
ULONG FileNameLength;
WCHAR FileName[1];
} FILE_RENAME_INFORMATION, *PFILE_RENAME_INFORMATION;
extern "C" NTSYSAPI NTSTATUS NTAPI NtQueryObject(HANDLE Handle OPTIONAL, OBJECT_INFORMATION_CLASS ObjectInformationClass, PVOID ObjectInformation OPTIONAL, ULONG ObjectInformationLength, PULONG ReturnLength OPTIONAL);
extern "C" NTSYSAPI NTSTATUS NTAPI NtCreateFile(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes,
PIO_STATUS_BLOCK IoStatusBlock, PLARGE_INTEGER AllocationSize, ULONG FileAttributes,
ULONG ShareAccess, ULONG CreateDisposition, ULONG CreateOptions, PVOID EaBuffer, ULONG EaLength);
extern "C" NTSYSAPI NTSTATUS NTAPI NtSetInformationFile(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID FileInformation,
ULONG Length, FILE_INFORMATION_CLASS FileInformationClass);
//AnsiToUnicode Function ;
HRESULT __fastcall AnsiToUnicode(LPCSTR pszA, LPOLESTR* ppszW)
{
ULONG cCharacters;
DWORD dwError;
if (NULL == pszA)
{
*ppszW = NULL;
return NOERROR;
}
cCharacters = strlen(pszA) + 1;
*ppszW = (LPOLESTR) CoTaskMemAlloc(cCharacters*2);
if (NULL == *ppszW)
return E_OUTOFMEMORY;
// Covert to Unicode.
if (0 == MultiByteToWideChar(CP_ACP, 0, pszA, cCharacters, *ppszW, cCharacters))
{
dwError = GetLastError();
CoTaskMemFree(*ppszW);
*ppszW = NULL;
return HRESULT_FROM_WIN32(dwError);
}
return NOERROR;
}
//UnicodeToAnsi Function;
HRESULT __fastcall UnicodeToAnsi(LPCOLESTR pszW, LPSTR* ppszA)
{
ULONG cbAnsi, cCharacters;
DWORD dwError;
if (pszW == NULL)
{
*ppszA = NULL;
return NOERROR;
}
cCharacters = wcslen(pszW) + 1;
cbAnsi = cCharacters*2;
*ppszA = (LPSTR) CoTaskMemAlloc (cbAnsi);
if (NULL == *ppszA)
return E_OUTOFMEMORY;
// Convert to ANSI.
if (0 == WideCharToMultiByte(CP_ACP, 0, pszW, cCharacters, *ppszA, cbAnsi, NULL, NULL))
{
dwError = GetLastError();
CoTaskMemFree(*ppszA);
*ppszA = NULL;
return HRESULT_FROM_WIN32(dwError);
}
return NOERROR;
}
char *replace(const char *s, const char *old, const char *newstr)
{
char *ret = NULL, *sr = NULL;
size_t i, count = 0;
size_t newlen = strlen(newstr);
size_t oldlen = strlen(old);
if (newlen != oldlen)
{
for (i = 0; s[i] != '\0'; )
{
if (memcmp(&s[i], old, oldlen) == 0)
count++, i += oldlen;
else
i++;
}
}
else
i = strlen(s);
ret = (char*) malloc(i + 1 + count * (newlen - oldlen));
if (ret == NULL)
return NULL;
sr = ret;
while (*s)
{
if (memcmp(s, old, oldlen) == 0)
{
memcpy(sr, newstr, newlen);
sr += newlen;
s += oldlen;
}
else
*sr++ = *s++;
}
*sr = '\0';
return ret;
}
void GetFileNameFromVolumeName(wchar_t * VolumeName, wchar_t * FilePath)
{
wchar_t *Ptr = NULL ;
if ((Ptr = StrStrIW(VolumeName, L"\\device\\mup"))!= NULL)
{
wcscpy(FilePath, Ptr + 11);
return;
}
if ((Ptr = StrStrIW(VolumeName, L"\\??\\UNC"))!= NULL)
{
wcscpy(FilePath, Ptr + 7);
return;
}
if ((Ptr = StrStrIW(VolumeName, L"\\??\\"))!= NULL)
{
wcscpy(FilePath, Ptr + 4);
return;
}
}
void GetFileNameFromDeviceName (wchar_t * DevicePath,wchar_t * FilePath)
{
int i, j = 0;
DWORD test, mydrives = 100;
wchar_t *lpBuffer = new wchar_t[100];
wchar_t *lpTargetPath = new wchar_t[1000];
wchar_t *drives = new wchar_t[26];
wchar_t *str1 = new wchar_t[512] ;
wchar_t *pch;
test = GetLogicalDriveStringsW(mydrives, lpBuffer);
if (test != 0)
{
for (i = 0; i < 100; i += 4)
{
wsprintf(drives + j,L"%c:", lpBuffer[i]);
if (wcslen(drives + j) == 0) break;
QueryDosDeviceW((LPCWSTR)drives + j, lpTargetPath, 1000);
if ((pch = StrStrIW(DevicePath, lpTargetPath)) != NULL)
{
wcscpy(str1, drives + j);
wcsncat(str1, DevicePath + wcslen(lpTargetPath), wcslen(DevicePath) - wcslen(lpTargetPath));
wcscpy(FilePath, str1);
delete drives;
delete str1 ;
break;
}
j+= 2;
}
delete lpBuffer;
delete lpTargetPath;
}
}
void GetFilePath(HANDLE hFile, wchar_t *filename)
{
static ANY_BUFFER nameFull, nameRel, nameMnt;
ULONG returnedLength;
NTSTATUS status;
status = NtQueryObject(hFile, ObjectNameInformation, nameFull.Buffer, sizeof(nameFull.Buffer), &returnedLength);
wchar_t *ptr = wcschr(nameFull.UnicodeString.Buffer, L'\\');
if (StrStrIW(ptr, L"device\\mup") == NULL)
GetFileNameFromDeviceName(ptr, filename);
else
GetFileNameFromVolumeName(ptr, filename);
}
typedef NTSTATUS(WINAPI *NtCreateFileNext)(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes,
PIO_STATUS_BLOCK IoStatusBlock, PLARGE_INTEGER AllocationSize, ULONG FileAttributes,
ULONG ShareAccess, ULONG CreateDisposition, ULONG CreateOptions, PVOID EaBuffer, ULONG EaLength);
NtCreateFileNext Real_NtCreateFileData = NULL;
NTSTATUS WINAPI NtCreateFileCallback(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes,
PIO_STATUS_BLOCK IoStatusBlock, PLARGE_INTEGER AllocationSize, ULONG FileAttributes,
ULONG ShareAccess, ULONG CreateDisposition, ULONG CreateOptions, PVOID EaBuffer, ULONG EaLength)
{
LPSTR buff = NULL ;
HRESULT res = 0;
LPOLESTR AnsiToUniBuf = {0};
NTSTATUS status;
POBJECT_ATTRIBUTES OAttributes ;
status = Real_NtCreateFileData(FileHandle, DesiredAccess, ObjectAttributes, IoStatusBlock, AllocationSize, FileAttributes, ShareAccess, CreateDisposition, CreateOptions, EaBuffer, EaLength);
char * buffer = new char [MAX_PATH];
char * buff2 = new char [MAX_PATH];
wchar_t *FileCreated = new wchar_t[512];
if (IoStatusBlock->Information == FILE_CREATED)
{
GetFileNameFromVolumeName(ObjectAttributes->ObjectName->Buffer, FileCreated);
MessageBoxW(NULL, FileCreated, L"Created", MB_OK);
/*UnicodeToAnsi( ObjectAttributes->ObjectName->Buffer, &buff);
for (int i = 0 ; i < strlen(buff) ; i++)
{
buff2[i] = tolower(buff[i]);
}
buffer = replace(buff2, "\\??\\c:", "\\??\\d:");
AnsiToUnicode(buffer,&AnsiToUniBuf);
wcscpy(ObjectAttributes->ObjectName->Buffer, AnsiToUniBuf);*/
}
delete buffer;
delete buff2;
delete FileCreated;
return status;
}
typedef NTSTATUS(WINAPI *NtSetInformationFileNext)(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID FileInformation,
ULONG Length, FILE_INFORMATION_CLASS FileInformationClass);
NtSetInformationFileNext Real_NtSetInformationFileData = NULL;
NTSTATUS WINAPI NtSetInformationFileCallback(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID FileInformation,
ULONG Length, FILE_INFORMATION_CLASS FileInformationClass)
{
wchar_t * renfrom = new wchar_t[512];
if (FileInformationClass == FILE_DELETED)
{
memset(renfrom, 0, sizeof(wchar_t)*512);
GetFilePath(FileHandle,renfrom);
MessageBoxW(NULL, renfrom, L"Deleted File", MB_OK);
}
if (FileInformationClass == FILE_RENAMED)
{
memset(renfrom, 0, sizeof(wchar_t)*512);
FILE_RENAME_INFORMATION *pInfo = NULL;
pInfo=(PFILE_RENAME_INFORMATION)FileInformation;
GetFilePath(FileHandle,renfrom);
MessageBoxW(NULL, renfrom, L"Renamed From", MB_OK);
memset(renfrom, 0, sizeof(wchar_t)*512);
GetFileNameFromVolumeName(pInfo->FileName, renfrom);
MessageBoxW(NULL, renfrom, L"Renamed To", MB_OK);
}
if (FileInformationClass == FILE_MODIFIED)
{
memset(renfrom, 0, sizeof(wchar_t)*512);
GetFilePath(FileHandle,renfrom);
MessageBoxW(NULL, renfrom, L"Modified File", MB_OK);
}
delete renfrom;
return Real_NtSetInformationFileData(FileHandle, IoStatusBlock, FileInformation, Length, FileInformationClass);
}
//DllMain Function
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
//HINSTANCE hwnd = LoadLibraryA("ntdll.dll");
//if (hwnd != NULL)
//{
// Actual_NtCreateFileData = (NtCreateFileNext)GetProcAddress(hwnd, "NtCreateFile");
// //Actual_NtSetInformationFileData = (NtSetInformationFileNext)(hwnd, "NtSetInformationFile");
//}
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
if (MH_Initialize() != MH_OK)
{
MessageBoxW(NULL, L"Failed Initialize", L"Info!", MB_ICONWARNING|MB_OK);
}
if (MH_CreateHook(&NtCreateFile, &NtCreateFileCallback, reinterpret_cast<void**>(&Real_NtCreateFileData)) != MH_OK)
{
MessageBoxW(NULL, L"Failed CreateHook NtCreateFile", L"Info!", MB_ICONWARNING|MB_OK);
}
if (MH_EnableHook(&NtCreateFile) != MH_OK)
{
MessageBoxW(NULL, L"Failed EnableHook NtCreateFile", L"Info!", MB_ICONWARNING|MB_OK);
}
if (MH_CreateHook(&NtSetInformationFile, &NtSetInformationFileCallback, reinterpret_cast<void**>(&Real_NtSetInformationFileData)) != MH_OK)
{
MessageBoxW(NULL, L"Failed CreateHook NtSetInformationFile", L"Info!", MB_ICONWARNING|MB_OK);
}
if (MH_EnableHook(&NtSetInformationFile) != MH_OK)
{
MessageBoxW(NULL, L"Failed EnableHook NtSetInformationFile", L"Info!", MB_ICONWARNING|MB_OK);
}
break;
case DLL_PROCESS_DETACH:
if (MH_Uninitialize() != MH_OK)
{
}
if (MH_DisableHook(&NtCreateFile) != MH_OK)
{
}
if (MH_DisableHook(&NtSetInformationFile) != MH_OK)
{
}
break;
}
return TRUE;
}
上面的代码构建良好,如果尝试在安装了 Visual Studio 的 Windows-7 32/64 位上的资源管理器进程中注入此 dll,则在构建后它正在注入并且工作正常,但它没有在 Windows 的任何进程中注入-7 未安装 Visual Studio 的 32/64 位机器。请帮助我