Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.17.174.239] |
|
Сообщ.
#1
,
|
|
|
Рекурсивный поиск файлов (FASM) ; -=-=-=-=-=-=-=-=-=-=-=-=-=- ; Global files search in FASM ; Created by Ct757 ; -=-=-=-=-=-=-=-=-=-=-=-=-=- ; ; ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ; В данном примере показана рекурсивная реализация ; поиска файлов на ассембеле под Windows с помощью ; API-функций FindFirstFile + FindNextFile, а так же ; показано как можно узнать список присутстующих ; в системе дисков с помощью функции GetLogicalDrives ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ format PE GUI 4.0 ; PE EXE файл entry start ; Точка входа include '%fasminc%\win32a.inc' section '.main' code readable writeable executable ; Секция кода ; и данных buf rb 500h ; Буффер для имени директории fake1 dd '.',0 ; Дирекории, которые fake2 dd '..',0 ; НЕ надо сканировать start: ; Начало основной ; Программы push 1h ; SEM_FAILCRITICALERRORS call [SetErrorMode] ; Установим error mode ; что бы в случае обращения ; к недоступному диску ; не вываливалось сообщение call [GetLogicalDrives] ; Получаем список дисков, ; существующих в системе mov ecx,25 ; Будем проверять, начиная с Z:\ .find_drives: mov ebx,1 ; Нехитрые опрерации в shl ebx,cl ; ходе которых мы выясняем and ebx,eax ; присутствует диск в je .no_disk ; системе или нет ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ; На всякий случай, пояснение из MSDN: ; ; ;---------------------------------; ; ; DWORD GetLogicalDrives(void); ; ; ;---------------------------------; ; ; Return Values: ; -------------- ; If the function succeeds, the return value is a bitmask ; representing the currently available disk drives. ; Bit position 0 (the least-significant bit) is drive A, ; bit position 1 is drive B, bit position 2 is drive C, and so on. ; ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ add cl,65 ; Если да, то добавим mov byte [buf],cl ; букву диска в sub cl,65 ; буффер mov dword [buf+1],':\*.' ; Сформируем строку mov byte [buf+5],'*' ; для поиска, вида, mov byte [buf+6],0 ; например, C:\*.* push eax ; Сохраняем в стеке push ecx ; нужные регистры call find_files ; Вызываем процедуру поиска pop ecx ; Восстанавливаем pop eax ; регистры .no_disk: ; Если диска нет, dec ecx ; то проверяем следующий jge .find_drives ; пока ecx>0 push 0 ; Выходим из call [ExitProcess] ; программы proc find_files ; Рекурсивная процедура ; поиска файлов locals ; Локальные переменные: fd FINDDATA ; структура WIN32_FIND_DATA find_h dd ? ; и хэндл поиска endl lea eax,[fd] ; Вычисляем и кладем в стек push eax ; указатель на стуктуру find data push buf ; Указатель на имя директории, где искать call [FindFirstFile] ; Ищем inc eax ; Если ничего je .exit ; не нашли - выходим dec eax ; Иначе, сохраним mov [find_h],eax ; хэндл поиска .find_next: mov eax,[fd.dwFileAttributes] ; Проверяем, нашли and eax,FILE_ATTRIBUTE_DIRECTORY ; директорию? je .found ; Если нет - прыгаем на .found lea eax,[fd.cFileName] ; Проверяем, push eax ; вдруг это push fake1 ; "." call [lstrcmp] ; test eax,eax ; Если да, je .next ; ищем следующий файл lea eax,[fd.cFileName] ; Проверяем, push eax ; вдруг это push fake2 ; ".." call [lstrcmp] ; test eax,eax ; Если да je .next ; ищем следующий файл push buf ; Вычислим call [lstrlen] ; длину строки sub eax,3 ; вычтем *.* push eax ; сохраним полученную длину mov byte [buf+eax],0 ; Если мы всё-таки lea eax,[fd.cFileName] ; нашли директорию push eax ; то прибавляем push buf ; её имя к текущей call [lstrcat] ; папке push buf ; Опять вычислим call [lstrlen] ; длину получившейся строки mov dword [buf+eax],'\*.*' ; и прибавим mov byte [buf+eax+4],0 ; \*.* для поиска call find_files ; Вызываем процедуру ; поиска для найденной ; директории pop eax ; Восстановим mov dword [buf+eax-1],'\*.*' ; имя прежней mov byte [buf+eax+3],0 ; директории jmp .next ; Ищем следующий файл .found: lea eax,[fd.cFileName] push eax call [lstrlen] cmp dword [fd.cFileName+eax-4],'.txt' ; Проверим расширение файла jne .next ; Если не совпадает ищем дальше lea eax,[fd.cFileName] push 0 ; push eax ; push eax ; push 0 ; Покажем MessageBox с call [MessageBox] ; именем найденного файла .next: lea eax,[fd] ; Кладем в стек указатель push eax ; на структуру find_data push [find_h] ; Хэндл текущего поиска call [FindNextFile] ; Ищем следующий файл test eax,eax ; jne .find_next ; Если ничего не нашли, push [find_h] ; то закрываем call [FindClose] ; хэндл поиска .exit: ; ret ; Выход endp data import ; Импорт нужных API-функций library kernel32,'KERNEL32.DLL',\ user32,'USER32.DLL' include '%fasminc%\APIA\kernel32.inc' include '%fasminc%\APIA\user32.inc' end data |
Сообщ.
#2
,
|
|
|
Рекурсивный поиск файлов (MASM32) ; -=-=-=-=-=-=-=-=-=-=-=-=-=- ; Global files search in MASM ; Created by Ct757 ; -=-=-=-=-=-=-=-=-=-=-=-=-=- ; ; ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ; В данном примере показана рекурсивная реализация ; поиска файлов на ассемблере под Windows с помощью ; API-функций FindFirstFile + FindNextFile, а так же ; показано как можно узнать список присутствующих ; в системе дисков с помощью функции GetLogicalDrives ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .386 .model flat, stdcall option casemap:none include \masm32\include\windows.inc include \masm32\include\kernel32.inc include \masm32\include\user32.inc includelib \masm32\lib\user32.lib includelib \masm32\lib\kernel32.lib .data ; Секция данных buf db 500h dup(?) ; Буффер для имени директории fake1 db '.',0 ; Директории, которые fake2 db '..',0 ; НЕ надо сканировать .code ; Секция кода find_files proc ; Рекурсивная процедура ; Поиска файлов push ebp ; Выделим место в стеке mov ebp,esp ; под хэндл поиска sub esp,144h ; и структуру WIN32_FIND_DATA lea eax,[ebp-144h] ; Вычисляем указатель на find_data invoke FindFirstFile,offset buf,eax ; Ищем файлы inc eax ; Если ничего je exit ; не нашли - выходим dec eax ; Иначе, сохраним mov dword ptr [ebp-6h],eax ; хэндл поиска find_next: mov eax,dword ptr [ebp-144h] ; Проверяем, нашли and eax,FILE_ATTRIBUTE_DIRECTORY ; директорию? je found ; Если нет - прыгаем на found lea eax,[ebp-118h] ; Вычислим указатель на cFileName invoke lstrcmp,offset fake1,eax ; это "."? test eax,eax ; Если да, je next ; ищем дальше lea eax,[ebp-118h] ; Вычислим указатель на cFileName invoke lstrcmp,offset fake2,eax ; это ".."? test eax,eax ; Если да, je next ; ищем дальше invoke lstrlen,offset buf ; Вычислим длину строки sub eax,3 ; Вычтем *.* push eax ; Сохраним полученную длину mov byte ptr [buf+eax],0 ; Если мы всё-таки нашли lea eax,[ebp-118h] ; директорию, то прибавим invoke lstrcat,offset buf,eax ; к её имени cFileName invoke lstrlen,offset buf ; Вычислим длину строки mov dword ptr [buf+eax],'*.*\' ; Прибавим \*.* mov byte ptr [buf+eax+4],0 ; для поиска call find_files ; Вызываем процедуру поиска ; для найденной директории pop eax ; Восстановим дляну строки mov dword ptr [buf+eax-1],'*.*\' ; И восстановим \*.* mov byte ptr [buf+eax+3],0 ; jmp next ; Ищем дальше found: lea eax,[ebp-118h] ; Вычислим длину invoke lstrlen,eax ; cFileName cmp dword ptr [ebp-118h+eax-4],'txt.' ; Проыерим расширение файла jne next ; Если не равно ищем дальше lea eax,[ebp-118h] ; Если нашли, то что нужно invoke MessageBox,0,eax,eax,0 ; Покажем MessageBox с именем файла next: lea eax,[ebp-144h] ; Вычислим указатель на find_data invoke FindNextFile,dword ptr [ebp-6h],eax ; Ищем следующий файл test eax,eax ; jne find_next ; Если ничего не нашли invoke FindClose,dword ptr [ebp-6h] ; Закрываем хэндл поиска exit: leave ; Выходим из ret ; процедуры find_files endp start: invoke SetErrorMode,SEM_FAILCRITICALERRORS ; Установим error mode ; чтобы в случае обращения ; к недоступному диску ; не вываливалось сообщение invoke GetLogicalDrives ; Получаем список дисков ; существующих в системе mov ecx,25 ; Будем проверять, начиная с Z:\ find_drives: mov ebx,1 ; Нехитрые операции в shl ebx,cl ; ходе которых мы выясняем and ebx,eax ; присутсвует диск в je no_disk ; системе или нет ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ; На всякий случай, пояснение из MSDN: ; ; ;---------------------------------; ; ; DWORD GetLogicalDrives(void); ; ; ;---------------------------------; ; ; Return Values: ; -------------- ; If the function succeeds, the return value is a bitmask ; representing the currently available disk drives. ; Bit position 0 (the least-significant bit) is drive A, ; bit position 1 is drive B, bit position 2 is drive C, and so on. ; ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ add cl,65 ; Если да, то mov byte ptr buf,cl ; добавим букву sub cl,65 ; диска в буффер mov dword ptr buf+1,'.*\:' ; Сформируем строку mov byte ptr buf+5,'*' ; для поиска, вида, mov byte ptr buf+6,0 ; например, C:\*.* push eax ; Сохраняем нужные push ecx ; регистры в стеке call find_files ; Вызываем процедуру поиска pop ecx ; Восстанавливаем pop eax ; регистры no_disk: ; Если диска нет, dec ecx ; то проверяем следующий jge find_drives ; пока ecx>0 invoke ExitProcess,0 ; Выходим из программы end start |