; ================ ; == 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]
Comments
0 B
|👍
/👎
0 B
|👍
/👎
0 B
|👍
/👎