AdjWang / RA2YurisRevengeTrainer

红色警戒2 尤里的复仇v1.001 内存修改器
76 stars 8 forks source link

【信标】辅助:联网对战的时候只能下最多三个信标,当超过三个时需要把多余的删除掉才能下信标,是否可以提供辅助自动删除老信标? #19

Open bigsinger opened 8 months ago

bigsinger commented 8 months ago

实现思路:

当玩家下信标时候,维护一个信标数组,当超过3个时,自动移除较早下的信标(先进先出),这样表现的效果上看,就是可以一直下信标,相当于辅助自动把超过3个的信标删除了。

该辅助功能不是变态外挂,仅仅是把删除信标的繁琐操作给简化了,我认为这种辅助还是比较实用的,也不影响游戏的平衡性。 请作者考虑。

AdjWang commented 8 months ago

功能不错,值得考虑。只是现在联网的游戏客户端用的都是 Ares 的版本,在 Ares 版本上再做平行的修改容易出问题(issue #13 #15 #16 ),最好是能直接集成到 Ares 里。不知道 Ares 和国内的平台愿不愿意做……

bigsinger commented 8 months ago

功能不错,值得考虑。只是现在联网的游戏客户端用的都是 Ares 的版本,在 Ares 版本上再做平行的修改容易出问题(issue #13 #15 #16 ),最好是能直接集成到 Ares 里。不知道 Ares 和国内的平台愿不愿意做……

我们平时玩的是红警战网的版本:https://www.ra2ol.com/ 我简单分析过,这个版本跟你代码分析的版本是一致的,很多地址和代码仍然有效。

我不知道你说的Ares是什么版本 有网站吗 @AdjWang

AdjWang commented 8 months ago

不知道战网具体的方案,不过应该是类似这些:

Syringe 是注入器,YRpp 是逆向出来的支持库,Phobos 是国内爱好者在 YRpp 基础上二次开发的支持库。我也没具体研究过 Ares 改了什么,只是之前有一堆莫名其妙的 issue 从 Ares 版本报出来,感觉跟进的话是个大麻烦……

bigsinger commented 8 months ago
  • Ares-YRpp

Ares-YRpp 这个里面能搜到beacon(信标)相关的, 在GeneralDefinitions.h 文件里:


enum class Action : unsigned int {
    None = 0,
    ……
    PlaceBeacon = 60,
    SelectBeacon = 61,
    ……
};

有一个思路是:

  1. 下信标的时候,自动拦截下来,记录信标对象到一个临时数组;需要知道信标对象是怎样的;
  2. 并判断数组是否>=3个,超过则删除最早的一个;需要知道如何删除信标;
  3. 这种使用注入模式比较方便实现一些 也算是 https://github.com/AdjWang/RA2YurisRevengeTrainer/issues/19 的一个佐证。
shengsixiangxu commented 7 months ago

联网注入应该会被检测吧,国内联机平台使用gamemd的是CnCNet的gamemd-spawn比CnCNet的低很多版本,使用ares大部分是为了做特殊效果,之前看到个平台好像在宣传Phobos的功能?把Phobos也弄到平台了?很久没联机过了

Phobos是海外一群程序猿不满Ares功能不足闭源无法编辑而建立的新项目,主要作为Ares的补充,与Ares是一样的结构和原理,现在逐渐发展下有了自己独有的扩展逻辑。

Ares0.6从0.6不再开源,现在3.0,它好像自带调试器,导致OD没法附加,所以比较难弄。。。

AdjWang commented 7 months ago

今天看了下,实现这个功能需要做3处改动。CE脚本写出来了,但是正如@shengsixiangxu所说,对代码段的直接修改会被反作弊检测到,所以现在还是不能直接用于联网版本。我测试的时候是在加载地图的时候用CE强行把游戏消息循环改到单机分支上,这样游戏会用联网模式处理信标事件,而且不检测玩家是否掉线。

因为暂时不能直接用于联网模式,就先把脚本贴这,暂时不集成到修改器功能里。

  1. 接收键盘事件的时候需要跳过信标数量检测

    [ENABLE]
    //code from here to '[DISABLE]' will be used to enable the cheat
    alloc(newmem,2048)
    label(returnhere)
    label(originalcode)
    label(exit)
    
    newmem: //this is allocated memory, you have read,write,execute access
    jmp 004AC9B8
    
    originalcode:
    mov eax,[00A83D4C]
    
    exit:
    jmp returnhere
    
    "gamemd-spawn.exe"+AC99F:
    jmp newmem
    returnhere:
    
    [DISABLE]
    //code from here till the end of the code will be used to disable the cheat
    dealloc(newmem)
    "gamemd-spawn.exe"+AC99F:
    mov eax,[00A83D4C]
    //Alt: db A1 4C 3D A8 00
  2. 放置信标函数起始位置需要跳过信标数量检测

    [ENABLE]
    //code from here to '[DISABLE]' will be used to enable the cheat
    alloc(newmem,2048)
    label(returnhere)
    label(originalcode)
    label(exit)
    
    newmem: //this is allocated memory, you have read,write,execute access
    jmp 00430BE2
    
    originalcode:
    cmp dword ptr [eax],00
    je 00430BE2
    
    exit:
    jmp returnhere
    
    "gamemd-spawn.exe"+30BC6:
    jmp newmem
    returnhere:
    
    [DISABLE]
    //code from here till the end of the code will be used to disable the cheat
    dealloc(newmem)
    "gamemd-spawn.exe"+30BC6:
    cmp dword ptr [eax],00
    je 00430BE2
    //Alt: db 83 38 00 74 17
  3. 放置信标函数里存储信标对象之前检测到信标数量到达上限后,覆盖原来的跳出函数的逻辑,处理信标队列的前移

    [ENABLE]
    //code from here to '[DISABLE]' will be used to enable the cheat
    alloc(newmem,2048)
    label(returnhere)
    label(originalcode)
    label(exit)
    
    newmem: //this is allocated memory, you have read,write,execute access
    // output:
    // eax: beacon_idx
    // input:
    // ebx: player_idx
    // ebp: beacons_list
    // beacons_list: 89C3B0
    pushad
    // remove beacon at index 0
    mov eax, 0
    push eax
    push ebx
    mov ecx, 89C3B0
    call 4311C0
    // move rest beacons forward 1->0 2->1
    lea edx, [ebx*2+1]
    add edx, ebx          // beacon index 1
    mov eax, [ebp+edx*4]  // beacon object at index 1
    lea edx, [ebx*2+0]
    add edx, ebx          // beacon index 0
    mov [ebp+edx*4], eax  // move beacon at index 1 to index 0
    
    lea edx, [ebx*2+2]
    add edx, ebx          // beacon index 2
    mov eax, [ebp+edx*4]  // beacon object at index 2
    lea edx, [ebx*2+1]
    add edx, ebx          // beacon index 1
    mov [ebp+edx*4], eax  // move beacon at index 2 to index 1
    popad
    // place the new beacon at index 2
    mov eax, 2
    jmp 00430C64
    
    originalcode:
    push esi
    call 007C8B3D
    
    exit:
    jmp returnhere
    
    "gamemd-spawn.exe"+30C4E:
    jmp newmem
    nop
    returnhere:
    
    [DISABLE]
    //code from here till the end of the code will be used to disable the cheat
    dealloc(newmem)
    "gamemd-spawn.exe"+30C4E:
    push esi
    call 007C8B3D
    //Alt: db 56 E8 E9 7E 39 00

    (必须吐槽下红警2的代码,真的垃圾,信标数量硬编码进程序里的,估计是个宏……)

后续怎么办我也不知道,给Phobos提需求?但是对战平台不一定能立刻集成进去。或者直接跟对战平台沟通?我倒是能联系到兰博电竞的团队。

bigsinger commented 7 months ago

联网注入应该会被检测吧,国内联机平台使用gamemd的是CnCNet的gamemd-spawn比CnCNet的低很多版本,使用ares大部分是为了做特殊效果,之前看到个平台好像在宣传Phobos的功能?把Phobos也弄到平台了?很久没联机过了

Phobos是海外一群程序猿不满Ares功能不足闭源无法编辑而建立的新项目,主要作为Ares的补充,与Ares是一样的结构和原理,现在逐渐发展下有了自己独有的扩展逻辑。

Ares0.6从0.6不再开源,现在3.0,它好像自带调试器,导致OD没法附加,所以比较难弄。。。

可以分析对战平台的版本:https://www.ra2ol.com/ 没有反调试。

bigsinger commented 7 months ago

今天看了下,实现这个功能需要做3处改动。CE脚本写出来了,但是正如@shengsixiangxu所说,对代码段的直接修改会被反作弊检测到,所以现在还是不能直接用于联网版本。我测试的时候是在加载地图的时候用CE强行把游戏消息循环改到单机分支上,这样游戏会用联网模式处理信标事件,而且不检测玩家是否掉线。

因为暂时不能直接用于联网模式,就先把脚本贴这,暂时不集成到修改器功能里。

  1. 接收键盘事件的时候需要跳过信标数量检测

    [ENABLE]
    //code from here to '[DISABLE]' will be used to enable the cheat
    alloc(newmem,2048)
    label(returnhere)
    label(originalcode)
    label(exit)
    
    newmem: //this is allocated memory, you have read,write,execute access
    jmp 004AC9B8
    
    originalcode:
    mov eax,[00A83D4C]
    
    exit:
    jmp returnhere
    
    "gamemd-spawn.exe"+AC99F:
    jmp newmem
    returnhere:
    
    [DISABLE]
    //code from here till the end of the code will be used to disable the cheat
    dealloc(newmem)
    "gamemd-spawn.exe"+AC99F:
    mov eax,[00A83D4C]
    //Alt: db A1 4C 3D A8 00
  2. 放置信标函数起始位置需要跳过信标数量检测

    [ENABLE]
    //code from here to '[DISABLE]' will be used to enable the cheat
    alloc(newmem,2048)
    label(returnhere)
    label(originalcode)
    label(exit)
    
    newmem: //this is allocated memory, you have read,write,execute access
    jmp 00430BE2
    
    originalcode:
    cmp dword ptr [eax],00
    je 00430BE2
    
    exit:
    jmp returnhere
    
    "gamemd-spawn.exe"+30BC6:
    jmp newmem
    returnhere:
    
    [DISABLE]
    //code from here till the end of the code will be used to disable the cheat
    dealloc(newmem)
    "gamemd-spawn.exe"+30BC6:
    cmp dword ptr [eax],00
    je 00430BE2
    //Alt: db 83 38 00 74 17
  3. 放置信标函数里存储信标对象之前检测到信标数量到达上限后,覆盖原来的跳出函数的逻辑,处理信标队列的前移

    [ENABLE]
    //code from here to '[DISABLE]' will be used to enable the cheat
    alloc(newmem,2048)
    label(returnhere)
    label(originalcode)
    label(exit)
    
    newmem: //this is allocated memory, you have read,write,execute access
    // output:
    // eax: beacon_idx
    // input:
    // ebx: player_idx
    // ebp: beacons_list
    // beacons_list: 89C3B0
    pushad
    // remove beacon at index 0
    mov eax, 0
    push eax
    push ebx
    mov ecx, 89C3B0
    call 4311C0
    // move rest beacons forward 1->0 2->1
    lea edx, [ebx*2+1]
    add edx, ebx          // beacon index 1
    mov eax, [ebp+edx*4]  // beacon object at index 1
    lea edx, [ebx*2+0]
    add edx, ebx          // beacon index 0
    mov [ebp+edx*4], eax  // move beacon at index 1 to index 0
    
    lea edx, [ebx*2+2]
    add edx, ebx          // beacon index 2
    mov eax, [ebp+edx*4]  // beacon object at index 2
    lea edx, [ebx*2+1]
    add edx, ebx          // beacon index 1
    mov [ebp+edx*4], eax  // move beacon at index 2 to index 1
    popad
    // place the new beacon at index 2
    mov eax, 2
    jmp 00430C64
    
    originalcode:
    push esi
    call 007C8B3D
    
    exit:
    jmp returnhere
    
    "gamemd-spawn.exe"+30C4E:
    jmp newmem
    nop
    returnhere:
    
    [DISABLE]
    //code from here till the end of the code will be used to disable the cheat
    dealloc(newmem)
    "gamemd-spawn.exe"+30C4E:
    push esi
    call 007C8B3D
    //Alt: db 56 E8 E9 7E 39 00

(必须吐槽下红警2的代码,真的垃圾,信标数量硬编码进程序里的,估计是个宏……)

后续怎么办我也不知道,给Phobos提需求?但是对战平台不一定能立刻集成进去。或者直接跟对战平台沟通?我倒是能联系到兰博电竞的团队。

牛!赞一个!我用的是 https://www.ra2ol.com/ 对战平台,应该可以添加。当然如果对战平台那边能沟通达成是最好的,信标这个确实不方便。如果兰博的平台可以加进去,那就很方便了,竞争优势也能提升上来。

bigsinger commented 7 months ago

@AdjWang @shengsixiangxu 想到一个可以规避作弊检测的方法: 1、新注入一个dll模块,代码放在这个模块里; 2、该模块通过寻址手段,获取到存储信标的地址,并能知道当前一共多少信标了; 3、该模块起个定时器,每一秒检测信标数量,>=3个时就自动调用调用删除信标的函数,删除最老的信标腾坑;

这几个操作对原始代码均没有覆写修改,顶多是读取。而注入模块的定时器功能这个很好实现的。

bigsinger commented 4 months ago

@AdjWang @shengsixiangxu 想到一个可以规避作弊检测的方法: 1、新注入一个dll模块,代码放在这个里; 2、该模块通过定位手段,获取到存储信标的地址,并能知道当前总共有多少信模块标了; 3、该模块起个定时器,每一秒检测信标数量,>=3个时就自动调用删除信标的函数,删除最老的信标腾坑; 这个操作对原始代码均没有覆写修改,顶多是几个读取。而注入模块的定时器功能这个很好实现的。

研究了下是怎么检测的,反作弊在游戏本体进行检测,对战平台没有额外检测。应该是CRC检测,试了试,没啥思路。看到个有意思的帖子顺便把调试功能移植过来了YRDbgOut.DLL

这个帖子思路很有意思,相当于重新恢复原始的调试日志,靠打印日志来去分析摸排。

shengsixiangxu commented 3 months ago

实现联机信标,因为涉及过反作弊,所以没法开源。信标数量有个cmp,其实可以无限放,但因为有些bug,超过的信标有的不能删除,所以我在这里限制了20个

AdjWang commented 3 months ago

实现联机信标,因为涉及过反作弊,所以没法开源。信标数量有个cmp,其实可以无限放,但因为有些bug,超过的信标有的不能删除,所以我在这里限制了20个

能分享下除反作弊以外的实现思路吗?

bigsinger commented 3 months ago

实现联机信标,因为涉及过反作弊,所以没法开源。信标数量有个cmp,其实可以无限放,但因为有些bug,超过的信标有的不能删除,所以我在这里限制了20个

过反作弊的可以不开源,其他的可以? 另外无限放体验不太好,最好能删除老的。 @shengsixiangxu

shengsixiangxu commented 3 months ago

"gamemd-spawn.exe"+30C4E:

这个往前看会找到 inc eax add ecx, 4 cmp eax, 3//信标数量 jl short 430C40