C++ FreeLibrary未取消挂钩DLL
我正在尝试将DLL挂接到记事本进程上,然后将其取消挂接。钩住后,只要用户单击“另存为”,DLL就会使记事本创建一个隐藏文件(此代码未显示)。当脱钩时,情况不应该如此 然而,由于某种原因,虽然我收到了“DLL从进程中取消挂钩”的消息,但DLL仍然没有从记事本进程中取消挂钩,我知道这一点,因为记事本仍然会在不应该这样做的情况下创建附加文件 返回值whatsover上没有错误消息(至少据我所知没有),因此我删除了大多数返回值检查 钩住C++ FreeLibrary未取消挂钩DLL,c++,winapi,dll,hook,createremotethread,C++,Winapi,Dll,Hook,Createremotethread,我正在尝试将DLL挂接到记事本进程上,然后将其取消挂接。钩住后,只要用户单击“另存为”,DLL就会使记事本创建一个隐藏文件(此代码未显示)。当脱钩时,情况不应该如此 然而,由于某种原因,虽然我收到了“DLL从进程中取消挂钩”的消息,但DLL仍然没有从记事本进程中取消挂钩,我知道这一点,因为记事本仍然会在不应该这样做的情况下创建附加文件 返回值whatsover上没有错误消息(至少据我所知没有),因此我删除了大多数返回值检查 钩住 HANDLE hThread; char * pid = argv
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
}
}
取消挂钩(在dll内部)
这是因为上面的
InlineUnhook
调用调用的是加载到注入进程中的dll副本,而不是目标进程中的副本。您的注入器直接调用InlineUnhook()
,因此它将作用于注入进程中加载的dll实例,而不是挂接进程
freelLibraryAndExitThread()
与CreateRemoteThread()
不兼容,因此不能像使用LoadLibraryA()
那样使用远程线程直接调用它
在DLL本身内部,它不需要为自己调用OpenProcess()
、LoadLibrary()
、或CreateRemoteThread()
。DLL可以像任何其他本地函数一样,直接调用FreeLibraryAndExitThread()
HINSTANCE hThisInst;
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
{
hThisInst = hinstDLL;
...
return 1;
}
void __stdcall InlineUnhook()
{
FreeLibraryAndExitThread(hThisInst, 0);
}
您的注入器必须使用远程线程在挂接进程的上下文中调用InlineUnhook()
,而不是直接调用它。这意味着您需要:
- 从DLL导出
InlineUnhook()
- 在挂钩进程中查找加载的DLL的地址。如果您的DLL是32位加载到32位目标进程中,则当调用
完成LoadLibraryA()
时,可以从CreateRemoteThread()
获取该地址。否则,您必须在以后查找加载的地址,例如通过GetExitCodeThread()
或EnumProcessModules()
CreateToolhelp32Snapshot(TH32CS\u SNAPMODULE)
- 在钩住的进程中查找导出的
的地址。在注入器内使用InlineUnhook()
和LoadLibrary()
计算DLL内GetProcAddress()
的偏移量,然后将该偏移量应用于挂接进程内加载的DLL的地址InlineUnhook()
- 使用
在该计算地址调用CreateRemoteThread()
。您必须更改InlineUnhook()
的签名才能与InlineUnhook()
兼容,例如:CreateRemoteThread()
@takeru如果您想使用
freebrary()
而不是InlineUnhook()
,那么是的,这将起作用(按原样使用dll\u base\u addr
,而不从中减去unhook\u func\u addr
)。如果您想改用InlineUnhook()
,则可以自己使用unhook\u func\u addr
,而不将其传递给FreeLibrary()
,但查找该地址需要几个步骤,正如我在answer@takeru不,它更像是CreateRemoteThread(hProcess,NULL,0,(LPTHREAD\u START\u例程)取消挂钩功能地址,空,0,空)代码>其中unhook_func_addr
的计算方式类似于dll_base_addr+offset
,其中offset
的计算方式类似于lib=LoadLibrary(“dll”);偏移量=(UINT_PTR)GetProcAddress(lib,“InlineUnhook”)-(UINT_PTR)lib代码>请不要污损您的问题。一旦您在此网站上提出问题,您的问题及其代码将根据您在加入该网站时同意的服务条款成为该网站的财产。@takeru(再次)回滚。原始问题的答案已发布,编辑后将变得毫无意义。不要那样做。正如有人告诉你的,你不能删除/污损你的问题。不过,您可以将您的姓名从中删除,请参见
HINSTANCE hThisInst;
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
{
hThisInst = hinstDLL;
...
return 1;
}
void __stdcall InlineUnhook()
{
FreeLibraryAndExitThread(hThisInst, 0);
}
DWORD __stdcall InlineUnhook(LPVOID)
{
FreeLibraryAndExitThread(hThisInst, 0);
return 1;
}