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.cThis produces an executable file (
product_key_checker.exeon 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
199hashes 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
objdumpto inspect the binary:objdump -d product_key_checker.exe > disassembled_code.txtThis generates a disassembly file (
disassembled_code.txt) with assembly instructions. -
Locate the Main Function: Search for the
mainfunction in the disassembly to find the product key validation logic. -
Identify the
cmpInstruction: Look for acmpinstruction inmainthat compares the computed hash with the hardcoded hash. It might look like this:3d e8 8a 87 0b cmp $0xb878ae8, %eaxHere,
3d e8 8a 87 0bin hexadecimal representscmp $0xb878ae8, %eax, where0xb878ae8corresponds to193432296.
Step 4: Plan the Modification to Bypass Validation
-
Objective: Change the
cmpinstruction to always evaluate as “equal.” -
Modify
cmpto Compareeaxwith Itself: Replacecmp $0xb878ae8, %eaxwithcmp %eax, %eax, which will always yield equality since a register compared to itself is always equal. The hexadecimal forcmp %eax, %eaxis39 c0. -
Fill Remaining Bytes with
NOP: Since the original instruction is 5 bytes andcmp %eax, %eaxis only 2 bytes, useNOP(90) to fill the remaining bytes. This keeps the program aligned. -
Final Byte Sequence: Replace
3d e8 8a 87 0bwith: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 0bin the hex editor. -
Edit the Bytes: Replace
3d e8 8a 87 0bwith39 c0 90 90 90to 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.exeto 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
cmpInstruction: Find thecmpinstruction in the disassembled code. - Plan the Modification: Change
cmp $0xb878ae8, %eaxtocmp %eax, %eax. - Edit in Hex Editor: Replace
3d e8 8a 87 0bwith39 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.
