|
This is the SVDL language in BNF modified format (I use parameter for specify the dimension of a argument):
svdl ::= CODE 01; block block ::= instruction IF bool_esp + string instruction(i) ::= { IF bool_esp - | identifier(i) := ext_esp ; } bool_esp ::= ( identifier(i) | read(i) ) ( < | <= | = | > | >= | <> ) ( identifier(i) | constant(i) | string(i) ) identifier(byte) ::= (( | | @ ) letter % ) | letter # identifier(word) ::= letter % letter ::= A | ... | Z constant(byte) ::= ' char ' | number(byte) constant(word) ::= ' char char ' | number(word) read(word >word) ::= [ number(byte) +] | [ identifier +] read(byte) ::= [ number(byte) ] | [ identifier ] | [_ number(byte)] | [_ identifier ] | ext_esp(byte) ::= ext_esp_(byte) ext_esp(word) ::= ext_esp_(word) | TIME | DATE | ATTR| DIML | DIMH ext_esp_(i) ::= read(i) | INC | DEC | identifier(i) | identifier(i) ( ADC | ADD | AND | DIV | IDIV | IMUL | MUL | OR | ROL | ROR | SAR | SBB | SHL | SAL | SHR | SUB | XOR ) identifier(i) string ::= ' { char } ' char ::= an ascii char number(i) ::= hex number of type i comment ::= { string }
The SVDL is a language that is based on machine 8086 language. A SVDL variable is
simple an alphabet letter: A, B, ... Z.
Due to the machine language corresponding, we must always specify it's dimension:
X# a byte variable X% a word variableSo, X# must be think like BL register, while X% must be think like AX register. But in 8086, AX may be divided in AL and AH, so in SVDL a word variable can be divided too:
|X% a low byte of word variable @X% a high byte of word variableAt one variable we can assign other thing of the same type like:
C#:=45; an byte hex number C#:=|B%; the low part of word variable D%:= A% XOR B%; an xor of two word variable X#:='d'; a charNote that a word assignment is like in 8086 endian type: low, high.
C#:=[12]; a disk byte read from position 12h of file C%:=[12+]; a disk bytes read from position 12h of file C#:=[_12h]; a disk byte read from end position 12h of file C#:=[A#]; a disk byte read from position given by A# of file C#:=[_A#]; a disk byte read from end position given by A# of fileNote that a read with word variables has two implementation: if variables is from A to L the jump is up to 2 at pow of 16, while if they are from M to Z the jump is up to 2 at pow of 32, because:
C#:=[M%]; the jump is to the 32 bit number given by N%:M%This is useful for file that has a size upper than 64KB.
Other special instruction can be assigned to a variables:
C%:=DATE; gives the DOS file date C%:=DIML; gives the low dimension of the file C%:=DIMH; gives the high dimension of the file C%:=ATTR; gives the DOS attribute of the file C%:=TIME; gives the DOS file timeThe SVDL has a particular implementation of a IF instruction: a IF without the ELSE part. In fact, if one IF give false, this means that the virus don't have infect this file, so the SVDL program terminate. In a IF instruction we can compare variables with other variables (of the same type), or information from file:
IF A%>=B% - compares if A is greater or equal that B IF [00+]='string' - compares if file from position 0 has stringIf a IF has a + instead of - this means that a true comparison terminate the SVDL programs showing the string after +:
IF A#=@B% + 'virus found'Note that a SVDL programs start with the instruction CODE. CODE specify the actual version of SVDL.
Here there's the SVDL for detecting the Dark Avenger virus in an EXE program:
CODE 01; IF [00+]='ZM' - A%:=[08+]; {header paragraphs} B%:=[16+]; {initial CS} A%:=A% ADD B%; D%:=10; Z%:=0; A%:=A% MUL D%; B%:=[14+]; {initial IP} A%:=A% ADD B%; C%:=0; Z%:=Z% ADC C%; {address Z%:A%} D%:=68; A%:=A% SUB D%; E%:=Z% SBB C%; {virus moves pointer to E%:A%, not needed here} F%:=708; A%:=A% ADD F%; E%:=E% ADC C%; L%:=DIML; H%:=DIMH; IF L%=A% - IF H%=E% + 'DarkAvenger (EXE)' {the virus now compares if there's it's body from the position of file pointer}The below is the SVDL program that detects the FLIP virus. Flip use a little sophisticated encryptios technique to mask itself.
CODE 01; IF [_47]=0E {PUSH CS } - IF [_46]=0BB {MOV BX,..} - IF [_43]=1F {POP DS } - IF [_42]=0B9 {MOV CX,..} - IF [_3F]=0B2 {MOV DL,..} - IF [_3D]=81 {ADD ... } - IF [_3C]=0C1 {... CX,..} - IF [_39]=0EB {JMP ... } - A#:=[_38]; B#:=37; B#:=B# SUB A#; IF [_B#]=00 {ADD ...} - B#:=DEC; IF [_B#]=97 {... [BX],DL} - C#:=3; B#:=B# SUB C#; IF [_B#]=43 {INC BX} - B#:=DEC; IF [_B#]=0EB {JMP ...} - B#:=DEC; A#:=[_B#]; B#:=DEC; B#:=B# SUB A#; IF [_B#]=0E2 {LOOP ...} - B#:=DEC; B#:=DEC; IF [_B#]=0E9 {JMP ...} + 'FLIP (COM-EXE)'
PC | Tognon Stefano programs |