Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ; ================
- ; == About this ==
- ; ================
- ; This is an assembly file to generate the EICAR AntiVirus Test File.
- ; Assembling this triggers your anti virus, so don't do it.
- ; The file itself is not dangerous and servers as a safe AV demo.
- ; The compiled assembly uses only instructions that result in the byte range 0x1F < x < 0x80
- ; To achieve this, it uses a lot of XOR instructions because MOV is outside of ASCII
- ; moving data to and from registers is done via PUSH/POP for the same reason.
- ; ================
- ; == Assembling ==
- ; ================
- ; Depending on your assembler, the settings differ. Flat assembler (FASM) doesn't has any of them.
- ; 1. Disable all optimizations
- ; 2. Set Target instruction set to 16 bit x86 (Real Mode)
- ; 3. Set OS Target to DOS
- ; ===============
- ; == Verifying ==
- ; ===============
- ; If properly done, the output can be opened in any text editor and should read exactly:
- ; X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*
- ; No other bytes should be in the file.
- ; =============
- ; == Running ==
- ; =============
- ; Your anti virus should trigger as soon as you assemble.
- ; To actually run the binary, you have to disable your anti virus.
- ; 64 bit Windows has no support for 16 bit executables anymore.
- ; To run under 64 bit Windows, use a DOS emulator like DOSBox
- ; =======================
- ; == DOS Memory Layout ==
- ; =======================
- org 0100h ; Make this a DOS .com executable
- ; The first 0xFF bytes are used by DOS to store information for the application.
- ; An example would be the command line string to extract the arguments from.
- ; This is the reason why .com files start at offset 0x100
- ; MS-DOS .com executables run under 16 bit mode and thus have to fit into 64K of memory.
- ; This binary makes usage of the stack to avoid the MOV instruction.
- ; The stack pointer is initialized by DOS to point to the end of memory (0xFFFE to fit a WORD).
- ; Stack, data and code share the same unprotected memory page,
- ; which means that if you are pushing too much onto the stack it will eventually overwrite code.
- ; It also means that the stack size is primarily determined by how much memory you use for code and data.
- ; There are at most 2 values on the stack and no memory for data storage is needed,
- ; therefore only 4 bytes of memory need to be free of the 64k page for this application.
- ; ===================
- ; == Start Of Code ==
- ; ===================
- ; Get 0x214F on the stack
- pop ax ; AX = 0 because DOS initialized the stack for us already and the memory is set to zero.
- xor ax,214Fh ; xor with zero is the same as using mov but falls into ASCII range
- push ax
- ; Note: The reason we can try to get a value from an empty stack is because in x86 it wraps around
- ; Get address of instruction to be changed and move it from ax into bx
- and ax,4140h ; AX = 0x0140 because 0x214F was still in there: 0x214F & 0x4140 = 0x140
- push ax
- pop bx
- ; Get address location of printable string into dx. The DOS print call expects it to be there
- xor al,5Ch ; AX = 0x011C because we only use xor on the lower byte of the register (AL)
- push ax
- pop dx
- ; Get the first value (0x214F) back from the stack, modify it, and put it into the SI register
- pop ax
- xor ax,2834h ; AX = 0x097B, AH = 0x09 -> DOS INT21 Service: "Display String"
- push ax
- pop si
- ; We don't have to worry about AL, because DOS INT21 only cares for AH.
- ; Self modify code: change instruction at 0x0140 (second last instruction of this code) to "int 21h"
- sub [bx],si ; [0x0140] = 0x2B48 - 0x097B = 0x21CD -> 0x21 = "DOS print string call", 0xCD = "int instruction"
- ; This also overwrites the first byte of the last instruction
- ; Self modify code: change instruction at 0x0142 (last two bytes of last instruction) to "int 20h"
- inc bx
- inc bx ; BX = 0x0142
- sub [bx],si ; [0x0142] = 0x2A48 - 0x097B = 0x20CD -> 0x20 = DOS exit call, 0xCD = "int instruction"
- ; Jump over the string to the (meanwhile) changed Instruction at 0x0140.
- jge 0140h ; "jge" is the same as "jnl"
- ; Because of the subtraction done before this jump, the required flags (S+Z) are set as needed.
- ; This jump is always performed.
- ; EICAR string in the middle of the file.
- ; The '$' is used by the DOS print call to signal the end of a string, as opposed to the more common '\0' in C.
- ; The content of the string can be freely changed as long as the length stays the same.
- ; To keep the length, the string can be padded with '$'
- ; If you change the string you likely will no longer trigger any anti virus response.
- DB "EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$"
- ; These two instructions are here to occupy 1+3 bytes
- dec ax
- sub cx,[bx+si+2Ah]
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement