Introduction
In the old goodtimes there were nothing easier as infecting COM file.
But the Microsoft went to market with his Windoze 9x series of betas.
This has changed some COM files and near the EOF we started to see string
'ENUNS' followed by word with various value. This is apparently some
kind of checksum or other security shit. Many virus coder solved the
this problem simply by avoiding the infection of such a modified COM
files.
Research part
But as we all know, Microsoft is lame company and its programmers
are morons. So let's take a closer look what does such a ENUNS file
in action. We will pick up a handy and short file from directory
C:\WINDOWS\COMMAND - file choice.com
If we 'll play a little bit with hex editor and we 'll add some extra bytes to the end of the file, after running CHOICE.COM without any command line parameters, we will see
[ , ]?
instead of the usual
[Y,N]?
Let's start debuging this file. After couple of jumps and calls we land in following code
cs:0B27 1E push ds
cs:0B28 06 push es
cs:0B29 1F pop ds
cs:0B2A 8B D7 mov dx, di
cs:0B2C 83 C2 03 add dx, 3
cs:0B2F B8 00 3D mov ax, 3D00h
cs:0B32 CD 21 int 21h
The code above opens the file which is run (choice.com)
cs:0B34 1F pop ds
cs:0B35 72 3C jb error
cs:0B37 8B D8 mov bx, ax
cs:0B39 89 1E 77 05 mov handle, bx
cs:0B3D E8 3F 00 call test_ENUNS
cs:0B40 9C pushf
cs:0B41 B8 00 3E mov ax, 3E00h
cs:0B44 8B 1E 77 05 mov bx, handle
cs:0B48 CD 21 int 21h
cs:0B4A 9D popf
cs:0B4B 72 2C jb loc_0_B79
Call to the test_ENUNS seem to be quit important. Closer look shows what this procedure does:
cs:0B7F 06 push es
cs:0B80 33 C9 xor cx, cx
cs:0B82 33 D2 xor dx, dx
cs:0B84 83 EA 07 sub dx, 7
cs:0B87 83 D9 00 sbb cx, 0
cs:0B8A B8 02 42 mov ax, 4202h
cs:0B8D CD 21 int 21h
cs:0B8F B9 07 00 mov cx, 7
cs:0B92 03 C1 add ax, cx
cs:0B94 83 D2 00 adc dx, 0
cs:0B97 A3 80 05 mov size_lo, ax
cs:0B9A 89 16 82 05 mov size_hi, dx
cs:0B9E B8 00 3F mov ax, 3F00h
cs:0BA1 8D 16 92 05 lea dx, ds:592h
cs:0BA5 CD 21 int 21h
cs:0BA7 72 1A jb bad_handle
The routine seek to EOF-7 and read last 7 bytes of the file to some buffer. Filesize is saved on this occasion.
cs:0BA9 81 3E 95 05 4E 53cmp word_0_595, 'SN'
cs:0BAF 75 12 jnz bad_handle
Location EOF-4 is checked for presence of string 'NS'.
cs:0BB1 A1 97 05 mov ax, checksum
cs:0BB4 8B 16 80 05 mov dx, size_lo
cs:0BB8 8B 0E 82 05 mov cx, size_hi
cs:0BBC 2B D0 sub dx, ax
cs:0BBE 83 D9 00 sbb cx, 0
cs:0C07 89 0E 80 05 mov size_lo, cx
cs:0C0B 89 16 82 05 mov size_hi, dx
Word at location EOF-2 is subtracted from the file size and result is stored.
cs:0C0F BE 01 00 mov si, 1
cs:0C12 E8 16 00 call sub_0_C2B
cs:0C15 73 0F jnb loc_0_C26
cs:0C17 8B 0E 80 05 mov cx, size_lo
cs:0C1B 8B 16 82 05 mov dx, size_hi
cs:0C1F 33 F6 xor si, si
cs:0C21 E8 07 00 call sub_0_C2B
cs:0C24 72 03 jb loc_0_C29
cs:0C26 E8 7F 00 call sub_0_CA8
cs:0C29 07 pop es
cs:0C2A C3 retn
From our (virus) point of the view is decising the call to cs:0xC2B.
cs:0C2B 51 push cx
cs:0C2C 52 push dx
cs:0C2D B8 00 42 mov ax, 4200h
cs:0C30 CD 21 int 21h
File pointer is moved to the location (filesize-(word at EOF-2))
cs:0C32 B9 10 00 mov cx, 10h
cs:0C35 B4 3F mov ah, 3Fh
cs:0C37 8D 16 92 05 lea dx, ds:592h
cs:0C3B CD 21 int 21h
cs:0C3D 72 37 jb loc_0_C76
cs:0C3F 3B C1 cmp ax, cx
cs:0C41 75 33 jnz loc_0_C76
Read form inside the file is performed.
cs:0C43 A1 9D 05 mov ax, word_0_59D
cs:0C46 3D 4E 53 cmp ax, 'SN'
cs:0C49 75 2B jnz loc_0_C76
Location inside the file is checked for presence of string 'NS'. This is what the program does with the magic 'ENUNS' shit. Quit lame and interesting at the same time. Well as we know what the does, we should try to create some workaround.
What do we need?
There are two requests for elegant solution of the problem
Solution
We take common non-overwriting appending COM infector. If we choose
some ENUNSed targed and we will infect it in normal way, the proggy
with virus on its end will have no 'NS' at EOF-4. In the very rare
case it will have 'NS' there, word at EOF-2 sends the file pointer
somewhere in deep space 9 and the next check will fail. Therefore
solution of the problem is
As we need to have at least 'NS' at EOF-4, in the line of our elegant solution we will add there 'ENUNS' string. Then we need to adapt the word at EOF-2 in such a way it will point to the location it pointed before the file was infected.
The word located at EOF-2 is subtracted from file size - it could be expressed as follows
uninfected situation:
but when the file is infected the situation is
Resulting pointer is now "somewhat" incorrect from our viral point of the view. This dramatic equation is easy to solve just by moving some shit from left to right side of the equation...
note: under the term "added code" you should understand our 2nd 'ENUNS??' string.
Dear readers, the solution for the ENUNS problem is just to copy the last 7 bytes from the target file to the end of the virus body with only one change - to the value of last word in the file we simply add the size of all appended code including our duplicite ENUNS?? string.
And here comes the demonstration of the above mentioned solution.