; 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 }
声明:站内资源为整理优化好的代码上传分享与学习研究,如果是开源代码基本都会标明出处,方便大家扩展学习路径。请不要恶意搬运,破坏站长辛苦整理维护的劳动成果。本站为爱好者分享站点,所有内容不作为商业行为。如若本站上传内容侵犯了原著者的合法权益,请联系我们进行删除下架。
评论(0)