Objective
The goal is to modify a program that checks a product key by altering the binary to always pass the check, regardless of the input.
Tutorial Video
If you’d like a visual walkthrough, watch the tutorial below:
Step-by-Step Guide
Step 1: Understand the Program Structure
- Obtain the Program Code or Binary: Start with the program’s source code or compiled binary. In this case, we have a C program that validates a product key using a hash function.(you can find the source code here)
-
Identify the Hash Function:
- The code contains a hash function (based on DJB2) that computes a hash for the input product key.
- This computed hash is then compared to a hardcoded hash value. If they match, the program grants access.
-
Analyze the Program Logic: The program’s validation flow looks like this:
- Prompt for the product key.
- Hash the product key input.
- Compare the computed hash with a predefined value.
- Allow access if the hashes match; otherwise, deny access.
Step 2: Compile and Test the Program
-
Compile the Program (if you have the source code): Use a C compiler (like GCC) to compile the code:
gcc -o product_key_checker product_key_checker.c
This produces an executable file (
product_key_checker.exe
on Windows). - Run the Program: Run the compiled binary to understand its behavior and confirm that it only accepts a valid product key.
- Identify a Known Valid Product Key (Optional):
If possible, run tests to identify a product key that hashes to the correct value. For example, if
199
hashes to the expected value, use it to test the binary’s validation behavior.
Step 3: Disassemble the Binary to Locate the Comparison
-
Disassemble the Binary: Use a disassembler like
objdump
to inspect the binary:objdump -d product_key_checker.exe > disassembled_code.txt
This generates a disassembly file (
disassembled_code.txt
) with assembly instructions. - Locate the Main Function:
Search for the
main
function in the disassembly to find the product key validation logic. -
Identify the
cmp
Instruction: Look for acmp
instruction inmain
that compares the computed hash with the hardcoded hash. It might look like this:3d e8 8a 87 0b cmp $0xb878ae8, %eax
Here,
3d e8 8a 87 0b
in hexadecimal representscmp $0xb878ae8, %eax
, where0xb878ae8
corresponds to193432296
.
Step 4: Plan the Modification to Bypass Validation
- Objective: Change the
cmp
instruction to always evaluate as “equal.” - Modify
cmp
to Compareeax
with Itself: Replacecmp $0xb878ae8, %eax
withcmp %eax, %eax
, which will always yield equality since a register compared to itself is always equal. The hexadecimal forcmp %eax, %eax
is39 c0
. - Fill Remaining Bytes with
NOP
: Since the original instruction is 5 bytes andcmp %eax, %eax
is only 2 bytes, useNOP
(90
) to fill the remaining bytes. This keeps the program aligned. -
Final Byte Sequence: Replace
3d e8 8a 87 0b
with:39 c0 90 90 90
Step 5: Modify the Binary in a Hex Editor
- Open the Binary:
Open the compiled program (
product_key_checker.exe
) in a hex editor (like HxD). - Locate the Comparison Instruction:
Search for the byte sequence
3d e8 8a 87 0b
in the hex editor. - Edit the Bytes:
Replace
3d e8 8a 87 0b
with39 c0 90 90 90
to force the comparison to always succeed.
Step 6: Save and Test the Modified Program
- Save the Modified Binary: Save the file after making changes in the hex editor.
- Run the Modified Program:
Run
product_key_checker.exe
to test it. Now, the program should accept any product key, as the comparison is forced to succeed.
Summary of Steps
- Analyze the Program: Identify the hash check and validation logic.
- Locate
cmp
Instruction: Find thecmp
instruction in the disassembled code. - Plan the Modification: Change
cmp $0xb878ae8, %eax
tocmp %eax, %eax
. - Edit in Hex Editor: Replace
3d e8 8a 87 0b
with39 c0 90 90 90
. - Save and Test: Run the modified binary to confirm that the product key check is bypassed.
This process effectively alters the binary’s validation flow, allowing any input as a valid product key.