Один из методов работы с занятами файлами на Асемблере

Тема в разделе "WASM.BEGINNERS", создана пользователем assch, 5 ноя 2011.

  1. assch

    assch Member

    Публикаций:
    0
    Регистрация:
    17 мар 2011
    Сообщения:
    208
    На сайте прочёл статью "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):
    1. .386
    2. .model flat,stdcall
    3. option casemap:none
    4.  
    5. include \masm32\include\windows.inc
    6. include \masm32\include\user32.inc
    7. include \masm32\include\kernel32.inc
    8.  
    9. includelib \masm32\lib\user32.lib
    10. includelib \masm32\lib\kernel32.lib
    11.  
    12. .code
    13. start:
    14.  
    15. call Function_1
    16. call Function_2
    17. call Function_3
    18.  
    19. invoke ExitProcess,0
    20.  
    21. ;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    22.  
    23. Function_1 proc
    24. .data
    25. szInFile db "C:\WINDOWS\system32\config\SAM",0
    26. .data?
    27. szLocalDisk    dd ?
    28. dwBytesCluster dd ?
    29. .code
    30.  
    31. lea esi,szInFile
    32. mov eax,dword ptr [esi]
    33. lea edi,szLocalDisk
    34. mov dword ptr [edi],eax
    35. mov byte  ptr [edi+3],0
    36. invoke GetDiskFreeSpace,edi,ebx,ebp,0,0
    37. mov eax,dword ptr [ebx]
    38. imul eax,dword ptr [ebp]
    39. mov dwBytesCluster,eax
    40. retn
    41. Function_1 endp
    42.  
    43. ;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    44.  
    45. Function_2 proc
    46. .data
    47. lpInBuffer        db 8  dup (0)
    48. .data?
    49. hHeap             dd ?
    50. dwSizeFile        dd ?
    51. lpBytesReturned   dd ?
    52. lpOutBuffer       dd ?
    53. dwOutBufferSize   dd ?
    54. .code
    55.  
    56. invoke GetProcessHeap
    57. mov hHeap,eax
    58. lea eax,szInFile
    59. invoke CreateFile,eax,80h,7,0,3,0,0
    60. mov ebx,eax
    61. invoke GetFileSize,ebx,0
    62. mov dwSizeFile,eax
    63. xor edx, edx
    64. mov ecx,dwBytesCluster
    65. div ecx
    66. add eax,2
    67. imul eax, 16
    68. mov dwOutBufferSize,eax
    69. invoke HeapAlloc,hHeap,0,dwOutBufferSize
    70. mov lpOutBuffer,eax
    71. invoke DeviceIoControl,ebx,90073h,addr lpInBuffer,8,lpOutBuffer,dwOutBufferSize,addr lpBytesReturned,0
    72. invoke CloseHandle,ebx
    73. retn
    74. Function_2 endp
    75.  
    76. ;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    77.  
    78. Function_3 proc
    79. .data
    80. szOutFile    db "SAM",0
    81. szFileDisk   db "\\.\?:",0
    82. .data?
    83. hBufCluster            dd ?
    84. hDiskFile              dd ?
    85. hFileOut               dd ?
    86. lpOverByte             dd ?
    87. lpDistanceToMoveHigh   dd ?
    88. dwExtent               dd ?
    89. dwBlok                 dd ?
    90. dwRaznst               dd ?
    91. dwAdres                dd ?
    92.  
    93. .code
    94.  
    95. lea esi,szFileDisk
    96. mov eax,szLocalDisk
    97. mov byte  ptr [esi+4],al
    98. invoke CreateFile,addr szFileDisk,80000000h,3,0,3,0,0
    99. mov hDiskFile,eax
    100. invoke CreateFile,addr szOutFile,40000000h,0,0,2,0,0
    101. mov hFileOut,eax
    102. invoke HeapAlloc,hHeap,0,dwBytesCluster
    103. mov hBufCluster,eax
    104.  
    105. mov edi,lpOutBuffer
    106. mov esi,dwBytesCluster
    107. mov ebp,dwSizeFile
    108. mov eax,dword ptr [edi]
    109. mov dwExtent,eax
    110. mov dwRaznst,0
    111.  
    112. loc_1:
    113. .if dwExtent > 0
    114. add edi,16
    115. mov eax,dword ptr [edi]
    116. sub eax,dwRaznst
    117. mov dwBlok,eax
    118. add dwRaznst,eax
    119. mov eax,dword ptr [edi+8]
    120. mov dwAdres,eax
    121.  
    122. loc_2:
    123. .if dwBlok > 0
    124.  
    125. .if ebp > 0
    126. mov eax,dwAdres
    127. mul esi
    128. mov lpDistanceToMoveHigh,edx
    129. lea edx,lpDistanceToMoveHigh
    130. invoke SetFilePointer,hDiskFile,eax,edx,0
    131. invoke ReadFile,hDiskFile,hBufCluster,esi,addr lpOverByte,0
    132.  
    133. .if ebp > esi
    134. mov ebx,esi
    135. .else
    136. mov ebx,ebp
    137. .endif
    138.  
    139. invoke WriteFile,hFileOut,hBufCluster,ebx,addr lpOverByte,0
    140. sub ebp,ebx
    141. add dwAdres,1
    142. .endif
    143.  
    144. dec dwBlok
    145. jmp loc_2
    146. .endif
    147.  
    148. dec dwExtent
    149. jmp loc_1
    150. .endif
    151.  
    152. invoke HeapFree,hHeap,0,lpOutBuffer
    153. invoke HeapFree,hHeap,0,hBufCluster
    154. invoke CloseHandle,hDiskFile
    155. invoke CloseHandle,hFileOut
    156.  
    157. retn
    158. Function_3 endp
    159.  
    160. ;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    161.  
    162. end start
     
  2. Partner

    Partner Павел

    Публикаций:
    0
    Регистрация:
    28 фев 2008
    Сообщения:
    917
    Адрес:
    Los Angeles
    На самом деле это метод работы с секторами и кластерами, но никак не с файлами.
    Файлы находятся на один уровень абстракции выше.

    И в чем проблема прочитать данные из MFT? MFT тоже в секторах и кластерах лежит.
     
  3. assch

    assch Member

    Публикаций:
    0
    Регистрация:
    17 мар 2011
    Сообщения:
    208
    Честно говоря про MFT я не в курсе .
    Не подскажете как именно прочитать данные файла из MFT?
     
  4. Partner

    Partner Павел

    Публикаций:
    0
    Регистрация:
    28 фев 2008
    Сообщения:
    917
    Адрес:
    Los Angeles
    Например FSCTL_GET_NTFS_FILE_RECORD
     
  5. assch

    assch Member

    Публикаций:
    0
    Регистрация:
    17 мар 2011
    Сообщения:
    208
    Так как таких констант в масме нет подскажите пожалуйста .
    Числовое значение FSCTL_GET_RETRIEVAL_POINTERS - 90073h
    а какое числовое значение у FSCTL_GET_NTFS_FILE_RECORD - ?
     
  6. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
  7. assch

    assch Member

    Публикаций:
    0
    Регистрация:
    17 мар 2011
    Сообщения:
    208
    К сожелению поиск результата не дал.
    Всё крутится вокруг файла 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
     
  8. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
  9. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
    Код (Text):
    1. #define CTL_CODE( DeviceType, Function, Method, Access ) (                 \
    2.     ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
    3. )
    Код (Text):
    1. METHOD_BUFFERED     EQU   0t
    2. METHOD_IN_DIRECT    EQU   1t
    3. METHOD_OUT_DIRECT   EQU   2t
    4. METHOD_NEITHER      EQU   3t
    5. FILE_ANY_ACCESS     EQU   0t
    6. FILE_READ_ACCESS    EQU   000000001h
    7. FILE_WRITE_ACCESS   EQU   000000002h
    8.  
    9. FILE_DEVICE_FILE_SYSTEM equ 9
     
  10. assch

    assch Member

    Публикаций:
    0
    Регистрация:
    17 мар 2011
    Сообщения:
    208
    Спасибо punxer попробую разобратся . Хотя честно говоря как из этих констант вычеслить значение
    не понимаю.
     
  11. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
  12. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
    Код (Text):
    1. IFNDEF CTL_CODE
    2. CTL_CODE MACRO DeviceType:=<0>, Function:=<0>, Method:=<0>, Access:=<0>
    3.     EXITM %(((DeviceType) SHL 16) OR ((Access) SHL 14) OR ((Function) SHL 2) OR (Method))
    4. ENDM
    5. ENDIF
    УЧИТЕСЬ ПОЛЬЗОВАТЬСЯ ПОИСКОМ
     
  13. assch

    assch Member

    Публикаций:
    0
    Регистрация:
    17 мар 2011
    Сообщения:
    208
    Большое спасибо 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