Strange Brigade [Engine:Asura] - Scripts, goodies and more..

Upload your cheat tables here (No requests)
User avatar
SunBeam
Administration
Administration
Posts: 4702
Joined: Sun Feb 04, 2018 7:16 pm
Reputation: 4285

Strange Brigade [Engine:Asura] - Scripts, goodies and more..

Post by SunBeam »

[ 17.01.2019 - Update #2 ]

Added:
  • Super Accuracy
  • Fast Fire
  • No Recoil / Screen Shake


Download:

StrangeBrigade_DX12.CT
1.2
(14.9 KiB) Downloaded 794 times

BR,
Sun

[ 16.01.2019 - Update #1 ]

Adjusted some stuff, as well as adding infinite clip ammo and instant/infinite amulet charge.

StrangeBrigade_DX12.CT
1.1
(10.94 KiB) Downloaded 173 times

BR,
Sun

[ 30.12.2018 - First Release ]

«[ INTRO ]»

Hello folks.

I've been on to Sniper Elite's engine since the third title came out. Haven't studied a lot of it, but now that I had some spare time (instead of addressing other countless table/trainer updates and user requests), let me brief you in a bit on this engine. Recently learned its name is Asura. The version.. I don't know yet. But will determine some internals at some point :P

Alright; so, in Sniper Elite 4 I had this piece of code that I hooked to get player structure and player id:

Code: Select all

00000001415E82D0 | 48:83EC 28         | SUB RSP,28                                |
00000001415E82D4 | 48:8B05 75AF62FF   | MOV RAX,QWORD PTR DS:[140C13250]          |
00000001415E82DB | 48:85C0            | TEST RAX,RAX                              |
00000001415E82DE | 74 4A              | JE sniperelite4_dx11_dumped.1415E832A     |
00000001415E82E0 | 8B50 14            | MOV EDX,DWORD PTR DS:[RAX+14]             |
00000001415E82E3 | 81FA E7030000      | CMP EDX,3E7                               |
00000001415E82E9 | 75 09              | JNE sniperelite4_dx11_dumped.1415E82F4    |
00000001415E82EB | 803D 66F857FF 00   | CMP BYTE PTR DS:[140B67B58],0             |
00000001415E82F2 | 75 2C              | JNE sniperelite4_dx11_dumped.1415E8320    |
00000001415E82F4 | 48:8D0D 35F857FF   | LEA RCX,QWORD PTR DS:[140B67B30]          |
00000001415E82FB | E8 F09CA1FF        | CALL sniperelite4_dx11_dumped.141001FF0   |
00000001415E8300 | 48:89C2            | MOV RDX,RAX                               |
00000001415E8303 | 48:85C0            | TEST RAX,RAX                              |
00000001415E8306 | 74 1A              | JE sniperelite4_dx11_dumped.1415E8322     |
00000001415E8308 | 48:8B40 08         | MOV RAX,QWORD PTR DS:[RAX+8]              |
00000001415E830C | 48:6348 04         | MOVSXD RCX,DWORD PTR DS:[RAX+4]           |
00000001415E8310 | F64411 10 01       | TEST BYTE PTR DS:[RCX+RDX+10],1           |
00000001415E8315 | 75 09              | JNE sniperelite4_dx11_dumped.1415E8320    |
00000001415E8317 | 803D B4955FFF 00   | CMP BYTE PTR DS:[140BE18D2],0             |
00000001415E831E | 74 02              | JE sniperelite4_dx11_dumped.1415E8322     |
00000001415E8320 | 31D2               | XOR EDX,EDX                               |
00000001415E8322 | 48:89D0            | MOV RAX,RDX                               | <-- hook
00000001415E8325 | 48:83C4 28         | ADD RSP,28                                |
00000001415E8329 | C3                 | RET                                       |
00000001415E832A | 48:83C4 28         | ADD RSP,28                                |
00000001415E832E | C3                 | RET                                       |
In the actual hook I did this:

Code: Select all

Hook:
mov rax,rdx              // original code
test rax,rax             // check if NULL
je short @f              // if 0, exit; else..
  push rdi               // store rdi
  mov [pPlayer],rdx      // store rdx as Player pointer
  mov edi,[rax+rcx+18]   // get id into rdi/edi
  mov [dwPlayerId],edi   // store id into PlayerId as DWORD
  pop rdi                // restore rdi
@@:
add rsp,28               // out
jmp GetPlayerAndId+7     // jump back
So I wanted to replicate this in Strange Brigade, mostly because I think the engine is more or less identical. When I say identical, I don't mean the CODE to be 100% identical, as I know most of the times that doesn't happen. I mean the engine logic to do same crap as it did in Sniper Elite 4, but much simpler (why; because there are elements from SE4 that are missing; like hearbeat, health being displayed as a number; no skeletal display of AI; so things got dumbed down for a simple shoot'em'up game).

Had some struggle finding it mostly because the developers decided to optimize the compiled code and throw in some inlining in their project. As such, the CALL you see in my function above at 1415E82FB address is spread across whole function :) That still didn't stop me finding it :P So here's the function in Strange Brigade:

Code: Select all

0000000144B44090 | 53                 | PUSH RBX                            |
0000000144B44091 | 55                 | PUSH RBP                            |
0000000144B44092 | 41:56              | PUSH R14                            |
0000000144B44094 | 48:83EC 20         | SUB RSP,20                          |
0000000144B44098 | 45:0FB6F0          | MOVZX R14D,R8B                      |
0000000144B4409C | 89D5               | MOV EBP,EDX                         |
0000000144B4409E | 48:89CB            | MOV RBX,RCX                         |
0000000144B440A1 | 81FA E7030000      | CMP EDX,3E7                         |
0000000144B440A7 | 75 17              | JNE strangebrigade_dx12.144B440C0   |
0000000144B440A9 | 8079 28 00         | CMP BYTE PTR DS:[RCX+28],0          |
0000000144B440AD | 74 11              | JE strangebrigade_dx12.144B440C0    |
0000000144B440AF | 31C0               | XOR EAX,EAX                         |
0000000144B440B1 | 48:83C4 20         | ADD RSP,20                          |
0000000144B440B5 | 41:5E              | POP R14                             |
0000000144B440B7 | 5D                 | POP RBP                             |
0000000144B440B8 | 5B                 | POP RBX                             |
0000000144B440B9 | C3                 | RET                                 |
0000000144B440BA | 66:0F1F4400 00     | NOP WORD PTR DS:[RAX+RAX],AX        |
0000000144B440C0 | B9 88130000        | MOV ECX,1388                        | <-- this would be where the inlined CALL starts
..
..
0000000144B44153 | 48:85D2            | TEST RDX,RDX                        | <-- CALL ends here
0000000144B44156 | 74 20              | JE strangebrigade_dx12.144B44178    |
0000000144B44158 | 48:8B42 08         | MOV RAX,QWORD PTR DS:[RDX+8]        |
0000000144B4415C | 48:6348 04         | MOVSXD RCX,DWORD PTR DS:[RAX+4]     |
0000000144B44160 | F64411 10 01       | TEST BYTE PTR DS:[RCX+RDX+10],1     |
0000000144B44165 | 0F85 44FFFFFF      | JNE strangebrigade_dx12.144B440AF   |
0000000144B4416B | 803D 552C20FC 00   | CMP BYTE PTR DS:[140D46DC7],0       |
0000000144B44172 | 0F85 37FFFFFF      | JNE strangebrigade_dx12.144B440AF   |
0000000144B44178 | 48:89D0            | MOV RAX,RDX                         |
0000000144B4417B | 48:83C4 20         | ADD RSP,20                          |
0000000144B4417F | 41:5E              | POP R14                             |
0000000144B44181 | 5D                 | POP RBP                             |
0000000144B44182 | 5B                 | POP RBX                             |
0000000144B44183 | C3                 | RET                                 |
«[ PURSUIT ]»

Upon checking the TEST at 144B44160, I noticed there's a bunch of other addresses using the instruction. As such, I looked for a spot checking that BYTE at [rcx+rdx+10] that'd work for only our Player structure pointer ;) Then I discovered that I am actually looking at a pointer, player-related, that isn't the REAL Player pointer we need :) Found a stable location where only one hit appeared in the "Find out what addresses this instruction accesses" list:

Code: Select all

StrangeBrigade_DX12.exe+C7E3F2F - 48 8B 93 B0080000     - mov rdx,[rbx+000008B0]
StrangeBrigade_DX12.exe+C7E3F36 - 48 85 D2              - test rdx,rdx
StrangeBrigade_DX12.exe+C7E3F39 - 0F84 AF000000         - je StrangeBrigade_DX12.exe+C7E3FEE
StrangeBrigade_DX12.exe+C7E3F3F - 48 8B 42 08           - mov rax,[rdx+08]
StrangeBrigade_DX12.exe+C7E3F43 - 48 63 48 04           - movsxd  rcx,dword ptr [rax+04]
StrangeBrigade_DX12.exe+C7E3F47 - F6 44 11 10 01        - test byte ptr [rcx+rdx+10],01 <--
So our TEST uses rcx and rdx in the logic; rcx is acquired above the test instruction; rdx is acquired up top, from [rbx+8B0]. So I wanted to know who this is :P And found that "rbx" is the real pointer we want. The offset is still good to know, as we might use it in - perhaps - other checks later on ;) So I ended up at this location:

Code: Select all

StrangeBrigade_DX12.exe+C238C48 - 48 63 41 04           - movsxd  rax,dword ptr [rcx+04]
StrangeBrigade_DX12.exe+C238C4C - 44 8B 74 30 18        - mov r14d,[rax+rsi+18] <-- rax is 0x8C0 here; rsi == 0xC0728BD0
StrangeBrigade_DX12.exe+C238C51 - 41 81 FE E7030000     - cmp r14d,000003E7 { 999 }
..
..
StrangeBrigade_DX12.exe+C238CC0 - 49 8B 14 CC           - mov rdx,[r12+rcx*8]
StrangeBrigade_DX12.exe+C238CC4 - 45 8B 0C 8B           - mov r9d,[r11+rcx*4]
StrangeBrigade_DX12.exe+C238CC8 - 48 85 D2              - test rdx,rdx
StrangeBrigade_DX12.exe+C238CCB - 0F85 F5000000         - jne StrangeBrigade_DX12.exe+C238DC6
StrangeBrigade_DX12.exe+C238CD1 - 45 85 C9              - test r9d,r9d
StrangeBrigade_DX12.exe+C238CD4 - 0F85 F5000000         - jne StrangeBrigade_DX12.exe+C238DCF
StrangeBrigade_DX12.exe+C238CDA - 48 89 FA              - mov rdx,rdi
StrangeBrigade_DX12.exe+C238CDD - F0 FF 0D 3CAFAAF4     - lock dec [StrangeBrigade_DX12.exe+CE3C20] { [00000000] }
StrangeBrigade_DX12.exe+C238CE4 - 48 85 D2              - test rdx,rdx
StrangeBrigade_DX12.exe+C238CE7 - 0F84 75050000         - je StrangeBrigade_DX12.exe+C239262
StrangeBrigade_DX12.exe+C238CED - 48 8B 42 08           - mov rax,[rdx+08]
StrangeBrigade_DX12.exe+C238CF1 - 48 63 48 04           - movsxd  rcx,dword ptr [rax+04]
StrangeBrigade_DX12.exe+C238CF5 - 84 5C 11 10           - test [rcx+rdx+10],bl <-- rcx is 0xDE0 here; rdx == 0xC1AEAF90 (can also be retrieved from [C0728BD0+8B0])
If you want to know, that copy pointer that's checking the same byte and PlayerId is the HUD.Player :) See the below function:

Code: Select all

StrangeBrigade_DX12.exe+DA911B0 - 48 83 EC 28           - sub rsp,28 { 40 }
StrangeBrigade_DX12.exe+DA911B4 - 84 C9                 - test cl,cl
StrangeBrigade_DX12.exe+DA911B6 - 0F84 17010000         - je StrangeBrigade_DX12.exe+DA912D3
StrangeBrigade_DX12.exe+DA911BC - 48 8B 05 65C635F3     - mov rax,[StrangeBrigade_DX12.exe+DED828] { [1401FE180] }
StrangeBrigade_DX12.exe+DA911C3 - 48 89 5C 24 30        - mov [rsp+30],rbx
StrangeBrigade_DX12.exe+DA911C8 - 48 8D 1D A1197BF2     - lea rbx,[StrangeBrigade_DX12.exe+242B70] { [83485640] }
StrangeBrigade_DX12.exe+DA911CF - 48 89 7C 24 20        - mov [rsp+20],rdi
StrangeBrigade_DX12.exe+DA911D4 - 40 30 FF              - xor dil,dil
StrangeBrigade_DX12.exe+DA911D7 - 48 85 C0              - test rax,rax
StrangeBrigade_DX12.exe+DA911DA - 74 11                 - je StrangeBrigade_DX12.exe+DA911ED
StrangeBrigade_DX12.exe+DA911DC - 48 89 C3              - mov rbx,rax
StrangeBrigade_DX12.exe+DA911DF - 48 C7 05 3EC635F3 00000000 - mov qword ptr [StrangeBrigade_DX12.exe+DED828],00000000 { 0 }
StrangeBrigade_DX12.exe+DA911EA - 40 B7 01              - mov dil,01 { 1 }
StrangeBrigade_DX12.exe+DA911ED - 48 8D 0D 4C12E9F2     - lea rcx,[StrangeBrigade_DX12.exe+922440] { ["Does this player have extra health above the base health."] }
StrangeBrigade_DX12.exe+DA911F4 - FF D3                 - call rbx
StrangeBrigade_DX12.exe+DA911F6 - 40 84 FF              - test dil,dil
StrangeBrigade_DX12.exe+DA911F9 - 48 8B 7C 24 20        - mov rdi,[rsp+20]
StrangeBrigade_DX12.exe+DA911FE - 74 13                 - je StrangeBrigade_DX12.exe+DA91213
StrangeBrigade_DX12.exe+DA91200 - 48 89 1D 21C635F3     - mov [StrangeBrigade_DX12.exe+DED828],rbx { [1401FE180] }
StrangeBrigade_DX12.exe+DA91207 - B0 01                 - mov al,01 { 1 }
StrangeBrigade_DX12.exe+DA91209 - 48 8B 5C 24 30        - mov rbx,[rsp+30]
StrangeBrigade_DX12.exe+DA9120E - 48 83 C4 28           - add rsp,28 { 40 }
StrangeBrigade_DX12.exe+DA91212 - C3                    - ret 
StrangeBrigade_DX12.exe+DA91213 - 48 8B 0D 669E2BF3     - mov rcx,[StrangeBrigade_DX12.exe+D4B080] { [03F5F740] }
StrangeBrigade_DX12.exe+DA9121A - 41 B0 01              - mov r8l,01 { 1 }
StrangeBrigade_DX12.exe+DA9121D - 41 0FB6 D0            - movzx edx,r8l
StrangeBrigade_DX12.exe+DA91221 - 48 8B 01              - mov rax,[rcx]
StrangeBrigade_DX12.exe+DA91224 - FF 50 60              - call qword ptr [rax+60]
StrangeBrigade_DX12.exe+DA91227 - 48 8B 5C 24 30        - mov rbx,[rsp+30]
StrangeBrigade_DX12.exe+DA9122C - B0 01                 - mov al,01 { 1 }
StrangeBrigade_DX12.exe+DA9122E - 48 83 C4 28           - add rsp,28 { 40 }
StrangeBrigade_DX12.exe+DA91232 - C3                    - ret
..
..
StrangeBrigade_DX12.exe+DAEC300 - 48 83 EC 28           - sub rsp,28 { 40 }
StrangeBrigade_DX12.exe+DAEC304 - 48 8B 05 356628F3     - mov rax,[StrangeBrigade_DX12.exe+D72940] { [A6FF5780] }
StrangeBrigade_DX12.exe+DAEC30B - 48 85 C0              - test rax,rax
StrangeBrigade_DX12.exe+DAEC30E - 74 4B                 - je StrangeBrigade_DX12.exe+DAEC35B
StrangeBrigade_DX12.exe+DAEC310 - 48 8B 0D 915728F3     - mov rcx,[StrangeBrigade_DX12.exe+D71AA8] { [43CCBFF0] }
StrangeBrigade_DX12.exe+DAEC317 - 48 85 C9              - test rcx,rcx
StrangeBrigade_DX12.exe+DAEC31A - 74 33                 - je StrangeBrigade_DX12.exe+DAEC34F
StrangeBrigade_DX12.exe+DAEC31C - 80 3D 676528F3 00     - cmp byte ptr [StrangeBrigade_DX12.exe+D7288A],00 { 0 }
StrangeBrigade_DX12.exe+DAEC323 - 74 2A                 - je StrangeBrigade_DX12.exe+DAEC34F
StrangeBrigade_DX12.exe+DAEC325 - 83 B9 8C020000 00     - cmp dword ptr [rcx+0000028C],00 { 0 }
StrangeBrigade_DX12.exe+DAEC32C - 75 21                 - jne StrangeBrigade_DX12.exe+DAEC34F
StrangeBrigade_DX12.exe+DAEC32E - 8B 91 78020000        - mov edx,[rcx+00000278]
StrangeBrigade_DX12.exe+DAEC334 - 41 B0 01              - mov r8l,01 { 1 }
StrangeBrigade_DX12.exe+DAEC337 - 48 8D 0D B27A1FF3     - lea rcx,[StrangeBrigade_DX12.exe+CE3DF0] { [C18E5810] }
StrangeBrigade_DX12.exe+DAEC33E - E8 8D3464F2           - call StrangeBrigade_DX12.exe+12F7D0
StrangeBrigade_DX12.exe+DAEC343 - 48 85 C0              - test rax,rax
StrangeBrigade_DX12.exe+DAEC346 - 75 13                 - jne StrangeBrigade_DX12.exe+DAEC35B
StrangeBrigade_DX12.exe+DAEC348 - 48 8B 05 F16528F3     - mov rax,[StrangeBrigade_DX12.exe+D72940] { [A6FF5780] }
StrangeBrigade_DX12.exe+DAEC34F - 48 8B 80 E8000000     - mov rax,[rax+000000E8] <-- gets 0xC1AEAF90 in rax
StrangeBrigade_DX12.exe+DAEC356 - 48 83 C4 28           - add rsp,28 { 40 }
StrangeBrigade_DX12.exe+DAEC35A - C3                    - ret 
StrangeBrigade_DX12.exe+DAEC35B - 48 83 C4 28           - add rsp,28 { 40 }
StrangeBrigade_DX12.exe+DAEC35F - C3                    - ret 
The above function checks the HUD HP you see displayed in the bottom left of the screen. That's how I knew.

In the end I chose this place for the hook:

Code: Select all

StrangeBrigade_DX12.exe+AF05B34 - 49 8B 40 08           - mov rax,[r8+08]
StrangeBrigade_DX12.exe+AF05B38 - 48 63 48 04           - movsxd  rcx,dword ptr [rax+04]
StrangeBrigade_DX12.exe+AF05B3C - 42 F6 44 01 10 01     - test byte ptr [rcx+r8+10],01 <-- hook
Wrote the initialization script, enabled it and now I have these:

Image

Now that the script is in place, we can make use of pPlayer and dwPlayerId in other scripts. At the time I'm writing this, I've already figured out infinite magazine (managed to make use of some internal engine functions which led to switching magazine to infinite; will detail it later). Pretty much like what you see for the revolver, but for any weapon :) See below:

Image

«[ GOD MODE ]»

You can find health by scanning memory for floats, ranged 10-100 and do sequential has increased/decreased/unchanged depending on what happens to your health in-game. At the point where I am in-game (have only played with Frank), the max value is 40.0. Just so you know what you'd have to start from. Once you debug the found address/value on write as some mob hits you, you'll get an instruction part of a function where health is subtracted and written via MMX instructions:

Code: Select all

StrangeBrigade_DX12.exe+5FDF7BC - 44 0F28 C8            - movaps xmm9,xmm0
StrangeBrigade_DX12.exe+5FDF7C0 - F3 0F5C CE            - subss xmm1,xmm6
StrangeBrigade_DX12.exe+5FDF7C4 - 0F2F CF               - comiss xmm1,xmm7
StrangeBrigade_DX12.exe+5FDF7C7 - F3 0F11 4B 50         - movss [rbx+50],xmm1 <-- health on being hit
So we want god mode. But we don't want just some normal, crappy, no health decrementing god mode. We want: no stagger (when hit, you won't move); no visual blood effects. Let's do this:

- start by breaking the below instruction in the health subtraction function

StrangeBrigade_DX12.exe+5FDF787 - F6 44 0A 10 01 - test byte ptr [rdx+rcx+10],01

- get an enemy to hit you
- once CE freezes scroll to the function's epilogue

StrangeBrigade_DX12.exe+5FDF750 - 53 - push rbx

- set breakpoint on it
- F9 to resume
- note down [rsp] on next break

StrangeBrigade_DX12.exe+BB32550 - E8 1B4165F4 - call StrangeBrigade_DX12.exe+186670

- ret epilogue

StrangeBrigade_DX12.exe+5FDF750 - 53 - push rbx
to
StrangeBrigade_DX12.exe+5FDF750 - C3 - ret

- resume game

- see if you still take damage on next hit

- we do take visual damage
- HP doesn't decrease
- enemy HP doesn't decrease if I fire at them
- everyone has "god mode" basically

- leave that ret on so we don't die

- head to StrangeBrigade_DX12.exe+BB32550
- scroll up to prologue

StrangeBrigade_DX12.exe+BB324C0 - 48 89 5C 24 10 - mov [rsp+10],rbx

- set breakpoint on it
- note down [rsp] on break

StrangeBrigade_DX12.exe+BB0BC4D - E8 9EECA4F4 - call StrangeBrigade_DX12.exe+55A8F0

- now ret it

StrangeBrigade_DX12.exe+BB324C0 - 48 89 5C 24 10 - mov [rsp+10],rbx
to
StrangeBrigade_DX12.exe+BB324C0 - C3 - ret

- we still take damage and get pushed if hit
- aim is a no stagger god mode and no visual effects on-screen
- let's continue

- head to StrangeBrigade_DX12.exe+BB0BC4D
- scroll to prologue

StrangeBrigade_DX12.exe+BB0BB40 - 53 - push rbx

- set breakpoint
- note down [rsp] on break

StrangeBrigade_DX12.exe+BAFBEA6 - FF 50 38 - call qword ptr [rax+38]

- now ret the epilogue

StrangeBrigade_DX12.exe+BB0BB40 - 53 - push rbx
to
StrangeBrigade_DX12.exe+BB0BB40 - C3 - ret

- still getting damaged

- head to StrangeBrigade_DX12.exe+BAFBEA6
- scroll to prologue

StrangeBrigade_DX12.exe+BAFBE50 - 53 - push rbx

- break it and get [rsp] on hit

StrangeBrigade_DX12.exe+C73DB2C - FF 50 18 - call qword ptr [rax+18]

- time to ret it

StrangeBrigade_DX12.exe+BAFBE50 - 53 - push rbx
to
StrangeBrigade_DX12.exe+BAFBE50 - C3 - ret

- once you do that, you will notice 2 things:
a) no more blood on your screen and Frank whining
b) any mob trying to hit you hits thin air; you're not being pushed on mob hits

So now it's just a matter of applying a filter at that location so that we tell the game engine to exit the function (that's what "ret" means) only when our player is hit. And for that we can use pPlayer and dwPlayerId ;) If you break at StrangeBrigade_DX12.exe+BAFBE50 and check the registers, you will see that when you get hit, RBX=RDX=pPlayer and RSI=dwPlayerId :) Another thing you might've noticed is all the spawned AIs have their ids generated starting with +1 from yours (when the engine generates a wave of mobs, it will check first entity's id; well, that's us; from that id onward it will increment by 1 each spawned AI's id; assuming new ones are spawned, if the id already exists, it will loop +1 till it finds a "free" one).

So the God Mode script will look like this:

Code: Select all

[ENABLE]

aobscanmodule( h_GodMode, StrangeBrigade_DX12.exe, 534883EC408079??004889CB75??48 )
registersymbol( h_GodMode )
label( h_GodMode_o )
registersymbol( h_GodMode_o )
alloc( GodMode_h, 0x1000, StrangeBrigade_DX12.exe )

GodMode_h:
push rax                 // store register
mov rax,[pPlayer]        // load our Player pointer in rax
cmp rdx,rax              // check it against rdx
pop rax                  // restore rax
jne short @f             // ZF is preserved, even if we did "pop rax"
  ret                    // if us, ret
h_GodMode_o:             // else, run original code for any other AI
readmem( h_GodMode, 5 )
jmp h_GodMode+5

h_GodMode:
jmp GodMode_h

[DISABLE]

h_GodMode:
readmem( GodMode_o, 5 )

dealloc( GodMode_h )
unregistersymbol( h_GodMode_o )
unregistersymbol( h_GodMode )
Seteki brutes and pendulum traps will now just pass through you with the script enabled, LOL. In fact, you can very well walk through anything that would normally deal damage.





Will post more as I progress, alongside a table :P Hold tight.

BR,
Sun

L.E.#1: Looks like you can get damaged by your own grenades. Oh wellz, not that big of a fuzz :P

How to use this cheat table?
  1. Install Cheat Engine
  2. Double-click the .CT file in order to open it.
  3. Click the PC icon in Cheat Engine in order to select the game process.
  4. Keep the list.
  5. Activate the trainer options by checking boxes or setting values from 0 to 1
Attachments
StrangeBrigade_DX12.CT
1.0
(3.41 KiB) Downloaded 229 times

User avatar
SunBeam
Administration
Administration
Posts: 4702
Joined: Sun Feb 04, 2018 7:16 pm
Reputation: 4285

Re: Strange Brigade [Engine:Asura] - Scripts, goodies and more..

Post by SunBeam »

Alright, got some news :) I have updated the table to look like this:

Image

Added another item, pPlayer as pointer, 0x8B0 offset to point to what I discussed in previous post (Ctrl+F for 8B0). In the same post I said I had already found infinite magazine; well, I've revisited it last night. Let's check it out.

Looking for "infinite" in the string references, I found this:

Image

Let's inspect that line.

«[ INFINITE MAGAZINE ]»

We got this:

Image

Let's inspect the code, while debugging. Place a breakpoint here:

Code: Select all

StrangeBrigade_DX12.exe+B68CE30 - 48 89 5C 24 08        - mov [rsp+08],rbx
Back in, as soon as the game is resumed (hit Escape to close menu), CE will break. Let's trace; I'm gonna map below the instructions being executed:

Code: Select all

StrangeBrigade_DX12.exe+B68CE30 - 48 89 5C 24 08        - mov [rsp+08],rbx
StrangeBrigade_DX12.exe+B68CE35 - 57                    - push rdi
StrangeBrigade_DX12.exe+B68CE36 - 48 83 EC 20           - sub rsp,20
StrangeBrigade_DX12.exe+B68CE3A - 84 C9                 - test cl,cl
StrangeBrigade_DX12.exe+B68CE3C - 74 33                 - je StrangeBrigade_DX12.exe+B68CE71
..
StrangeBrigade_DX12.exe+B68CE71 - 83 3D 18476EF5 00     - cmp dword ptr [StrangeBrigade_DX12.exe+D71590],00
StrangeBrigade_DX12.exe+B68CE78 - 0F84 8B000000         - je StrangeBrigade_DX12.exe+B68CF09
StrangeBrigade_DX12.exe+B68CE7E - 48 8B 05 234C6EF5     - mov rax,[StrangeBrigade_DX12.exe+D71AA8] { [8DDCCB10] }
StrangeBrigade_DX12.exe+B68CE85 - 48 85 C0              - test rax,rax
StrangeBrigade_DX12.exe+B68CE88 - 74 7F                 - je StrangeBrigade_DX12.exe+B68CF09
StrangeBrigade_DX12.exe+B68CE8A - 8B 50 14              - mov edx,[rax+14] // <-- at this point, edx holds "PlayerId"
StrangeBrigade_DX12.exe+B68CE8D - 81 FA E7030000        - cmp edx,000003E7
StrangeBrigade_DX12.exe+B68CE93 - 74 74                 - je StrangeBrigade_DX12.exe+B68CF09
StrangeBrigade_DX12.exe+B68CE95 - 41 B0 01              - mov r8l,01
StrangeBrigade_DX12.exe+B68CE98 - 48 8D 0D 516F65F5     - lea rcx,[StrangeBrigade_DX12.exe+CE3DF0] { [C9101A00] }
StrangeBrigade_DX12.exe+B68CE9F - E8 2C29AAF4           - call StrangeBrigade_DX12.exe+12F7D0
StrangeBrigade_DX12.exe+B68CEA4 - 48 85 C0              - test rax,rax // <-- the CALL above returns 0xB8FEB3C0 in RAX
                                                                       // what I've mapped new in the top screenshot as "Player"
StrangeBrigade_DX12.exe+B68CEA7 - 74 60                 - je StrangeBrigade_DX12.exe+B68CF09
StrangeBrigade_DX12.exe+B68CEA9 - 48 8B 10              - mov rdx,[rax]
StrangeBrigade_DX12.exe+B68CEAC - 48 89 C1              - mov rcx,rax
StrangeBrigade_DX12.exe+B68CEAF - FF 92 D0000000        - call qword ptr [rdx+000000D0]
StrangeBrigade_DX12.exe+B68CEB5 - 48 85 C0              - test rax,rax // <-- CALL above returns 0xB53EAA30 in RAX (Weapon)
StrangeBrigade_DX12.exe+B68CEBA - 8B 15 D0466EF5        - mov edx,[StrangeBrigade_DX12.exe+D71590] { [69172C63] }
StrangeBrigade_DX12.exe+B68CEC0 - 48 89 C1              - mov rcx,rax
StrangeBrigade_DX12.exe+B68CEC3 - E8 E8F70DF5           - call StrangeBrigade_DX12.exe+76C6B0
StrangeBrigade_DX12.exe+B68CEC8 - 48 85 C0              - test rax,rax // <-- CALL above returns my magazine's base pointer
                                                                       // 0xB84ABA20
StrangeBrigade_DX12.exe+B68CECB - 74 14                 - je StrangeBrigade_DX12.exe+B68CEE1
StrangeBrigade_DX12.exe+B68CECD - 48 8B 10              - mov rdx,[rax]
StrangeBrigade_DX12.exe+B68CED0 - 48 89 C1              - mov rcx,rax
StrangeBrigade_DX12.exe+B68CED3 - FF 92 00010000        - call qword ptr [rdx+00000100]
StrangeBrigade_DX12.exe+B68CED9 - 84 C0                 - test al,al // <-- the CALL above tells us if magazine is infinite or not
StrangeBrigade_DX12.exe+B68CEDB - 74 04                 - je StrangeBrigade_DX12.exe+B68CEE1
StrangeBrigade_DX12.exe+B68CEDD - B0 01                 - mov al,01
StrangeBrigade_DX12.exe+B68CEDF - EB 02                 - jmp StrangeBrigade_DX12.exe+B68CEE3
And "call [rdx+100]" does this:

Code: Select all

StrangeBrigade_DX12.exe+D8A5FA0 - 0FB6 81 08010000      - movzx eax,byte ptr [rcx+00000108]
StrangeBrigade_DX12.exe+D8A5FA7 - C3                    - ret 
So offset 0x108 tells us if magazine is infinite or not. 0 = not; 1 = yes. Flipping that from 0 to 1 at 0xB84ABA20 + 0x108 does this:

[ before ]

Image

[ after ]

Image

See the bottom-right part, where the ammo is :P This works for also the magazine of the unique weapons you can unlock at supply boxes ;)

Am not sure if this is the correct interpretation of the function, but I read it like this:

- get PlayerID from:

Code: Select all

StrangeBrigade_DX12.exe+B68CE7E - 48 8B 05 234C6EF5     - mov rax,[StrangeBrigade_DX12.exe+D71AA8] { [8DDCCB10] }
StrangeBrigade_DX12.exe+B68CE85 - 48 85 C0              - test rax,rax
StrangeBrigade_DX12.exe+B68CE88 - 74 7F                 - je StrangeBrigade_DX12.exe+B68CF09
StrangeBrigade_DX12.exe+B68CE8A - 8B 50 14              - mov edx,[rax+14]
- with that id in rdx (2nd param for the function) + the below, get Actor structure (you'll see further down why I call it like that):

Code: Select all

StrangeBrigade_DX12.exe+B68CE8A - 8B 50 14              - mov edx,[rax+14]
..
StrangeBrigade_DX12.exe+B68CE95 - 41 B0 01              - mov r8l,01
StrangeBrigade_DX12.exe+B68CE98 - 48 8D 0D 516F65F5     - lea rcx,[StrangeBrigade_DX12.exe+CE3DF0] { [C9101A00] }
StrangeBrigade_DX12.exe+B68CE9F - E8 2C29AAF4           - call StrangeBrigade_DX12.exe+12F7D0
StrangeBrigade_DX12.exe+B68CEA4 - 48 85 C0              - test rax,rax
A pseudo would be GetPlayer( "StrangeBrigade_DX12.exe+CE3DF0", id, 0x1 ).

- then get another structure (I think it's Weapon - - the currently held weapon):

Code: Select all

StrangeBrigade_DX12.exe+B68CEA9 - 48 8B 10              - mov rdx,[rax]
StrangeBrigade_DX12.exe+B68CEAC - 48 89 C1              - mov rcx,rax
StrangeBrigade_DX12.exe+B68CEAF - FF 92 D0000000        - call qword ptr [rdx+000000D0]
StrangeBrigade_DX12.exe+B68CEB5 - 48 85 C0              - test rax,rax
- then get the magazine structure of the current weapon in use:

Code: Select all

StrangeBrigade_DX12.exe+B68CEBA - 8B 15 D0466EF5        - mov edx,[StrangeBrigade_DX12.exe+D71590] { [69172C63] }
StrangeBrigade_DX12.exe+B68CEC0 - 48 89 C1              - mov rcx,rax
StrangeBrigade_DX12.exe+B68CEC3 - E8 E8F70DF5           - call StrangeBrigade_DX12.exe+76C6B0
StrangeBrigade_DX12.exe+B68CEC8 - 48 85 C0              - test rax,rax
- then check if the magazine is infinite or not:

Code: Select all

StrangeBrigade_DX12.exe+B68CECD - 48 8B 10              - mov rdx,[rax]
StrangeBrigade_DX12.exe+B68CED0 - 48 89 C1              - mov rcx,rax
StrangeBrigade_DX12.exe+B68CED3 - FF 92 00010000        - call qword ptr [rdx+00000100]
StrangeBrigade_DX12.exe+B68CED9 - 84 C0                 - test al,al
Do correct me where I missed :P

Then.. looking around our "Player"'s member-functions, I see this:

Image

So.. the "Player" I just added to my table in the top screenshot is actually our Actor :)

BR,
Sun

L.E.#1: The function we were discussing above is executed via this console command: Project.HUD.RemainingAmmoInfinite.

TroliusMaximus
Expert Cheater
Expert Cheater
Posts: 200
Joined: Thu May 25, 2017 3:10 pm
Reputation: 20

Re: Strange Brigade [Engine:Asura] - Scripts, goodies and more..

Post by TroliusMaximus »

Give you're familiar with the Rebellion game engine, you do not by any chance, have Sniper Elite 4 CT script / trainer that can SWITCH OFF MAP BOUNDARIES IN SURVIVAL MODE...?

This particular restriction in said game, really nerfs said mode's strategic options, fun and overall replay value. A script that points to the bot A.I.'s 'cone of vision' / reaction parameters, would be a godsend too...

User avatar
SunBeam
Administration
Administration
Posts: 4702
Joined: Sun Feb 04, 2018 7:16 pm
Reputation: 4285

Re: Strange Brigade [Engine:Asura] - Scripts, goodies and more..

Post by SunBeam »

My table for SE4 has that last part. Look it up :P

Carmonaro
Noobzor
Noobzor
Posts: 13
Joined: Sat Dec 22, 2018 9:10 pm
Reputation: 0

Re: Strange Brigade [Engine:Asura] - Scripts, goodies and more..

Post by Carmonaro »

any update?

User avatar
SunBeam
Administration
Administration
Posts: 4702
Joined: Sun Feb 04, 2018 7:16 pm
Reputation: 4285

Re: Strange Brigade [Engine:Asura] - Scripts, goodies and more..

Post by SunBeam »

Yeah, I've almost finished the game. Updated the table a bit, as swapping characters and maps would render the hook point useless (e.g.: it doesn't work on map #1). Also added Unlimited Clip Ammo and working on accuracy (got it done, just not scripted) and recoil at the moment :P

User avatar
sebastianyyz
Expert Cheater
Expert Cheater
Posts: 315
Joined: Sun Jul 09, 2017 3:33 am
Reputation: 53

Re: Strange Brigade [Engine:Asura] - Scripts, goodies and more..

Post by sebastianyyz »

Thank you SunBeam

User avatar
SunBeam
Administration
Administration
Posts: 4702
Joined: Sun Feb 04, 2018 7:16 pm
Reputation: 4285

Re: Strange Brigade [Engine:Asura] - Scripts, goodies and more..

Post by SunBeam »

sebastianyyz wrote:
Tue Jan 15, 2019 8:34 pm
Thank you SunBeam
You're welcome :) Updated table to 1.1 ;)

Carmonaro
Noobzor
Noobzor
Posts: 13
Joined: Sat Dec 22, 2018 9:10 pm
Reputation: 0

Re: Strange Brigade [Engine:Asura] - Scripts, goodies and more..

Post by Carmonaro »

SunBeam wrote:
Tue Jan 15, 2019 11:26 pm
sebastianyyz wrote:
Tue Jan 15, 2019 8:34 pm
Thank you SunBeam
You're welcome :) Updated table to 1.1 ;)
Thank you so so much! :lol: unlimited ammo all I wanted so I can play with special weapons as much as I like. again thank you.

User avatar
SunBeam
Administration
Administration
Posts: 4702
Joined: Sun Feb 04, 2018 7:16 pm
Reputation: 4285

Re: Strange Brigade [Engine:Asura] - Scripts, goodies and more..

Post by SunBeam »

Adding accuracy, no recoil and faster rate of fire this evening ;) Maybe I'll find a way to unlock the fire rate to insane speeds. Also.. while doing no recoil I also stumbled upon the audio for the fire shot; which I can suppress. So now you fire, but it's done silently (shot sound is never produced) :) Think it's nice for a quiet game, lol.

Carmonaro
Noobzor
Noobzor
Posts: 13
Joined: Sat Dec 22, 2018 9:10 pm
Reputation: 0

Re: Strange Brigade [Engine:Asura] - Scripts, goodies and more..

Post by Carmonaro »

SunBeam wrote:
Wed Jan 16, 2019 1:14 pm
Adding accuracy, no recoil and faster rate of fire this evening ;) Maybe I'll find a way to unlock the fire rate to insane speeds. Also.. while doing no recoil I also stumbled upon the audio for the fire shot; which I can suppress. So now you fire, but it's done silently (shot sound is never produced) :) Think it's nice for a quiet game, lol.
:D amazing work as always :lol:

just one problem I found: faster rate of fire causes immediate freeze and crash to the game :!:

User avatar
SunBeam
Administration
Administration
Posts: 4702
Joined: Sun Feb 04, 2018 7:16 pm
Reputation: 4285

Re: Strange Brigade [Engine:Asura] - Scripts, goodies and more..

Post by SunBeam »

Hmmm..

I think your problem is the allocation. I've explained this several times in the past: the script expects a standard 5-bytes JMP to be placed at the location I scan for. If the allocated memory address is far-off and the calculated JMP exceeds 5-bytes, then a long one is placed instead, sized 14-bytes. As such, try this: enable all scripts at main menu. Go in-game and tell me if it still crashes. Maybe we can do it over TeamViewer, if you still experience it after this.

BR,
Sun

blackops12345
Noobzor
Noobzor
Posts: 9
Joined: Wed Jan 02, 2019 4:17 pm
Reputation: 1

Re: Strange Brigade [Engine:Asura] - Scripts, goodies and more..

Post by blackops12345 »

Thanks a lot sunbeam your just super how about something to change weapon give scarab gun thanks

User avatar
bloodsucker
Expert Cheater
Expert Cheater
Posts: 218
Joined: Tue Mar 14, 2017 1:08 am
Reputation: 25

Re: Strange Brigade [Engine:Asura] - Scripts, goodies and more..

Post by bloodsucker »

do you have skill point cheat?

ign1z
Cheater
Cheater
Posts: 31
Joined: Sat Oct 28, 2017 6:20 pm
Reputation: 13

Re: Strange Brigade [Engine:Asura] - Scripts, goodies and more..

Post by ign1z »

no code for vulkan version ? :(

Post Reply

Who is online

Users browsing this forum: admantx, bigbri, daim, Google [Bot], Google Adsense [Bot], LanceToTheN, Mr. Seth Marshall, One, Pisallo, shockie85, tindr_sb, Vasily, yami973, zyzerg