# Reversing - runme
This sweet little program just wants us to run it, and in exchange for thisunweighty trifle it will give us the flag! How nice of it!
But maybe let's first have a short look in IDA? It starts with the quitepredictable `open`-`malloc`-`read`-`close` dance, but then it forks,increments a 16-bit counter:
```.text:080489E3 memset_0_done:.text:080489E3                 call    _fork.text:080489E8                 mov     [esp+0F0h+pid], eax.text:080489EC                 movzx   eax, [esp+0F0h+incme_after_fork].text:080489F1                 add     eax, 1.text:080489F4                 mov     [esp+0F0h+incme_after_fork], ax.text:080489F9                 cmp     [esp+0F0h+pid], 0.text:080489FE                 jz      in_child```
hashes a 16-byte buffer we've just `memset` to all zeroes:
```.text:08048A04 in_parent:.text:08048A04                 mov     [esp+0F0h+arg1], 10h.text:08048A0C                 lea     eax, [esp+0F0h+buf].text:08048A10                 mov     [esp+0F0h+arg0], eax.text:08048A13                 call    hash_md5_val.text:08048A18                 cmp     [esp+0F0h+incme_after_fork], 0.text:08048A1E                 jns     incme_after_fork_ge_0 ; 2**15 times```
goes through a bunch of `nop`s:
```.text:08048B2A in_child:                               ; CODE XREF: main+101↑j.text:08048B2A                 nop```
falls through to waiting for its child:
```.text:08048B3F incme_after_fork_ge_0:                  ; CODE XREF: main+121↑j.text:08048B3F                 call    _wait.text:08048B44                 jmp     memset_0_done```
and repeats the whole sequence until 16-bit counter's sign bit does not become1, that is, 2 ** 15 times. This means that that many processes will be spawnedat a time. That's not a proper fork bomb yet, but it's not hard to imagine thata reasonable person would still find this rude and not acceptable.
So, let's defuse the evil contraption?
```# skip forkb *0x080489E3commands  set $eip = 0x080489E8  set $eax = 1  cend
# skip waitb *0x08048B3Fcommands  set $eip = 0x08048B44  cend```
The code runs quite quickly and orderly under this gdbscript. Instead ofcreating new processes, it does all the hashing inside of the main one, andthen, as intended, uses the result as an AES key to decrypt the flag.Unfortunately, this produces total garbage. Where is the catch?
Let's try to recap how the program is supposed to work, given infinite timeand resources:
```main:  memset(buf, 0, sizeof(buf))  for _ in range(2 ** 15):    hash(buf)    child0:      wait()  # should return -1, errno=ECHILD      for _ in range(2 ** 15 - 1):        hash(buf)        child1:          ...          exit(0)        wait(child1)  # should return 0 and set *wstatus = 0        decrypt()        exit(0)    wait(child0)  # should return 0 and set *wstatus = 0  decrypt()  exit(0)```
So, the whole action is sequential, despite the number of involved processes.Children will create each other recursively, each ultimately hashing the buffer2 ** 15 times and saving the decrypted flag to the disk, overwriting eachother's work. Finally, the parent would save its own decrypted version,overriding what the last child did. This should be the correct flag.
The bothersome thing is:
```.text:08048B3F                 call    _wait.text:08048B44                 jmp     memset_0_done```
Where is the argument? Where will `wstatus` be saved? This is a 32-bit program,so all the arguments are passed on stack. The last time something was put ontop of the stack was:
```.text:08048A0C                 lea     eax, [esp+0F0h+buf].text:08048A10                 mov     [esp+0F0h+arg0], eax.text:08048A13                 call    hash_md5_val```
This is the buffer that is being hashed! So, sneakily, in addition to hashing,the code overwrites the first 32 bits of the buffer with wstatus, which issupposed to always be zero. It could be possible to enhance gdbscript tosimulate that, but now it's also possible to simply implement the whole logic inPython. Doing this correctly decrypts the flag:`SECCON{infinite_fork_is_not_good_for_system}`. It sure isn't.