Ich lerne, um Haken für Windows API zu schreiben und für Übung schreibe ich einen Haken für pDeleteFileA Funktion. Wenn die Funktion aufgerufen wird, werde ich vor dem Löschen der Datei prüfen, ob der Dateiname "testfile.txt" lautet. Wenn ja, wird eine Nachricht angezeigt, anstatt sie zu löschen. Wenn sie etwas anderes aufgerufen hat, wird die Datei gelöscht.Windows API Hook C++
Ich habe bereits Code geschrieben und der Code kompiliert ohne Fehler, aber wenn ich versuche, 'testfile.txt' zu löschen, wird es gerade gelöscht. Vielleicht könnte mir jemand einen Hinweis geben, was ich falsch mache oder was ich nicht mache?
Hier ist mein Code so weit:
#include <Windows.h>
struct hook_t{// a datatype to store information about our hook
bool isHooked = false;
void* FunctionAddress = operator new(100);
void* HookAddress = operator new(100);
char Jmp[6] = { 0 };
char OriginalBytes[6] = {0};
void* OriginalFunction = operator new(100);
};
namespace hook {
bool InitializeHook(hook_t* Hook, char* Module, char* Function, void* HookFunction) {
HMODULE hModule;
DWORD OrigFunc, FuncAddr;
byte opcodes[] = {0x90, 0x90, 0x90, 0x90, 0x90, 0xe9, 0x00, 0x00, 0x00, 0x00};
if (Hook->isHooked) {
return false;
}
hModule = GetModuleHandleA(Module);
if (hModule == INVALID_HANDLE_VALUE) {
Hook->isHooked = false;
return false;
}
Hook->Jmp[0] = 0xe9;
*(PULONG)&Hook->Jmp[1] = (ULONG)HookFunction - (ULONG)Hook->FunctionAddress - 5;
memcpy(Hook->OriginalBytes, Hook->FunctionAddress, 5);
Hook->OriginalFunction = VirtualAlloc(0, 4096, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (Hook->OriginalFunction == NULL) {
return false;
}
memcpy(Hook->OriginalFunction, Hook->OriginalBytes, 5);
OrigFunc = (ULONG)Hook->OriginalFunction + 5;
FuncAddr = (ULONG)Hook->OriginalFunction + 5;
*(LPBYTE)((LPBYTE)Hook->OriginalFunction + 5) = 0xe9;
*(PULONG)((LPBYTE)Hook->OriginalFunction + 6) = (ULONG)FuncAddr;
Hook->isHooked = true;
return true;
}//end InitializeHook
bool InsertHook(hook_t* Hook) {
DWORD op;
if (!Hook->isHooked) {
return false;
}
VirtualProtect(Hook->FunctionAddress, 5, PAGE_EXECUTE_READWRITE, &op);
memcpy(Hook->FunctionAddress, Hook->Jmp, 5);
VirtualProtect(Hook->FunctionAddress, 5, op, &op);
return true;
}
bool Unhook(hook_t* Hook) {
DWORD op;
if (!Hook->isHooked) {
return false;
}
VirtualProtect(Hook->FunctionAddress, 5, PAGE_EXECUTE_READWRITE, &op);
memcpy(Hook->FunctionAddress, Hook->OriginalBytes, 5);
VirtualProtect(Hook->FunctionAddress, 5, op, &op);
Hook->isHooked = false;
return true;
}
bool FreeHook(hook_t* Hook) {
if (Hook->isHooked) {
return false;
}
VirtualFree(Hook->OriginalFunction, 0, MEM_RELEASE);
memset(Hook, 0, sizeof(hook_t*));
return true;
}
}//end namespase
==========================================================================
#define _CRT_SECURE_NO_WARNINGS
#include "apihook.h"
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
using namespace hook;
//define the function to be hooked
typedef BOOL(WINAPI* pDeleteFileA)(LPCSTR lpFileName);//in this case this will be delete file a
pDeleteFileA pDeleteFile;//instance of it
hook_t* Hook = new hook_t();
//this function will replace the original API function in the process
BOOL WINAPI HookDeleteFileA(LPCSTR lpFileName) {
//we can do here whatever we want before the original API function is called
//for example disable deleting of a certain file
if (strstr(lpFileName, "testfile")) {//checks if parameter contains a string
//disable deleting of this file
SetLastError(ERROR_ACCESS_DENIED);
MessageBoxA(0, "You can't delete this file!", "error", 0);
return false;
}
return pDeleteFile(lpFileName);//if parameter does not contain our string, call the original API function
}
void StartRoutine() {
pDeleteFile = (pDeleteFileA)&Hook->OriginalFunction;
//the pDeleteFileA is located in "kernel32.dll"
InitializeHook(Hook, "kernel32.dll", "DeleteFileA", HookDeleteFileA);
InsertHook(Hook);//spawn the hook to the current process
}
BOOL WINAPI DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpReserved) {
switch (dwReason) {
case DLL_PROCESS_ATTACH:
printf("API Hook Attached!");//notify
StartRoutine();
break;
case DLL_PROCESS_DETACH:
Unhook(Hook);//unhook the hook
FreeHook(Hook);//remove the hook from memory
}
}
int main() {
HMODULE hModule = GetModuleHandleA("kernel32.dll");
//The reason code that indicates why the DLL entry-point function is being called.
//This parameter can be one of the following values:
//DLL_PROCESS_ATTACH 1:
//The DLL is being loaded into the virtual address space of the current process
//as a result of the process starting up or as a result of a call to LoadLibrary.
//DLL_PROCESS_DETACH 0:
//The DLL is being unloaded from the virtual address space of the calling process
//because it was loaded unsuccessfully or the reference count has reached zero
//(the processes has either terminated or called FreeLibrary one time for each time it called LoadLibrary).
DWORD dwReason = DLL_PROCESS_ATTACH;
//If fdwReason is DLL_PROCESS_ATTACH, lpvReserved is NULL for dynamic loads and non-NULL for static loads
//If fdwReason is DLL_PROCESS_DETACH, lpvReserved is NULL if FreeLibrary has been called or the DLL load
//failed and non-NULL if the process is terminating.
LPVOID lpReserved = NULL;
DllMain(hModule, dwReason, lpReserved);
return 0;
}
Hängen Sie Ihren eigenen Prozess ein und löschen Sie die Datei im Explorer? –
Ja, das ist mein erster Haken, also wenn ich es falsch mache, könntest du mir einen Rat geben? – Nikolaj
Ja, das wird nicht funktionieren. Sie haben DeleteFileA für Ihren eigenen Prozess angehängt, sodass der Explorer selbst diese DLL geladen haben sollte, was natürlich nicht passieren wird. Was passiert mit DllMain in main() exe Einstiegspunkt? – bunglehead