AHK读写游戏内存的函数

利用AHK读写游戏内存也是很容易的,可以先用金山游侠或者CE搜索出要读写的内存地址,然后使用AHK读写它。当然难点在于搜索出准确的内存地址,那才是高手的拿手好戏。

;----------------------------------
;  AHK读写游戏内存的函数  By FeiYue
;
; 中途读取(或写入)N级指针地址时不应该设置“字节”参数,
; 但是最后读取的数值需要准确指明“字节”参数,读取1、2、4、8字节的正整数值。
; 如果最后读取的是负数或小数或字符串,还需要指明“类型”或“编码”参数。
; 类型参数可以使用Char(1字节)、Short(2字节)、Int(4字节)
; 、Float(4字节)、Double(8字节)、Str(N字节,可以加编码)。
;
; 读值(进程ID或进程名, 目标地址, 字节="", 类型="", 编码="")
; 写值(进程ID或进程名, 目标地址, 写入值, 字节="", 类型="", 编码="")
;----------------------------------

F1::

程序名 := "Loginp.exe"
基址   := 0x01c4c5a8
血偏移 := 0x15c
写入值 := 15000

读取值:=读值(程序名, 读值(程序名,基址)+血偏移, 4)
MsgBox, 4096, 提示, % "写入前读取值为:" 读取值

写值(程序名, 读值(程序名,基址)+血偏移, 写入值, 4)

读取值:=读值(程序名, 读值(程序名,基址)+血偏移, 4)
MsgBox, 4096, 提示, % "写入后读取值为:" 读取值

return


;======== 下面是函数 ========

; 中途读取(或写入)N级指针地址时不应该设置“字节”参数,
; 但是最后读取的数值需要准确指明“字节”参数,读取1、2、4、8字节的正整数值。
; 如果最后读取的是负数或小数或字符串,还需要指明“类型”或“编码”参数。
; 类型参数可以使用Char(1字节)、Short(2字节)、Int(4字节)
; 、Float(4字节)、Double(8字节)、Str(N字节,可以加编码)。

读值(进程ID或进程名, 目标地址, 字节="", 类型="", 编码="")
{
    static buf, type:={1:"uchar", 2:"ushort", 4:"uint", 8:"int64"}
    ;------------------
    Process, Exist, %进程ID或进程名%
    if !(PID:=ErrorLevel)
        Throw "获取进程ID失败"
    ;------------------
    if !进程句柄:=DllCall("OpenProcess"
    , "UInt",0x001F0FFF, "UInt",0, "UInt",PID, "Ptr")
        Throw "获取进程句柄失败"
    ;------------------
    字节:=字节 ? 字节 : (!A_Is64bitOS) ? 4 : DllCall("IsWow64Process"
        , "Ptr",进程句柄, "IntP",IsWow64)*0+IsWow64 ? 4 : 8
    类型:=类型 ? 类型 : type[字节]
    VarSetCapacity(buf, (字节<8?8:字节), 0)
    ;------------------
    if !DllCall("ReadProcessMemory", "Ptr",进程句柄
    , "Ptr",目标地址, "Ptr",&buf, "UInt",字节, "UInt",0)
        Throw "读取内存值失败" DllCall("CloseHandle","Ptr",进程句柄)
    ;------------------
    if !DllCall("CloseHandle", "Ptr",进程句柄)
        Throw "关闭进程句柄失败"
    ;------------------
    return (类型!="Str") ? NumGet(buf, 类型)
        : (编码="") ? StrGet(&buf, 字节)
        : StrGet(&buf, 字节, 编码)
}

写值(进程ID或进程名, 目标地址, 写入值, 字节="", 类型="", 编码="")
{
    static buf, type:={1:"uchar", 2:"ushort", 4:"uint", 8:"int64"}
    ;------------------
    Process, Exist, %进程ID或进程名%
    if !(PID:=ErrorLevel)
        Throw "获取进程ID失败"
    ;------------------
    if !进程句柄:=DllCall("OpenProcess"
    , "UInt",0x001F0FFF, "UInt",0, "UInt",PID, "Ptr")
        Throw "获取进程句柄失败"
    ;------------------
    字节:=字节 ? 字节 : (!A_Is64bitOS) ? 4 : DllCall("IsWow64Process"
        , "Ptr",进程句柄, "IntP",IsWow64)*0+IsWow64 ? 4 : 8
    类型:=类型 ? 类型 : type[字节]
    VarSetCapacity(buf, (字节<8?8:字节), 0)
    ;------------------
    (类型!="Str") ? NumPut(写入值, buf, 类型)
        : (编码="") ? StrPut(写入值, &buf, 字节)
        : StrPut(写入值, &buf, 字节, 编码)
    ;------------------
    if !DllCall("VirtualProtectEx", "Ptr",进程句柄
    , "Ptr",目标地址, "UInt",字节, "UInt",0x04, "UInt*",0)
        Throw "修改权限失败" DllCall("CloseHandle","Ptr",进程句柄)
    ;------------------
    if !DllCall("WriteProcessMemory", "Ptr",进程句柄
    , "Ptr",目标地址, "Ptr",&buf, "UInt",字节, "UInt",0)
        Throw "写入内存值失败" DllCall("CloseHandle","Ptr",进程句柄)
    ;------------------
    if !DllCall("CloseHandle", "Ptr",进程句柄)
        Throw "关闭进程句柄失败"
    ;------------------
    return 目标地址+字节
}

提权()  ; 有可能需要
{
   static PROCESS_QUERY_INFORMATION := 0x400
   , TOKEN_ADJUST_PRIVILEGES := 0x20
   , SE_PRIVILEGE_ENABLED := 0x2

   hProc := DllCall("OpenProcess", "UInt",PROCESS_QUERY_INFORMATION
   , "Int",0, "UInt",DllCall("GetCurrentProcessId"), "Ptr")
   DllCall("Advapi32\OpenProcessToken", "Ptr",hProc
   , "UInt",TOKEN_ADJUST_PRIVILEGES, "PtrP", token)

   DllCall("Advapi32\LookupPrivilegeValue"
   , "Ptr",0, "Str","SeDebugPrivilege", "Int64P",luid)
   VarSetCapacity(TOKEN_PRIVILEGES, 16, 0)
   NumPut(1, TOKEN_PRIVILEGES, "UInt")
   NumPut(luid, TOKEN_PRIVILEGES, 4, "Int64")
   NumPut(SE_PRIVILEGE_ENABLED, TOKEN_PRIVILEGES, 12, "UInt")
   DllCall("Advapi32\AdjustTokenPrivileges", "Ptr",token
   , "Int",0, "Ptr",&TOKEN_PRIVILEGES, "Int",0, "Ptr",0, "Ptr",0)
   res := A_LastError
   DllCall("CloseHandle", "Ptr",token)
   DllCall("CloseHandle", "Ptr",hProc)
   Return res
}

给TA捐赠
共{{data.count}}人
人已捐赠
其他应用案例

AHK 接收参数运行 嵌入Listary菜单中

2022-2-24 15:56:48

应用

能不能实现Rime小狼毫输入法非输入状态自动切换为英文?

2022-3-5 9:23:21

6 条回复 A文章作者 M管理员
  1. 火

    多指针没有效果,最多只能偏移一次,例如ce第八关4级指针读取不了数据

  2. ┌刘

    虽然看不懂,但感觉也是很厉害

  3. 蜜獾哥
    蜜獾哥给您打赏了¥2
  4. AHK中文社区
    1河许人给您打赏了¥2
个人中心
购物车
优惠劵
有新私信 私信列表
搜索