Difference between revisions of "Cheat Engine:Auto Assembler"
(some linebreaks) |
1838641320 (talk | contribs) m (→General Information) |
||
(24 intermediate revisions by 10 users not shown) | |||
Line 1: | Line 1: | ||
− | + | [[Category:Assembler]] | |
+ | == Writing a Script == | ||
+ | You need to have the Memory Viewer window open and go to "Tools->Auto Assemble" or hit CTRL+A to open the Auto assemble window. When you click "Execute" the code is '''not''' actually executed, but ''assembled'' into machine code. The code is actually executed when you overwrite existing game code and the game executes it in the normal course of playing or when you call CREATETHREAD. | ||
+ | |||
+ | Writing an address or label followed by a colon will do one of two opposite things. If the label is known, i.e. it is an address or if there is a defined symbol or memory has been allocated with that name, the assembler will move to that address for assembling the following code. If the label is unknown, it must have been passed to LABEL(name) (or you will get an error) and the value of that label will be set to the current position where code is set to be assembled. | ||
+ | |||
+ | [[Auto Assembler Example 1|Simple Example]] - Example showing ALLOC, LABEL, REGISTERSYMBOL and CREATETHREAD. | ||
+ | |||
+ | |||
+ | == Assigning a Script to a CheatTable == | ||
+ | Scripts assigned to cheat tables usually have two sections, "[ENABLE]" and "[DISABLE]". Code before "[ENABLE]" will be '''''assembled''''' every time the script is enabled OR disabled. The code in the "[ENABLE]" section will be '''''assembled''''' (not executed) when the entry is checked and the code in the "[DISABLE]" section will be '''''assembled''''' when the entry is unchecked. | ||
+ | |||
+ | You will generally alloc memory in [ENABLE] and overwrite existing instructions inside the process you have opened to jump to your code where you can modify values and jump back. You will then dealloc the memory and put the original instructions back when disabling. | ||
+ | |||
+ | To assign it to your cheat table, click on "File->Assign to current cheat table" and close the window because to edit the table script you have to double-click on the "<script>" value in your table. | ||
+ | |||
+ | [[Auto Assembler Example 2|Serious Sam 3 BFE Example]] - Example showing ENABLE and DISABLE | ||
+ | |||
+ | |||
+ | == Injecting a DLL == | ||
+ | loadlibrary(name) can be used to load a dll and register it's symbols for | ||
+ | use by your assembly code. Note that you should not put quotes around the DLL name. Here's an example: | ||
+ | |||
+ | [[Auto Assembler Example 3|LoadLibrary Example]] | ||
+ | |||
+ | == General Information == | ||
Auto assemble allows you to write assembler code at different locations using a script. It can be found in the memory view part of cheat engine under extra. | Auto assemble allows you to write assembler code at different locations using a script. It can be found in the memory view part of cheat engine under extra. | ||
− | + | See [[Auto_Assembler:Commands|Auto Assembler Commands]] for a full list of all Auto Assembler commands. | |
− | + | ||
− | + | {| class="gallery" style="background-color:#f4f4f4" | |
− | ALLOC( | + | |+ Auto Assembler Commands |
− | DEALLOC( | + | ! Command !! Description |
− | FULLACCESS(address,size) | + | |- |
− | + | | [[Auto Assembler:aobScan|AOBSCAN]](name, xx xx xx xx xx) || Scans the memory for the given array of byte and sets the result to the symbol named "name" | |
− | REGISTERSYMBOL( | + | |- |
− | UNREGISTERSYMBOL( | + | | [[Auto Assembler:aobScanModule|AOBSCANMODULE]](name, moduleName, xx xx xx xx xx) || Scans the memory of a specific module for the given array of byte and sets the result to the symbol names "name" |
+ | |- | ||
+ | | [[Auto Assembler:aobScanRegion|AOBSCANREGION]](name, Sadd$, Fadd$, xx xx xx) || Will scan the specific range from start address to finish addressfor the given AOB and labels it with the given name | ||
+ | |- | ||
+ | | [[Auto Assembler:alloc|ALLOC]](allocName, sizeInBytes, Optional: AllocateNearThisAddress) || Allocates a certain amount of memory and defines the specified name in the script. If AllocateNearThisAddress is specified CE will try to allocate the memory near that address. This is useful for 64-bit targets where the jump distance could be bigger than 2GB otherwise | ||
+ | |- | ||
+ | | [[Auto Assembler:dealloc|DEALLOC]](allocName) || Deallocates a block of memory allocated with Alloc. It always gets executed last, no matter where it is positioned in the code, and only actually frees the memory when all allocations have been freed. Only usable in a script designed as a cheat table. (e.g used for the disable cheat) | ||
+ | |- | ||
+ | | [[Auto Assembler:createThread|CREATETHREAD]](address) || Will spawn a thread in the process at the specified address | ||
+ | |- | ||
+ | | [[Auto Assembler:define|DEFINE]](name,whatever) || Creates a token with the specified name that will be replaced with the text of whatever | ||
+ | |- | ||
+ | | [[Auto Assembler:fullAccess|FULLACCESS]](address,size,preferedsize) || Makes a memory region at the specified address and at least "size" bytes readable, writable and executable | ||
+ | |- | ||
+ | | [[Auto Assembler:globalAlloc|GLOBALALLOC]](name,size) || Allocates a certain amount of memory and registers the specified name. Using GlobalAlloc in other scripts will then not allocate the memory again, but reuse the already existing memory. (Or allocate it anyhow if found it wasn't allocated yet) | ||
+ | |- | ||
+ | | [[Auto Assembler:include|INCLUDE]](filename) || Includes another auto assembler file at that spot | ||
+ | |- | ||
+ | | [[Auto Assembler:label|LABEL]](labelName) || Enables the word labelName to be used as an address | ||
+ | |- | ||
+ | | [[Auto Assembler:loadBinary|LOADBINARY]](address,filename) || Loads a binary file at the specified address | ||
+ | |- | ||
+ | | [[Auto Assembler:loadLibrary|LOADLIBRARY]](filename) || Injects the specified DLL into the target process | ||
+ | |- | ||
+ | | [[Auto Assembler:readMem|READMEM]](address,size) || Writes the memory at the specified address with the specified size to the current location | ||
+ | |- | ||
+ | | [[Auto Assembler:registerSymbol|REGISTERSYMBOL]](symbolName) || Adds a symbol to the user-defined symbol list so cheat tables and the memory browser can use that name instead of a address (The symbol has to be declared in the script when using it) | ||
+ | |- | ||
+ | | [[Auto Assembler:unregisterSymbol|UNREGISTERSYMBOL]](symbolName) || Removes a symbol from the user-defined symbol list. No error will occur if the symbol doesn't exist. | ||
+ | |} | ||
+ | |||
+ | == Value Notation == | ||
+ | Normally everything is written as hexadecimal in auto assembler, but there are ways to override this so you can input decimal values, and even floating point values. | ||
+ | for example, a integer value of 100 can be written in hex as 64, but you can also write it as #100, or as (int)100 | ||
+ | for floating point value like 100.1 you can use (float)100.1 | ||
+ | and for a double, you could use (double)100.1 | ||
+ | NOTE:Use 'dq (double)100.1' instead of 'dd'! | ||
+ | |||
+ | === {$lua} === | ||
+ | Auto assembler scripts support section written in Lua.You can start such a section using the [[Auto Assembler:LUA ASM|{$lua}]] keyword, and end it with [[Auto Assembler:LUA ASM|{$asm}]]. | ||
+ | |||
+ | The return value of such a function (if it returns a value at all) will be interpreted as normal auto assembler commands. | ||
+ | |||
+ | When syntax checking, the lua sections get executed. To make sure your lua script behaves properly in those situations, check the "syntaxcheck" boolean. If it's true, then do not make permanent changes. | ||
+ | e.g: | ||
+ | <pre> | ||
+ | if syntaxcheck then return end | ||
+ | </pre> | ||
+ | Of course, if your script is meant to generate code, do make it return code so that it passes the initial syntax check. (e.g label definitions etc...) | ||
+ | |||
+ | == Examples == | ||
+ | |||
+ | === Basic Example === | ||
+ | <pre> | ||
+ | 00451029: | ||
+ | jmp 00410000 | ||
+ | nop | ||
+ | nop | ||
+ | nop | ||
+ | |||
+ | 00410000: | ||
+ | mov [00580120],esi | ||
+ | mov [esi+80],ebx | ||
+ | xor eax,eax | ||
+ | jmp 00451031 | ||
+ | </pre> | ||
+ | |||
+ | |||
+ | === Example using LABEL === | ||
+ | <pre> | ||
+ | label(mylabel) | ||
+ | |||
+ | 00451029: | ||
+ | jmp 00410000 | ||
+ | nop | ||
+ | nop | ||
+ | nop | ||
+ | mylabel: | ||
+ | |||
+ | 00410000: | ||
+ | mov [00580120],esi | ||
+ | mov [esi+80],ebx | ||
+ | xor eax,eax | ||
+ | jmp mylabel | ||
+ | </pre> | ||
+ | |||
+ | |||
+ | === Example using ALLOC === | ||
+ | <pre> | ||
+ | alloc(alloc1,4) | ||
+ | |||
+ | 00451029: | ||
+ | jmp 00410000 | ||
+ | nop | ||
+ | nop | ||
+ | nop | ||
+ | |||
+ | 00410000: | ||
+ | mov [alloc1],esi | ||
+ | mov [esi+80],ebx | ||
+ | xor eax,eax | ||
+ | jmp 00451031 | ||
+ | </pre> | ||
+ | |||
+ | === Example using ALLOC and LABEL === | ||
+ | <pre> | ||
+ | alloc(alloc1,4) | ||
+ | label(mylabel) | ||
+ | |||
+ | 00451029: | ||
+ | jmp 00410000 | ||
+ | nop | ||
+ | nop | ||
+ | nop | ||
+ | mylabel: | ||
+ | 00410000: | ||
+ | mov [alloc1],esi | ||
+ | mov [esi+80],ebx | ||
+ | xor eax,eax | ||
+ | jmp mylabel | ||
+ | </pre> | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
+ | === Example using FULLACCESS === | ||
+ | <pre> | ||
+ | FULLACCESS(00400800,4) //00400800 is usually read only non executable data, this makes it writeable and executable | ||
+ | 00451029: | ||
+ | jmp 00410000 | ||
+ | nop | ||
+ | nop | ||
+ | nop | ||
− | + | 00410000: | |
+ | mov [00400800],esi | ||
+ | mov [esi+80],ebx | ||
+ | xor eax,eax | ||
+ | jmp 00451031 | ||
+ | </pre> | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
+ | === Example using DEFINE === | ||
+ | <pre> | ||
+ | DEFINE(clear_eax,xor eax,eax) | ||
+ | 00400500: | ||
+ | clear_eax | ||
+ | </pre> | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | === Example using READMEM === | |
− | + | <pre> | |
− | + | alloc(x,16) | |
− | + | alloc(script,2048) | |
− | |||
− | + | script: | |
− | + | mov eax,[x] | |
− | + | mov edx,[x+c] | |
− | + | ret | |
− | + | x: | |
− | + | readmem(00410000,16) //place the contents of address 00410000 at the address of X | |
− | + | </pre> | |
− | |||
− | |||
− | |||
− | |||
− | + | == See also == | |
− | + | * [[Assembler]] | |
+ | * [[Tutorials]] |
Latest revision as of 06:11, 20 June 2019
Contents
Writing a Script[edit]
You need to have the Memory Viewer window open and go to "Tools->Auto Assemble" or hit CTRL+A to open the Auto assemble window. When you click "Execute" the code is not actually executed, but assembled into machine code. The code is actually executed when you overwrite existing game code and the game executes it in the normal course of playing or when you call CREATETHREAD.
Writing an address or label followed by a colon will do one of two opposite things. If the label is known, i.e. it is an address or if there is a defined symbol or memory has been allocated with that name, the assembler will move to that address for assembling the following code. If the label is unknown, it must have been passed to LABEL(name) (or you will get an error) and the value of that label will be set to the current position where code is set to be assembled.
Simple Example - Example showing ALLOC, LABEL, REGISTERSYMBOL and CREATETHREAD.
Assigning a Script to a CheatTable[edit]
Scripts assigned to cheat tables usually have two sections, "[ENABLE]" and "[DISABLE]". Code before "[ENABLE]" will be assembled every time the script is enabled OR disabled. The code in the "[ENABLE]" section will be assembled (not executed) when the entry is checked and the code in the "[DISABLE]" section will be assembled when the entry is unchecked.
You will generally alloc memory in [ENABLE] and overwrite existing instructions inside the process you have opened to jump to your code where you can modify values and jump back. You will then dealloc the memory and put the original instructions back when disabling.
To assign it to your cheat table, click on "File->Assign to current cheat table" and close the window because to edit the table script you have to double-click on the "<script>" value in your table.
Serious Sam 3 BFE Example - Example showing ENABLE and DISABLE
Injecting a DLL[edit]
loadlibrary(name) can be used to load a dll and register it's symbols for use by your assembly code. Note that you should not put quotes around the DLL name. Here's an example:
General Information[edit]
Auto assemble allows you to write assembler code at different locations using a script. It can be found in the memory view part of cheat engine under extra.
See Auto Assembler Commands for a full list of all Auto Assembler commands.
Command | Description |
---|---|
AOBSCAN(name, xx xx xx xx xx) | Scans the memory for the given array of byte and sets the result to the symbol named "name" |
AOBSCANMODULE(name, moduleName, xx xx xx xx xx) | Scans the memory of a specific module for the given array of byte and sets the result to the symbol names "name" |
AOBSCANREGION(name, Sadd$, Fadd$, xx xx xx) | Will scan the specific range from start address to finish addressfor the given AOB and labels it with the given name |
ALLOC(allocName, sizeInBytes, Optional: AllocateNearThisAddress) | Allocates a certain amount of memory and defines the specified name in the script. If AllocateNearThisAddress is specified CE will try to allocate the memory near that address. This is useful for 64-bit targets where the jump distance could be bigger than 2GB otherwise |
DEALLOC(allocName) | Deallocates a block of memory allocated with Alloc. It always gets executed last, no matter where it is positioned in the code, and only actually frees the memory when all allocations have been freed. Only usable in a script designed as a cheat table. (e.g used for the disable cheat) |
CREATETHREAD(address) | Will spawn a thread in the process at the specified address |
DEFINE(name,whatever) | Creates a token with the specified name that will be replaced with the text of whatever |
FULLACCESS(address,size,preferedsize) | Makes a memory region at the specified address and at least "size" bytes readable, writable and executable |
GLOBALALLOC(name,size) | Allocates a certain amount of memory and registers the specified name. Using GlobalAlloc in other scripts will then not allocate the memory again, but reuse the already existing memory. (Or allocate it anyhow if found it wasn't allocated yet) |
INCLUDE(filename) | Includes another auto assembler file at that spot |
LABEL(labelName) | Enables the word labelName to be used as an address |
LOADBINARY(address,filename) | Loads a binary file at the specified address |
LOADLIBRARY(filename) | Injects the specified DLL into the target process |
READMEM(address,size) | Writes the memory at the specified address with the specified size to the current location |
REGISTERSYMBOL(symbolName) | Adds a symbol to the user-defined symbol list so cheat tables and the memory browser can use that name instead of a address (The symbol has to be declared in the script when using it) |
UNREGISTERSYMBOL(symbolName) | Removes a symbol from the user-defined symbol list. No error will occur if the symbol doesn't exist. |
Value Notation[edit]
Normally everything is written as hexadecimal in auto assembler, but there are ways to override this so you can input decimal values, and even floating point values. for example, a integer value of 100 can be written in hex as 64, but you can also write it as #100, or as (int)100 for floating point value like 100.1 you can use (float)100.1 and for a double, you could use (double)100.1 NOTE:Use 'dq (double)100.1' instead of 'dd'!
{$lua}[edit]
Auto assembler scripts support section written in Lua.You can start such a section using the {$lua} keyword, and end it with {$asm}.
The return value of such a function (if it returns a value at all) will be interpreted as normal auto assembler commands.
When syntax checking, the lua sections get executed. To make sure your lua script behaves properly in those situations, check the "syntaxcheck" boolean. If it's true, then do not make permanent changes. e.g:
if syntaxcheck then return end
Of course, if your script is meant to generate code, do make it return code so that it passes the initial syntax check. (e.g label definitions etc...)
Examples[edit]
Basic Example[edit]
00451029: jmp 00410000 nop nop nop 00410000: mov [00580120],esi mov [esi+80],ebx xor eax,eax jmp 00451031
Example using LABEL[edit]
label(mylabel) 00451029: jmp 00410000 nop nop nop mylabel: 00410000: mov [00580120],esi mov [esi+80],ebx xor eax,eax jmp mylabel
Example using ALLOC[edit]
alloc(alloc1,4) 00451029: jmp 00410000 nop nop nop 00410000: mov [alloc1],esi mov [esi+80],ebx xor eax,eax jmp 00451031
Example using ALLOC and LABEL[edit]
alloc(alloc1,4) label(mylabel) 00451029: jmp 00410000 nop nop nop mylabel: 00410000: mov [alloc1],esi mov [esi+80],ebx xor eax,eax jmp mylabel
Example using FULLACCESS[edit]
FULLACCESS(00400800,4) //00400800 is usually read only non executable data, this makes it writeable and executable 00451029: jmp 00410000 nop nop nop 00410000: mov [00400800],esi mov [esi+80],ebx xor eax,eax jmp 00451031
Example using DEFINE[edit]
DEFINE(clear_eax,xor eax,eax) 00400500: clear_eax
Example using READMEM[edit]
alloc(x,16) alloc(script,2048) script: mov eax,[x] mov edx,[x+c] ret x: readmem(00410000,16) //place the contents of address 00410000 at the address of X