Aquí os dejo el código:
/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* Blau (indetectables.net) wrote this file. As long as you retain this notice you
* can do whatever you want with this stuff. If we meet some day, and you think
* this stuff is worth it, you can buy me a beer in return.
* ----------------------------------------------------------------------------
*/
#include <Windows.h>
#include <iostream>
using namespace std;
void PrintFile(char* szFileName);
/** HOOKS **/
// https://www.codeproject.com/kb/winsdk/libminhook.aspx
// Disponible por NuGet
#include <MinHook.h>
typedef HANDLE (WINAPI * THookCreateFileA)(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile);
THookCreateFileA OriginalCreateFileA = (THookCreateFileA) GetProcAddress(GetModuleHandleA("kernel32.dll"), "CreateFileA");
typedef BOOL(WINAPI * TReadFile)(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped);
TReadFile OriginalReadFile = (TReadFile)GetProcAddress(GetModuleHandleA("kernel32.dll"), "ReadFile");
typedef BOOL(WINAPI * TCloseHandle)(HANDLE);
TCloseHandle OriginalCloseHandle = (TCloseHandle)GetProcAddress(GetModuleHandleA("kernel32.dll"), "CloseHandle");
HANDLE WINAPI HookCreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile);
BOOL WINAPI HookReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped);
BOOL WINAPI HookCloseHandle(HANDLE hFile);
/** CONFIG **/
#define TARGET_FILE "dummy.txt"
#define MAPPING_NAME "Local\\dummy.txt"
/** VARIABLES GLOBALES **/
char g_FileText[] = "This is a virtual text file.";
DWORD g_FileSize = strlen(g_FileText) + 1;
HANDLE g_FileHandle = INVALID_HANDLE_VALUE;
int main()
{
// Reemplazamos algunas funciones por las nuestras gracias a MinHook
MH_Initialize();
MH_CreateHookApi(L"kernel32", "CreateFileA", HookCreateFileA, reinterpret_cast<LPVOID*>(&OriginalCreateFileA));
MH_CreateHookApi(L"kernel32", "ReadFile", HookReadFile, reinterpret_cast<LPVOID*>(&OriginalReadFile));
MH_CreateHookApi(L"kernel32", "CloseHandle", HookCloseHandle, reinterpret_cast<LPVOID*>(&OriginalCloseHandle));
MH_EnableHook(MH_ALL_HOOKS);
// Mostramos el contenido del archivo después de realizar los hooks
PrintFile(TARGET_FILE);
// Desactivamos los hooks
MH_DisableHook(MH_ALL_HOOKS);
MH_Uninitialize();
return 0;
}
void PrintFile(char* szFileName) {
// Abrimos el archivo y mostramos el contenido por consola
HANDLE hFile = CreateFileA(szFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
DWORD dwFileSize = GetFileSize(hFile, NULL);
char* szFileText = new char[1024];
DWORD dwBytesRead;
ReadFile(hFile, LPVOID(szFileText), dwFileSize, &dwBytesRead, NULL);
CloseHandle(hFile);
szFileText[dwBytesRead] = 0; // null char
cout << szFileText << endl;
delete[] szFileText;
}
// Esta función es la que se ejecutará cuando se llame a la función 'CreateFileA'
HANDLE WINAPI HookCreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile) {
if (strcmp(lpFileName, TARGET_FILE) == 0) {
// Si el archivo a abrir (lpFileName) es nuestro archivo, entonces empezamos el mapeo
HANDLE hMapFile = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, g_FileSize, MAPPING_NAME);
if (hMapFile == NULL) {
cout << "Cannot create file mapping. Error code: " << GetLastError() << endl;
}
LPVOID lpMapFile = MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, g_FileSize);
if (lpMapFile == NULL) {
cout << "Cannot map file. Error code: " << GetLastError() << endl;
}
CopyMemory(lpMapFile, g_FileText, g_FileSize);
g_FileHandle = hMapFile;
return hMapFile;
}
else {
// Si es cualquier otro archivo llamaremos a la función original
return OriginalCreateFileA(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
}
}
BOOL WINAPI HookReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped) {
if (hFile == g_FileHandle) {
HANDLE hMapFile = OpenFileMappingA(FILE_MAP_ALL_ACCESS, FALSE, MAPPING_NAME);
if (hMapFile == NULL) {
return FALSE;
}
LPVOID lpMapFile = MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, g_FileSize);
if (lpMapFile == NULL) {
return FALSE;
}
CopyMemory(lpBuffer, lpMapFile, g_FileSize);
*lpNumberOfBytesRead = g_FileSize;
UnmapViewOfFile(lpMapFile);
CloseHandle(hMapFile);
return TRUE;
}
else {
return OriginalReadFile(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped);
}
}
BOOL WINAPI HookCloseHandle(HANDLE hFile) {
if (hFile == g_FileHandle) {
return (OriginalCloseHandle(g_FileHandle) && OriginalCloseHandle(hFile));
}
else {
return OriginalCloseHandle(hFile);
}
}