PSVITACHEATZ06
1 界面
2 下载
3 Z06版更新
- 只支持3.65系统以上
- 增加支持suprx插件方式金手指
- 使用双缓冲改善图像闪烁问题
- 更换字体文件,增加繁体中文界面
- cheat文件编码从GBK转变为UTF8
- dump内存多生成同名.txt文件,记录进程所有的module信息以供金手指制作者使用
- 改进B2格式代码
- 精准搜索搜索范围增加Auto选项
- 主界面显示游戏名称、剩余内存信息
- 适配游戏分辨率不是960*544的显示
4 更新内容介绍
4.1 只支持3.65系统以上
没什么好说的,懒得去适配3.60系统了,要使用新版请升级系统,否则用回Z05版。
4.2 增加支持suprx插件方式金手指
普通作弊代码格式方式不够灵活,对于进阶者来说可能希望使用更灵活的插件方式编写作弊代码。
首先需要搭建PSV开发环境,此处略过不谈,可自行上网搜索解决。
然后来看Example,最终幻想X高清版(PCSH00042)的修改,原作弊代码来自于http://www.speedfly.cn/19985.html
这里仅做移植演示,下面对重要的地方作说明,其他地方参考Example来修改即可。
/** * 结构体代表一项修改 * {{language}}_name代表修改名称,vitacheat会根据菜单语言选择相应的选项 * func是函数指针,函数内执行修改 **/ typedef struct vitacheatinfo { char* english_name; char* simplified_name; char* traditional_name; char* japanese_name; /* 本来想做日文菜单的,没时间只能暂时放弃,这一项暂时没用 */ uintptr_t func; } vitacheatinfo; /** * 00. module name: ffx_phyreApp * path: ux0:/app/PCSH00042/ffx_phyreApp.self * vaddr: 0x81000000 * memsz: 0x62af50 * vaddr: 0x8162b000 * memsz: 0x1dd283c **/ /** * 由module name获取module信息,这里的module name是ffx_phyreApp **/ int get_ffx_phyreApp_module(tai_module_info_t* pt_module_info) { pt_module_info->size = sizeof(tai_module_info_t); return taiGetModuleInfo("ffx_phyreApp", pt_module_info); } /** * * Code Author: Dask * Source: http://www.speedfly.cn/19985.html * * _V0 Max Gil After Using => _V0 Max Gil After Using * $A100 811CD8C4 0000BF00 => $B200 00000000 00000000 * => $A100 001CD8C4 0000BF00 * **/ static SceUID mgauUID = -1; /** * CODE区修改 * 锁定/禁用 切换的时候会调用该函数 **/ static void max_gil_after_using(int lock) { if (lock) { /** * 锁定 **/ if (mgauUID > 0) { return; } /** * 获取module信息 **/ tai_module_info_t module_info; int ret = get_ffx_phyreApp_module(&module_info); if (ret != 0) { return; } /** * 设置offset和value,对应 * $A100 001CD8C4 0000BF00 **/ const uint32_t offset = 0x1CD8C4; const uint16_t value = 0xBF00; /** * 设置参数调用taiInjectDataForUser修改内存 **/ tai_offset_args_t args; args.size = sizeof(args); args.modid = module_info.modid; args.segidx = 0; args.offset = offset; args.source = &value; args.source_size = sizeof(value); /** * 记录injectid,后面释放需要 **/ mgauUID = taiInjectDataForUser(&args); } else { /** * 禁用,对应CODE区修改这里需要"解锁"释放内存,让程序值恢复原值 **/ if (mgauUID > 0) { taiInjectRelease(mgauUID); mgauUID = -1; } } } /** * Code Author: Dask * Source: http://www.speedfly.cn/19985.html * * _V0 All Item 99 => _V0 All Item 99 * $4101 8262A76C 00002000 => $B200 00000001 00000000 * $006F 00000002 00000001 => $4101 00FFF76C 00002000 * $4001 8262A96C 00000063 => $006F 00000002 00000001 * $006F 00000001 00000000 => $4001 00FFF96C 00000063 * => $006F 00000001 00000000 * **/ /** * DATA区修改 * 锁定/禁用 切换的时候会调用该函数 **/ static void all_item_99(int lock) { if (lock) { /** * 获取module信息 **/ tai_module_info_t module_info; int ret = get_ffx_phyreApp_module(&module_info); if (ret != 0) { return; } /** * 获取kernel_module_info **/ SceKernelModuleInfo kernel_module_info = {0}; ret = sceKernelGetModuleInfo(module_info.modid, &kernel_module_info); if (ret != 0) { return; } /** * 获取seg1(也就是DATA区)的base **/ SceKernelSegmentInfo* seg1 = &(kernel_module_info.segments[1]); uint16_t value1 = 0x2000; uint32_t offset = 0xFFF76C; for (int i = 0; i < 0x6F; ++i) { /** * 定位到实际地址 **/ void* addr = seg1->vaddr + offset + i * 0x2; *(uint16_t*)addr = value1; value1 += 0x1; } const uint8_t value2 = 0x63; offset = 0xFFF96C; for (int i = 0; i < 0x6F; ++i) { void* addr = seg1->vaddr + offset + i; *(uint8_t*)addr = value2; } } /** * 注意DATA区修改不需要记录injectid,也不需要恢复原值,所以禁用(lock=0)情况不需要编写代码 **/ } /** * CHEAT LIST * 定义作弊代码名称和对应上面的函数即可。 **/ static vitacheatinfo info[] = { { .english_name = "Max Gil After Using", .simplified_name = "金钱变动后MAX", .traditional_name = "金錢變動后MAX", .japanese_name = "Max Gil After Using", .func = (uintptr_t)max_gil_after_using }, { .english_name = "All Item 99", .simplified_name = "全道具99个", .traditional_name = "全道具99個", .japanese_name = "All Item 99", .func = (uintptr_t)all_item_99 }, { .english_name = NULL, .simplified_name = NULL, .traditional_name = NULL, .japanese_name = NULL, .func = 0 }, };
重点就是上面的内容,其他要修改的地方就是把Example涉及到titleid都替换成自己要改的titleid。
最后把源代码编译成{{titleid}}.suprx,放到ux0:vitacheat/plg目录下即可。
4.3 使用双缓冲改善图像闪烁问题
对菜单进行操作需要刷新界面,在原图像内绘制会明显感受到闪烁,使用双缓冲后几乎感受不到闪烁,当然了内存占用也会增加一倍,如果申请不到足够内存则不使用双缓冲。
4.4 更换字体文件,增加繁体中文界面
以前版本的中文字体使用的GBK编码,新版改为UNICODE,界面增加繁体中文,cheat文件支持英文、简体中文、繁体中文、日文、韩文。
4.5 cheat文件编码从GBK转变为UTF8
字体更换了,原来的cheat文件编码也跟着变化,所以之前的cheat文件需要重新保存为UTF8编码。
4.6 dump内存多生成同名.txt文件,记录进程所有的module信息以供金手指制作者使用
Z05版显示了EBOOT(大多数游戏的main module)的信息,目的是为了解决不同版本的游戏内存偏移问题,但是少部分游戏数值存在其他module,这次更新导出所有module信息。
4.7 改进B2格式代码
Z05版新增的内容,当时只考虑到EBOOT,这次更新可以定位到其他module。
$B2XX 0000000Y 00000000 XX=module序号(从上面的同名.txt文件可知相应的module序号) Y=0或1,0代表seg0,1代表seg1
Z06更新了XX部分,兼容以前代码。
由于module动态加载/卸载,通过序号定位module的方法依然不能100%保证到准确的module,最好的办法是写suprx根据module name定位。
4.8 精准搜索搜索范围增加Auto选项
选择Auto选项不用指定搜索范围,程序搜索所有的module和heap内存。
4.9 主界面显示游戏名称、剩余内存信息
插件主界面增加游戏名称、剩余内存信息显示,剩余内存等于3个值相加,单位是字节。
4.10 适配游戏分辨率不是960*544的显示
少部分游戏分辨率不是960*544,导致插件的界面显示异常,这次更新修复大部分情况,少数界面如内存浏览更改适配麻烦未做修改。
5 FAQ
5.1 为什么config配置了插件路径却没能呼出金手指插件?
- tai/config.txt文件通常有两个(ux0、ur0),其中只有一个有效,确认更改的config文件正确(ux0优先于ur0)
- 确认vitacheat.suprx放入正确的目录
- 确认机器重启(所有skprx替换要生效都必须重启)
- 其他原因
5.2 为什么搜索不到数值?
- 搜索类型不正确(比如道具数量通常是8bit,搜索类型却选择了32bit)
- 搜索范围不正确,可适当的扩大范围,或者使用新版的Auto选项
- 游戏里显示的值与游戏内实际存储的值不一致(比如Virtua Tennis 4分数显示的15、30,实际存储的却是1、2)
- 其他原因
5.3 为什么插件呼出后CHEAT LIST为空?
- 确认db目录有相应的{{titleid}}.psv文件
- 确认{{titleid}}.psv文件没有语法错误(新版加载到语法错误的.psv文件会提示)
- 其他原因
5.4 为什么锁定了金手指代码没效果或者异常退出?
- 使用者游戏版本与金手指代码制作者的游戏版本不一致(NND和MAI,以前的很多代码没使用B2格式,NND与MAI格式能共用的少)
- 使用者游戏版本号与金手指代码制作者的游戏版本号不一致(比如使用者游戏版本号1.05,制作者游戏版本号1.00)
- 其他原因
5.5 为什么有些游戏金手指插件无法呼出?
少数游戏设计机制比较独特,导致无法正常兼容,暂时没时间精力去处理这部分问题。新版提供游戏启动时按L键不加载vitacheat.suprx。
5.6 为什么CHEAT LIST里代码组限制为50组?
50组已经能够包含绝大部分修改功能了,而且每组最多200行代码,总共50*200=10000行代码已经能够容纳足够多的修改。
5.7 指针搜索功能?
之前有打算过在vitacheat里面做指针搜索功能,实验过后发现虽然可行,但是很多麻烦的细节要处理,暂时没有时间精力去弄。
6 Support or Contact
有问题请联系finalcheat@gmail.com