Single machine Lianliankan crack

QQ Lianliankan stand-alone version: qqlk.exe

Title:

1. Find the exe of the program itself

2. Remove the advertisement in the program

3. Write a QQ plug-in

Tools used:

OD

PEID

ImpREC

VS2013

Test environment:

Virtual machine win7 platform 32-bit

1. Initial interface

  We found that opening a real program went through two layers of advertising.

  When we click directly on the real program

  Qqllk.exe (big advertisement) - > qqllk.ocx (small advertisement) - > kyodai.exe (real code, but its code has been extracted). The routine is layer by layer

  1.1: use PE tool to query basic information

Remember: when we get a program, we first use PE tools for comprehensive analysis and try to collect more information

  The program is an MFC program written by VC6

Open OD and find that the code of wmain function is wrong

2: OD tracker

Idea:

Through testing the software, we found that the program is to open two advertisements and then run the real program.

Then go to the CreateProcessA or W breakpoint

2.1: big advertisement (QQ watch starter)

  Summary:

Find big ads and call small ads

2.2: small advertisement (Baidu connection)

Idea:

Directly down CreateProcessA or W breakpoint

Suspicious place:

   The thread suspension here is very suspicious. We opened the main program directly and found that the PE file was modified. However, opening the main program indirectly through advertising can run normally. We can suspect that the PE file code was restored (small advertising Baidu connection).

  2.3 attach the main program with OD when the program is suspended (preferably before restoring the thread)

  We found that the software is written in a typical VC6.0:

  Find wmain function

  At this time, the code of wmain has not been repaired

  2.4 when we run through advertisement 2 (Baidu connection), we attach it again

  Summary:

  We can speculate that the program can run normally only through the repair of these two advertisements. Because we found that the thread stopped in the second advertisement,

    When the ad 2 (Baidu connection) program is run, the code is added and the repair is completed. Then we can judge that the program is repaired between the suspended thread and the recovery thread through ad 2 (Baidu connection).

   Through the above features:

   We can boldly infer the API used by the program:

Generally, remote modification of the other party's memory data is used

//1. Open process

   OpenProcess open process

//2. Write to the opposite process space

Parameter Description:

BOOL WINAPI WriteProcessMemory(
  _ In_     HANDLE hProcess,                        // process handle
  _ In_     LPVOID lpBaseAddress,             // Pointer to the data to be written
  _ In_     LPCVOID lpBuffer,                        // buffer address
  _ In_     SIZE_T nSize,                                   // Bytes to write
  _ Out_    SIZE_T *lpNumberOfBytesWritten      // Returns the actual read and write bytes
);

   SuspendThread suspends the thread

  ResumeThread   Recovery thread

be careful:

Handling method of OD attachment failure

  2.5: open two, one of which OD attaches kyodai.exe to the next breakpoint in winmain, so as to know when it has been modified

  2.6: open two OD, one of which is attached to ad 2 (Baidu link), and the WriteProcessMemory breakpoint

  And remember the modified address: 43817A

  Go to another additional kyodai.exe main program to view the modified place (just inside the wmain function call)

  Follow up wmaincall and find that the code has been fixed

2.7: you can Dump the main program after the program executes WriteProcessMemory

2.7.1: or Dump the thread before resuming the thread

  Because the dump at the OEP is relatively clean without pollution, remember that the OEP address 438048 - base address 400000 = 38048

2.8: repair IAT table with ImportREC

  Go to the file that you just used the OD plug-in dump to overwrite it

2. Remove the advertisement in the program

 

3. Write a QQ plug-in:

Reverse search is for data, as long as you find the code that operates the map data

3.1: first judge what program is written

VC6 release dynamics

  3.2: use PE tools to analyze and find key API s

rand key API

  3.3: start at rand

  We found that there are many places where rand is called, and we can only filter and find the most similar places again and again

No key code found in the first place, pending

  The second. kml is dedicated to storing landmark files, and it is suspicious with memcpy

  Important data:

483AC8                      Map template

12BB50                      Map template (483AC8 memory copy to it)

[Esi+0x195C]=12BB50   Map template

Map width 19

Map height 11

  Follow up call

  call function:

① : request heap space

② : randomly generate data from heap space

③ : give the randomly generated data in the heap space to the 12BB50 map template (fill in all non-zero data)

④ : free heap space

3.4 in order to judge whether the map game data operates one map or multiple maps, directly start the game and observe the 12BB50 data

  We observe that the map data is just D1 (209 = width 19 * height 11)

Idea:

     We found that a prop is that the compass automatically helps us find two places that can be eliminated. We can start by modifying the compass without going to the inverse algorithm.

realization:

    Drop a hardware breakpoint at the map data

  Stack return

  The value stored in the stack is not fixed, so you need to find some fixed values

 ESI = [45DCF8]

  Get address

 

 MOV ECX,DWORD PTR DS:[ESI+0x1E84]

  Get address=

ECX = [ESI+0X1E84] map buffer = [ECX+4] map start = map buffer + 8  

ECX = [[45DCF8]+ 0x1E84] 

summary   dd [[[45DCF8]+0x1e84]+4]+8

  3.3 inject DLL to realize the call of analog compass

/*        

0041DE53 | .  8D8E 94040000   lea ecx, dword ptr ds : [esi + 0x494]

0041DE59 | .  52                           push edx

0041DE5A | .  53                           push ebx

0041DE5B | .  53                           push ebx

0041DE5C | .FF50 28                    call dword ptr ds : [eax + 0x28]

*/

_asm

{

mov eax,0x45DCF8

mov eax, dword ptr[eax]

lea ecx, dword ptr[eax+0x494]

push 0xf0

push 0

push 0

mov eax,0x0041E691

call eax

}
 

3.4 finding array subscripts for compass positioning

[Ebp-0x28]129d8c

[Ebp-0x20]129d94

Then we directly write the breakpoint to the hardware under the two parameters passed in from the outside

Found it broken

  Let's simulate the call inside

Compare our program

  We use dll injection to simulate

  The following codes are specifically implemented:

//Analog call code

//We found that there is no base address for esi+0x19F0

//But esi+0x19f0 is the same as [ESI+0X1E84]

//Then we use esi+0x1E84(esi has base address) instead of esi+0x19f0

/*

0041E75E > \8B8E F0190000 mov ecx, dword ptr ds : [esi + 0x19F0];  ecx = this Pointer first address virtual function mark + 4 map array first address; Case F0(BM_GETCHECK) of switch 0041E749

0041E764   .  8D45 D8       lea eax, dword ptr ss : [ebp - 0x28];  POINT structure

0041E767   .  50            push eax

0041E768   .  8D45 E0       lea eax, dword ptr ss : [ebp - 0x20];  POINT

0041E76B   .  50            push eax

0041E76C.E8 CEAA0000   call dumo_.0042923F;  Returns the coordinates of two flags that can be eliminated

*/

POINT FirstDot = { 0 };                                        //XY coordinate point of the first Xiaole

POINT SecondDot = { 0 };                                    //XY coordinate point of the second Xiaole

MessageBox(0, L"Found the injection point", 0, 0);

_asm{

           mov eax, 0x45DCF8

mov eax, dword ptr[eax]                     //Take the value 12A1F4 in 45DCF8

mov ecx, dword ptr[eax + 0x1E84]   //Take the value 013A83D0 in 12C078. The first four bytes in it are virtual function table + 4 is the first address of the map

//The above three sentences are equivalent to mov ecx,[esi+0x19F0]

lea eax, dword ptr[FirstDot]

push eax

lea eax, dword ptr[SecondDot]

push eax

mov eax, 0x42923F

call eax                                                   //The function returns two subscripts that can eliminate chess pieces

}
 

3.5 now that you have all the array subscripts, you can find the call API to eliminate

Just simulate these six parameters

 //Analog code

//6 parameters

//00129bb8 00000000

//00129bbc 0012bb50 map header address

//00129bc0 00129bec chess piece address A

//00129bc4 00129bf4 chess piece address B

//00129bc8 019b8400 the address is 13683D0+30

//formula

//mov eax, 0x45DCF8

//mov eax, dword ptr[eax]                   

//mov ecx, dword ptr[eax + 0x1E84]


//00129bcc 00000004 fixed value



push 4                                                                        //Fixed value                                                                                                                

mov ebx,ReEcx

add ebx,0x30

push ebx                                //13683D0+30

lea eax,[FirstDot]                      //Coordinate A

lea ebx, [SecondDot]                                        //Coordinate B

push ebx

push eax



/******************Get the first address of 12BB50 map***************************/

mov eax, 0x45DCF8

mov ecx, dword ptr[eax]

lea eax, dword ptr[ecx + 0x1e84]

mov eax, dword ptr[eax]

mov eax, dword ptr[eax + 4]

push eax                                                        

/*******************Get the first address of 12BB50 map**************************/

push 0                              //Dead value 0

mov eax,0x41C68E                    

call eax                           //call immediate is not supported
 

Keywords: C++ Windows WPF

Added by biba028 on Tue, 07 Dec 2021 12:25:49 +0200