Log in

View Full Version : Help discovering elements used to create a serial number


zambuka42
June 8th, 2008, 14:45
Hi, although I consider myself at a beginner/intermediate level.. I am posting this in the advanced forum because with my limited knowledge I believe the problem I am working on is an advanced one. This is something I believe people smarter than myself have tried to reverse and failed.. yet I am giving it a shot.

I've been working for over a week on this, done as much searching as is reasonably possible, and have resisted posting any questions regarding it save one about api's that reserve memory space.

My problem is that I can find the point at which a serial number (specific to the machine from which the program is run) is generated internally, yet can not figure out how to find/interpret the method from which this number is created.

Basically, I'm just putting it out there that if anyone cares to privately discuss the details of this project and the information I've gleaned thus far.. feel free to PM me.

FrankRizzo
June 16th, 2008, 20:46
If you could post small snippets of code, we could look at them, and maybe help you. Usually, what gives you a BIG hint, is the windows functions that are being called. Let your study begin there. Then, once you understand what the functions that they call return, you should see the code in a whole different light.

For instance, I just looked at a target that literally added the hex values of the user name string together, sprintf'd it with %04X, and then used those 4 characters in strategic places in the expected registration code. Grand time from download to complete reversal? 1.5 hours.

Gotta LOVE those Borland apps! They just guide you straight to their heart.

Kayaker
June 16th, 2008, 21:25
Quote:
[Originally Posted by FrankRizzo;75174]Gotta LOVE those Borland apps! They just guide you straight to their heart.


Heh, that's what I remember too, a certain pattern in how ecx and edx were used to transfer pointers and leading directly to a Borland string comparison that never changed its look. Monitor the comparison results and you could begin to build a serial number.

It's been years. Silly question, why did it seem that 100% of Asprotected apps were Borland?

FrankRizzo
June 16th, 2008, 22:02
These days it's even easier. I did a Delphi app, and a C++ Builder 6 app in the same day thanks to DeDe. The combination of it, and IDA is a deadly combination for folks writing apps in those "languages".

The steps go like this:

Load app into IDA.
Load app into DeDe.
Find stupidly named form "RegistrationForm" or similar
Look through definition of form, and find function name for OK button. How about "OnClickOK"
Then label any Borland functions that IDA didn't get but Dede did.
Use Brain tool
Understand "protection".


Which brings me to my next rant. If you are a shareware programmer and want to compare the key typed in to the one you expect, here is how to NOT do it.

Don't generate the proper key, and then do a strcmp to the one the user typed in! Because if you do, I'll change the pointer to your error message to point to the correct key, so that when you enter the wrong key, you get a MessageBox with the correct one in it!

It's stupid, just don't do it.

zambuka42
June 17th, 2008, 00:35
Hey guys, I'm sorry for not replying sooner but I wasn't notified that replies existed. I wish I could post just snippets, but I've done so much work already that a simple snippet is not going to help anything.

However, if a mod would tell me that I can post specifics (without revealing the exact app itself).. I would love to do it.

FrankRizzo
June 17th, 2008, 00:47
That's what I meant. Post the specific parts of the code that you're having trouble with. (Without any identifying marks).

zambuka42
June 17th, 2008, 01:10
*This is a txt file I wrote originally for anyone that might be curious enough about this to take a look. Obviously I've modified it so as not to break any rules here (hopefully). It was originally intended for someone to read while also looking at the app itself*

-------------------------------------------------------------------

Ok, this is the installer for a program that requires definition updates. The installer will download new definitions one time before it runs the setup. It accomplishes this by internally creating a serial number based on some unknown elements... then it creates another shorter code based on this serial number... then it creates a url that includes this code that asks a remote server for definitions.

If I can get it to create a different valid random serial number each time it is run.. then I think it will always get the updates.

-------------------------------------------------------------------

There are two important files. The installer we'll call installer.exe, and a dll that we'll call installer.dll

I believe this is the sequence of events:

1) At 4016E5 of installer.exe, the 00C50000 memory space is made available. (Later a serial number will be placed at 00C51CD0)

Code:
004016DA | 6A 04 |PUSH 4 ; Protect = PAGE_READWRITE
004016DC | 68 00100000 |PUSH 1000 ; |AllocationType = MEM_COMMIT
004016E1 | 2BFB |SUB EDI, EBX ;
004016E3 | 57 |PUSH EDI ; Size = 4000 (16384.)
004016E4 | 53 |PUSH EBX ; Address = 00C50000
004016E5 | E8 26FCFFFF |CALL <JMP.&kernel32.VirtualAlloc> ; VirtualAlloc



2) at 402765 (after many visits to this address) a serial number common to ALL machines is placed at 00C51CD0. The number is all capital letters, and is 20 digits.

Code:
00402738 / 56 PUSH ESI
00402739 | 57 PUSH EDI
0040273A | 89C6 MOV ESI, EAX
0040273C | 89D7 MOV EDI, EDX
0040273E | 89C8 MOV EAX, ECX
00402740 | 39F7 CMP EDI, ESI
00402742 | 7F 13 JG SHORT 00402757
00402744 | 74 2F JE SHORT 00402775
00402746 | C1F9 02 SAR ECX, 2
00402749 | 78 2A JS SHORT 00402775
0040274B | F3:A5 REP MOVS DWORD PTR ES:[EDI], DWORD PTR D>
0040274D | 89C1 MOV ECX, EAX
0040274F | 83E1 03 AND ECX, 3
00402752 | F3:A4 REP MOVS BYTE PTR ES:[EDI], BYTE PTR DS:>
00402754 | 5F POP EDI
00402755 | 5E POP ESI
00402756 | C3 RETN
00402757 | 8D740E FC LEA ESI, DWORD PTR DS:[ESI+ECX-4]
0040275B | 8D7C0F FC LEA EDI, DWORD PTR DS:[EDI+ECX-4]
0040275F | C1F9 02 SAR ECX, 2
00402762 | 78 11 JS SHORT 00402775
00402764 | FD STD
00402765 | F3:A5 REP MOVS DWORD PTR ES:[EDI], DWORD PTR D>
00402767 | 89C1 MOV ECX, EAX
00402769 | 83E1 03 AND ECX, 3
0040276C | 83C6 03 ADD ESI, 3
0040276F | 83C7 03 ADD EDI, 3
00402772 | F3:A4 REP MOVS BYTE PTR ES:[EDI], BYTE PTR DS:>
00402774 | FC CLD
00402775 | 5F POP EDI
00402776 | 5E POP ESI
00402777 \ C3 RETN


3) at EEC22C of the module installer.dll, a call is made that takes this serial number and uses it to create a 20 digit code that will be sent to the app's online servers. This code will be common to all machines and is also 20 digits, but can be made of any character.

4) Next, a window will appear with a welcome screen and the option of hitting NEXT

5) After hitting next, a procedure will be run in installer.exe to create a serial number specific to this machine. I don't know where this happens, but I know that It will be placed in memory using the same procedure as before (402765), except this time the location in memory that it is placed will be different from 00C51CD0. It is a random address and thus, I don't know how to track backwards to where the serial number is created.

6) Using this new serial, another 20 digit code will be created based off this serial number at the same place as before (EEc22C). It is this 20 digit code, that I believe is then sent to the app's servers using a URL created at EE8297 of the installer.dll

7) If the URL formed has valid information that has not been sent to the app's server before, it will respond with the url that the installer may download the definitions from.

FrankRizzo
June 17th, 2008, 19:10
OK, you've posted a routine used to malloc the memory to HOLD the string, and the function used to MOVE the string to the address. The problem is, you HAVEN'T posted the function that actually MAKES the string.

You need to find what ESI and EDI point to when this routine is called. I bet one of those is the serial # in question. We'll assume that it does. You now need to find the code that puts the serial # in that place. Work backwards until you find the place where the # is generated.

How do I do that? you're asking. Well, you can set a WRITE breakpoint on the location that it's written to, and wait for it to break.