Aslan (4514N) - Binary Code Integrator - Okaeri

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.

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.

Before you will get too hasty:This project is still in development phase, however even if 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 Miśta's cat :-)). I did it for fun additionally it helps me with "pentests"...

12
komentarze:

I think i May have a platform and a way to integrate a dynamic analyzer It still needs alot of work..but...I think the Subsystem I am developing would highly benefit from the features decribed and provide unique utility into what I think is a very passive subsystem underneath the thin layer of win32..

but then again the concept would have to be rewritten using only Native Api..and patch sections as the PE Loads before LdrpMapDll..

Im not gonna lie to you i have no money..I can't buy your idea, but I think we could both benefit from a little interaction :D

Oh ok i wasn't aware you are the Anonymous one :-) Anyway if you could provide 99-100% code coverage with just static code analysis it would be a really significant improvement! I'm just afraid static analysis itself can always return 'ambiguous' results. Hope to hear from you soon!

well as a byproduct of my subsystem development i can now 'request' code mapped into the the shared section..By placing "patched" in hooks or even direct file modification or process preload hotpatching.. on LdrpCallInitRoutine and BaseThreadStartThunk by placing the 'patches' at these locations we can then extract a initialial static analysis of each thread before it starts (Figure where thread function ends,gather call data,Gather Jmp Flow chart data and so on..)I can then build a thread behavior signature and store that for refernce to identify similaries in the 'next execution of the program' or to activly identify 'newly' created threads with certain similaries (EIP being the main one...)this also will account and gather for all threads..also Ive ben taking into my mind your other new paper on aggressive binary unpacking. using this approach on "stubbed" packerscan provide us with a further advantage over this type of "protection" as well as your excellent methods!!

more on that note can be found on www.woodmann.com in the comments part of Why Opcodex90's 'dll injection shield' fails against RtlCreateUserThread..

Currently adding debug output to the whole thing so its easier to identify bugs..also working on ways to separate out the different objects that call into LdrpCallInitRoutine..thinking about testing return address but might need to do return address reverse disassembly to find the 'entry signature for the various callers of this function'

what else is there that you are "afraid" of? cause I will throw as much time as I can into researching and analyzing how to better approach the "problem"..

Did you get the Code on the SkyDrive?

its still a somewhat buggy mess but it works the first run through ;) also ive removed the actual hooking code for LdrpCallInitRoutine..as im not completely done with it, but even without that it show's how im doing it..I need to hear your concerns in a more detailed way as to why it wouldn't provide the needed code coverage. maybe we can come up with something "better" after we address these concerns ;D

I think we should start from the beginning since i guess we are talking about kinda two different things. Let's focus on a static binary code analysis for a while. You said in previous comment that you are able to guess the code coverage even without running the executable. I was concerned about it because like i said static binary code analysis is limited and very often it brings some 'ambiguous' results. For example we have following sample code:

Lets assume you start the disassembly process from the start label. While preparing structures for the integration process you must be able to guess correctly if XXXXXXh points to the code or it points to the data (things that are not executed). In this funky example it should be treated as a code. So in other words it should be disassembled as well. However as you can see it is a very obvious example and even though it is hard to find a general algorithm which would determine such situations (solutions like emulators, signature things are not very good, of course they can make the disassembly better to some point but they do not solve the entire problem). Anyway if in this situation you will treat XXXXXXh as data, it means that you will not be able to repair the instructions located at XXXXXXh. So putting it simple whenever you will make a mistake (you will treat CODE as DATA or vice versa) it will be fatal to the integrated program (it can influence its behavior - typically causes a crash). This is the general thing i am worried about. Let me know how do you see it. Cheers.

- pb

P.S I may respond in some days because i'm going for a trip with my bike ;-)

make the program learn the target..staticly and dynamically..with any means neccessary? do static analysis by sig seeking call's XXXXXXXXh and jmp's XXXXXXXXh..then do stack analysis noting where what is done with [esp] and how its used..then for the rest of the calls/jmps do some runtime dynamic analysis..also you named a solution as well did ;)"So in other words it should be disassembled as well" maybe just disassemble it anyways and check for recognizable code..use isalnum and the other isal functions to separate some of this junk out as well..then for remaining..if there are.. then I would have to resort to some kind of dynamic analysis..breakpoints,GPF's,anyway possible..

the more important one is how will CallBackRoutines and Apc's be handled..these two would have to go through both static and even tougher dynamic methods to recognize them...

First of all sorry for delays, i began ridding pseudo-enduro races with myself huh this is so much fun :-)

BanMe well i can agree that both static analysis and dynamic analysis can cooperate and make the general code vs data view more reliable. However there are many binary files that are somehow resistant to such algorithms. And what is important here, lets say you have obtained 99\% the binary layout correctly but this 1\% (even one instruction mismatched - treated incorrectly) may be fatal. The dynamic analysis is a very good approach but also limited, for example the execution path may be depended on user requests from the GUI etc. etc. - so not all paths will be traced. In Aslan user must decide about such situations. Like i said and you have said too we could use some SIG matching, but it is only good to some point - look at IDA it uses many of those signatures tricks (FLIRT etc.) and still there are inconsistent situations. Anyway we can also took some knowledge from CallBackRoutines u have mentioned but i was thinking rather about approach that does not depend on operating system. But yes we can use this as additional support.