When I inject this DLL via the conventional LoadLibrary method, the DLL is injected and when I attach it to the process (notepad.exe) and run it in a debugger, it seems to work.
However, when I type some characters in Notepad or save the file to disk, it calls the original WriteFile function, not the custom Hook function.
When I perform these actions in notepad and monitor it via rohitab's API monitor, notepad calls the native NtWriteFile when I type something (it saves the data to a temporary file) and it calls WriteFile when the user saves the file manually on disk.
Anyway, someone once said that possibly loaderlock occurs, is that the case? I don't call one of these functions from DLL main though? https://learn.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-best-practices
Can someone please help me? I'm not a pro in C, so maybe I made some rooky mistakes but can't find them..
*Note: for some reason, when I remove the fprintf statements, I get an error:
"Debug assertion failed"
#include "pch.h"
#include <windows.h>
#include <stdio.h>
#include <psapi.h>
#include <string.h>
#include <wchar.h>
FILE* file_pointer;
FILE* write_file;
HMODULE array_modules[1024];
DWORD number_bytes;
DWORD WB = 0;
WCHAR BUFFER[1024]; //Unicode characters
int i;
char BUFFER_OUTPUT[] = "test1"; //Unicode characters
typedef int(WINAPI* Func_Pointer)(HANDLE, LPCVOID, DWORD, LPDWORD, LPOVERLAPPED);
Func_Pointer Original_VA_WriteFile = NULL;
BOOL WINAPI WriteFile_HOOK(HANDLE hFile, LPCVOID lpBuffer,
DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten,
LPOVERLAPPED lpOverlapped)
{
fopen_s(&write_file, "C:\\Users\\Mikail\\Documents\\outputinjectedDLL7.txt", "w+");
fprintf(write_file, "test");
fclose(write_file);
return Original_VA_WriteFile(hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, lpOverlapped);
}
BOOL APIENTRY DllMain(HMODULE Base_DLL_Address, DWORD Reason_CALL, LPVOID Reserved)
{
switch (Reason_CALL)
{
case DLL_PROCESS_ATTACH:
MessageBoxA(NULL, "OK", "01", MB_OK);
Original_VA_WriteFile = WriteFile;
DWORD PID = GetCurrentProcessId();
HANDLE Handle_Process = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID);
if (Handle_Process == NULL) {
DWORD error = GetLastError();
fprintf(file_pointer, "Handle not retrieved %s", error);
}
else {
fopen_s(&file_pointer, "C:\\Users\\Mikail\\Documents\\outputinjectedDLL10.txt", "w+");
fprintf(file_pointer, "\nVA of WriteFile_HOOK is :%p", WriteFile_HOOK);
char* ImageBase = NULL;
if (EnumProcessModules(Handle_Process, array_modules, sizeof(array_modules), &number_bytes) != 0) {
for (i = 0; i < (number_bytes / sizeof(HMODULE)); i++) {
DWORD Module_LEN_string = GetModuleFileNameEx(Handle_Process, array_modules[i], BUFFER, sizeof(BUFFER));
if (wcsstr(BUFFER, L"Notepad.exe") != NULL) {
ImageBase = array_modules[i];
fprintf(file_pointer, "\nImagebase: %p", ImageBase);
PIMAGE_DOS_HEADER dosHeaders = (PIMAGE_DOS_HEADER)ImageBase;
fprintf(file_pointer, "\ndosHeader: %p", dosHeaders);
PIMAGE_NT_HEADERS ntHeaders = (PIMAGE_NT_HEADERS)((DWORD_PTR)ImageBase + dosHeaders->e_lfanew);
fprintf(file_pointer, "\nntHeader: %p", ntHeaders);
IMAGE_DATA_DIRECTORY ImportsDirectory_RVA = ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
PIMAGE_IMPORT_DESCRIPTOR Import_Directory = (PIMAGE_IMPORT_DESCRIPTOR)(ImportsDirectory_RVA.VirtualAddress + (DWORD_PTR)ImageBase);
fprintf(file_pointer, "\nImport Directory: %p", Import_Directory);
while (Import_Directory->Name != NULL)
{
char* Module_AA = (char*)(ImageBase + Import_Directory->Name);
PIMAGE_THUNK_DATA OFT_value = (LPCSTR)Import_Directory->OriginalFirstThunk; //RVA_OFT
PIMAGE_THUNK_DATA PointerModule_AA_OFT = (LPCSTR)Import_Directory->OriginalFirstThunk + (DWORD_PTR)ImageBase; //VA_OFT
PIMAGE_THUNK_DATA PointerModule_AA_FT = (LPCSTR)Import_Directory->FirstThunk + (DWORD_PTR)ImageBase; //(R)VA_FT
if (strstr(Module_AA, "KERNEL32.dll") != NULL) {
while (PointerModule_AA_FT->u1.Function != NULL) {
PIMAGE_THUNK_DATA Win32_Function_AA_FT = (PIMAGE_THUNK_DATA)PointerModule_AA_FT->u1.Function; //AA WIN32 Function
PIMAGE_THUNK_DATA Win32_Function_RVA_OFT = (PIMAGE_THUNK_DATA)PointerModule_AA_OFT->u1.Function; //RVA WIN32 Function
PIMAGE_IMPORT_BY_NAME functionName = (PIMAGE_IMPORT_BY_NAME)((DWORD_PTR)ImageBase + PointerModule_AA_OFT->u1.AddressOfData);
if (strstr(functionName->Name, "WriteFile")) {
DWORD OR_Access_Rights;
int VirtualProtect_Memory = VirtualProtect(&Win32_Function_AA_FT->u1.Function, sizeof(DWORD_PTR), PAGE_EXECUTE_READWRITE, &OR_Access_Rights);
if (VirtualProtect_Memory == 0) {
fprintf(file_pointer, "\nVirtualProtectMemory FAILED");
}
else {
fprintf(file_pointer, "\nVirtualProtectMemory SUCCEEDED: %d", VirtualProtect_Memory);
}
Win32_Function_AA_FT->u1.Function = (DWORD_PTR)WriteFile_HOOK;
if (Win32_Function_AA_FT->u1.Function == (DWORD_PTR)WriteFile_HOOK) {
fprintf(file_pointer, "\nAddress stored in IAT %p", Win32_Function_AA_FT->u1.Function);
fprintf(file_pointer, "\nAddress of WriteFile_HOOK %p", WriteFile_HOOK);
break;
}
else {
fprintf(file_pointer, "\nHOOK FAILED");
}
}
PointerModule_AA_OFT++;
}
}
Import_Directory++;
}
}
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
;
}
}
}