Keygenning Sandwich crackme

I had a very pleasant time reversing this crackme, so I decided to share my experience with it. You can find the crackme this article covers at this link. When launched, it shows as simple interface that let you only specify a serial number: Example image First of all, we type something random in the serial field, to make the crackme display to us the usual error: Example image Now, it is the time to open the executable in a disassembler. I will show you screens from Hopper Disassembler, but I will be forced to show you also some screens from Ida Pro. I will explain why later on. After opening and a really short background analysis, we get to the main Hopper screen, and we already see some promising code to dig in. In particular, we have a [SandwichAppDelegate validateSerial:] method that looks very promising. After a short run in the debugger, I discovered that that method was indeed in charge of validating the serial number:

Example image

As you can see, the method starts with some validation code that checks, one after another:

  1. If the entered serial number is 19 (0x13 in Hex) characters in length.
  2. It splits the serial into components separated by “-”. If there are not 4 components it fails.

  3. The components must have a length of 4 otherwise it fails.

Now, if all the above checks are passed, we come upon the true validation code:

Example image

You can see it in the last paragraph of the validateSerial method: the steps are the following:

It takes the first component and call intValue on it to get it as an integer. Then, it does the same with the second component and adds the two in esi (You can see that at location 0x1c99). At this point, it takes that sum, and apply a “sar esi, 0x2”. This instruction was unknown to me so far, and I could not rapidly find documentation about it. In those cases in my experience that kind of rare instruction is there to make it difficult to reverse. Fortunately, I have a friend that has the Ida Pro decompilers, and the output of the process to the validateSerial method, gave me a translation of that shift instruction in C: as simple as:

long value = previousValue >> 2;

Then, as you can see in 0x1cc4, it places a fixed value of 0x19c5 in the edx register. Then, it subtracts to this value the result of the “sar” instruction. At this point the real comparison is done, by comparing the previous result with eax, that contains the intValue of the fourth component. As you can see, the contents of the third component, apart that it has to be 4 in length, can be anything, even alphanumeric characters. They are ignored. By understanding the above, I was able to write a method in Objective-C (well, mainly C) to calculate random serial numbers. The main code is reported here:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
-(IBAction)userDidPressGenerateRandomSerial:(id)sender {

    long first = arc4random_uniform(10000);

    long second = arc4random_uniform(10000);

    NSInteger thirdDoesNotCount = arc4random_uniform(10000);

    long sum = first + second;

    long fixedValue = 0x19C5;

    long sarred = sum >> 2; // This is the translation of the sar assembly instruction

    long calculatedLastSerialNumberPart = fixedValue - sarred;

    self.serialString = [NSString stringWithFormat:@"%.4ld-%.4ld-%.4ld-%.4ld", first, second,

    thirdDoesNotCount,calculatedLastSerialNumberPart];

}

You can find the entire xcode project on github at this link