Background Image
Table of Contents Table of Contents
Previous Page  11 / 20 Next Page
Basic version Information
Show Menu
Previous Page 11 / 20 Next Page
Page Background

CodeBreakers Magazine – Vol. 1, No. 2, 2006

gev.tls_original.StartAddressOfRawData, size );

memset ( (void*) gev.tls_original.EndAddressOfRawData,

0,

gev.tls_original.SizeOfZeroFill );

}

safe_to_callback_tls = true;

if ( delayed_tls_callback ) {

TLSCallbackThunk ( TLS_dll_handle TLS_reason

TLS_reserved );

}

}

Once you have done that, it is finally safe to call over to

the original program. You should have a published

external global that will be set up by the packing

application that specifies the original program's entry

point. I will call it

DWORD orig_entry;

which will be a member of GlobalExternVars. It will be

initialized to an RVA and we will fix it up to a VA by

adding the load_address. This done only once on the first

pass, of course.

For EXEs, the entry point will never return. For DLLs it

will. Moreover for DLLs there are the original

parameters which must be pushed. This brings us to the

final topic, the last bit needed for DLL support.

18 Last Bit for DLL Support

EXEs go into their entry point only once, and with no

parameters (remember, this is not main(), but well before

that). DLLs, on the other hand enter at least twice and

perhaps once per thread. Obviously, the stuff we did

before (the decompression, relocs, imports, TLS) only

needs to be done once. Easy enough, add a global boolean

that indicates that stuff was done and set it to true after

the first pass.

The slightly more tedious thing is producing a stub that

works for DLLs and exes, since you will want to return

the value.

What I like to do is make use of the declspec ( naked )

attibute I applied to the StubEntryPoint. This causes the

compiler to emit no prolog and epilog code. Consequently,

if we don't mess with the stack, we can do and assembly

jmp to the original entry point, and the right behaviour

will happen if we are an EXE or a DLL. Thusly:

asm jmp gevt.orig_entry;

And all should be running.

19 Afterthoughts on Stubs

Looking at other packers, I have seen some slightly

different stub techniques. I think the most interesting is

UPX, where the packer actually acts somewhat like a

linker, building the stub code dynamically and including

only what is necessary at pack time.

You can implement the stub in the fashion of your

choosing, and you can omit features you don't think will

be necessary in your particular application.

20 What's Next

OK, this was a good bit longer than I expected. Still, I

wanted to communicate as much as possible the details

so that others won't have had to spend as much time in

the debugger as I had. Debugging a compressed exe is a

major pain because the debugging info is all useless so

you have to do it in assembly.

Next installment will cover the packer application, which

will be much more straightforward from the standpoint

of configuration, but will have much more work to do

than the stub.

21 Continuo

This series is about creating exe packers for Windows 32­

bit PE files.

In the previous installment I described how to create a

decompression stub that would be bound to an existing

executable. In this (final?) installment I'm going to

describe the actual packer application, which binds the

stub to an arbitrary executable and sets up parameters

the stub will need at runtime. Additionally, it will

perform some duties normally done by the OS loader.

The packer application will wind up being the biggest

hunk of code for the project. Fortunately, it will be fairly

straightforward.

22 First Things

There are some basic things to setup or consider before

we get moving with the actual packer.

22.1 Project Configuration

As mentioned in the previous installment, configuration

is a function of your particular design. For the sake of

discussion in this article we are assuming a design where

the decompression stub is produced as a dll. The binary

of that dll will be incorporated into the packer

application as a binary resource. None of this is strictly

necessary. The stub 'dll' will never exist in the real world

© CodeBreakers Journal,

http://www.CodeBreakersJournal.com