Aslan REVISITED !!!

:: Introduction (words from the author)


As some of you probably remember in 2006 i have announced a tool called Aslan (4514N). The purpose of this tool was to develop a binary code integration (static binary code rewriting) engine which would allow Portable Executable file modification on the binary level (so without source code). The tool itself was limited to X86-32 architecture. It's quite a shame because i haven't done a single update to this project since 2006, so for about 3 years :( However things have changed recently. I have forced myself to sit and think about Aslan for a while. This took me some of my free time, but I have REWRITTEN Aslan completely from scratch - i have made it faster, more stable and more fabulous then ever. But that's not all - i think it is really worth mentioning that i have added a very very innovative feature to it called BINARY CODE WELDING (MERGING). As far as i know i am the first one to introduce this feature on such complication level.
 

UPDATE: I have decided it is good to know about some references here, first of all the topic of binary translation/code rewriting techniques (either static or dynamic)/binary code manipulation tools were used in the past - like in for example QPT(1994), Shade(1994), ATOM(1994), NJMC(1994), EEL(1995), Freeport Express(1995), FX!32 (1996) etc. The PE integration itself was also used by Zombie in Mistfall engine (somewhere in 2000). However the "welding" feature was not introduced back then. Besides Aslan does not rely on other integration engine code.

 

:: BINARY CODE WELDING


Before even i started creating this technique i was introducing the Aslan concept to one of my good friends HackerFantastic. In one of the talks we had few days ago he said it would be total wreck if i could integrate code that is not only written in ASM. As you probably know old Aslan required you to integrate assembly code only (binary form) which typically was a position-independent code too. Not to mention that typically such binary injected stubs needed to resolve API addresses on their own and finally for most of the people assembly is not much fun. So can you imagine how to integrate let say a code written in C to another program at any pseudo-random location? Have you though about what should you repair, how to manage unresolved imported APIs and stuff? It may sound easy but to any researcher following the idea - this is a hell on earth. But yes, i did it. Ok enough words lets bring out some example.

 

:: EXAMPLE (WELDING TWO HLL APPS INTO ONE)


For the sake of this example i have chosen two applications REGEDIT.EXE (146KB application) and a LESSON4.EXE (a 8kb application, written in C and produced by LCC compiler, this application comes from NEHE OPENGL tutorials and all it does it shows two rotating figures in the window).

The objective: Inject code from LESSON4.EXE to REGEDIT.exe and preserve the functionality of original file and the injected code. This means now the LESSON4.EXE code will be a part of REGEDIT.exe and all will look like it was originally compiled this way.

So what we should take from LESSON4.EXE? In order to make the correct welding happen we need to split bytes from LESSON4.EXE for code and data (often needs to be writable so we need to locate it in the proper segment). Following table shows what fragments do we need:

FROM LESSON4.EXE

CODE

0x00401000-0x00401FC4

DATA

0x00402000-0x004025FF
0x00403000-0x00403340

As you probable know Aslan provides you unique abilities and allows you to inject code into any particular location in the original PE file (of course it should be logical). For the sake of this example i have chosen following injection points:

 

INJECTION POINTS IN REGEDIT.EXE

CODE

0x010062C7

DATA

0x01019020

Injection points original disassembly:

 

CODE INJECTION POINT (.text section - first section)
.text:010062BA ; ---------------------------------------------------------------------------
.text:010062BA
.text:010062BA
loc_10062BA: ; CODE XREF: RegEdit_OnCommand(x,x,x,x)+67j
.text:010062BA
; DATA XREF: .text:off_10063F6o
.text:010062BA
push edi ; jumptable 0100620C case 8
.text:010062BB
call _RegEdit_OnKeyTreeRefresh@4 ; RegEdit_OnKeyTreeRefresh(x)
.text:010062C0
jmp loc_10063EF
.text:010062C5
; ---------------------------------------------------------------------------
.text:010062C5
.text:010062C5
loc_10062C5: ; CODE XREF: RegEdit_OnCommand(x,x,x,x)+67j
.text:010062C5
; DATA XREF: .text:off_10063F6o
.text:010062C5
push 10h ; jumptable 0100620C case 27
.text:010062C7
call sub_1009C30 <--- CODE INJECTION POINT HERE !!!!!!!!!!!!!!!!!!!!!!
.text:010062CC
pop ecx

It means that every instruction (every area marked as code -> 0x00401000-0x00401FC4) from LESSON4.EXE will be injected at 0x010062C7 (.text section) of original REGEDIT.EXE application. Analogous the DATA from LESSON4.exe (0x00402000-0x004025FF and 0x00403000-0x00403340) will be put at 0x01019020 (.data section r&w) in original REGEDIT.exe application.

WHAT ABOUT IMPORTS?

As you probably know REGEDIT.EXE is using some different imported APIs and libraries than LESSON4.EXE. This is shown on the following pictures:

 
Imports of REGEDIT.EXE

 
Imports of LESSON4.EXE

As you can see some libraries are missing like opengl32.dll/glu32.dll etc. You can belive me or not but even when same library is used in two files specified imported APIs are still missing.

Aslan is able to disassemble both of the import tables to some intermediate representation, join them together (if of course this is needed, so if a wanted API is already imported by REGEDIT.EXE there is no need to declare it one more time). The newly created import table can be also stored at any position in the PE file as long as it stays valid. Some of the know PE utilities like CFF Explorer have some features like ImportAdder but they always put additional imported entries at the end of the file - Aslan does not work that way! When all the imports are resolved Aslan links them with requests from LESSON4.EXE code. Now all the LESSON4.EXE code looks like it came just out from the linker. Here is the final import table:

 
Imports of REGEDIT_WELD.EXE

As you can see now the final import section is quite bigger. Following pictures will show you that even if the imports are now bigger the import directory still resides in the same PE section (first section - .text). Additionally the number of sections between the original program (REGEDIT.exe) and the welded one is the same, and also the resources directory points to the same section (.rsrc):

 
Some of DataDirectories from REGEDIT.EXE

 
Some of DataDirectories from REGEDIT_WELD.EXE

 

 
Sections layout of REGEDIT.EXE

 
Section layout of REGEDIT_WELD.EXE


Following table presents final offsets (locations) in REGEDIT_WELD.EXE:

INJECTION POINTS IN REGEDIT_WELD.EXE

CODE

0x01006D68

DATA

0x0101E020

Where at 0x01006D68 an unconditional jump is placed, which throws the execution to the orignal LESSON4.EXE entrypoint just like the following picture shows:

 
Fragment of REGEDIT_WELD.EXE code showing the start of injected code.

And this is "all done" by following piece of code:


#define	M_IS_CODE(x) ((x >= 0x00401000) && (x <= 0x00401FC4))
#define M_IS_DATA(x) (((x >= 0x00402000) && (x <= 0x004025FF)) || ((x >= 0x00403000) && (x <= 0x00403340)))

	
	for (iter = cdListMerger.begin(); iter != cdListMerger.end(); iter++)
	{
		cdbb	=	*iter;
		if (M_IS_CODE(cdbb->old_startVA))
		{
			listMCode.push_back(cdbb);
			listMCodeMap.insert(make_pair(cdbb->old_startVA,cdbb));
		}
		if (M_IS_DATA(cdbb->old_startVA))
		{
			listMData.push_back(cdbb);
		}
	}

#define CODE_INJ_ADDR	0x010062C7	// in regedit
#define DATA_INJ_ADDR	0x01019020
#define CODE_INJ_EP		0x004011CB	// in lesson 4 search by old addr

	cdbb	=	merger_find_by_oldaddr(&listMCodeMap,CODE_INJ_EP);
	cd_basicblock *cd_jump	=	create_jump(cdbb);
	listMCode.push_front(cd_jump);

	// first put a jmp to entrypoint
	// since first element in the listMCode is not always the entrypoint
	// inject code
	iter	=	find_list_iter_by_addr(CODE_INJ_ADDR);

	CDBBlockList.insert(iter,listMCode.begin(),listMCode.end());

	// inject data
	iter	=	find_list_iter_by_addr(DATA_INJ_ADDR);
	CDBBlockList.insert(iter,listMData.begin(),listMData.end());

 

 

:: Sample binaries (original REGEDIT.EXE, LESSON4.EXE and REGEDIT_WELD.EXE)
 

INTEGRATED BINARIES

 

:: Video demo (running REGEDIT_WELD.EXE)

You can check the video in HD using this link: http://vimeo.com/5550537 (password: 'die')

 

Aslan from Piotr Bania on Vimeo.

 

 

:: Last words

Summing it up:

Aslan engine can rebuild all the PE structure, internal offsets (jumps, references etc.), any type of PE directories like relocs, imports, exports, resources...) - all is done automatically. Additionaly now it can also meld programs written in High Level Lanaguages like C!!!

Of course i haven't described Aslan mechanisms deeply, this is obvious since i don't want to write a book about it :-)

This project is still in development phase, however even if I finish it i doubt i will release it for public. This is obvious since most of people would use it for evil purposes and in the end it will not bring me much good karma. Besides i have decided to delete entire GUI so right now Aslan has no interface so i am probably the only person who can use it correctly (not to mention Marcin Mita's cat :-)). I did it for fun additionally it helps me with "pentests".

As you can see currently Aslan is using only static analysis to obtain the correct disassembly, because of that almost always user interaction is required because static analysis often produces inconsistent results. This can be done interactively in IDA Pro. Perhaps it would be good to mix it with some sort of dynamic analyzer which could help (and only help, there is still no 100% guarantee that the entie disassembly will be obtained) in providing more correct disassembly. Maybe something like Trace Recorder (see PAPER - thanks to skape for the paper) or something like that? We will see :) Hope you enjoyed this little demo.

 

 

www.piotrbania.com
 2009 - All rights reserved
 Copyrights - Piotr Bania