PSVITACHEATZ06

Table of Contents

1 界面

vitacheat_eng_main_menu.png

vitacheat_simp_main_menu.png

vitacheat_trad_main_menu.png

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

Author: FinalCheat

Created: 2018-12-25 Tue 00:00