Blog. Just Blog

Быстрый поиск

Введите фрагмент названия статьи для поиска

Преобразование символических ссылок в путь к файлу

08.02.2019 | Категория: Образ мышления: Assembler | Автор: ManHunter
"По следам наших публикаций". В одной из недавних статей я использовал код для преобразования символических ссылок на файл в привычный путь. Немного поразмыслив, я решил доработать его до полноценной универсальной функции, которая будет приводить любые "кривые" пути и символические ссылки к человекопонятному виду. Функция разворачивает переменные окружения, исправляет обратные слеши, а также обрабатывает символические ссылки вида "\SystemRoot\explorer.exe", "\Device\HarddiskVolume1\WINDOWS\win.ini", "\??\E:\asm\" и "file:///C:/Windows/explorer.exe". Поддерживаются файлы, каталоги и диски.
  1. ;------------------------------------------------------------
  2. ; Функция нормализации пути к файлу или каталогу
  3. ;------------------------------------------------------------
  4. ; Параметры:
  5. ;   lpPath - указатель на исходный путь
  6. ;   lpNorm - указатель на строку с нормализованным путем
  7. ; На выходе:
  8. ;   EAX = 1 - путь успешно нормализован
  9. ;   EAX = 0 - путь не найден
  10. ;------------------------------------------------------------
  11. proc normalize_path lpPath:DWORD,lpNorm:DWORD
  12.         _OBJ_CASE_INSENSITIVE         = 0x00000040
  13.         _FILE_SYNCHRONOUS_IO_NONALERT = 0x00000020
  14.         _FILE_READ_DATA               = 1
  15.  
  16.         ; Тип запрашиваемой информации
  17.         _ObjectNameInformation = 1
  18.  
  19.         ; Структура для получения результата
  20.         struct _OBJECT_NAME_INFORMATION
  21.                 Length        dw ?
  22.                 MaximumLength dw ?
  23.                 Buffer        dd ?
  24.                 String        rw MAX_PATH-1
  25.         ends
  26.  
  27.         ; Структура для юникодной строки
  28.         struct _UNICODE_STRING
  29.                 Length        dw ?
  30.                 MaximumLength dw ?
  31.                 Buffer        dd ?
  32.         ends
  33.  
  34.         ; Структура для статуса выполнения операции
  35.         struct _IO_STATUS_BLOCK
  36.                 Status      dd ?
  37.                 Pointer     dd ?
  38.                 Information dd ?
  39.         ends
  40.  
  41.         ; Структура для атрибутов объекта
  42.         struct _OBJECT_ATTRIBUTES
  43.                 Length                   dd ?
  44.                 RootDirectory            dd ?
  45.                 ObjectName               dd ?
  46.                 Attributes               dd ?
  47.                 SecurityDescriptor       dd ?
  48.                 SecurityQualityOfService dd ?
  49.         ends
  50.  
  51.         locals
  52.                 hFile            dd ?
  53.                 tmp_name         rw MAX_PATH-1
  54.                 dDisk            dd ?
  55.                 szDisk           rw 4
  56.                 result           dd ?
  57.                 szTmp            rw MAX_PATH-1
  58.                 ObjectName       _UNICODE_STRING
  59.                 ObjectAttributes _OBJECT_ATTRIBUTES
  60.                 IoStatusBlock    _IO_STATUS_BLOCK
  61.                 dwSize           dd ?
  62.                 ObjectNameInfo   _OBJECT_NAME_INFORMATION
  63.         endl
  64.  
  65.         pusha
  66.  
  67.         mov     [result],0
  68.  
  69.         ; Преобразовать File URL в путь
  70.         lea     eax,[dwSize]
  71.         mov     dword [eax],MAX_PATH*2
  72.         lea     ebx,[szTmp]
  73.         invoke  PathCreateFromUrl,[lpPath],ebx,eax,0
  74.         or      eax,eax
  75.         jz      @f
  76.  
  77.         mov     ebx,[lpPath]
  78. @@:
  79.         ; Развернуть переменные окружения
  80.         lea     eax,[tmp_name]
  81.         invoke  ExpandEnvironmentStrings,ebx,eax,MAX_PATH*2
  82.  
  83.         ; Исправить обратные слеши
  84.         lea     ebx,[tmp_name]
  85.         mov     esi,ebx
  86.         mov     edi,ebx
  87. .loc_fix_slashes:
  88.         lodsw
  89.         cmp     ax,'/'
  90.         jne     @f
  91.         mov     ax,'\'
  92. @@:
  93.         stosw
  94.         or      ax,ax
  95.         jnz     .loc_fix_slashes
  96.  
  97.         ; Путь уже нормализован?
  98.         cmp     word [ebx+2],':'
  99.         jne     @f
  100.  
  101.         ; Больше ничего делать не требуется
  102.         invoke  lstrcpy,[lpNorm],ebx
  103.         mov     [result],1
  104.         jmp     .loc_ret
  105. @@:
  106.         lea     eax,[ObjectName]
  107.         invoke  RtlInitUnicodeString,eax,ebx
  108.  
  109.         push    _FILE_SYNCHRONOUS_IO_NONALERT
  110.         push    FILE_SHARE_READ+FILE_SHARE_WRITE+FILE_SHARE_DELETE
  111.         lea     eax,[IoStatusBlock]
  112.         push    eax
  113.         lea     ebx,[ObjectAttributes]
  114.         push    ebx
  115.         mov     [ebx+_OBJECT_ATTRIBUTES.Length],sizeof._OBJECT_ATTRIBUTES
  116.         lea     eax,[ObjectName]
  117.         mov     [ebx+_OBJECT_ATTRIBUTES.ObjectName],eax
  118.         mov     [ebx+_OBJECT_ATTRIBUTES.Attributes],_OBJ_CASE_INSENSITIVE
  119.         push    _FILE_READ_DATA+SYNCHRONIZE
  120.         lea     eax,[hFile]
  121.         push    eax
  122.         invoke  NtOpenFile
  123.         or      eax,eax
  124.         jz      @f
  125.  
  126.         ; Файл открыть не удалось
  127.         lea     ebx,[tmp_name]
  128.         invoke  lstrcpy,[lpNorm],ebx
  129.         jmp     .loc_ret
  130. @@:
  131.         lea     ebx,[dwSize]
  132.         ; Получить размер информации
  133.         invoke  NtQueryObject,[hFile],_ObjectNameInformation,NULL,0,ebx
  134.         ; Получить информацию об объекте
  135.         push    ebx
  136.         push    [dwSize]
  137.         lea     eax,[ObjectNameInfo]
  138.         push    eax
  139.         invoke  NtQueryObject,[hFile],_ObjectNameInformation
  140.         or      eax,eax
  141.         jz      @f
  142.  
  143.         ; Имя объекта получить не удалось
  144.         lea     ebx,[tmp_name]
  145.         invoke  lstrcpy,[lpNorm],ebx
  146.         invoke  NtClose,[hFile]
  147.         jmp     .loc_ret
  148. @@:
  149.         ; Сохранить полученное имя
  150.         lea     eax,[ObjectNameInfo]
  151.         lea     eax,[eax+_OBJECT_NAME_INFORMATION.String]
  152.         lea     ebx,[tmp_name]
  153.         invoke  lstrcpy,ebx,eax
  154.  
  155.         ; Закрыть открытый файл
  156.         invoke  NtClose,[hFile]
  157.  
  158.         ; Перебрать все диски, начиная с A:
  159.         mov     [dDisk],1
  160. .loc_find_drive:
  161.         invoke  GetLogicalDrives
  162. @@:
  163.         test    eax,[dDisk]
  164.         jnz     @f
  165.         shl     [dDisk],1
  166.         jnz     @b
  167.  
  168.         ; Диск определить не удалось
  169.         lea     ebx,[tmp_name]
  170.         invoke  lstrcpy,[lpNorm],ebx
  171.         jmp     .loc_ret
  172. @@:
  173.         lea     eax,[szDisk]
  174.         mov     dword [eax],0x003A0041 ; 'A:' в юникоде
  175.         mov     dword [eax+4],0
  176.         mov     ecx,[dDisk]
  177.         bsr     ecx,ecx
  178.         add     dword [eax],ecx
  179.  
  180.         ; Следующий диск
  181.         shl     [dDisk],1
  182.  
  183.         ; Преобразовать букву диска в строку типа \Device\HarddiskVolume1
  184.         lea     eax,[szDisk]
  185.         lea     ebx,[szTmp]
  186.         invoke  QueryDosDevice,eax,ebx,MAX_PATH*2
  187.         or      eax,eax
  188.         ; Диска нет, пропускаем
  189.         jz      @f
  190.         ; Сравнить начало пути со строкой устройства
  191.         mov     ecx,eax
  192.         lea     esi,[tmp_name]
  193.         mov     edi,ebx
  194.         repe    cmpsw
  195.         or      ecx,ecx
  196.         jnz     @f
  197.  
  198.         ; Только буква диска
  199.         lea     eax,[szDisk]
  200.         invoke  lstrcpy,[lpNorm],eax
  201.         mov     [result],1
  202.         jmp     .loc_ret
  203. @@:
  204.         cmp     ecx,1
  205.         jne     .loc_find_drive
  206.         ; Дополнительная проверка корректности пути
  207.         dec     esi
  208.         dec     esi
  209.         cmp     word [esi],'\'
  210.         jne     .loc_find_drive
  211.  
  212.         ; Диск + оставшийся путь к файлу
  213.         lea     eax,[szDisk]
  214.         invoke  lstrcpy,[lpNorm],eax
  215.         invoke  lstrcat,[lpNorm],esi
  216.         mov     [result],1
  217. .loc_ret:
  218.         popa
  219.  
  220.         mov     eax,[result]
  221.         ret
  222. endp
Параметры вызова: lpPath - указатель на юникодную строку с исходным путем, lpNorm - указатель на строку, куда будет записан нормализованный путь к файлу или каталогу. В регистре EAX возвращается результат выполнения операции: 1 - нормализация прошла успешно, 0 - что-то пошло не так, например, не найден объект, на который указывает символическая ссылка, или файл расположен на сетевом диске. В случае неудачи в lpNorm будет записан исходный путь, но с развернутыми переменными окружения и исправленными слешами, или вовсе без изменений, если никаких преобразований не выполнялось.

Читать статью целиком »
Просмотров: 455 | Комментариев: 1

Кодирование и декодирование чисел по алгоритму Base58

22.01.2019 | Категория: Образ мышления: Assembler | Автор: ManHunter
Base58 - вариант кодирования чисел в виде буквенно-цифрового текста на основе цифр и символов латинского алфавита. Алфавит Base58, как можно догадаться из названия, содержит 58 символов. Base58 был разработан для передачи данных и уменьшения количества ошибок у пользователей, которые вручную вводят данные на основе распечатанного текста или фотографии, то есть без возможности машинного копирования и вставки. Так, к примеру, Base58 используется для кодирования идентификаторов кошельков Bitcoin, для создания коротких ссылок на фотохостингах и т.п. В отличие от кодирования Base64, позволяющего работать с неограниченными объемами двоичных данных, Base58 предназначен для кодирования только одиночных числовых значений.

Согласно спецификации, в алфавит Base58 не входят буквенно-цифровые символы, которые имеют сходное написание и могут неоднозначно восприниматься человеком (например, буква "О" и цифра "0"), а также символы, используемые при формировании URL. Вместе с тем, порядок следования символов в алфавите ничем не регламентирован, зависит только от сферы применения кодирования и может быть любым. Для этой статьи я выбрал следующий алфавит Base58:
  1. alpha db '123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ'
  2. alpha_len=$-alpha
Использования своего собственного порядка символов также позволяет добавить немного секурности вашему проекту, затрудняя перебор последовательных идентификаторов. Но вы должны понимать, что целиком надеяться на это ни в коем случае не стоит.

Читать статью целиком »
Просмотров: 559 | Комментариев: 2

Алгоритмы шифрования TEA и XTEA на Ассемблере

13.12.2018 | Категория: Образ мышления: Assembler | Автор: ManHunter

Алгоритмы шифрования TEA и XTEA на Ассемблере

Tiny Encryption Algorithm (TEA) - один из видов блочных алгоритмов шифрования данных. Главными отличиями TEA являются высокая скорость работы, нетребовательность к памяти и простота реализации на различных языках программирования. Не обошлось и без недостатков в виде уязвимости к некоторым типам криптографических атак, но даже несмотря на это алгоритм завоевал широкую популярность в различных системах.

Читать статью целиком »
Просмотров: 818 | Комментариев: 8

Как удалить BOM из файлов

24.12.2017 | Категория: Web-мастеру и не только | Автор: ManHunter
Маркер последовательности байтов, он же BOM - специальный символ Юникода, который вставляется в начало текстового файла для обозначения того, что в этом файле используется Юникод. Согласно спецификации, использование этого символа не является обязательным, однако оно широко распространено, что иногда приводит к проблемам при обработке данных.

Так, к примеру, однажды я столкнулся с ситуацией, когда от сторонней системы передавался файл в формате JSON, а я у себя должен был извлечь поступившие данные при помощи стандартной функции PHP json_decode. Файл передается и принимается успешно, на первый взгляд имеет абсолютно корректную структуру, правильно открывается в браузере и блокноте, но функция декодирования все равно возвращает ошибку, что данные некорректные. Сейчас я не смогу сказать, сколько времени потратил на выяснение причины ошибки, пока, наконец, не решил открыть файл при помощи HEX-редактора. Оказалось, что всему виной был маркер BOM, из-за которого функция json_decode не могла корректно раскодировать файл.

Для решения проблемы я быстренько нарисовал вот такую функцию в несколько строчек:
  1. // Функция удаления BOM из потока данных
  2. function remove_BOM($data) {
  3.     // Маркер UTF-8
  4.     if (substr($data,0,3)=="\xEF\xBB\xBF") {
  5.         return substr($data,3);
  6.     }
  7.     // Маркер UTF-16
  8.     elseif (substr($data,0,2)=="\xFF\xFE") {
  9.         return substr($data,2);
  10.     }
  11.     else {
  12.         return $data;
  13.     }
  14. }
При получении файла данные сперва обрабатывались при помощи этой функции и только после этого отправлялись на декодирование в json_decode.

Просмотров: 837 | Комментариев: 1

Расстояние между двумя точками на карте

27.08.2017 | Категория: Web-мастеру и не только | Автор: ManHunter

Расстояние между двумя точками на карте

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

Читать статью целиком »
Просмотров: 1274 | Комментариев: 2

prev 01 02 03 04 05 06
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2019
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.12 сек. / MySQL: 3 (0.0465 сек.) / Память: 5 Mb
Наверх