Map and projects (the most frequently updated page of this blog)

2010/01/18

Sail to the edge and I'd be there

Messing with the TLS
TLS, aka Thread Local Storage, is a way to execute some code before the EntryPoint or after ExitThread/ExitProcess.
the 10th Data Directory points to a structure, and one of the elements (VA, not RVA) points to null-terminated list of callbacks, which will be called one after the other.
This list is stored as VAs (it includes the ImageBase then), which makes it quite uncommon among the PE structures.
IMAGE_TLS_DIRECTORY32:
...
AddressOfCallBacks dd Callbacks ; VA
...
Callbacks:
dd TLS
dd 0 ; null-terminated list

The size of the Data Directory is not taken into account. Some tool may ignore wrongly the TLS if it's not defined, though.

Callbacks are executed on (before) thread start and on (after) thread exit. However, (credits goes to Peter Ferrie and Kris Kaspersky here), TLS callbacks execution won't happen if no dll importing kernel32 is imported itself. So, if kernel32.dll is the only 'official' import (it doesn't mean it's the only dll in the program space), the callbacks are not executed.

2010/01/17

If you got the money honey, we got your disease

Messing with the EntryPoint
In most files, the EP is in the first section. In many packers or file infecters, it will be in another section. It's actually common in the header itself (Upack, FSG), and sometimes (like - among others - in collapsed.asm), it's at RVA 0, in which case the MZ signature is just interpreted as dec ebp, pop edx, which is benign. Many packers just put some trampoline code at RVA 0, then the rest of the code further.
So, usually:
Section0 VA <= EntryPoint <= Section0 VA + Physical Size
and to a general extend:
0 <= EntryPoint <= SizeOfImage
But no check is actually done on the EntryPoint value!

2010/01/16

With a rebel yell! more, more, more!

Description of a compiled PE header
In my previous posts, I started exploring PE Headers with a minimum amount of information (as opposed to the official specifications). On the other hand, standard compilers like MASM add more elements (not necessarily documented), on top of defining, as you would expect, mosts elements of the structures.

To understand things correctly, I assembled and linked a simple HelloWorld code source in Masm, and reproduce the complete structure of the executable with a YASM source (that defines every byte of the header manually).

2010/01/14

Hey, hey, hey, what's in your head?

PE Header holes / filling them
Since the PE loader in Windows is too flexible, most of the PE Header information can be discarded.
As the Tiny PE project proved, it's possible to get a 97 bytes PE! It also proved a valid PE can't be smaller, as 97 bytes is the minimum size to fit all the structures until OPTIONAL_HEADER.Subsystem, the last compulsory element.

In my short one-section file header (which I use in my helloworld.asm example), I define a minimum (not an absolute minimum, though) amount of elements of the PE structure, to have a file with Imports, Section and EntryPoint (none of them is strictly necessary):
IMAGE_DOS_HEADER
e_magic (constant)
e_lfanew
IMAGE_NT_HEADERS
Signature (constant)
IMAGE_FILE_HEADER
Machine (almost constant)
NumberOfSections (not strictly necessary)
SizeOfOptionalHeader
Characteristics
IMAGE_OPTIONAL_HEADER32
Magic (almost constant)
AddressOfEntryPoint (not strictly necessary)
ImageBase
SectionAlignment
FileAlignment
MajorSubsystemVersion (almost constant)
SizeOfImage
SizeOfHeaders
Subsystem
NumberOfRvaAndSizes (not strictly necessary)
IMAGE_DATA_DIRECTORY
ImportsVA (not strictly necessary)
IMAGE_SECTION_HEADER
VirtualAddress (not strictly necessary)
SizeOfRawData (not strictly necessary)
PointerToRawData (not strictly necessary)

2010/01/13

They say jump, you say how high

Various ways of JMPing
jumping, aka branching, is one of the most common operations.

I wrote a file that implements many forms of jumping, whether they are common, obfuscated, or rare. Not everything is detailed in this post, check the source for further information.

First, Jumps,

EB 07 JMP SHORT 004000F9
E9 07000000 JMP 00400105
FFE7 JMP EDI ; 00400113
FF25 19014000 JMP DWORD PTR DS:[400119] ; 00400124
EA 32014000 1B00 JMP FAR 001B:00400132
FF2D 38014000 JMP FAR DS:[400138] ; DS:[00400138]=001B:00400145

then CALLs,

E802 CALL 00400103
FF1A CALL FAR [EDX]
FF12 CALL [EDX]
FFD2 CALL EDX
9A 7C014000 1B00 CALL FAR 001B:0040017C

RETurns

C3 RETN ; Return to 004001DE
CB RETF ; Return to 001B:004001EC
CF IRETD ; Return to 001B:004001FB, flags = 206

loop*.

2010/01/12

Storm warning, but there's no fear

relocater < mutater < virtualiser
I already wrote about a relocater and different kinds of virtual machines. Between the two of them, there is another kind of executable, simpler than virtual machine but particularly suitable for obfuscation:
a mutater, or polymorphic code.
Similar to virtual machines, some data represents the virtual code to execute. However, in this case, the architecture is strictly the same as the cpu. The main point of mutation is randomization. And if you add some junk code in the middle, you get what happens when virii modifies themselves from one file to the other.

2010/01/11

And go where you're going to

DIY PE
To be able to create custom PEs, I wrote a simple script that helps with simple tasks like generating import structures, PE checksum and default values.

So, add all PE structures manually (or better, use the same one over and over), generate imports, and voila! you have a handmade PE file in which you control every byte.

I didn't extend (yet?) that script to Exports/Resource/Relocations/TLS/Sections, because I don't use them so often.
Also, different Section/File alignments are not supported. Once again, I don't really need it (often).

Source directory

[...]

PE maison

Pour pouvoir créer des PEs spéciaux, j'ai écrit un script simple, qui permet de faire des petites choses comme générer les structure des imports, calculer la checksum ou mettre des valeurs par défaut.

Donc, ajoutez les structures PE a la main (ou mieux, utilisez toujours le même en-tête), générez les imports, et voilà! vous avez un PE fait main, dans lequel vous contrôlez chaque octet.

Je n'ai pas (encore?) ajouté la gestion des Exports/Resource/Relocations/TLS/Sections, car je n'en ai pas besoin si souvent.
De même, les alignements Section/File différents ne sont pas possibles. Là aussi, je n'en ai pas besoin (souvent).

répertoire Source

Useless but original

An different form of junk code
You probably know about the overlapping instruction technique used to fool disassemblers:
due to the way x86 CPUs work, jumping over a E8 byte will make a bogus CALL instruction appear in the code.

if you use a longer instruction like IMUL, you can fit any instruction, so you can create a blocky piece of code.
So from the outside, whether from hex or from assembly, it looks quite blocky
EB 02 JMP SHORT 004000F4
69846A 40681C01 4000EB02 IMUL EAX,[EDX+EBP*2+11C6840],2EB0040
698468 22014000 9090EB02 IMUL EAX,[EAX+EBP*2+400122],2EB9090
69846A 00E81E00 0000EB02 IMUL EAX,[EDX+EBP*2+1EE800],2EB0000
69846A 00E81900 00005461 IMUL EAX,[EDX+EBP*2+19E800],61540000

while the execution trace looks almost normal:

You'll stumble in my footsteps

A different flow obfuscation: a relocater
I wrote a simple executable, implementing an idea by Piotr Krysiuk, where all routines are made to be executed at the same address. Because of that feature, following the flow is potentially difficult, and creating a direct dump could be annoying as no disassembler allow different pieces of code to be present at the same address.

To give you an example, here are the 2 functions of that binary upon their execution:
First:
004000FA 6A 40 PUSH 40

004000FC 68 6E014000 PUSH 0040016E ; ASCII "Tada!"
00400101 68 74014000 PUSH 00400174 ; ASCII "Hello World!"
00400106 6A 00 PUSH 0
00400108 E8 55000000 CALL 00400162 ; MessageBoxA
Later:
004000FA 6A 00 PUSH 0
004000FC E8 67000000 CALL 00400168 ; ExitProcess

2010/01/02

when CPUs have too many opcodes...

Back from my last post, to real machines, I decided to release as-is a YASM source that contains most x86 32bits opcodes, including SSE, AVX, FPU,...

My conclusion is that there are way too many!

You can use it just for curiosity or testing your favorite disassembler.

Source Code (Yasm)

the longest opcode (as a word) is
vaeskeygenassist xmm0, xmm0, 0
even though the recent
vbroadcastf128 ymm0, [0]
is not far behind.

2009/12/24

when VMs have only one opcode...

VMs are common in advanced packers or virii, but they seem to follow the same architectures (x86 or stack machine).
I was curious, and implemented, around a small fibonacci example, the usual models of course, but as well the TTA and Subleq ones, two models of one instruction set architectures.

Opcode-less VMs are quite small in code, but the virtual code is quite obscure - which makes an easy but annoying challenge:
typically, you would expect that MOV is the most basic opcode, and arithmetic operations tend to be more complex. But in Subleq, a standard MOV is made of 4 lines of code, while SUB+JLE is only 1.

2009/12/19

This is not a pipe

...nor a virus.... just the EICAR test file.
I never took the time before to look at it in details, so I wrote a commented source to re-create it exactly.

Source code

2009/05/10

a few fixes

I created a minimal project to keep libdasm updated.
a few fixes were already submitted, thanks to Silvo Cesare and Georg Wicherski, to fix a few FPU, TEST and MOV opcodes.

2009/04/16

Stupid sequence of the day

Inspired from ReWolf:
9A 69 E8 C8 C2 CD C3
generates instructions that decode correctly at every bytes, independantly of the following bytes...
9A 69E8C8C2CDC3 callf 0C3CD:0C2C8E869
69 E8C8C2CDC3 imul ebp,eax,0C3CDC2C8
E8 C8C2CDC3 call 0C40E0C36
C8 C2CDC3 enter 0CDC2,0C3
C2 CDC3 retn 0C3CD
CD C3 int 0C3
C3 retn
sadly the 69 imul doesn't always decode that way, it's not a generic 5 bytes cloaker.

2009/02/01

no more hidden progress

After having converted several working hashes algorithms to classes, I decided to put everything from my personal wip repository to a branches/wip on the public repository.

next step : reduce the /wip branch to the minimum.

2008/05/19

a different challenge

A colleague brought an interesting puzzle to solve.
I like the fact that you can always remove any part of this puzzle, even the first one you put, it's not stuck under the next ones. It gives you the impression that it's very easy and you can solve it within minutes. err....
Sadly, I realized I wouldn't have enough time IMO, so I went for the bruteforcing - and learned to make shallow copies of lists :)

codesource (python) here

2008/03/02

changes

New job and new family situation made me stop working on challenges as much as I wanted to...
No more teach-me neither, at least for now. Still planning to do many things, but right now everything is on hold.

2007/11/11

done

haiklr's hysteria crackme
unusual keyfileme with weaknesses to find. patience & logic

BlueOwl's UpxEd
funny hand-crafted upx, simple obfuscation

2007/11/09

done

imp's SimpleS
Socket. original & simple. looking forward to a sequel.

2007/11/06

done

Unicorn CrackMe1
pure logic, original. Couldn't prove there is only one serial though.