Reverse analysis of the CrackMe series - Analysis of the registration code algorithm of CrackMe004

Reverse analysis of CrackMe series - CrackMe004 registration code algorithm analysis

The content of this article follows the previous work and records my analysis process and ideas at each step. Because the content is long, I will write a separate article.
(The CrackMe resources in this series are all from I Love Cracking Network ).

18. Through the previous analysis , it is initially believed that the generation algorithm is hidden in the two infinite loops just mentioned. Let’s analyze them one by one:

Insert image description here
Insert image description here
19. Start single-step execution from 00457FDC, point edx to [ebp-C] at 00457FDC, we monitor [ebp-C], F8 continues to execute, and find that after the call 00423348 function is called, the data in the stack is changed Now, the data of [ebp-C] becomes the username entered by the user “wwwwwwwwwwwwww

Insert image description here
20. Continue the execution and find that [ebp-C] is passed as a parameter to the following function call call 00403B7C, but we do not know what this function does; don’t worry, continue to analyze , eax is operated immediately after calling the function, which means that eax should store the return value of the above function. We check eax. The value of eax is 0x0000000C, and the value is 12, which is exactly the length of the user name we entered. ;Then we can guess the function of the above function: calculate the length of the string entered into the user name. Next, do the addition: eax=eax+1E, the result here is 0x0C+0x1E=0x2A.

Insert image description here
21. Continue to execute, edx points to [ebp-8], observe [ebp-8] and the register, and find that the content of [ebp-8] has changed, and a string "42" is stored. How can it run? What about "42"? Just when I pressed F7 to take a closer look, I suddenly discovered that the decimal value of the result "0x2A" just calculated by eax is: 2*16+10=42. It turns out that this function is a function that converts hexadecimal to decimal (the operating parameter is eax="0x2A", and edx is used to store the result).

Insert image description here
22. Continue the execution and find that new variables appear. edx points to [ebp-10] and is passed as a parameter to the following function call (call 00423348). Why does this function look so familiar? Looking up, in 00457FE5 is also called, and the user obtains the user name entered by the user; continuing the execution, it is found that the same operation is still performed, except that the user name entered by the user is stored in [ebp-10].

Insert image description here
23. Continue the analysis, push the user name onto the stack, and then call the function that converts hexadecimal to decimal, but the parameters have changed, eax=ebx (the initial value of ebx is 0), and edx points to [ebp- 14], since eax=0, there is nothing in the memory address pointed to by [ebp-14]:

Insert image description here
24. Continue execution, [ebp-14] is pushed onto the stack, new variables appear, eax points to [ebp-4], observe it and continue execution, and find that after the following function call (call 00403C3C), [ebp -4] has changed, and its content has become "42wwwwwwwwwwww0"; it looks like a string concatenation has been performed, the "42" just calculated, the entered user name "wwwwwwwwwwww" and a "0".

Insert image description here
25. Continue execution, ebx=ebx+1, and then compare ebx with 0x13 (value 19). If it is less than 0x13, jump back and continue execution. Σ(っ°Д ° ;)っIt turns out that the loop just now is not an infinite loop! ! ! (I obviously held down F8 and didn’t release it. When I saw the loop, it felt like an endless loop.) Embarrassing! ! ! ,   , 26.
 
However, it’s not a big problem, hahahaha… continue the analysis. Since ebx is used for judgment, we mainly focus on the parts related to ebx, that is, [ebp-14] and [ebp-4], observe the data changes of these two memories, and repeat the cycle.
 
27. It is found that there is still no data in the memory pointed to by [ebp-14], but the data in [ebp-4] has changed, from "42wwwwwwwwwwww0" to "42wwwwwwwwwwww1"; after looping again, it becomes "42wwwwwwwwwwww2" "; Loop again and it becomes "42wwwwwwwwwwww3"; I seem to understand something. I guess the memory data pointed to by [ebp-4] when jumping out of the loop should be "42wwwwwwwwwwww18". We break at the statement immediately following the loop. (That is, address 00458031)

Insert image description here
28. After interrupting, F9 continues to execute. After interrupting, it is found that the memory data pointed to by [ebp-4] is indeed "42wwwwwwwwwwww18", and at the same time, the data pointed by [ebp-14] changes to "18".

Insert image description here
29. The cmp here performs a comparison. Why are none of the values ​​just calculated used? ╰( °▽° )╯; Compare the memory data pointed to by [esi+30C] in cmp with 0x85 (esi=010DB1970 at this time, [esi+30C] (address 01DB1C7C) There is nothing (;′⌒`) )

Insert image description here
30. So where does esi come from? I had to go back and monitor esi, and found that there were no esi-related operations in the loop just now. Looking up, I found the suspect's address 00457FCA, which happened to be not far from where we just cut off. According to the eax assignment, we got:

Insert image description here
31. When we execute to the next break point (00457FB8), we find that eax at this time is 01DB1970, which means that eax has been assigned a value before running here. This is not the real suspect. What can be done?
 
32. Look no further! ! Since the value is assigned before this module is called, we can just find the module before the call:
      keep running single-step (F8) to retn, until returning to a new code block, first encounter the first retn: (General situation Just use ctrl+F9, but the program will not stop here, it’s so weird (⊙﹏⊙) )

Insert image description here
33. Continue the execution and find that it jumps to a short distance below, which is a bit strange:

Insert image description here
34. It is found that there is no operation to modify eax, continue tracking until retn, check the stack, and find that the jump returns to address 00424658:

Insert image description here
35. Tracked to 00424658:

Insert image description here
36. It is found that the previous one is a function call. Although there is a jump here, since it is the address returned from the stack, it can only be carried out by the function call branch. In other words, the one we just analyzed Most of them are implemented in the previous function. Okay, we are one step closer to the real suspect. We continue to analyze and find an eax operation (mov eax, dword ptr [ebx+10C]). Without saying anything else, we disconnect at address 0042464C:

Insert image description here
37. It is found that [ebx+0C] at this time is the entry address of a function. The entry address of the function will not change, which means that tracking here is meaningless. How to fix it? Memory breakpoints to see who changed the values ​​in memory. Continue to click on the gray box and find that the program will not be interrupted, indicating that the serial number detection process has ended at this time; try modifying the serial number and find that the program is interrupted:

Insert image description here
38. Observe all memory contents and stacks, and then perform single-step debugging. It is found that when the function call 00423348 is called at 00457D69, the value of [ebp-28] changes from 00000000 to the entered user name "wwwwwwwww", and at the same time, the Lots of information related to username and entered serial number:

Insert image description here
Insert image description here
39. Continue execution and find that the user name is assigned to eax. After the function call at 00457D76, eax=0x0C (number 12), which looks familiar. The user name we entered is exactly 12; then the function of this function is to calculate Enter the length of the username; why does this part of the code look so familiar? Looking at the notes, I found that the function here is the same as the code block analyzed in step 21. It should be the same function, but some of the local variables and constants in it have occurred. Changes; After analyzing this code, I found that there is still no substantive operation like the previous code block.

  • Step 21:
    Insert image description here
  • Now
    Insert image description here

 
 
40. It’s a bit nerve-wracking. Let’s ignore this memory breakpoint for now. Let’s look at the next memory breakpoint. At 00457EF5, we find a similar code part to step 18 , but there is an extra cmp and jump in it. Here is the code block. It is almost exactly the same as the code block at step 18, and there is no substantive operation:

Insert image description here
41. I don’t know where to start. Look at the place where we first set the memory breakpoint. There is another string:
Insert image description here
42. Let’s set a memory breakpoint on it and see what happens after modifying the registration code:

Insert image description here
43. Continuing the analysis, another string "Blackhead Sun Bird17dseloffc-012-OK wwwwwwwwwwww" was found in [ebx+318] ; **"Blackhead Sun Bird" is the string prompted by the program interface, and "17" is in front It has appeared, "dseloffc-012-OK" is the string we tracked, and it is also directly initialized. "wwwwwwwwww"** is the entered user name, and we guess it is the correct serial number:

Insert image description here
44. Test with the new string you just got, success! :

Insert image description here
45. Then the registration code is a concatenation of several characters:“黑头Sun Bird“+“17”+“dseloffc-012-OK”+“wwwwwwwwwwww”. Among them, only the number "17" was obtained. We looked back and found that it was the data in the memory of [ebx+2F8] . We called itLAdd 0x05 and convert to decimal; that is:

  • Registration code = "黑头SunBird"+"L+5"+"dseloffc-012-OK"+username

Insert image description here
46. ​​However, there is no modification of [ebx+2F8] (memory [01D81C68]) data in the code modification part, so we set a memory breakpoint (write) on it

Insert image description here
47. It is found that the value of [01D81C68] is calculated by the function at address 00457E59, interrupt it, and then analyze it. There are still function calls, continue to analyze, remember that ecx=0, edx=0E at this time:

Insert image description here
48. Continue to follow and find that the function at 00424308 modifies variable 4, and eax is obtained by assigning value to variable 4:

Insert image description here
49. Follow up and continue reading. We find that the code block in this part is very long. We directly set a memory breakpoint (write) on variable 4.

Insert image description here
50. After modifying the user input name, the break reaches 0042705F:

Insert image description here
51. It was found that the eax value was returned by a function in the user32.dll library;

Insert image description here
52. Gave up. Although I suspected it was the length of the username when I first saw the number, I could confirm it through multiple sets of tests, such as,

  • Enter 123, L becomes 3;
    enter 1234, L becomes 4;
    enter 12345; L becomes 5;
    enter wwwwww, L becomes 6;
    enter wwwwwww, L becomes 7

It can be inferred that L is the length of the input username.
Therefore, the entire serial number generation algorithm is:
Registration code = "Black Head Sun Bird" + "Enter the length of the user name + 5" + "dseloffc-012-OK" + the entered user name
 
53. Summary:

  • The program author has designed many interfering code breaks, which are the steps 18 to 28 of the previous analysis. In fact, there are similar interfering code breaks in other places during the entire analysis process.
  • The entire analysis process is relatively redundant and not concise. It mainly records the ideas and analysis process during the entire analysis process.
  • After looking at other people's analysis, it is much faster to directly use the Delphi language decompiler to analyze. Just start the analysis directly from the entry addresses of several specific functions.

Guess you like

Origin blog.csdn.net/weixin_39561364/article/details/108246298