At the start of the function you can see a read() of 4 bytes and a first check afterwards, which would exit the application
if you enter 4 bytes bigger than 0x3e8.
If this is check is passed, the entered value input_size is used in the while loop to read() more data into input_data.
After this loop is completed, input_data is hashed in 16 byte chunks with SHA1() and written into code.
At the end the original input_data is overwritten with 0xffffffff and the program jumps to the code data.

So the data we input in the loop, gets hashed in 16 byte chunks with SHA1 and then we jump to those hashes.
Now it's clear what we have to do - we have to generate SHA1 hashes with valid x86-64 opcodes.

This is a bit of crappy C code to bruteforce hashes with specific values.

Now that we have a little tool to generate hashes with opcodes we have to come up with a general
idea to fit the shellcode into the hashes:

The program jumps to the start of the first hash and there will be a jump to the end of the 2nd hash. At the end of the 2nd
hash starts the shellcode with the first instruction(s). The beginning of the hash afterwards will be another jump the the end of the hash after that.

So generally we have in the beginning of one hash a jump to the end of the next hash, which will contain one or more shellcode opcodes. This way we can execute anything we want...

The only problem is the length of the opcode. It was fairly fast to bruteforce up to three bytes.
But I had to get the long string /bin/sh into the 64bit register and the 10 byte opcode is too
long to bruteforce.

But because 3 bytes can be bruteforced easily and the jmp only needs 2 bytes, we can
bruteforce 3 bytes at the end of the one hash, and 3 bytes at the beginning fo the next hash to match
opcode (4 bytes) + jump (2 bytes) = 6 bytes

The number behind jmp 2/3 means if it will jump to 2 or 3 bytes before the end of the next hash. Because jumps are done relatively and not absolute it is always the same hash. qzg3NxCyYGweMVIr == jump to the last 3 bytes of the next hash and EI6Tlq7y76Vh5hyN == jump to the last 2 bytes of the next hash.

Now we can put the full string together, with \x3a\x00\x00\x00 as prefix to pass the first check, followed by the 16 byte chunks for the sha1 hashes: