我在Delphi应用程序中遇到问题,确定当前应用程序(当前线程)句柄。我知道我可以使用Windows API函数GetCurrentThreadID
获取当前线程ID,但我需要当前的Thread句柄作为另一个Windows API函数SuspendThread的param。
其实我要做的是让我的旧dll之一用于挂钩kernel32.dll中的API函数,如OpenProcess
或TerminateProcess
,也可以挂钩SuspendProcess
。 Hook位于dll文件中,使用SetWindowsHookEx注入正在运行的进程,然后查找目标函数的基址。
挂钩函数如TerminateProcess我没有问题,因为它需要进程ID作为param,在主应用程序中使用GetCurrentProcessID
很容易获得。要为SuspendThread
函数创建类似的钩子,我需要将线程句柄作为参数传递。
只有我找到线程句柄的地方才是包含
的PROCESS_INFORMATION
结构
typedef struct _PROCESS_INFORMATION { // pi
HANDLE hProcess;
HANDLE hThread;
DWORD dwProcessId;
DWORD dwThreadId;
} PROCESS_INFORMATION;
但问题是此结构仅在使用CreateProcess
API函数创建进程后才可用。主要目标是防止程序用户使用ProcessExplorer等在线提供的不同工具来终止进程。我实现了成功挂钩TerminateProcess API调用并阻止关闭我的应用程序但在这些过程探索工具中的Suspend选项可以暂停我的进程。它是互联网信息亭应用程序,用户无法关闭该应用程序至关重要。应用程序当前在Windows XP中运行,并且必须在管理员帐户上运行,因为用户在登录我的应用程序后使用的其他应用程序需要管理员帐户才能运行,所以我不能简单地在受限用户下运行我的应用程序。
有什么方法可以在Delphi中获取我的主应用程序主线程句柄?
提前致谢
答案 0 :(得分:6)
调用SuspendThread
的唯一安全方法是使用当前线程的句柄。暂停任何其他线程是一个坏主意。要获取当前线程的句柄,只需调用GetCurrentThread
即可。您可以在需要线程处理的任何地方使用它。但是不要把这个句柄交给另一个线程 - 它是一个特殊的“伪句柄”,总是意味着“当前线程”,无论哪个线程都有它。
您可以使用OpenThread
或DuplicateHandle
来获取“真正的”线程句柄,但这可能无法让您到达目的地。您将无法识别暂停线程或进程的尝试,因为句柄另一个程序用于挂起您的线程不一定与您调用{{1}时的值相同}。句柄仅在打开它们的过程中有意义,并且可以获取同一事物的多个句柄,并且每次可能产生或不产生相同的值。
相反,调用OpenThread
来获取被挂起的线程的ID,然后查看它是否与您的任何程序的线程ID匹配。线程ID唯一标识线程;手柄没有。同样,对于进程ID和句柄。
答案 1 :(得分:5)
如果你有线程ID,你可以使用OpenThread来获取它的句柄:
HANDLE WINAPI OpenThread(
__in DWORD dwDesiredAccess,
__in BOOL bInheritHandle,
__in DWORD dwThreadId
);