Video Tutorial How to Hack Gwent - Witcher 3 Cheat Engine Tutorial

Hexui Undetected CSGO Cheats Sinkicheat PUBG Cheat

TheHackerDev

Nobleman
Jul 13, 2020
4
78
0
Learn how to reverse engineer Gwent and create a basic Cheat Engine Code Injection Script to modify the game, resulting in an auto-win cheat.


Gwent Hack steps:

1. Scan for score value
- 4 byte int

2. Find where it is being accessed
- Look for write
- Things to keep in mind:
- Seeing [base + offset * size] indicates an array-like structure. This is usually how data is stored with other directly related data (like two sets of scores) inside of an entity object.
- Don't be thrown off by the number of times it is accessed. There are often other functions that are using the value in ways that you can't anticipate (eg enemy AI, NPCs with same values, etc.).
- Trying to modify the value may not do anything. In this case, it appears that it's being written before being read, or just overwritten at different times. If that doesn't work, try changing the instruction that overwrites the value (start with a nop).

3. Try NOP to validate that the instruction is the one we're looking for. In this case, it is actually a shared instruction (affects multiple values).
- Ideally, you want to find a non-shared instruction, but that's not always the case. So you just need to find a unique value/ID for the structure/value that you want to modify...

4. Find what other addresses this instruction accesses.
- BOOM. Score values found.

5. Compare registers
1. Sometimes the automatic scan for commonalities doesn't find anything for some reason.
2. Manually select "show registers"
3. See difference in concrete value that's not a pointer - R15 (0 for our score, and 1 for opponent). This is our compare value/unique ID.

The script
Code:
{ Game   : witcher3.exe
  Version: 1.0
  Date   : 2020-07-11
  Author : TheHackerDev

  This script automatically sets our Gwent score to 200 when enabled.
}

[ENABLE]

//aobscanmodule(gwent_score_update,witcher3.exe,42 89 04 B9 8B 4C 24 30) // should be unique
assert("witcher3.exe"+1556D32, 42 89 04 B9 8B 4C 24 30)

define(fn_GwentScoreUpdate, "witcher3.exe"+1556D32)
registersymbol(fn_GwentScoreUpdate)

alloc(newmem,$1000,"witcher3.exe"+1556D32)
registersymbol(newmem)

label(update_player_score)
label(update_opponent_score)
label(original_code)
label(return)

// New code
newmem:
  pushf
  cmp r15,00
  je update_player_score
  jmp update_opponent_score

update_player_score:
  mov [rcx+r15*4],#200
  jmp original_code

update_opponent_score:
  mov [rcx+r15*4],eax
  jmp original_code

original_code:
  // mov [rcx+r15*4],eax
  mov ecx,[rsp+30]
  popf
  jmp return

// Original dissassembly
fn_GwentScoreUpdate:
  jmp newmem
  nop 3
return:

[DISABLE]

fn_GwentScoreUpdate:
  db 42 89 04 B9 8B 4C 24 30

unregistersymbol(newmem)
unregistersymbol(fn_GwentScoreUpdate)
dealloc(newmem)

{
// ORIGINAL CODE - INJECTION POINT: "witcher3.exe"+1556D32

"witcher3.exe"+1556D13: FF 49 18                 -  dec [rcx+18]
"witcher3.exe"+1556D16: 75 05                    -  jne witcher3.exe+1556D1D
"witcher3.exe"+1556D18: E8 93 14 D8 FF           -  call witcher3.exe+12D81B0
"witcher3.exe"+1556D1D: 44 88 2F                 -  mov [rdi],r13l
"witcher3.exe"+1556D20: EB 14                    -  jmp witcher3.exe+1556D36
"witcher3.exe"+1556D22: 44 88 2F                 -  mov [rdi],r13l
"witcher3.exe"+1556D25: EB 35                    -  jmp witcher3.exe+1556D5C
"witcher3.exe"+1556D27: 48 8B 4E 18              -  mov rcx,[rsi+18]
"witcher3.exe"+1556D2B: 8B 44 24 40              -  mov eax,[rsp+40]
"witcher3.exe"+1556D2F: C6 07 01                 -  mov byte ptr [rdi],01
// ---------- INJECTING HERE ----------
"witcher3.exe"+1556D32: 42 89 04 B9              -  mov [rcx+r15*4],eax
"witcher3.exe"+1556D36: 8B 4C 24 30              -  mov ecx,[rsp+30]
// ---------- DONE INJECTING  ----------
"witcher3.exe"+1556D3A: 8B C1                    -  mov eax,ecx
"witcher3.exe"+1556D3C: 83 E0 1F                 -  and eax,1F
"witcher3.exe"+1556D3F: 3C 09                    -  cmp al,09
"witcher3.exe"+1556D41: 7E 19                    -  jle witcher3.exe+1556D5C
"witcher3.exe"+1556D43: C1 E9 09                 -  shr ecx,09
"witcher3.exe"+1556D46: F6 C1 01                 -  test cl,01
"witcher3.exe"+1556D49: 48 8D 4C 24 30           -  lea rcx,[rsp+30]
"witcher3.exe"+1556D4E: 74 07                    -  je witcher3.exe+1556D57
"witcher3.exe"+1556D50: E8 AB AA FC FF           -  call witcher3.exe+1521800
"witcher3.exe"+1556D55: EB 05                    -  jmp witcher3.exe+1556D5C
}
Download Cheat Table from attachments

This video was made for GH by TheHackerDev
https://twitter.com/TheHackerDev
Twitch
 

Attachments

Last edited by a moderator:

Icew0lf

Software Ninjaneer
Dank Tier VIP
Fleep Tier Donator
Aug 20, 2013
601
17,558
43
i thought for a second this is for the MP Gwent game..its witcher3 ofc, stupid me. good idea!
Im curious, will watch definately
 

Rake

Cesspool Admin
Administrator
Jan 21, 2014
12,061
78,998
2,370
Great video & welcome to team GH
 
Attention! Before you post:

Read the How to Ask Questions Guide
99% of questions are answered in the Beginner's Guide, do it before asking a question.

No Hack Requests. Post in the correct section.  Search the forum first. Read the rules.

How to make a good post:

  • Fill out the form correctly
  • Tell us the game name & coding language
  • Post everything we need to know to help you
  • Ask specific questions, be descriptive
  • Post errors, line numbers & screenshots
  • Post code snippets using code tags
  • If it's a large project, zip it up and attach it

If you do not comply, your post may be deleted.  We want to help, please make a good post and we will do our best to help you.

Community Mods