Reverse engineering No. 007: Bridging the gap between CM4 verification mechanisms (Part one)

Source: Internet
Author: User
Tags uppercase letter

First, preface

This article is the last of the reverse Analysis CM4 series, I will be the game's serial number verification mechanism analysis completed, and then write the registration code generator.

Ii. Analysis of the second verification cycle

Continue with the contents of the previous article, and come to the following code:


Figure 1

The code above does not have a particular need to pay attention to, just know that the next loop needs to be executed 4 times. Here is the important validation section:


Figure 2

This is the registration code in the second set of four characters of the generated code, mainly using [ebp+var_20] to operate, the result as a string offset value, thereby obtaining the registration code. Looking back, here [ebp+var_20] is the remainder of the previous operation, it can be seen that the game's validation process of the residual operation is more. The next two pieces of code are more like the code in Figure 2:


Figure 3


Figure 4

The above two pieces of code in the remainder and get the corresponding characters, but also changed the [ebp+var_20], [ebp+var_2c] and [ebp+var_38] values, for the next operation, because it is relatively simple, here will not repeat.

At this point, CM4 's registration code verification mechanism thoroughly analyzed, then you can begin to write the registration code generator.

Third, write the registration code generatorCombined with previous analysis, it's easy to write a keygen. But note that when we generate the registration code, we need to use the "Cm4.epe" This file, we need to place the two in the same directory, so that the Registrar can easily read the "password" in the contents of the operation, the code is as follows:

#include <stdio.h> #include <windows.h>////////////////////////////////////////////////////////////// The Getnum function is used to calculate the DWORD size at the corresponding offset value in the Cm4.epe file//hexadecimal value for the next operation, which has a parameter var, save//has an offset value/////////////////////////////////         DWORD Getnum (DWORD dwOffset) {HANDLE hfile = Null;dword dwsignum = 0;            The contents of the DWORD byte that is used to hold the offset position DWORD dwnum = 0; Constant is 0, as the parameter of ReadFile//open a file named Cm4.epe, the file and the program should be in the same directory hfile = CreateFile ("Cm4.epe", Generic_read, 0, NULL , Open_existing, File_attribute_normal, NULL);//If the file fails to open, an error message is prompted and the if (hfile = = Invalid_handl          E_value) {printf ("Could not open cm4.epe\n");    return 0;} Sets the file pointer to the specified position SetFilePointer (hfile, DwOffset, 0, File_begin);//reads the hexadecimal code starting at the position of the file pointer, reads a length of 4 bytes (DWORD) ReadFile (hfile,    &dwsignum, sizeof (DWORD), &dwnum, NULL); CloseHandle (hfile); return dwsignum;}             int main () {int A, b, C;          Used to control the number of cycles int i, j, M, N; Used to save the first set of validationsCode of four ASCII code value int count = 10;              Number of groups used to save the generated registration code int TMP[4];                The ASCII code used to temporarily save the first four-digit verification code minus 0x30 or 0x37 after the value int temp;                 Used to save a temporary operation result int edx;               The remainder of the save operation, DWORD Num; Used to save the hexadecimal code at the corresponding offset at Cm4.epe dword var_9c = 0x800000;            This is a fixed value, as the divisor DWORD var_14 after verification;        The result of saving the final operation of the first loop algorithm DWORD var_20 = 0;dword var_2c = 0;dword var_38 = 0; These three variables are used to hold the result of the operation in the second loop algorithm char reg[4][4] = {"0"};//this two-dimensional array holds the resulting registration code char LETTER[37] = {"0123456789ABCDEFGHIJKLMNOPQRSTUV WXYZ "};//alphabet, used to generate the registration code////////////////////////////////////////////////////////////////here is the first verification loop of the registration code algorithm, here through the four-heavy loop, to continually//verify a combination of different ASCII values, that is, from 0000 to zzzz, resulting in//first set of verification codes (4 characters)////////////////////////////////////////////////////// This loop generates the first character for the first set of verification codes for (i = <=; I, i++) {if (I >= && i <=) continue;//if the registration code is Number, minus 48if (i >= && i <=) {tmp[0] = i-48;} If the registration code is an uppercase letter, subtract 55else{tmp[0] = i-55;} This loop generates the second character for the first set of verification codes for (j = 48; J <= 90; J + +) {if (J >= && J <=) continue;//If the registration code is a number, subtract 48if (J >=, && J <=) {tmp[ 1] = j-48;} If the registration code is uppercase, subtract 55else{tmp[1] = j-55;}     This loop generates the third character of the first set of verification codes for (M = <=; M-m++) {if (M >= && m <=) continue;//minus 48 If the registration code is a number    if (M >= && m <=) {tmp[2] = m-48;} If the registration code is uppercase, subtract else{tmp[2] = m-55;} This loop generates the fourth character for the first set of verification codes for (n = <=; n n++) {if (n >= && n <=) continue;//If the registration code is a number, subtract 4        8 if (n >= && n <=) {tmp[3] = n-48;}    If the registration code is uppercase, subtract else{tmp[3] = n-55;}                        var_14 = 0;//is calculated according to the algorithm for (a = 3; a >= 0; a--) {var_14 *= 36; Var_14 + = Tmp[a];}                        if (var_14%!! = 0) {//LOC_4132CB Num = Getnum (var_14); var_20 = Num% Var_9c;temp = var_20;temp%= 36;if (temp = = 0) {continue;}                            else{//loc_41330f Num = Getnum (var_20);    var_2c = Num% var_9c;temp = var_2c;temp%= 36;if (temp = = 0) {continue;}                                else{//loc_413353 Num = Getnum (VAR_2C);    var_38 = Num% var_9c;temp = var_38;temp%= 36;        if (temp = = 0) {continue;} else{//First group (top four) registration code verification completed and assigned value reg[0][0] = i; Reg[0][1] = j; Reg[0][2] = m; REG[0][3] = n;////////////////////////////////////////////////////////////////Here is the second verification loop of the registration code algorithm, where the result of the previous operation is passed,//                                    The remainder (edx) is calculated as an offset from the letter[] alphabet, thus generating//registering the code character////////////////////////////////////////////////////////////// LOC_4133C5, the second loop algorithm for (b = 0; b < 4; b++) {c = 1;edx = var_20% 36;    REG[C][B] = letter[edx];c + = 1; temp = var_20/36;var_20 = Temp;edx = var_2c% 36; REG[C][B] = letter[edx];c + = 1;temp = var_2c/36;var_2c = Temp;edx = var_38% 36; Reg[c][b] = Letter[edx];temp = var_38/36;var_38 = temp;}    Output the registered code for (a = 0; a <= 3; a++) {for (b = 0; b <= 3; b++) {printf ("%c", Reg[a][b]). }if (A! = 3) {printf ("-");}} printf ("\ n");}}} count--;} if (count = = 0) {GetChar (); return 0;}}}} return 0;}

In combination with previous analysis, the code is not difficult to understand, just a variety of verification and loops more. Here I only care about the implementation, regardless of the code optimization and so on.

Iv. Program TestingHere my husband becomes a 10 registration code. Since the last three sets of registration code characters are strictly dependent on the first set of registration code character values, and the first set of registration code character range is between 0000 to FFFF, then I generated here the 10 registration code in fact, all the first 10 of the registration code, run the result is as follows:


The first 10 registration codes generated in Figure 5

In order to test these registration codes, we do not need to reinstall the game, because the game will be installed in the registry to establish a corresponding key value, to save the registration code, and every time the game starts and will query the registry to obtain the registration code, so we just need to modify the key value:


Figure 6

I can not verify all the registration code, but to verify the 10, the result is feasible, then you may consider the above procedure is feasible, here no longer repeat.

Five, PostScriptThese three articles on CM4 's reverse analysis can be said to be the longest I have written so far. In this series of articles, I was studying FIFA07 and "Paladin biography" after the intention to write, probably in mid-June this year. At that time wrote a first draft, that is, through the "blasting" way to bypass the verification mechanism, want to continue to write the register machine writing part, helpless level limited, has been dragged until now to complete. This big half year time is also my knowledge level grows the fastest half year, otherwise I still cannot analyze the CM4 verification mechanism. The three articles of the medium and the next, is the use of one weeks of time to complete the assault, this period of time only a few times a day for analysis, and the analysis process also took a lot of detours, it is precisely because of these detours, I can always show a smooth road in the article. Because it is the first time to analyze the registration code verification Mechanism, no experience, time-consuming is also relatively long. But my harvest is huge. I also hope that you will be able to learn from these articles, a lot of practice, a lot of thinking, and constantly try to do what they have learned, and really apply to their own side and their work.

Reverse engineering No. 007: Bridging the gap between CM4 verification mechanisms (Part one)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.