CE自动汇编之AOB注入

目录

一、什么是AOB注入?

二、什么时候使用AOB注入?

三、代码注入

四、全部注入

五、“全部注入”和“AOB注入”的分别

六、代码注入与AOB注入的区别


CE自动汇编的模板中,有三种注入代码的方式:

第一种是代码注入,就是训练教程中的步骤7所示。

一、什么是AOB注入?

AOB(Array of Bytes)是一系列唯一的字节数组,除了我们的指令能在内存中生成这些字节数组外,内存中的其它任何地方都不会再有这样的字节。这将有助于作弊者在游戏重新启动后,通过查找这些字节码,再次准确的提取那些动态地址。

二、什么时候使用AOB注入?

比如写了一个作弊器,但是游戏版本更新了,很有可能出现,涉及到作弊的那段游戏代码本身没有变化,但代码在内存中的位置却可能会变动的情况。这个时候,是不是又要重新去寻找一遍代码地址?

如果采用AOB注入的方式,则不需要再重新寻找地址了,因为它是通过代码在内存中的字节码来寻找地址。

自动汇编的界面如下,可以在“模板”中选择“AOB注入”:

我们还是拿训练教程的步骤7作为例子:

 找到修改代码后,选择“自动汇编”中的“AOB”注入:

 完整的代码如下:

[ENABLE]

aobscanmodule(INJECT,Tutorial-x86_64.exe,83 AE E0 07 00 00 01) // should be unique
alloc(newmem,$1000,INJECT)

label(code)
label(return)

newmem:

code:
  //sub dword ptr [rsi+000007E0],01
  add dword ptr [rsi+000007E0],02  // 增加2
  jmp return

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

[DISABLE]

INJECT:
  db 83 AE E0 07 00 00 01

unregistersymbol(INJECT)
dealloc(newmem)

这个代码稍微复杂了一点.

1.aobscanmodule命令

Auto Assembler aobScanModule(SymbolNameModuleNameAOBString)

Scans the memory used by the module ModuleName for a specific byte pattern defined by AOBString and sets the resulting address to the symbol SymbolName.

上面英文已经讲得比较清楚了,就是扫描AOBString这个16进制字节数组,将扫描到的数据的地址存入SymbolName。

具体来说,看程序第一行代码:

aobscanmodule(INJECT,Tutorial-x86_64.exe,83 AE E0 07 00 00 01) // should be unique

这里面的"83 AE E0 07 00 00 01"就是sub指令行在内存中的字节码,虽然是模板里面可以自动生成,但是我们也可以手动确认下,可以在“Memory Viewer”界面内找到这个字节码:

 然后,在CE主界面,搜索16进制数据,先选择“数值类型”为字节数组,才能选择扫描类型。

另外,一定不要勾选“可写”类型,要取消选择(表示不可写)或像设为“方框”,表示可不可写无所谓。

aobscanmodule命令在模块中搜索,第一个参数INJECT是搜索结果的别名,当标签使用,第二个参数是要搜索的模块,第三个参数就是要搜索的字节码。

2.alloc

alloc(newmem,$1000,INJECT)

注意,上面$1000代表16进制0x1000,转换成10进制就是4096.

3.registersymbol

Auto Assembler registerSymbol(SymbolName)

Adds a symbol to the user-defined symbol list so cheat tables and the memory browser can use that name instead of an address.

脚本命令registersymbol和unregistersymbol,前者是说将目标注册成一个全局符号,一旦注册,无论是其他脚本还是CE地址列表,都可以直接用这个注册的符号来表示这个地址,后者则表示取消注册符号。

需要注意的是在【DISABLE】部分,这里直接用了“db 83 AE E0 07 00 00 01”来还原,而非汇编指令。本质上来说,“INJECT: db 83 AE E0 07 00 00 01”代表的意思和下面的代码意思一样:

"Tutorial-x86_64.exe"+2DB57:
sub dword ptr [rsi+000007E0],01

 那为什么不用上面的汇编指令来替换呢?其实是可以这么做的,但是一般来说,用字节码更好。

要知道,同样的汇编代码,可能会因为不同的汇编器而生成不同的字节代码。平时无所谓,像这种通过AOB来定位的方式,如果我们激活脚本,然后关闭脚本,一旦在代码还原时生成了不同的字节码,则脚本就无法再次激活了。所以直接写回原来的机器码是更好的选择。实际上,任何时候这都是个更好的选择。 

最后,将sub改成add后,点击“文件”中的“分配到当前的CT表”,我们可以观察激活这段汇编脚本前后的变化情况。

激活前:

 激活后:

 

 从效果上看,“INJECT”全局符号就相当于C语言的宏,和“代码注入”中的“Tutorial-x86_64.exe+2DB57 ”是一样的,但是后面的字节码却变成了"E9 A4 24 FC FF"(这个就是"jmp FFFF0000"对应的字节码)。所以最后【DISABLE】关闭脚本时,要把地址还原成原来指令(sub dword ptr [rsi+000007E0],01)对应的字节码:

INJECT:
  db 83 AE E0 07 00 00 01

三、代码注入

代码注入,前面文章已经讲了,这里直接贴代码:

[ENABLE]
alloc(newmem,2048,"Tutorial-x86_64.exe"+2DB57) 
label(returnhere)
label(originalcode)
label(exit)
 
newmem: //this is allocated memory, you have read,write,execute access
//place your code here
jmp returnhere
 
originalcode:
//sub dword ptr [rsi+000007E0],01
add dword ptr [rsi+000007E0],02  // 增加2
 
exit:
jmp returnhere
 
"Tutorial-x86_64.exe"+2DB57:
jmp newmem
nop 2
returnhere:
 
[DISABLE]
dealloc(newmem)
"Tutorial-x86_64.exe"+2DB57:
sub dword ptr [rsi+000007E0],01

四、全部注入

“全部注入”的方式其实和AOB是差不多的,见下列代码:

define(address,"Tutorial-x86_64.exe"+2DB57)
define(bytes,83 AE E0 07 00 00 01)

[ENABLE]

assert(address,bytes)
alloc(newmem,$1000,"Tutorial-x86_64.exe"+2DB57)

label(code)
label(return)

newmem:
  add dword ptr [rsi+000007E0],2

code:
  //sub dword ptr [rsi+000007E0],01
  jmp return

address:
  jmp newmem
  nop 2
return:

[DISABLE]

address:
  db bytes
  // sub dword ptr [rsi+000007E0],01

dealloc(newmem)

 这里面多了一个assert。

Auto Assembler assert(AddressArrayOfBytes)

Will check the memory address for the given bytes. If the address's memory is not what is defined by the array of bytes given, the auto assemble script will not execute.

 assert起一个检查的作用,检查address和ArrayOfBytes是否一样,不一样就不执行后面的代码。

五、“全部注入”和“AOB注入”的分别

//全部注入

define(address,"Tutorial-x86_64.exe"+2DB57)
define(bytes,83 AE E0 07 00 00 01)

assert(address,bytes)

//AOB注入

aobscanmodule(INJECT,Tutorial-x86_64.exe,83 AE E0 07 00 00 01) // should be unique

。。。

registersymbol(INJECT)

可以看出,“全部注入”加了一句assert,就是先要判断下,address与bytes要相同,才执行后面的代码。另外,AOB注入会增加一个全局符号INJECT。

六、代码注入与AOB注入的区别

1.代码注入与AOB注入的主要区别是,寻址方式不同:

//代码注入

alloc(newmem,2048,"Tutorial-x86_64.exe"+2DB57) 

//aob注入

aobscanmodule(INJECT,Tutorial-x86_64.exe,83 AE E0 07 00 00 01) // should be unique
alloc(newmem,$1000,INJECT)

可以看出,“代码注入”直接使用"Tutorial-i386.exe"+2DB57,而AOB是通过搜索其对应的字节码来定位。这个区别很重要,因为很多时候,只能找到一个动态地址(重启游戏动态地址会变的地址),找不出基址,这个时候只能用AOB的方式注入。

但是AOB字节码并不是可以通吃,字节码是通过操作码+操作数生成的,如果出现两条一样的操作码+操作数,那么它们生成的字节码也会是一样的。如:

 上面的两条test指令内容完全一样,所以生成的字节码也是一样。这个时候采用aob注入的话,就会出现问题。

2.还原方式不一样:

//代码注入,还原代码

[DISABLE]
dealloc(newmem)
"Tutorial-x86_64.exe"+2DB57:
sub dword ptr [rsi+000007E0],01

//AOB注入,还原代码

[DISABLE]

INJECT:
  db 83 AE E0 07 00 00 01

unregistersymbol(INJECT)
dealloc(newmem)

AOB注入通过程序代码的字节码还原。

参考文章:

https://wiki.cheatengine.org/index.php?title=Auto_Assembler:Commands

  • 9
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值