As you said, the Lua engine is embedded directly into the game. It's inside plugins/GameManagerVC.dll (or GameManagerVC64.dll in case of 64-bit).
So, first step will be finding out, which version of Lua it is. So put this DLL into Ghidra or IDA Pro. The most easiest way of figuring out, what version of Lua it uses, is by searching for "Lua" string ...
It was pretty easy one so I could do myself:)
We have exploit.c file where I need to debug it in order to get the flag with 'gcc'. I run the program with:
gcc -g exploit.c -o exploit and got 'exploit' which is executable exploit.c file.
Then: gdb exploit
We have bool c = false; on line 21, so put the break line on it:
Then: I changed the value of c ...
The if statement is likely compiled into a conditional jump so you just need to step until the comparison and change the result. For example, if the jump is je or jne, you need to change the zero flag (ZF) to force the jump in the opposite direction.
For changing flags in GDB, see
Another option is to change the ...
I found a solution and gonna leave it here for future reference.
First, you need to calculate the linear address (the one the binary will have in run-time) from the RIP offset of the jump. Let's say the RIP offset is 0x8fe. You add this, and the offset of the instruction itself (offset from start of .text section) plus the instruction size and you get a ...
Let's break it down line by line. Assuming x is the thing you want to multiply by 21 and it's stored in eax (as it is in this example after line 34).
<39>: mov edx, eax ; so copy the x to edx
<41>: mov eax, edx ; it's pointless to do this mov; after those two lines eax & edx has the value of x
<43>: shl eax, 2 ; so eax = x * 4
From type == 0 you see that it writes to param_3 and reads from param_4. So those parameters must be pointers to output and input buffers respectively. In fact, if you change them to correct type (byte *), then I believe Ghidra should be able to simplify the rest of the code to easily understandable form.
The part that modifies param_2 is a simple pseudo-...
Apart from what defragger said, there are few things to note (as you are learning about calling conventions). This is an example of 32 bit x86 calling convention (C).
Before a subroutine call, caller saves caller-saved registers on stack (registers eax, ecx, edx - "if required")
Then it pushes subroutine parameters on stack in inverted order (in ...
Yes, this is possible with some cooperation from the debugger. The OllyMigrate plugin supports migration between following debuggers:
It seems Visual Studio is not supported but you can always do it the manual way:
Patch an infinite loop (EB FE) at the current EIP/RIP;
Detach the current debugger. ...
Yes, mov DWORD PTR 40[rsp], 6 is the same as mov DWORD PTR [rsp + 40], 6. The first syntax makes a lot more sense in cases where the constant is the base address of an array, and the register contains a byte offset into that array. That's the use case the syntax was designed for.