Residence in Windows viruses at Ring-3 level
Billy Belcebu/DDT

Here goes a brief introduction to one of the most asked topics in the virus scene nowadays, and one of the most interesting i think. I'm not trying to say that this little tutorial will make the job for you... Just the opposite because here i'll give you ideas, and almost all this article is theorical. Don't worry, there's some code, too. As i said in my "Heuristic Technology" article... "the experience is the mother of the science".

% Introduction %

When i was learning about residence (and asking a lot of people about this matter), i realized that there weren't any tutorials about this matter, and all the people i asked used completly different ways to do it. Here i will only explain the two ways i found more interesting : The Win95 global residence (by nIgr0) and the per-process residence. Well, i recognise that there are a lot of ways for go resident under Win32 enviroments, but anyway i only commented this two way because they are the simplest ones under my viewpoint

% Win9X Global Residence (nIgr0 method) %

The first time i saw this method was in Win95.K32 virus, made by my friend nIgr0 (the same that contributed to this magazine with his great Lord of the Rings). The objective of this residence is quite simple : copy the virus body to a hole, pass the control to the virus in that hole, hook APIs globally (modifying directly its code), and infect programs. I must say that this method WON'T work under WinNT, and you will see soon why.

Well, as we all know, in Win9X (Win95, Win98) the kernel memory is read-only So we must find a way for make it to allow writes, as we want to write in it right?. Well, we can do it physically, but it will leave signs of our virus, and we don't want this. But... what if we unprotect in memory only the pages we need to? This is the solution. Then you wonder how. Well, we have, in the great VxDCALL 0 a function for do that, called _PageModifyPermissions. Let's see how to get VxDCALL 0 address:

                    mov     eax,0BFF70000h          ; Put in EAX harcoded kernel
                    mov     ebx,dword ptr [eax+3Ch] ; Move ptr to begin of PE
                    add     ebx,eax                 ; Align it
                    cmp     word ptr [ebx],"EP"     ; Is it a PE?
                    jnz     Not_PE                  ; Nope, go away
                    mov     ebx,[ebx+78h]           ; Go to export table
                    lea     ebx,[ebx+1Ch+eax]       ; Go to address table
                    mov     ebx,[ebx]               ; And put its address in EBX
                    add     eax,[eax+ebx]           ; And we have VxDCALL0 in EAX

Simple, huh? :) Better save EAX now in a safe place, because we have now our wanted VxDCALL0 ;) Well, let's see how to call _PageModifyPermissions, as nIgr0 does.

                    push    020060000h              ; New page attributes (writ.)
                    push    000000000h              ; uninteresting
                    push    000000001h              ; Number of pages
                    push    <page_to_unprotect>     ; page
                    push    00001000Dh              ; VxD 1 service D
                    call    <VxDCALL0>

Well, we need a system hole where move the virus body, right? I only know the existence of one (forgive me, i'm lame :P), located in 0BFF70400h, just after the PE header in memory. This memory zone is write protected, so you'll must unprotect that before do anything. Well, then, we you have done that, it's time to move the virus body to that zone. And you know how to do that :) A simple MOVSB loop will be enough. Now we give the control to the resident copy of the virus. We are now resident... charming, isn't it? ;)

Well, but now it's time to make something... if we stay as we are now, we are just making nothing. We need to hook an API. As we are a global resident let's hook the APIs radically (i.e. globally ;) How? I think you are enough intelligent, and you had made a routine for catch the APIs we need, right? Just use the offset of the API(s) you liked more, and put it in memory into read-write mode, with the routine shown below. Just overwrite the first bytes in the API code with a routine that brings the control to your API handler (of course, save the overwritten bytes goddamit! ;). That API handler must have the properly code for infect the program that request/is involved in its use... and that's all folks.

% Win9X Global Residence (GriYo's method) %

No, no, no. I won't explain his method. Why? Heh, there is a very complete article about it, wrote by him in 29A#3, so go and download it if you still don't have that jewel. Hrm, in a very short brief comment, what it does is to "hook" the VxDCALL0 (heh, you remember?) for all file access, so it acts as the likeness of a normal TSR DOS infector, but in Win9X (read HPS virus).

% Per-Process Residence %

Well, this is the only known way i know for make Win32 viruses to be resident. Yes, you have read Win32 and not Win9X. This is because this method can work also under WinNT. First of all you must know what a process is. The thing that surprised me more is that the people that is beginning in the windows programming know what this is, and know what this method is, but they ussually don't know his name. Well, when we execute a Windows application, that is a process :) Very easy to understand. And what does this residence way? First of all we must allocate memory, for put virus body there, but this memory is from the own process that we are executing. So, we allocate some memory that the system gives to the process. It could be made by using the API "VirtualAlloc". But... what for hook APIs? Well, the most useful solution that comes to my mind now is to change the API's addresses in the import table. It is, under my viewpoint, the only possible way. As the import could be written, this is more easy, and we don't need the help of any function of the VxDCALL0...

But the weak point of this kinda residence is here too... as we look in the import we can only work with the imported functions, and the infection rate depends higly of what file we have infected. For example, if we infect the CMD.EXE of WinNT, and we have a handler for FindFirstFile(A/W) and FindNextFile(A/W), that infects all the files that are found using that APIs That makes our virii very infectious, mainly because that APIs're higly used when we make a DIR command under WinNT. Anyway, the Per-Process method is very weak if we don't make the virus that uses that method to have any other ways for make it more infectious, such as in Win32.Cabanas, a runtime part. Well, we make that runtime part to infect each time some files in the \WINDOWS and \WINDOWS\SYSTEM directories. Another good choice is, as i said before in the example with CMD.EXE, hit that very special files directly in the first infection of a system...

Well, i explained sum theory. Just see what viruses do and understand it.

Billy Belcebu,
mass killer and ass kicker.