VX Heaven

Library Collection Sources Engines Constructors Simulators Utilities Links Forum

AVP 2.2 naked

Mister Sandman
29a [1]
December 1996

[Back to index] [Comments]

We all know AVP is the best antivirus in the world, no doubt about it. The most complete, the most reliable, above all, the most professional, but... is it also the safest? the answer is no :)

We also know there's no antivirus invulnerable to a good codefuck. What we'll do with this report is to show some -until know- secret holes in AVP, and how to exploit them in order to write new retro functions.


AVP uses a detection scheme based on a sort of antiviral databases, which contain the necessary data (search strings, decryption routines, cleaning info...) for detecting and disinfecting viruses. They're predefined, and these are their names:

AVP's heuristics (code analyzer)
Decompression routines (ZIP, ARJ, RAR...)
AVP's kernel database
Macro viruses detection
Trojan detection
Unpacking routines (PkLite, Diet...)
Main base, with all the viruses
Weekly updates

All these databases are defined in AVP.SET, which is the file AVP reads before loading the them. Here is where AVP problems start... there's a good point to attack its kernel, because it contains all the necessary info about how to use the rest of the antiviral databases. Without it, AVP can't detect any virus, because it doesn't know how to interpret the data stored there... it's enough to comment it out from AVP.SET by means of a semicolon in order to knock out AVP; even if KERNEL.AVB is loaded b4 the rest of the databases, in other than first position.

It would be enough to have a simple resident program (which might be a virus, of course) which would intercept function 4bh of int 21h and test for AVP.EXE; when being this file executed, it'd only have to open and modify AVP.SET by replacing the first character (KERNEL.AVB's "K") with a semicolon (;). Being executed in this way, AVP would detect *NOTHING*.

Another interesting method is to change the DX value when AVP's about to read AVP.SET; instead of the original value (0004), we might enter 0010, so it would point to the second line of AVP.SET, skipping KERNEL.AVB.

As a last thing, have a look at Tcp's AVP-Aids and at my AntiCARO... they both fool AVP in order to exploit some bugs which favour the spreading of our viruses :)

Of course, due to the basereading system AVP uses, we can fuck the heuristic scanning (CA.AVB), the main virus database (V_YYMMDD.AVB), etc.


Another head-breaking problem for AVP. We're still trying to avoid the AVP detection, this time in a less abrupt method, which consists on modifying the executable itself in memory. Intercepting the open and read functions, after some tracing, we reach a key point: a couple of conditional jumps, with which AVP decides whether a file is infected or not. Let's have a look at them:


2B9C:00D3 55		PUSH BP
2B9C:00D6 56		PUSH SI
2B9C:00D7 8B760A 	MOV SI,[BP+0A]
2B9C:00DA C45E06 	LES BX,[BP+06]
2B9C:00DD 26837F0A00	CMP Word Ptr ES:[BX+0A],+00
2B9C:00E2 7506		JNE 00EA <- First jump --------.
2B9C:00E4 33D2		XOR DX,DX                      |
2B9C:00E6 33C0		XOR AX,AX                      |
2B9C:00E8 EB53		JMP 013D                       |
2B9C:00EA C45E06	LES BX,[BP+06]                 |
2B9C:00ED 26C45F19	LES BX,ES:[BX+19]              |
2B9C:00F1 8BC6		MOV AX,SI                      |
2B9C:00F3 D1E0		SHL AX,1                       |
2B9C:00F5 03D8		ADD BX,AX                      |
2B9C:00F7 26833F00	CMP Word Ptr ES:[BX],+00       |
2B9C:00FB 742A		JZ 0127 <- Second jump --------'
2B9C:00FD 33C0		XOR AX,AX
2B9C:00FF 50		PUSH AX

Ok... it's rather obvious that we have to modify the first jump, but... ohhh, little fucking surprise; AVP stops its scanning and displays the following message:

General protection fault at ED22:050B ;-)

Hoho... watch out... the old russian bearded beerdrinker has implemented a protection routine in its code! and i recognize that i had a lot of fun when i saw that winking smiley... ok, one point for Kaspersky :)

Nevertheless, if we 'touch' the second jump (74 -> 75, so the jz turns into a jnz), there's no stupid message and AVP's detection is completely blowed out... it will continue scanning without noticing any infection... Mister Sandman scores and ties ;)

Anyway, if you don't wanna spend so many time (five minutes :) tracing thru AVP's code, just use this other way to reach the same result by following a simpler method. Your weapon will be GameTools or any other debugger able to intercept functions on the fly. Start intercepting every open with 3dh/int 21h; then intercept the file read (3fh/int 21h), and start tracing AVP's code as soon as it gets intercepted:


1610:0C14 B43F		MOV AH,3F <- intercepted function
1610:0C16 8B5E06	MOV BX,[BP+06]
1610:0C19 8B4E0C	MOV CX,[BP+0C]
1610:0C1C C55608	LDS DX,[BP+08]
1610:0C1F CD21		INT 21
1610:0C21 1F		POP DS
1610:0C22 7202		JB 0C26 [...]

Once you've got this, just change b43f for b43c, so AVP will close the file instead of reading from it... the result will be that, as usual, AVP won't detect any virus. This method is a bit bully, but you'll save some time and the result will be the same :)

Oh, btw... i was gonna forget it... Mister Sandman, 2; Kaspersky, 1 ;-P


Another of the resources in order to fuck AVP is using trojans, albeit from here on, imagination is worth it. The twister ideas you have, the better and more original results you get ;)

These are two of the ideas i've practised (i can't include their code as it's destructive and goes against the rules of 29A) :)


Just note one more. In the AV community (sect?), the ratio between the stupidity of the sanity check is directly proportional with the stupidity of its author. And Kaspersky is part of that AV community, of course :)

As he ain't a dork at all, the sanity check is quite original and effective. It just consists on a simple comparison of the address of the original entry point with the actual one.

What does this mean? oh, well... just stop and think for a while about viruses which don't modify the entry point of the file they infect ;)

As you can see, all it takes is some knowledge on how AVP behaves and some imagination to exploit its bugs. I stopped commenting the AVP.EXE disassembly, as AVP 3.0 will be released very soon, and its kernel has been written in ASM, so it will be much easier to explore than the code of previous versions, which was written in C++ <g>, and be sure that i'll bring you more news and bugs on it in 29A#2 ;)

				Mister Sandman,
				bring me a dream.
By accessing, viewing, downloading or otherwise using this content you agree to be bound by the Terms of Use! aka