2012-08-24 4 views
0

안녕하세요. 1) NtCreateFile 및 의 두 가지 기능을 연결하여 하나의 빌드를 개발했습니다. 2) 파일 Raname, 삭제, 만들기를 모니터링하기위한 NtSetInformationFile. 그것은 Visual Studio가 설치되어 있지만 그것이 Visual Studio가 설치되어 있지 않은 경우 동일하게 작동하지 않는 Windows-7 32 및 64 비트에서 잘 작동합니다. 제게 도움이됩니다.Visual Studio가 설치되지 않은 컴퓨터에서 My Build가 작동하지 않습니다.

#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; 
} 

위의 코드에 탐색기 과정에서이 DLL을 주입하려고하면이 구축 얻을 잘 구축하고 이후 따를 때 내 코드는 비주얼 스튜디오와 32/64 비트가 주입하고 잘 작동 설치 윈도우 7 하지만 그것은 Visual Studio가 설치되어 있지 않은 Windows-7 32/64 비트 컴퓨터에 대한 프로세스 중 아무 것도 주입하지 않습니다. 도움 말

+2

당신은 아마 [이런] 뭔가를 (원하는 http://www.microsoft.com/en-gb/download/details.aspx?id=8328 : 그 DLL을 누락하는 당신을 보여 드리죠). 원하는 패키지는 Visual Studio 버전에 따라 다릅니다. – arx

답변

관련 문제