Archive for the ‘Keygen Tutorials’ Category


b. Ví dụ 2 :

Phần tiếp theo , chúng ta sẽ làm thêm một ví dụ nữa. Ở ví dụ này chúng ta sẽ thực hành trên một crackme. Cách thức thực hiện trên crackme cũng hoàn toàn tương tự như khi chúng ta thực hiện đối với Software ở trên. Oki, chúng ta bắt đầu : ).
Chạy thử Crackme, tiến hành nhập thông tin và nhấn nút “Check It!”. Chằng thấy có Nag nào bắn ra cả.

ex1

Nhấn nút “Give Up!” để exit .Mở Ollydbg lên và load crackme vào (crackme này được code bằng Microsoft Visual C++ 6.0).
Sau khi load xong , dùng chức năng Search For \ All referenced text strings để tìm kiếm thông tin. Chúng ta có được kết quả như sau :

ex2

Double Click tại 00401639 chúng ta sẽ quay trở lại màn hình chính của Ollydbg. Dịch lên một chút , ta đặt BP tại 004015BC. Nhấn F9 để Run , tiến hành nhập lại Fake Information. Sau đó nhấn “Check It!”, Ollydbg sẽ Ice tại điểm đặt BP. Nhấn F8 để Trace, chúng ta sẽ có như sau :

ex3

Như mọi người nhìn thấy thì Crackme này sẽ tiến hành một số quá trình kiểm tra như sau : Độ dài của UserName mà chúng ta nhập vào phải thỏa mãn điều kiện là 5 < Length(FakeUser) < 20. Bên cạnh đó thì chiều dài của FakeSerial mà chúng ta nhập vào cũng phải bằng với chiều dài của FakeUser. Nếu như chúng ta nhập đúng các thông tin thỏa mãn tất cả các điều kiện trên thì chúng ta sẽ vượt qua được quá trình check này. Sau đoạn check ở trên chúng ta sẽ gặp một vòng lặp tính toán ra Real Serial của Crackme . Cụ thể như sau :

ex4

Do đặc thù của kĩ thuật Internal Keygen như đã nói ở trên , ở đây ta không cần quan tâm đến quá trình tính toán Serial như thế nào. Ta chỉ cần biết rằng đây chính là vòng lặp dùng cho việc tính ra Real Serial và giá trị trong thanh ghi AL tại địa chỉ 00401629 chính là giá trị RealSerial sau mỗi quá trình tính toán của vòng lặp . Vòng lặp này có số lần lặp phụ thuộc vào chiều dài của chuỗi UserName mà chúng ta nhập vào.
Nhưng mọi người để ý rằng, ngay tại lần lặp đầu tiên giá trị thứ nhất của RealSerial sẽ được tính toán , sau đó giá trị này được lưu vào thanh ghi AL. Tiếp theo , tại địa chỉ 00401629 là quá trình so sánh kí tự đầu tiên trong chuỗi Fake Serial mà chúng ta nhập vào với giá trị Real Serial lưu trong thanh ghi AL. Nếu 2 giá trị này khác nhau thì ngay lập tức sẽ có một lệnh nhảy thoát ra khỏi vòng lặp tính toán. Vậy tức là nếu như ngay từ đầu kết quả so sánh này đã sai thì chúng ta luôn bị out khỏi vòng lặp và sẽ không thể biết hểt được giá trị tiếp theo sẽ sinh ra của chuỗi Real Serial. Đây là điều mà chúng ta không muốn! Vậy hướng giải quyết ở đây là thế nào?

Để ý rằng dưới câu lệnh :

00401629 . 38040A CMP BYTE PTR DS:[EDX+ECX], AL ; <== FakeSerial[i] = Temp ?

là một lệnh nhảy làm cho chúng ta out ra khỏi vòng lặp tính toán :

0040162C . /75 1C JNZ SHORT Rith_Cra.0040164A ; <== If not, Jump to Bad boy

nhưng chúng ta thấy rằng, chuỗi FakeSerial của chúng ta được đưa vào thanh ghi EDX. Mà giá trị trong BYTE PTR DS:[EDX+ECX] chính là kí tự đầu tiên của chuỗi Fake Serial(lúc đầu ECX = 0). Quan sát thấy , ngay dưới lệnh nhảy ở trên là lệnh :

0040162E . 41 INC ECX ; <== i ++

Vậy ta có thể kết luận một điều rất quan trọng như sau : Nếu như giá trị trong BYTE PTR DS:[EDX+ECX] = AL (tức là giá trị đầu tiên của chuỗi FakeSerial mà chúng ta nhập vào bằng với giá trị RealSerial của quá trình tính toán) thì chúng ta sẽ không bị out khỏi vòng lặp tại lệnh nhảy , do đó giá trị ECX sẽ tăng lên để trỏ tới vị trí tiếp theo trong chuỗi FakeSerial. Vậy thì ngay tại chỗ này , chúng ta nảy ra một ý tưởng là , chúng ta sẽ dùng chính chuỗi FakeSerial này để lưu chuỗi Serial của quá trình tính toán.

Để thực hiện được điều này chúng ta chỉ việc thay đổi câu lệnh so sánh tại 00401629. Tại địa chỉ này, nhấn Space để mở cửa sổ Assemble , chúng ta edit lại như sau :

ex6

Tiếp theo chúng ta sẽ NOP câu lệnh nhảy tại 0040162C. Ta sẽ có được như sau :

ex7

Oki , tiến hành Run thử và Dump tại thanh ghi EDX , chúng ta sẽ có được kết quả mà chúng ta mong muốn . Vậy là qua bước thứ nhất tìm ra nơi tính toán RealSerial và nơi lưu trữ giá trị RealSerial :

ex8

Bước tiếp theo chúng ta sẽ cho hiện cái RealSerial này thông qua cái MessageBox. Công việc này hết sức đơn giản. Chúng ta chỉ việc trỏ tới vị trí của dòng :

0040163E 68 20304000 PUSH Rith_Cra.00403020 ; ASCII "Well done cracker!"

sau đó nhấn Space và sửa thành :

PUSH EDX

Cuối cùng chúng ta Save thành quả của chúng ta thành một file exe. Chạy file này lên, nhập thông tin vào nhớ là chiều dài UserName phải bằng với chiều dài Serial nhập vào : ). Chúng ta sẽ có được kết quả như sau :

ex10

Vậy là thành công rồi !!!

Best Regards
_[Kienmanowar]_

–++–==[ Greatz Thanks To ]==–++–
My family, Computer_Angel, Moonbaby , Zombie_Deathman, Littleboy, Benina, QHQCrker,
the_Lighthouse, Merc, Hoadongnoi, Nini … all REA‘s members, TQN, HacNho, RongChauA,
Deux, tlandn, light.phoenix, dqtln, ARTEAM …. all my friend, and YOU.

–++–==[ Thanks To ]==–++–
iamidiot, WhyNotBar, trickyboy, dzungltvn, takada, hurt_heart, haule_nth, hytkl v..v..

I want to thank Teddy Roggers for his great site, Reversing.be folks(especially haggar),
Arteam folks(Shub-Nigurrath, MaDMAn_H3rCuL3s) and all folks on crackmes.de, thank
to all members of unpack.cn (especially fly and linhanshi). Great thanks to lena151(I like
your tutorials). And finally, thanks to RICARDO NARVAJA and all members on
CRACKSLATINOS.

>>>> If you have any suggestions, comments or corrections email me: kienmanowar[at]reaonline.net

Advertisements

Kĩ thuật Internal Keygen[

I. Lời giới thiệu :

Nếu như các bạn đã từng đọc qua loạt tut về Olly của ARTEAM thì chắc chắn sẽ bắt gặp cụm từ “Internal Keygen” . Trong một số tài liệu khác cụm từ này có thể xuất hiện dưới các tên khác là “Keygen Injection” hay “Code Injection”. Vậy cụm từ này có nghĩa là gì ?

Thực chất thì “Internal Keygen” là một kĩ thuật giúp Cracker lợi dụng chính chương trình mà họ muốn crack , biến chương trình trở thành một Keygen. Nói như vậy vẫn có vẻ hơi mơ hồ và xa lạ !!
Như các bạn đã biết , trong quá trình crack soft mỗi User Name nhập vào thì chương trình mà chúng ta crack sẽ lại sinh ra một số Serial khác nhau ứng với User Name đó. Do đó, nếu như Serial mà chúng ta tìm được là chính xác thì việc đăng kí diễn ra hoàn toàn bình thường. Nhưng do mỗi Serial là khác nhau với mỗi User Name , do đó nếu như có một người nào đó muốn sử dụng chương trình thì bản thân họ phải tự tìm lấy Serial tương ứng với User Name của họ nhập vào. Điều này là rất bất tiện cho những người chẳng biết gì về Crack.

Khi bạn là một Cracker, thì tôi tin rằng các bạn cũng đã biết Keygen là cái gì và làm thế nào để có một Keygen. Keygen thường áp dụng cho các chương trình sử dụng cơ chế bảo vệ Name/Serial. Đối với các Cracker thì việc Keygen hoàn chỉnh được một soft đỏi hỏi họ phải biết phân tích thuật toán mà coder sử dụng để cho ra Serial (đôi khi cũng phải đoán xem ý đồ của coder, nhắm xem coder định làm gì để chặn đầu).Nhưng để phân tích và code ra một Keygen sẽ phải tốn khá nhiều thời gian và công sức, vì mỗi chương trình sẽ có những cơ chế tính toán khác nhau từ dễ đến khó để làm nản lòng các Cracker. Do đó, kĩ thuật “Internal Keygen” ra đời và được các Cracker sử dụng để tiết kiệm thời gian và công sức nhưng vẫn đem lại hiệu quả nhất định. Họ sẽ dùng kĩ thuật này để giải quyết bài toán với mỗi User Name sẽ có một Serial (tương đương với việc code một Keygen) bằng cách lợi dụng quá trình tính toán của chương trình để biến chương trình trở thành một Keygen.

Như đã nói ở trên, Cracker sẽ lợi dụng chương trình để biến nó thành Keygen ! Vậy họ sẽ lợi dụng cái gì ? Và làm thế nào để lợi dụng ?
Trong quá trình đăng kí sử dụng hợp pháp một chương trình , thì theo thường lệ chương trình sẽ yêu cầu chúng ta nhập User Name và Serial vào các text box . Khi chúng ta nhấn Register / OK thì có nghĩa là chúng ta muốn chương trình sẽ chấp nhận cho phép chúng ta đăng kí với những gì chúng ta đã nhập vào. Nếu như những gì chúng ta nhập vào là đúng thì một Message Box sẽ hiện ra thông báo đại loại như “Thank You” or “Successful” thông báo cho chúng ta biết là chương trình đồng ý với những gì chúng ta nhập vào và dĩ nhiên chúng ta đã trở thành người dùng hợp pháp : ). Nhưng trong trường hợp ngược lại , khi những gì chúng ta nhập vào là sai, thì lẽ thường tình đã có “Thank you” thì chắc chắn sẽ có một Message Box khác làm công việc ngược lại là thông báo “ Wrong Code” or “ Invalid Serial” bắn ra , báo cho ta biết đừng có mà cố gắng nữa làm gì . Càng cố càng sai thôi!! : ). Vậy cái mà Cracker lợi dụng ở đây chính là cái Message Box thông báo khi chúng ta nhập sai đó, thay vì việc nó Pop up ra thông báo “Wrong Code” or “Invalid Serial” thì Cracker sẽ cho chương trình Pop up ra cái Real Serial của chương trình sau quá trình tính toán. Mà cái Real Serial này dùng để làm gì tiếp theo chì chắc chắn không cần nói thì ai cũng biết phải làm gì .

Vậy để lợi dụng được nhược điểm này, không còn một cách nào khác là Cracker phải dùng một chương trình Debugger để Debug chương trình . Họ sẽ tìm xem chương trình sẽ sinh ra Serial ở đâu và lưu vào vị trí nào trong bộ nhớ. Song song với quá trình này thì họ cũng phải biết cái hàm Message Box thông báo sai nằm ở đâu. Khi đã có được 2 điều kiện cần ở trên , họ sẽ tiến hành sửa code để cho chương trình sẽ không bắn ra thông báo sai mà sẽ bắn ra cái Real Serial mà lẽ ra phải nhập vào tương ứng với User Name chứ không phải là một Fake Serial nào đó mà chúng ta nhập vào …

Để dễ hình dung hơn, các bạn hãy quan sát một đoạn code đơn giản sau đây :

Original code:

CMP EAX, EBX ; EAX=our serial | EBX=correct serial
JNZ WrongCode ; Not the same? Then display "Wrong Code"
.... ; This is where the "Thank You" stuff is.
....
WrongCode:
.. ; Shoot Nag “Wrong Code”

Code after change:

CMP EAX, EBX ; EAX=our serial | EBX=correct serial
JNZ WrongCode ; Not the same? Then run the built-in keygen.
.. ; This is where the "Thank You" stuff is.
..
.. ; All the other code of the program.
..
WrongCode: ; We place our keygen at a convenient location.
.. ;
.. ; Push Right serial
Call xxxx ; Display the RIGHT serial.
... ; Continue the program Normal
...

Như các bạn đã thấy trên đây , mọi việc diễn ra rất đơn giản không có gì là phức tạp cả. Vậy tóm lại để có được một “Internal Keygen” chúng ta sẽ phải trải qua các bước sau đây :

1. Chúng ta phải biết được Real Serial được tạo ra ở đâu và được lưu vào vị trí nào trong bộ nhớ.

2. Chúng ta phải biết vị trí của hàm Message Box bắn ra thông báo sai ở đâu.

3. Cuối cùng chúng ta phải chỉnh sửa hàm Message Box thế nào khiến cho nó hiện ra Real Serial thay vì hiện ra thông báo sai.

Oki , tổng quát về kĩ thuật “Internal Keygen” là như thế, không có gì là “cao siêu” cả. Bước tiếp theo trong bài viết này tôi sẽ hướng dẫn các bạn một làm một ví dụ nho nhỏ để các bạn hiểu rõ hơn về kĩ thuật này.

II. Thực hành :

Trong phần giới thiệu ở trên, tôi đã chỉ cho các bạn các bước cơ bản nhất để tiến hành áp dụng kĩ thuật “Internal Keygen”. Trong phần tiếp theo này, tôi sẽ cùng với các bạn làm một ví dụ nho nhỏ để áp dụng kĩ thuật này. Một phần là để thay đổi không khí, một phần là để các bạn có cái nhìn trực quan hơn về cách thực hiện cũng như hiểu rõ thêm về các bước phải làm. Oki, chúng ta bắt đầu nhé!.

Ví dụ mà tôi sẽ sử dụng sau đây chính là file Wallpaper.exe (Down load here : http://www.reaonline.net/forum/showthread.php?t=884) đã được đề cập trong tut “Phân tích ASM và Code Keygen”(Link to this tut : http://www.reaonline.net/forum/showthread.php?t=921). Oki, chúng ta sẽ tiến hành phân tích chương trình này.

Đầu tiên chúng ta chạy thử chương trình, ngay lập tức chương trình sẽ hiện ra một hộp thoại “Wallpaper Registration” yêu cầu chúng ta nhập User Name và Serial vào. Chúng ta chưa có gì trong tay cả nên cứ việc nhập đại vào hai text box đó ( Vd : kienmanowar & 11111982 ). Sau đó nhấn OK, khi chúng ta nhấn vào nút này thì ngay lập tức chương trình sẽ tính toán lại Serial dựa trên User Name mà chúng ta đưa vào , sau đó so sánh Serial mà nó tính toán được với cái Serial mà chúng ta nhập vào (quá trình này xảy ra rất nhanh). Nếu trùng thì Ok , còn không nó sẽ Pop up ra thông báo sau :



kg1

Như những gì tôi đã nói với các bạn ở trên về kĩ thuật “Internal Keygen”, chúng ta sẽ biến chương trình này thành một Keygen để thay vì việc nó hiện ra cái thông báo sai như các bạn nhìn thấy ở trên, nó sẽ phải hiện ra cái Serial thật mà nó tạo ra cho chúng ta thấy. Oki , mục đích và ý tưởng là như thế , tiếp theo chúng ta sẽ hiện thực hóa ý tưởng của chúng ta.

Đầu tiên mở Olly lên , load file Wallpaper.exe vào Olly, việc tìm ra điểm đặt BP của chương trình này đã được tôi nói tới trong tut “Phân tích ASM và Code Keygen” rồi , các bạn có thể xem lại hoặc tự làm. Việc tìm ra điểm đặt BP của soft này hết sức dễ dàng. Oki, khi có được BP, nhấn F9 để run chương trình, tiến hành nhập thông tin đăng kí gồm FU & FS và nhấn Ok . Olly sẽ Ice tại điểm mà chúng ta đặt BP. Tiến hành Trace(F8) chúng ta sẽ có như sau :

00404A35 . 8B3B MOV EDI, DWORD PTR DS:[EBX] ; <== Fake User
00404A37 . B9 FFFFFFFF MOV ECX, -1
00404A3C . 2BC0 SUB EAX, EAX
00404A3E . F2:AE REPNE SCAS BYTE PTR ES:[EDI]
00404A40 . F7D1 NOT ECX
00404A42 . 49 DEC ECX ; <== Length(FU)
00404A43 . 0F84 08010000 JE Wallpape.00404B51 ; <== If Length(FU) == 0 then Jump to Nag

Tiếp tục :

00404A49 . 8B7E 5C MOV EDI, DWORD PTR DS:[ESI+5C] ; <== Fake Serial
00404A4C . B9 FFFFFFFF MOV ECX, -1
00404A51 . 2BC0 SUB EAX, EAX
00404A53 . F2:AE REPNE SCAS BYTE PTR ES:[EDI]
00404A55 . F7D1 NOT ECX
00404A57 . 49 DEC ECX ; <== Length(FS)
00404A58 . 0F84 F3000000 JE Wallpape.00404B51 ; <== If Length(FS)==0 then Jump to Nag

Oki, do chúng ta đã nhập đầy đủ các thông số mà chương trình yêu cầu , nên chúng ta đã vượt qua được đoạn code này. Tiếp theo chúng ta sẽ đến một đoạn code rất quan trọng , đó chính là đoạn code tạo ra Real Serial của chương trình :

00404A5E . 6A 00 PUSH 0 ; /Arg1 = 00000000
00404A60 . 8BCB MOV ECX, EBX ; |
00404A62 . E8 24D40200 CALL Wallpape.00431E8B ; \Wallpape.00431E8B
00404A67 . 50 PUSH EAX ; /Arg1
00404A68 . 8BCE MOV ECX, ESI ; |
00404A6A . E8 21010000 CALL Wallpape.00404B90 ; \Wallpape.00404B90 ;<==(Calculation)

Do đặc thù của kĩ thuật Internal Keygen cho nên chúng ta không cần phải biết và không cần quan tâm tới giải thuật hay thuật toán mà chương trình dùng để tính toán ra Real Serial, mà chúng ta chỉ cần biết vị trí của hàm tính toán ra Real Serial mà thôi. Như vậy , theo yêu cầu này thì chúng ta đã tìm ra được vị trí của hàm này rồi đó, chính là ở 00404A6A. Nhấn F8 tiếp tục cho tới hàm này và Trace qua hàm này. Sau khi Trace qua hàm này thì ngay lập tức chúng ta sẽ nhìn thấy Real Serial hiện ra trong cửa sổ Registers :

kg2

Cụ thể ở đây , chúng ta sẽ thấy Real Serial mà chương trình sinh ra sau hàm CALL ở 00404A6A được lưu vào thanh ghi EAX, cụ thể là tại địa chỉ 008E1210. Right Click lên thanh ghi EAX và chọn Follow In Dump chúng ta có được như sau :

kg3

Khà khà …Như vậy bước đầu tiên trong 3 bước của kĩ thuật “Internal Keygen” đã được chúng ta thực hiện xong. Bước thứ 2 là chúng ta phải tìm ra chỗ của hàm Message Box “Invalid Key” ở đâu ? Để thực hiện được điều này, chúng ta nhìn xuống dưới đoạn code tính toán Serial :

00404A6A . E8 21010000 CALL Wallpape.00404B90 ; \Wallpape.00404B90 ;<==(Calculation)

chúng ta sẽ thấy như sau :

00404A97 > \85C0 TEST EAX, EAX
00404A99 . 0F85 B2000000 JNZ Wallpape.00404B51

Click chuột vào hàm JNZ này , là lần theo hướng mũi tên mà nó chỉ chúng ta sẽ tới được vị trí mà chúng ta cần tìm. (Thực ra khi các bạn đi tìm điểm đặt BP thì các bạn cũng đã phải thông qua bước tìm thông báo này rồi) :

00404B5A . 68 09040000 PUSH 409
00404B5F . 68 00000400 PUSH 40000
00404B64 68 B8024400 PUSH Wallpape.004402B8 ; ASCII "ERROR"
00404B69 68 C4044400 PUSH Wallpape.004404C4 ; ASCII "Invalid key"
00404B6E > 6A 00 PUSH 0 ; |hOwner = NULL
00404B70 . FF15 84994400 CALL NEAR DWORD PTR DS:[<&USER32.>; \MessageBoxExA

Vậy là bước thứ 2 trong cũng đã được thực hiện xong một cách rất dễ dàng . Tiếp theo tôi muốn nói với bạn một chút về hàm MessageBox:

int MessageBox(

HWND hWnd, // handle of owner window
LPCTSTR lpText, // address of text in message box
LPCTSTR lpCaption, // address of title of message box
UINT uType // style of message box
);

Hàm MessageBox là một hàm nội tại của Windows. Điều này có nghĩa là , khi bạn là người lập trình , bạn viết một chương trình và thay vì việc bạn phải tự thân vận động để ngồi code ra một MessageBox của riêng chúng ta thì chúng ta có thể dùng hàm MessageBox sẵn có của Windows . Hàm MessageBox này sẽ tạo , hiển thị và thi hành một message box. Hàm MessageBox sẽ được gọi giống như bất cứ một hàm nào , và để sử dụng được hàm này thì điều đầu tiên chúng ta cần phải truyền biến cho nó hay còn gọi là đối số. Các đối số này đã được liệt kê như các bạn đã thấy ở trên. Việc tìm hiểu thêm về việc làm thế nào một MessageBox được tạo ra sẽ giúp cho chúng ta có những hiểu biết cơ bản để vận dụng nó vào công việc. (Để biết thêm chi tiết về hàm này các bạn có thể tham khảo trong tài liệu MSDN hoặc trong file win32.hlp ).

Như trên đã nói , chúng ta vừa trải qua hai bước : bước thứ nhất là tìm vị trí của hàm tạo ra Serial và vị trí của Serial được lưu tại thanh ghi EAX, bước thứ 2 là tìm ra vị trí của hàm MessageBox thông báo sai. Công việc tiếp theo và cũng quan trọng không kém 2 bước trước là bước thứ 3 : Edit code.
Như các bạn thấy, trong hàm MessageBox ở trên các đối số sẽ lần lượt được truyền vào theo cơ chế của Stack . Tức là đối số nào ở vị trí đầu tiên thì sẽ được truyền vào cuối cùng để khi lời gọi hàm MessageBox xuất hiện thì các đối số này sẽ được lấy ra lần lượt theo thứ tự ngược lại. Và trong ví dụ trên các bạn sẽ quan sát rất rõ điều này thông qua các lệnh Push. Để có cái nhìn thực tế hơn nữa các bạn có thể Trace để tới đoạn code bắt đầu của quá trình truyền đối số cho hàm MessageBox, trong cửa sổ Stack Window các bạn sẽ thấy như sau :

kg4

Khà khà…. các bạn có thấy gì không , khi chúng ta nhập thông tin đăng kí vào. Chương trình tiến hành tính toán và sẽ kiểm tra Serial ta nhập vào với Serial mà nó tính toán. Do chúng ta nhập Serial sai, nên sau vài bước kiểm tra chương trình sẽ Jump tới đoạn code để Pop up ra thông báo như chúng ta thấy . Các đối số được đưa vào ở đây cho phép chúng ta hiểu được có những thông tin như sau :
Tiêu đề của hộp thoại là : “ERROR”
Dòng text sẽ hiển thị trên hộp thoại là : “Invalid key”
v…v..

Vậy chúng ta sẽ phải làm gì ? Việc chúng ta phải làm là ép hàm MessageBox này thay vì nó sẽ hiện ra thông báo “Invalid key” thì ta buộc nó phải hiện Real Serial. Chúng ta đã biết địa chỉ của hàm tính toán Serial là tại 00404A6A và khi Trace qua hàm này ta nhận được Real Serial nắm ở thanh ghi EAX . Ta cũng đã biết được điểm bắt đầu của hàm MessageBox là ở địa chỉ 00404B5A. Vậy ta sẽ sửa câu lệnh ngay phía dưới của hàm tính toán để cho chương trình sẽ nhảy tới điểm bắt đầu của hàm MessageBox. Do đó tại câu lệnh :

00404A6F 8B56 5C MOV EDX, DWORD PTR DS:[ESI+5C] ; <== Fake Serial

chúng ta nhấn Space hoặc Right Click và chọn Assemble. Olly sẽ hiện ra hộp thoại Assemble cho phép chúng ta Edit lại đoạn code. Chúng ta sẽ thay lệnh trên bằng lệnh nhảy tới điểm bắt đầu của hàm MessageBox như sau, trong hộp thoại chúng ta gõ :

JMP 00404B5A

nhấn Enter , màn hình Olly sẽ hiện như sau :

kg5

Nhấn F8 để thực hiện lệnh này , nó sẽ nhảy tới điểm bắt đầu của hàm MessageBox. Để ý rằng lúc này giá trị Real Serial vẫn nằm tại thanh ghi EAX. Tiếp theo chúng ta sẽ thay đổi câu lệnh Push mà đẩy dòng text “Invalid Key” thành câu lệnh Push đẩy giá trị Real Serial. Do đó tại dòng :

00404B69 68 C4044400 PUSH Wallpape.004404C4 ; ASCII "Invalid key"

Chúng cũng thao tác tương tự và sửa nó thành :

00404B69 50 PUSH EAX

Nhấn Enter, màn hình Olly sẽ hiện như sau :

kg7

Nhấn F8 để Trace đến hàm gọi MessageBox, quan sát cửa sổ Stack các bạn sẽ thấy như sau :

kg8

Ke..Ke.. Nhìn vào đây các bạn có thể biết được khi chúng ta Trace qua hàm MessageBox thì nó sẽ hiển thị cho chúng ta cái gì rồi phải không. Đó chính là thứ mà từ đầu đến giờ chúng ta đã phải tốn nhiều giấy mực để thực hiện. Thật đáng đồng tiền bát gạo !!

kg9

Cuối cùng một công việc không thể thiếu đó là chúng ta hãy lưu lại tất cả những gì chúng ta vừa mới thực hiện . Ngay tai màn hình Olly , Right Click vào một vị trí bất kì trên màn hình Code Window và chọn Copy to Executable –> All modifications. Một hộp thọai hiện ra , ta chọn Copy All. Một màn hình mới xuất hiện , tại màn hình này chúng ta Right Click và chọn Save file. Đặt một cái tên bất kì mà chúng ta muốn và nhấn Save. Vậy là chúng ta đã có được một Internal Keygen rồi đó , đem phân phát cho mọi người thôi. : )

PS : Tại sao lại phải lưu vào , là vì trong trường hợp file chúng ta crack và save lại có kích thước nhỏ thì việc phát tán nó cho người khác rất dễ dàng. Nhưng nếu như file đó có dung lượng lớn thì chúng ta sẽ dùng file gốc và file đã được chỉnh sửa này để tạo ra một Patch file có kích thước nhỏ hơn để phân phát cho User.

III. Tổng kết :

Qua tất cả những gì tôi vừa trình bày ở trên , các bạn đã hiểu được phần nào kĩ thuật Internal Keygen là gì? Thực chất nó là kĩ thuật cho phép Cracker không phải ngồi lọ mọ nghiền ngẫm thuật toán để code ra một Keygen hoàn chỉnh , nó cho phép Cracker lợi dụng chính hàm MessageBox thông báo sai của chương trình , biến hàm này thành một hàm phục vụ cho việc hiển thị Real Serial mà chương trình đã tính toán ra. Mà để thực hiện được điều đó thì chúng ta phải biết Real Serial nằm ở đâu và hàm gọi thông báo sai nằm ở đâu để mà áp dụng kĩ thuật này một cách hợp lý và hiệu quả nhất.
Hi vọng với những gì cơ bản nhất mà tôi đã trình bày ở trên sẽ giúp ích cho các bạn phần nào trên con đường trở thành Craker
smilie

23/04/2005
-== kienmanowar ==-

– Thank to my family, Computer_Angel, Moonbaby , Zombie_Deathman, Littleboy, Benina, QHQCrker, the_Lighthouse, Hoadongnoi, Nini … all REA‘s members, HacNho, RongChauA, Deux, tlandn, dqtln, Arteam …. all my friend, and YOU. : )


Phân tích ASM và code Keygen

Lời nói đầu :

Sau khi có được cái Keygen Form như trong bài viết trước đã hướng dẫn xây dựng. Trong bài viết tiếp theo này chúng ta sẽ tiến hành việc phân tích ASM của một soft để từ đó tiến hành công việc code keygen :”đầy gian nan nhưng cũng vô cùng thú vị” . Trong bài viết này, chúng ta sẽ sử dụng soft Wallpaper v1.2 mà chú đèn đã viết trong box Newbie (http://www.reaonline.net/forum/showthread.php?t=884) để phục vụ cho việc Keygen. Bài viết này sẽ đối chiếu từng đoạn code tương ứng được nói trong bài viết của chú đèn để mọi người tiện theo dõi. Oki , giờ chúng ta bắt tay vào làm việc.

1. Phân tích ASM của soft trong Ollydbg :

– Để có thể phân tích được ASM của một soft chúng ta cần một chương trình Debug mà cụ thể ở đây là Ollydbg. Chúng ta mở Olly lên và load file Wallpaper.exe vào trong Olly. Tìm và set BP như trong bài viết của chú đèn đã nói. Sau khi đã có được điểm đặt BP tại 00404A35 , chúng ta Run chương trình bằng cách nhấn F9. Tiếp theo chúng tiến hành công việc nhập FU và FS vào trong màn hình Register của chương trình. Ở đây mình nhập như sau : FU : kienmanowar và FS : 11111982. Sau đó nhấn OK , chúng ta sẽ Ice tại điểm mà chúng ta đã set BP. Bước tiếp theo đây sẽ liên quan chặt chẽ tới bài của chú đèn. Chúng ta chú ý tới đoạn code sau :


00404A35 . 8B3B MOV EDI,DWORD PTR DS:[EBX] ; <== FU
00404A37 . B9 FFFFFFFF MOV ECX,-1
00404A3C . 2BC0 SUB EAX,EAX
00404A3E . F2:AE REPNE SCAS BYTE PTR ES:[EDI]
00404A40 . F7D1 NOT ECX
00404A42 . 49 DEC ECX ; <== Length(FU)
00404A43 . 0F84 08010000 JE Wallpape.00404B51 ; <== If Length (FU) = 0 then Jump to Nag

/* Đoạn code này sẽ kiểm tra xem chúng ta có nhập Username không, nếu như không nhập (tức là Length = 0) thì sẽ nhảy tới Nag */

– Đoạn code tiếp theo :

00404A49 . 8B7E 5C MOV EDI,DWORD PTR DS:[ESI+5C] ; <== FS
00404A4C . B9 FFFFFFFF MOV ECX,-1
00404A51 . 2BC0 SUB EAX,EAX
00404A53 . F2:AE REPNE SCAS BYTE PTR ES:[EDI]
00404A55 . F7D1 NOT ECX
00404A57 . 49 DEC ECX ; <== Length (FS)
00404A58 . 0F84 F3000000 JE Wallpape.00404B51 ; <== If Length(FS) = 0 then Jump to Nag

/* Cũng tương tự đoạn code trên , đoạn này dùng để kiểm tra xem chúng ta có nhập Serial vào không */

– Oki , chúng ta đã nhập FU và FS vào rùi nên chúng ta sẽ vượt qua được hai đoạn kiểm tra này. Chúng ta sẽ đến một đoạn code hết sức quan trọng . Đó chính là đoạn Calculation :

00404A5E . 6A 00 PUSH 0 ; /Arg1 = 00000000
00404A60 . 8BCB MOV ECX,EBX ; |
00404A62 . E8 24D40200 CALL Wallpape.00431E8B ; \Wallpape.00431E8B
00404A67 . 50 PUSH EAX ; /Arg1
00404A68 . 8BCE MOV ECX,ESI ; |
00404A6A . E8 21010000 CALL Wallpape.00404B90 ; \Wallpape.00404B90 <==Calculation(trace into)

– Sau khi Trace Into vào trong hàm trên chúng ta sẽ găp một đoạn code như sau :


00404B90 /$ 83EC 2C SUB ESP,2C
00404B93 |. C74424 00 050>MOV DWORD PTR SS:[ESP],5 ; <== Default1 = 5
00404B9B |. C74424 04 030>MOV DWORD PTR SS:[ESP+4],3 ; <== Default2 = 3
00404BA3 |. C74424 08 070>MOV DWORD PTR SS:[ESP+8],7 ; <== Default3 = 7
00404BAB |. C74424 0C 010>MOV DWORD PTR SS:[ESP+C],1 ; <== Default4 = 1
00404BB3 |. 53 PUSH EBX
00404BB4 |. 56 PUSH ESI
00404BB5 |. 57 PUSH EDI
00404BB6 |. BB 88583422 MOV EBX,22345888 ; <== Temp = 0x22345888
00404BBB |. C74424 20 020>MOV DWORD PTR SS:[ESP+20],2 ; <== Default5 = 2
00404BC3 |. C74424 24 060>MOV DWORD PTR SS:[ESP+24],6 ; <== Default6 = 6
00404BCB |. 55 PUSH EBP
00404BCC |. 6A 09 PUSH 9
00404BCE |. C74424 30 040>MOV DWORD PTR SS:[ESP+30],4 ; <== Default7 = 4
00404BD6 |. 33ED XOR EBP,EBP ; <== i = 0
00404BD8 |. 896C24 24 MOV DWORD PTR SS:[ESP+24],EBP ; <== Default8 = 0

/* Chúng ta thấy rằng đây chính là một quá trình khởi tạo giá trị ban đầu sẽ sử dụng để tính toán về sau. Việc đầu tiên nó sẽ khởi tạo các giá trị mặc định là 5 , 3, 7, 1, 0, 2, 6, 4 vào trong một mảng. Để cho tiện chúng ta sẽ gọi mảng chứa những phần tử này là reaDefault [COLOR=Red](int reaDefault[9] = {0x5, 0x3, 0x7, 0x1, 0x0, 0x2, 0x6, 0x4}; ). Tiếp theo chúng ta sẽ thấy chương trình khởi tạo một giá trị khác là 0x22345888 được cất giữ trong thanh ghi EBX , vậy chúng ta gọi một biến là Temp sẽ chứa giá trị này (unsigned long int Temp = 0x22345888smilie . Cuối cùng chúng ta để ý thấy có một lệnh XOR EBP, EBP , lệnh này làm cho giá trị của thanh ghi EBP = 0x0, cho nên ta khai báo một biến i và khởi gán là 0 (i = 0) . Việc tại sao lại đặt tên biến là i sẽ nói ngay dưới đây thôi */[/COLOR]

– Sau khi trace qua đoạn code này, chúng ta sẽ đến một đoạn code tiếp theo:

00404BE1 |. 8B5424 44 MOV EDX,DWORD PTR SS:[ESP+44] ; <== FU
00404BE5 |. 83C4 04 ADD ESP,4
00404BE8 |. 8BF0 MOV ESI,EAX
00404BEA |. 8BFA MOV EDI,EDX ; <== FU
00404BEC |. B9 FFFFFFFF MOV ECX,-1
00404BF1 |. 2BC0 SUB EAX,EAX
00404BF3 |. F2:AE REPNE SCAS BYTE PTR ES:[EDI]
00404BF5 |. F7D1 NOT ECX
00404BF7 |. 49 DEC ECX ; <== Length (FU)
00404BF8 |. 74 1A JE SHORT Wallpape.00404C14

/* Đoạn code này chỉ là việc tính toán lại chiều dài của chuỗi FU mà chúng nhập vào , Length(FU) này sẽ được sử dụng trong quá trình lặp để tính toán tiếp phía dưới */

– Qua đoạn tính toán Length ở trên chúng ta sẽ đến đoạn code tính toán như sau :

00404BFA |> /45 /INC EBP ; <== i = i + 1
00404BFB |. |8BFA |MOV EDI,EDX ; <== FU
00404BFD |. |0FBE442A FF |MOVSX EAX,BYTE PTR DS:[EDX+EBP-1] ; <== FU[i]
00404C02 |. |03D8 |ADD EBX,EAX ; <== Temp = Temp + Fu[i]
00404C04 |. |B9 FFFFFFFF |MOV ECX,-1
00404C09 |. |2BC0 |SUB EAX,EAX
00404C0B |. |F2:AE |REPNE SCAS BYTE PTR ES:[EDI]
00404C0D |. |F7D1 |NOT ECX
00404C0F |. |49 |DEC ECX ; <== Length (FU)
00404C10 |. |3BCD |CMP ECX,EBP ; <== While (Length(FU) > i)
00404C12 |.^\77 E6 \JA SHORT Wallpape.00404BFA ; <== Continue Loop

/* Tại đoạn code trên, chúng ta quan sát thấy quá trình tăng dần của thanh ghi EBP , sau đó giá trị này sẽ được đem đi so sánh với với chiều dài của FU đã đựơc cất trong ECX trong đoạn code tính Length ở trên.Đó chính là lí do tại sao chúng ta lại khai báo một biến [COLOR=Red]i . Vòng lặp này sẽ thực hiện công việc như sau , nó sẽ lấy từng kí tự trong FU sau đó thực hiện một phép cộng dồn với biến Temp (Biến Temp lúc này đang lưu giá trị là 0x22345888). Vòng lặp này sẽ thực hiện bao nhiêu lần là tùy thuộc vào vào chiều dài của chuỗi FU. Kết quả sau khi tính toán được sẽ được biến Temp lưu giữ */

Trong VC++ vòng lặp tính toán cộng dồn trên được viết như sau :

//Caculation
i = 0;
while ( i < LenUser )
{
Temp = Temp + (reaName[i] & 0xFF);
i++;
}

– Sau khi qua khỏi vòng lăp này chúng ta sẽ đến đoạn code sau :


00404C18 |. 53 PUSH EBX ; <== Temp
00404C19 |. 68 D0044400 PUSH Wallpape.004404D0 ; ASCII "%08X"
00404C1E |. 50 PUSH EAX
00404C1F |. E8 AC6B0100 CALL Wallpape.0041B7D0 ; <== TempString = Convert(Temp) to String

/* Đoạn code trên đây làm công việc chuyển đổi giá trị chứa trong biến Temp . Cụ thể là nó sẽ chuyển giá trị trong biến Temp sang chuỗi ở dạng Hexa như định dạng mà nó đã đưa ra trong lệnh [COLOR=Red]PUSH (ASCII “%08X”) . Ví dụ như sau : với chuỗi FU là kienmanowar , sau vòng lặp cộng dồn chúng ta có được biến Temp chứa giá trị sau : 0x22345D24 , sau quá trình chuyển đổi này ta sẽ có một chuỗi là “22345D24”. Chuỗi này chúng ta lưu trữ trong một biến là TempString (char reaTempString[64] = {0}; ) */

Đoạn code chuyển đổi được viết lại trong VC++ như sau :
//Convert Temp value to Hex String
wsprintf(reaTempString, "%08X",Temp);

– Trace tiếp chúng ta sẽ đến đoạn code dưới đây :


00404C27 |. 33C0 XOR EAX,EAX ; <== i = 0
00404C29 |> 8B4C84 10 /MOV ECX,DWORD PTR SS:[ESP+EAX*4+10]; <== j = Default [i]
00404C2D |. 40 |INC EAX ; <== i = i + 1
00404C2E |. 83F8 08 |CMP EAX,8
00404C31 |. 8A4C0C 30 |MOV CL,BYTE PTR SS:[ESP+ECX+30] ; <== TempString[j]
00404C35 |. 884C06 FF |MOV BYTE PTR DS:[ESI+EAX-1],CL ; <== reaTempSerial[i] = TempString[j]
00404C39 |.^ 72 EE \JB SHORT Wallpape.00404C29

/* Trong đoạn code trên chúng ta nhận thấy lại có quá trình tăng dần của EAX cho nên ta lại khởi gán biến i = 0 . Vòng lặp này làm nhiệm vụ như sau, nó sẽ lấy các giá trị trong biến reaTempString theo những vị trị đã được khai báo trong biến reaDefault. Mà để lấy được các giá trị trong biến reaDefault chúng cần một biến j . Do đó ta khai báo thêm một biến j . Vòng lặp này sẽ được thực hiện [COLOR=Red]8 lần , để cho ra một chuỗi chứa trong reaTempSerial , mà thực chất chuỗi này chỉ là xáo trộn các vị trí trong reaTempString mà thôi. Thực ra sau quá trình này thì reaTempSerial chính là Real Serial , nhưng để dễ hiểu ta cứ gọi là reaTempSerial */

Đoạn code tương ứng được viết lại trong VC++ :

//Creat reaTempSerial
i = 0;
while (i < 8)
{
j = reaDefault[i];
reaTempSerial[i] = reaTempString[j];
i++;
}

– Cuối cùng sau khi chúng ta qua khỏi vòng lặp này chúng ta sẽ đi đến đích cuối cùng :


00404C3B |. 8BC6 MOV EAX,ESI ; <== Right Serial

/* Chúng ta sẽ thấy được Right Serial ngay tại câu lệnh trên */

Đoạn code tương ứng trong VC++ :

wsprintf(reaSerial,reaTempSerial);

2. Code Keygen trong VC++ :

Dựa vào tất cả những gì đã phân tích rất chi tiết ở trên , chúng ta chỉ việc ghép lại để có một đoạn code Keygen hoàn chỉnh như sau :


void CKEYGENDlg::OnGenerate()
{
// TODO: Add your control notification handler code here

char reaName[64]={0};
char reaSerial[64]={0};
char reaTempString[64] = {0};
char reaTempSerial[64] = {0};

unsigned long int Temp = 0x22345888;
int reaDefault[9] = {0x5, 0x3, 0x7, 0x1, 0x0, 0x2, 0x6, 0x4};
int i=0,j=0, LenUser=0;

LenUser=GetDlgItemText(IDC_NAME,reaName,128);
if (LenUser < 1 || LenUser > 64)
{
MessageBox(” ———-===== Your name atleast 1 chart =====———- \n\n———-===== But not over than 64 charts =====———- “,”Hey !! Please input your name again !! “);
}
else
{

// Calculation
i = 0;
while ( i < LenUser )
{
Temp = Temp + (reaName[i] & 0xFF);
i++;
}

//Convert Temp value to Hex String
wsprintf(reaTempString, “%08X”,Temp);

//Creat reaTempSerial
i = 0;
while (i < 8)
{
j = reaDefault[i];
reaTempSerial[i] = reaTempString[j];
i++;
}

wsprintf(reaSerial,reaTempSerial);
}

SetDlgItemText(IDC_SERIAL,reaSerial);

}

Trên đây một trong số các cách thức để một cracker thực hiện công việc code keygen . Sau khi bạn đọc xong bài viết này , bạn có cảm thấy dễ dàng hơn không? smilie . Thực sự Keygen nhiều lúc không đơn giản , nó đòi hỏi cả một nghệ thuật để làm sao đoạn code ngắn gọn , trong sáng nhất. Trong 4room này thì anh Moon là người có khả năng đó (và còn nhiều người khác nữa trong đội ngũ BQT của REA :wub: ). Em chỉ là Super Newbie học đòi theo anh Moon mà thôi. Hi vọng với bài viết với tinh thần truyền tải những gì hết sức basic như trên , các bạn sẽ định hình được phần nào công việc code Keygen của mình.

03/03/2005

Best Regards

kienmanowar


..::[Cách đưa một file ảnh vào trong Keygen Form]::..

===========================================

_\\|//_

(‘ * * ‘)

_____________________________ooO_(_)_Ooo_____________________________

_”Đồ nghề” mà chúng ta cần phải chuẩn bị là 1 form cần đưa ảnh vào và một ảnh bất kì dạng .bmp.

_Giả sử chúng ta có một Keygen Form như sau (Bác nào chưa biết cách tạo thì đọc bài viết cũ của tôi) :

_Ngày trước mới theo sư phụ Moon tập tọe code Keygen , hiii cũng muốn làm cho cái Keygen của mình đẹp bằng anh bằng em nhưng khổ nỗi lúc đó trình độ có hạn, có muốn cũng chẳng được. Sau mấy buổi học Coding online cùng sư phụ cuối cùng thì cũng tạo được form và code được keygen cho một em. Hic lúc đó có được cái form , cộng thêm vừa viết được keygen cho soft là đã thấy “phê” lắm rồi. Cứ thế là crack + code hùng hục như trâu :), chẳng để ý gì đến cái “Interface” của Keygen. Hic nhân tiện có chú Merc hỏi cách đưa ảnh vào Form như thế nào, về nhà lục lọi lại “em yêu” ngày xưa. Hic trông em tàn tạ quá :), đành lôi ra vọc thử xem để đưa cái ảnh vào cho nó hoành tráng.

_Hic như các bác đã nhìn thấy dung nhan của “em yêu” ở trên thì thấy không còn hợp thời nữa rùi. Cần chỉnh sửa “nhan sắc” lại một chút. Bây giờ tôi muốn thay thế cái Label : Reversing Engineering Association thành một bức ảnh mang phong cách của REA thì làm thế nào? Hii có lời giải đáp ngay đây thôi, chẳng có gì là cao siêu cả , đọc xong các bác lại nói tôi cần gì phải viết lách cho nó dài dòng :).

_Oki để có thể đưa ảnh vào trong Form , ta làm như sau: đầu tiên chúng ta xóa cái Label mà chúng ta muốn thay thế đi.Chuyển qua ResourceView, tại đây chúng ta sẽ Import một file ảnh dạng bimap vào trong Resource. Đế có thể Import được các bạn làm như hình minh họa dưới đây :

………

Download toàn bộ bài viết tại đây :

https://kienmanowar.files.wordpress.com/2009/03/import_image_into_keygen_form.doc

Best Regards

kienmanowar


Xây dựng Keygen Form trong VC++

Lời nói đầu :

Bài viết này không nhắm tới mục đích ép buộc mọi người phải tạo dựng một Form theo chuẩn mà chỉ cung cấp những kiến thức tối thiểu……hiii chỉ là tối thiểu thôi nhé (basic) để Newbie mới tiếp cận với VC++ có thể dễ dàng xây dựng một Form dùng cho việc học code keygen sau này. Lý do tại sao em lại viết bài viết này , đó là vì muốn chia sẻ những kiến thức mà em biết được . Cũng giống như các bác Newbie bây giờ thôi, lần đầu tiên khi tiếp xúc với VC++ thấy rất khó khăn nhưng nhờ có sự giúp đỡ của anh Moon cộng với “mưa dầm thấm lâu” nên cái đầu ngu muội của tôi cũng mở mang ra chút ít. Hi vọng với bài viết này sẽ giúp cho các bác phần nào trong việc học VC++

1. Tạo dựng vùng làm việc (Project WorkSpace) :

Nếu như các bác đã từng lập trình trên một ngôn ngữ nào đó thì điều đầu tiên cần phải làm là tạo dựng một dự án hay một không gian làm việc. Đối với VC++ cũng vậy , mọi ứng dụng trên VC++ muốn phát triển phải có một dự án (project).Một không gian làm việc trong VC++ là nơi bao gồm các thư mục lưu trữ mã nguồn của ứng dụng , cũng như các file cấu hình v..v.. Để tạo một project chúng ta làm như sau :

Chọn File > New để mở cửa sổ New Wizards tương tự như hình minh họa dưới đây :

vc1

Tại đây, trong Projects tab chọn kiểu Project mà chúng ta muốn phát triển . Do như đã nói ở phần tiêu đề trên , ở đây chúng ta chọn kiểu Projects là MFC AppWizard(exe) . Trong textbox Project name chúng ta nhập vào là Keygen . Mặc định Project này sẽ được lưu theo đường dẫn sau : E:\Program Files\Microsoft Visual Studio\MyProjects\. Nếu muốn có thể hoàn toàn đổi thư mục lưu trữ Project. Sau khi hoàn tất công việc này nhấn OK để chuyển sang bước tiếp theo.

Oki sau khi nhấn OK , một màn hình khác sẽ hiện ra đó chính là MFC Wizards . Màn hình này sẽ cung cấp cho chúng ta những lựa chọn theo từng Step với những câu hỏi lựa chọn , qua đó chúng ta chọn kiểu ứng dụng mà chúng ta sẽ xây dựng , các đặc điểm cũng như những chức năng mà chúng ta cần. Quá trình này bao gồm 6 Step như sau :

a. Step 1 cho phép chúng ta chọn kiểu ứng dụng mà chúng ta muốn xây dựng . Cụ thể ở đây ta chọn là Dialog Based. Language để mặc định là English (United States). Sau đó nhấn Next .

b. Step 2 cho phép chúng ta chọn các Features cho ứng dụng . Tại bước này chúng ta uncheck ô ActiveX Controls . Còn Tile của Dialog cứ để nguyên hoặc nhập gì tùy thích , không quan trọng.

c. Step 3 , do chúng ta chọn kiểu Project là MFC cho nên ở bước này style của project mặc định là MFC Standard . Nếu bạn muốn tạo các file chú thích thì có thể chọn Yes còn không thì chọn No tùy mọi người. Còn trong phần Library chúng ta nên chọn ô As a statically linked library. Sau đó nhấn Next.

d. Step 4 cho chúng ta biết sẽ tạo các Class cho ứng dụng của chúng ta. Nhấn Finish để hoàn tất

e. Một màn hình mới hiện lên thông báo cho chúng ta biết về thông tin của Project .


vc2

f. Nhấn OK , Form của ứng dụng sẽ xuất hiện như hình minh họa dưới đây :


vc3

Oki , như các bác thấy việc xây dựng Project rất đơn giản và trực quan. Thông qua một sổ Step chúng ta đã có một Project dùng cho công việc Keygen rồi .

2. Thiết kế giao diện :

Trước tiên , chúng ta xóa bỏ cái Label : TODO… trên form đi. Thậm chí xóa bỏ 2 nút OK và Cancel đi . Chúng ta sẽ xây dựng lại từ đầu .
Để đổi tên cho form , ta click chuột phải trên form chọn Properties , trong phần Caption này chúng ta sẽ gõ vào tên bất kì mà bạn muốn chẳng hạn tên soft và version của soft mà chúng ta định Keygen.
Sau đó chúng ta sẽ đưa các điều khiển lên Form , tương tự như hình minh họa dưới đây :


vc4

Object Property Setting
Static Text ID IDC_STATIC
Caption REVERSE ENGINEERING ASSOCIATION

Static Text ID IDC_STATIC
Caption ------==Copyright (C) 2004 - REA - cRaCkErTeAm ==------

Static Text ID IDC_STATIC
Caption Name :

Static Text ID IDC_STATIC
Caption Serial :

Edit Box ID IDC_NAME

Edit Box ID IDC_SERIAL

Button ID IDC_GENERATE
Caption ---==Generate==---

Button ID IDC_REA
Caption ---==REA==---

Button ID IDC_EXIT
Caption ---==Exit==---

Cách thêm các điều khiển vào Form hết sức dễ dàng và đơn giản nhờ vào thanh Control của VC++ .


vc5

Ngoài ra sau khi thêm các điều khiển vào Form , các bạn có thể tùy biến các thuộc tính của các điều khiển như canh lề cho đoạn text gõ vào text box hoặc chọn các kiểu Styles cho điều khiển . Việc này được thực hiện thông qua việc Click chuột phải vào điều khiển và chọn Properties. Cài này xin nhường cho các bạn tự khám phá.

Trên đây chỉ là những gì cơ bản nhất trong quá trình làm việc với VC++ mà thôi. Nếu muốn tìm hiểu kĩ hơn các bạn nên tìm đọc quyển VC++ 21days để có được những kiến thức cơ bản và đầy đủ hơn.

Have Fun ! 😀