Blog. Just Blog

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

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

Рекурсивный обход дерева каталогов

19.01.2009 | Категория: Образ мышления: Assembler | Автор: ManHunter
Обход дерева каталогов является одной из классических прикладных задач на применение рекурсии. В Windows штатных API-функций для этого нет, поэтому поиск файлов выполняется при помощи пары API-функций FindFirstFile и FindNextFile. Совершенно непонятно, почему разработчики Windows не дали возможность точно настраивать критерии поиска, ограничившись только маской имени файла. Даже в MS-DOS для решения аналогичной задачи можно было задать по крайней мере атрибуты файлов, например для поиска только каталогов. Более расширенные возможности для поиска предоставляет API-функция FindFirstFileEx, но она доступна только в операционной системе Windows 2000 и выше.

Для рекурсивного обхода дерева каталогов я написал следующую функцию. Она сканирует дерево каталогов, начиная с указанного, и передает все найденные имена файлов в заданную функцию-обработчик. Все действия с найденными файлами выполняются уже в ней.
  1. ;------------------------------------------------------------------
  2. ; Функция рекурсивного обхода дерева каталогов
  3. ; (C) ManHunter / PCL
  4. ; http://www.manhunter.ru
  5. ;
  6. ; Параметры вызова:
  7. ; lpFStr - указатель на начальный каталог без завершающего слеша.
  8. ;          он должен быть в буфере размером не менее MAX_PATH байт
  9. ; lpProc - указатель на callback-функцию для передачи имен файлов,
  10. ;          это обязательный параметр
  11. ; dFlag  - флаг "передавать в callback-функцию имена найденных
  12. ;          каталогов" (TRUE/FALSE)
  13. ;------------------------------------------------------------------
  14. proc    FindFileRecursive lpFStr:dword,lpProc:dword,dFlag:dword
  15.         local   hFind:DWORD     ; Локальный хэндл текущего поиска
  16.  
  17.         locals
  18.         FndData WIN32_FIND_DATA ; Локальная структура WIN32_FIND_DATA
  19.         endl
  20.  
  21.         ; Сохранить изменяемые регистры
  22.         push    ebx ecx edx
  23.  
  24.         ; Добавить к пути поиска '\*.*'
  25.         invoke  lstrcat,[lpFStr],ff_mask
  26.  
  27.         ; Найти первый файл
  28.         lea     eax,[FndData]
  29.         push    eax
  30.         invoke  FindFirstFile,[lpFStr]
  31.         ; В случае ошибки полностью прекратить дальнейшее сканирование
  32.         cmp     eax,INVALID_HANDLE_VALUE
  33.         jne     @f
  34.         xor     eax,eax
  35.         jmp     ff_exit
  36. @@:
  37.         ; Сохранить хэндл текущего поиска
  38.         mov     [hFind],eax
  39.  
  40. ff_chk_file:
  41.         ; Проверить имя файла на недопустимое
  42.         lea     eax,[FndData.cFileName]
  43.         push    eax
  44.         ; Имя файла '.'
  45.         invoke  lstrcmp,ff_skip1
  46.         or      eax,eax
  47.         ; Да, пропустить
  48.         jz      ff_next_file
  49.  
  50.         lea     eax,[FndData.cFileName]
  51.         push    eax
  52.         ; Имя файла '..'
  53.         invoke  lstrcmp,ff_skip2
  54.         or      eax,eax
  55.         ; Да, пропустить
  56.         jz      ff_next_file
  57.  
  58.         ; Если установлен флаг dFlag=TRUE, то передавать в callback-процедуру
  59.         ; все найденные результаты, в том числе и каталоги
  60.         cmp     [dFlag],0
  61.         jne     @f
  62.  
  63.         ; Установлен флаг передавать только файлы. Проверить атрибуты
  64.         ; найденного файла
  65.         mov     eax,[FndData.dwFileAttributes]
  66.         and     eax,FILE_ATTRIBUTE_DIRECTORY
  67.         ; Это каталог, пропустить
  68.         jnz     ff_do_not_callback
  69. @@:
  70.         ; Вычислить длину текущей строки поиска и обрезать '*.*'
  71.         invoke  lstrlen,[lpFStr]
  72.         sub     eax,3
  73.         add     eax,[lpFStr]
  74.         mov     byte [eax],0
  75.         push    eax
  76.  
  77.         ; Дописать к пути имя найденного файла или каталога
  78.         lea     eax,[FndData.cFileName]
  79.         push    eax
  80.         invoke  lstrcat,[lpFStr]
  81.         ; Передать имя файла в callback-функцию
  82.         stdcall [lpProc],[lpFStr]
  83.  
  84.         ; Вернуть маску поиска на место
  85.         pop     ecx
  86.         mov     dword [ecx],'*.*'
  87.  
  88.         ; Если callback-функция вернула 0, то прекратить сканирование
  89.         or      eax,eax
  90.         jz      ff_stop_scan
  91.  
  92.         ; Это каталог?
  93.         mov     eax,[FndData.dwFileAttributes]
  94.         and     eax,FILE_ATTRIBUTE_DIRECTORY
  95.         je      ff_next_file
  96.  
  97. ff_do_not_callback:
  98.         ; Вычислить длину текущей строки поиска и обрезать '*.*'
  99.         invoke  lstrlen,[lpFStr]
  100.         sub     eax,3
  101.         add     eax,[lpFStr]
  102.         mov     byte [eax],0
  103.         push    eax
  104.  
  105.         ; Дописать к пути имя найденного каталога
  106.         lea     eax,[FndData.cFileName]
  107.         push    eax
  108.         invoke  lstrcat,[lpFStr]
  109.  
  110.         ; Рекурсивный вызов поиска файлов в новом каталоге
  111.         stdcall FindFileRecursive,[lpFStr],[lpProc],[dFlag]
  112.  
  113.         ; Вернуть маску поиска на место
  114.         pop     ecx
  115.         mov     dword [ecx],'*.*'
  116.  
  117.         ; Если callback-функция вернула 0, то прекратить сканирование
  118.         or      eax,eax
  119.         jz      ff_stop_scan
  120.  
  121. ff_next_file:
  122.         ; Найти следующий файл
  123.         lea     eax,[FndData]
  124.         push    eax
  125.         invoke  FindNextFile,[hFind]
  126.         or      eax,eax
  127.         ; Файл найден, обработать его
  128.         jnz     ff_chk_file
  129.         ; По умолчанию установить флаг "продолжать сканирование"
  130.         mov     eax,TRUE
  131. ff_stop_scan:
  132.         ; Закрыть хэндл текущего поиска
  133.         push    eax
  134.         invoke  FindClose,[hFind]
  135.         pop     eax
  136. ff_exit:
  137.         ; Восстановить измененные регистры
  138.         pop     edx ecx ebx
  139.  
  140.         ; Возврат из процедуры.
  141.         ; Код возврата EAX=1 - продолжать сканирование, EAX=0 - стоп
  142.         ret
  143.  
  144. ff_mask  db '\*.*',0    ; Маска файлов для поиска
  145. ff_skip1 db '.',0       ; Запрещенное имя файла
  146. ff_skip2 db '..',0      ; Запрещенное имя файла
  147.  
  148. endp
Путь к начальному каталогу должен размещаться в буфере размером не менее определенного в системе MAX_PATH (обычно 256 символов). Обязательным параметром является адрес callback-функции RecursiveFindFileProc, которой поочередно передаются все результаты поиска. Флаг dFlag указывает, будут передаваться в callback-функцию все найденные результаты, включая каталоги, или же будут передаваться только найденные файлы. Код возврата из FindFileRecursive EAX=1 - сканирование было закончено, когда больше ни одного файла не было найдено, EAX=0 - сканирование завершилось аварийно или же было остановлено из callback-функции.

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

Gothic Metal фест от агентства "Московский Рок клуб"

17.01.2009 | Категория: Жизнь в оффлайне | Автор: ManHunter

Gothic Metal фест от агенства "Московский Рок клуб"

Сегодня сходил в клуб "Plan B" на мероприятие с мудреным названием "Первый концерт МРК в поддержку неформального искусства и творческой молодежи", оно же Gothic/Industrial Metal фест от концертного агентства "Московский Рок клуб". Трудовая неделя явно затянулась, так что организм требовал встряски и позитива одновременно.

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

Meizu Music Card (Ritmix RF-7400)

14.01.2009 | Категория: Обзоры техники | Автор: ManHunter

Meizu Music Card (Ritmix RF-7400)

Надоело мучать свою мобилу несвойственными ей функциями MP3-плеера, поэтому к Рождеству сделал себе любимому такой приятный подарок. После лазания по "Савёле" остановился на этой модели. Выбор был сделан из желания получить не очень дорогой плеер с максимальной емкостью памяти для этой цены. Тактико-технические характеристики девайса без труда можно найти в интернете. Это не реклама, просто опишу свои личные ощущения от использования.

Управление очень простое. Все действия выполняются одной большой сенсорной кнопкой и одной маленькой кнопкой листания композиций. Сперва никак не мог приловчиться выполнять прокрутку, пытался делать это легким касанием, но оказалось что ее надо делать как раз с небольшим нажимом, а касание расценивается как команда "Ввод". Меню на русском языке, все интуитивно понятно. К тому же в комплекте идет внушительный мануал с картинками и описанием всех действий, тоже на русском языке. Чтобы кнопки случайно не нажались, например когда плеер лежит в кармане, на корпусе предусмотрен переключатель блокировки. Подключается через стандартный разъем mini-USB к компьютеру, системой определяется как обычная флешка. Заряжается через него же, не требует никаких посторонних батареек и аккумуляторов, что для меня является огромным плюсом. Заряд держит очень долго, даже при постоянном использовании. В документации заявлено более 20 часов непрерывной работы, похоже что так оно и есть.

Звук просто шикарный, особенно после телефона. Настраивается точно под ваши требования с использованием целой кучи опций, таких как объемный звук, усиление басов и высоких частот и т.д. На выходе дает такой громкий сигнал, что даже мой слух, тренированный разными брутальными стилями музыки, максимальную громкость в наушниках не выдерживает. Понимает форматы MP3, WMA, OGG, FLAC, WAV, все залитые в него композиции воспроизвелись без проблем. Также в устройстве есть FM-радио и диктофон. Ни тем, ни другим не пользуюсь, так что ничего больше про них сказать не могу. Еще из полезных мелочей присутствуют часы и календарик.

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

Runtime error R6002 floating point not loaded

13.01.2009 | Категория: Темная сторона Силы | Автор: ManHunter
После распаковки приложений, написанных на Microsoft Visual C++ и накрытых некоторыми протекторами (Armadillo, PECompact и другие) они могут падать при запуске или выполнении каких-либо действий с ошибкой Runtime error R6002 floating point not loaded. Причина ее возникновения следующая: программа была скомпилирована с Microsoft.VC80.CRT и при запуске в ней проверяются атрибуты секций.

Первый способ устранения ошибки R6002 заключается в выставлении атрибутов секций в распакованном файле в точности, как было в оригинальном. Сделать это можно с использованием бесплатной утилиты CFF Explorer VII. Второй вариант, более надежный и гарантированно рабочий - пропатчивание в исполняемом файле функции __fptrap, которая и отвечает за появление этого сообщения об ошибке. Дизассемблером IDA в файле она определяется примерно так:
  1. __fptrap  proc near
  2.           push    2             ; <--- заменить на RET
  3.           call    __amsg_exit
  4.           pop     ecx
  5.           retn
  6. __fptrap  endp
Ее надо пропатчить, заменив первую команду на немедленный возврат из функции RET. Сигнатура поиска 6A 02 E8 ?? ?? ?? ?? 59 C3. К сожалению, сигнатура достаточно короткая и в большом коде может быть найдено несколько совпадений, поэтому при анализе файла очень желательно пользоваться дизассемблером.

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

Функции base64 на Ассемблере

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

Алгоритм Base64 обратимый, то есть из закодированного текста можно в точности получить исходные данные. Начнем с функции кодирования.
  1. ;---------------------------------------------------------------
  2. ; Функция кодирования Base64
  3. ;---------------------------------------------------------------
  4. ; Параметры:
  5. ; lpFrom - указатель на исходные данные
  6. ; lpTo   - указатель на буфер для приема кодированных данных
  7. ; dSize  - размер исходных данных
  8. ; Функция ничего не возвращает
  9. ;---------------------------------------------------------------
  10. proc    base64_encode lpFrom:dword, lpTo:dword, dSize:dword
  11.         pusha
  12.  
  13.         mov     ebx,.base64
  14.         mov     esi,[lpFrom]
  15.         mov     edi,[lpTo]
  16.         mov     ecx,[dSize]
  17.  
  18.         or      ecx,ecx
  19.         jz      .r3
  20. .encode_loop:
  21.         lodsd
  22.         mov     edx,eax
  23.         bswap   edx
  24.         xor     eax,eax
  25.  
  26.         shld    eax,edx,6
  27.         shl     edx,6
  28.         xlatb
  29.         stosb
  30.  
  31.         xor     eax,eax
  32.         shld    eax,edx,6
  33.         shl     edx,6
  34.         xlatb
  35.         stosb
  36.         dec     ecx
  37.         jz      .r2
  38.  
  39.         xor     eax,eax
  40.         shld    eax,edx,6
  41.         shl     edx,6
  42.         xlatb
  43.         stosb
  44.         dec     ecx
  45.         jz      .r1
  46.  
  47.         xor     eax,eax
  48.         shld    eax,edx,6
  49.         shl     edx,6
  50.         xlatb
  51.         stosb
  52.  
  53.         dec     esi
  54.         dec     ecx
  55.         jnz     .encode_loop
  56.  
  57.         jmp     .r3
  58. .r2:
  59.         mov     al,'='
  60.         stosb
  61. .r1:
  62.         mov     al,'='
  63.         stosb
  64. .r3:
  65.         xor     eax,eax
  66.         stosb
  67.         popa
  68.  
  69.         ret
  70.  
  71. .base64 db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
  72.         db 'abcdefghijklmnopqrstuvwxyz'
  73.         db '0123456789+/'
  74. endp
Параметры вызова: lpFrom - указатель на кодируемые данные, lpTo - указатель на буфер для приема кодированных данных и dSize - размер кодируемых данных. Все параметры обязательные. Размер буфера-приемника должен быть примерно в 1,3 раза больше исходных данных, это обусловлено особенностями алгоритма кодирования.

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

01 ... 389 390 391 392 393 394 395 ... 404
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2024
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.1 сек. / MySQL: 2 (0.0339 сек.) / Память: 4.5 Mb
Наверх