文章目录[隐藏]
我们首先搞清楚第一个问题,什么是易语言的子程序指针,易语言的子程序如果在类中,我们可以称之为方法,方法是属于对象的,而在程序集下的子程序,我们可以理解是一段封装的可以反复调用的代码,就是用来执行其他事件的一个命令分区,目的是提高执行效率,类的"方法名"需要在程序集中声明才能执行,而程序集的"子程序"不需要声明在源代码任何地方都可以执行.
第二个问题,什么是子程序指针,首先子程序指针是易语言里的一个特殊的数据类型,它的实质是一个整数,这个整数只指向这段功能代码区的首地址,我们可以这样调用:&子程序名称,或者 (到整数 (&子程序1))
第三个问题,子程序指针, 指向的是程序片段的首地址,他不是对象结构!
第四个问题,易语言本身的取指针地址(),其实和到到整数 (&子程序1)是一样的,这里得到的整数,并非真正的子程序指针!!那么所谓的真实的子程序指针是什么?就是取子程序的内存变量地址!
第五个问题,如何获取易语言真实的取子程序指针,需要调用AIP:strcpynA,特别注意:它的前两个参数的类型都是 子程序指针!!
第六个问题,我们为什么取子程序的指针,有什么作用,比如我们要劫持,hook这段子程序的里的代码,让它执行我们想做的事情,这里就需要了。
第七个问题,如果你临时不需要这些知识,那么了解后会发现自己懂得了更多了一点,最后有源码下载。
用到的API
.版本 2 .DLL命令 _RtlMoveMemory_读字节, , "kernel32.dll", "RtlMoveMemory" .参数 Destination, 字节型, 传址 .参数 Source, 整数型 .参数 Length, 整数型 .DLL命令 _RtlMoveMemory_读整数, , "kernel32.dll", "RtlMoveMemory" .参数 Destination, 整数型, 传址 .参数 Source, 整数型 .参数 Length, 整数型 .DLL命令 _lstrcpyn_子程序指针, 整数型, "kernel32.dll", "lstrcpynA", , 取内存变量地址 .参数 lpString1, 子程序指针, 传址, 传址 .参数 lpString2, 子程序指针, 传址 .参数 iMaxLength, 整数型
封装取子程序指针
注意:这个子程序的参数类型也是:子程序指针!!
.版本 2 .子程序 取子程序指针, 整数型 .参数 子程序指针, 子程序指针 .局部变量 指针, 整数型 .局部变量 call, 字节型 .局部变量 读取位置, 整数型 .局部变量 实际指针, 整数型 指针 = _lstrcpyn_子程序指针 (子程序指针, 子程序指针, 0) _RtlMoveMemory_读整数 (指针, 指针, 4) 读取位置 = 3 _RtlMoveMemory_读字节 (call, 指针 + 读取位置, 1) .如果真 (call ≠ 232) 读取位置 = 20 .如果真结束 读取位置 = 读取位置 + 1 _RtlMoveMemory_读整数 (实际指针, 指针 + 读取位置, 4) 返回 (指针 + 读取位置 + 4 + 实际指针)
两个要取的子程序
.版本 2 .子程序 子程序1 aa = aa + 1 .子程序 子程序2 .参数 有参数 aa = aa + 1
对两个子程序分别调用
.版本 2 .支持库 spec .子程序 _按钮1_被单击 .局部变量 a, 整数型 .局部变量 b, 整数型 .局部变量 c a = 到整数 (&子程序1) b = 取子程序指针 (&子程序1) 调试输出 (a, b) aa = 0 c = 取启动时间 () .计次循环首 (100000000, ) 置入代码 ({ 255, 85, 252 }) ' call [ebp-4] .计次循环尾 () c = 取启动时间 () - c 调试输出 (c) 调试输出 (aa) aa = 0 c = 取启动时间 () .计次循环首 (100000000, ) 置入代码 ({ 255, 85, 248 }) ' call [ebp-8] .计次循环尾 () c = 取启动时间 () - c 调试输出 (c) 调试输出 (aa) .子程序 _按钮2_被单击 .局部变量 a, 整数型 .局部变量 b, 整数型 .局部变量 c a = 到整数 (&子程序2) b = 取子程序指针 (&子程序2) 调试输出 (a, b) aa = 0 c = 取启动时间 () .计次循环首 (100000000, ) 置入代码 ({ 104, 0, 0, 0, 0 }) ' push 0 置入代码 ({ 255, 85, 252 }) ' call [ebp-4] .计次循环尾 () c = 取启动时间 () - c 调试输出 (c) 调试输出 (aa) aa = 0 c = 取启动时间 () .计次循环首 (100000000, ) 置入代码 ({ 104, 0, 0, 0, 0 }) ' push 0 置入代码 ({ 255, 85, 248 }) ' call [ebp-8] .计次循环尾 () c = 取启动时间 () - c 调试输出 (c) 调试输出 (aa)