Extending De4dot

17 Jul 2015

Hey, what’s up everybody?

About two months ago I came across a modified version of de4dot someone made, which required me to replace my current de4dot version in it’s entirety. I did not like this and therefore I decided to work on extension support for de4dot. Basically it allows you to add new deobfuscator modules or replace the existing (sometimes outdated) ones, in a dynamic way.

In this blogpost I will explain to you how to add a simple deobfuscator for OrangeHeap. The actual deobfuscator code is not written by me, but by TheProxy. It only serves as an example of how de4dot can be extended :)

Getting started

To get started, we need to set up our development environment. For this you need Git and Visual Studio. Follow these steps to get a development environment running:

  1. Clone the repository with git clone --recursive https://github.com/0xd4d/de4dot.git;
  2. Copy and rename the deobfuscator.Template directory to deobfuscator.OrangeHeap;
  3. In that same directory, rename deobfuscator.Template.csproj to deobfuscator.OrangeHeap.csproj;
  4. Open the main de4dot.sln in Visual Studio 2010 or higher and add deobfuscator.OrangeHeap.csproj to the solution;
  5. Now the only thing left is to rename the output file name and namespace from deobfuscator.Template to deobfuscator.OrangeHeap.

Coding the deobfuscator

In this post I won’t go too much in depth about the internal de4dot architecture, mainly because I don’t know a whole lot about it. You’d have to check the built-in deobfuscators by yourself to find out how it works. Here is a post by kao that explains extending de4dot in a more detailed manner.

The identifying class for a deobfuscator is the DeobfuscatorInfo class. It has to provide a Name and a Type string field, where the Type field must be unique. It also has a CreateDeobfuscator method that will handle the actual deobfuscation.

You can find the full code over here. TheProxy wrote a full tutorial with details over at his blog

Sharing the deobfuscator

Now before I go into this, I have to say that you are obligated by the license de4dot uses (GPL) to share any modifications you make to de4dot under the same (GPL) license. This includes extensions that are dynamically loaded by de4dot, although this is controversial.

Now to share the deobfuscator, for example for internal company usage or simply because you want to share prebuilt binaries of your GPL extension, simply copy the bin/deobfuscator.OrangeHeap.dll to the de4dot bin directory on another machine. Here is a screenshot that shows what happens before and after I added the DLL to the bin directory (obviously without any other modifications to de4dot):

extensibility!

Overriding/Extending existing deobfuscators

If you want to change the behavior of an existing deobfuscator, simply make the DeobfuscatorInfo.Type field return an already-present typename (like co for CryptoDeobfuscator or df for Dotfuscator). Basically you have to rip the current deobfuscator class out in a separate project (I tested this). See here for a starting point. It should be pretty straightforward.

Well, that’s all for today. Hopefully till next time!

mrexodia

Leave a comment

Script Api

01 Jul 2015

Hey everyone,

For the people who keep checking this blog: thanks a lot!

Recently I had quite a lot of deadlines, so as usual I didn’t write anything on my blog :) I did however work on quite some interesting things. Together with the guys on #x64dbg and some other people I worked on a script API for x64dbg. What this means is that (once this API is finished) people can write bindings for their favorite script language and publish it as a plugin!

Right now I have these implemented:

  • Basic debugging stuff (run, step, stop, pause);
  • Register setters/getters;
  • Memory read/write;
  • Pattern finding/writing;
  • Module information;
  • GUI selection setters/getters.

I plan on adding much more:

  • PE information;
  • Breakpoint management;
  • Comment/Bookmark/Label/Function/Loop management (useful for analysis scripts);
  • Settings;
  • Event callbacks;
  • Etc (contact me if you have requests).

Some work was done with AngelScript in the testplugin.

void myStepOut()
{
    duint cip = Register::GetCIP();
    Print("[SCRIPT] Started on CIP = 0x%p\n", cip);
    do
    {
        Debug::StepOver();
        cip = Register::GetCIP();
    }
    while(Memory::ReadByte(cip) != 0xC3);
    Print("[SCRIPT] Finished on CIP = 0x%p\n", cip);
}

void main()
{
    Print("[SCRIPT] Welcome to AngelScript!\n");
    myStepOut();
}

Another idea I had was to load script DLLS, so you can write scripts in your favorite programming language (basically any language that supports native exports). You would write a single export StartScript that then calls the script API directly. This would allow for many possibilities, including commercial unpacking scripts.

This summer I will try to work on x64dbg as much as I can, to at least complete the script API. I also plan on fixing performance problems and solving as many issues as I can. Contact me if you know C++ and like to work on x64dbg. All help is appreciated.

Till next time,

mrexodia

Leave a comment

Function Analysis

11 May 2015

Hey everyone!

Right now I am in the fourth and final term of this education year. It looks like I can go on studying computer science, since I passed all my exams as of now!

Introduction

In this post I will discuss a (fairly simple) algorithm I came up with half-drunk with the purpose of determining function boundaries in x86 assembly code. Right now, it is implemented in x64dbg and you can see how it works with a command called anal (short for analyze). It does not work on weird/obfuscated/Microsoft’s code, but it’s nice to have an idea where functions start and end without having to manually go through every function you are looking at.

Screenshot:

x64dbg function

The requirements

Maybe you already noticed, but x64dbg does barely use the information provided in the PE Header of a debuggee for its operations. If your executable is malformed, but can be started by CreateProcess without problems x64dbg should be able to debug it.

The downside is that x64dbg has no idea if it is looking at code, an import table, a resource table or just random data. You would have to figure that out yourself. The upside is that anything that can be run by Windows can at least be started by x64dbg.

The algorithm has a very simple input: a block of memory. The output should be a list of function boundaries. It requires nothing to work, except the virtual base address of the memory block.

The idea

After talking with various people (including cyberbob who created ArkDasm) the thing a lot of people (including our ‘competition’ at HexRays) appear to do is some kind of recursive ‘tracing’ from a certain point (usually the entry point). Basically it simulates multiple possible execution paths from that point and constructs the function boundaries from data (such as call and ret instructions) it collected on the way.

Usually I like what the cool kids on the block do, but I saw some problems:

  1. Recursive algorithms require housekeeping. In this case you would need to make sure data is not analyzed more than once (in case of analyzing a recursive function).
  2. It is hard to estimate when the recursive algorithm would end. Maybe there is only one (very small) execution path and it ends immediately, or it keeps dragging on, evaluating thousands of possible paths.
  3. There is no known entry point.

Now computer scientists appear to like complexity analysis of an algorithm. Probably you cannot do better than linear anyway, so I decided that I wanted to algorithm to be done in linear time O(n).

The idea I had was very simple, but it requires two assumptions to work:

  1. Every call destination or immediate pointing inside the memory block given for analysis is assumed to be the start of a function;
  2. A function ends at or after the start of that function and cannot overlap with other functions.

The first assumption should be clear to you. The second assumption might not be, but it is actually very simple: when a function starts it has to end before another function starts. This means that this system will horribly break on optimized code that places chunks of code randomly scattered throughout the memory region. Microsoft’s kernel32.dll does this for example.

Now the actual idea is to do things in two steps:

  1. Find all function starts;
  2. Figure out where functions end.

Simple right?

Finding all function starts

Doing this is actually trivial with the given assumptions! Just find any immediate that points in the memory block currently being analyzed and then sort the results and remove duplicates (a function might be called from multiple places is why). The reason for the sorting that the end cannot be further away than the next function start.

Finding the end of a function #1

The thing that immediately comes to mind is just searching for the first ret instruction after the function start and call this the function end.

The problem with this approach is that there might be multiple exit points:

multiple exit points

Finding the end of a function #2

Another thing that comes in mind really quickly is just to scan backwards from a function start for the ret instruction. When found, this is the end of the previous function:

scan backwards

The main problem with this is that there could be unreferenced functions between the two functions that were found using the method for finding function starts. This could make really weird functions appear:

wrong functions

Finding the end of a function #3

The actual method I used to find the end of a function is a variation of #1. This algorithms has four cursors (the names are taken from the actual algorithm):

  1. addr is the current address being disassembled. addr will always move forward disassembling every instruction on the way;
  2. end is the current function end (basically this is the last ret instruction encountered by addr);
  3. fardest is the farthest forward destination of a jxx. This will point to the farthest destination the function can go by using jumps;
  4. jumpback is the address of the last jmp instruction that jumps before the end at that time.

For the understanding of the algorithm I visualized it using x64dbg. These are the colors used to indicate the various variables:

  • addr
  • end
  • fardest
  • jumpback

The first animation shows how fardest is used. When a ret instruction is encountered it is considered to be the function end if fardest has no value or points before the current ret instruction. When fardest points after the ret instruction, the algorithm will continue instead looking for another ret:

algorithm animation 1

The second animation shows how the jumpback variable is used. Basically what could happen is that there is some kind of repeated structure before a function returns and that the compiler optimized this by jumping back to this structure from the end of the function (this could be done to save space for example). When the limit to where the algorithm can disassemble is reached the jumpback will be used as end of the function instead of end:

algorithm animation 2

Final words

Alright, that was about it! I plan on improving this algorithm to support weird function structures done by some compilers, but the idea will stay the same (I think). I hope you enjoyed reading through this, I definitely enjoyed making it (even fixed some bugs on the way).

Greetings,

mrexodia

Leave a comment

Progress

18 Apr 2015

Hey guys,

After (again) almost a month of not writing I decided to write a little about various things I’m doing currently.

GleeBug

As some of you might have picked up I’m working on a replacement for TitanEngine. This replacement is going to be called GleeBug. Currently the project is in early stages, but with some help from nice people in my live stream we got single stepping with callbacks working very well!

GleeBug is going to have full support for child process debugging and it will be written in an object oriented style. (name) is working with me. You can find the repository here.

x64dbg

After I started a bachelor in computer science, other projects started degrading because of the lack of motivation and time I had. Recently I did a weekend of live streaming and it motivated me greatly! If I have some time between the assignments I have to do and playing GTA 5 (amazing game by the way) I will do another streaming session this weekend. Otherwise Monday (which is when I have to hand in the assignments).

A lot has happened to x64dbg since the last time I wrote, here is a quick summary for the people not following the commit logs:

  • YARA rules matching was added;
  • A new version was released;
  • x64_dbg is renamed to x64dbg;
  • We moved to GitHub;
  • You can now donate with PayPal (or Bitcoin);
  • Nukem did a great deal of refactoring with the result that x64dbg is now on VS2013. XP will stay supported, but backwards compatibility is still a WIP so the current snapshots will not run on XP (move on already guys);
  • Various bugs were fixed (some fixed as a result of the refactoring), see the commit logs on the repository for more information.

Well, that’s about it! Thanks for reading and leave me a comment on my twitter or in the comment section.

mrexodia

Leave a comment

Look Out!

21 Mar 2015

Hey,

At the moment I feel like I should say I plan on posting something like every month from now on.

This is just a small post warning you guys for some very annoying behavior in DeviceIoControl. After a quick read of the documentation I did code like this:

static bool ControlDevice(HIDECOMMAND Command, HIDEINFO* HideInfo)
{
    HANDLE hDevice = GetDeviceHandle();
    if (hDevice == INVALID_HANDLE_VALUE)
	    return false;
    bool result = !!DeviceIoControl(hDevice, //hDevice
                                    Command, //dwIoControlCode
                                    HideInfo, //lpInBuffer
                                    sizeof(HIDEINFO), //nInBufferSize
                                    NULL, //lpOutBuffer
                                    0, //nOutBufferSize
                                    NULL, //lpBytesReturned
                                    NULL //lpOverlapped
                                   ); //
    CloseHandle(hDevice);
    return result;
}

Reading the documentation in a quick glance it looked like lpBytesReturned and lpOverlapped are optional (it says so in the function definition).

I tested the code on Windows 8.1 and everything worked fine, so I published the code. After a while however, my client told me there was a crash on Windows 7 near DeviceIoControl.

Reading the documentation again I stumbled across this sentence:

If lpOverlapped is NULL, lpBytesReturned cannot be NULL. Even when an operation returns no output data and lpOutBuffer is NULL, DeviceIoControl makes use of lpBytesReturned. After such an operation, the value of lpBytesReturned is meaningless.

Moral of the story: don’t assume optional actually means a parameter is optional in WinAPI documentation :)

Cya around,

mrexodia

Leave a comment