吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 15490|回复: 39
收起左侧

[游戏安全] cheat engine--CE游戏修改-共用代码-aob注入-人造指针-指针扫描--以《枪血黑手党...

  [复制链接]
laozhhaiJohn 发表于 2022-3-27 21:31
本帖最后由 laozhhaiJohn 于 2022-4-16 14:09 编辑

cheat engine--CE游戏修改-共用代码-aob注入-人造指针-指针扫描--以《枪血黑手党2》为例
20220319:

    闲来无事,反正因为疫情被封在小区,鼓捣鼓捣游戏和cheat engine吧。这次用《枪血黑手党2》(Guns Gore and Cannoli 2)来一次共用代码、aob注入、人造指针、指针扫描、线程注入的游戏。
    特别强调!!!!!这只是我在修改游戏时候,在win10记事本中记录的自己修改的过程和心得,由于记事本的限制,因此没有配图片,请见谅!!!!!



一、找主角生命值:
数值类型:单浮点
搜索方法:初始未知->减少、不变等等几次搜索
结果:找到三个值(查看其初始值为150),两个地址类似2D74E8**,一个地址类似455*****。
分析:不一样的那个地址,每次载入游戏会变化(指没有退出游戏情况下,比如主角别干掉。如果退出游戏到系统后再运行游戏,则3个地址都会变化,但是2个基本不变1个经常变的规律通用)。
    锁定这个地址后,主角血量不减。

二、CE进行剖析:
  1、在该不一样地址上右键,“找出什么改写了这个地址”
  2、主角被击打掉血后,找到一条指令:
     ???????? - F3 0F11 AE C0010000  - movss [rsi+000001C0],xmm5
  3、ce替换该指令,主角不掉血了,但是敌人也不掉血了!!!
     看来不能简单粗暴的替换!


三、代码共用程序段的分析:
  4、在ce找到指令的窗口中,在指令上右键点击,然后选择右键菜单中的“找出代码访问的地址”
  5、然后ce打开新窗口“访问的地址为。。。”,
  6、返回游戏,主角修理一下对面的几个敌人,
  7、这时候发现,在“访问的地址为。。。”窗口出现了几个地址。
     仔细查看可以发现,其中一个为主角血量的地址,其余几个为当前被主角击打的敌人地址。
  8、在CE找到指令窗口,点击右侧按钮“显示反汇编程序”,ce新建内存浏览窗口(Memory Viewer)。
  9、在窗口中点“工具”--“分析数据/结构”,出现一个“结构分析”窗口.
     (步骤8、9,其实可以合为一个步骤,即在访问地址窗口选中那几个地址,然后右键,选择“打开选中地址的分析数据”,然后在新出现的窗口点击“<新建窗口>”,之后一路确定,也会打开一个下面第12步的数据分析窗口。)


  10、在结构分析窗口中,将主角和敌人的地址分别加进去。
      首先在群组1的第一个地址中,填写第7步窗口中主角的地址-1C0(也就是填写rsi的地址,因为访问地址中的地址,是程序的rsi+000001C0后得到的地址,现在需要从rsi开始分析结构,所以真实地址要减去1C0。)
      然后,点击“文件”--“添加额外的地址”,在群组1下又出现一个地址框,将敌人的地址填入,同样减去1C0。
      之后,将其余敌人地址按照上面方法一一填入。
  11、地址都填写完毕,发现结构分析窗口下面空白,并没有任何数据。
      点击“结构”--“定义新的结构”,可以命名该结构名称,注意:在长度位置需要填写大一些的一个值,至少要比1C0要大(1c0为十进制400多,所以可以长度填写500以上)。
      这时候发现这两个地址下出现大量数据。
  12、仔细对比敌我的数据,红色的为不同值,绿色的为相同值。我们主要看不同值有什么特点。
     发现几组地址似乎可以用:
     例如:+190处(4字节),主角为1,敌人为0
     例如:+1BC处(4字节),主角为1,敌人为0
     例如:+250处(4字节),主角为1,敌人为0
     例如:+260处(4字节),主角为1,敌人为0

     例如:+194处(4字节),主角为0,敌人为1
     例如:+1A4处(4字节),主角为0,敌人为1

     例如:+1DC处(浮点),主角为1,敌人为0
     例如:+258处(4字节),主角为0,敌人为7
     例如:+25C处(4字节),主角为2,敌人为1

     例如:+184处(4字节),主角为0,敌人为巨大数值

     多运行几次游戏,观察后可发现,有几处会发生变化,比如+1BC处,可能都会变为1。
     不会变化的有几处:+190,+194,+1DC(浮点),+250,+260。

     但是,诡异的是,这些值都是在游戏暂停时候的值!!!
     一旦游戏处于非暂停的运行状态,则好几处值比如+190、+194等,无论敌我,值都会变成相同的,导致无法区分敌我。

     于是再次在游戏非暂停状态下,主角或者敌人被打击的时候,观察这些值!!

     发现+260处(4字节),主角为1,敌人为0不会变动。但是在第二个小关卡即楼房好多窗户中藏着好多警察的地方,这些警察的+260值竟然也为1,无法区分敌我啦。

     +184(4字节),+226(2字节),+22A(2字节),这三个地址,我方为0,敌方都不为0.
    选择+184这个偏移的值,作为区分敌我的判断。

四、通过分析共用代码后,进行汇编代码注入:
  13、在内存浏览窗口中,点击“工具”--“自动汇编”后,出现自动汇编窗口。
  14、在新窗口中,点击“模板”--“CT表框架代码”;然后继续点击“模板”--“代码注入”,ce自动填写了一些代码。
  15、写代码:
    主要是增加了2条指令,一个比较[rsi+1BC]处的值是否为1,为1则跳走不执行减少血量命令,为0则执行减血命令。
    代码如下:


[ENABLE]
//code from here to '[DISABLE]' will be used to enable the cheat
alloc(newmem,2048,01469BEF)
label(returnhere)
label(originalcode)
label(exit)

newmem: //this is allocated memory, you have read,write,execute access
//place your code here
cmp [rsi+00000260],1
//比较这个地址,值为1是主角,值为0是敌人
je exit
//上一条比较,为1相等(是主角)则跳走不减血。不相等,则继续执行减血指令。

originalcode:
movss [rsi+000001C0],xmm5

exit:
jmp returnhere

01469BEF:
jmp newmem
nop 3
returnhere:


[DISABLE]
//code from here till the end of the code will be used to disable the cheat
dealloc(newmem)
01469BEF:
movss [rsi+000001C0],xmm5
//Alt: db F3 0F 11 AE C0 01 00 00



五、通过特征码扫描定位注入代码,完成锁定主角生命值任务!

    16、上面的脚本勾选运行后,又发现新情况!!!
    就是:完全退出游戏到win10桌面,再次打开游戏进入,发现修改无效。
    再次查找血槽值,找到后,找“改写该地址的指令”,发现指令的地址变化啦(指令本身的字节数组不变,但是存放这段指令的地址发生了变化。)。
    因此需要找这段指令的字节数组的特征码,然后让CE搜索此特征码,找到后再进行注入处理。

    17、
     第2步中的减血指令:
     ???????? - F3 0F11 AE C0010000  - movss [rsi+000001C0],xmm5
     在CE中搜索该指令的字节码,看看是否唯一:

    首先在游戏中游玩,让主角挨打以及打击敌人(否则搜索不到。)
    在ce中搜索,设置如下:
数值类型:字节数组
搜索方法:注意在搜索框前面,有个十六进制的复选框,需要勾选上。
          然后将“F3 0F11 AE C0010000”复制到搜索框中,点击“首次扫描”。
结果:找到1或者2个地址。
分析:有时候找到1个唯一地址,有时候找到2个地址,不知道怎么回事。但多数时候找到1个地址。
    (20220322补充:后来发现,如果发现是2条的话,可能是编写的脚本没有将内存中脚本中
   的该条指令清除导致的,因此,如果游戏退出到win10系统,再进入游戏,则只能找到
   唯一地址。)

      (因此,为了保险起见,对比找到的2个地址,发现该指令后面很长是相同的,该指令向前找几条之后发现不同。因此从这个不同开始将特征码扩大如下:
      0F83 5B000000 F3 0F10 45 F0 F3 0F5A C0 F2 0F5A E8 F3 0F11 AE
      然后再ce中按照上述步骤搜索,可以发现多次只能搜索到唯一一个地址。
      因此确定使用这个特征码。)这段没有使用。

    18、在ce的自动汇编窗口中编写指令:

        在下面的CEAA中,同时增加给主角加血、对敌人一击必杀的指令。


{ Game   : ggc2.exe
  Version:
  Date   : 2022-03-20
  This script does blah blah blah
}

[ENABLE]
//code from here to '[DISABLE]' will be used to enable the cheat

aobscan(zhurudian,F3 0F 11 AE C0 01 00 00) // should be unique
alloc(newmem,$1000,zhurudian)

label(code)
label(return)

label(exit)

label(team1)  //我方
label(team0)  //敌方
label(team1Value)  //我方血量
label(team0Value)  //敌方血量


newmem:
  pushfq   ///保存标志位
  cmp [rsi+00000184],0 ///检测是否为我方team1
    //比较这个地址,值为0是主角,值不是0则敌人. 注意执行后ZF值的变化。
    //等,则设置ZF=1,不等则置0
  je team1  //je表示等,则跳转.等与不等看标志位ZF,zf=1表示相等。
    //为1相等(是主角)则跳。不相等,则继续执行。
       //cmp [rsi+00000184],0 ///检测是否为敌方team0//等,则置ZF=1,否则置0
  jne team0  //不等则跳.标志位ZF=0表示不等。
  exit:
    popfq ///恢复标志位

code:
  movss [rsi+000001C0],xmm5
  jmp return

team1: //我方
  movss xmm5,[team1Value]
  jmp exit

team0: //敌方
  movss xmm5,[team0Value]
  jmp exit

team1Value: //我方
  dd (float)5000 //主角血槽值5000

team0Value: //敌方
  dd 0  //敌方血槽值置0,一击必杀

zhurudian:
  jmp newmem
  nop 3

return:
  registersymbol(zhurudian)

[DISABLE]
//code from here till the end of the code will be used to disable the cheat
zhurudian:
  db F3 0F 11 AE C0 01 00 00

unregistersymbol(zhurudian)
dealloc(newmem)

{
// ORIGINAL CODE - INJECTION POINT: 06E999CF

06E9999D: F3 0F 10 45 F0                 - movss xmm0,[rbp-10]
06E999A2: F3 0F 5A C0                    - cvtss2sd xmm0,xmm0
06E999A6: F3 0F 10 8E C0 01 00 00        - movss xmm1,[rsi+000001C0]
06E999AE: F3 0F 5A C9                    - cvtss2sd xmm1,xmm1
06E999B2: 66 0F 2F C8                    - comisd xmm1,xmm0
06E999B6: 0F 8A 61 00 00 00              - jp 06E99A1D
06E999BC: 0F 83 5B 00 00 00              - jae 06E99A1D
06E999C2: F3 0F 10 45 F0                 - movss xmm0,[rbp-10]
06E999C7: F3 0F 5A C0                    - cvtss2sd xmm0,xmm0
06E999CB: F2 0F 5A E8                    - cvtsd2ss xmm5,xmm0
// ---------- INJECTING HERE ----------
06E999CF: F3 0F 11 AE C0 01 00 00        - movss [rsi+000001C0],xmm5
// ---------- DONE INJECTING  ----------
06E999D7: 48 8B CE                       - mov rcx,rsi
06E999DA: 48 83 EC 20                    - sub rsp,20
06E999DE: 49 BB 10 A3 3B 2C 00 00 00 00  - mov r11,000000002C3BA310
06E999E8: 41 FF D3                       - call r11
06E999EB: 48 83 C4 20                    - add rsp,20
06E999EF: 85 C0                          - test eax,eax
06E999F1: 74 09                          - je 06E999FC
06E999F3: 8B 46 20                       - mov eax,[rsi+20]
06E999F6: 83 C8 01                       - or eax,01
06E999F9: 89 46 20                       - mov [rsi+20],eax
}




六、通过指针扫描获取血槽值基址。
    指针扫描可以用来快速解决这个问题,首先找到所需值的地址,保存生成的指针映射,重新启动游戏,再次搜索地址,保存另一个指针映射,然后将两者进行比较。

  1、搜索血量地址并加入到ce表中:(同上不再详述。)
  数值类型:单浮点
  扫描类型:
  搜索方法:
  结    果:
  分    析:
  锁    定:

  2、找到三个地址中的关键地址,在该地址上右键--选择“对这个地址进行指针扫描”。
    在指针扫描器的窗口选项中,我习惯将最大偏移设置为2000,最大偏移级别设置为6。(这样如果找不到基址,则可以考虑增大最大偏移和最大偏移级别。)其他选项可以不管。
    确定后,ce提示保存到一个文件。之后,根据设置和游戏的大小以及电脑性能的不同,ce开始时间略长的一个分析。之后会报告找到n个指针路径。

  3、游戏重开关卡或者退出游戏重新开启。之后再次搜索到主角血量地址,地址加入ce表。
    如果指针扫描窗口已关闭,请打开保存的指针列表。这时候,列表中一些内容显示???表示错误了。
    现在在扫描窗口,点“指针扫描器”-->“重新扫描内存”选项。
    在新打开的选项窗口中,选“要查找的地址”,并输入新的血量地址。
    为新指针列表选择一个名称保存,CE过滤掉指向错误地址的指针。指针列表中指针减少。

  4、将上面1、2、3步骤重复几次,指针列表数大量减少。
    观察这些指针,找指针层级较少的一些,和不同的模块下的指针,双击这些想要的指针,即可将这个指针加入到ce表中。这里建议多找一些指针存到ce表中,以备有些指针是错误的好以后剔除。
    载入游戏几次后,或者重启电脑载入游戏几次后,会发现又有许多指针不能使用了。删这些错误的指针,留下正确的。



七、通过人造指针设置血槽值。
  【申请地址】创建人造指针法:
  (1) 右键点血量值的地址,打开“找出是谁改写了这个地址”,找到固定的程序段。

  (2) 在下列操作码写入到??????窗口中,选择“显示反汇编程序”。
    之后会打开该程序段的内存视图,选择“工具”-“自动汇编”-“模板”-“CT表框架”-“代码注入”或者“AOB注入”。由于本游戏这里的代码段也是随机分配的,所以选择aob注入。

  (3) 使用alloc(标识名,地址长度)动态申请内存,将血量地址保存到申请的内存中。

  (4) 申请的内存地址一般只能在当前脚本中使用,我们将其保存到一个全局变量中,使得可以在其它脚本中也能访问使用。
   CEAA提供了一个函数命令registersymbol(标识名),表示将参数标识加入到全局表。

  (5) 在[disable]中添加释放申请内存的指令dealloc(标识名,地值长度)

  (6) 前面将申请的内存标识加入了全局表,那么在关闭脚本时须将标识从全局表中剔除[unregistersymbol(标识名),将参数标识从全局表中剔除]

  (7) 在CE表中手动添加地址,类型为指针,地址填写该全局标识名。OK!!
     以下为该CEAA脚本代码:


{ Game   : ggc2.exe
  Version:
  Date   : 2022-03-21
}

[ENABLE]
//code from here to '[DISABLE]' will be used to enable the cheat

aobscan(INJECT,F3 0F 11 AE C0 01 00 00) // should be unique
alloc(newmem,$1000,INJECT)
alloc(my_point_HP,$4)
registersymbol(my_point_HP)

label(code)
label(return)

newmem:
  push eax
  lea eax,[rsi+000001C0]
  mov [my_point_HP],eax
  pop eax

code:
  movss [rsi+000001C0],xmm5
  jmp return

INJECT:
  jmp newmem
  nop 3

return:
registersymbol(INJECT)

[DISABLE]
//code from here till the end of the code will be used to disable the cheat
INJECT:
  db F3 0F 11 AE C0 01 00 00

unregistersymbol(INJECT)
unregistersymbol(my_point_HP)
dealloc(newmem)
dealloc(my_point_HP)

{
// ORIGINAL CODE - INJECTION POINT: 0129189F

0129186D: F3 0F 10 45 F0                 - movss xmm0,[rbp-10]
01291872: F3 0F 5A C0                    - cvtss2sd xmm0,xmm0
01291876: F3 0F 10 8E C0 01 00 00        - movss xmm1,[rsi+000001C0]
0129187E: F3 0F 5A C9                    - cvtss2sd xmm1,xmm1
01291882: 66 0F 2F C8                    - comisd xmm1,xmm0
01291886: 0F 8A 61 00 00 00              - jp 012918ED
0129188C: 0F 83 5B 00 00 00              - jae 012918ED
01291892: F3 0F 10 45 F0                 - movss xmm0,[rbp-10]
01291897: F3 0F 5A C0                    - cvtss2sd xmm0,xmm0
0129189B: F2 0F 5A E8                    - cvtsd2ss xmm5,xmm0
// ---------- INJECTING HERE ----------
0129189F: F3 0F 11 AE C0 01 00 00        - movss [rsi+000001C0],xmm5
// ---------- DONE INJECTING  ----------
012918A7: 48 8B CE                       - mov rcx,rsi
012918AA: 48 83 EC 20                    - sub rsp,20
012918AE: 49 BB 80 0A 05 2C 00 00 00 00  - mov r11,000000002C050A80
012918B8: 41 FF D3                       - call r11
012918BB: 48 83 C4 20                    - add rsp,20
012918BF: 85 C0                          - test eax,eax
012918C1: 74 09                          - je 012918CC
012918C3: 8B 46 20                       - mov eax,[rsi+20]
012918C6: 83 C8 01                       - or eax,01
012918C9: 89 46 20                       - mov [rsi+20],eax
}


八、完善:

    上面脚本中,都依赖rsi的值来确定玩家的血量地址。但是在游戏开启脚本后,会发现,rsi的值也是敌我共用的。当敌人攻击玩家的时候,rsi的值是玩家;当玩家攻击敌人时候,rsi的值是敌人。因此,自造指针在玩家攻击敌人时候显示敌人血槽值。

    因此,再次研究血量减少的指令代码。在指令代码上右键后点击"指令访问的地址",之后在指令访问的地址窗口中找到玩家和敌人的地址,对这些地址按CTRL+R键(或者右键选显示寄存器状态),打开这些地址当前寄存器情况窗口,仔细对比发现:

    玩家的R8=0,敌人R8都不为0

    于是,在脚本中判断这个值来区分敌我试试。完全ok。
    新脚本如下:

{ Game   : ggc2.exe
  Version:
  Date   : 2022-03-24
  aob注入后将rsi+1C0写全局-激活才有效-fix
}

[ENABLE]
//code from here to '[DISABLE]' will be used to enable the cheat

aobscan(INJECT,F3 0F 11 AE C0 01 00 00) // should be unique
alloc(newmem,$1000,INJECT)
alloc(my_point_HP,$4)
registersymbol(my_point_HP)

label(code)        //
label(return)      //
label(BuXiangDeng) //不相等

newmem:
  pushfq     //保存标志位
  cmp R8,0  //比较R8值是否为0,为0,则现在是主角
             //r8值为0则等,则设置标志ZF=1,不等则置0
  jne BuXiangDeng   //不等则跳:检测zf=0表示不等
             //等则不跳,继续执行下面的代码
  push eax   //保存eax值
  lea eax,[rsi+000001C0] //把玩家血量地址放到eax中转
  mov [my_point_HP],eax  //把玩家血量值放到”我的hp指针"
  pop eax    //恢复eax值
  BuXiangDeng:
    popfq  //恢复标志位

code:
  movss [rsi+000001C0],xmm5
  jmp return

INJECT:
  jmp newmem
  nop 3

return:
registersymbol(INJECT)

[DISABLE]
//code from here till the end of the code will be used to disable the cheat
INJECT:
  db F3 0F 11 AE C0 01 00 00

unregistersymbol(INJECT)
unregistersymbol(my_point_HP)
dealloc(newmem)
dealloc(my_point_HP)

{
// ORIGINAL CODE - INJECTION POINT: 0129189F

0129186D: F3 0F 10 45 F0                 - movss xmm0,[rbp-10]
01291872: F3 0F 5A C0                    - cvtss2sd xmm0,xmm0
01291876: F3 0F 10 8E C0 01 00 00        - movss xmm1,[rsi+000001C0]
0129187E: F3 0F 5A C9                    - cvtss2sd xmm1,xmm1
01291882: 66 0F 2F C8                    - comisd xmm1,xmm0
01291886: 0F 8A 61 00 00 00              - jp 012918ED
0129188C: 0F 83 5B 00 00 00              - jae 012918ED
01291892: F3 0F 10 45 F0                 - movss xmm0,[rbp-10]
01291897: F3 0F 5A C0                    - cvtss2sd xmm0,xmm0
0129189B: F2 0F 5A E8                    - cvtsd2ss xmm5,xmm0
// ---------- INJECTING HERE ----------
0129189F: F3 0F 11 AE C0 01 00 00        - movss [rsi+000001C0],xmm5
// ---------- DONE INJECTING  ----------
012918A7: 48 8B CE                       - mov rcx,rsi
012918AA: 48 83 EC 20                    - sub rsp,20
012918AE: 49 BB 80 0A 05 2C 00 00 00 00  - mov r11,000000002C050A80
012918B8: 41 FF D3                       - call r11
012918BB: 48 83 C4 20                    - add rsp,20
012918BF: 85 C0                          - test eax,eax
012918C1: 74 09                          - je 012918CC
012918C3: 8B 46 20                       - mov eax,[rsi+20]
012918C6: 83 C8 01                       - or eax,01
012918C9: 89 46 20                       - mov [rsi+20],eax
}





---------------------------------------------------------------------------

找主角武器弹药的地址:

一、链锯使用次数:

  1、搜索:
  数值类型:4字节
  扫描类型:精确数值
  搜索方法:每次扫描都输入游戏画面中的电锯值
  结    果:搜索2次后找到2个地址。
  分    析:分别锁定2个中的某一个,在游戏中使用电锯,可以发现1个地址是关键。
  锁    定:锁定2个中的关键地址后,电锯子弹不再变化。OK!

  2、(这个判断错误!)对关键地址进行指针扫描,但是扫描3次后找到0个指针!(这个判断错误!)
     (----------------补充完善:上面说的不对!!!!!----------------------)
     (找不到是因为设置的扫描指针层级少,当指针层级达到7或者8时候,就能搜到指针!!!)
     (但是,切切注意!!!当设置扫描指针层级达到7的时候,扫描时间尚可。
       当指针扫描层级设置为8的时候,扫描开始到记录结束,花费时间漫长,在我的配置较低的
       电脑上,以cpu占用较高情况下,扫描花费10分钟,而这只是一个中等以下级别的游戏!!)

     (所以,扫描指针的时候,一定以7级为一个量级,7级以下扫描不到,之后再设置扫描8级!)


  3、用查找“改写该地址指令”的方式,找到如下指令,
    062B57E3 - 89 46 1C  - mov [rsi+1C],eax
    但指令的地址也是动态的,每次开游戏会变动。

  4、因此上AOB,进行注入解决问题:

    采用搜索该代码(CE的AOB注入),然后定位该指令位置,然后汇编处理。

    打开该程序段的内存视图,选择“工具”-“自动汇编”-“模板”-“CT表框架”-“AOB注入”。

    CE会自动搜特征码(注意,是CE自动找,不需要人工找!),找到后定位到你指定的注入位置。

    编写代码,保存到CT表,锁定,发现一切OK。

   (代码段(特征码)是:48 63 46 1C FF C8 89 46 1C 48 8B 75 F8 C9)


{ Game   : ggc2.exe
  Version:
  Date   : 2022-03-22
  武器链锯不掉链子的自动脚本!哈哈,新版本。
}

[ENABLE]
//code from here to '[DISABLE]' will be used to enable the cheat

aobscan(INJECT,C8 89 46 1C 48 8B 75 F8) // should be unique
alloc(newmem,$1000,INJECT)

label(code)
label(return)

newmem:
  mov eax, #8000  //给电锯加8000个子弹量,这样电锯就不会掉链子了。
  //在CEAA中,#代表数值为十进制,$代表十六进制。

code:
  mov [rsi+1C],eax  //注意这里的eax,其值为8000了。
  mov rsi,[rbp-08]
  jmp return

INJECT+01:
  jmp newmem
  nop 2
return:
registersymbol(INJECT)

[DISABLE]
//code from here till the end of the code will be used to disable the cheat
INJECT+01:
  db 89 46 1C 48 8B 75 F8

unregistersymbol(INJECT)
dealloc(newmem)

{
// ORIGINAL CODE - INJECTION POINT: 062B57E3

062B57C0: 49 BB 50 D8 75 2C 00 00 00 00  - mov r11,000000002C75D850
062B57CA: 41 FF D3                       - call r11
062B57CD: 48 83 C4 20                    - add rsp,20
062B57D1: 85 C0                          - test eax,eax
062B57D3: 75 11                          - jne 062B57E6
062B57D5: 48 63 46 1C                    - movsxd  rax,dword ptr [rsi+1C]
062B57D9: 85 C0                          - test eax,eax
062B57DB: 7E 09                          - jle 062B57E6
062B57DD: 48 63 46 1C                    - movsxd  rax,dword ptr [rsi+1C]
062B57E1: FF C8                          - dec eax
// ---------- INJECTING HERE ----------
062B57E3: 89 46 1C                       - mov [rsi+1C],eax
// ---------- DONE INJECTING  ----------
062B57E6: 48 8B 75 F8                    - mov rsi,[rbp-08]
062B57EA: C9                             - leave
062B57EB: C3                             - ret
062B57EC: 00 00                          - add [rax],al
062B57EE: 00 00                          - add [rax],al
062B57F0: 00 00                          - add [rax],al
062B57F2: 00 00                          - add [rax],al
062B57F4: 3C 00                          - cmp al,00
062B57F6: 00 00                          - add [rax],al
062B57F8: 4C 00 00                       - add [rax],r8l
}



                                 bylaoz20210113 fix:20220322


二、单手枪子弹:

  1、搜索:
  数值类型:4字节
  扫描类型:精确数值
  搜索方法:每次扫描都输入游戏画面中的单手枪枪内子弹值
  结    果:搜索2次后找到1个地址。
  分    析:锁定1个地址。
  锁    定:锁定1地址后,单手枪子弹不再变化。OK!

  2、

三、双枪子弹:
  1,在游戏画面中,主角头上方为血量值。再上面是手中使用武器的弹药量。
    弹药量显示类似为:15/80  这样子。在斜杠左边的15,代表武器中弹夹内子弹数。
    斜杠右边的80,代表携带的剩余子弹数。这两个数的和就是该武器的总弹药数。

    来查找并修改枪弹夹子弹数并锁定,这样就不至于在激烈的战斗中耽误时间换弹夹啦。

  2,查找枪内弹夹子弹地址:
    数值类型:4字节
    扫描类型:精确值
    搜索方法:输入当前子弹数,几次搜索后得到唯一值。
    结    果:找到唯一值,该值等于游戏画面中显示的值。
    分    析:
    锁    定:锁定这个地址后,弹夹内子弹数不减。
              但是,但是你会发现手枪的总子弹数在减少!!!

  3,查找携带的双枪子弹总数地址:
    数值类型:4字节
    扫描类型:精确值
    搜索方法:输入弹夹子弹数+剩余子弹数,几次搜索后得到唯一值。
    结    果:找到唯一值,该值不在游戏画面中显示。
    分    析:
    锁    定:锁定这个地址后,总弹药数不减。
              同时锁定弹夹子弹数后,两个数值都不再变化!!ok!!

  4,链锯、单枪、双枪弹夹、双枪总弹药这4个地址之间毫无关联关系!!!


四、找控制指令:
   在分别在手枪、双枪弹夹地址上右键,点“找出什么改写了这个地址”。
   发现一条指令在不停的执行,计数值不断增大。
   开枪试试,发现在“下列操作码写入到??????”窗口新增了一条指令。就是下面这条指令。

   2B1D0283 - mov [rdi+24],eax    (字节码:89 47 24)

   控制单手枪的子弹减少指令地址,同控制双枪弹夹子弹的指令和地址都完全一样!!!

   再找双枪子弹总数的控制指令,发现该指令和链锯的控制指令完全一样!!!

   后面的其他武器,都是这里的两条语句控制。


五、扫描查找弹夹值和总弹药值的指针:

     (扫描指针层级达到7或者8时候,就能搜到这两个值的基址!!!)
     (但是,切切注意!!!当设置扫描指针层级达到7的时候,扫描时间尚可。
       当指针扫描层级设置为8的时候,扫描开始到记录结束,花费时间漫长,在我的配置较低的
       电脑上,以cpu占用较高情况下,扫描花费10分钟,而这只是一个中等以下级别的游戏!!)

     (所以,扫描指针的时候,一定以7级为一个量级,7级以下扫描不到,之后再设置扫描8级!)

    弹夹值和总弹药值我分别搜索到上百个的基址。建议多选一些基址指针,层级少的一定要都加入到地址表中,之后层级多的也要选一些不同类型的加入地址表。根据我的CE使用经验,一般来说,加到地址列表的指针,经过多次重启游戏,都会有一些错误的,所以在地址表中多加一些指针以备删除错误留下正确可用的。
    我加了大约20多个地址,经过几次游戏退出打开和电脑关闭打开,剔除失效不准的地址,一般我会留下10个地址存入一个地址分组中。然后将指针层级最少的之一拿出来,供其他脚本使用。

六、利用基址指针修改并锁定血槽值、弹夹值、总弹药值。20220327

    但是这个脚本有个缺陷:在脚本执行中,当玩家更换武器以后,弹夹子弹不减少,但是总弹药值在减少。但是关闭脚本,再次打开脚本,这个脚本就按照我们设计的执行了,也就是说血量、、弹夹值、总弹药值又都被锁定。但是不要换武器!

{ Game   : ggc2.exe
  Version:
  Date   : 2022-03-26
  指令注入到弹夹子弹减少代码位置。
}

    define(hppt,[[[[[["ggc2.exe"+01449AA0]+0]+10]+28]+48]+1C0]) //血量值指针
  define(djpt,[[[[[[[["ggc2.exe"+01449AA0]+0]+10]+28]+50]+028]+10]+24]) //弹夹指针
define(zzdpt,[[[[[[[[["ggc2.exe"+01449AA0]+0]+10]+28]+50]+028]+10]+18]+1C]) //总子弹指针

[ENABLE]
//code from here to '[DISABLE]' will be used to enable the cheat

aobscan(INJECT_danjia894724,89 47 24 48 8B CF 48)    // danjia894724:
alloc(newmem_danjia894724,$1000,INJECT_danjia894724) //表示:弹夹+指令操作码

label(code)
label(return)

alloc(mydjpt,$4,INJECT_danjia894724)

newmem_danjia894724:  //脚本跳转到这里

  mov hppt,(float)99999 //脚本运行的第二句指令,以下顺序执行.这里加血量
  //mov djpt,#9999      //加子弹(但是下面的注入点的原始代码,会将eax写入弹夹地址
                        //而eax目前保存的是当前弹夹子弹数(未修改的)。所以这句即使
                        //执行了,也会因为下面mov [rdi+24],eax代码而使这里做无用功。
    mov eax,#9999       //因此,这里将加子弹数先写入eax。)
  mov zzdpt,#109999     //加总弹药

code:  //注入点原始代码
  mov [rdi+24],eax   //这里eax9999写入弹夹地址。这里[rdi+24] 和djpt是同一个地址)
  mov rcx,rdi
  jmp return //以上顺序执行到这里,在这里跳到return

INJECT_danjia894724: //以下是原始程序中的注入点!
  jmp newmem_danjia894724 //注意,这是脚本运行的第一句指令
  nop
return: //跳到return这里后,脚本结束,跳回原始程序注入点下一句。
registersymbol(INJECT_danjia894724)

[DISABLE]
//code from here till the end of the code will be used to disable the cheat
INJECT_danjia894724:
  db 89 47 24 48 8B CF

unregistersymbol(INJECT_danjia894724)
dealloc(newmem_danjia894724)

{
// ORIGINAL CODE - INJECTION POINT: 2A156FB3

2A156F9A: 00 00                          - add [rax],al
2A156F9C: 00 00                          - add [rax],al
2A156F9E: 00 00                          - add [rax],al
2A156FA0: 55                             - push rbp
2A156FA1: 48 8B EC                       - mov rbp,rsp
2A156FA4: 57                             - push rdi
2A156FA5: 48 83 EC 08                    - sub rsp,08
2A156FA9: 48 8B F9                       - mov rdi,rcx
2A156FAC: 48 89 55 F0                    - mov [rbp-10],rdx
2A156FB0: 48 8B C2                       - mov rax,rdx
// ---------- INJECTING HERE ----------
2A156FB3: 89 47 24                       - mov [rdi+24],eax
// ---------- DONE INJECTING  ----------
2A156FB6: 48 8B CF                       - mov rcx,rdi
2A156FB9: 48 83 EC 20                    - sub rsp,20
2A156FBD: 49 BB 00 70 15 2A 00 00 00 00  - mov r11,000000002A157000
2A156FC7: 41 FF D3                       - call r11
2A156FCA: 48 83 C4 20                    - add rsp,20
2A156FCE: 48 8B 7D F8                    - mov rdi,[rbp-08]
2A156FD2: C9                             - leave
2A156FD3: C3                             - ret
2A156FD4: 00 00                          - add [rax],al
2A156FD6: 00 00                          - add [rax],al
}



七、利用基址指针修改并锁定血槽值、弹夹值、总弹药值--完美版!!!

  经过仔细观察基址指针和脚本注入点的寄存器情况,发现只要更换武器,再内存中的这个位置
[[[[[[["ggc2.exe"+01449AA0]+0]+10]+28]+50]+028]+10]的内容会被程序改写。估计是将当前武器
的位置地址写入到这里了。

  在脚本注入点位置,是武器开枪后,弹夹减少子弹的指令。仔细观察寄存器,rdi的值就是
[[[[[[["ggc2.exe"+01449AA0]+0]+10]+28]+50]+028]+10]处存放的内容。因此,可以让脚本直接读取
rdi值,然后通过指针,找到当前武器总弹药的新地址。

   按照这个思路,成功完成完美版锁血量、弹夹、总弹药的脚本。20220327


{ Game   : ggc2.exe
  Version:
  Date   : 2022-03-26
  用指针锁定血量、弹夹、总弹药--完美版
}

define(hppt,[[[[[["ggc2.exe"+01449AA0]+0]+10]+28]+48]+1C0]) //血量值指针

[ENABLE]
//code from here to '[DISABLE]' will be used to enable the cheat

//  指令注入到弹夹子弹减少代码位置。
aobscan(INJECT_danjia894724,89 47 24 48 8B CF 48)    // danjia894724:
alloc(newmem_danjia894724,$1000,INJECT_danjia894724) //表示:弹夹+指令操作码

label(code)
label(return)

alloc(mydjpt,$4,INJECT_danjia894724)

newmem_danjia894724:  //在原程序中跳转后,到这里开始执行。

  mov eax,[rdi+18]       //rdi值和目前武器密切相关,换个武器,则rdi值改变。
  mov [eax+1C],#109999   //将109999写入总弹药值地址。

  mov hppt,(float)99999 //这里加血量

  mov eax,#9999         //将弹夹子弹数9999先写入eax。

code:  //注入点原始代码
  mov [rdi+24],eax   //这里eax(9999)写入弹夹地址。
  mov rcx,rdi
  jmp return //以上顺序执行到这里,在这里跳到return

INJECT_danjia894724: //以下是原始程序中的注入点!
  jmp newmem_danjia894724 //注意,这是脚本运行的第一句指令
  nop
return: //跳到return这里后,脚本结束,跳回原始程序注入点下一句。
registersymbol(INJECT_danjia894724)

[DISABLE]
//code from here till the end of the code will be used to disable the cheat
INJECT_danjia894724:
  db 89 47 24 48 8B CF

unregistersymbol(INJECT_danjia894724)
dealloc(newmem_danjia894724)

{
// ORIGINAL CODE - INJECTION POINT: 2A156FB3

2A156F9A: 00 00                          - add [rax],al
2A156F9C: 00 00                          - add [rax],al
2A156F9E: 00 00                          - add [rax],al
2A156FA0: 55                             - push rbp
2A156FA1: 48 8B EC                       - mov rbp,rsp
2A156FA4: 57                             - push rdi
2A156FA5: 48 83 EC 08                    - sub rsp,08
2A156FA9: 48 8B F9                       - mov rdi,rcx
2A156FAC: 48 89 55 F0                    - mov [rbp-10],rdx
2A156FB0: 48 8B C2                       - mov rax,rdx
// ---------- INJECTING HERE ----------
2A156FB3: 89 47 24                       - mov [rdi+24],eax
// ---------- DONE INJECTING  ----------
2A156FB6: 48 8B CF                       - mov rcx,rdi
2A156FB9: 48 83 EC 20                    - sub rsp,20
2A156FBD: 49 BB 00 70 15 2A 00 00 00 00  - mov r11,000000002A157000
2A156FC7: 41 FF D3                       - call r11
2A156FCA: 48 83 C4 20                    - add rsp,20
2A156FCE: 48 8B 7D F8                    - mov rdi,[rbp-08]
2A156FD2: C9                             - leave
2A156FD3: C3                             - ret
2A156FD4: 00 00                          - add [rax],al
2A156FD6: 00 00                          - add [rax],al
}




---------------------------------------------------------------------------

主角坐标寻找:
1、在画面中,横(左右)是x,纵(上下)是y。假设玩家向右走x增加,向左走x减少。据说在游戏程序中,一般来说,x、y(3D游戏中还有z轴)地址是连续存放的,且坐标值都是单浮点类型(单浮点数值在内存中占用4个字节,这个知识点要知道)。
   因此,先来找主角横坐标即x坐标。

2、找横坐标:
    数值类型:单浮点
    扫描类型:未知的初始值
    搜索方法:主角左走值变大,右走值变小,原地不动值不变。
    结    果:经过大约10次扫描后,剩下770个结果,之后扫描到的地址数基本不再减少了。
    分    析:将700多个结果都加到地址列表中,然后把一半锁定,回游戏看主角可否移动,不能动,就把列表中的其余一半删掉。如此这般进行1/2筛选法,直到最后剩下1个值。
    锁    定:锁定后,主角无法左右移动了。

3、找纵坐标:打开这个地址的内存查看窗口,看到这个地址前面4字节是0,后面4字节有值。将这个地址加入到地址列表,锁定试试,果然,主角在纵向不停抖动。
   因此,主角的纵坐标=横坐标地址 + 4

   再次查看ce的地址列表,发现:主角血量地址 + hex38 = x坐标

<基本完工,少许修改修订待续>






CE-枪血黑手党2ggc2-20220328.rar

7.32 KB, 下载次数: 48, 下载积分: 吾爱币 -1 CB

免费评分

参与人数 8吾爱币 +8 热心值 +8 收起 理由
执骨哟 + 1 + 1 用心讨论,共获提升!
沉默的羊羔 + 1 用心讨论,共获提升!
xiahhhr + 1 + 1 用心讨论,共获提升!
w360 + 1 + 1 我很赞同!
gunxsword + 1 + 1 热心回复!
Direp + 1 + 1 热心回复!
tanpanyi + 1 + 1 很用心了!
縈默A + 2 + 1 热心回复!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| laozhhaiJohn 发表于 2022-3-29 06:20
本帖最后由 laozhhaiJohn 于 2022-3-29 06:23 编辑
zqtzheng 发表于 2022-3-28 16:15
游戏搭配手柄使用,有些手柄无法被专门的游戏软件识别,比如说xbox,steam,这个有办法绕过检测吗

抱歉,我其实也是新手,这个专业问题实在回答不出。抱歉抱歉。

感谢各位给予的评分和热心值&#10084;&#65039;&#10084;&#65039;&#10084;&#65039;&#10084;&#65039;&#10084;&#65039;

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
zqtzheng + 1 + 1 热心回复!

查看全部评分

Leaf1742 发表于 2024-1-8 16:00
我在激活mono功能对unity游戏进行修改的时候,通过反汇编改写数值的地址可以找到函数的地址,一般来说可以通过自动汇编定位地址修改,但是我发现了两个相同名字的函数地址不一样,导致定位会从第一个函数开始定位,于是偏移,有什么办法可以写汇编让ce跳过第一个函数的地址?
wangxinglu 发表于 2022-3-27 22:23
awJYNL 发表于 2022-3-27 23:55
看不懂,帮顶一下子
LightSylcanus 发表于 2022-3-28 00:43
给他爱也是公用代码  可以试一下
lin1229 发表于 2022-3-28 07:15
好厉害啊!
southpark 发表于 2022-3-28 08:27
666感谢分享
chendageng 发表于 2022-3-28 10:21
好东西,感谢分析
sdm123 发表于 2022-3-28 13:48
支持一下
lanzhe00 发表于 2022-3-28 14:04
挺好玩的一个,推荐自己闯
zqtzheng 发表于 2022-3-28 16:15
游戏搭配手柄使用,有些手柄无法被专门的游戏软件识别,比如说xbox,steam,这个有办法绕过检测吗
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-12-22 00:34

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表