007D2383 |> 47 |INC EDI 007D2384 |. 43 |INC EBX 007D2385 |. 4E |DEC ESI 007D2386 |.^ 75 A7 \JNZ SHORT dumped_.007D232F ; Encrytp Name Tiếp theo cũng chẳng có gì wan trọn EBX tăng lên 1 để trỏ đến kí tự tiếp theo (và đồng nghĩa ở phép cộng EDX = EBX + EDI, EBX cũng thay đổi há). Code: 007D2341 |. 8B45 FC |MOV EAX, [LOCAL.1] 007D2344 |. 0FB64418 FF |MOVZX EAX, BYTE PTR DS:[EAX+EBX-1] 007D2349 |. 8D143B |LEA EDX, DWORD PTR DS:[EBX+EDI] 007D234C |. 2BC2 |SUB EAX, EDX 007D234E |. 8D55 E4 |LEA EDX, [LOCAL.7] 007D2351 |. E8 FA9AC3FF |CALL dumped_.0040BE50 Đoạn code này là ở phần Check Code: 007D233D |. 3BC2 |CMP EAX, EDX 007D233F |. 7E 22 |JLE SHORT dumped_.007D2363 ; If EAX (Name.SubString) <= EDX Then Jump Trong trường hợp EAX > EDX thì sẽ vô đoạn này Nó cũng tương tự đoạn khi Jump. chỉ khác là. Code: 007D234C |. 2BC2 |SUB EAX, EDX Rồi OK hén Tóm lại Function này có nhiệm vụ mã hóa chuỗi Name (sau khi đã fixed Length) thành 1 chuỗi mã Hex. Đoạn mã hóa tóm tắt lại sẽ như sau: - Nhận vào Name. Loop lấy từng Char trong Name ra - Nhận vào đối số cho EDX (trong trường hợp này là nhận vào giá trị 1Ah). Hay là đối số thứ 2 của cả Function chính. - EDX = EDX + 46h Nếu EAX <= EDX thì - Lấy Char trong Name ra - EDX = EBX + EDI. Trong đó EBX là giá trị tương ứng vị trí Char đang trỏ tới (tính Char đầu tiên = 1). Còn EDI là giá trị được truyền vào ban đầu (cũng có thể xem nó như một đối số). - EAX = EAX + EDX sau đó convert ra Hex Ngược lại nếu EAX > EDX thì EAX = EAX - EDX Do đó nhìn tóm lại ta có thể xem như ở đây (tạm gọi Loop này là Function EncryptName) Function nhận vô các đối số sau - Name - Giá trị khởi tạo cho EDX - Giá trị khởi tạo cho EDI sau đó thì xử lý như nêu trên ok ? Zom tạm viết lại Function EncryptName bằng Visual Basic .NET như sau: Code: Shared Function EncryptName(ByVal in_strName As String, _ ByVal in_intStartEDI As Integer, Optional ByVal in_intStartEDX As Integer = 0) As String Dim out_strEncryptedName As String Dim intEAX As Integer Dim intEBX As Integer Dim intEDI As Integer = in_intStartEDI Dim intEDX As Integer If in_strName = "" Then Return "" Else For intEBX = 1 To in_strName.Length intEAX = Asc(in_strName.Substring(intEBX - 1, 1)) intEDX = intEBX + intEDI If intEAX <= &H46 + in_intStartEDX Then intEAX = intEAX + intEDX Else intEAX = intEAX - intEDX End If out_strEncryptedName = out_strEncryptedName & intEAX.ToString intEDI = intEDI + 1 Next Return out_strEncryptedName End If End Function OK giờ thì tiếp tục nào. Code: 007D2388 |> \BB 31000000 MOV EBX, 31 007D238D |. EB 20 JMP SHORT dumped_.007D23AF 007D238F |> 8D45 DC /LEA EAX, [LOCAL.9] 007D2392 |. 8BD3 |MOV EDX, EBX 007D2394 |. E8 6338C3FF |CALL dumped_.00405BFC 007D2399 |. 8B55 DC |MOV EDX, [LOCAL.9] 007D239C |. 8D45 F4 |LEA EAX, [LOCAL.3] 007D239F |. E8 6439C3FF |CALL dumped_.00405D08 007D23A4 |. 43 |INC EBX 007D23A5 |. 83FB 39 |CMP EBX, 39 007D23A8 |. 75 05 |JNZ SHORT dumped_.007D23AF 007D23AA |. BB 31000000 |MOV EBX, 31 007D23AF |> 8B45 F4 MOV EAX, [LOCAL.3] ; MOV EAX, EncryptedName 007D23B2 |. E8 4939C3FF |CALL dumped_.00405D00 ; Name.Length 007D23B7 |. 83F8 14 |CMP EAX, 14 007D23BA |.^ 7C D3 \JL SHORT dumped_.007D238F Heheh Khúc này đây. Đúng ! Nhìn nó cũng là Loop để Insert Chars vào sau chuỗi. Nhưng lần này EBX khởi tạo giá trị = 31 Còn ai nhớ lần trước cũng hàm Loop tương tự này không ???? Nhưng EBX khởi tạo = 21h hehe OK Vậy còn gì nữa tận dụng lại Function đó luôn, truyền đối số vào là EBX = 31h cho lần này :D Hey Bình tĩnh easy take it easy Nhìn kĩ xem hoàn toàn giống 100% không ??? Không Chú ý ở Loop này khống chế EBX khi lên tới 39h là way về lại 31h Trong khi đó ở Loop trước với EBX = 21h thì hoàn toàn không có khống chế giá trị max EBX Ngoài ra số lần Loop cũng khác nhau. Vậy sao ? Viết lại 1 Function FixEncryptedNameLength mới ??? òh cũng được Nhưng Zom thì lại làm như sau. Code: Shared Function FixLength(ByVal in_strName As String, ByVal in_byteLoopCount As Byte, _ ByVal in_byteStart4CrypName As Byte, Optional ByVal in_byteMaxValue As Byte = 0) As String Dim intIndex As Integer = in_byteStart4CrypName If in_strName.Length <= 0 Then Return "" Else Do While in_strName.Length < in_byteLoopCount in_strName = in_strName & Chr(intIndex) intIndex = intIndex + 1 If (intIndex > in_byteMaxValue) And (in_byteMaxValue > 0) Then intIndex = in_byteStart4CrypName End If Loop ' End If Return in_strName End Function Toàn bộ đều sử dụng Parameters truyền vào hết. - Số lần Loop: in_byteLoopCount - Giá trị khởi tạo EBX: in_byteStart4CrypName - Giá trị max EBX: in_byteMaxValue. Mặc định giá trị này = 0. Khi Loop nếu check in_byteMaxValue > 0 (tức ta có gán max EBX) và check EBX khi đó > in_byteMaxValue thì cho reset EBX về lại in_byteStart4CrypName. OK ? Code: 007D23BC |. BB 01000000 MOV EBX, 1 007D23C1 |> 8D45 D8 /LEA EAX, [LOCAL.10] 007D23C4 |. 8B55 F4 |MOV EDX, [LOCAL.3] 007D23C7 |. 8A541A FF |MOV DL, BYTE PTR DS:[EDX+EBX-1] 007D23CB |. E8 2C38C3FF |CALL dumped_.00405BFC 007D23D0 |. 8B55 D8 |MOV EDX, [LOCAL.10] 007D23D3 |. 8D45 F0 |LEA EAX, [LOCAL.4] 007D23D6 |. E8 2D39C3FF |CALL dumped_.00405D08 007D23DB |. 43 |INC EBX 007D23DC |. 83FB 06 |CMP EBX, 6 007D23DF |.^ 75 E0 \JNZ SHORT dumped_.007D23C1 ; Part 1 Đoạn Code này cho qua lẹ Chẳng có gì Nó lấy ra 6 Chars trong EncryptedName để là Part 1 của Serials. Tạm Code cái Function Gen Part 1 như sau: Code: Shared Function Part1(ByVal in_strEncryptedName As String, Optional ByVal in_bytePartLength As Byte = 6) As String If (in_strEncryptedName = "") Or (in_strEncryptedName.Length < in_bytePartLength) Then Return "" Else Return in_strEncryptedName.Substring(0, in_bytePartLength) End If End Function Sử dụng Parameter PartLength nhằm tính trước trường hợp Part 1 có thay đổi về Length ta vẫn tận dụng lại Code được. Code: 007D23E1 |. 8D45 F0 LEA EAX, [LOCAL.4] 007D23E4 |. BA C4257D00 MOV EDX, dumped_.007D25C4 007D23E9 |. E8 1A39C3FF CALL dumped_.00405D08 ; Insert "-" Insert "-" vào Part 1 để phân cách với Part 2. Code: 007D23F0 |. 8A45 FB MOV AL, BYTE PTR SS:[EBP-5] ; 9 ??? 007D23F3 |. 83F8 0B CMP EAX, 0B ; Switch (cases 1 B) 007D23F6 |. 0F87 E0000000 JA dumped_.007D24DC 007D23FC |. FF2485 03247D>JMP NEAR DWORD PTR DS:[EAX*4+7D2403] Select Case LicenseType. Ở đây là System Mechanic 6 (Standard) nên là Case 9. Code: 007D24B1 |> \8D45 F0 LEA EAX, [LOCAL.4] ; Case 9 of switch 007D23F3 007D24B4 |. BA 30267D00 MOV EDX, dumped_.007D2630 ; ASCII "S6" 007D24B9 |. E8 4A38C3FF CALL dumped_.00405D08 ; Insert Prefix Tiếp theo khúc này có một chút thú vị với 2 Instruction ASM khá lạ: . 6439C3FF |CALL dumped_ .00 405 D08 00 7D23A4 |. 43 |INC EBX 00 7D23A5 |. 83FB 39 |CMP EBX, 39 00 7D23A8 |. 75 05 |JNZ SHORT dumped_ .00 7D23AF 00 7D23AA |. BB 3 10 000 00 |MOV EBX, 31 00 7D23AF |> 8B45. 00 7D23BC |. BB 01 0 00 000 MOV EBX, 1 00 7D23C1 |> 8D45 D8 /LEA EAX, [LOCAL . 10 ] 00 7D23C4 |. 8B55 F4 |MOV EDX, [LOCAL.3] 00 7D23C7 |. 8A541A FF |MOV DL, BYTE PTR DS:[EDX+EBX -1] 00 7D23CB |. E8. dumped_ .00 405 BFC 00 7D23D0 |. 8B55 D8 |MOV EDX, [LOCAL . 10 ] 00 7D23D3 |. 8D45 F0 |LEA EAX, [LOCAL.4] 00 7D23D6 |. E8 2D39C3FF |CALL dumped_ .00 405 D08 00 7D23DB |. 43 |INC EBX 00 7D23DC |. 83FB 06 |CMP