На сайте прочёл статью "3 метода работы с занятыми файлами". Но исходный код там был дан не на Асемблере. Я конечно понимаю что для хороших програмистов это не имеет значения. Они как правило хорошо ориентируются в любых языках. А вот для начинающих програмировать на Асемблере это (в некоторых случаях) создаёт небольшую проблемку. Ради интереса попробывал перекинуть один из методов "Чтение файла с помощью прямого доступа к диску" на Асемблер. С применением (для простоты) высокоуровневой инструкции "invoke" Я не стал заморачиватся с локальными переменными и все переменные сделал глобальными и (для наглядности) инициализацию переменных сделал в каждой функции. В примере показано как можно например скопировать системный файл реестра "SAM" который обычными средствами на работающей системе скопировать не удастся. Поэтому кому интересно предсавляю этот код на Асемблере. Но не стоит забывать, как пишет автор статьи: Несомненно этот метод выглядит просто и кажется весьма мощным, но к сожалению и ему присущи недостатки. Таким способом можно читать только файлы которые можно открыть с доступом FILE_READ_ATTRIBUTES (не читаются только файлы подкачки), файл обязательно должен быть не сжат, не зашифрован (иначе мы прочитаем ерунду), и должен иметь свой кластер (маленькие файлы в NTFS могут целиком размещаться в MFT). Также следует учесть, что во время чтения файл может быть изменен (и мы получим в результате фиг знает что). Внимание: Код написан только для понимания алгоритма данного процесса на Асемблере. В нём нет проверок на успешность. И нет востановлений значений регистров "esi, edi, ebp и ebx" В одной статье Iczelion'а я прочитал: При пpогpаммиpовании под Win32 вы должны помнить несколько важных пpавил. Самое важное следующее: Windows использует esi, edi, ebp и ebx для своих целей и не ожидет, что вы измените значение этих pегистpов. Если же вы используете какой-либо из этих четыpех pегистpов в вызываемой функции, то не забудте восстановить их пеpед возвpащением упpавления Windows. Да и честно говоря не сильно удивлюсь если кто то найдёт здесь ошибки. Истину "Век живи век учись" ещё ни кто не отменял. Код тестировал только под Windows XP. Поэтому как этот код поведёт себя на других системах я не знаю. Код (Text): .386 .model flat,stdcall option casemap:none include \masm32\include\windows.inc include \masm32\include\user32.inc include \masm32\include\kernel32.inc includelib \masm32\lib\user32.lib includelib \masm32\lib\kernel32.lib .code start: call Function_1 call Function_2 call Function_3 invoke ExitProcess,0 ;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Function_1 proc .data szInFile db "C:\WINDOWS\system32\config\SAM",0 .data? szLocalDisk dd ? dwBytesCluster dd ? .code lea esi,szInFile mov eax,dword ptr [esi] lea edi,szLocalDisk mov dword ptr [edi],eax mov byte ptr [edi+3],0 invoke GetDiskFreeSpace,edi,ebx,ebp,0,0 mov eax,dword ptr [ebx] imul eax,dword ptr [ebp] mov dwBytesCluster,eax retn Function_1 endp ;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Function_2 proc .data lpInBuffer db 8 dup (0) .data? hHeap dd ? dwSizeFile dd ? lpBytesReturned dd ? lpOutBuffer dd ? dwOutBufferSize dd ? .code invoke GetProcessHeap mov hHeap,eax lea eax,szInFile invoke CreateFile,eax,80h,7,0,3,0,0 mov ebx,eax invoke GetFileSize,ebx,0 mov dwSizeFile,eax xor edx, edx mov ecx,dwBytesCluster div ecx add eax,2 imul eax, 16 mov dwOutBufferSize,eax invoke HeapAlloc,hHeap,0,dwOutBufferSize mov lpOutBuffer,eax invoke DeviceIoControl,ebx,90073h,addr lpInBuffer,8,lpOutBuffer,dwOutBufferSize,addr lpBytesReturned,0 invoke CloseHandle,ebx retn Function_2 endp ;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Function_3 proc .data szOutFile db "SAM",0 szFileDisk db "\\.\?:",0 .data? hBufCluster dd ? hDiskFile dd ? hFileOut dd ? lpOverByte dd ? lpDistanceToMoveHigh dd ? dwExtent dd ? dwBlok dd ? dwRaznst dd ? dwAdres dd ? .code lea esi,szFileDisk mov eax,szLocalDisk mov byte ptr [esi+4],al invoke CreateFile,addr szFileDisk,80000000h,3,0,3,0,0 mov hDiskFile,eax invoke CreateFile,addr szOutFile,40000000h,0,0,2,0,0 mov hFileOut,eax invoke HeapAlloc,hHeap,0,dwBytesCluster mov hBufCluster,eax mov edi,lpOutBuffer mov esi,dwBytesCluster mov ebp,dwSizeFile mov eax,dword ptr [edi] mov dwExtent,eax mov dwRaznst,0 loc_1: .if dwExtent > 0 add edi,16 mov eax,dword ptr [edi] sub eax,dwRaznst mov dwBlok,eax add dwRaznst,eax mov eax,dword ptr [edi+8] mov dwAdres,eax loc_2: .if dwBlok > 0 .if ebp > 0 mov eax,dwAdres mul esi mov lpDistanceToMoveHigh,edx lea edx,lpDistanceToMoveHigh invoke SetFilePointer,hDiskFile,eax,edx,0 invoke ReadFile,hDiskFile,hBufCluster,esi,addr lpOverByte,0 .if ebp > esi mov ebx,esi .else mov ebx,ebp .endif invoke WriteFile,hFileOut,hBufCluster,ebx,addr lpOverByte,0 sub ebp,ebx add dwAdres,1 .endif dec dwBlok jmp loc_2 .endif dec dwExtent jmp loc_1 .endif invoke HeapFree,hHeap,0,lpOutBuffer invoke HeapFree,hHeap,0,hBufCluster invoke CloseHandle,hDiskFile invoke CloseHandle,hFileOut retn Function_3 endp ;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% end start
На самом деле это метод работы с секторами и кластерами, но никак не с файлами. Файлы находятся на один уровень абстракции выше. И в чем проблема прочитать данные из MFT? MFT тоже в секторах и кластерах лежит.
Так как таких констант в масме нет подскажите пожалуйста . Числовое значение FSCTL_GET_RETRIEVAL_POINTERS - 90073h а какое числовое значение у FSCTL_GET_NTFS_FILE_RECORD - ?
К сожелению поиск результата не дал. Всё крутится вокруг файла winioctl.h который и указан в MSDN. Но в файле информация указана так: #define FSCTL_GET_NTFS_FILE_RECORD CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 26, METHOD_BUFFERED, FILE_ANY_ACCESS) // NTFS_FILE_RECORD_INPUT_BUFFER, NTFS_FILE_RECORD_OUTPUT_BUFFER #define FSCTL_GET_RETRIEVAL_POINTERS CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 28, METHOD_NEITHER, FILE_ANY_ACCESS) // STARTING_VCN_INPUT_BUFFER, RETRIEVAL_POINTERS_BUFFER
Код (Text): #define CTL_CODE( DeviceType, Function, Method, Access ) ( \ ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \ ) Код (Text): METHOD_BUFFERED EQU 0t METHOD_IN_DIRECT EQU 1t METHOD_OUT_DIRECT EQU 2t METHOD_NEITHER EQU 3t FILE_ANY_ACCESS EQU 0t FILE_READ_ACCESS EQU 000000001h FILE_WRITE_ACCESS EQU 000000002h FILE_DEVICE_FILE_SYSTEM equ 9
Спасибо punxer попробую разобратся . Хотя честно говоря как из этих констант вычеслить значение не понимаю.
Код (Text): IFNDEF CTL_CODE CTL_CODE MACRO DeviceType:=<0>, Function:=<0>, Method:=<0>, Access:=<0> EXITM %(((DeviceType) SHL 16) OR ((Access) SHL 14) OR ((Function) SHL 2) OR (Method)) ENDM ENDIF УЧИТЕСЬ ПОЛЬЗОВАТЬСЯ ПОИСКОМ
Большое спасибо punxer с твоей помощью разобрался #define FSCTL_GET_NTFS_FILE_RECORD CTL_CODE ( FILE_DEVICE_FILE_SYSTEM , 26 , METHOD_BUFFERED , FILE_ANY_ACCESS ) 00000000000010010000000001101000 - 90068h 0000000000001001 - DeviceType - 9 00 - Access - 0 000000011010 - Function - 26 00 - Method - 0 FSCTL_GET_NTFS_FILE_RECORD - 90068h