2002-09-06 13:40:43 +00:00
|
|
|
This documentation is written for those brave souls who want to
|
2000-05-19 16:04:55 +00:00
|
|
|
understand and/or modify the UPX assembly stubs - the small snippets
|
|
|
|
that do the runtime decompression when a compressed program is started.
|
|
|
|
|
2006-07-03 15:13:53 +02:00
|
|
|
If you look at the C++ source files, you can find code fragments like
|
|
|
|
this:
|
2000-05-19 16:04:55 +00:00
|
|
|
|
|
|
|
addLoader("PEMAIN20",
|
|
|
|
ih.entry ? "PEDOJUMP" : "PERETURN",
|
|
|
|
"IDENTSTR""UPX1HEAD",
|
|
|
|
NULL
|
|
|
|
);
|
|
|
|
|
2006-07-03 15:13:53 +02:00
|
|
|
linker->defineSymbol("original_entry", ih.entry);
|
2000-05-19 16:04:55 +00:00
|
|
|
|
2006-07-03 15:13:53 +02:00
|
|
|
and in the assembly files fragments like this:
|
2000-05-19 16:04:55 +00:00
|
|
|
|
2006-07-03 15:13:53 +02:00
|
|
|
section PEISDLL1
|
|
|
|
cmpb [esp + 8], 1
|
|
|
|
jnz reloc_end_jmp
|
2000-05-19 16:04:55 +00:00
|
|
|
|
2006-07-03 15:13:53 +02:00
|
|
|
section PEMAIN21
|
|
|
|
reloc_end_jmp:
|
2000-05-19 16:04:55 +00:00
|
|
|
|
2006-07-03 15:13:53 +02:00
|
|
|
section PERETURN
|
|
|
|
xor eax, eax
|
|
|
|
inc eax
|
|
|
|
ret 0x0C
|
|
|
|
section PEDOJUMP
|
|
|
|
jmp original_entry
|
2000-05-19 16:04:55 +00:00
|
|
|
|
2006-07-03 15:13:53 +02:00
|
|
|
Everything works as you would expect. If you want to add the code
|
|
|
|
fragment which is in `section PERETURN' to the runtime stub, then
|
|
|
|
simply use `addLoader("PERETURN")' in the C++ source.
|
2000-05-19 16:04:55 +00:00
|
|
|
|
|
|
|
That's nice, you could say, but how cross section jumps and calls are
|
|
|
|
handled? Well, that is the nicest part of this stuff - they are handled
|
|
|
|
automatically. All you have to do is to add the required sections to the
|
|
|
|
loader using `addLoader()' and the rest is done by upx. It will resolve
|
2006-07-03 15:13:53 +02:00
|
|
|
every conditional or unconditional jumps or subroutine calls for you.
|
2000-05-19 16:04:55 +00:00
|
|
|
|
2006-07-03 15:13:53 +02:00
|
|
|
You can also use (undefined) symbols in the assembly for values that
|
|
|
|
can only be computed during compression time (like `original_entry').
|
|
|
|
These symbols can be defined later in C++ using
|
2000-05-19 16:04:55 +00:00
|
|
|
|
2006-07-03 15:13:53 +02:00
|
|
|
linker->defineSymbol("xx", yy)
|
2000-05-19 16:04:55 +00:00
|
|
|
|
2007-03-04 17:39:21 +01:00
|
|
|
This functionality (we could say it's a simple linker) is achieved by
|
2006-07-03 15:13:53 +02:00
|
|
|
compiling the assembly into an ELF object file which a little C++
|
|
|
|
module (src/linker.cpp) can interpret and work with.
|