Flag: Tornado! Hurricane!

 Forums >>  Brainstorms - General  >>  Novel anti-dump technique using Fibers

Topic created on: August 15, 2008 07:19 CDT by noglorp .

Fairly simplistic:
Call ConvertThreadToFiber prior OEP, and then within the packed code plant calls to CreateFiber (could also be pre-OEP) and SwitchToFiber. If the process is dumped at OEP, the call to SwitchToFiber will cause an access violation.

What makes this a little sexier is that SwitchToFiber contains no calls itself and could be inlined, making it hard to spot/easy to obfuscate. Along with calling CreateFiber in unpacking stub this could require a sharp eye to spot.

Sample code for convenience:
#include <stdlib.h>
#include <stdio.h>

#define WIN32_LEAN_AND_MEAN
#include <windows.h>

void __stdcall Test()
{
printf("Inside fiber");
}

void main2()
{
void *f = CreateFiber(0,Test,NULL);
printf("Pre fiber - ");
SwitchToFiber(f);
}
int main()
{
ConvertThreadToFiber(NULL);
main2();

return 0;
}

  noglorp     August 17, 2008 03:36.59 CDT
Alternative call instead of SwitchToFiber, functionally the same (to prevent finding the call by name)

void aSwitchToFiber(void *f)
{
asm (
//fix broken stack from prolog
//wouldn't be necissary if GCC allowed
//__declspec(naked) with x86
"pop %ebp\n"
//begin identical code
"movl %fs:0x18, %edx\n"
"movl %ds:0x10(%edx), %eax\n"
"movl %esp, %ecx\n"
"movl %ebx, %ds:0xB8(%eax)\n"
"movl %edi, %ds:0xB0(%eax)\n"
"movl %esi, %ds:0xB4(%eax)\n"
"movl %ebp, %ds:0xC8(%eax)\n"
"movl %ss:(%esp), %ebx\n"
"add  $0x8,%ecx\n"
"movl %ecx, %ds:0xD8(%eax)\n"
"movl %ebx, %ds:0xCC(%eax)\n"
"movl %ds:(%edx), %ecx\n"
"movl %ds:0x8(%edx), %ebx\n"
"movl %ecx, %ds:0x4(%eax)\n"
"movl %ebx, %ds:0xC(%eax)\n"
"movl %ss:0x4(%esp), %eax\n"
"movl %ds:0x4(%eax), %ecx\n"
"movl %ds:0x8(%eax), %ebx\n"
"movl %ds:0xC(%eax), %esi\n"
"movl %ds:0x10(%eax), %edi\n"
"movl %ecx, %ds:(%edx)\n"
"movl %ebx, %ds:0x4(%edx)\n"
"movl %esi, %ds:0x8(%edx)\n"
"movl %edi, %ds:0xE0C(%edx)\n"
"movl %eax, %ds:0x10(%edx)\n"
"movl %ds:0xB0(%eax), %edi\n"
"movl %ds:0xB4(%eax), %esi\n"
"movl %ds:0xC8(%eax), %ebp\n"
"movl %ds:0xB8(%eax), %ebx\n"
"movl %ds:0xCC(%eax), %ecx\n"
"movl %ds:0xD8(%eax), %esp\n"
"jmp *%ecx\n"
);
}

  GynvaelColdwind     August 17, 2008 04:58.26 CDT
Hi,

First of all, I would like to mention that I like the trick very much ;>

I would propose inlining not the SwitchToFiber, but CreateFiber and ConvertThreadToFiber - both can be inlined and the shouldn't give a hint to what they really are (since ConvertThreadToFiber uses only memory allocation, which could be skiped if we use static memory (however I would leave it as is), and CreateFiber uses memory allocation + some stack related stuff that could be rewritten to be a little less functional, yet shorter).

I think that an unconcealed SwitchToFiber call happening after OEP without prior unconcealed calls to ConvertThreadToFiber and CreateFiber would be more surprising  (however it's just my opinion ;>).

From another point of view, this trick, after inlining everything related to fibers, we get a trick that could be described as 'setting something before OEP that is used after OEP'. So the trick could be done without involving fibers, it might very well be some function pointer or sth.
Well, but bringing fibers to it makes it a lot more confusing at the first sight ;>

Good work ;> Keep the fire burning ;>

  GynvaelColdwind     August 18, 2008 02:45.04 CDT
About "naked" functions in gcc/g++, I did a little research how can it be done when last doing some project. You can checkout my blog for description. Short version:

int gimme_five(void);
__asm(
  ".globl __Z10gimme_fivev\r\n"
  ".globl _gimme_five\r\n"
  "__Z10gimme_fivev:\r\n"
  "_gimme_five:\r\n"
  "  movl $5, %eax\r\n"
  "  ret"
);

  noglorp     August 23, 2008 19:38.34 CDT
Thanks, and thanks for the info about naked gcc.

It really pisses me off that they have that restriction :/. They allow naked for embedded architectures, but not for anything else. The reasoning is "you should just use a .s" but I don't think that works with inlining, and is a pain in the ass, not to mention the "just use a .s" argument does not differentiate between embedded architectures and others, so wtf? -_-

PS: -masm=intel is sweet to, considering all disassembly tools for Windows use intel syntax. I've spent ages looking through Gnu manuals without finding that :D

  noglorp     August 23, 2008 19:46.26 CDT
Also, if I read that correctly, will GCC still append the header, only the function will still start after the header? Like,
push ebp
mov ebp, esp
gimme_five:
...

  GynvaelColdwind     August 24, 2008 06:16.53 CDT
Yeah, I've looked a lot for the -masm=intel too ;>

As for the header, no ;> Since the function does not exist at C level. The C compiler does nothing with it, it just knows that there is an external function called 'gimme_five'. The function begins to exist at object generation level (which are generated by the assembler, not the compiler), and there are also "linked" at the assembler level (since the assembler knows that such a label (we are not talking about functions any more ;>) exists an where it is ;>).
So the compiler never has a change to append any header. It's a WYSIWYG in the __asm case.

  noglorp     August 25, 2008 13:31.11 CDT
I understand.
I was confusing int gimme_five(); __asm(...);
with int gimme_five() { __asm( ... ); }
I didn't know you could use __asm in static context like that, that is cool.

I also found a nice way to use intel syntax for asm.
".intel_syntax" and ".att_syntax" assembler directives can be used any time, but you need to do .att_syntax after your function to switch the assembler back or else it tries to interpet gcc's att asm as intel asm.

  GynvaelColdwind     August 25, 2008 14:47.18 CDT
Oh, thanks for the ".intel_syntax" and ".att_syntax". Didn't stumble upon it earlier ;> Thx ;>

Note: Registration is required to post to the forums.

There are 31,320 total registered users.


Recently Created Topics
[help] Unpacking VMP...
Mar/12
Reverse Engineering ...
Jul/06
hi!
Jul/01
let 'IDAPython' impo...
Sep/24
set 'IDAPython' as t...
Sep/24
GuessType return une...
Sep/20
About retrieving the...
Sep/07
How to find specific...
Aug/15
How to get data depe...
Jul/07
Identify RVA data in...
May/06


Recent Forum Posts
Finding the procedur...
rolEYder
Question about debbu...
rolEYder
Identify RVA data in...
sohlow
let 'IDAPython' impo...
sohlow
How to find specific...
hackgreti
Problem with ollydbg
sh3dow
How can I write olly...
sh3dow
New LoadMAP plugin v...
mefisto...
Intel pin in loaded ...
djnemo
OOP_RE tool available?
Bl4ckm4n


Recent Blog Entries
halsten
Mar/14
Breaking IonCUBE VM

oleavr
Oct/24
Anatomy of a code tracer

hasherezade
Sep/24
IAT Patcher - new tool for ...

oleavr
Aug/27
CryptoShark: code tracer ba...

oleavr
Jun/25
Build a debugger in 5 minutes

More ...


Recent Blog Comments
nieo on:
Mar/22
IAT Patcher - new tool for ...

djnemo on:
Nov/17
Kernel debugger vs user mod...

acel on:
Nov/14
Kernel debugger vs user mod...

pedram on:
Dec/21
frida.github.io: scriptable...

capadleman on:
Jun/19
Using NtCreateThreadEx for ...

More ...


Imagery
SoySauce Blueprint
Jun 6, 2008

[+] expand

View Gallery (11) / Submit