通过API(CreateProcessA)创建进程后,先暂停这个进程,然后申请内存空间,把我们注入DLL路径写入内存,再通过CreateRemoteThread创建远程线程调用LoadLibraryA函数,获取远程句柄,然后ResumeThread唤醒主线程,实现注入。
CreateProcessA暂停注入
.版本 2
.支持库 spec
.局部变量 文件路径, 文本型
.局部变量 运行目录, 文本型
.局部变量 si, STARTUPINFO
.局部变量 pi, 进程结构
.局部变量 sRet, 整数型
.局部变量 模块名称, 文本型
.局部变量 dll文件路径, 整数型
.局部变量 Param, 整数型
.局部变量 LoadLibraryA地址, 整数型
.局部变量 hThread, 整数型
.局部变量 bRet, 整数型
文件路径 = “D:\游戏\剑侠\剑侠情缘网络版\gamefree.exe”
运行目录 = 取文本左边 (文件路径, 倒找文本 (文件路径, “\”, , 假))
模块名称 = 编辑框1.内容
' 1、创建进程
sRet = CreateProcessA (文件路径, “”, 0, 0, 假, 4, 0, 运行目录, si, pi)
调试输出 (sRet)
' 2、申请内存空间
dll文件路径 = 取文本长度 (模块名称) + 1
Param = VirtualAllocEx (pi.进程句柄, 0, dll文件路径, 4096, 4)
' 3、把DLL路径写入内存
WriteProcessMemory (pi.进程句柄, Param, 模块名称, 取字节集长度 (到字节集 (模块名称)), 0)
' 4、获取loadlibrary地址
LoadLibraryA地址 = GetProcAddress (GetModuleHandleA (“kernel32”), “LoadLibraryA”)
' 5、创建远程线程调用LoadLibraryA函数,获取远程句柄
hThread = CreateRemoteThread (pi.进程句柄, 0, 0, LoadLibraryA地址, Param, 0, 0)
.如果 (hThread = 0)
信息框 (“创建线程注入失败”, 0, , )
返回 ()
.否则
.如果结束
' 5、唤醒主线程
bRet = ResumeThread (pi.线程句柄)
.如果 (bRet = -1)
信息框 (“ResumeThread线程唤醒失败”, 0, , )
返回 ()
.否则
.如果结束
' 6、测试等待
WaitForSingleObject (hThread, -1)
' 7、关闭句柄
CloseHandle (hThread)
在注入主程序里我们分为:
获取DLL 路径,
填写DLL函数名称,
hook注入,
载入DLL,启动线程,
本注入DLL的编写。
载入DLL
dll句柄 = LoadLibraryA (编辑框1.内容)
启动线程
.版本 2
.支持库 spec
.支持库 EThread
.局部变量 函数地址
.局部变量 内存地址
.局部变量 线程ID
.局部变量 线程句柄
函数地址 = GetProcAddress (dll句柄, 编辑框2.内容)
内存地址 = 申请内存 (取文本长度 (编辑框2.内容), )
写到内存 (编辑框2.内容, 内存地址, )
线程句柄 = CreateThread (0, 0, 函数地址, 内存地址, 0, 线程ID)
.如果真 (等待线程 (线程句柄, 100))
关闭线程句柄 (线程句柄)
释放内存 (内存地址)
注入DLL
在注入的DLL里我们采用启动线程的方式,载入窗口
.版本 2
.支持库 EThread
启动线程 (&th, , )
_临时子程序 () ' 在初始化代码执行完毕后调用测试代码
返回 (0) ' 返回值被忽略。
.子程序 _临时子程序
' 本名称子程序用作测试程序用,仅在开发及调试环境中有效,编译发布程序前将被系统自动清空,请将所有用作测试的临时代码放在本子程序中。 ***注意不要修改本子程序的名称、参数及返回值类型。
.子程序 th, , 公开
载入 (窗口1, , 真)
游戏的控制代码写在启动窗口创建后,支持大漠的注册和多线程,前面的例子已经贴出了代码。