I'm trying to hook the DLL onto a notepad process, and then unhook it. When hooked, the DLL should cause the notepad to create a hidden file whenever the user clicks "Save As" (code for this is not shown). When unhooked, that should not be the case.
However, for some reason, while I got the message "DLL unhooking from process", the DLL still is not unhooked from the notepad process, and I know this because the notepad still creates the additional file when it should not have done that.
There are no error messages on the return values whatsover (at least none that I know of), so I removed most return value checks.
Hook
HANDLE hThread;
char * pid = argv[1];
DWORD user_pid = atoi(pid);
LPCSTR Dllpath = "C:\\Users\\xxx\\Desktop....\\MyDll.dll"
LPVOID pDllPath; // Address in remote process where Dllpath will be copied to.
HMODULE hKernel32 = GetModuleHandle("Kernel32");
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, user_pid);
char * command = argv[2];
if (strcmp(command,"hook") == 0){
SIZE_T bytesWritten = 0;
//Allocate memory to target process, and write dll to the allocated memory.
pDllPath = VirtualAllocEx(hProcess, NULL,strlen(DllPath)+1, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
// Write DLL hook name
WriteProcessMemory(hProcess, pDllPath, (LPCVOID)DllPath, strlen(Dllpath)+1,&bytesWritten);
// Load Dll to remote process
hThread = CreateRemoteThread(hProcess, NULL,0,(LPTHREAD_START_ROUTINE)GetProcAddress(hKernel32, "LoadLibraryA"), pDllPath,0,NULL);
WaitForSingleObject(hThread, INFINITE);
//Clean up
CloseHandle(hThread);
VirtualFreeEx(hProcess, pDllPath, strlen(DllPath+1, MEM_RELEASE);
else if (strcmp(command,"unhook")==0){
InlineUnhook(); //Call unhook inside the dll itself
}
}
Unhook (inside the dll itself)
HANDLE __stdcall InlineUnhook(){
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId());
LoadLibrary("C:\\Users\\xxx\\Desktop...\\MyDll.dll);
HMODULE hLibModule = GetModuleHandleA ("C:\\Users\\xxx\\Desktop...\\MyDll.dll);
HANDLE hThread = CreateRemoteThread(hProcess, NULL,0,(LPTHREAD_START_ROUTINE)GetProcAddress(hKernel32, "FreeLibraryAndExitThread"), (void *)(hLibModule,0),0,NULL);
if (hThread == NULL){
OutputDebugStringA("CreateRemoteThread failed.");
return -1;
}
else{
WaitForSingleObject(hThread, INFINITE);
//Clean up
CloseHandle(hThread);
OutputDebugStringA("DLL unhooking from process...");
return 0;
}
}
Your injector is calling
InlineUnhook()
directly, so it will act on the instance of the DLL that is loaded in the injector process, not the hooked process.FreeLibraryAndExitThread()
is not compatible withCreateRemoteThread()
, so you can't use a remote thread to call it directly, like you can withLoadLibraryA()
.Inside of the DLL itself, there is no need for it to call
OpenProcess()
,LoadLibrary()
, orCreateRemoteThread()
for itself. The DLL can simply callFreeLibraryAndExitThread()
directly, like any other local function.Your injector will have to use a remote thread to call
InlineUnhook()
within the context of the hooked process, rather than calling it directly. That means you need to:export
InlineUnhook()
from the DLL.find the address of the loaded DLL within the hooked process. If your DLL is 32bit being loaded into a 32bit target process, that address can be obtained from
GetExitCodeThread()
whenCreateRemoteThread()
is done callingLoadLibraryA()
. Otherwise, you will have to go hunting for the loaded address afterwards, such as byEnumProcessModules()
orCreateToolhelp32Snapshot(TH32CS_SNAPMODULE)
.find the address of the exported
InlineUnhook()
within the hooked process. UseLoadLibrary()
andGetProcAddress()
inside the injector to calculate the offset ofInlineUnhook()
within the DLL, and then apply that offset to the address of the loaded DLL within the hooked process.use
CreateRemoteThread()
to callInlineUnhook()
at that calculated address. You will have to change the signature ofInlineUnhook()
to be compatible withCreateRemoteThread()
, eg: