Here will be described some rare method of executable files infection. It is based on parsing trojan code into instructions, and injecting these instructions into free areas (alignment) between subroutines of the target file. This idea is not new, and probably has always been used in some viruses. Also, under executable files i'll mean executable ELF files for x86 platform, though it can be win32 PE files too.
Implementation depends on bytes filling the alignment areas. Size of these free areas depends on compiler options, and even in a single executable we can find blocks having different procedure alignment, since code is linked from different separately compiled object files. Mostly used C compiler alignment sizes are 4 and 16 bytes, which can give us 0..3 and 0..15 free bytes at the end of the each subroutine. We rely on second variant. Alignment bytes can be all equal to the same value, such as 0x90 (bcc) or 0xCC (msvc), or have different values, forming one or more instructions of summary size exactly equal to the alignment size (gcc).
In 1st case, it is easy to find alignment areas using the following algorithm:
xxxxxxx: C3 retn ; end of subroutine xxxxxxx: 90 nop ; \ alignment: 1..15 bytes xxxxxxx: 90 nop ; / xxxxxx0: 55 push ebp ; begin of next subroutine xxxxxx1: 8B EC mov ebp, esp ; note: 8B EC or 89 E5 here
In 2nd case, when alignment is formed of one or more instructions, we should search for more signatures. However, number of these signatures is finite, since usual compilers doesnt generate random or polymorphic code, yet. ;-)
length: sample alignment bytes (gcc): 6 8D B6 00 00 00 00 7 8D B4 26 00 00 00 00 8 90 8D B4 26 00 00 00 00 9 89 F6 8D BC 27 00 00 00 00 10 8D 76 00 8D BC 27 00 00 00 00 11 8D 74 26 00 8D BC 27 00 00 00 00 12 8D B6 00 00 00 00 8D BF 00 00 00 00 13 8D B6 00 00 00 00 8D BC 27 00 00 00 00 14 8D B4 26 00 00 00 00 8D BC 27 00 00 00 00 15 EB 0D 90 90 90 90 90 90 90 90 90 90 90 90 90
As such, to find free alignment areas within code section(s) of some executable file, we only need to search for some predefined signatures. This is easy, but not very reliable, and it will not find all possible alignment areas. In the related INFELF tool we will use another algorithm.
Now, lets talk about how to insert single code snippet into multiple small free areas of some executable file. This can be done by parsing code snippet into instructions, and inserting these instructions into suitable free areas of the executable file. Sure, each "injected" instruction must be followed by a JMP to the next injected instruction, unless it is JMP or RET. Also, if instruction has relative argument (such as in JMP, CALL, JXX & etc.), this argument must be correctly modified, to point to the new target location. If instructions is in short form (JMP SHORT, JXX SHORT) it should be expanded to become near, since in most cases new distance between caller and target becomes greater than 128 bytes. If instruction is LOOP/LOOPZ/LOOPNZ/JECXZ (E0..E3), it should be replaced with equivalent code, containing near JXX. Also, there appears some requirements to our snippet's code:
Since parsing code snippet into instructions requires length-disassembler, we can try to use this disassembler in other tasks, such as finding alignment areas within target executable file. As such, finding free areas will consist of (1) parsing executable file into instructions and (2) analyzing these instructions.
(1) Algorithm of parsing executable file into instructions:
(2) Algorithm of finding free areas within parsed executable file:
INFELF tool is designed to inject code snippets into executable ELF files. It parses both file and snippet into instructions, injects each snippet's instruction into suitable alignment area within target file, and links all these injected instructions with each other using JMP NEAR.
While parsing ELF file into instructions, the following methods of finding function offsets are used:
Injection offset (i.e. offset of instruction at which to dispatch control) can be defined using these options:
For example, to inject some code snippet into grep starting at function main(), do the following:
./infelf /bin/grep -out newgrep -snippet snippet.bin -func main
Code snippets for INFELF tool has two special signatures inside, used in infection process.
Signature db '$ORIGINAL_BYTES$' (length=16) is required, and used to store original bytes from executable file. This is because INFELF inserts JMP NEAR at hook offset, and original instruction(s) must be placed somewhere. Minimal amount of bytes used is 5, but it can be more, since there is no guarantee that instruction(s) at hook offset will be of exactly same size as JMP NEAR. Copied bytes are padded with NOPs. Delta between original instructions length and 5 is padded with NOPs too.
Signature MOV ESP, 0AA55AA55h (length=5) is optional, and will be changed to JMP NEAR to (hook offset + 5), to return back to the infected program, after snippet's code is executed.
Here is sample snippet's code (use nasm -f bin snippet.asm to compile):
BITS 32 ; receives control from JMP NEAR at hook offset db '$ORIGINAL_BYTES$' ; to be replaced with original bytes, padd with NOP's pusha nop ; payload popa mov esp, 0aa55aa55h ; to be replaced with jmp (hook_offset + 5)
This means that INFELF will take some instructions from target executable at hook offset, of summary size >= 5, padd'em with NOPs to make 16 bytes, and copy'em into snippet's original-bytes signature. Second signature will be changed to JMP NEAR returning control to executable right after that JMP NEAR at hook offset that passed control to 1st snippet's instruction.
download INFELF v1.02