''.join([chr((ord(flag[i]) << 8) + ord(flag[i + 1])) for i in range(0, len(flag), 2)])
picoCTF{1n_7h3_|<3y_of_xxxxxxxx}
where x
stands for a "dynamic" character. Our objective is to reverse engineer the check_key
function and pass the check.check_key
is not fully implemented and there are eight if
statements checking if a certain character is valid. We could simply write a script and recover each character.decode_secret
function.1765227561
and 1830628817
? File: chall.S Flag format: picoCTF{XXXXXXXX} -> (hex, lowercase, no 0x, and 32 bits. ex. 5614267 would be picoCTF{0055aabb})bls
: Branch on Lower than or Same.
atoi
twice to convert the arguments to integers and then calls func1
to compare those two integers. Since .L2
. Now w0 = [sp+8] = 1830628817 = x0
.printf
is called, the value stored in x0
will be printed (calling convention). Hence this program prints 1830628817
, which is 0x6d1d2dd1
in hex.mercury.picoctf.net:53740
, but I can't tell what it is. Can you?nc mercury.picoctf.net 34938
.win
with variables 85
, 6
and 3
? File: chall_1.S Flag format: picoCTF{XXXXXXXX} -> (hex, lowercase, no 0x, and 32 bits. ex. 5614267 would be picoCTF{0055aabb})lsl
: Logical Shift Left. It provides the value of a register multiplied by a power of two, inserting zeros into the vacated bit positionssdiv
: Signed Dividex29
register is the frame pointer in ARM64. It is equivalent to the RBP
register in Intel x86-64. The function func
is just doing math:arg = 1813
, which is 0x715
in hex.3848786505
? File: chall_2.S Flag format: picoCTF{XXXXXXXX} -> (hex, lowercase, no 0x, and 32 bits. ex. 5614267 would be picoCTF{0055aabb})b
: Branch. This is the uncoditional branchbcc
: Branch on Carry Clear. This is the conditional branchwzr
register is equivalent to 0. The instruction str wzr, [sp, 24]
zeros out the content of [sp+24]
.[sp+24]
is the result and [sp+28]
is the counter. The loop keeps increment [sp+24]
by 3
and compares the counter [sp+28]
with 3848786505
. In the end, the result [sp+24]
is printed out. In other word, the program computes 3848786505 * 3 = 11546359515
, which is 0x2b03776db
in hex. Since the flag requires 32-bit hex, this hex number is truncated as 0xb03776db
.mercury.picoctf.net:35862
.3350728462
? File: chall_3.S Flag format: picoCTF{XXXXXXXX} -> (hex, lowercase, no 0x, and 32 bits. ex. 5614267 would be picoCTF{0055aabb})stp
: Store Pairbl
: Branch with Linklsr
: Logical Shift Rightand w0, w0, 1
, where w0
is the argument. If the w0 & 1 = 1
, it increments the counter by 3. Otherwise, it does nothing and continues. After each round of testing, the program divides w0
by 2 and repeats this test until w0 = 0
.memcmp
function compares our input with the flag. Set a breakpoint on memcmp
and run the program again:unk_2008
is the encrypted flag:call puts
instruction for "Correct!":call puts
instruction for "Incorrect.":3964545182
? File: chall_4.S Flag format: picoCTF{XXXXXXXX} -> (hex, lowercase, no 0x, and 32 bits. ex. 5614267 would be picoCTF{0055aabb})bhi
: Branch on Higher thannc mercury.picoctf.net 17615