Challenge 2

Inverse! Inverse everywhere!

  • We have a Windows PE file named "very_success.exe". Looking at it's imports, it's moror less the same as the previous challenge i.e takes a value from STDIN and gives a success or failure output.

  • There are four functions in the program. We are going to start with the "_start" function.

  • The start function calls "sub_401000" function, scans the string in EDI register (scasd), stores the value in the AL register (stosb), loads it into ESI (lodsd) and finally calls the "sub_401097" function.

  • We need to look into the "sub_401000" function first.

Disassembly
Decompilation
  • The function takes an 50 byte input, stores it in "data_402159" and then sends it to "sub_401084". If "sub_401084" returns true, then the program returns success; else it's a failure. Now that this function is done, we can move on to the next function.

  • First, after setting up the stack and zeroing out the EBX register, this function checks if the third input argument (arg3) which is the length of the input buffer is 0x25 (37) or not. This means that the flag is most probably 37 bytes long.

  • Then we come to the main calculation "part" of the function.

  • In the loop, EDI (where the key is being stored) is continually decremented by 2. Also initially, the EDI is set to the last byte of the key instead of the first. This means that the key is stored in memory in the reverse order.

  • In the loop, BX is copied to DX and is ANDed with 0x03; which clears all but the bottom 2 bits. Next the value 0x1c7 is moved to the stack through AX register. Then, the SAHF instruction loads the highest bit of that value (0x1) to the EFALGS register. This leads to the lowermost flag in the register (carry) being set. The lodsb instruction then loads a byte of the input (in the ESI register) into AL and pushfd stores the EFLAGS register in the stack.

  • The input byte in AL is XORed with a value. After spending some time in x32dbg, the value turns out to be 0xc7.

  • The contents of AH is still set to 0x01 and is then rotated (left) by the amount specified by the lowest 2 bits of the rolling sum value. Then the POPF instruction restores the EFLAGS register with the saved flags on the stack (carry flag set). The ADC instruction that follows is just like a normal ADD instruction but it also adds the carry. After that, the EDX register is zeroed out and the lower 8 bits / lower byte of EAX is added to bx.

  • The scasb instruction then scans the above value and compares it with the value in EDI. If this fails, then the loop is terminated. This complicated reverse process is repeated 37 times. After that, if the input value is correct, the success output appears. We need to write a python script to kind of emulate this process to get the flag value.

  • We have now got the flag. Hurray!!

Last updated