2. PEB Walkz
- Base address:
0000000140000000 - Entry point:
00000001400014f0

1. Analyze main function
main function is at address 00000001400013bf, here is the decompiled C code:
// write access to const memory has been detected, the output may be wrong!
__int64 __fastcall sub_140001190(__int64 a1, __int64 a2)
{
_STARTUPINFOA *p_StartupInfo; // r8
__int64 v3; // rcx
PVOID StackBase; // rsi
signed __int64 v5; // rax
int v6; // ebp
char **v7; // rax
char v8; // cl
char *v9; // rax
char v10; // dl
char v11; // dl
int wShowWindow; // eax
int v13; // ebx
size_t v14; // r12
_QWORD *v15; // rax
__int64 v16; // r13
__int64 v17; // rdi
__int64 v18; // rbp
__int64 v19; // rbx
size_t v20; // rsi
void *v21; // rax
__int64 v22; // rax
__int64 result; // rax
_STARTUPINFOA StartupInfo; // [rsp+20h] [rbp-A8h] BYREF
p_StartupInfo = &StartupInfo;
memset(&StartupInfo, 0, sizeof(StartupInfo));
v3 = 0;
if ( unk_14000D090 )
GetStartupInfoA(&StartupInfo);
StackBase = NtCurrentTeb()->NtTib.StackBase;
while ( 1 )
{
v5 = _InterlockedCompareExchange64(qword_14000DB98, (signed __int64)StackBase, 0);
if ( !v5 )
{
v6 = 0;
if ( unk_14000DB90 == 1 )
goto LABEL_39;
goto LABEL_8;
}
if ( StackBase == (PVOID)v5 )
break;
Sleep(0x3E8u);
}
v6 = 1;
if ( unk_14000DB90 == 1 )
{
LABEL_39:
amsg_exit(31, a2, p_StartupInfo);
if ( unk_14000DB90 == 1 )
goto LABEL_40;
LABEL_11:
if ( v6 )
goto LABEL_12;
goto LABEL_41;
}
LABEL_8:
if ( unk_14000DB90 )
{
dword_14000D008 = 1;
}
else
{
unk_14000DB90 = 1;
initterm(&qword_14000F018, qword_14000F030);
}
if ( unk_14000DB90 != 1 )
goto LABEL_11;
LABEL_40:
initterm(&qword_14000F000, &qword_14000F010);
unk_14000DB90 = 2;
if ( v6 )
goto LABEL_12;
LABEL_41:
_InterlockedExchange64(qword_14000DB98, 0);
LABEL_12:
if ( TlsCallback_0 )
TlsCallback_0(0, 2, 0);
sub_140001AB0(v3, a2, p_StartupInfo);
qword_14000D0D0 = (__int64)SetUnhandledExceptionFilter(TopLevelExceptionFilter);
sub_1400077E0(nullsub_1);
sub_140001810();
qword_14000DB88 = (__int64)off_14000A740;
v7 = (char **)sub_1400078C0();
v8 = 0;
v9 = *v7;
if ( !v9 )
goto LABEL_27;
while ( 1 )
{
v10 = *v9;
if ( *v9 <= 32 )
break;
if ( v10 == 34 )
v8 ^= 1u;
LABEL_19:
++v9;
}
if ( !v10 )
goto LABEL_26;
if ( (v8 & 1) != 0 )
{
v8 = 1;
goto LABEL_19;
}
do
v11 = *++v9;
while ( v11 && v11 <= 32 );
LABEL_26:
qword_14000DB80 = (__int64)v9;
LABEL_27:
if ( unk_14000D090 )
{
wShowWindow = 10;
if ( (StartupInfo.dwFlags & 1) != 0 )
wShowWindow = StartupInfo.wShowWindow;
dword_140009000 = wShowWindow;
}
v13 = dword_14000D028;
v14 = 8LL * (dword_14000D028 + 1);
v15 = malloc(v14);
v16 = qword_14000D020;
v17 = (__int64)v15;
if ( v13 > 0 )
{
v18 = (unsigned int)(v13 - 1);
v19 = 0;
do
{
v20 = strlen(*(const char **)(v16 + 8 * v19)) + 1;
v21 = malloc(v20);
*(_QWORD *)(v17 + 8 * v19) = v21;
memcpy(v21, *(const void **)(v16 + 8 * v19), v20);
v22 = v19++;
}
while ( v18 != v22 );
v15 = (_QWORD *)(v17 + v14 - 8);
}
*v15 = 0;
qword_14000D020 = v17;
sub_140001600();
_initenv = qword_14000D018;
result = sub_140007CF0((unsigned int)dword_14000D028, qword_14000D020);
dword_14000D010 = result;
if ( !dword_14000D00C )
exit(result);
if ( !dword_14000D008 )
{
cexit();
return (unsigned int)dword_14000D010;
}
return result;
}
From the decompiled C code, it performs:
- Dynamic API resolution
- Brute-force key to decrypt shellcode
- Check valid shellcode with
48 81 e4 f0hex pattern - VirtualAlloc + CreateThread to execute shellcode
Encrypted shellcode is at 0x140009108, here is the script to decrypt the shellcode:
#!/usr/bin/env python3
import re
from pathlib import Path
# Paste the raw hexdump/text you posted (or the raw dumped block) between the triple quotes.
# Keep the addresses, ascii column, etc — the script will extract only hex byte pairs.
hexdump_text = r"""
71 49 99 99 99 d8 c8 d8 c9 cb c8 cf d1 a8 4b fc d1 12 cb f9 a7 d1 12 cb
81 a7 d1 12 cb b9 a7 d1 12 eb c9 a7 d1 96 2e d3 d3 d4 a8 50 d1 a8 59 35 a5 f8 e5 9b b5 b9 d8 58
50 94 d8 98 58 7b 74 cb d8 c8 a7 d1 12 cb b9 a7 12 db a5 d1 98 49 a7 12 19 11 99 99 99 d1 1c 59
ed f6 d1 98 49 c9 a7 12 d1 81 a7 dd 12 d9 b9 d0 98 49 7a c5 d1 66 50 a7 d8 12 ad 11 d1 98 4f d4
a8 50 d1 a8 59 35 d8 58 50 94 d8 98 58 a1 79 ec 68 a7 d5 9a d5 bd 91 dc a0 48 ec 4f c1 a7 dd 12
d9 bd d0 98 49 ff a7 d8 12 95 d1 a7 dd 12 d9 85 d0 98 49 a7 d8 12 9d 11 d1 98 49 d8 c1 d8 c1 c7
c0 c3 d8 c1 d8 c0 d8 c3 d1 1a 75 b9 d8 cb 66 79 c1 d8 c0 c3 a7 d1 12 8b 70 d0 66 66 66 c4 d0 5e
58 99 99 99 99 a7 d1 14 0c 67 99 99 99 a7 d5 14 1c 83 98 99 99 d1 a8 50 d8 23 dc 1a cf 9e 66 4c
d1 a8 50 d8 23 69 2c 3b cf 66 4c cb ce ca da e2 ac f1 aa a8 a8 c6 fa a9 fd aa c6 fd aa fb ec a0
a0 a8 f7 a0 e3
"""
# If your hexdump included the "data_140009225" tail as a separate line, append it here (optional)
tail_hex = "99dacacecb99e4" # update if different or leave as "" if already included above
# Extract all two-hex-digit tokens (this ignores addresses, ascii, and non-hex junk)
hex_pairs = re.findall(r'[0-9a-fA-F]{2}', hexdump_text)
if tail_hex:
# ensure tail is split into pairs and appended
tail_pairs = re.findall(r'[0-9a-fA-F]{2}', tail_hex)
hex_pairs += tail_pairs
if not hex_pairs:
raise SystemExit("No hex bytes found in the pasted hexdump. Make sure you pasted the correct block.")
blob = bytes.fromhex(''.join(hex_pairs))
print(f"Blob length = {len(blob)} bytes")
# Brute-force single-byte XOR searching for shellcode prefix
target_prefix = b"\xFC\x48\x81\xE4\xF0"
def find_key_and_decrypt(blob, prefix):
for k in range(256):
dec = bytes(b ^ k for b in blob)
if dec.startswith(prefix):
return k, dec
return None, None
key, dec = find_key_and_decrypt(blob, target_prefix)
if key is None:
print("No single-byte XOR key produced the expected prefix.")
# Helpful diagnostics: show bytes for keys that fix the first byte only
first = blob[0]
cand = [k for k in range(256) if (first ^ k) == target_prefix[0]]
print("Keys that make first byte match:", cand[:50], f"(count {len(cand)})")
else:
print(f"Found key: 0x{key:02x} ({key})")
out = Path("decrypted_shellcode.bin")
out.write_bytes(dec)
print(f"Wrote decrypted blob to {out} ({len(dec)} bytes)")
print("First 64 bytes (hex):", dec[:64].hex())
Flag: RWSC{5h311_c0d3_d3bu991n9z}