易语言 HOOK API 教程 要详细的说明
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了易语言 HOOK API 教程 要详细的说明相关的知识,希望对你有一定的参考价值。
易语言 HOOK API 教程 列子 要详细的说明 ,别整那些看不懂的来 我水平基础还可以
#include#include "APIHook.h" extern CAPIHook g_OpenProcess; // 自定义OpenProcess函数 #pragma data_seg("YCIShared") HHOOK g_hHook = NULL; DWORD dwCurrentProcessId=0; #pragma data_seg() HANDLE WINAPI Hook_OpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId) typedef HANDLE (WINAPI *PFNTERMINATEPROCESS)(DWORD, BOOL,DWORD); if(dwProcessId != dwCurrentProcessId) return ((PFNTERMINATEPROCESS)(PROC)g_OpenProcess)(dwDesiredAccess,bInheritHandle,dwProcessId); return 0; // 挂钩OpenProcess函数 CAPIHook g_OpenProcess("kernel32.dll", "OpenProcess", (PROC)Hook_OpenProcess); ////static HMODULE ModuleFromAddress(PVOID pv) MEMORY_BASIC_INFORMATION mbi; if(::VirtualQuery(pv, &mbi, sizeof(mbi)) != 0) return (HMODULE)mbi.AllocationBase; else return NULL; static LRESULT WINAPI GetMsgProc(int code, WPARAM wParam, LPARAM lParam) return ::CallNextHookEx(g_hHook, code, wParam, lParam); BOOL WINAPI SetSysHook(BOOL bInstall, DWORD dwThreadId) BOOL bOk; dwCurrentProcessId=dwThreadId; if(bInstall) g_hHook = ::SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, ModuleFromAddress(GetMsgProc), 0); bOk = (g_hHook != NULL); else bOk = ::UnhookWindowsHookEx(g_hHook); g_hHook = NULL; return bOk; API 通过HOOK OpenProcess() 实现进程防杀2007-07-04 14:41在WINDOWS操作系统下,当我们无法结束或者不知道怎样结束一个程序的时候,或者是懒得去找“退出”按钮的时候,通常会按“CTRL+ALT+DEL”呼出任务管理器,找到想结束的程序,点一下“结束任务”就了事了,呵呵,虽然有点粗鲁,但大多数情况下都很有效,不是吗? 设想一下,如果有这么一种软件,它所要做的工作就是对某个使用者在某台电脑上的活动作一定的限制,而又不能被使用者通过“结束任务”这种方式轻易地解除限制,那该怎么做?无非有这么三种方法:1.屏蔽“CTRL+ALT+DEL”这个热键的组合;2.让程序不出现在任务管理器的列表之中;3.让任务管理器无法杀掉这个任务。对于第一种方法,这样未免也太残酷了,用惯了“结束任务”这种方法的人会很不习惯的;对于第二种方法,在WINDOWS 9X下可以很轻易地使用注册服务进程的方法实现,但是对于WINDOWS NT架构的操作系统没有这个方法了,进程很难藏身,虽然仍然可以实现隐藏,但实现机制较为复杂;对于第三种方法,实现起来比较简单,我的作品:IPGate网址过滤器 就是采用的这种方式防杀的,接下来我就来介绍这种方法。 任务管理器的“结束任务”实际上就是强制终止进程,它所使用的杀手锏是一个叫做TerminateProcess()的Win32 API函数,我们来看看它的定义: BOOL TerminateProcess( HANDLE hProcess; // 将被结束进程的句柄 UINT uExitCode; // 指定进程的退出码 ); 看到这里,是不是觉得不必往下看都知道接下来要做什么:Hook TerminateProcess()函数,每次TerminateProcess()被调用的时候先判断企图结束的进程是否是我的进程,如果是的话就简单地返回一个错误码就可以了。真的是这么简单吗?先提出一个问题,如何根据hProcess判断它是否是我的进程的句柄?答案是:在我的进程当中先获得我的进程的句柄,然后通过进程间通讯机制传递给钩子函数,与hProcess进行比较不就行了?错!因为句柄是一个进程相关的值,不同进程中得到的我的进程的句柄的值在进程间进行比较是无意义的。 怎么办?我们来考察一下我的hProcess它是如何得到的。一个进程只有它的进程ID是独一无二的,操作系统通过进程ID来标识一个进程,当某个程序要对这个进程进行访问的话,它首先得用OpenProcess这个函数并传入要访问的进程ID来获得进程的句柄,来看看它的参数: HANDLE OpenProcess( DWORD dwDesiredAccess, // 希望获得的访问权限 BOOL bInheritHandle, // 指明是否希望所获得的句柄可以继承 DWORD dwProcessId // 要访问的进程ID ); 脉络渐渐显现:在调用TerminateProcess()之前,必先调用OpenProcess(),而OpenProcess()的参数表中的dwProcessId是在系统范围内唯一确定的。得出结论:要Hook的函数不是TerminateProcess()而是OpenProcess(),在每次调用OpenProcess()的时候,我们先检查dwProcessId是否为我的进程的ID(利用进程间通讯机制),如果是的话就简单地返回一个错误码就可以了,任务管理器拿不到我的进程的句柄,它如何结束我的进程呢? 至此,疑团全部揭开了。由Hook TerminateProcess()到Hook OpenProcess()的这个过程,体现了一个逆向思维的思想。其实我当初钻进了TerminateProcess()的死胡同里半天出也不来,但最终还是蹦出了灵感的火花,注意力转移到了OpenProcess()上面,实现了进程防杀。喜悦之余,将这心得体会拿出来与大家分享。参考资料: http://hi.baidu.com/wlw7758/blog/item/9d109322816032f1d7cae2d7.html版权所有,谢绝抄袭!!!!!!追问如何HOOK呢 你这样里都没有说如何HOOK 我要的是方法
追答HOOK的是哪个方面的啊,说清楚点。。
追问就好比你说的这个 把他的过程写下来 说是要HOOK OpenProcess() 但它的过程了 就这么一句话说 HOOK OpenProcess() 我怎么知道怎么怎么搞 说了要详细的说明 例子
追答还是听不清楚你在说什么,能说的再详细点么。。。HOOK有很多方面,不知道你说的是哪个方面。。。
追问这样吧 就想你说的这个 拦截OpenProcess() 就能实现防杀 那应该怎么实现了?
参考技术A珍藏已久的Hook例子,键盘、鼠标Hook
图文多线程入门教程
易语言写多线程应用要么使用多线程相关的api支持库或模块,其实那些支持库或模块也都是封装的api,但是要比api使用方便。 本次教程以易语言官方的多线程支持库为例。
一、加载多线程支持库
支持库勾选上之后就可以使用易语言的多线程支持库了。
二、多线程创建线程的命令:启动线程
命令名:启动线程
创建并启动一条线程,可重复使用以创建多条线程,成功返回真,失败返回假。
参数 |
数据类型 |
说明 |
参数<1>的名称为“欲执行的子程序” |
子程序指针(SubPtr) |
本参数提供创建线程时欲启动的子程序,根据是否需要传递参数数据,该子程序必须没有或具有一个整数型参数,否则将出错。 |
参数数据 |
整数型(int) |
可以被省略。本参数提供线程被启动时传递到欲启动子程序的整数数据。如果本参数未被省略,此时被启动子程序必须接收一个整数型参数,否则将出错。 |
线程句柄 |
整数型(int) |
,可以被省略,提供参数数据时只能提供变量。如果提供了本参数,将向参数变量写入线程句柄(Windows下为HANDLE,Linux下为pthread_t),请在适当的时机关闭该句柄。如果不提供本参数接收线程句柄,内部将自动处理线程句柄。 |
首先,先演示创建一条线程(控制台程序下):
注意:&子程序1 代表子程序1的子程序指针
执行结果:
这时候子程序1 将不是在主线程中执行的,而是在线程句柄为552的新线程中执行,和主线程互不相关。
接下来,我们通过下面的代码理解下为什么要使用线程:
如果按钮被按下之后,只要循环不结束,界面是不能响应任何消息的,也就是拖动点击什么的都没用,相当于卡死。
但是如果把按钮下调用的子程序1 ,改为启动线程 (&子程序1, , ),则窗口可以正常响应消息,因为创建了一条新的线程来执行子程序1,主线程可以继续处理窗口消息。
三、多线程关闭线程句柄的命令:关闭线程句柄
命令名:关闭线程句柄
返回真表示已成功关闭线程句柄。在Linux下,如果线程已经结束,本命令可能返回假。本命令为初级命令。
参数 |
数据类型 |
说明 |
线程句柄 |
整数型(int) |
可通过“启动线程”的第三个参数获取线程句柄。 |
演示关闭线程句柄的例子:
执行结果:
注意:每次启动线程的句柄都是不确定的
在启动线程之后习惯性地关闭线程句柄释放资源,你可能会问:我创建了线程句柄就不关闭也没见怎么样?就像易语言多线程之启动线程中一样,也没见怎么样,但是这只是创建了一个线程来演示,如果线程持续创建且不释放就会出现内存占用不断增加的情况。此外,关闭线程句柄,顾名思义,是把线程句柄给关闭掉,而不是把线程给关闭掉,这点要分清楚!关闭线程句柄,只是把它的句柄给关闭了,关闭了线程句柄的线程可能继续在执行,但是没了句柄我们已经不能对这条线程进行控制了。
四、多线程等待线程的命令:等待线程
命令名:等待线程
等待,直到指定线程结束或等待超时才返回。返回真表示等待成功。注意,在Linux下暂不支持超时等待。本命令为初级命令。
参数 |
数据类型 |
说明 |
线程句柄 |
整数型(int) |
可通过“启动线程”的第三个参数获取线程句柄。 |
等待时间 |
整数型(int) |
可以被省略。指定等待时间,单位为毫秒。如果为0或负数,或被省略,表示不限定等待时间。 |
我们可以通过等待线程来判断一个线程是否结束:
执行结果:
但是这样还有一个问题,本来用多线程的本意是为了子程序1的循环不影响窗口的消息响应,但是加了一个等待线程又把主线程阻塞了,不符合我们的本意。
解决方法就是把等待线程放到另一个线程中去:
执行结果:
如此,在不阻塞主线程的情况下完成了等待线程。
五、多线程强制结束线程的命令:强制结束线程
命令名:强制结束线程
返回真表示执行成功。本命令为初级命令。
参数 |
数据类型 |
说明 |
线程句柄 |
整数型(int) |
可通过“启动线程”的第三个参数获取线程句柄。 |
强制结束一个线程的例子:
执行结果:
点击强制结束线程按钮后,
判断线程是否正在等待,如果是正在运行,那么,执行制结束线程,制结束线程是不管线程有没有结束,都强制结束线程;如果已经结束,则关闭线程句柄。
强制结束线程和等待线程比起来,更为霸道,可以说是蛮不讲理,也容易处理不当造成程序错误,所以,不推荐使用。
六、多线程防止线程冲突的命令:多线程许可证
我们在使用多线程时会出现资源独享的情况,这时候,我们使用加入许可区之后可以防止多个线程同时访问公用变量是发生冲突。加入许可区的代码同时只允许一个线程访问以避免冲突。
主要命令包括:
创建许可区:
创建并返回一个进入许可证数值,此许可证值用作进入程序中的指定许可代码区,以避免多线程冲突。成功返回非零整数值,失败返回0。所创建的许可证在不再使用后,必须使用“删除进入许可证”命令将其删除。本命令为初级命令。
删除进入许可证:
删除由“创建进入许可证”命令所创建返回的进入许可证。成功返回真,失败返回假。本命令为初级命令。
参数 |
数据类型 |
说明 |
进入许可证 |
“整数型(int) |
本参数应提供由“创建进入许可证”命令所创建并返回的数值。 |
进入许可区:
根据已经创建的许可证进入指定许可代码区,在此线程未退出之前,其它线程如要通过同一个进入许可证进入该许可代码区则必须先等待此线程退出许可代码区,从而保证了指定许可代码区在任何时候都只能有一条线程进入并执行。本命令为初级命令。
参数 |
数据类型 |
说明 |
进入许可证 |
整数型(int) |
本参数应提供由“创建进入许可证”命令所创建并返回的数值。 |
退出许可区:
指示当前线程将退出许可代码区,并允许其它使用同一进入许可证的线程进入此许可代码区。本命令为初级命令。
参数 |
数据类型 |
说明 |
进入许可证 |
整数型(int) |
本参数应提供由“创建进入许可证”命令所创建并返回的数值。 |
反例:不加许可证
调试输出结果:
* 8
* 9
* 7
* 6
* 5
* 4
* 3
* 2
* 1
在执行一次:
* 8
* 7
* 9
* 6
* 5
* 4
* 3
* 2
* 1
* 0
我们可以明显的发现问题,,虽然最终是把num减到了0,但是结果完全是乱的。
利用许可证解决上面的问题:
输出结果:
* 9
* 8
* 7
* 6
* 5
* 4
* 3
* 2
* 1
* 0
用了许可证之后每次都是这样的稳定结果。
七、多线程例程
接下来,我们把上述命令组合在一起搭配使用,组成一个简单的多线程例程
注意几点:
1.多线程不是越多线程越好,控制在30左右的线程个数是一个比较合理的区间;
2.从实战经验上来看,要做好对句柄的处理;
3.多线程的崩溃的问题,不要只盯着框架本身,而多考虑是执行的代码问题,就好像执行下图的代码,一万个都不会出现问题,而执行实际的代码,则弄不好就会报错。
(易语言自习室对部分内容进行修改完善)
以上是关于易语言 HOOK API 教程 要详细的说明的主要内容,如果未能解决你的问题,请参考以下文章