?? 29a-7.015
字號:
Per-process residency review: common mistakes
by Bumblebee
Introduction
Per-process residency is a TSR method discovered by Jack Qwerty in
the early days of win32 platform. This great vxer got an alternative way
to hook system calls instead of global residency, very common under DOS
environments but so hard to obtain under win32 (win32 means win9x, ME,
NT, 2000, XP, ?).
That method is well known and has been used in several viruses. At run
time the import table is patched to hook API calls of the infected host
and then perform viral actions each time a call is done.
I don't want to explain here how to do the per-process residency. I think
there are yet so many infos about this topic (check references at the end
of this article for more about this tech). This little article aims the
result of the per-process residency. May be Jack Qwerty as pioneer didn't
realize matters of efficiency, but at this point, we must analyze the
method and (i hope) avoid some mistakes.
I've coded so many times per-process residency and i've tried to find
some ways to apply successfully the method. I hope this little article
provide a different scope of view to per-process residency.
State of the art: bad applied tech
When i read on irc one of the best vxers in the history of virus writing
type: "bah, it won't go so far, it's just a per-process", i got confused.
What's the problem of per-process residency? We are wrong thinking is a
kewl tech to find new files to infect? That's true, but wrong under some
basis.
Let's analyze what we understand by per-process residency:
1. The virus patchs import table (does not matter at infection or run
time)
2. The API is called
3. The hook gets the filename and tries to infect the file
May be theoricaly that seems ok. But we will see in practice that this
won't work at all.
The classic per-process hook affects the APIs that can access a file:
CopyFile* CopyFileEx* CreateFile* FindFirstFile FindFirstFileEx
FindNextFile GetCurrentDirectory SetCurrentDirectory GetFileAttributes*
SetFileAttributes* GetFileSize* GetFileType* GetFullPathName* LockFile*
LockFileEx* MoveFile* MoveFileEx* SearchPath* UnlockFile* UnlockFileEx* ...
Lemme explain why this approach is wrong and it won't help your virus to
spread.
At first place we must realize most of the APIs listed never (or quite
never) are called from a usual win32 app over an executable file. How
many programs installed in your comp use CopyFile? There's at least one
that will copy an EXE? Following this idea all the APIs marked with * are
not interesting to hook. Due: 1. those APIs are not used by user apps and/or
2. those APIs never will access an executable (and we infect executables).
At second place are the APIs not marked with *. Let's do two groups: find
file and set/get directory. Find file APIs are a great way to infect files
under windows nt if you affect cmd.exe. But since SFC is here to fuck us,
i think those APIs are not usefull anymore (even them work fine under nt).
Only that app is interesting, because the rest of the apps have a behavior
that make them unusefull. And that behavior will fuck second group too, the
set/get directory ones. Those APIs are not called from gui apps. Win32
provides a set of common dialogs to perform such task. If a gui app needs
to open a file, it will ask the user for it using such common dialogs.
Those apps never user find files directly to browse folders. And if them
use its own dialogs (rare), they are implemented through DLL. Those common
dialogs affect also the set/get directory, when you ask for a file to open,
it's usual let the dialog change the work directory, so those APIs are not
called.
So, what are the results? We have lots of per-process viruses that never, or
almost never, infect files using its residency.
It's believed that a per-process infector must have a run-time part due
this residency method is not effective. In fact is not a bad idea: you get
all windows files infected and then you have hosts to apply residency.
In consequence most per-process resident viruses are just plain run-time
direct action viruses. What a pitty.
But the problem is not in the residency but in the way we apply it.
Little ideas: open your mind
Those ideas are the result of my little research and my buggy viruses.
At first place i've proved the good results of run-time direct action
methods over DLLs. When a DLL is loaded and its EP called, the work
directory of the DLL is the same of the loader. So a simple scan of the
work directory should give us new files to infect. But that's not perfect
at all due the loader is running and then the file locked, so we cannot
infect it and probably there is not other execultables to infect. However
if an infected DLL from the system is loaded, it will be loaded before
other local DLLs of the loader, so there is a chance to infect DLLs too.
As you must realize, that idea is not nice under an environment with
SFC fucking arround [SFC]. I played this idea 1st time with AOC [AOC].
That idea should be applied to per-process. If we peep into explorer.exe
under win98 we see per-process residence is a bad idea. You will never
affect an executable (or at least a little only). Most interesting calls
to CreateFileA are performed by DLLs loaded by explorer at run time. So
if you hook LoadLibraryA and then in that API hook all CreateFileA in
the DLLs loaded by explorer, you'll get an awesome residency method with
almost all files hit by explorer infected. I used this residency under
BeeFree [BEF].
It's true explorer is a special case, and BeeFree was direct action vs
it due that. Again SFC is a problem ;-) And this idea is not better than
infect kernell32.dll on disk. But per-process applied to DLL may be is
a good intermediate idea. That means you must implement DLL infection
(sometimes not so trivial) and again your success is limited by SFC.
I used that idea at 99Ways [99W].
Beefree idea can be used with in-memory infection, and there are some
examples of viruses doing it. That should be a great answer to our
prays, but i wanna discard it coz with that idea the important part
is not the per-process but the in-memory infection. Check the stuff
about that done by Griyo [GRY].
At this point we have two unusual ways to apply per-process residency that
seem effective without SFC. But that apply is only about 'where', and we
must discuss also 'how'.
Let's say that per-process residence over a simple CreateFileA in a PE
EXE can be very effective. But we must change the 'how'.
Just change the chip: out aim is not a file but a folder. Ah! kewl XD
Don't spect an EXE when CreateFileA is called. Peep the path. There are
three kind of path possible in a CreateFileA: 1. it's an absolute path, 2.
it's a relative path, 3. just a filename. In 1st case we get the path (yeah,
discard the filename... i bet is not infectable), change directory to that
path and scan the folder for files to infect. In 2nd case just do the same,
and in 3rd just infect current folder because is prossible a commond dialog
changed the folder intead the app. Tadaa! You got it. Per-process is now
effective. Very effective! Just think that escenario:
1. Notepad is infected
2. User opens the readme.txt of a new installed soft
3. Notepad opens the file and our virus gets a hot path
4. The new app is infected
Pretty easy. Is true under SFC files that method will be more limited, but
you don't need to infect a protected file to rock! Every app that needs to
open a file to do something with it is able to get new paths to peep into.
In fact direct action vs windows folder is not really needed, but once
you must code routines to scan directories, include a direct action part
and let it work under system without SFC.
I used this approach under some viruses: 99Ways, Youngary [YOU], ...
To end this article i wanna comment another way i've used lately in
freebird [FRB]. Since the folder idea looks for folders, that one looks for
directory changes. It's a less effective method due it's more slow. Let's
say is a slow infector. For this approach you must get work directory
before release the control to the host. You can make this approach with
threads and not use per-process hooks at all, but it won't be so fine due
usual problems of threads running in an app that doesn't know that threads
are running ;)
Then you choose an API that is called with a moderated frequency, or related
to directory changes (not set/get directory due thos APIs won't be called
and probably not available to hook). In last instance hook ExitProcess, but
then it will be a slow-slow infector XD You won't do nothing with the API,
so a GetDC or like should rock. When the hooked API is run, just get current
directory, and if it's not the same than the stored... just infect current
directory. Store the new one to test in the future and return the control
to the host. Easy, isn't it? In that way we will infect on directory change
even when we don't know where the hell is done that directory change.
You must be very carefull with the API you choose. We don't want to overload
the app with calls to GetCurrentDirectory and checking code. And it must
be an API suitable to be called in the app process after a possible
directory change.
Last words
I hope you enjoy that article and you got the point.
I cannot end this article without a reference to the current state of the
vx scene huehehe. It's true there are so few ppl able to code this tech,
but for those few beginners that are in the good way of the win32asm...
do it per-process! XD
As you can see, per-process residency is still as kewl as Jack Qwerty got
it so many years ago. We just need to do some tunning to make it more
efficient and it is still a great alternative to the sanct sanctorum of
the global residency under win32. Keep it ring3!
Regards.
References
SFC - Win2K infection, Griyo 29A-4
Win2k.SFPDisable, Benny & Ratter 29A-6
AOC - Win32.Anvil of Crom, Bumblebee 29A-4
BEF - BeeFree, Bumblebee 29A-6
99W - 99 Ways to die, Bumblebee 29A-5
GRY - EXPLORER *in-memory* infection, Griyo 29A-4
YOU - Win32.Yonggary!, Bumblebe MTX-3
FRB - Freebird, Bumblebee 29A-7
**
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -