
Работа с escape-последовательностями на Ассемблере

Работа с escape-последовательностями на Ассемблере
Escape-последовательности, также известные как экранированные последовательности или символьные объекты, представляют собой особый метод представления символов внутри строк. В зависимости от синтаксиса языка, ими могут кодироваться не только ASCII-символы, но и вся последовательность юникода UTF-16 и даже UTF-32. В процессе компиляции или при отображении на экране каждая escape-последовательность заменяется на соответствующий ей код символа. Кроме этого, такую запись символов очень часто используют в различных обфускаторах для скриптов PHP и JavaScript с целью затруднения визуального анализа текстовых строк или кодирования исходных текстов. Escape-последовательность обычно распознается по начальному символу обратного слеша и фиксированному количеству символов, следующих за ним.
Функция раскодирования escape-последовательностей принимает в качестве параметров три значения: указатель на исходную строку, длина исходной строки и указатель на буфер для раскодированной строки. В принципе, можно было бы модифицировать функцию, чтобы в ней же определялась длина исходной строки, но пока так.
Code (Assembler) : Убрать нумерацию
- ;-----------------------------------------------------------------------
- ; Функция Escape-декодирования
- ; by ManHunter / PCL
- ; http://www.manhunter.ru
- ;-----------------------------------------------------------------------
- ; Параметры:
- ; lpData - указатель на строку
- ; dSize - длина строки
- ; lpBuff - указатель на буфер-приемник
- ;-----------------------------------------------------------------------
- proc esc_decode lpData:DWORD, dSize:DWORD, lpBuff:DWORD
- push eax ebx ecx edx edi esi
- mov ecx,[dSize]
- mov esi,[lpData]
- mov edi,[lpBuff]
- or ecx,ecx
- jz .loc_done
- .loc_decode:
- xor eax,eax
- lodsb
- ; Возможно, это закодированный символ
- cmp al,'\'
- jne .loc_store
- ; Строка заканчивается?
- cmp ecx,4
- jb .loc_store
- ; Однобайтовые юникод-скаляры \xNN
- cmp byte [esi],'x'
- jne @f
- jmp .decode_ascii
- @@:
- ; Двухбайтные юникод-скаляры \uNNNN (UTF-16)
- cmp byte [esi],'u'
- jne @f
- ; Строка заканчивается?
- cmp ecx,6
- jb .loc_store
- jmp .decode_unicode16
- @@:
- ; Четыребайтные юникод-скаляры \UNNNNNNNN (UTF-32)
- cmp byte [esi],'U'
- jne .loc_store
- ; Строка заканчивается?
- cmp ecx,10
- jb .loc_store
- jmp .decode_unicode32
- .decode_ascii:
- ; Проверить следующие символы
- push eax
- xor ebx,ebx
- xor edx,edx
- inc edx
- mov ah,3
- jmp .decode_digit
- .decode_unicode16:
- ; Проверить следующие символы
- push eax
- xor ebx,ebx
- xor edx,edx
- inc edx
- mov ah,5
- jmp .decode_digit
- .decode_unicode32:
- ; Проверить следующие символы
- push eax
- xor ebx,ebx
- xor edx,edx
- inc edx
- mov ah,9
- .decode_digit:
- shl ebx,4
- mov al,byte [esi+edx]
- cmp al,'0'
- jb .loc_skip
- cmp al,'9'
- ja @f
- sub al,'0'
- jmp .decode_digit_next
- @@:
- ; Символ в нижний регистр
- or al,20h
- cmp al,'a'
- jb .loc_skip
- cmp al,'f'
- ja .loc_skip
- sub al,'a'-10
- .decode_digit_next:
- add bl,al
- inc edx
- cmp dl,ah
- jb .decode_digit
- xchg eax,ebx
- shr ebx,8
- ; Пропустить следующие символы
- sub ecx,ebx
- add esi,ebx
- pop ebx
- jmp .loc_store
- .loc_skip:
- pop eax
- .loc_store:
- cmp eax,0FFh
- jbe .loc_store_byte
- cmp eax,0FFFFh
- jbe .loc_store_word
- .loc_store_dword:
- ; Записать раскодированный юникодный символ в строку
- stosd
- jmp @f
- .loc_store_word:
- ; Записать раскодированный юникодный символ в строку
- stosw
- jmp @f
- .loc_store_byte:
- ; Записать раскодированный символ в строку
- stosb
- @@:
- dec ecx
- or ecx,ecx
- jnz .loc_decode
- .loc_done:
- ; Символ конца строки
- mov al,0
- stosb
- pop esi edi edx ecx ebx eax
- ret
- endp
Функция преобразования строки в escape-последовательность принимает три параметра: указатель на исходную строку, длина исходной строки и указатель на буфер для закодированной строки.
Code (Assembler) : Убрать нумерацию
- ;-----------------------------------------------------------------------
- ; Функция Escape-кодирования
- ; by ManHunter / PCL
- ; http://www.manhunter.ru
- ;-----------------------------------------------------------------------
- ; Параметры:
- ; lpData - указатель на строку
- ; dSize - длина строки
- ; lpBuff - указатель на буфер-приемник
- ;-----------------------------------------------------------------------
- proc esc_encode lpData:DWORD, dSize:DWORD, lpBuff:DWORD
- push eax ecx edi esi
- mov ecx,[dSize]
- mov esi,[lpData]
- mov edi,[lpBuff]
- or ecx,ecx
- jz .loc_done
- .loc_encode:
- ; Префикс однобайтового скаляра
- mov ax,'\x'
- stosw
- ; Загрузить символ из строки
- lodsb
- ; Перевести байт в HEX-строку
- movzx eax,al
- ror eax,4
- and al,0Fh
- daa
- add al,0F0h
- adc al,40h
- stosb
- shr eax,28
- and al,0Fh
- daa
- add al,0F0h
- adc al,40h
- stosb
- loop .loc_encode
- .loc_done:
- ; Символ конца строки
- mov al,0
- stosb
- pop esi edi ecx eax
- ret
- endp
В приложении примеры двух программ с исходными текстами, демонстрирующие функции escape-кодирования и декодирования текстовых строк.
Просмотров: 5673 | Комментариев: 1
Метки: Assembler, полезные функции

Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
Игорь
(12.07.2015 в 08:38):
Спасибо

Добавить комментарий
Заполните форму для добавления комментария
