Dop Dop Yes (Skibidi Toilet Reverse)
Dop Dop Yes (Skibidi Toilet Reverse)
Platform: CUSTOM | Category: Reversing | Type: Challenge | Difficulty: Easy | OS: N/A | **Author: XESXOR Techniques: Custom XOR-based cipher reverse engineering, Mouse cursor position constraint solving, Multi-layer decoding (binary -> ASCII -> Base64), PE64 disassembly and analysis
Summary
Walkthrough of the CUSTOM Reversing Dop Dop Yes (Skibidi Toilet Reverse). Task: Reverse "Dop Dop Yes" — Skibidi Toilet. Solution: Meme-based reverse, TikTok culture reference.
Description
"Я нашёл это у своего внука на компьютере. Очень не понимаю, почему там какие-то туалеты и роботы. Может, вы знаете?"
(I found this on my grandson's computer. I don't understand why there are some toilets and robots. Do you know?)
The task name "доп доп ес" = "dop dop yes" is a reference to the Skibidi Toilet meme.
Files
tv2.0.exe- PE32+ executable (console) x86-64, MinGW-compiled- Multiple PNG images with Skibidi Toilet theme (camera.png, car.png, tvman.png, etc.)
Analysis
Step 1: Initial Reconnaissance
The executable is a Windows PE64 binary compiled with MinGW. The accompanying PNG images are all Skibidi Toilet meme-related, which is a hint from the task name.
bash read-only • copy allowedfile tv2.0.exe # tv2.0.exe: PE32+ executable (console) x86-64, for MS Windows
Step 2: Disassembly Analysis
Using objdump to disassemble the binary:
bash read-only • copy allowedobjdump -d tv2.0.exe > disasm.txt
Key findings in the disassembly:
Mouse Position Checks (at 0x401771-0x4017c1)
asm read-only • copy allowed401771: 8b 85 c8 09 00 00 movl 0x9c8(%rbp), %eax # X coordinate 401777: 35 37 13 37 13 xorl $0x13371337, %eax 40177c: 3d bd 13 37 13 cmpl $0x133713bd, %eax 401781: 0f 8e 81 03 00 00 jle 0x401b08 # Jump if (X ^ 0x13371337) <= 0x133713bd 401787: 8b 85 cc 09 00 00 movl 0x9cc(%rbp), %eax # Y coordinate 40178d: 35 36 13 37 13 xorl $0x13371336, %eax 401792: 3d c1 13 37 13 cmpl $0x133713c1, %eax 401797: 0f 8f 6b 03 00 00 jg 0x401b08 # Jump if (Y ^ 0x13371336) > 0x133713c1 # Y % 121 == 16 check (using multiplication trick) 4017a3: ba 5b 3d 3b 04 movl $0x43b3d5b, %edx 4017a8: 89 c8 movl %ecx, %eax 4017aa: f7 ea imull %edx # ... modulo 121 calculation 4017ba: 6b c0 79 imull $0x79, %eax, %eax # 0x79 = 121 4017be: 83 f8 10 cmpl $0x10, %eax # Check if remainder == 16
The conditions are:
(X ^ 0x13371337) > 0x133713bd(Y ^ 0x13371336) <= 0x133713c1Y % 121 == 16X == Y(from earlier comparison)
Step 3: Solving for X and Y
python read-only • copy allowed# Condition 1: (X ^ 0x13371337) > 0x133713bd # Condition 2: (Y ^ 0x13371336) <= 0x133713c1 # Condition 3: Y % 121 == 16 # Condition 4: X == Y # For X = Y: # (X ^ 0x13371337) > 0x133713bd # (X ^ 0x13371336) <= 0x133713c1 # X % 121 == 16 # Testing X = 137: # 137 ^ 0x13371337 = 0x133713be > 0x133713bd ✓ # 137 ^ 0x13371336 = 0x133713bf <= 0x133713c1 ✓ # 137 % 121 = 16 ✓ X = Y = 137
Step 4: Encrypted Data Location
At offset 0x4017cb, the code loads encrypted data:
asm read-only • copy allowed4017cb: 48 8d 15 4e 28 00 00 leaq 0x284e(%rip), %rdx # 0x404020 4017d2: b9 b9 09 00 00 movl $0x9b9, %ecx # Size = 2489 bytes
The encrypted data is at file offset 0x2820 (RVA 0x404020), size 0x9b9 (2489) bytes.
Step 5: Reverse Engineering the Cipher
The encryption algorithm (at 0x40181a-0x401a6d) performs 18 operations per byte:
python read-only • copy alloweddef transform(data, X, Y): result = bytearray() prev = 0 for i, b in enumerate(data): original = b # Save original for prev update # Step 1: XOR with prev b ^= prev # Step 2: XOR with 0xAF b ^= 0xAF # Step 3: XOR with Y b ^= Y # Step 4: XOR with 0x3C b ^= 0x3C # Step 5: ADD ((prev + 0x34) ^ (X + i)) b = (b + ((prev + 0x34) ^ (X + i))) & 0xFF # Step 6: XOR with (prev + Y), then XOR 0x19 b = (prev + Y) ^ b ^ 0x19 # Step 7: ADD (X ^ 0x50) b = (b + (X ^ 0x50)) & 0xFF # Step 8: SUB 0x34 b = (b - 0x34) & 0xFF # Step 9: SUB (i ^ 0xAB) b = (b - (i ^ 0xAB)) & 0xFF # Step 10: XOR with (prev + i + 0x74) b = (prev + i + 0x74) ^ b # Step 11: XOR with prev b ^= prev # Step 12: SUB prev b = (b - prev) & 0xFF # Step 13: XOR 0xCC b ^= 0xCC # Step 14: ADD i b = (b + i) & 0xFF # Step 15: XOR 0xAA b ^= 0xAA # Step 16: ADD 0x31 b = (b + 0x31) & 0xFF # Step 17: XOR 0x44 b ^= 0x44 result.append(b) prev = original # Key insight: prev = original encrypted byte return bytes(result)
Critical insight: The prev variable is updated with the original encrypted byte, not the decrypted one. This is visible in the assembly at 0x401a6d-0x401a7a.
Solution
Full Decryption Script
python read-only • copy allowed#!/usr/bin/env python3 import base64 def extract_encrypted_data(filename): """Extract encrypted data from PE file at offset 0x2820""" with open(filename, 'rb') as f: f.seek(0x2820) return f.read(0x9b9) def transform(data, X, Y): """Apply the transformation algorithm""" result = bytearray() prev = 0 for i, b in enumerate(data): original = b b ^= prev b ^= 0xAF b ^= Y b ^= 0x3C b = (b + ((prev + 0x34) ^ (X + i))) & 0xFF b = (prev + Y) ^ b ^ 0x19 b = (b + (X ^ 0x50)) & 0xFF b = (b - 0x34) & 0xFF b = (b - (i ^ 0xAB)) & 0xFF b = (prev + i + 0x74) ^ b b ^= prev b = (b - prev) & 0xFF b ^= 0xCC b = (b + i) & 0xFF b ^= 0xAA b = (b + 0x31) & 0xFF b ^= 0x44 result.append(b) prev = original return bytes(result) def binary_to_ascii(binary_string): """Convert space-separated binary strings to ASCII""" result = "" for byte_str in binary_string.split(): if len(byte_str) == 8: result += chr(int(byte_str, 2)) return result # Main encrypted = extract_encrypted_data("tv2.0.exe") X = Y = 137 # Apply transformation decrypted = transform(encrypted, X, Y) # Decode as UTF-8 (binary strings) binary_text = decrypted.decode('utf-8', errors='ignore') print("Binary strings (first 200 chars):", binary_text[:200]) # Convert binary to ASCII ascii_text = binary_to_ascii(binary_text) print("\nASCII text:", ascii_text) # Decode Base64 try: final = base64.b64decode(ascii_text).decode('utf-8') print("\nFinal message:", final) except Exception as e: print(f"Base64 decode error: {e}")
Decoding Chain
- Apply transformation with X=Y=137 to encrypted data
- Result: Space-separated binary strings (8 bits per character)
01010000 01101100 01100101 01100001 01110011 01100101 ... - Convert binary to ASCII: Each 8-bit group becomes a character
- Result: Base64 encoded string
- Decode Base64: Final message with flag
Output
Binary strings: 01010000 01101100 01100101 01100001 01110011 01100101 ...
ASCII text: UGxlYXNlIGRvIG5vdCBydW4gdW5mYW1pbGlhciBmaWxlcyBvbiB5b3VyIHN5c3RlbS4g...
Final message: Please do not run unfamiliar files on your system. Always analyze
them before running them, as the damage of laziness may be more than wasting some
time. CODEBY{REDACTED}
Lessons Learned
- Meme references matter: The task name "dop dop yes" directly references Skibidi Toilet, setting the theme
- Constraint solving: Mouse position checks can be solved algebraically
- prev variable tracking: In cipher analysis, carefully track which value updates the state variable
- Multi-layer encoding: Be prepared for nested encodings (binary -> ASCII -> Base64)
- Security message: The flag itself is a reminder to analyze files before running them
References
- Skibidi Toilet - The meme referenced in the task
- PE file format analysis
- XOR cipher reverse engineering
Key Takeaways / Lessons
- Mastering Custom XOR-based cipher reverse engineering, Mouse cursor position constraint solving, Multi-layer decoding (binary -> ASCII -> Base64), PE64 disassembly and analysis was key to this challenge.
- Always check for common misconfigurations and verify assumptions.
Crafted by XESXOR Research • 2025-12-25 • CUSTOM • Dop Dop Yes (Skibidi Toilet Reverse) • Difficulty: Easy