SpeakEasy writeup

kishou yusa
3 min readAug 5, 2021

--

1. Overview

Open the challenge give us a 64 bit pe file. If you run it, it will ask to submit the password to continue. The password will be the flag, if you input it right, it will congratulate and the password is flag.

For this challenge i use this tools:

  • NoVmp: To lift the VMProtect instructions
  • Vtil-Util: To convert vtil byte code to vtil instructions
  • tiny-tracer: Understand the flow of the file
  • Pe-bear: Check the pe file

2. Intuation

First i use pe-bear to see the information of the pe file.

In the section, you can see there are 2 sections that have very interesting names: .vmp0 .vmp1

Just from that, i knew that i am dealing with VmProtect file.

Lucky i have read a blog 1–2 months ago about VmProtect: VMProtect 2 — Detailed Analysis of the Virtual Machine Architecture // Back Engineering. You should really read it to understand about the how VmProtect work.

3. The control flow

I will use binary ninja cloud for easy to understand

vm_1: https://cloud.binary.ninja/embed/0a6f426c-637c-4284-88e6-8104467b96ef

main_vm_function: https://cloud.binary.ninja/embed/8f0db8c8-e326-45d8-ae7f-e14afde182c3

Navigate to main_vm_function, you will see that there are 4 vm function (i have name them as vm_1, vm_2, vm_3, vm_4)

At the beginning, each function has a structure which look like:

Beginning structure for VmProtect

That is the vm_entry of the VmProtect, we gonna need it for NoVmp to run.

To understand the control flow of the vm i use tiny_tracer, it is a great tool that tell you the api that the execute call and when and where the execute jump to different section to execute code.

4. Solving the challenge

For the vm to work it need to jump from section to section to execute the vm. So with tiny_tracer i can know at which address will the section jump take place (a section jump is a jump from one section to another by call and indirect or direct jump)

Here is a segment of the output from tiny tracer:

As you can see when it need to execute the vm, it need to jump from .text section to .vmp0 section and then return back to .text section for further execution.

Now using the rva that tiny_tracer produce, we can get all the vm_entry that we need and the execution flow of it: 28270 -> 262c9 -> 12b360 -> 12b2ef -> 12b2fe -> 12b309.

Now to we use NoVmp to dump the vm instruction from each of the vm_entry above. And then use vtil util to turn the byte code into readable vtil instruction. It will look like this:

the first 2 vm_entry(28270, 262c9): Is use the encrypt your input and then store it to the allocated. That is the only 2 function that you need to understand to solve this challenge.

After some time debug the code, i notice that in the rva 2690 (in binary ninja cloud u can find it as main_cmp_function) it take our input that hava been ecrypted by the 2 vms above and then compare with a generate chunk of byte from 12b360, 12b2ef, 12b2fe vms and then compare if they are the same.

So to solve the function i dump the content of it and then make a decrypt for 28270 and 262c9 vms.

Here is the final code:

The flag: uiuctf{D0nt_b3_@_W3T_bl4nK3t_6n7a}

If you have any question feel free to dm me on discord: kishou yusa™#6557

--

--