English [MMA 2015] [Reverse – How to use?] Write Up

Description

We were given a file : howtouse.

Resolution

We checked the type of the file:
$ file howtouse

howtouse: PE32 executable (DLL) (GUI) Intel 80386, for MS Windows

Ok. A DLL, let’s switch to Windows !
Well in fact…so boring !

Using a decompiler, we had the following code (I cut some parts):

#include <windows.h>
#include <defs.h>

signed int sub_6FAC1010();
signed int sub_6FAC1020();
signed int sub_6FAC1030();
int __cdecl fnhowtouse(int);
...

signed int sub_6FAC1010()
{
  return 97;
}

signed int sub_6FAC1020()
{
  return 98;
}

int __cdecl fnhowtouse(int a1)
{
  signed int (*v2)();
  signed int (*v3)();
  signed int (*v4)();
  signed int (*v5)();
...

  v2 = sub_6FAC1080;
  v3 = sub_6FAC1080;
  v11 = sub_6FAC1090;
  v14 = sub_6FAC1090;
...
  return (*(&v2 + a1))();
}

The most interesting part here is the fnhowtouse function.
Each integer variable is filled by a sub_XXXXXXXX function when running the code.
Below is a good example :

v2 = sub_6FAC1080;

calls the function:

signed int sub_6FAC1080()
{
  return 77;
}

so v2 = 77;

When calling all the functions:

v2 = sub_6FAC1080; 77
v3 = sub_6FAC1080; 77
v4 = sub_6FAC1070; 65
v5 = sub_6FAC1110; 123
v6 = sub_6FAC1060; 102
v7 = sub_6FAC1030; 99
v8 = sub_6FAC10E0; 55
v9 = sub_6FAC1040; 100
v10 = sub_6FAC1100; 57
v11 = sub_6FAC1090; 48
v12 = sub_6FAC1030; 99
v13 = sub_6FAC1010; 97
v14 = sub_6FAC1090; 48
v15 = sub_6FAC1090; 48
v16 = sub_6FAC10A0; 49
v17 = sub_6FAC1060; 102
v18 = sub_6FAC1030; 99
v19 = sub_6FAC10F0; 56
v20 = sub_6FAC10E0; 55
v21 = sub_6FAC10A0; 49
v22 = sub_6FAC10B0; 50
v23 = sub_6FAC10D0; 52
v24 = sub_6FAC1100; 57
v25 = sub_6FAC10E0; 55
v26 = sub_6FAC1040; 100
v27 = sub_6FAC10F0; 56
v28 = sub_6FAC10F0; 56
v29 = sub_6FAC1040; 100
v30 = sub_6FAC1100; 57
v31 = sub_6FAC1050; 101
v32 = sub_6FAC1050; 101
v33 = sub_6FAC10E0; 55
v34 = sub_6FAC1050; 101
v35 = sub_6FAC1060; 102
v36 = sub_6FAC1010; 97
v37 = sub_6FAC1100; 57
v38 = sub_6FAC1050; 101
v39 = sub_6FAC1100; 57
v40 = sub_6FAC1020; 98
v41 = sub_6FAC10C0; 51
v42 = sub_6FAC10B0; 50
v43 = sub_6FAC1050; 101
v44 = sub_6FAC1040; 100
v45 = sub_6FAC10F0; 56
v46 = sub_6FAC1120; 125

$ python

>>> s = '77 77 65 123 102 99 55 100 57 48 99 97 48 48 49 102 99 56 55 49 50 52 57 55 100 56 56 100 57 101 101 55 101 102 97 57 101 57 98 51 50 101 100 56 125'
>>> print "".join([chr(int(c)) for c in s.split(' ')])
MMA{fc7d90ca001fc8712497d88d9ee7efa9e9b32ed8}

Flag is MMA{fc7d90ca001fc8712497d88d9ee7efa9e9b32ed8}

9 thoughts on “[MMA 2015] [Reverse – How to use?] Write Up”

  1. Hello. it was very difficult for me. Could i ask question? how to call the all functions and convert this numbers 77 77 65 123 102 99 55 100 57 48 99 97 48 48 49 102 99 56 55 49 50 52 57 55 100 56 56 100 57 101 101 55 101 102 97 57 101 57 98 51 50 101 100 56 125. please explain more and more?

    1. Hello Tsuka 🙂
      In fact you can simply parse the decompiled C code.
      You don’t need to call the functions from outside.
      1) Sort all the variables v2, v3, v4 etc.. as I did.
      2) For each variable there’s a function called, which will return a value.
      I’ll take another more detailed example, not in my cropped source code :
      v22 = sub_6FAC10B0; //Here v22 = the variable, sub_6FAC10B0 is the function
      If you search the function named sub_6FAC10B0 in your decompiled code, you’ll find :
      signed int sub_6FAC10B0()
      {
      return 50;
      }

      The final value of the variable v22 will be 50.
      3) The function returns an integer (notice the “signed int” before the name).
      It’s not a binary value and there are no letters A-F, so it can only be a decimal form.
      You have to take the value the 50 and convert it in ASCII which gives 2.
      v22 = 2; //50 in decimal.
      4) When you have all the numbers, pass theses to a converter from decimal to ASCII.
      This is an explanation of my code in python :
      – it splits the string with all the values you gave it
      – for each number it converts it in an ASCII value
      – prints the final ASCII string

      I hope it will be easier to understand now 🙂

  2. Hello, I’m a beginner with CTFs, which compiler did you use? I was messing around with IDA Pro and I saw the same fnhowtouse but I never put the pieces together. Which compiler did you use?

    1. Exactly what decompiler did you use? I’m a beginner and would like to have proper tools from the start. I used ret-dec and it didn’t give me the proper ascii.

      1. We commonly use IDA Pro for reversing and decompiling. WtF did this challenge, but given his decompiling result, I would assume he used IDA.
        (I’ll let him confirm though)

          1. From IDA, how did you get the result to look so “readable”. Mine mostly came out with assembly commands.

          2. You have to use the decompiler (and not just stay in disassembler mode) :
            File / Produce file / Create C file…

            If you haven’t all the returned int values in the file, you have to attach the DLL to rundll32.exe:
            – Choose windbg as debugger
            – Debugger / Process options…
            – Application : rundll32.exe

            As example:
            howtouse_without_windbg.txt
            howtouse_with_windbg.txt

Leave a Reply to Tsuka Cancel reply

Your email address will not be published. Required fields are marked *