30 Sep 2018

September update of unpackers

Last few months have been... extra busy. I survived HDD crash, participated in Flare-On reversing contest (and finished 4th!), had quite fun projects at work - but all that is a matter of another story. Today I want to share with you a long-overdue update for unpackers.

Enigma Virtual Box unpacker

  • Added support for Enigma Virtual Box v8.10, v8.20, v9.00 and v9.10.
  • Unpacker now restores file attributes and date/time. Be careful, unpacked files might have attributes "read only", "hidden", etc.!
  • Added validation of extracted folder/file names to prevent directory traversal attacks. It was on my todo list for a long time and all the media-craziness around Zip Slip finally forced me to do something about it.
  • Fixed warning message about TLS directory. Mea culpa.

Molebox Virtualization Studio unpacker

  • Fixed error "VFSDecrypt: failed to find STELPACK signature" on some data files;
  • Fixed error "SPack catalog not found or invalid. vfsrootsize=00000000" on some EXE files;
  • Fixed out-of-memory error when unpacking huge data files;
  • Loads possible filenames from mole_dictionary.txt;

How to use mole_dictionary.txt

If you have a file which uses "hide files" feature of Molebox VS, it only stores hash of the filename - original filenames are not stored anywhere. But if you have a good idea what the filename might be, you can add it to mole_dictionary.txt and my unpacker will use that for intelligent guessing.
Read More

15 May 2018

Unity3D, Mono and invalid PE files

Some time ago, Reoto asked a very nice question on Black Storm forum:

Can someone fix the .dll (.net) pe header to MS DOS?
How can I do that?
If you know about protecting .net files for Android, please help me.
I have another question.
Can I fix dnspy to resolve .dll pe header isn't .net?

Obviously, English is not author's first language but it seemed like an interesting problem, so I decided to look into it.

Here is one of the files in question: https://mega.nz/#!0g4VHaIR!KmpQirte4_3lv8MSxyjETiufjFGb-CITpFGrXwxSgGY

TL;DR: Mono loader used by Unity3D accepts invalid PE files. It can be used to break most .NET decompilers. dnlib and tools based on dnlib (dnSpy, de4dot) were updated on 20-Apr-2018 but the rest of the tools still can't handle such files.
Read More

27 Feb 2018

February update of unpackers

Enigma Virtual Box unpacker v0.51

  • Hopefully solved the UI-freeze issues.
  • Improved loading speed for big files (100+ MB).
  • Added a warning for the user when loading big file:
  • Added support for Enigma Virtual Box v8.00.
  • Enigma Virtual Box v8.00 finally added support for TLS callbacks. My unpacker will detect such files and will try to fix TLS directory automatically.

Known issue - for x64 executables exception directory is not restored. The unpacked executable will work until an exception happens. If you find any such executable, please send it to me and I'll work to improve the unpacker.

demoleition v0.60

  • Hopefully solved the UI-freeze issues.
  • Fixed bug with certificates and overlays that I introduced few versions ago.
  • Fixed bug with multi-packed files
  • Main form shows that only Molebox v2.x is supported.
  • Improved loading speed for big files (100+ MB) and added warning for users.

demoleition VS v0.01


This is first BETA release of static unpacker for Molebox v4.x. It works for most of the files in my collection but is not well tested by any means. If you notice any bugs (trust me, you will!), please let me know.

Known limitations: way too many. Few most important ones:

  • Error checking is very limited. If something bad happens, it will most likely crash.
  • Main file is saved as _unpacked.bin. Overlay (if present) is saved as overlay.bin.
  • The biggest problem is the "hide files" feature of MoleboxVS. It does not store original filename, just the MD5 hash of it. So, in those cases it's almost impossible to restore original filenames. I added big fat warning for those cases.
  • Loading large files will make the UI freeze. I'll fix it after the bugs in unpacker itself are fixed.

So, why release it? I've had it like this for 5+ years now. It almost works. But without your feedback it will stay in this "almost working" state forever. The more bugs you report, the bigger the chance that I'll finally finish this project.. So, have fun!


Bugs reported by users. I'll work to fix the when I get some free time.

  • Some data files can't be unpacked. Error
  • Sometimes main EXE file will not be unpacked. No error message but _unpacked.bin file won't be created.
  • Mysterious unpacking problem on some files. Error
  • Very large data files can't be unpacked. Error
20 Dec 2017

December update for unpackers

This month brings us not one but two updated unpackers! smile

Updated Molebox unpacker

  • Fixes a crash with double-packed files. Thanks to whoknows for reporting the issue!

Updated Enigma Virtual Box unpacker

  • Support for Enigma Virtual Box v7.90
  • Detection of Enigma Protector. The feature was added long time ago but accidentally removed later.

I still need to work on the UI-freeze issue. When unpacking very large files, UI will appear to be frozen until unpacking process completes. It may take 5+ minutes on very large files, please be patient!

21 Nov 2017

Running WinDbgX on Windows 7

Motivation

Main reason for writing this blog-post is the extremely crappy article by Vallejo named "Installation and First Contact With the New WinDbg". I read it, cried for a few minutes and decided to fix it.

Mandatory XKCD reference:
Someone is wrong on the Internet

Having said that, let's go through some of the most "brilliant" Vallejo's statements!

Installation

We execute WinDbg from installation shortcut and we search the main process.

Dude, when your article is called "Installation and first steps..." shouldn't you start at the beginning and tell us where to get this app and how to install it?

You need to get the app from the Windows Store: https://www.microsoft.com/store/apps/9pgjgd53tn86.

No, there is no real technical reason for that, just another attempt of Microsoft to convert you to Windows 10 and make you use their Windows Store.

To make matters worse, you need to have installed the latest and greatest update of Windows 10 to do that. There is no technical reason for that, either.

After you've jumped through all those hoops, you get this nice and shiny Windows Store app. Windows Store apps get installed under "C:\Program Files\WindowsApps\" and this one is no different. At the moment of writing the application version was 1.0.16, so it got installed into "C:\Program Files\WindowsApps\Microsoft.WinDbg_1.0.16.0_x86__8wekyb3d8bbwe".

Reparse point

The installation creates another exe here: C:\Users\<user>\AppData\Local\Microsoft\WindowsApps\WinDbgX.exe. It is zero bytes, and if you try, for example, to copy it, you can’t.

Because it's a reparse point, not an EXE file.

Windows 10 processes bundled Windows Store application's AppxManifest.xml and creates appropriate appExecutionAlias'es:

Same thing goes for all other applications Vallejo "found" under C:\Users\<user>\AppData\Local\Microsoft\WindowsApps\, like dbgsrv64.exe:

You can read more about aliases on MSDN: Start your app by using an alias.

Fsutil

I have not found a tool or way to manage or get information about these files.

Ever tried fsutil? It's been part of Windows since Windows7.. bigsmile

Here's output of fsutil reparsepoint query WinDbgX.exe:

As you can see, it's a reparse point with a tag 0x8000001b (IO_REPARSE_TAG_APPEXECLINK).

Sure, you can Google for that - but it won't tell you much, except that it's not really documented and should be left alone.

Command-line

Old windbg.exe accepted parameters with “-“, for example -k. New Windbg needs /k parameter to pass the connection configuration

Bullshit! In fact, WinDbgX accepts any of 4 different delimiters: "-", "–", "—", "/" and combinations of those..

Ok, that was enough criticism for one day. Let's do something more constructive!

Running WinDbgX on Windows 7

Remember how I said that there is no technical reason why WinDbgX should be available only on Windows 10 and only as a store app? There really isn't. smile

Here's WinDbgX running on my Windows 7 and debugging one of the FLARE2017 crackmes:

It's actually a really simple fix.

  1. You need to copy all the files from your Windows 10 machine to your other machine (Windows 7 in my case). It's as simple as selecting all files in "C:\Program Files\WindowsApps\Microsoft.WinDbg_1.0.16.0_x86__8wekyb3d8bbwe" and copy-pasting them. Don't worry about the reparse points in C:\Users\<user>\AppData\Local\Microsoft\WindowsApps\, we'll fix that later.
  2. If you try to run DbgX.Shell.exe on Windows 7, it will fail with Exception:
  3. Let's look at that code in DbgX.dll using dnSpy:

    It's crashing on the Package.Current.Id.FamilyName, as this function is available only for Windows Store apps.

    As a simple hack, we can replace this call with an empty string. Better hack would be to use the proper folder based on the actual WinDbgX path. But the simple way will do for our demo..

  4. Using "Edit IL instructions" function in dnSpy, replace first 4 instructions with ldstr and nops:
  5. Save the module. If saving fails, remove read-only attribute from DbgX.dll and try again.
  6. Since we chose a simple hack, create folder C:\Users\<user>\AppData\Local\Microsoft\WindowsApps\
  7. Depending on your OS (32- or 64-bit), copy files from WinDbgX\X86 or WinDbgX\amd64 folder to C:\Users\<user>\AppData\Local\Microsoft\WindowsApps\. Rename dbgsrv.exe to dbgsrv32.exe or dbgsrv64.exe accordingly.
  8. Run the DbgX.Shell.exe shell now. It will work just fine!

There are 3 more places in DbgXUI.dll, DbgX.Util.dll and Extensions\DbgX.External.dll that might need similar fixes. But that's behind the scope of this article.

Conclusion

It is true that classic WinDbg looks really dated. So, I can totally understand why Microsoft would want to create a replacement with a better UI. However, WinDbgX falls short on everything - its installation via Windows Store is brain-dead stupid, its user interface is confusing (who would look at Model->Change Query to change debugger settings?!) and severely limited (no multiple Memory windows, seriously?). If it was a school project, it wouldn't get even a B-. But for some reason, Microsoft insists that this is the only way forward. Oh, well.. sad

At least, the DLLs are not obfuscated, so someone can take them and make a much better UI.. wink

Have fun!
kao.

04 Oct 2017

October update to Molebox unpacker

Thanks to my reader Max I have fixed another bug in the Molebox unpacker.

  • Removed memory leak that caused "out of memory" error when unpacking very large files (1.5GB+)

The usual request

I hope you find this unpacker useful. But if it doesn't work for you, please send me an error report with all the details you can and I'll try to fix it. Have fun!

22 Aug 2017

Yet another update to Molebox unpacker

Thanks to my readers I have fixed few more bugs in the Molebox unpacker.

  • Better support for non-ASCII symbols in filenames
  • Very large (4GB+) files will now unpack correctly
  • Unpacker will extract embedded files packed with old versions of Molebox (like version 2.0570)

The usual request

I hope you find this unpacker useful. But if it doesn't work for you, please send me an error report with all the details you can and I'll try to fix it. Have fun!

19 Aug 2017

Use of syscall and sysenter in VMProtect 3.1

Few days ago Xjun briefly mentioned a new feature of VMProtect 3.1 - it uses direct syscalls to check if software is running under debugger. I decided to take a quick look myself and figure out how exactly it works.

I'll give you 2 targets for the research:

  • oppo_flash_tool.exe (https://mega.nz/#!ZgJzjQxR!cNEHMwM-jKnLVgPXf4OUupyk1DNt69FYB2rEfY-5AlA) - it was given as an example by Xjun;
  • asshurt.dll (https://mediafire.com/?3xyc0ugc2hxervn) - some sort of a cheat for Roblox. I don't care about the cheat itself, it just happened to have the syscall feature enabled. And it uses different syscalls than Oppo.

In addition to that, I'll provide a very simple demo executable which replicates part of the VMProtect protection, so that you don't waste time looking at obfuscated code.

As a debugger in 32-bit OS you can use anything you like. On 64-bit OS you will really need to use WinDbg - as far as I know, it's the only debugger that can handle those tricks..

32bit OS

Let's start by debugging oppo_flash_tool.exe. First, we need to get past the usual tricks like IsDebuggerPresent and CheckRemoteDebuggerPresent. If you're reading this, I'm sure you know how to do that.

Few moments later we'll arrive here:

Remember this conditional jump. It's taken on 32bit OSes and not taken on 64-bit OS.

Let's look at 32bit OS version first. Now VMProtect prepares to call sysenter.

Since the code is obfuscated, here comes a cleaned-up version. Please note that in other applications, different registers can be used.

64-bit OS

Here it is getting interesting! smile You cannot use sysenter instruction from 32-bit code in 64-bit Windows. But, as ReWolf described few years ago, one can mix x86 code with x64 code in the same process. And that's exactly what VMProtect 3.1 is doing.

Let's go back to that conditional jump and see what happens in 64-bit OS. The jump will not be taken:

Far call?! Last time I saw that was in 16-bit Windows era..

As explained in ReWolf's article:

Summing things up, for every process (x86 & x64) running on 64-bits Windows there are allocated two code segments:

  • cs = 0x23 -> x86 mode
  • cs = 0x33 -> x64 mode

So, as soon as you execute that call, you'll switch to a 64-bit world. WinDbg happily recognizes that, all other debuggers just go astray..

x64 code does pretty much the same thing as x86 code - sets up a stack frame, sets up registers and then executes syscall instruction. Cleaned-up and shortened version follows:

You'll notice that x64 version is slightly more complex due to the way parameters are passed (registers vs. stack). It also includes a special treatment for 8 special edge cases - it will modify syscall parameters to adjust buffers and pointer sizes to satisfy requirements for 64-bit code.

NOTE - to keep code simple, I only showed the part which deals with NtQueryInformationProcess but other cases are similar.

As you can see, return back from x64 to the x86 world is a simple retf instruction. x86 code continues right where it left off:

Instruction at address 0x00ddaeba is the same for both x86 and x64 OS-es and VM continues as usual.

Different protection modes and syscalls

I provided you with 2 real-world test executables. Oppo seems to be simpler and use just 3 syscalls:

  • NtQueryInformationProcess with ProcessDebugObjectHandle class
  • NtSetInformationThread with ThreadHideFromDebugger class
  • NtProtectVirtualMemory to set protection attributes for each section in original executable

Asshurt doesn't have antidebug trick with NtQueryInformationProcess but it uses additional syscalls for some purposes:

  • NtOpenFile
  • NtCreateSection
  • NtMapViewOfSection
  • NtQueryVirtualMemory
  • NtUnmapViewOfSection
  • NtClose

Suggested workaround

Since VMProtect is using undocumented Windows features, it somehow needs to ensure that the protection will work on each and every Windows version. That's VMProtect's biggest strength and also the biggest weakness.

Windows' syscall numbers change in each version and also between major builds. Use the wrong syscall number and you're guaranteed to receive unexpected results. So, VMProtect developers had to hardcode a table with Windows build numbers and corresponding syscall id's in the executable.

You can see the syscall numbers in the j00ru's page (slightly out of date) or in tinysec's windows kernel syscall table

To obtain Windows build number, VMProtect uses information from PEB (Process Environment Block). The method is already described in The MASM Forum, so I'll just reproduce the (ugly) code from their page:

VMProtect checks only the build number and picks the corresponding syscall number. However, if the build number is not in the internal database, it will not use direct syscall and fall back to standard protection. Bingo, problem solved - no need for ugly hacks like Xjun's SharpOD plugin!

Hint: VMProtect 3.1 doesn't support Windows 10 Creators Update (build number 15063).

Demo time

As promised, here is a download link for the test application: https://mediafire.com/?niqqbs0fqcq8n23
Note: it should support most common builds of Windows XP/7/8.1/10. Windows 2003/Vista and other rare systems are not supported!

If it shows "OK" message, you've hidden your debugger well. If it shows "Debugger detected", you have a problem. smile

Have fun!
kao.

EDIT: Updated download link for Oppo. Mediafire's antivirus tends to have plenty of False Positives..

02 Jun 2017

Enigma’s EP_CryptDecryptBuffer internals

For one of my private projects, I needed to decrypt some data. Original executable uses Enigma's EP_CryptDecryptBuffer function but I needed to implement the same thing using .NET. Much to my surprise, there was no information about what encryption algorithm is used by Enigma or how it works internally. So, I started by compiling Enigma's sample project CryptBuffer and debugging the executable.

TL;DR - IDEA cipher in CBC mode, password = MD5(user_password), IV for CBC comes from IDEA.Encrypt(8-zeroes, password).

Research

After protecting my executable with Enigma, few assembly lines

got changed into something horrible that looked like an Enigma's VM:

I didn't feel like spending my time on analyzing that. Much easier solution was to put hardware breakpoints on my data and password and wait for them to trigger. In a few seconds I landed into code that looked like MD5 (notice the constants!):

and few hits later I landed into code that I didn't recognize at first:

Delphi compiler had helpfully included RTTI information telling me that this second piece of code belongs to a class called TIdeaCipher. Now I had all the information I needed, I just had to put it all together. smile

Implementing decryption in C#

There aren't many IDEA implementations in C#. In fact, there are 2: by BouncyCastle and by LexBritvin. Since I'm not a big fan of huge and complex libraries like BouncyCastle, so I took the simplest possible code: from Github and modified it a bit.

First, we need change password generation algorithm to use MD5 to generate real password:

Second, we need to add support for CBC mode. It requires both calculating correct IV value and pre/post-processing each block we're encrypting or decrypting.

Calculating IV is quite simple:

Processing each block is slightly harder but not a rocket science either. As explained in image borrowed from Wikipedia:
.

Before decrypting the data block, we need to store the encrypted values as IV for the next block. After decrypting the block, we need to XOR each byte of data with a corresponding byte of IV. Unfortunately, during encryption the data flow is different, so the simple crypt function has to be replaced with 2 functions: encrypt and decrypt.

Few more cosmetic changes and that's it! We got clean and nice implementation of EP_CryptDecryptBuffer in pure C#. smile
Download link: https://bitbucket.org/kao/ep_cryptdecryptbuffer/

Have fun!

P.S. My implementation only supports cases where data length is divisible by 8, adding support for other lengths is left as an exercise for the reader.