||2 years ago|
|patcher-source||2 years ago|
|.gitignore||2 years ago|
|README.md||2 years ago|
Recently I got sent a R6 Cheat, with the wish of getting it "cracked". When I saw that it was an unpacked console app, I decided to accept the challenge and now I'm posting this write-up to help upcoming reverse engineers and to help software developers protect their code. I only ran this cheat inside of my Virtual Machine, its not malicious, but if you run it its under your own risk.
You can download this release HERE. I would really appreciate it if you read along though.
Step 0: Identification
As I already said, it is a native x64 console application that has not been packed. I started it, and it asks you for a client id and password. Upon entering wrong information, the app prints our an error message and closes after a short amount of time. The first thing I obviously did was to throw it into IDA and have a look at the strings.
I did not find the string that gets written when the authentication fails, which means, that they we're encrypted.
These are some interesting strings I found:
Uses something made by xerox
Step 1: Checking out the xrefs
A really interesting string was
Please press F1 when in menu... which lead me right to this function:
I renamed the function to
StartCheat. I reversed
LoadKernelDriver by finding the
GetProcAddress call containing the string
NtLoadDriver and then I just took a look at the cross references until I eventually ended up in
GetProcessByName was pretty obvious.
Now we already know which function we need to call in order for the cheat to start! Great! I will come back to that later.
Step 2: Taking a look at main()
StartCheat, I found, that it was getting called in
main. But before continuing on my actual goal, I took a look around too see, what happens in
main. One of the things I noticed right away was the string encryption:
DoHttpRequests by going back to the URL string and checking out the xrefs. It gets called right at the start of
main. It contained a call to
WinHttpOpen, so I guessed that somewhere deeper in the code there should obviously be a call to
By getting the xrefs to it, I found the exact place and debugged it, to see, what is requested.
My guess it, that the first request gets a token of some kind that is needed for the second request, that probably gets some variables, like offsets from the auth.gg API.
I didn't bother about reversing it further, so I went back to my original goal.
Step 3: Finding the right place to patch
In Step 1 I found
StartCheat and that it gets called at the very end of
main after the user has put in the login credentials.
An assumption I made is that the return value of the function inside of the
if condition is the success of the login process. By going into the debugger and setting a breakpoint there, I saw, that the code reached this line, but after calling the function the Program just exited.
Inside of this function, there was a reference to the auth.gg URL string and I found 4 calls to
exit() that came right after a 2 second
sleep. Exactly the behavior I explained in Step 0. Essentially this it the authenticate function. This simply means, that we have to patch out the call completely, because the function itself exits when the credentials are wrong. I could have gone further and reversed the exact conditional jump that needs to be patched, but I had already reached my goal.
The call consist of 4 bytes and it is expected to return a single byte.
We can simple NOP those 4 bytes located at
godtier.exe + 0x4A49, then the function won't be called and the
al register, which should contain the return value, already has a value, which means, that the expression evaluates to
Step 4: Wrapping things up
I could have now simply byte patched the binary file and called it a day, but I decided to write a program that patches it, just for fun. The source code of this App is in this repository.
It was a pretty fun experience and I hope you had fun reading. I'm probably not the right person to give tips like this, but this application could have been better protected if it:
- was packed
- all strings we're encrypted
- The variables from the API get pulled AFTER a successful login
Here is a video that proves the concept, that someone who tested it sent me: https://streamable.com/fyxiai