Page 1 of 1

Tips you may not know.

Posted: Mon Oct 05, 2020 4:58 pm
by Dread_Pony_Roberts
This isn't meant to be a "your first table" tutorial, but it is instead a collection of methods that I have picked up over time. I will try to explain them as best as I can, but if you don't understand them then it is likely you still have more to learn.



How to update proof static address
Let's say your game has your health on a static address. Good, no need for pointers. The bad news is that the game keeps getting updates, and each update changes the static address location. What do you do?

If your address is ever read by code similar to this, even once, then you are in luck.

Code: Select all

8B 0D 58129500        - mov ecx,[LEGOStarWarsSaga.exe+551258]
The address is right there in the bytes (58129500), all you need to do is read it.
Since you're just reading the bytes and not manipulating them, your script will be very simple.

Code: Select all

[ENABLE]
aobscanmodule(Minikit_Reader,LEGOStarWarsSaga.exe,50 ?? ?? ?? ?? ?? ?? ?? ?? 51 83 EC 08 D9 5C 24 04)
alloc(minikit_base,4)
registersymbol(minikit_base)

minikit_base:
readmem(Minikit_Reader+5,4)

[DISABLE]
unregistersymbol(Minikit_Reader)
dealloc(minikit_base)
unregistersymbol(minikit_base)
readmem is the main function of the script. The +5 tells the readmem to read the bytes 5 bytes ahead of the aobscan, and the ,4 tells it to read the next 4 bytes. minikit_base will be the base pointer address that would be used in this table.
If done right the static address would work even if the game gets updated.



Easy player compare
Let's say your health and the enemy's health is being written to by the same address. Most methods I've seen involve going through the player and enemy structures to find one difference between them. While it is a useful method to know and can work if all else fails, there is an easier method which I believe is best to try first.

I've found that the player base is often addressed by an address which only addresses that one address (what a tongue twister). Basically, if you can find a code which only accesses the player base, and nothing else, then you have an easy compare.
If there's nothing which only addresses the player base, then it is still likely that something only addresses one of the offsets of the player base. Then you could still find the player base using that.

The script should look something like this.

Code: Select all

aobscanmodule(Player_Base_Reader,halo3.dll,41 0F B7 4D 00 48 8D) // should be unique
alloc(newmem1,$100,"halo3.dll"+38B347)
alloc(p_base,8)
registersymbol(p_base)

label(code1)
label(return1)

newmem1:
  mov [p_base],r13
code1:
  movzx ecx,word ptr [r13+00]
  jmp return1

Player_Base_Reader:
  jmp newmem1
return1:
registersymbol(Player_Base_Reader)
All this script does is moves the player base (which is always in r13) into [p_base].

A later script could be

Code: Select all

cmp [p_base],rbx
jne code
This would only allow the player address to go through, filtering out all other bases.



Advanced Methods
The following methods are for more advanced users, and as such I won't put as much time into trying to explain their finer details.
(basically this is my way of saying that I'm too lazy to explain everything in full detail)



Manipulator
Sometimes you just a general work script. This is a script which is always active and can be used to write max health to the player, save coordinates for teleportation, and whatever else you need.
This can be accomplished by using a lua timer, or making a new thread. But to keep it simple and in assembly, I just make a script from some code that is always active.

For safety sake, I like to push all the registers to keep everything I'm doing contained.

If you do something like

Code: Select all

mov rax,[p_base]
be sure to add a compare to prevent it from being used when that base hasn't been read yet, else the game will crash.

Code: Select all

cmp [p_base],0
je code


Teleportation

Code: Select all

coordinate_save:
cmp byte ptr [save+0],1
jne @f
mov byte ptr [saved+0],1
mov byte ptr [save+0],0
mov eax,[r9+70]
mov [coordinates+0],eax
mov eax,[r9+74]
mov [coordinates+4],eax
mov eax,[r9+78]
mov [coordinates+8],eax
@@:
cmp byte ptr [save+1],1
jne @f
mov byte ptr [saved+1],1
mov byte ptr [save+1],0
mov eax,[r9+70]
mov [coordinates+C],eax
mov eax,[r9+74]
mov [coordinates+10],eax
mov eax,[r9+78]
mov [coordinates+14],eax
@@:
cmp byte ptr [save+2],1
jne @f
mov byte ptr [saved+2],1
mov byte ptr [save+2],0
mov eax,[r9+70]
mov [coordinates+18],eax
mov eax,[r9+74]
mov [coordinates+1C],eax
mov eax,[r9+78]
mov [coordinates+20],eax
@@:

teleportation:
cmp byte ptr [teleport+0],1
jne @f
cmp byte ptr [saved+0],1
jne @f
mov byte ptr [teleport+0],0
mov eax,[coordinates+0]
mov [r9+70],eax
mov eax,[coordinates+4]
mov [r9+74],eax
mov eax,[coordinates+8]
mov [r9+78],eax
@@:
cmp byte ptr [teleport+1],1
jne @f
cmp byte ptr [saved+1],1
jne @f
mov byte ptr [teleport+1],0
mov eax,[coordinates+C]
mov [r9+70],eax
mov eax,[coordinates+10]
mov [r9+74],eax
mov eax,[coordinates+14]
mov [r9+78],eax
@@:
cmp byte ptr [teleport+2],1
jne @f
cmp byte ptr [saved+2],1
jne @f
mov byte ptr [teleport+2],0
mov eax,[coordinates+18]
mov [r9+70],eax
mov eax,[coordinates+1C]
mov [r9+74],eax
mov eax,[coordinates+20]
mov [r9+78],eax
@@:
This is a teleportation script of mine. save is the flag that tells the script that I wish to save my coordinates. saved is the flag that prevents the teleportation from working if no coordinates have been saved (to prevent you from accidentally teleporting to 0,0,0). teleport is the flag that tells the script that I wish to teleport. coordinates are the saved coordinates. Lastly, the teleport and save flags are internally disabled, this is to ensure that the scripts are only used once until the flag is reset.



How to make a script disable from table view
Basically, this will make the checkmark go away as soon as the script is enabled. This is useful for teleportation since you'd want it to reset as soon as you pressed the button.

Code: Select all

[Enable]
{$lua}
memrec.OnActivate = function(memrec, preState, curState)
  if (not preState) and curState then
    local t = createTimer()
    t.Interval = 100
    t.OnTimer = function(t)
      t.destroy() -- destroy timer so it doesn't run again
      memrec.Active = false -- disable this script
    end
  end
  return true -- don't interrupt, not sure how it'd be handled...
end
{$asm}

save+0:
db 1

[Disable]


On Hotkey Press
Some scripts you want to only run while a specific hotkey is pressed. It is easier to do it in lua, but it is still very possible in assembly.

Code: Select all

  push RAX
  push RCX
  push RDX
  push R8
  push R9
  push R10
  push R11
  sub rsp,28
  mov rcx,[bind]
  call GetAsyncKeyState
  add rsp,28
  pop r11
  pop r10
  pop r9
  pop r8
  pop rdx
  pop rcx
  test ax,8001
  pop rax
  jz @f
  (your code you wish to use here)
  @@:
The most important part of this code is the bind that is being moved to rcx. You can set it directly in the script, but I prefer to make it easily customizable for the user. To make it customizable, you will want to alloc 4 bytes and registersymbol the bind. Then in the script that enables this one is where the user can set their bind.

Code: Select all

bind:
db A0
The byte corresponds to a virtual key code. A list of them can be found here.
[Link]

20=Spacebar
A0=Left Shift key
26=Up Arrow Key
49=I Key
A2=Left Control Key
A4=Left Alt Key (It is also called the Left Menu Key in the website)
ect...



Flight
Flight is one of my most complicated scripts but I'll try to explain some of the basics.

First you will need to find and set the ground flag to whatever registers the player as on the ground, or else you will be flying but have little control (halo will even have you die because you've been "falling" for too long. You will also need to prevent anything else from writing to your z direction, or else you will slowly fall as this script tries to counter the game's code.

Code: Select all

  cmp byte ptr [flight_smoother],1
  je Flight_Up
  cmp byte ptr [flight_smoother],2
  je Flight_Down

Flight_Up:
  push RAX
  push RCX
  push RDX
  push R8
  push R9
  push R10
  push R11
  sub rsp,28
  mov rcx,[up_bind]
  call GetAsyncKeyState
  add rsp,28
  pop r11
  pop r10
  pop r9
  pop r8
  pop rdx
  pop rcx
  test ax,8001
  pop rax
  jz @f
  fld [r9+F8]
  fadd [flight_speed]
  fstp [r9+F8]
  mov byte ptr [flight_smoother],1
  jmp flight_end
@@:
  mov byte ptr [flight_smoother],0

Flight_Down:
  push RAX
  push RCX
  push RDX
  push R8
  push R9
  push R10
  push R11
  sub rsp,28
  mov rcx,[down_bind]
  call GetAsyncKeyState
  add rsp,28
  pop r11
  pop r10
  pop r9
  pop r8
  pop rdx
  pop rcx
  test ax,8001
  pop rax
  jz @f
  fld [r9+F8]
  fsub [flight_speed]
  fstp [r9+F8]
  mov byte ptr [flight_smoother],2
  jmp flight_end
@@:
  mov byte ptr [flight_smoother],0

flight_end:
I try to keep the movement speed customizable using the same method as for the bind, this way the user can increase the speed easily.
flight_smoother is very important, it prevents one movement direction from having priority over the other. If this is removed, the up direction would always take priority over the down direction.



Built in Cheat Engine scripts
Here's some scripts to enable built in Cheat Engine features.

Compact Mode

Code: Select all

[ENABLE]
LuaCall(function cycleFullCompact(sender,force) local state = not(compactmenuitem.Caption == 'Compact View Mode'); if force~=nil then state = not force end; compactmenuitem.Caption = state and 'Compact View Mode' or 'Full View Mode'; getMainForm().Splitter1.Visible = state; getMainForm().Panel4.Visible    = state; getMainForm().Panel5.Visible    = state; end; function addCompactMenu() if compactmenualreadyexists then return end; local parent = getMainForm().Menu.Items; compactmenuitem = createMenuItem(parent); parent.add(compactmenuitem); compactmenuitem.Caption = 'Compact View Mode'; compactmenuitem.OnClick = cycleFullCompact; compactmenualreadyexists = 'yes'; end; addCompactMenu(); cycleFullCompact(nil,true))

[DISABLE]
LuaCall(cycleFullCompact(nil,false))
Speedhack

Code: Select all

[Enable]
{$lua}
memrec.OnActivate = function(memrec, preState, curState)
  if (not preState) and curState then
    local t = createTimer()
    t.Interval = 100
    t.OnTimer = function(t)
      t.destroy() -- destroy timer so it doesn't run again
      memrec.Active = false -- disable this script
    end
  end
  return true -- don't interrupt, not sure how it'd be handled...
end
{$asm}

LUACALL(speedhack_setSpeed(0.5)) {Edit this number to change speed}

[Disable]

Re: Methods you may not know.

Posted: Mon Oct 05, 2020 9:56 pm
by Chiados
Nice work.

Re: Tips you may not know.

Posted: Sun Oct 11, 2020 3:18 am
by asthebloody
this is very helpful , btw thank youuu

Some additions...

Posted: Fri Nov 13, 2020 7:04 pm
by Paul44
^^ I'll be adding some comments in due time, related to each 'topic'. For starters:
a) How to update proof static address: this works perfectly for x32, not so much for x64. In that case, you'll get the offset-value related to the next opcode, following this one. Practically: get the offset as explained above, get the address from the next opcode line; then add to that address the offset value, which will give you the address holding that particular value. Iow if you need to get that value, you'll have to do another readPointer (or readInteger/etc).
ps: i've seen several lua scripts, both posted here and @CEF. I've written my own version for that purpose (and more). Just check out one of my AC tables (preferably AC BF), and have a look at the 'getStaticAddress()' (that script allows me to perform a number of approaches: get the address, get the address' value, get the aobscan address e.g.)

b) Easy player compare: "base is often addressed by an address which only addresses that one address". I would add to that that - permitting time - you will always find an opcode which returns/handles that specific address uniquely. One of the techniques I use here often, is to scan for (hex)values with 'Writable' flag set to "Gray-ed" (with some luck you'll find an address as explained in your point a) above ~ = static address = "green" )
* However: if you really want to open up your options, then do following: [ goto to Debug Settings, and select 'Page exceptions' as breakpoint method]. Once done, get your base address opened in the 'Dump window' (~memory region). Next, select a whole bunch of bytes (best set display to 'Byte hex) - I tend to select 0~500 bytes per time - then choose 'Data breakpt ~ Find out what accesses...'. (and be prepared that this will cause a serious charge to your cpu's capabilities). But: you'll get "tons of code" to choose from...! (btw: this tip was taught to me by #Sunbeam)
PS: this works great in CE pre-v7.x; far "less effective" in V7.x (only per 64 bytes ~ i'm sure they have their reasons). And: do NOT forgot to "reset" that breakpoint method; you'll notice soon enough when doing your "normal stuff" thereafter...
* Another technique I use here, is 'pointerscanning': in a series like AC, you'll find out that "a" particular data structure could be taken as 'base' for many other datastructures. For example, in all (well, at least those I've tackled), once you've find either the 'Entity' or 'BhvAssassin' structure, you can set out a bunch of pointer chains to pretty important structures (such as health, inventory, etc).
How to tackle this (at least, that's how i'm doing it): once I've found my health, I do a pointerscan (usually taken a somewhat longer path range) for its value. So related to my example: once I got the ptr_list reduced to an acceptable amount, add 5-10 to your addresslist; then just check out of if any of the datastructs' addresses - you already know - also show up in that chain... (I tend to follow the whole chain - from within a datastruct table - as I might come across other VFTs I've already handled in the past)
tip: you also might want to try out the option 'first element of struct must point to module/VFT)': no guarantee for good results - I suppose it highly depends on how well CE builds a datastructure - but better chances of finding important data structures in that pointer_chain.
ps2: I actually came to this approach by looking at #Sunbeam's tables. Did you ever wonder HOW he got to all those pointers?! (I never asked, btw...)
* And finally: something I also do frequently: once you got your base address, do a simple hex_scan (4-8 bytes) of that address, which usually returns enough results. Add all those to the addresslist, and then check out 'what accesses': again with some luck, you'll get your "unique address opcode".
General tip here: if you find several working opcodes/scripts, then keep ALL of them "in your backpocket" ! As games upgrade, so will those opcodes, and when one starts failing you'll have at least - with some luck - a "backup-script" at hand...

...

x) How to make a script disable from table view: a really (yes, really) simple code: (I tend to use this primarily in lua-scripted code; as last part in the ENABLE section ~ see table below)
{$asm}
test al,al

my guess: when CE verifies the code it "seems" ok syntax-wise, but upon executing it'll error out... (iow its errorhandling routine kicks in... kicking us out...)

...tobecontinued...






Table of "generic" scripts; not related to any particular game per se.
Features:
- Generate Components List (w/ Properties)...
- Show Lua Engine window & Dis/enable some elements..
- Clear Lua Engine window & Wait for processing...
- Reverse hex_value... & "Auto"-disable script...
- Get current Processlist & How to select a processName (or Id)...
- Open & Close MemoryViewer...
- Get full path location from processName/Id & Use in OpenDialog()...
- Get a particular CE registry key...
- Get a particular 'system' registry key... (~ my default browser)
- Show table name, using messageDialog()...

- (more to come...)

Tips you may not know.

Posted: Fri Nov 13, 2020 8:08 pm
by Dread_Pony_Roberts
Paul44 wrote:
Fri Nov 13, 2020 7:04 pm
"First you will need to find and set the ground flag to whatever registers the player as on the ground": I recognize the situation (including falling to death ~ pretty much most games I've tackled show this behaviourism). I tend to approach that situation with a Godmode cheat (so, yeah, a cheat in every sense 8-) ). anyways: it is not clear to me how you tackle this exactly. as far as I can see, the scripts shown here only handle the 'movement' aspect of it...
Great read so far, I look forward to seeing it continued.

As for your question. I only went over the movement part since that's the main meat of the code, though I'll need to tidy the tutorial up a bit to better explain some things.
The ground flag is what switches you from being able to walk and run, to being in a hard to control falling state. It's usually easy to find, often a single byte switching from 1 to 0. If found and frozen you should look like you're standing in the air whenever you jump.
Often I've found the games don't update their ground flags constantly. Because of this, you can simply write at the start of the flight code

Code: Select all

mov [flag address],0
If something did constantly write to the flag, then you would have to disable that first.

I hope this helps.

Re: Tips you may not know.

Posted: Sat Nov 14, 2020 2:04 pm
by Paul44
^ I've just downloaded/checked up on your 'Halo' table. That particular flag seems to be residing within the same (?) datastruct as the player's coordinates. I'm going to verify that in some AC titles, although I doubt it (structure there is called 'Entity'). #Sunbeam has done some serious work on those titles as well, but can not recall ever seeing such a flag there (will go through them again, just to be sure).
Anyways: if I can not pinpoint to something similar, I might download/install that game myself. If I recall well, it got cracked some time back... (fyi ofc :ph34r: )

btw: looks great, with plenty of options. I feel a shiver going down my spine, just thinking about maintenance :dry:

Re: Tips you may not know.

Posted: Tue Nov 17, 2020 8:19 am
by Dread_Pony_Roberts
Paul44 wrote:
Sat Nov 14, 2020 2:04 pm
^ I've just downloaded/checked up on your 'Halo' table. That particular flag seems to be residing within the same (?) datastruct as the player's coordinates. I'm going to verify that in some AC titles, although I doubt it (structure there is called 'Entity'). #Sunbeam has done some serious work on those titles as well, but can not recall ever seeing such a flag there (will go through them again, just to be sure).
Anyways: if I can not pinpoint to something similar, I might download/install that game myself. If I recall well, it got cracked some time back... (fyi ofc :ph34r: )

btw: looks great, with plenty of options. I feel a shiver going down my spine, just thinking about maintenance :dry:
Halo is especially maintenance heavy. Each major update practically breaks most of my scripts for each game. At the very least then all I have to do is just link it up with my original code instead of starting from scratch.

I hope you were able to understand it well and get the game running. If you need any more help understanding it then let me know.

Re: Tips you may not know.

Posted: Thu Nov 19, 2020 6:16 pm
by q13allz420
Is there an easy way to keep me updated on the Status of your Halo 4 Project I am very interested in using a table over trainers because most of these traainers have bugs that can be annoying if not game breaking. with a table it's easier to manipulate the game also I am wondering with some if not all of your tables I've seen you've found a way to turn skulls off in game. I'm wondering with all of the bypass and what not on if I can complete a LASO Reach Campaign earning cheats with the blind skull off?

Re: Tips you may not know.

Posted: Fri Nov 20, 2020 8:48 am
by Paul44
^@q13allz420: wrong topic; would you mind posting such a request in the proper topic (next time(s))? (nothing wrong with your request, it just has NOTHING to do with this topic...)