Про загадку с прошлой недели

Nov 23, 2010 18:46

Как некоторые правильно догадались, это был исполняемый файл программы, которая делает UUDECODE (раскодирует двоичный файл, который с помощью программы UUENCODE был закодирован для пересылки в текстовом письме). Детище тех времен, когда аттачи в письмах отсутствовали и двоичные файлы специальным образом кодировались для пересылки.

Фишка этой программы, написанной мной в 93 году, является использование только печатных символов в коде программы. Ее можно просто вырезать в любом редакторе, сохранить в файл с расширением .com и запустить. Программа замечательно выдерживает вставление пустых строк и пробелов в концах строк (и даже в середине строк, но только не в первой). В общем - при любом насилии при пересылке она все равно запустится.

Зачем это надо? Ну так я намекнул на проблему курицы и яйца: чтобы послать человеку двоичный файл, его надо закодировать, а у получателя должен быть раскодировщик. А раскодировщика у него нет, интернетов в то время народ не знал, так что раскодировщик надо послать в письме :)



Тут только стартовая часть этой программы, обеспечивающая наличие только печатных символов и устойчивость к добавлению мусора. Она раскодирует хвост, который к ней приклеен и запускает его. В хвосте может быть что угодно, но по смыслу - uudecode.

Поскольку программа патчит и декодирует сама себя, в комплекте была и программа для предварительного патча и кодирования откомпилированного кода. Но это уже не так прикольно, так что можно и опустить.

Принципиальным является количество байт до метки prgstart, поскольку туда нельзя вставлять переводы строк, а выходить за 75 символов в строке не хотелось.

oxor macro offs, reg
xor [bp - 222 + offset offs - offset start + 100h], reg
endm

bxor macro offs, reg
xor [bp - 256 + offset offs - offset start + 100h], reg
endm

code segment
assume cs:code, ds:code
org 100h
start:
pop ax
push ax
pop cx
sub ax, 2122h ; AX = DEDE
push bx
push ax
inc sp
pop bp ; BP = E0
sub ax, 5E5Eh ; AX = 8080
push ax
pop dx ; DX = 8080
sub al, 40h
push ax
pop bx ; BL = 40

oxor __1, dx
oxor __1+3, bl
oxor cloop, dx
oxor __2+1, dl
oxor __3+1, dl

sub ax, [bx+35] ; NOPs :)
and ax, [bp+55]
cmp al, [bp+63]
xor al, [bx+93]

inc cx
push cx
push cx
inc sp
pop bp

__1: cld ; FC
mov si, offset prgstart ; BE nn 01
push si ; 56
pop di ; 5F

cloop:
lodsb ; AC
stosb ; AA
cmp al, '!' ; 3C 21
__2: ja cloop ; 77 FA
dec di ; 4F
__3: jb cloop ; 72 F7

prgstart:
push si

bxor _1, dl
bxor _1+2, bl
bxor floop, dl
bxor _2, dx
bxor _3-1, dx
bxor _4+1, dx

cmp ax, [bx+35] ; NOPs :)
xor ax, [bp+55]
sub al, [si+43]
and al, [di+39]
cmp al, [bp+63]

_1: mov si, offset ncode ; BE nn 01
push si ; 56
pop di ; 5F

inc cx ; 41
inc cx ; 41
inc cx ; 41
floop:
lodsw ; AD
sub ax, ':W' ; 2D 23 23
_2: shl ah, cl ; D2 E4
xor al, ah ; 32 C4
_3: stosb ; AA
cmp al, '~' ; 3C 7E
_4: jne floop ; 75 F3

ncode = $

pop si

dec di
push di
xor bx, bx
mov cx, bx
??1:
lodsb
sub al, ' '
jbe ??1
and al, 3Fh
jz program
mov dl, al
??2:
lodsb
sub al, ' '
jbe ??2
and al, 3Fh
cbw
xchg ah, al
sub cl, 2
ror ax, cl
or bx, ax
add cl, 8
cmp cl, 8
jl ??2
mov al, bh
stosb
mov bh, bl
mov bl, 0
sub cl, 8
dec dl
jnz ??2
jmp ??1

program:

code ends
end start

Историческое

Previous post Next post
Up