hasherezade / tiny_tracer

A Pin Tool for tracing API calls etc
1.25k stars 138 forks source link

Problems with vmprotect #26

Open merfin993 opened 1 year ago

merfin993 commented 1 year ago

Hi, I was trying to check the syscalls of a malware sample protected with vmprotect and noticed that the execution stops before reaching the payload. (the malware does not run and no error message is displayed)

Doing other tests (with the demo version of vmprotect and a test payload) I realized that the problem is only related to the vmprotect debugger flag, without the flag the test payload is executed and traced.

Do you know of a way around this problem?

hasherezade commented 1 year ago

hi @merfin993 ! I know that VMProtect tries to disrupt analysis tools in various ways. Depending on the version, and the used settings, some of this disruptions can be counteracted, and others not. If you can share a sample packed with the settings that you found causing the issue, I will reproduce the problem, and try to resolve it. You can attach the sample here, or send to my email: hasherezade-at-protonmail.com

merfin993 commented 1 year ago

Hi @hasherezade, thanks for the reply. The setting that doesn't run the payload with Tiny_Tracer (vmprotect demo latest version) debugger

And the sample sample.zip (Password "infected")

You will find the 3 payloads I made for safe testing. Is a sample that injects shellcode (which starts calc.exe) into another process (explorer.exe) via direct system calls. (queueAPCthread)

The two samples that have "ok" in the name are traced correctly while the one called "debugger" does not execute the payload.

For simplicity the vmprotect antivm flags are disabled in all 3 samples.

I'm also trying to find a solution.

Thank you

hasherezade commented 1 year ago

thank you @merfin993 ! I appreciate. I am gonna check it & get back to you soon

merfin993 commented 1 year ago

Hi @hasherezade. Today I was able (with a driver) to get trace of system calls used by vmprotect with usermode and usermode + kernelmode antidebug flags enabled.

I wanted to ask if they could be useful to identify the problems that tiny_tracer has with vmprotect.

I thank you again.

hasherezade commented 1 year ago

hi @merfin993 ! was you able to pinpoint what exactly are the flags that VMProtect checks? to be honest, so far I wasn't able to find the exact ones. I am afraid finding them will require deeper digging, and devirtualization of this stub.

so far I made some blackbox tests using Al-khaser, and I found what of the standard flags used by debuggers are set by PIN. And indeed I found something: it seems to set ProcessDebugFlags. For now I just tried to bypass the option "Usermode debugger"

So I implemented in tiny_tracer an option to hide it:

The feature seems to work correct (yet it turned out not to be sufficient to solve the original problem with VMProtect).

This is before hiding enabled:

pin_before_hide

This is after hiding enabled:

with_hide

Next I am gonna try to hide the marker based on INT 2D. UPDATE: it does not seem to be INT 2D either...

So, so far I am trying to pinpoint what exactly is the check done by VMProtect for which I should find the workaround. If your collected material provides any clues about it, I would be grateful if you share!

merfin993 commented 1 year ago

Hi @hasherezade.

I did some tests by disabling virtualization and mutations to get the cleanest trace possible. (the sample is contained in the archive) Using a driver to get syscall callbacks I got the trace. (I didn't use pins)

I send you the results of the syscalls obtained through a driver. vmptrace.zip

I'm still analyzing the traces to determine what checks vmprotect does (syscalls side)

In case it's not a check made via syscalls these are some projects I'm analyzing:

hasherezade commented 1 year ago

Hi @merfin993, just a small update. I found what was the reason why no error message was displayed. It was due to the Trap Flag, that was causing the tracer to crash. The latest version 2.6 automatically unsets the Trap Flag and makes it go a bit more forward. You can enable it by selecting an option ANTIDEBUG in the INI file (more info here). Note that it is not a complete bypass that would cause the payload to execute, but at least we know more details of what is happening.

dbg_info

I hope soon I am gonna have more time to dedicate to TinyTracer again, and I will dig into details and try to make a complete bypass.

hasherezade commented 1 year ago

@merfin993 - After the latest updates, TinyTracer is finally able to bypass this Trap-based check. I tested with your sample application, as well as with my own testcases, protected by VMProtect with the mentioned settings.

trap_bypassed

The bypass works when ANTIDEBUG mode is enabled

helloobaby commented 1 week ago

I also tested it, and the 64-bit app version has no problem, but the 32-bit app protected by VMProtect cannot be traced either. And I researched for a few days and saw the latest issue about winlicense,so I suspect that 32-bit apps need to do more in anti-debugging. I just found: Int 2E is also used as anti-debugging in VMProtect.

Here is a 32-bit compiled app protected by VMProtect3.8 for testing.

al-khaser.vmp.zip

Hope this helps a little

hasherezade commented 1 week ago

thank you @helloobaby , I will have a look when I get some free time

hasherezade commented 5 days ago

@helloobaby - I added some fixes. It turns out that your sample switches to 64-bit mode via Heaven's Gate - this is something that PIN cannot handle. But it is now reported in the tracelog. With applied fixes, your sample can be traced on a 32-bit Windows. The following settings in TinyTracer.ini must be set:

ANTIDEBUG=1
ANTIVM=1
EMULATE_HYPERV=True

al-khaser.vmp.exe.tag.txt

traced

helloobaby commented 5 days ago

Thank you very much, this question has puzzled me for many days.