0

大家好,我已经通过挂钩两个函数开发了一个版本,即 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 位机器。请帮助我

4

1 回答 1

2

在不工作的机器上运行Dependency Walker 。这将向您显示缺少哪些 DLL:

http://www.dependencywalker.com

于 2012-08-25T13:39:47.123 回答