I didn't found special limitations for Kernel32.dll. Are there some limitations?
#include "mhook/mhook-lib/mhook.h"
#include <fstream>
typedef BOOL(WINAPI* _CopyFileA)(LPCSTR lpExistingFileName, LPCSTR lpNewFileName, BOOL bFailIfExists);
typedef BOOL(WINAPI* _CopyFileW)(LPCWSTR lpExistingFileName, LPCWSTR lpNewFileName, BOOL bFailIfExists);
typedef BOOL(WINAPI* _CopyFileExA)(LPCSTR lpExistingFileName, LPCSTR lpNewFileName, LPPROGRESS_ROUTINE lpProgressRoutine, LPVOID lpData, LPBOOL pbCancel, DWORD dwCopyFlags);
//////////////////////////////////////////////////////////////////////////
// Defines and typedefs
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
typedef struct _MY_SYSTEM_PROCESS_INFORMATION
{
ULONG NextEntryOffset;
ULONG NumberOfThreads;
LARGE_INTEGER Reserved[3];
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
UNICODE_STRING ImageName;
ULONG BasePriority;
HANDLE ProcessId;
HANDLE InheritedFromProcessId;
} MY_SYSTEM_PROCESS_INFORMATION, *PMY_SYSTEM_PROCESS_INFORMATION;
typedef NTSTATUS (WINAPI *PNT_QUERY_SYSTEM_INFORMATION)(
__in SYSTEM_INFORMATION_CLASS SystemInformationClass,
__inout PVOID SystemInformation,
__in ULONG SystemInformationLength,
__out_opt PULONG ReturnLength
);
//////////////////////////////////////////////////////////////////////////
// Original function
PNT_QUERY_SYSTEM_INFORMATION OriginalNtQuerySystemInformation =
(PNT_QUERY_SYSTEM_INFORMATION)::GetProcAddress(::GetModuleHandle(L"ntdll"), "NtQuerySystemInformation");
_CopyFileA origCPAHandlerPtr = (_CopyFileA)::GetProcAddress(::GetModuleHandle(L"Kernel32"), "CopyFileA");
_CopyFileW origCPWHandlerPtr = (_CopyFileW)::GetProcAddress(::GetModuleHandle(L"Kernel32"), "CopyFileW");
_CopyFileExA origCopyFileExAPtr = (_CopyFileExA)::GetProcAddress(::GetModuleHandle(L"Kernel32"), "CopyFileExA");
//////////////////////////////////////////////////////////////////////////
// Hooked function
BOOL WINAPI HookCopyFileExA(
LPCSTR lpExistingFileName,
LPCSTR lpNewFileName,
LPPROGRESS_ROUTINE lpProgressRoutine,
LPVOID lpData,
LPBOOL pbCancel,
DWORD dwCopyFlags
)
{
std::ofstream("c:/tmp/test.txt", std::ios::app) << "CopyFileA" << std::endl;
if (origCopyFileExAPtr == nullptr)
return FALSE;
return origCopyFileExAPtr(lpExistingFileName, lpNewFileName, lpProgressRoutine, lpData, pbCancel, dwCopyFlags);
}
BOOL WINAPI HookCopyFileA(LPCSTR lpExistingFileName, LPCSTR lpNewFileName, BOOL bFailIfExists)
{
// CallHandler::logCall("CopyFileA", lpExistingFileName, lpNewFileName);
std::ofstream("c:/tmp/test.txt", std::ios::app) << "CopyFileA" << std::endl;
if (origCPAHandlerPtr == nullptr)
return FALSE;
return origCPAHandlerPtr(lpExistingFileName, lpNewFileName, bFailIfExists);
}
BOOL WINAPI HookCopyFileW(LPCWSTR lpExistingFileName, LPCWSTR lpNewFileName, BOOL bFailIfExists)
{
//getHandlers().getOriginFunctionPtr(L"Kernel32.dll", "CopyFileW");
// CallHandler::logCall("CopyFileW", lpExistingFileName, lpNewFileName);
std::ofstream("c:/tmp/test.txt", std::ios::app) << "CopyFileW" << std::endl;
if (origCPWHandlerPtr == nullptr)
return FALSE;
return origCPWHandlerPtr(lpExistingFileName, lpNewFileName, bFailIfExists);
}
NTSTATUS WINAPI HookedNtQuerySystemInformation(
__in SYSTEM_INFORMATION_CLASS SystemInformationClass,
__inout PVOID SystemInformation,
__in ULONG SystemInformationLength,
__out_opt PULONG ReturnLength
)
{
std::ofstream("c:/tmp/test.txt", std::ios::app) << "NtQuerySystemInformation" << std::endl;
NTSTATUS status = OriginalNtQuerySystemInformation(SystemInformationClass,
SystemInformation,
SystemInformationLength,
ReturnLength);
if (SystemProcessInformation == SystemInformationClass && STATUS_SUCCESS == status)
{
//
// Loop through the list of processes
//
PMY_SYSTEM_PROCESS_INFORMATION pCurrent = NULL;
PMY_SYSTEM_PROCESS_INFORMATION pNext = (PMY_SYSTEM_PROCESS_INFORMATION)SystemInformation;
do
{
pCurrent = pNext;
pNext = (PMY_SYSTEM_PROCESS_INFORMATION)((PUCHAR)pCurrent + pCurrent->NextEntryOffset);
if (!wcsncmp(pNext->ImageName.Buffer, L"Calculator.exe", pNext->ImageName.Length))
{
if (0 == pNext->NextEntryOffset)
{
pCurrent->NextEntryOffset = 0;
}
else
{
pCurrent->NextEntryOffset += pNext->NextEntryOffset;
}
pNext = pCurrent;
}
}
while(pCurrent->NextEntryOffset != 0);
}
return status;
}
//////////////////////////////////////////////////////////////////////////
// Entry point
BOOL WINAPI DllMain(
__in HINSTANCE hInstance,
__in DWORD Reason,
__in LPVOID Reserved
)
{
std::ofstream("c:/tmp/test.txt", std::ios::app) << "DllMain" << std::endl;
switch (Reason)
{
case DLL_PROCESS_ATTACH:
std::ofstream("c:/tmp/test.txt", std::ios::app) << "DLL_PROCESS_ATTACH " << Mhook_SetHook((PVOID*)&origCPAHandlerPtr, HookCopyFileA) << std::endl;
std::ofstream("c:/tmp/test.txt", std::ios::app) << "DLL_PROCESS_ATTACH " << Mhook_SetHook((PVOID*)&origCPWHandlerPtr, HookCopyFileW) << std::endl;
// Mhook_SetHook((PVOID*)&OriginalNtQuerySystemInformation, HookedNtQuerySystemInformation);
std::ofstream("c:/tmp/test.txt", std::ios::app) << "DLL_PROCESS_ATTACH " << Mhook_SetHook((PVOID*)&origCopyFileExAPtr, HookCopyFileExA) << std::endl;
break;
case DLL_PROCESS_DETACH:
std::ofstream("c:/tmp/test.txt", std::ios::app) << "DLL_PROCESS_DETACH" << std::endl;
// Mhook_Unhook((PVOID*)&OriginalNtQuerySystemInformation);
Mhook_Unhook((PVOID*)&origCPAHandlerPtr);
Mhook_Unhook((PVOID*)&origCPWHandlerPtr);
Mhook_Unhook((PVOID*)&origCopyFileExAPtr);
break;
default:
std::ofstream("c:/tmp/test.txt", std::ios::app) << "def: " << Reason << std::endl;
}
return TRUE;
}
#include <iostream>
#include <Windows.h>
int main()
{
CopyFileA("c:/tmp/1.txt", "c:/tmp/2.txt", FALSE);
CopyFileW(L"c:/tmp/1.txt", L"c:/tmp/2.txt", FALSE);
std::cout << "Hello World!\n";
}