вступление
Прежде всего хочется сказать что эту фишку я узнал от Яна, который
отложил ее реализацию в долгий ящик.
а зачем это вообще нужно?
Стек шифровка немного [!] усложняет анализ кода, такие расшифровщики
можно использовать в качестве антиевристических приемов (например против
dr. web'а). Главным недостатком таких декрипторов, как и рандомеров,
являются постоянные учаски кода, которые являются потенциальными
сигнатурами.
стек (для тех кто еще неосвоил что это такое)
Для хранения временных данных служит область памяти называемая стеком.
Для адресации сегмента стека используется регистр ss. Регистр sp является
указателем стека, в нем содержится адрес последнего записанного в стек
числа.
принципы написания стек_декрипторов/крипторов
Заносим декриптор в стек, но нужно помнить что последнее записанное в
стек значение будет считано первым, поэтому заносить декриптор нужно
задом наперед. После шифровки (или расшифровки) управление должно
передаться на определенный участок кода:
jmp far xxxx:yyyy
где xxxx - cs, yyyy - оффсет участка на который нужно передать
управление. Далее из стека изымается декриптор.
В качестве иллюстрации (смотри ниже) к статье была написана небольшая
программа, которая сначала шифрует кусок кода, а затем расшифровывает
его и передает ему управление.
----[scrypt.asm]-----[start]---------------------------------------------
; stack_encryptor/decryptor
;
; original idea by Janusz
; designed november 29, 1999 by mongoose
.model tiny
.code
org 100h
begin: in al,40h ; generate key
mov byte ptr [key+1],al ; move key to decryptor
call crypt ; crypt code
call decrypt ; decrypt code
code: mov ah,9
mov dx,offset message
int 21h
sub ax,ax
int 16h
mov ax,4c00h
int 21h
message db 'testing...ok$'
;------------------------------------------------------------------------
; криптор и декриптор
;------------------------------------------------------------------------
crypt:
decrypt: mov word ptr cs:[ret_offset],offset ret_control
mov word ptr cs:[ret_segment],cs
;------------------------------------------------------------------------
; загружаем декриптор в стек
;------------------------------------------------------------------------
mov si,offset end_of_code
mov cx,(end_of_code-sceleton+2)/2
move_to_stack: push word ptr [si]
dec si
dec si
loop move_to_stack
mov bp,sp
push ss
push bp
retf
;------------------------------------------------------------------------
; очищаем стек
;------------------------------------------------------------------------
ret_control: add sp,((end_of_code-sceleton+2)/2)*2
ret
;------------------------------------------------------------------------
; скелет расшифровщика заносимого в стек
;------------------------------------------------------------------------
sceleton: mov bp,offset code
key: mov dl,11
mov cx,(crypt-code)
xor_loop: xor byte ptr [bp],dl
inc bp
loop xor_loop
return: db 0eah
ret_offset dw ?
ret_segment dw ?
db ?
end_of_code label byte
end begin
----[scrypt.asm]-----[end]-----------------------------------------------
idea by Janusz
code & article by mongoose, misdirected youth
|