说了这么半天,也只是讲故事,因为目前干货还没出来,主要是因为dpcdll.dll比较难调试,目前看来重点还是应该放到pidgen.dll,至少调试setup.exe还是相对简单的。那么有人会问,为什么要搞dpcdll.dll呢?其实原因很简单,pidgen.dll和dpcdll.dll都用椭圆曲线签名算法能进行product id的检查,说明很可能是直接链接了许多相同的模块,而且dpcdll.dll有调试符号(pdb),pidgen.dll没有,估计大家猜到该怎么办了。。所以目前的思路就是利用dpcdll.dll的调试符号去对应pidgen.dll中的函数,这也就需要同时分析两个dll。准备好ida,windows xp rtm symbol package,恍然发现其实dpcdll.dll的符号还是很“友好”的,至少很多数学函数已经有名字了,再对应到windows 2000的源码,猛然发现了部分数学函数的声明,在private\windows\base\ntcrypto\dssinc\bignum.h,这样就方便了许多!到现在为止已经获得部分数学函数的“意义”,我会尽快贴出来。
First of all, this is pretty old stuff. It is mainly about my recent lazy reverse engineering on dpcdll.dll and pigden.dll from Windows Xp RTM (released more than 10 years ago). The reason to RE those stuff is because I am studying the ECC(Elliptic Curves Cryptography) lately.
And those are the essential libraries in Windows Xp which implements the ECDSA(Elliptic Curve Digital Signature Algorithm) to verify the Product Id(cdkey). For those who have already studied the two libraries, you probably have a much more through understanding. If you would like to share some of your knowledge, contact me by email (ganboing[at]gmail.com).
Below is just a quick briefing on the two dll and my approach to analyse them, and you may just skip those and download the archive below which contains the IDA database file of my analysis result. However I do suggest you have a look at them.
pidgen.dll is a 'simple' dll in-terms of size, and the dll is 'cleanly' designed to some extent. It exports those 'PIDGen?' functions which is kind of 'RE friendly'. If you are familiar with the term 'PID' in windows, you may recall the so called 'Product ID' stored in
That is basically what pidgen.dll is being designed to -- generate 'Product ID' from the CD-keys entered by the user during windows installation if the CD-key is valid, otherwise report the input CD-key is invalid. And that is why the pidgen.dll is not compressed in the Windows Xp installation CD so that the windows setup program is able to load the dll. Another good thing about pidgen.dll is that there aren't many tricky codes to analyze. The DllEntryPoint initialization routine is quite ordinary that it only initialize a HMODULE to the dll it-self besides calls to CRT_INIT. The very bad thing is that there is not a single pdb(debug information file) for pidgen.dll either from MS symbol server, or from Windows Symbol Package. And that is main and perhaps the only reason why we love to playing around with dpcdll.dll -- the symbol.
Talking about dpcdll.dll, we need to be aware that it is much more complex than pidgen.dll. The size (>100k) also indicates the work of RE. As we know, 'dpc' stands for 'Digital Product Check', so the dll not only does what pidgen.dll can do (except the Base24 decode part), but also many other things related to WPA which I am not willing to touch currently. Also be aware that the dll may behave trickier than you thought. It exports functions by 'Ordinal' rather by name in order to make RE difficult. Further more, there is an obvious mismatch between the number of exported function (in the rtm version, there are 3 in total) and the functionality the dll should be providing which suggests the dll may be using one of the exported function as a 'selector' to provide call back functions for different functionality. Bare these in mind, I am really not happy with REing dpcdll.dll. During the tough debugging, I find the DllEntryPoint calls a 'custom' initialization function where some dirty tricks such as 'modify return address' are used. Having a little taste of dpcdll.dll, I decided not to focus too much on dpcdll.dll.
So whats the point to RE the dpcdll.dll? Noticed that both dll have to have the capability to verify the Product Id of windows, it is quite natural for MS to develop both dll by simply link in some common libraries especially those math libraries to avoid redundant coding. And it is exactly what we can exploit -- match the functions in both dll so that the symbols of dpcdll.dll may tell us something. In fact, it works. Some functions in both dll have the same assembly code such as those CRC funcitons which is much easier for us to match them. Some math functions (those implements the high precision integer arithmetic) may reside in both dll but in different binary representation, in other words, the actual assembly codes are slightly different but the logic are same. In this case, we have to use our brain to do the match. To verify the match, just write a simple test program that loads both dll and call the matching functions correspondingly to see if our matching is correct or not. A very helpful header file which documented all the math library functions used in both dll shall be found in the Win2k leaked source. If you have the source, it can be found in
private\windows\base\ntcrypto\dssinc\bignum.h
(Someone has asked for the Win2k source. Actually it can be easily found on torrentz.eu. For convenience, I have uploaded the source archive. The file can be downloaded here)
Note that almost all of the prototype of those math function should be converted to stdcall convention by adding a __stdcall keyword. In this way, we are able to fully understand the meaning of lots of math functions in both dll.
After this step, we are much more closer to the core algorithm of verifying the Product Id which is basically ECDSA. Eventually we can get the public key and break the private key. Now I am still do the 'matching' while busy taking some not very helpful courses as a college student. I put the current analysis result (IDA database) below. If you can bear my poor RE skill, you can have a look. Nevertheless, I hope I do provide another useful way for you to RE pidgen.dll and other related stuff.