Zendenc FLEXlm 7.2 cracking information.
Written by Nolan Blender


This cracking information covers the cracking of the FLEXlm 7.2 package using the default encryption protection. Globetrotter has a new, improved Counterfeit Resistant Option which costs extra money - this essay does **not** cover this, as the Elliptic Curve Cryptography (the "Security Builder" code) has not been analysed at the time of this writing.

The target audience for this essay is experienced scene crackers who wish to have a quick and dirty way to get the encryption seeds from the latest versions of FLEXlm. A clear understanding of the current FLEXlm methods would help, and understanding how to use IDA and SoftICE is required.

Target's URL/FTP

Files you might need (Calcseed.exe / Zendenc.exe) : (534k).


FLEXlm keys are dependent on two secret values stored inside the licensing software - ENCRYPTION_SEED1 and ENCRYPTION_SEED2. These values are chosen by the software vendor who is integrating FLEXlm into their product. If these values are recovered, and no additional security measures (such as vendor defined checkouts, where additional checks are done against the license, or user crypt filters, where an additional layer of encryption is applied to the license key) are implemented, valid licenses can be generated for the target product.

The methods used to hide the values of the FLEXlm keys have become more sophisticated, possibly as a response to crackers being able to extract the keys/generate new warez releases before some customers even see the software arrive at their door. Although there is a long history of improvements, I will only cover the most recent ones.

Currently the seeds are hidden by including special subroutines that generate the key data in the build of programs meant for distribution to end customers. One of the routines generates a version of the VENDORCODE structure that contains correct vendor keys, but incorrect encryption seeds. A second routine takes this data, and extracts the seeds, but splits the valid data
between the job structure (a global data space used by Globetrotter to store state information of the current FLEXlm session) and the VENDORCODE structure. The data is recombined just before use in encryption or validation routines within FLEXlm.

A randomizing value (based on the time) is xored with both the value in the job structure and the value in the VENDORCODE structure in order to make it more difficult to retrieve the encryption seeds.

Earlier versions of FLEXlm (6.1-7.0) contained an implementation weakness. It was possible to recover the corrected seeds in the VENDORCODE structure by passing in a NULL pointer for the job structure into the recovery routine in lm_new. The easiest technique (although there are others) was to search for l_sg using IDA and the FLEXlm signatures, search for the call to the lm_new seed recovery routine (usually near the beginning of the l_sg routine, and a call to a pointer value). Using SoftICE, the program is loaded, then a breakpoint set at the point where the decoding routine is called.

The pointer to the job structure, the first argument, is then replaced with a null pointer (0). The pointer to the vendorcode structure, the third argument, is examined, and the program stepped over the call to the lm_new routine. The VENDORCODE structure was examined after the call, and it then contains the correct seeds. Later versions of FLEXlm correct this problem by not filling in the correct seeds when a NULL pointer is passed in for the job structure. Instead, the subroutine makes no attempt to modify the seeds. How can the seeds be recovered in this instance?.

As it turns out, the algorithms used to distribute the data between the VENDORCODE and the job structures are quite simple and based only on the first character of the vendorname. Since lm_new.c is generated by lmrand2, it is possible to totally reverse engineer how the seeds are extracted, then write a program to recombine the data from the job structure and the vendorcode structure, and recover the seeds this way. The essay Nolflex2.htm contains a detailed description of this.

The program zendenc.exe is first loaded into IDA, then after the initial decompilation is complete, a search is done for a routine that does many calls to _time, which will be the lm_new routine. If we had the correct signature for that version, we could simply apply the signature in IDA, and locate l_sg, however since we don't we have to do it the hard way. Once we've located the routine with a lot of calls to time, we look for references to that routine in other parts of the program - in this case, we find only one reference to it :

.text:004010E7 cmp dword_49E5EC, 0
.text:004010EE jnz short loc_4010FA
.text:004010F0 mov dword_49E5EC, offset sub_40D572

The value at 49E5EC will refer to the lm_new decoding routine after the instructions at 4010FA are executed. The next step is to look for references to 49E5EC, since that will be where the routine is called, or the value there will be copied into a register to be called. By examining the references to that location, we find one location that is a likely location for the call in question :

.text:0043900D mov eax, [ebp+arg_8]
.text:00439010 push eax
.text:00439011 mov ecx, [ebp+arg_4]
.text:00439014 push ecx
.text:00439015 mov edx, [ebp+arg_0]
.text:00439018 push edx
.text:00439019 call dword_49E5EC

The call at 439019 is the call to that pointer, so this is most likely where the call to the decoding routine occurs. It's not identified as being in l_sg, but it's a safe bet that if we had signatures for 7.1 FLEXlm, that's what the routine would be named. We need to have a "fake" license file in order to get this routine called though. That way, we can get this routine to be called.

FEATURE Zend_Encoder zend 9.9 permanent uncounted VENDOR_STRING=blah \
HOSTID=ANY SIGN=123412341234

I think I got the feature name by looking for calls to the checkout, and looking to see what got passed in there, but there are numerous ways of doing this, all of which I'm sure you're familiar with if you know anything about FLEXlm. The next step is to put the fake license in license.dat, and load up the zendenc.exe program in SoftICE, possibly with a loaded symbol table if you felt it important to make one.

After the program loads and breaks at the entry point, a breakpoint is then set at 439019, and the stack examined at that point - I use dd esp to do that. Since arguments are pushed onto the stack from right to left, and there are three arguments that are passed into the decoding routine, we can figure out what is being passed into that routine, esp contains a pointer to the job structure, esp+4 contains a pointer to a string containing the vendor name, and esp+8 contains a pointer to the vendorcode structure. I recorded the the values on my machine as follows - you may have got different values.

302B70 - ptr to job structure
302CBC - ptr to vendor name
12CF98 - ptr to vendorcode structure

By examining the include files kindly by Globetrotter, we determine that the values at vendorcode+4 and vendorcode+8 are the ones that are used as data[0] and data[1], and later hold the encryption seeds. We can do dd (12CF98+4) to get the base of the encryption seed data values, and dd (302b70+8) to get the values for the seed hiding area in the job structure. Every time the program is run you will get different for these values, so record both sets of values at the same time.

Here's what I got in my run :

vendorcode+4 which is data[0] : DCE0A0A2
vendorcode+8 which is data[1] : FC58117B

job+8 : D3B4B0C2
job+c : 81042659
job+10 : D493C07C

Running calcseed reveals the following :


I have provided calcseed.exe, which is really an implementation of the Nolflex2.htm essay, and it will perform the calculations described in the essay to derive the seeds. encseed[0] and encseed[1] are the actual encryption seeds. Selector values are the indicies of the values taken from the job array when the job array is treated as an array of chars, and are provided for interest only. The XOR value is the derived value to xor with the data values to get the encryption seeds.

Final Notes

This is another essay describing FLEXlm, by the wizard of Globetrotter, Nolan Blender, you ought to know what to do with this by now, sit back and learn - CrackZ.