Log in

View Full Version : Malware (packed, polymorphic) dll. Pecompact 2.xx?


TCM
June 1st, 2007, 22:15
Hello,

I was told that I might find more help here than at reverse-engineering.net

Where to begin:

Firstly, I do not have much experience in reversing malware. I have completed about 30 crackme's in my lifetime and have a fairly decent knowledge of windows internals (or so I thought).

Recently, I decided to attempt the disassembly of a random piece of malware downloaded from a website.

I first ran the program through PEiD. It detected it as packed with PECompact 2.xx, yet the program was not packed and could be disassembled with ease.

During execution, the malware loaded kernel32.dll and some choice functions. It then extracted a resource and wrote it to a file called "malware_filename.dat". It then called LoadLibrary on the .dat file.

When this was being disassembled with IDA Pro I received an access violation exception. Upon examination of the code I witnessed:
Code:
Code:

xor eax, eax
move [eax], ecx



I didn't understand what I was seeing until I read an article about how packers can execute their code in the SEH. I tried to trace where the SEH was by looking for the TIB, but it pointed to some location in ntdll.dll which did not seem correct.

I did trace the code a couple times and notice that it is polymorphic in the sense that it seems to write to memory and then call it.

I can't seem to figure out how to dump a clean version of the dll.

UnPE2 and unpecompact both do not work on dlls.

Furthermore there are some interesting anti-debugging techniques used such as placing me in an infinite loop inside of ntdll_DbgUIRemoteBreakin.

The only reason I think it uses PEcompact2 is because you can physically see an ascii string "pecompact2" inside of it, which may have been placed there to trick me.

PEiD does not detect anything, IDA and Olly beg to differ.

Does anyone have any ideas? Has anyone seen anything similar before? Any tutorials to point me in the right direction?

If you would like the file, I could upload it. But I will only need help defeating the packer/polymorphic code.

Thanks,
-TCM

blabberer
June 2nd, 2007, 02:38
Quote:

I didn't understand what I was seeing until I read an article about how packers can execute their code in the SEH. I tried to trace where the SEH was by looking for the TIB, but it pointed to some location in ntdll.dll which did not seem correct.


assuming you are using ollydbg you dont have to search tib teb and peb for seh handlers

view->seh chain will provide a neat over view of all the structured exception handlers that have been chained together

the top most one will be called first and the bottom most one will be called last before the application crashes if none of them handled the specific exception

you can use right click follow handler to follow and analyse the seh handler
after you follow you can set a breakpoint there
and use shift+f9 (pass exception to handler)

hope that helps

disavowed
June 2nd, 2007, 12:17
Some other possibilities:
It might be using Vectored Exception Handling instead of or in addition to Structured Exception Handling.
It might not have any custom SEH functions at that point in the execution because it purposely went down a "bad-guy" path because it detected your debugger.

TCM
June 3rd, 2007, 12:46
Well. I managed to trace it to right before the point where I become jailed.

The DLL virtualalloc a space in memory at 0x00350000.
The DLL then points to it's text section and begins (in some weird way) decrypting a section and writing the result in the new memory region.
Eventually the DLL jumps into the new region.

When inside the new memory .text section it runs a very similar LoadLibraryA/GetProcAddress loop.

Code:

00350365 8B0E MOV ECX,DWORD PTR DS:[ESI] ; Load Integer Offset
00350367 03CB ADD ECX,EBX ; Translate Address
00350369 51 PUSH ECX ; Arg1 = Library Name
0035036A FF93 211E1701 CALL DWORD PTR DS:[EBX+1171E21] ; Call LoadLibraryA -> 7C801D77
00350370 8945 FC MOV DWORD PTR SS:[EBP-4],EAX
00350373 8B56 04 MOV EDX,DWORD PTR DS:[ESI+4]
00350376 8B7E 08 MOV EDI,DWORD PTR DS:[ESI+8]
00350379 03D3 ADD EDX,EBX
0035037B 03FB ADD EDI,EBX
0035037D 33C0 XOR EAX,EAX
0035037F 0302 ADD EAX,DWORD PTR DS:[EDX]
00350381 74 16 JE SHORT 00350399
00350383 52 PUSH EDX
00350384 8B02 MOV EAX,DWORD PTR DS:[EDX] ; Load Integer Offset
00350386 03C3 ADD EAX,EBX ; Translate Address
00350388 50 PUSH EAX ; Arg2 = Function Name
00350389 FF75 FC PUSH DWORD PTR SS:[EBP-4] ; Arg1 = Library Address
0035038C FF93 251E1701 CALL DWORD PTR DS:[EBX+1171E25] ; Call GetProcAddress -> 7C80ADA0
00350392 AB STOS DWORD PTR ES:[EDI] ; Store Address in Memory
00350393 5A POP EDX
00350394 83C2 04 ADD EDX,4
00350397 ^ EB E4 JMP SHORT 0035037D
00350399 83C6 0C ADD ESI,0C
0035039C 0306 ADD EAX,DWORD PTR DS:[ESI]
0035039E ^ 75 C5 JNZ SHORT 00350365




For some reason, it successfully loads kernel32.dll (or aquires the handle to it since it is already loaded). When it needs to load user32.dll it gets stuck in an infinite loop somewhere in ntdll.

Has anyone seen this before as a possible anti-debugging method?
I can F8 over the kernel32.dll load, but if I try over the user32.dll load I lose control of execution.


Here is what it should load from user32.dll eventually.

Quote:
00350C00 75 73 65 72 33 32 00 4D 65 73 73 61 67 65 42 user32.MessageB
00350C10 6F 78 41 00 77 73 70 72 69 6E 74 66 41 00 94 1D oxA.wsprintfA.”
00350C20 17 01 E1 1D 17 01 F9 1D 17 01 5B 1D 17 01 47 1D áù[G
00350C30 17 01 53 1D 17 01 00 00 00 00 6B 65 72 6E 65 6C S....kernel
00350C40 33 32 00 45 78 69 74 50 72 6F 63 65 73 73 00 43 32.ExitProcess.C
00350C50 6C 6F 73 65 48 61 6E 64 6C 65 00 4F 70 65 6E 50 loseHandle.OpenP
00350C60 72 6F 63 65 73 73 00 47 65 74 4D 6F 64 75 6C 65 rocess.GetModule
00350C70 48 61 6E 64 6C 65 41 00 56 69 72 74 75 61 6C 50 HandleA.VirtualP
00350C80 72 6F 74 65 63 74 rotect


blabberer
June 3rd, 2007, 13:11
you mean you can f8 this line once

0035036A FF93 211E1701 CALL DWORD PTR DS:[EBX+1171E21] ; Call LoadLibraryA -> 7C801D77

and after f8 you land in this line
00350370 8945 FC MOV DWORD PTR SS:[EBP-4],EAX

but the second time you cannot f8 on this line ?

can you set a f2 break point on the
00350370 8945 FC MOV DWORD PTR SS:[EBP-4],EAX

and f9 it ?

i assume you are using a virtual machine or a safe environment
while doing this experiment
and not using your production machine with network access etc ??

no loadlibrary system call doesnt have any antidebug tricks
and user32.dll initialization code also doesnt have any antidebug tricks
as far as i know

TCM
June 3rd, 2007, 13:59
Quote:
[Originally Posted by blabberer;66157]you mean you can f8 this line once

0035036A FF93 211E1701 CALL DWORD PTR DS:[EBX+1171E21] ; Call LoadLibraryA -> 7C801D77

and after f8 you land in this line
00350370 8945 FC MOV DWORD PTR SS:[EBP-4],EAX

but the second time you cannot f8 on this line ?

can you set a f2 break point on the
00350370 8945 FC MOV DWORD PTR SS:[EBP-4],EAX

and f9 it ?


Your assumptions are correct, and I have tried to bp/F9 the following line. Unfortunately, After I F8 the second LoadLibraryA (for user32.dll), I "lose control" of execution. Ollydbg's CPU utilization hits 90% and all it says is "running..." in the bottom corner. If I attempt to actualize the thread I always find it near NtContinue.



Quote:

i assume you are using a virtual machine or a safe environment
while doing this experiment
and not using your production machine with network access etc ??


Yes. I'm running a Win XP SP2 box under VMware Server. It has network access to my other machine through an anonymous windows share for transferring files and thats it.



Btw, the "View SEH chain" worked perfectly. That is how I was able to get so far.


Update: It looks like the control is lost when syscall #06C is called (NtMapViewOfSection)

blabberer
June 4th, 2007, 04:45
it is stopped on NtContinue

how are you determining this did you hit f12 pause the app and view the call stack ?

does it say NtContinue is in top of the stack ?

are there any other thread running besides the main

in thecall stack window you can view call stacks for every thread by rightclicking and checkmarking differnent threads that are running

if your main is stuck on NtContinue

NtContinue takes a CONTEXT Parameter whose member eip will point to where it will will land once system returns

find it in stack follow in dump and then follow the eip in disassembler from dump [esp+4] == (CONTEXT *) = 0x123456##; [123456##+0xb8] == pointer to eip
in c
typedef struct _CONTEXT
{
..
..
..
dword eip;
..
}CONTEXT *PCONTEXT;


PCONTEXT pcontfoo;
pcontfoo->eip

you should see where it will start executing

NtmapViewOfSection also doesnt have any antidebugtricks
but it holds LoaderLock a critical section and if the critical section locks wasnt released then it will simply be looping infinitely

but that should normally not happen unless in some special cases where you shouldnt be reaching this point without some earlier failure

you might have landed in a kind of intentional misleading code sequence may be thats supposed to make you go insane tracing that while you should never be in this place ?? red herrings ??

if it is a plain NtMapViewOfSection it should never loop infinitely

on a heavily loaded multithreaded apllication it may take a few clock ticks
more than normal becuse some other thread hasnt ceded control of the critical section but in a normal app it should never loop infinitely

disavowed
June 4th, 2007, 10:54
Quote:
[Originally Posted by blabberer;66157]loadlibrary system call doesnt have any antidebug tricks

The unpacking stub could have patched anti-debug code into the LoadLibrary function in USER32's memory space. Unlikely, but a possibility to consider.

blabberer
June 4th, 2007, 11:34
yeah disavowed definately a possibility why unlikely ??
if he is tracing code that he should have never been tracing in the first place then every thing is a possibilty however remote

that why i added a qualifier system some kind of obtuse referance to indicate possible fiddling

TCM
June 8th, 2007, 12:51
Thanks for all of the responses. I'm not exactly sure of what happened but I can successfully trace over (F8) the call now. It appears that when the program attempted to load user32.dll, there were tons of other dlls loaded too including gdi32.dll and advapi32.dll. Also, when I F8 over the LoadLibraryA for user32.dll I get another warning from OllyDbg that the entry point of the module that I am working on is outside of the range (or whatever that generic "this file is packed" message is).


I managed to make a dump of the dll after it finished all of it's writing to the .text section. It actually went through a large loop where it XOR'd large sections of the code with '0x55' and then wrote calls to internal functions all over the .text section.

It hid ascii strings using a function that takes a hard-coded number and a encoded string and uses XOR to decode it. Pretty lame if you ask me.

Has anyone seen a type of packer or obfuscation like this?


Finally, does anyone know of website that lists explanations of the methods of packers so I could compare what I saw?

I would like to thank disavowed and blabberer for all of the help they have given me. I have learned a lot You guys are great.