Search This Blog

Showing posts with label protectors. Show all posts
Showing posts with label protectors. Show all posts

Saturday, May 19, 2012

Simple Runtime Framework by Example

Source code for this article may be found here.

These days we are simply surrounded by different software frameworks. Just to name a few: Java, .Net and, actually, many more. Have you ever wondered how those work or have you ever wanted or needed to implement one? In this article, I will cover a simple or even trivial runtime framework.

As usual - note for nerds:
The source code given in this article is for example purposes only. I know that this framework is far from being perfect, therefore, this article is not a howto or tutorial - just an explanation of principle. Error checks are omitted on purpose. You want to implement a real framework - do it yourself, including error checks.

Now, to let's get to business.

Software Framework
Wikipedia gives the following identification for the term "Software Framework" - "A software framework is a universal, reusable software platform used to develop applications, products and solutions. Software Frameworks include support programs, compilers, code libraries, an application programming interface (API) and tool sets that bring together all the different components to enable development of a project or solution". As you can see, software framework is quite a complex thing. However, let's simplify it and see how it basically work.

Figure 1.
Software Framework
The diagram on the left may give you a good understanding of what Software Framework is and what role it performs. Simply saying, it is a shim between the user application and the Operating System. There are at least two types of Software Frameworks:

  1. Application Programming Interface (API) - if we take a look at Windows API, we may see that it is a framework as well. However, it may be bypassed or, at least, a programmer may choose to decrease the interaction with it by, for example, using functions from ntdll.dll instead of those provided by kernel32.dll or even "talk" to Windows kernel directly (highly not recommended, but may be unavoidable some times) through interrupts.
  2. .Net like framework - total isolation of user code from the operating system. Such frameworks are mostly virtual machines totally isolating user application from the operating system and hardware. However, such framework has to provide the application with all the services available in the Operating System. This is type of framework we are going to build in this article.




Virtual Machine
The basics of building a simple virtual machine is covered in this article, so I will only give a brief explanation here. Our VM in this example will consist of the following components:
  1. Virtual CPU
    A structure that represents a CPU - basically, has 6 registers and a pointer to the stack:

    typedef struct
    {
       unsigned int  regs[6];
       unsigned int* stack;
    }CPU;

    The 6 registers are general purpose
    A, B, C and D, where A is also used to store system call return value and C is used as a counter for LOOP instruction, STACK POINTER (SP) and INSTRUCTION POINTER (IP).
  2. Instruction Interpreter
    A function or a set of functions which responsible for interpretation of the pseudo assembly (or call it intermediate assembly language) designed for this virtual machine (in this case 14 instructions).
  3. System Call Handler
    This component provides the means for the user application to interact with the Operating System (in this case 2 system calls:
    sys_write and sys_exit).

Core Function
The name of the function speaks for itself. This is the first function of the framework implementation which gains control. In this particular case, it does not have too many things to do - initialization of the virtual CPU and execution of the command interpreter, until the user application exits (signals the framework to terminate the execution).

Implementation
It is a common practice to implement a framework as a DLL (dynamic link library), for example, mscoree.dll - the core of the .Net framework. I do not see any reason to reinvent the wheel, therefore, this framework will be implemented as a DLL as well.

All is fine, you may say, but how should we pass the compiled pseudo assembly code to the framework? Well, I bet, most of you know how to do that. In case you don't - no worries, just keep reading.

In case of .Net framework (at least as far as I know), the loader identifies a file as a .Net executable, reads in the meta header, and initializes the mscoree.dll appropriately. We will not go through all those complications and will use a regular PE file:


Figure 2.
Customized PE file.

  • PE Header - regular PE Header, no modification needed;
  • Code Section - simply invokes the core function of the framework:

    push pseudo_code_base_address
    call [core]
  • Import Section - regular import section that only imports one function from the framework.dll - framework.core(unsigned int);
  • Data Section - this section contains the actual compiled pseudo assembly code and whatever headers you may come up with, that may instruct the core() function to correctly initialize the application.






Example Executable Source Code
The following is the source code of the example executable. It may be compiled with FASM (Flat Assembler).

include 'win32a.asm' ;we need the 'import' macro
include 'asm.asm'    ;pseudo assembly commands and constants

format PE console
entry start

section '.text' readable executable
start:
   push _base
   call [core_func]

section '.idata' data import writeable
library  framework, 'framework.dll'

import framework,\
   core_func, 'Core'

section '.data' readable writeable
_base:
   loadi A, _base
   loadi B, 0x31
   _add A, B
   loadr B, A
   loadi A, _data.string
   loadi C, _data.string_len
   _call _func
   loadi A, 1
   loadi B, _data.string
   loadi C, _data.str_len
   _int sys_write
   loadi A, 1
   loadi B, _data.msg
   loadi C, _data.msg_len
   _int sys_write
   _int sys_exit


_func:
   ; A = string address
   ; B = key
   ; C = counter
.decode:
   loadr D, A
   xorr D, B
   storr A, D
   loadi D, 4
   _add A, D
   _loop .decode
   _ret



_data:
.string db 'Hello, developer!', 10, 13
.str_len = $-.string
db 0
.string_len = ($-.string)/4
.msg db 'The program will now exit.', 10, 13
.msg_len = $-.msg

;Encrypt one string
load k dword from _base + 0x31
repeat 5
load a dword from _data.string + (% - 1) * 4
a = a xor k
store dword a at _data.string + (% - 1) * 4
end repeat



The code above produces a tiny executable which invokes framework's core() function. Pseudo assembly code simply prints two messages (the first one is decoded prior to being printed). Full sources are attached to this article (see the very first line).

The good thing is that you do not have to start the interpreter and load this executable (or specify it as a command line parameter) - you may simply run this executable, Windows loader will bind it with the framework.dll automatically. The bad thing is that you would, most probably, have to write your own compiler, because writing assembly is fun, dealing with pseudo assembly is fun as well, BUT, only when done for fun. It is not as pleasant when dealing with production code.


Possible uses
Unless you are trying to create a framework that would overcome existing software frameworks, you may use such approach to increase the protection of your applications by, for example, virtualizing cryptography algorithms or any other part of your program which is not essential by means of execution speed, but represents a sensitive intellectual property.

Hope you find this article helpful.

See you at the next!




Friday, March 2, 2012

Defeating Packers for Static Analysis of Malicious Code

I doubt whether there is anybody in either AV industry or among reverse engineers who does not know what a software packer is (for those who don't - this article may help). Malware research and reverse engineering forums are full of packers' related questions, descriptions thereof, unpacking suggestions and links to both packers and unpackers. In short - people have been doing a lot of precious work on defeating packers and protectors.

However, for those of us who are not afraid of static analysis, there is an easier way (I'd dare to say "generic") to handle packers and protectors and retrieve the unpacked form of the executable (cannot hold my self from adding a note for nerds: no, this does not include reversing virtual machines like Oreans' one. This is up to you). So, the main problem is obtaining the unpacked version of code as all the rest may be well handled from there. What we actually need is a dump of unpacked executable. There are lots of memory dumping programs, but some protectors "know" how to handle them, therefore, this article explains a simple and short way of obtaining such dump without teasing the implemented protections.

Knock Knock
First of all, we need to, let's say, get into the process. There are at least two ways to do that:

  • Use the OpenProcess Windows API with, preferably, PROCESS_ALL_ACCESS and read/write from/to process' memory.
  • Inject our code into the process' memory space (simply a code injection or a DLL injection).
My preference is the second one as you mostly have more power operating from inside.

There are several ways to inject a DLL into another process, e.g. calling LoadLibraryA as a remote thread in the victim process or even this one (my preference is the second one again). This is in deed the easiest part. My personal suggestion would be to create a suspended process, inject your DLL and then resume the main thread of the created process as this provides you with greater flexibility.

Set the Trap
No, I am not referring to 0xCC (trap to debugger). Trap, in this case, means something that would trigger the dumper embedded into the injected DLL and cause it to dump the unpacked image, for example, patch one of the API functions with a jmp instruction, which would redirect the execution flow to where we want. Be careful with this approach, as your patch may be well "overpatched" by the protection mechanism of the target executable. Let me give you a couple of suggestions: never patch the first bytes of the API (I assume this code is not a production code, so you may let it be bound to your version of Windows); patch as deep as possible - meaning leave the kernel32.dll alone and go further to ntdll.dll where possible. 

For example, if your target executable outputs a string to a console, that may be a good idea to patch either WriteConsoleA or WriteConsoleW API  function. However, it may be an even better idea to go deeper and patch WriteConsoleInternal (Win7) and install your notification jump there. Once that API is called - chances are that the executable has been fully unpacked. As an alternative, you may simply create a new thread in your DLL and Sleep it for several milliseconds (or even seconds) and then dump the memory.

You may perform these actions in the DllMain of your injected DLL, on the other hand, you may create a separate procedure for this, but then you'd have to use this approach or something similar.

Dumper Triggered
No matter how (either by the API patch or our thread) the dumper is triggered. Sure thing - we are not going to dump the whole memory allocated by the process. We just need the image. The easiest way of getting the information on ImageBase and SizeOfImage of the target module (usually the main module of the process) is to find the corresponding entry in PEB (you may want to check the "Hiding Injected DLL in Windows" post to get more information on PEB and related structures). However, it is important to mention that you HAVE to be careful with that, as the information in PEB may be altered by the protection scheme of the victim executable. Having found the base address and the size of the image, just write the content of that memory region to a file (make sure to take note of image's base address if you are dumping DLL). Quite simple, isn't it? Well, not really. You have to check for memory protection of every region you are currently going to dump as it may have either PAGE_WRITE or PAGE_EXECUTE access rights only, meaning that you cannot access it for reading. Once done with this, you may either let the program execution to continue or terminate the process.

In addition, it is strongly recommended to suspend all the threads of the process, except the thread our code is running in.

Using Dump
Nothing's easier - load the dump into IDA Pro and see how good it handles it.

P.S. Suspending/Resuming Threads
Suspending threads is a bit annoying as you have to get the IDs of all the threads currently running in the system, then select those with process ID of your process and suspend then. The same procedure is applicable for resuming suspended threads.

First of all CreateToolhelp32Snapshot (MSDN):

HANDLE WINAPI CreateToolhelp32Snapshot(
              DWORD wdFlags,
              DWORD th32ProcessID
       );

You have to specify TH32_SNAPTHREAD as flags in order to get threads information. If the return value is not NULL, the you may proceed with Thread32First:

BOOL WINAPI Thread32First(
            HANDLE          hSnapshot,
            LPTHREADENTRY32 lpte
            );

followed by subsequent calls to Thread32Next (has the same arguments) until the return value is FALSE.

The functions Thread32First and Thread32Next fill the THREADENTRY32 structure which has the following format:

typedef struct tagTHREADENTRY32
{
   DWORD dwSize; /* Should be set to sizeof(THREADENTRY32) prior 
                    to calling Thread32First */
   DWORD cntUsage;
   DWORD th32ThreadID;
   DWORD th32OwnerProcessID;
   LONG  tpBasePri;
   LONG  tpDeltaPri;
   DWORD dwFlags;
} THREADENTRY32, *PTHREADENTRY32;

Fields of interest for you would be the th32OwnerProcessID and the th32ThreadID. Compare the th32OwnerProcessID with the ID of the process (previously obtained with GetCurrentProcessId()) your code is running in. If those values are equal, then you have to open the thread with:

HANDLE WINAPI OpenThread(
              DWORD dwDesiredAccess, /* Would be THREAD_ALL_ACCESS */
              BOOL  bInheritHandle, /* FALSE */
              DWORD dwThreadId      /* th32ThreadID */
              );

Then suspend the thread with:

DWORD WINAPI SuspendThread( HANDLE hThread );

while passing the handle obtained with OpenThread().
You have to resume threads once you have saved the dump by calling:

DWORD WINAPI ResumeThread( HANDLE hThread );

Don't forget to close each thread handle with CloseHandle.


That's it. Hope this post was helpful (at least I used this method a lot).
See you at the next.