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 **