# h3 h3machine 0

So starting off, for these challenges we will have to set up a few things before we can really dive in. We will have to set up a virtual environment for this to work.

First if you don't have it already, you will need to install pipenv:
```
$    sudo pip install pipenv
```

Then unzip the tar file and traverse into it:
```
$    tar -zxvf h3-machine-emulator.tar.gz

.    .    .

$    cd h3-machine-emulator/
```

Then setup the virtual environment:

```
$    pipenv --three install
Virtualenv already exists!
Removing existing virtualenv...
Creating a virtualenv for this project...
Pipfile: /Hackery/pod/modules/custom_architecture/h3_h3machine0/h3-machine-emulator/Pipfile
Using /usr/bin/python3 (3.6.8) to create virtualenv...
⠙ Creating virtual environment...Using base prefix '/usr'
New python executable in /home/guyinatuxedo/.local/share/virtualenvs/h3-machine-emulator-1bmi1h2b/bin/python3
Also creating executable in /home/guyinatuxedo/.local/share/virtualenvs/h3-machine-emulator-1bmi1h2b/bin/python
Installing setuptools, pip, wheel...
done.
Running virtualenv with interpreter /usr/bin/python3

✔ Successfully created virtual environment!
Virtualenv location: /home/guyinatuxedo/.local/share/virtualenvs/h3-machine-emulator-1bmi1h2b
Virtualenv already exists!
Removing existing virtualenv...
Creating a virtualenv for this project...
Pipfile: /Hackery/pod/modules/custom_architecture/h3_h3machine0/h3-machine-emulator/Pipfile
Using /usr/bin/python3 (3.6.8) to create virtualenv...
⠙ Creating virtual environment...Using base prefix '/usr'
New python executable in /home/guyinatuxedo/.local/share/virtualenvs/h3-machine-emulator-1bmi1h2b/bin/python3
Also creating executable in /home/guyinatuxedo/.local/share/virtualenvs/h3-machine-emulator-1bmi1h2b/bin/python
Installing setuptools, pip, wheel...
done.
Running virtualenv with interpreter /usr/bin/python3

✔ Successfully created virtual environment!
Virtualenv location: /home/guyinatuxedo/.local/share/virtualenvs/h3-machine-emulator-1bmi1h2b
Installing dependencies from Pipfile.lock (ed1172)...
  🐍   ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 4/4 — 00:00:02
To activate this project's virtualenv, run pipenv shell.
Alternatively, run a command inside the virtualenv with pipenv run.
```

After that you will need to compile the emulator. Just run `make` in the same directory:

```
$	make
cc --std=gnu99 -Wall -Wextra -Werror -Wpedantic   -c -o src/h3emu.o src/h3emu.c
cc --std=gnu99 -Wall -Wextra -Werror -Wpedantic   -c -o src/machine.o src/machine.c
cc --std=gnu99 -Wall -Wextra -Werror -Wpedantic   -c -o src/opcodes.o src/opcodes.c
cc --std=gnu99 -Wall -Wextra -Werror -Wpedantic   -c -o src/opcode_lookup.o src/opcode_lookup.c
cc    -o h3emu src/h3emu.o src/machine.o src/opcodes.o src/opcode_lookup.o
```

So now that the setup is out of the way, let's focus on the challenge. So this module is all about dealing with a custom architecture (rather one particular instance of a custom architecture). This means that the assembly code of the binaries wasn't written in `x86`, `x64`, `MIPS`, `ARM` or anything else that you will typically see. The assembly code itself is custom and unique. Fortunately they provided some documentation in the `README.md` file that I will copy and paste here for convenience (reading this will really help). Again this following chunk of documentation was made by the challenge authors, not me:

```
# H3 Machine

The H3 Machine is a simple computer designed for writing interesting binary reversing problems.
It is a stack machine with no general-purpose registers.

# tl;dr

Each challenge is an executable image that can be run with the H3 machine
emulator. If the challenge runs correctly, it will print out the flag.

You can run the challenges like:

    ./h3emu [--trace] IMAGE [ARG1 [ARG2 [...]]]

For example,

  ./h3emu --trace challenge1.h3i 10 20 30

The --trace flag will print out each instruction as it executes.

You can also get a static disassembly with:

  ./h3disasm IMAGE


To get the flag, you may have to modify the challenge image slightly or provide
a particular set of arguments. Good luck!


# Building

    make

# Developers

To run the assembler or code generation, you need [pipenv][] installed.

You should say

    pipenv --three install

to get the virtualenv set up. After that, everything should just work.

# Registers

There are four special-purpose registers which are 16 bits in length:

-   IP: Instruction Pointer
-   SP: Stack Pointer
-   FR: Flag Register

The currently-defined flags are:

-   0x0001: Zero flag: set when 0x00000000 is pushed;
    cleared when any other value is pushed
-   0x0002: Carry flag: set when an arithmetic operation overflows;
    cleared when an arithmetic operation does not overflow.
    Non-arithmetic instructions do not update this flag.
-   0x8000: Flag flag: set when the top value of the stack at the HALT
    instruction most likely contains the flag.

There's a hidden stack used for CALL/RET.

# Memory

This machine operates on 32-bit words.
The total memory consists of 2^16 word-addressed 32-bit words (1 MiB).

By convention, word 0x0000 should always contain the value 0x00000000.

## Loading

An executable is loaded into the machine by memory mapping the file with 1 MiB total size.
IP is initialized to 0x0001, SP, and FR are initialized to 0x0000.

# Emulator

Additional command line arguments will be pushed on the stack before execution begins.

When the HALT instruction is reached, the stack and registers will be printed.

    h3emu [--trace] IMAGE [ARG1 [ARG2 [...]]]
    h3emu --version
    h3emu --help

# Disassembler

You can use the --trace flag of the emulator to get a dynamic stream of
instructions as they execute. Alternatively, you can use h3disasm to get a
basic static disassembly of the image.

  h3disasm IMAGE

# Instructions

The bits of the instruction are allocated like this:

   [PII_REDACTED]abcdef[PII_REDACTED]abcdef
    -------- opcode
            ----- reserved
                 --- addressing mode
                     ---------------- address

## Opcodes

Opcodes can take operands.
The first operand is read from the location indicated by the address field of the instruction.
Second and further operands are always popped from the stack.
Results are pushed onto the stack.

-   0x00 HALT: Machine stops execution

### Stack manip opcodes

-   0x10 DROP: Increment SP.
-   0x11 SWAP: Get two operands, then push them in reverse order.
-   0x12 PUSH: Get one operand, then push it.
-   0x13 POP: Remove the topmost stack entry, put it somewhere else according to the address.
    This operation is the only exception to the rule that the first argument is based on the address and the result goes on the stack.
    This operation works the other way around, the argument comes from the stack and the result goes to the location of the address.

### Arithmetic opcodes

-   0x20 ADD: Get two operands, add them (mod 2^32)
-   0x21 SUB: Get two operands, subtract