Cheat Engine Forum Index Cheat Engine
The Official Site of Cheat Engine
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 


FlappyBird crackme native win32 to try and win/RE

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> General programming -> Crackmes
View previous topic :: View next topic  
Author Message
v3rmin
How do I cheat?
Reputation: 0

Joined: 19 Dec 2020
Posts: 6

PostPosted: Sat Dec 19, 2020 7:38 am    Post subject: FlappyBird crackme native win32 to try and win/RE Reply with quote

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
View user's profile Send private message
atom0s
Moderator
Reputation: 160

Joined: 25 Jan 2006
Posts: 8160
Location: 127.0.0.1

PostPosted: Sat Dec 19, 2020 2:41 pm    Post subject: Reply with quote

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
View user's profile Send private message Visit poster's website
v3rmin
How do I cheat?
Reputation: 0

Joined: 19 Dec 2020
Posts: 6

PostPosted: Sat Dec 19, 2020 10:57 pm    Post subject: Reply with quote

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
View user's profile Send private message
atom0s
Moderator
Reputation: 160

Joined: 25 Jan 2006
Posts: 8160
Location: 127.0.0.1

PostPosted: Sat Dec 19, 2020 11:37 pm    Post subject: Reply with quote

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
View user's profile Send private message Visit poster's website
v3rmin
How do I cheat?
Reputation: 0

Joined: 19 Dec 2020
Posts: 6

PostPosted: Sun Dec 20, 2020 12:28 am    Post subject: Reply with quote

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
View user's profile Send private message
atom0s
Moderator
Reputation: 160

Joined: 25 Jan 2006
Posts: 8160
Location: 127.0.0.1

PostPosted: Sun Dec 20, 2020 12:44 am    Post subject: Reply with quote

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
View user's profile Send private message Visit poster's website
v3rmin
How do I cheat?
Reputation: 0

Joined: 19 Dec 2020
Posts: 6

PostPosted: Sun Dec 20, 2020 3:09 am    Post subject: Reply with quote

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
View user's profile Send private message
atom0s
Moderator
Reputation: 160

Joined: 25 Jan 2006
Posts: 8160
Location: 127.0.0.1

PostPosted: Sun Dec 20, 2020 1:59 pm    Post subject: Reply with quote

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
View user's profile Send private message Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> General programming -> Crackmes All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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


Powered by phpBB © 2001, 2005 phpBB Group

CE Wiki   IRC (#CEF)   Twitter
Third party websites