## Chal4 – Easy Keygen Challenge

Posted: January 26, 2016 in Chal4. Easy Keygen Challenge
Tags:

Rule: Find the Name when the Serial is 5B134977135E7D13

With the above Serial, we can guess the Name will have 8 characters. Combine analysis target by both IDA and OllyDBG, we have the pseudo code is:

```int __cdecl main(int argc, const char **argv, const char **envp)
{
signed int j; // ebp@1
signed int i; // esi@1
int result; // eax@6
int v6; // [sp+0h] [bp-13Ch]@0
int v7; // [sp+0h] [bp-13Ch]@1
char defVal[3]; // [sp+Ch] [bp-130h]@1
char szBuff; // [sp+10h] [bp-12Ch]@1
char v10; // [sp+11h] [bp-12Bh]@1
__int16 v11; // [sp+71h] [bp-CBh]@1
char v12; // [sp+73h] [bp-C9h]@1
char szCalSerial; // [sp+74h] [bp-C8h]@1
char v14; // [sp+75h] [bp-C7h]@1
__int16 v15; // [sp+139h] [bp-3h]@1
char v16; // [sp+13Bh] [bp-1h]@1

szBuff = 0;
szCalSerial = 0;
memset(&v10, 0, 0x60u);
v11 = 0;
v12 = 0;
memset(&v14, 0, 0xC4u);
v15 = 0;
v16 = 0;
defVal[0] = 0x10;
defVal[1] = 0x20;
defVal[2] = 0x30;
sub_4011B9((int)"Input Name: ", v6);
scanf("%s", &szBuff);
j = 0;
for ( i = 0; j < (signed int)strlen(&szBuff); ++i ) { if ( i >= 3 )
i = 0;
sprintf(&szCalSerial, "%s%02X", &szCalSerial, *(&szBuff + j++) ^ defVal[i]);
}
memset(&szBuff, 0, 0x64u);
sub_4011B9((int)"Input Serial: ", v7);
scanf("%s", &szBuff);
if ( !strcmp(&szBuff, &szCalSerial) )
{
sub_4011B9((int)"Correct!\n", *(int *)defVal);
result = 0;
}
else
{
sub_4011B9((int)"Wrong\n", *(int *)defVal);
result = 0;
}
return result;
}
```

Very clearly, this code gets the Input Name to szBuff. Through the loop to convert the Input Name by using XOR operator with defVal array and finally store value at szCalSerial. After that it compares Input Serial with szCalSerial, so szCalSerial must equal “5B134977135E7D13”. Perform reverse the XOR calculations we’ll have the correct Input Name:

```Input_Name[0] ^ 0x10 = 5B -> 4B K
Input_Name[1] ^ 0x20 = 13 -> 33 3
Input_Name[2] ^ 0x30 = 49 -> 79 y
Input_Name[3] ^ 0x10 = 77 -> 67 g
Input_Name[4] ^ 0x20 = 13 -> 33 3
Input_Name[5] ^ 0x30 = 5E -> 6E n
Input_Name[6] ^ 0x10 = 7D -> 6D m
Input_Name[7] ^ 0x20 = 13 -> 33 3
```
• Right Input Name : K3yg3nm3

End.

1. Nguyễn Nhật Tân says:

Dạ anh ơi, đoạn defVal[i] theo mặc định mã giả IDA tương ứng là v6, v7, v8; em muốn hỏi anh là anh đổi tên biến để cho bài viết dễ hiểu hơn (chỉnh sửa trên editor chứ không phải trực tiếp trên IDA), hay là anh sửa lúc làm challenge để dễ làm hơn (chỉnh sửa trực tiếp trên IDA), nếu cái sau thì anh sửa 3 biến thành một mảng tự động đếm với i trên IDA thì làm sao ạ? Em cảm ơn anh nhiều.

2. kienmanowar says:

@Tân:
Chào em, anh sửa trực tiếp từ IDA nên khi sinh pseudo code sẽ ra như trong bài viết nhé. Để tạo mảng tự động như thế trên IDA, sau khi em đọc code và biết nó là array, em nhấp đúp vào một biến, IDA sẽ chuyển sang cửa sổ biểu diễn Stack layout của hàm. Lúc này, căn cứ vào kích thước của mảng, ở đây ví dụ mảng có 3 phần tử là v6, v7, v8 đi, em dùng chuột chọn cả 3 biến này và nhấn chuột phải chọn Array. IDA sẽ hiển thị cho em Array size, … nhấn OK, em sẽ tạo được mảng mong muốn. Sau đó em đổi tên như anh là được!

Good luck!
Regards,

3. Nguyễn Nhật Tân says:

Dạ em làm được rồi, cảm ơn anh nhiều ^^. Anh ơi, em muốn hỏi tiếp là: “%s%02X”, mặc định là aS02x, rất dễ nhầm lẫn và khó nhìn với newbie như em, em muốn hỏi làm sao anh đổi sang là data string của nó cho dễ nhìn ạ?
Còn nữa ạ,ở câu lệnh:
sprintf(&szCalSerial, “%s%02X”, &szCalSerial, *(&szBuff + j++) ^ defVal[i]);
em không hiểu tham số &szCalSerial thứ 2 để làm gì nữa, em nghĩ là *(&szBuff + j++) XOR defVal[i] sẽ lưu vào &szCalSerial, với format “%s%02X” là đủ tham số rồi chứ ạ.
Em hơi phiền chút, mong anh bỏ qua 😀

4. kienmanowar says:

Câu thứ nhất: Em thử vào phần Options > Genernal > Strings, chỗ Prefix em chuyển thành sz thay vì là a.

Câu thứ hai: Cái này là do code của chương trình thôi em. Như em phân tích là đúng rồi. Tuy nhiên, trong code asm, có hai lệnh push eax & push ecx, mà cả hai thanh ghi này cùng trỏ tới vùng buffer szCalSerial, nên khi gọi hàm sẽ có 4 tham số và mã giả sinh ra là như thế.

Chúc em vui vẻ!
Regards,

5. Nguyễn Nhật Tân says:

Dạ em cảm ơn anh.
Với vấn đề thứ nhất: Em muốn làm rõ hơn thắc mắc của mình: mặc định pseudo code nó sẽ hiển thị string đó là aS02x, trong khi em thấy của anh dễ nhìn ra hơn với newbie như em, là “%s%02X”. Em muốn hỏi anh làm sao để nó chuyển về chuỗi như vậy cho dễ nhìn hơn đó ạ? Còn prefix em nghĩ không cần thiết phải thay đổi.
Từ vấn đề thứ nhất lại nảy sinh vấn đề mà em gặp nhiều lần, không biết của anh có gặp rồi hay chưa. Đó là khi mình đã tùy chỉnh rồi và đã lưu lại, nhưng đến phiên làm việc tiếp theo thì nó luôn trở về mặc định. Lúc trước em gặp ở việc muốn chọn auto comments, nhưng IDA cứ không lưu tùy chọn đó, khiến em phải vào file ida.cfg để sửa lại. Tuy nhiên nhiều tùy chọn em lại không tìm ra ở file configure và không biết tìm ở đâu, nên rất khó chịu. Em xin anh ít kinh nghiệm sử dụng IDA ở vấn đề này ạ, em cảm ơn anh.
Chúc anh 1 ngày vui vẻ 😀

6. kienmanowar says:

Bản IDA em đang dùng là bản nào? Anh đang dùng IDA 6.8 và của anh hiển thị thế nên cũng ko rõ phải giải thích sao :D. Cả ở Disassembly lẫn Pseudo code:

.text:0040108A lea eax, [esp+13Ch+var_C8]
.text:0040108E push ecx
.text:0040108F push eax
.text:00401090 lea ecx, [esp+144h+var_C8]
.text:00401094 push offset szS02x ; “%s%02X” <–
.text:00401099 push ecx ; char *
.text:0040109A call _sprintf

Còn việc em chỉnh trong Options mà nó không lưu, rồi phải chỉnh lại trong .cfg là bình thường, có những option anh cũng phải chỉnh như thế 😛

Thân mến!

7. Nguyễn Nhật Tân says:

Dạ em cảm ơn anh nhiều. Em mới học RE và sử dụng IDA, còn nhiều điều chưa biết ạ, hiện tại em đang dùng bản 7.0. 😀

8. kienmanowar says:

Okie em,

IDA 7 anh cũng đang xài, kết quả cũng tương tự như trên nhé:

.text:0040107E loc_40107E: ; CODE XREF: _main+7A↑j
.text:0040107E movsx ecx, [esp+esi+13Ch+var_130]
.text:00401083 movsx edx, [esp+ebp+13Ch+var_12C]
.text:00401088 xor ecx, edx
.text:0040108A lea eax, [esp+13Ch+var_C8]
.text:0040108E push ecx
.text:0040108F push eax
.text:00401090 lea ecx, [esp+144h+var_C8]
.text:00401094 push offset szS02x ; “%s%02X”
.text:00401099 push ecx ; char *
.text:0040109A call _sprintf

9. Nguyễn Nhật Tân says:

Dạ em kiểm chứng rồi anh :v Tại anh hỏi nên em nói. Anh nhiệt tình quá 😀 Em cảm ơn anh nhiều!

10. kienmanowar says:

Ok em, nếu vui anh sẽ public một bộ viết về IDA!

11. nightFury says:

@Tân
“`
Còn nữa ạ,ở câu lệnh:
sprintf(&szCalSerial, “%s%02X”, &szCalSerial, *(&szBuff + j++) ^ defVal[i]);
em không hiểu tham số &szCalSerial thứ 2 để làm gì nữa, em nghĩ là *(&szBuff + j++) XOR defVal[i] sẽ lưu vào &szCalSerial, với format “%s%02X” là đủ tham số rồi chứ ạ.
“`
Bạn hiểu đúng rồi, theo mình hiểu thì ở lệnh sprintf() đó, cái tham số thứ 2 mà bạn thắc mắc, bạn cứ hiểu như là nó kết hợp với vòng for để làm phép nối chuỗi bình thường thôi.

Vì bạn dùng 1 tham số nó sẽ bị viết đè vào szCalSerial ấy, nên là thêm 1 cái szCalSerial nữa để nó nối chuỗi mới vào sau chuỗi ban đầu.
Ví dụ A -> AB -> ABC ấy. Sorry vì mình diễn đạt có thể hơi lộn xộn khó hiểu.

Bạn cứ thử code lại bằng C thì sẽ hiểu thôi.

12. Nguyễn Nhật Tân says:

@nightFury: Mình/em cảm ơn bạn/anh chỉ thêm ví dụ cho dễ hiểu ạ

This site uses Akismet to reduce spam. Learn how your comment data is processed.