 |
Cheat Engine The Official Site of Cheat Engine
|
View previous topic :: View next topic |
Author |
Message |
v3rmin How do I cheat?
Reputation: 0
Joined: 19 Dec 2020 Posts: 6
|
Posted: Sat Dec 19, 2020 7:38 am Post subject: FlappyBird crackme native win32 to try and win/RE |
|
|
Hey would anyone be interested in this 'crackme' style game in which the goal is to win /beat this game using cheatengine or any other programs are allowed in order to win this game.
Some ideas I think could maybe work is that maybe each time a green drain/pole is reached you could maybe increase the points? Or maybe there is some other technique in which you can get beat this "Flappy Bird" type game. If you could show me the process or a script that would be able to do it with cheatengine or any other way that would be great thanks.
The game is a PE 32bit windows executable.
Here is the windows/Win32 executable for the game:
https[:]//gofile[.]io/d/6Ro4nN
(remove the [] in the URL above)
You can post your solutions to me in PM.
PS if anyone wants to discuss on discord ideas, PM me and I will send through my discord.
Thanks
|
|
Back to top |
|
 |
atom0s Moderator
Reputation: 204
Joined: 25 Jan 2006 Posts: 8577 Location: 127.0.0.1
|
Posted: Sat Dec 19, 2020 2:41 pm Post subject: |
|
|
A warning to others before just blindly downloading and running this:
https://www.virustotal.com/gui/file/7aa24d17cec7181c71a04b7a8279e420c30f7364acd8cc7ac351be63254071b0/detection
The collision detection is done here:
Code: |
HackyBird.exe+30DC (call IntersectRect)
HackyBird.exe+30F6 (call IntersectRect)
Nop out the test/jne after each of these calls and you can just fly through the pipes.
|
The score handling is done here:
Code: |
HackyBird.exe+312D FF 86 94 00 00 00 inc [esi+00000094]
HackyBird.exe+3133 81 BE 94 00 00 00 E7 03 00 00 cmp [esi+00000094], 000003E7
|
The game looks for a score higher than 999 to consider it 'won':
Code: |
.text:00403129 mov byte ptr [edi+14h], 1
.text:0040312D inc dword ptr [esi+94h]
.text:00403133 cmp dword ptr [esi+94h], 3E7h
.text:0040313D jle short loc_4031A2
|
The win message is then decoded based on the game information:
Code: |
HGDIOBJ __thiscall sub_4024E0(_DWORD *this, HDC *a2)
{
_DWORD *v2; // esi
int v3; // ecx
int v4; // edx
int v5; // eax
HMODULE v6; // edi
unsigned int v7; // ecx
int v8; // eax
unsigned int v9; // edx
char *v10; // edi
int v11; // eax
unsigned int v12; // eax
unsigned int v13; // eax
unsigned int v14; // eax
unsigned int v15; // eax
_BYTE *v16; // ecx
int i; // edx
int v18; // ecx
void *v19; // ecx
void *v20; // ecx
HGDIOBJ result; // eax
int v22; // [esp-10h] [ebp-C8h]
int v23; // [esp-Ch] [ebp-C4h]
unsigned int v25; // [esp+14h] [ebp-A4h]
WCHAR chText[2]; // [esp+18h] [ebp-A0h] BYREF
int v27[2]; // [esp+20h] [ebp-98h] BYREF
int v28; // [esp+28h] [ebp-90h]
unsigned int v29; // [esp+2Ch] [ebp-8Ch]
int v30[4]; // [esp+30h] [ebp-88h] BYREF
HGDIOBJ ho[2]; // [esp+40h] [ebp-78h] BYREF
__int128 Src[3]; // [esp+48h] [ebp-70h] BYREF
__int128 v33; // [esp+78h] [ebp-40h] BYREF
char v34[2]; // [esp+88h] [ebp-30h] BYREF
int v35; // [esp+8Ah] [ebp-2Eh]
__int64 Source; // [esp+8Eh] [ebp-2Ah] BYREF
int v37; // [esp+96h] [ebp-22h]
int v38; // [esp+9Ah] [ebp-1Eh]
char v39[10]; // [esp+9Eh] [ebp-1Ah]
int v40; // [esp+B4h] [ebp-4h]
v2 = this;
*(_QWORD *)ho = 0i64;
sub_4014E0(ho, 0x67u);
v40 = 0;
sub_401650(v22, v23, ho[0], ho[1]);
v3 = v2[1];
v4 = v2[2];
v30[2] = v3 + v2[3];
v5 = v2[4];
v30[0] = v3;
v30[3] = v4 + v5;
v30[1] = v4;
sub_4017F0(v30, v3);
v6 = GetModuleHandleW(0);
v7 = -1;
v8 = *((_DWORD *)v6 + 15);
v25 = *(_DWORD *)((char *)v6 + v8 + 28);
v9 = 0;
if ( v25 )
{
v10 = (char *)v6 + *(_DWORD *)((char *)v6 + v8 + 44);
do
{
v11 = (unsigned __int8)v10[v9++];
v12 = ((v11 ^ v7) >> 1) ^ -(((unsigned __int8)v11 ^ (unsigned __int8)v7) & 1) & 0xEDB88320;
v13 = (((v12 >> 1) ^ -(v12 & 1) & 0xEDB88320) >> 1) ^ -(((unsigned __int8)(v12 >> 1) ^ -(v12 & 1) & 0x20) & 1) & 0xEDB88320;
v14 = (((v13 >> 1) ^ -(v13 & 1) & 0xEDB88320) >> 1) ^ -(((unsigned __int8)(v13 >> 1) ^ -(v13 & 1) & 0x20) & 1) & 0xEDB88320;
v15 = (((v14 >> 1) ^ -(v14 & 1) & 0xEDB88320) >> 1) ^ -(((unsigned __int8)(v14 >> 1) ^ -(v14 & 1) & 0x20) & 1) & 0xEDB88320;
v7 = (v15 >> 1) ^ -(v15 & 1) & 0xEDB88320;
}
while ( v9 < v25 );
v2 = this;
}
v34[0] = *((_BYTE *)v2 + 20);
v34[1] = BYTE1(v2[5]);
Src[0] = xmmword_41B000;
v35 = ~v7;
Src[1] = xmmword_41B010;
Src[2] = xmmword_41B020;
v27[0] = -60482407;
v27[1] = 1304311949;
v28 = 800007618;
v29 = -1803913205;
Source = 0x5EE4B694991ED411i64;
v37 = -1657128498;
v38 = 1259390440;
*(_DWORD *)v39 = -83982270;
*(_DWORD *)&v39[4] = -57769309;
*(_WORD *)&v39[8] = -26640;
v33 = xmmword_41B030;
sub_4019F0(v34, v27);
v16 = (char *)&v33 + 14;
for ( i = 2; i < 64; ++i )
{
if ( *v16 != HIBYTE(v33) )
break;
*v16-- = 0;
}
*(_QWORD *)&v39[2] = 0x700000000i64;
WORD1(Source) = 0;
sub_401FB0((char *)&Source + 2, L"Courier", 7);
LOBYTE(v40) = 1;
v28 = 0;
v29 = 7;
chText[0] = 0;
sub_401FB0(chText, Src, wcslen((const unsigned __int16 *)Src));
sub_4018D0(a2, (int)v30, chText, v18, (wchar_t *)&Source + 1, 35);
if ( v29 >= 8 )
{
v19 = *(void **)chText;
if ( 2 * v29 + 2 >= 0x1000 )
{
v19 = *(void **)(*(_DWORD *)chText - 4);
if ( (unsigned int)(*(_DWORD *)chText - (_DWORD)v19 - 4) > 0x1F )
_invalid_parameter_noinfo_noreturn();
}
sub_4048D0(v19);
}
v28 = 0;
v29 = 7;
chText[0] = 0;
if ( *(_DWORD *)&v39[6] >= 8u )
{
v20 = *(void **)((char *)&Source + 2);
if ( (unsigned int)(2 * *(_DWORD *)&v39[6] + 2) >= 0x1000 )
{
v20 = *(void **)(*(_DWORD *)((char *)&Source + 2) - 4);
if ( (unsigned int)(*(_DWORD *)((char *)&Source + 2) - (_DWORD)v20 - 4) > 0x1F )
_invalid_parameter_noinfo_noreturn();
}
sub_4048D0(v20);
}
if ( ho[0] )
DeleteObject(ho[0]);
result = ho[1];
if ( ho[1] )
result = (HGDIOBJ)DeleteObject(ho[1]);
return result;
}
|
This is constructed and called via:
Code: |
.text:00403146 mov edx, [esi+94h]
.text:0040314C mov edi, eax
.text:0040314E add esp, 4
.text:00403151 mov [ebp-78h], edi
.text:00403154 mov dword ptr [edi], offset off_416F68
.text:0040315A mov ecx, [esi+4]
.text:0040315D mov [edi+4], ecx
.text:00403160 mov ecx, [esi+8]
.text:00403163 mov [edi+8], ecx
.text:00403166 mov ecx, [esi+0Ch]
.text:00403169 mov [edi+0Ch], ecx
.text:0040316C mov eax, [esi+10h]
.text:0040316F mov [edi+10h], eax
.text:00403172 mov dword ptr [edi], offset off_416F58
.text:00403178 mov [edi+14h], edx
.text:0040317B mov ecx, dword_41A4B4
.text:00403181 mov dword_41A4B4, edi
.text:00403187 test ecx, ecx
.text:00403189 jz short loc_40319F
.text:0040318B ; try {
.text:0040318B mov dword ptr [ebp-4], 4
.text:00403192 mov eax, [ecx]
.text:00403194 push 1
.text:00403196 call dword ptr [eax]
v2 = (int *)(*(v8 - 1) + v8[1] / 2);
if ( *(_DWORD *)(a1 + 24) + *(_DWORD *)(a1 + 32) / 2 >= (int)v2 )
{
*((_BYTE *)v8 + 20) = 1;
if ( (int)++*(_DWORD *)(a1 + 148) > 999 )
{
v16 = operator new(0x18u);
v17 = *(_DWORD *)(a1 + 148);
v18 = v16;
*v16 = &off_416F68;
v16[1] = *(_DWORD *)(a1 + 4);
v16[2] = *(_DWORD *)(a1 + 8);
v16[3] = *(_DWORD *)(a1 + 12);
v2 = *(int **)(a1 + 16);
v18[4] = v2;
*v18 = &off_416F58;
v18[5] = v17;
v19 = (int (__thiscall ***)(_DWORD, int))dword_41A4B4;
dword_41A4B4 = (int)v18;
if ( v19 )
{
v37 = 4;
LOBYTE(v2) = (**v19)(v19, 1);
v37 = -1;
}
v8 = v30;
}
}
}
|
Not going to spoil the flag message at the end given this is taken from a hack challenge site. You can figure out the rest/how to solve it from here.
The solution will look like this when completed properly:
https://i.imgur.com/csuw4Ii.png
There is a very simple way to defeat this once you understand how the message is being generated and what that function does in general.
_________________
- Retired. |
|
Back to top |
|
 |
v3rmin How do I cheat?
Reputation: 0
Joined: 19 Dec 2020 Posts: 6
|
Posted: Sat Dec 19, 2020 10:57 pm Post subject: |
|
|
Hi thankyou very much for your response.
So you would need to just score one point after changing the value/patching cmp fo rather equal 999, and then once that is done all you need to do is score 1 point in the game, to get the flag and win?
Thanks!
|
|
Back to top |
|
 |
atom0s Moderator
Reputation: 204
Joined: 25 Jan 2006 Posts: 8577 Location: 127.0.0.1
|
Posted: Sat Dec 19, 2020 11:37 pm Post subject: |
|
|
v3rmin wrote: | Hi thankyou very much for your response.
So you would need to just score one point after changing the value/patching cmp fo rather equal 999, and then once that is done all you need to do is score 1 point in the game, to get the flag and win?
Thanks! |
Would suggest reviewing the code of the message display; as your theory goes against something it does specifically in regards to editing functions.
_________________
- Retired. |
|
Back to top |
|
 |
v3rmin How do I cheat?
Reputation: 0
Joined: 19 Dec 2020 Posts: 6
|
Posted: Sun Dec 20, 2020 12:28 am Post subject: |
|
|
Oh right I see, another question I have, in using cheatengine with this task,
For example as you showed in the first step:
Code: | HackyBird.exe+30DC (call IntersectRect) |
When I use the "Go to Address" ( CTrl+G) in cheatengine to find the address in the memory viewer, however all the addresses have Opcodes as "??"
As I searched for this address: 30DC
Why is that? And how would you go about fixing it?
Thanks!
|
|
Back to top |
|
 |
atom0s Moderator
Reputation: 204
Joined: 25 Jan 2006 Posts: 8577 Location: 127.0.0.1
|
Posted: Sun Dec 20, 2020 12:44 am Post subject: |
|
|
HackyBird.exe+30DC means to use the base address of 'HackyBird.exe' and add the offset 30DC to it. So if the base address is 0x00400000 then it means the address would be 0x004030DC.
_________________
- Retired. |
|
Back to top |
|
 |
v3rmin How do I cheat?
Reputation: 0
Joined: 19 Dec 2020 Posts: 6
|
Posted: Sun Dec 20, 2020 3:09 am Post subject: |
|
|
atom0s wrote: | HackyBird.exe+30DC means to use the base address of 'HackyBird.exe' and add the offset 30DC to it. So if the base address is 0x00400000 then it means the address would be 0x004030DC. |
Hi thankyou very much for your response.
I managed to use the NOP on the instructions and now I am able to go through the green poles.
However what exactly is the win function dong is it using CRC on a string?
Also would it not be possible to change the value of 999 to a lower number say for example 5 and be able to win it that way and produce the flag?
.text:00403133 cmp dword ptr [esi+94h], 3E7h
Or would the CRC get in the way?
Thanks!
|
|
Back to top |
|
 |
atom0s Moderator
Reputation: 204
Joined: 25 Jan 2006 Posts: 8577 Location: 127.0.0.1
|
Posted: Sun Dec 20, 2020 1:59 pm Post subject: |
|
|
Given this is from a hack challenge site, I don't want to spoil/ruin things for others. The point of those sites is to work on your skills and learn. I'll explain a few things more, but the goal here is for you to read and understand the reversed information/debug what's going on and see what the game is doing.
In the 'win' function I posted above, the first part is:
Code: |
v6 = GetModuleHandleW(0);
v7 = -1;
v8 = *((_DWORD *)v6 + 15);
v25 = *(_DWORD *)((char *)v6 + v8 + 28);
v9 = 0;
if ( v25 )
{
v10 = (char *)v6 + *(_DWORD *)((char *)v6 + v8 + 44);
do
{
v11 = (unsigned __int8)v10[v9++];
v12 = ((v11 ^ v7) >> 1) ^ -(((unsigned __int8)v11 ^ (unsigned __int8)v7) & 1) & 0xEDB88320;
v13 = (((v12 >> 1) ^ -(v12 & 1) & 0xEDB88320) >> 1) ^ -(((unsigned __int8)(v12 >> 1) ^ -(v12 & 1) & 0x20) & 1) & 0xEDB88320;
v14 = (((v13 >> 1) ^ -(v13 & 1) & 0xEDB88320) >> 1) ^ -(((unsigned __int8)(v13 >> 1) ^ -(v13 & 1) & 0x20) & 1) & 0xEDB88320;
v15 = (((v14 >> 1) ^ -(v14 & 1) & 0xEDB88320) >> 1) ^ -(((unsigned __int8)(v14 >> 1) ^ -(v14 & 1) & 0x20) & 1) & 0xEDB88320;
v7 = (v15 >> 1) ^ -(v15 & 1) & 0xEDB88320;
}
while ( v9 < v25 );
v2 = this;
}
|
This is a CRC check. This is ensuring the memory of the code section has not been tampered with.
More specifically:
Code: |
v6 = GetModuleHandleW(0);
|
This is getting the module base of the current process (HackyBird.exe).
Code: |
v8 = *((_DWORD *)v6 + 15);
v25 = *(_DWORD *)((char *)v6 + v8 + 28 );
|
This is reading two values from the files PE header.
*((_DWORD *)v6 + 15) is visually misleading if you don't understand pointer casting in C/C++, this is actually trying to read:
HackyBird.exe + 0x3C
This would be 0x0108 in this case.
This points to the files e_lfanew value of the IMAGE_DOS_HEADER.
Next, *(_DWORD *)((char *)v6 + v8 + 28 ) is then looking inside of the IMAGE_NT_HEADERS at:
HackyBird.exe + 0x0108+ 0x1C
This points to the IMAGE_NT_HEADERS -> IMAGE_OPTIONAL_HEADER -> SizeOfCode which in this files case is currently: 0x10800
Next, when the CRC part starts, it first begins at:
Code: | v10 = (char *)v6 + *(_DWORD *)((char *)v6 + v8 + 44); |
This points to the IMAGE_NT_HEADERS -> IMAGE_OPTIONAL_HEADER -> BaseOfCode which in this files case is currently: 0x1000
This points to the virtual address of the code section (.text).
I won't give you more than that at this point, this is basically giving you the answer now. Take the time to read and understand what this function is doing and why your current approach is going to always be a problem/fail.
_________________
- Retired. |
|
Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You cannot download files in this forum
|
|