> For the complete documentation index, see [llms.txt](https://ret2basic.gitbook.io/ctfwriteup/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ret2basic.gitbook.io/ctfwriteup/web2-ctf/picoctf-2021/picoctf-2021-reverse-engineering.md).

# Reverse Engineering

## Transformation

### Challenge

I wonder what this really is... [enc](https://mercury.picoctf.net/static/2b4cea9b07db22bf4f933fddd1b8caa9/enc) `''.join([chr((ord(flag[i]) << 8) + ord(flag[i + 1])) for i in range(0, len(flag), 2)])`

### Solution

The encoding scheme acts on two characters from the flag each time. The first character is used as **higher 8 bits**, while the second character is used as **lower 8 bits**. Together, the 2-character pair is transformed into a **16-bit binary number** and this binary number is converted to ASCII character.

### Implementation

```python
#!/usr/bin/env python3

with open('enc', 'r') as f:
    encoded = f.read()

    flag = ''
    for ch in encoded:
        binary = "{0:016b}".format(ord(ch))
        first_half, second_half = binary[:8], binary[8:]
        flag += chr(int(first_half, 2))
        flag += chr(int(second_half, 2))

    print(flag)
```

## keygenme-py

### Challenge

[keygenme-trial.py](https://mercury.picoctf.net/static/a6d9cac3bfa4935ceb50c145d3ff5586/keygenme-trial.py)

### Source Code

```python
def check_key(key, username_trial):

    global key_full_template_trial

    if len(key) != len(key_full_template_trial):
        return False
    else:
        # Check static base key part --v
        i = 0
        for c in key_part_static1_trial:
            if key[i] != c:
                return False

            i += 1

        # TODO : test performance on toolbox container
        # Check dynamic part --v
        if key[i] != hashlib.sha256(username_trial).hexdigest()[4]:
            return False
        else:
            i += 1

        if key[i] != hashlib.sha256(username_trial).hexdigest()[5]:
            return False
        else:
            i += 1

        if key[i] != hashlib.sha256(username_trial).hexdigest()[3]:
            return False
        else:
            i += 1

        if key[i] != hashlib.sha256(username_trial).hexdigest()[6]:
            return False
        else:
            i += 1

        if key[i] != hashlib.sha256(username_trial).hexdigest()[2]:
            return False
        else:
            i += 1

        if key[i] != hashlib.sha256(username_trial).hexdigest()[7]:
            return False
        else:
            i += 1

        if key[i] != hashlib.sha256(username_trial).hexdigest()[1]:
            return False
        else:
            i += 1

        if key[i] != hashlib.sha256(username_trial).hexdigest()[8]:
            return False



        return True
```

### Solution

According to the global variables declared at the beginning of the source code, the flag is `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.

Note that `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.

### Implementation

```python
#!/usr/bin/env python3
import hashlib

username_trial = b"PRITCHARD"
digest = hashlib.sha256(username_trial).hexdigest()

print(f"index 4: {digest[4]}")
print(f"index 5: {digest[5]}")
print(f"index 3: {digest[3]}")
print(f"index 6: {digest[6]}")
print(f"index 2: {digest[2]}")
print(f"index 7: {digest[7]}")
print(f"index 1: {digest[1]}")
print(f"index 8: {digest[8]}")

flag_part_1 = 'picoCTF{1n_7h3_|<3y_of_'
flag_part_2 = ''
flag_part_2 += digest[4] + digest[5]
flag_part_2 += digest[3] + digest[6]
flag_part_2 += digest[2] + digest[7]
flag_part_2 += digest[1] + digest[8]
flag_part_3 = '}'

print(f"flag: {flag_part_1 + flag_part_2 + flag_part_3}")
```

## crackme-py

### Challenge

[crackme.py](https://mercury.picoctf.net/static/fd0e358d4b82695c220c0d6013c11484/crackme.py)

### Source Code

```python
# Hiding this really important number in an obscure piece of code is brilliant!
# AND it's encrypted!
# We want our biggest client to know his information is safe with us.
bezos_cc_secret = "A:4@r%uL`M-^M0c0AbcM-MFE055a4ce`eN"

# Reference alphabet
alphabet = "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ"+ \
            "[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"



def decode_secret(secret):
    """ROT47 decode

    NOTE: encode and decode are the same operation in the ROT cipher family.
    """

    # Encryption key
    rotate_const = 47

    # Storage for decoded secret
    decoded = ""

    # decode loop
    for c in secret:
        index = alphabet.find(c)
        original_index = (index + rotate_const) % len(alphabet)
        decoded = decoded + alphabet[original_index]

    print(decoded)



def choose_greatest():
    """Echo the largest of the two numbers given by the user to the program

    Warning: this function was written quickly and needs proper error handling
    """

    user_value_1 = input("What's your first number? ")
    user_value_2 = input("What's your second number? ")
    greatest_value = user_value_1 # need a value to return if 1 & 2 are equal

    if user_value_1 > user_value_2:
        greatest_value = user_value_1
    elif user_value_1 < user_value_2:
        greatest_value = user_value_2

    print( "The number with largest positive magnitude is "
        + str(greatest_value) )



choose_greatest()
```

### Solution

Modify the source code to call the `decode_secret` function.

### Implementation

```python
# choose_greatest()
print(decode_secret(bezos_cc_secret))
```

## ARMssembly 0

### Challenge

What integer does this program print with arguments `1765227561` and `1830628817`? File: [chall.S](https://mercury.picoctf.net/static/37069d9462289016ea1869ef4c993912/chall.S) Flag format: picoCTF{XXXXXXXX} -> (hex, lowercase, no 0x, and 32 bits. ex. 5614267 would be picoCTF{0055aabb})

### Assembly with Comments

```
    .arch armv8-a
    .file    "chall.c"
    .text
    .align    2
    .global    func1
    .type    func1, %function
func1:
    sub    sp, sp, #16 @ allocate 16 bytes on the stack
    str    w0, [sp, 12] @ store w0 into [sp+12]
    str    w1, [sp, 8] @ store w1 into [sp+8]
    ldr    w1, [sp, 12] @ load [sp+12] into w1
    ldr    w0, [sp, 8] @ load [sp+8] into w0
    cmp    w1, w0 @ compare w1 and w0 => compare [sp+12] and [sp+8]
    bls    .L2 @ branch to .L2 if ls
    ldr    w0, [sp, 12] @ load [sp+12] into w0
    b    .L3 @ branch to .L3
.L2:
    ldr    w0, [sp, 8]
.L3:
    add    sp, sp, 16
    ret
    .size    func1, .-func1
    .section    .rodata
    .align    3
.LC0:
    .string    "Result: %ld\n"
    .text
    .align    2
    .global    main
    .type    main, %function
main:
    stp    x29, x30, [sp, -48]!
    add    x29, sp, 0
    str    x19, [sp, 16]
    str    w0, [x29, 44]
    str    x1, [x29, 32]
    ldr    x0, [x29, 32]
    add    x0, x0, 8
    ldr    x0, [x0]
    bl    atoi
    mov    w19, w0
    ldr    x0, [x29, 32]
    add    x0, x0, 16
    ldr    x0, [x0]
    bl    atoi
    mov    w1, w0
    mov    w0, w19
    bl    func1
    mov    w1, w0
    adrp    x0, .LC0
    add    x0, x0, :lo12:.LC0
    bl    printf
    mov    w0, 0
    ldr    x19, [sp, 16]
    ldp    x29, x30, [sp], 48
    ret
    .size    main, .-main
    .ident    "GCC: (Ubuntu/Linaro 7.5.0-3ubuntu1~18.04) 7.5.0"
    .section    .note.GNU-stack,"",@progbits
```

### Solution

> `bls`: **Branch on Lower than or Same**.

The main function calls `atoi` twice to convert the arguments to integers and then calls `func1` to compare those two integers. Since $$1765227561 \leq 1830628817$$, the control flow goes to `.L2`. Now `w0 = [sp+8] = 1830628817 = x0`.

Eventually, when `printf` is called, the value stored in `x0` will be printed (**calling convention**). Hence this program prints `1830628817`, which is `0x6d1d2dd1` in hex.

## speeds and feeds

### Challenge

There is something on my shop network running at `mercury.picoctf.net:53740`, but I can't tell what it is. Can you?

### Solution

Save the G-code to a file:

```
$ nc mercury.picoctf.net 53740 > G-code.txt
```

Use [NC Viewer](ttps://ncviewer.com) to plot the flag.

## Shop

### Challenge

Best Stuff - Cheap Stuff, Buy Buy Buy... Store Instance: [source](https://mercury.picoctf.net/static/d2c8c9ee59822de6776dd8f20af63b91/source). The shop is open for business at `nc mercury.picoctf.net 34938`.

### Solution

Buy -10 "Quiet Quiches" and then buy 1 flag. Convert ASCII numbers to text.

### Implementation

```python
#!/usr/bin/env python3

characters = [112, 105, 99, 111, 67, 84, 70, 123, 98, 52, 100, 95, 98, 114, 111, 103, 114, 97, 109, 109, 101, 114, 95, 98, 97, 54, 98, 56, 99, 100, 102, 125]

flag = ""
for character in characters:
    flag += chr(character)

print(flag)
```

## ARMssembly 1

### Challenge

For what argument does this program print `win` with variables `85`, `6` and `3`? File: [chall\_1.S](https://mercury.picoctf.net/static/56a2cea908a525745578feff8b94719f/chall_1.S) Flag format: picoCTF{XXXXXXXX} -> (hex, lowercase, no 0x, and 32 bits. ex. 5614267 would be picoCTF{0055aabb})

### Assembly with Comments

```
    .arch armv8-a
    .file    "chall_1.c"
    .text
    .align    2
    .global    func
    .type    func, %function
func:
    sub    sp, sp, #32 @ allocate 32 bytes on the stack
    str    w0, [sp, 12] @ [sp+12] = w0 = [x29+44] = arg
    mov    w0, 85 @ w0 = 85
    str    w0, [sp, 16] @ [sp+16] = w0 = 85
    mov    w0, 6 @ w0 = 6
    str    w0, [sp, 20] @ [sp+20] = w0 = 6
    mov    w0, 3 @ w0 = 3
    str    w0, [sp, 24] @ [sp+24] = w0 = 3
    ldr    w0, [sp, 20] @ w0 = [sp+20] = 6
    ldr    w1, [sp, 16] @ w1 = [sp+16] = 85
    lsl    w0, w1, w0 @ w0 = w1 * (2**w0) = 85 * (2**6) = 85 * 64 = 5440
    str    w0, [sp, 28] @ [sp+28] = w0 = 5440
    ldr    w1, [sp, 28] @ w1 = [sp+28] = 5440
    ldr    w0, [sp, 24] @ w0 = [sp+24] = 3
    sdiv    w0, w1, w0 @ w0 = w1 // w2 = 5440 // 3 = 1813
    str    w0, [sp, 28] @ [sp+28] = w0 = 1813
    ldr    w1, [sp, 28] @ w1 = [sp+28] = 1813
    ldr    w0, [sp, 12] @ w0 = [sp+12] = arg
    sub    w0, w1, w0 @ w0 = w1 - w0 = 1813 - arg
    str    w0, [sp, 28] @ [sp+28] = w0 = 1813 - arg
    ldr    w0, [sp, 28] @ w0 = [sp+28] = 1813 - arg
    add    sp, sp, 32
    ret
    .size    func, .-func
    .section    .rodata
    .align    3
.LC0:
    .string    "You win!"
    .align    3
.LC1:
    .string    "You Lose :("
    .text
    .align    2
    .global    main
    .type    main, %function
main:
    stp    x29, x30, [sp, -48]!
    add    x29, sp, 0
    str    w0, [x29, 28]
    str    x1, [x29, 16]
    ldr    x0, [x29, 16]
    add    x0, x0, 8
    ldr    x0, [x0]
    bl    atoi
    str    w0, [x29, 44]
    ldr    w0, [x29, 44]
    bl    func
    cmp    w0, 0
    bne    .L4
    adrp    x0, .LC0
    add    x0, x0, :lo12:.LC0
    bl    puts
    b    .L6
.L4:
    adrp    x0, .LC1
    add    x0, x0, :lo12:.LC1
    bl    puts
.L6:
    nop
    ldp    x29, x30, [sp], 48
    ret
    .size    main, .-main
    .ident    "GCC: (Ubuntu/Linaro 7.5.0-3ubuntu1~18.04) 7.5.0"
    .section    .note.GNU-stack,"",@progbits
```

### Solution

{% hint style="info" %}
`lsl`: **Logical Shift Left**. It provides the value of a register **multiplied by a power of two**, inserting zeros into the vacated bit positions

`sdiv`: **Signed Divide**
{% endhint %}

Note that the `x29` 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:

$$
\frac{85 \cdot 2^6}{3} = arg
$$

Hence `arg = 1813`, which is `0x715` in hex.

## ARMssembly 2

### Challenge

What integer does this program print with argument `3848786505`? File: [chall\_2.S](https://mercury.picoctf.net/static/ae9fdcfd0d281e10893d885eef4ee138/chall_2.S) Flag format: picoCTF{XXXXXXXX} -> (hex, lowercase, no 0x, and 32 bits. ex. 5614267 would be picoCTF{0055aabb})

### Solution

{% hint style="info" %}
`b`: **Branch**. This is the **uncoditional** branch

`bcc`: **Branch on Carry Clear**. This is the **conditional** branch
{% endhint %}

Note that the `wzr` register is equivalent to 0. The instruction `str wzr, [sp, 24]` zeros out the content of `[sp+24]`.

Here `[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`.

## Hurry up! Wait!

### Challenge

[svchost.exe](https://mercury.picoctf.net/static/61cffe4f7cc04119c857dabd015d6c4a/svchost.exe)

### Solution

Each function call prints out a character:

![Pseudocode](/files/-MX3ec6vG7vODPdCbxC5)

## gogo

### Challenge

Hmmm this is a weird file... [enter\_password](https://mercury.picoctf.net/static/6cdf9f996eca303950f0c5d8a9e94242/enter_password). There is a instance of the service running at `mercury.picoctf.net:35862`.

### Solution

## ARMssembly 3

### Challenge

What integer does this program print with argument `3350728462`? File: [chall\_3.S](https://mercury.picoctf.net/static/9f5593ecc5da7043cf69a8926efc3be8/chall_3.S) Flag format: picoCTF{XXXXXXXX} -> (hex, lowercase, no 0x, and 32 bits. ex. 5614267 would be picoCTF{0055aabb})

### Assembly with Comments

```
    .arch armv8-a
    .file    "chall_3.c"
    .text
    .align    2
    .global    func1
    .type    func1, %function
func1:
    stp    x29, x30, [sp, -48]! @ push x29 and x30 onto the stack
    add    x29, sp, 0 @ x29 = sp + 0 = sp
    str    w0, [x29, 28] @ [x29+28] = w0 = 3350728462
    str    wzr, [x29, 44] @ [x29+44] = wzr = 0
    b    .L2 @ branch to .L2 unconditionally
.L4:
    ldr    w0, [x29, 28] @ w0 = [x29+28]
    and    w0, w0, 1 @ w0 &= 1 => => w0 = 1 if all bits of w0 are 1, w0 = 0 otherwise
    cmp    w0, 0 @ compare w0 and 0
    beq    .L3 @ branch to .L3 if w0 == 0
    ldr    w0, [x29, 44] @ w0 = [x29+44]
    bl    func2 @ branch to func2
    str    w0, [x29, 44] @ [x29+44] = w0
.L3:
    ldr    w0, [x29, 28] @ w0 = [x29+28]
    lsr    w0, w0, 1 @ w0 >> 1
    str    w0, [x29, 28] @ [x29+28] = w0
.L2:
    ldr    w0, [x29, 28] @ w0 = [x29+28]
    cmp    w0, 0 @ compare w0 and 0 => compare [x29+28] and 0
    bne    .L4 @ if [x29+28] != 0, branch to .L4
    ldr    w0, [x29, 44] @ w0 = [x29+44]
    ldp    x29, x30, [sp], 48
    ret
    .size    func1, .-func1
    .align    2
    .global    func2
    .type    func2, %function
func2:
    sub    sp, sp, #16 @ allocate 16 bytes on the stack
    str    w0, [sp, 12] @ [sp+12] = w0
    ldr    w0, [sp, 12] @ w0 = [sp+12]
    add    w0, w0, 3 @ w0 += 3 
    add    sp, sp, 16
    ret
    .size    func2, .-func2
    .section    .rodata
    .align    3
.LC0:
    .string    "Result: %ld\n"
    .text
    .align    2
    .global    main
    .type    main, %function
main:
    stp    x29, x30, [sp, -48]!
    add    x29, sp, 0
    str    w0, [x29, 28]
    str    x1, [x29, 16]
    ldr    x0, [x29, 16]
    add    x0, x0, 8
    ldr    x0, [x0]
    bl    atoi
    bl    func1
    str    w0, [x29, 44]
    adrp    x0, .LC0
    add    x0, x0, :lo12:.LC0
    ldr    w1, [x29, 44]
    bl    printf
    nop
    ldp    x29, x30, [sp], 48
    ret
    .size    main, .-main
    .ident    "GCC: (Ubuntu/Linaro 7.5.0-3ubuntu1~18.04) 7.5.0"
    .section    .note.GNU-stack,"",@progbits
```

### Solution

{% hint style="info" %}
`stp`: **Store Pair**

`bl`: **Branch with Link**

`lsr`: **Logical Shift Right**
{% endhint %}

The program computes `and 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`.

### Implementation

```python
#!/usr/bin/env python3

target = 3350728462

result = 0
while target != 0:
    if target & 1 != 0:
        result += 3
    target >>= 1

print(hex(result))
```

## Let's get dynamic

### Challenge

Can you tell what this file is reading? [chall.S](https://mercury.picoctf.net/static/0ae77c18ca85211e6439e5e710657a54/chall.S)

### Solution

Compile the assembly code:

```
$ gcc -c chall.S -o chall.o
$ gcc chall.o -o chall
```

Disassemble the main function:

```
pwndbg> disass main
```

![PIE](/files/-MX3l5xzWFDJl93W6RqT)

Since **PIE** is enabled, all the addresses here are just **offsets**. We need to **run the program** for the correct addresses to load:

```
pwndbg> r
...
pwndbg> disass main
```

![main](/files/-MX3lCGnUwT3cLGK2XmK)

The `memcmp` function compares our input with the flag. Set a breakpoint on `memcmp` and run the program again:

```
pwndbg> b *0x00005555555552f6
pwndbg> r
```

The flag is located in RSI at this moment:

![flag](/files/-MX3lJ7QQ29RC1_cdQNE)

## Easy as GDB

### Challenge

The flag has got to be checked somewhere... File: [brute](https://mercury.picoctf.net/static/34d95f5c7898c0d9500790225437239e/brute)

### Solution

Take a look at the pseudocode:

![strncpy()](/files/-MX3enlJJe3WuTz_VHEG)

Here `unk_2008` is the encrypted flag:

![Ecrypted flag](/files/-MX3f1RTgGEk2YdfcRQl)

This is a nice use case for the [angr template](https://www.ctfnote.com/reversing/angr#template-for-simple-crackme). What we have to do here is:

1. Figure out the flag **length**
2. Find the address of the **"Correct!"** state
3. Find the address of the **"Incorrect."** state

The length of the encrypted flag is 30, so the flag in clear should be **30-byte long** as well.

The `call puts` instruction for **"Correct!"**:

![Correct](/files/-MX3f59oXptVRNcFhNUq)

The `call puts` instruction for **"Incorrect."**:

![Incorrect](/files/-MX3f7y368ULml3lvCnW)

### Implementation

```python
#!/usr/bin/env python3
import angr
import claripy

FLAG_LEN = 30
STDIN_FD = 0

base_addr = 0x100000 # To match addresses to Ghidra

proj = angr.Project('brute', main_opts={'base_addr': base_addr}) 

flag_chars = [claripy.BVS('flag_%d' % i, 8) for i in range(FLAG_LEN)]
flag = claripy.Concat( *flag_chars + [claripy.BVV(b'\n')]) # Add \n for scanf() to accept the input

state = proj.factory.full_init_state(
        args=['brute'],
        add_options=angr.options.unicorn,
        stdin=flag,
)

# Add constraints that all characters are printable
for k in flag_chars:
    state.solver.add(k >= ord('!'))
    state.solver.add(k <= ord('~'))

simgr = proj.factory.simulation_manager(state)
find_addr  = 0x100a72 # the address of "call puts" for SUCCESS
avoid_addr = 0x100a86 # the address of "call puts" for FAILURE
simgr.explore(find=find_addr, avoid=avoid_addr)

if (len(simgr.found) > 0):
    for found in simgr.found:
        print(found.posix.dumps(STDIN_FD))
```

Start an angr Docker environment:

```
docker run -it angr/angr
```

Run this script and wait. The script will take some time to finish, so be patient.

## ARMssembly 4

### Challenge

What integer does this program print with argument `3964545182`? File: [chall\_4.S](https://mercury.picoctf.net/static/140885fffcd9e3a3264725ed3e568790/chall_4.S) Flag format: picoCTF{XXXXXXXX} -> (hex, lowercase, no 0x, and 32 bits. ex. 5614267 would be picoCTF{0055aabb})

### Assembly with Comments

```
    .arch armv8-a
    .file    "chall_4.c"
    .text
    .align    2
    .global    func1
    .type    func1, %function
func1:
    stp    x29, x30, [sp, -32]!
    add    x29, sp, 0
    str    w0, [x29, 28]
    ldr    w0, [x29, 28]
    cmp    w0, 100
    bls    .L2 @ if w0 <= 100, branch to .L2
    ldr    w0, [x29, 28] @ w0 = [x29+28]
    add    w0, w0, 100 @ w0 += 100
    bl    func2 @ branch to fun2
    b    .L3 @ branch to .L3 unconditionally
.L2:
    ldr    w0, [x29, 28]
    bl    func3 @ branch to func3
.L3:
    ldp    x29, x30, [sp], 32
    ret
    .size    func1, .-func1
    .align    2
    .global    func2
    .type    func2, %function
func2:
    stp    x29, x30, [sp, -32]!
    add    x29, sp, 0
    str    w0, [x29, 28]
    ldr    w0, [x29, 28]
    cmp    w0, 499
    bhi    .L5 @ branch to .L5 if w0 > 499
    ldr    w0, [x29, 28]
    sub    w0, w0, #86
    bl    func4 @ branch to func4
    b    .L6 @ branch to .L6 unconditionally
.L5:
    ldr    w0, [x29, 28]
    add    w0, w0, 13 @ w0 += 13
    bl    func5 @ branch to func5
.L6:
    ldp    x29, x30, [sp], 32
    ret
    .size    func2, .-func2
    .align    2
    .global    func3
    .type    func3, %function
func3:
    stp    x29, x30, [sp, -32]!
    add    x29, sp, 0
    str    w0, [x29, 28]
    ldr    w0, [x29, 28]
    bl    func7 @ branch to func7
    ldp    x29, x30, [sp], 32
    ret
    .size    func3, .-func3
    .align    2
    .global    func4
    .type    func4, %function
func4:
    stp    x29, x30, [sp, -48]!
    add    x29, sp, 0
    str    w0, [x29, 28]
    mov    w0, 17 @ w0 = 17
    str    w0, [x29, 44]
    ldr    w0, [x29, 44]
    bl    func1 @ branch to func1
    str    w0, [x29, 44]
    ldr    w0, [x29, 28]
    ldp    x29, x30, [sp], 48
    ret
    .size    func4, .-func4
    .align    2
    .global    func5
    .type    func5, %function
func5:
    stp    x29, x30, [sp, -32]!
    add    x29, sp, 0
    str    w0, [x29, 28]
    ldr    w0, [x29, 28]
    bl    func8 @ branch to func8
    str    w0, [x29, 28]
    ldr    w0, [x29, 28]
    ldp    x29, x30, [sp], 32
    ret
    .size    func5, .-func5
    .align    2
    .global    func6
    .type    func6, %function
func6:
    sub    sp, sp, #32
    str    w0, [sp, 12]
    mov    w0, 314 @ w0 = 314
    str    w0, [sp, 24] @ [sp+24] = w0 = 314
    mov    w0, 1932 @ w0 = 1932
    str    w0, [sp, 28] @ [sp+28] = w0
    str    wzr, [sp, 20] @ [sp+20] = 0
    str    wzr, [sp, 20]
    b    .L14 @ branch to .L14
.L15:
    ldr    w1, [sp, 28] @ w1 = [sp+28]
    mov    w0, 800 @ w0 = 800
    mul    w0, w1, w0 @ w0 *= w1
    ldr    w1, [sp, 24] @ w1 = [sp+24]
    udiv    w2, w0, w1 @ w2 = w0 // w1
    ldr    w1, [sp, 24] @ w1 = [sp+24]
    mul    w1, w2, w1 @ w1 *= w2
    sub    w0, w0, w1 @ w0 -= w1
    str    w0, [sp, 12] @ [sp+12] = w0
    ldr    w0, [sp, 20] @ w0 = [sp+20]
    add    w0, w0, 1 @ w0 += 1
    str    w0, [sp, 20] @ [sp+20] = w0
.L14:
    ldr    w0, [sp, 20]
    cmp    w0, 899
    bls    .L15 @ branch to .L15 if w0 <= 899
    ldr    w0, [sp, 12]
    add    sp, sp, 32
    ret
    .size    func6, .-func6
    .align    2
    .global    func7
    .type    func7, %function
func7:
    sub    sp, sp, #16
    str    w0, [sp, 12]
    ldr    w0, [sp, 12]
    cmp    w0, 100
    bls    .L18 @ branch to .L18 if w0 <= 100
    ldr    w0, [sp, 12]
    b    .L19 @ branch to .L19 unconditionally
.L18:
    mov    w0, 7 @ w0 = 7
.L19:
    add    sp, sp, 16
    ret
    .size    func7, .-func7
    .align    2
    .global    func8
    .type    func8, %function
func8:
    sub    sp, sp, #16
    str    w0, [sp, 12]
    ldr    w0, [sp, 12]
    add    w0, w0, 2 @ w0 += 2
    add    sp, sp, 16
    ret
    .size    func8, .-func8
    .section    .rodata
    .align    3
.LC0:
    .string    "Result: %ld\n"
    .text
    .align    2
    .global    main
    .type    main, %function
main:
    stp    x29, x30, [sp, -48]!
    add    x29, sp, 0
    str    w0, [x29, 28]
    str    x1, [x29, 16]
    ldr    x0, [x29, 16]
    add    x0, x0, 8
    ldr    x0, [x0]
    bl    atoi
    str    w0, [x29, 44]
    ldr    w0, [x29, 44]
    bl    func1
    mov    w1, w0
    adrp    x0, .LC0
    add    x0, x0, :lo12:.LC0
    bl    printf
    nop
    ldp    x29, x30, [sp], 48
    ret
    .size    main, .-main
    .ident    "GCC: (Ubuntu/Linaro 7.5.0-3ubuntu1~18.04) 7.5.0"
    .section    .note.GNU-stack,"",@progbits
```

### Solution

{% hint style="info" %}
`bhi`: **Branch on Higher than**
{% endhint %}

Here is my note:

```
arg = 3964545182

1. func1: 3964545182 + 100 = 3964545282
2. func2: 3964545282 + 13 = 3964545295
3. func5: do nothing
4. func8: 3964545295 + 2 = 3964545297
5. func1: do nothing
6. func3: do nothing
7. func7: do nothing

result = 3964545297 = 0xec4e2911
```

## Powershelly

{% hint style="warning" %}
Someone, pls solve it!
{% endhint %}

### Challenge

It's not a bad idea to learn to read Powershell. We give you the output, but do you think you can find the input? [rev\_PS.ps1](https://mercury.picoctf.net/static/e675715b02ce84237e547c7c157f4bef/rev_PS.ps1) [output.txt](https://mercury.picoctf.net/static/e675715b02ce84237e547c7c157f4bef/output.txt)

### Solution

Todo!

## Rolling My Own

{% hint style="warning" %}
Someone, pls solve it!
{% endhint %}

### Challenge

I don't trust password checkers made by other people, so I wrote my own. It doesn't even need to store the password! If you can crack it I'll give you a flag. [remote](https://mercury.picoctf.net/static/79d137e8d6b1668e4513d7756b6b37ba/remote) `nc mercury.picoctf.net 17615`

### Solution

Todo!

## Checkpass

{% hint style="warning" %}
Someone, pls solve it!
{% endhint %}

### Challenge

What is the password? File: [checkpass](https://mercury.picoctf.net/static/8c9aa2897fe88ac8208808dda083f089/checkpass) Flag format: picoCTF{...}

### Solution

Todo!
