Работа с Zone.Identifier на Ассемблере
Несколько лет назад я выкладывал пару статей на тему блокировки файлов с помощью альтернативных файловых потоков и Zone.Identifier. Там вся работа с ними выполнялась или средствами самой системы Windows, или сторонними приложениями. Настало время написать собственное приложение.Сперва немного теории. За блокировку файлов отвечает COM-объект IZoneIdentifier для работы с которым нам потребуется несколько структур, GUID'ов и констант, про которые не знает FASM.
Code (Assembler) : Убрать нумерацию
- ; GUID {0968E258-16C7-4DBA-AA86-462DD61E31A3}
- CLSID_PersistentZoneIdentifier \
- dd 00968E258h
- dw 016C7h
- dw 04DBAh
- db 0AAh, 086h, 046h, 02Dh, 0D6h, 01Eh, 031h, 0A3h
- ; GUID {CD45F185-1B21-48E2-967B-EAD743A8914E}
- IID_IZoneIdentifier \
- dd 0CD45F185h
- dw 01B21h
- dw 048E2h
- db 096h, 07Bh, 0EAh, 0D7h, 043h, 0A8h, 091h, 04Eh
- ; GUID {0000010B-0000-0000-C000-000000000046}
- IID_IPersistFile \
- dd 00000010Bh
- dw 00000h
- dw 00000h
- db 0C0h, 000h, 000h, 000h, 000h, 000h, 000h, 046h
- ; IID_IZoneIdentifier Interface
- struct IZoneIdentifier
- ; IUnknown
- QueryInterface dd ? ; 000h
- AddRef dd ? ; 004h
- Release dd ? ; 008h
- ; IZoneIdentifier
- GetId dd ? ; 00Ch
- SetId dd ? ; 010h
- Remove dd ? ; 014h
- ends
- ; IID_IPersistFile Interface
- struct IPersistFile
- ; IUnknown
- QueryInterface dd ? ; 000h
- AddRef dd ? ; 004h
- Release dd ? ; 008h
- ; IPersistFile
- GetClassID dd ? ; 00Ch
- IsDirty dd ? ; 010h
- Load dd ? ; 014h
- Save dd ? ; 018h
- SaveCompleted dd ? ; 01Ch
- GetCurFile dd ? ; 020h
- ends
- CLSCTX_INPROC_SERVER = 1
- S_OK = 0
- STGM_READ = 0
Как вы знаете из предыдущих статей, идентификатор зоны не может существовать сам по себе, он должен быть привязан к файлу. Для связки интерфейса IZoneIdentifier с файлом на диске требуется сперва получить интерфейс IPersistFile. После этого для работы с методами GetId и Remove нужно попробовать загрузить файл при помощи метода Load. Почему именно "попробовать"? Дело в том, что если файл был ранее разблокирован или у него вообще не было альтернативного файлового потока Zone.Identifier, то при вызове метод загрузки вернет ошибку ERR_FILE_NOT_FOUND. Метод SetId предварительной загрузки файла не требует. Пути к файлам обязательно должны быть полными и записаны в юникоде.
Начнем программирование с получения идентификатора зоны файла. Тут все просто. Проверяем наличие альтернативного потока Zone.Identifier в момент загрузки файла, если он присутствует, то запрашиваем его значение.
Code (Assembler) : Убрать нумерацию
- ; Инициализировать COM-объект
- invoke CoInitialize,NULL
- ; Получить полный путь к файлу
- invoke GetFullPathName,fname,MAX_PATH,szPath,NULL
- or eax,eax
- jz loc_exit
- ; Создать объект
- invoke CoCreateInstance,CLSID_PersistentZoneIdentifier,NULL,\
- CLSCTX_INPROC_SERVER,IID_IZoneIdentifier,pZoneId
- cmp eax,S_OK
- jne loc_exit
- ; Получить интерфейс IPersistFile объекта
- mov eax,[pZoneId]
- mov eax,[eax]
- stdcall dword [eax+IZoneIdentifier.QueryInterface],[pZoneId],\
- IID_IPersistFile,pPFile
- or eax,eax
- jnz loc_done2
- ; Попробовать загрузить файл
- mov eax,[pPFile]
- mov eax,[eax]
- stdcall dword [eax+IPersistFile.Load],[pPFile],\
- szPath,STGM_READ
- cmp eax,S_OK
- je @f
- ; Идентификатора нет
- jmp loc_done1
- @@:
- ; Получить значение идентификатора
- mov eax,[pZoneId]
- mov eax,[eax]
- stdcall dword [eax+IZoneIdentifier.GetId],[pZoneId],\
- dZoneID
- or eax,eax
- jnz loc_done1
- ; [dZoneID] = значение идентификатора
- ; Прибраться за собой
- loc_done1:
- mov eax,[pPFile]
- mov eax,[eax]
- stdcall [eax+IPersistFile.Release],[pPFile]
- loc_done2:
- mov eax,[pZoneId]
- mov eax,[eax]
- stdcall [eax+IZoneIdentifier.Release],[pZoneId]
- loc_exit:
- ; Удалить объект
- invoke CoUninitialize
Code (Assembler) : Убрать нумерацию
- ; Инициализировать COM-объект
- invoke CoInitialize,NULL
- ; Получить полный путь к файлу
- invoke GetFullPathName,fname,MAX_PATH,szPath,NULL
- or eax,eax
- jz loc_exit
- ; Создать объект
- invoke CoCreateInstance,CLSID_PersistentZoneIdentifier,NULL,\
- CLSCTX_INPROC_SERVER,IID_IZoneIdentifier,pZoneId
- cmp eax,S_OK
- jne loc_exit
- ; Получить интерфейс IPersistFile объекта
- mov eax,[pZoneId]
- mov eax,[eax]
- stdcall dword [eax+IZoneIdentifier.QueryInterface],[pZoneId],\
- IID_IPersistFile,pPFile
- or eax,eax
- jnz loc_done2
- ; Установить идентификатор
- mov eax,[pZoneId]
- mov eax,[eax]
- stdcall dword [eax+IZoneIdentifier.SetId],[pZoneId],\
- URLZONE_INTERNET
- or eax,eax
- jnz loc_done2
- ; Применить изменения
- mov eax,[pPFile]
- mov eax,[eax]
- stdcall dword [eax+IPersistFile.Save],[pPFile],\
- szPath,TRUE
- or eax,eax
- jnz loc_done1
- ; Новое значение идентификатора установлено
- ; Прибраться за собой
- loc_done1:
- mov eax,[pPFile]
- mov eax,[eax]
- stdcall [eax+IPersistFile.Release],[pPFile]
- loc_done2:
- mov eax,[pZoneId]
- mov eax,[eax]
- stdcall [eax+IZoneIdentifier.Release],[pZoneId]
- loc_exit:
- ; Удалить объект
- invoke CoUninitialize
Code (Assembler) : Убрать нумерацию
- ; Инициализировать COM-объект
- invoke CoInitialize,NULL
- ; Получить полный путь к файлу
- invoke GetFullPathName,fname,MAX_PATH,szPath,NULL
- or eax,eax
- jz loc_exit
- ; Создать объект
- invoke CoCreateInstance,CLSID_PersistentZoneIdentifier,NULL,\
- CLSCTX_INPROC_SERVER,IID_IZoneIdentifier,pZoneId
- cmp eax,S_OK
- jne loc_exit
- ; Получить интерфейс IPersistFile объекта
- mov eax,[pZoneId]
- mov eax,[eax]
- stdcall dword [eax+IZoneIdentifier.QueryInterface],[pZoneId],\
- IID_IPersistFile,pPFile
- or eax,eax
- jnz loc_done2
- ; Попробовать загрузить файл
- mov eax,[pPFile]
- mov eax,[eax]
- stdcall dword [eax+IPersistFile.Load],[pPFile],\
- szPath,STGM_READ
- cmp eax,S_OK
- je @f
- ; Идентификатора нет
- jmp loc_done1
- @@:
- ; Удалить идентификатор
- mov eax,[pZoneId]
- mov eax,[eax]
- stdcall dword [eax+IZoneIdentifier.Remove],[pZoneId]
- or eax,eax
- jnz loc_done1
- ; Применить изменения
- mov eax,[pPFile]
- mov eax,[eax]
- stdcall dword [eax+IPersistFile.Save],[pPFile],\
- szPath,TRUE
- or eax,eax
- jnz loc_done1
- ; Идентификатор успешно удален
- ; Прибраться за собой
- loc_done1:
- mov eax,[pPFile]
- mov eax,[eax]
- stdcall [eax+IPersistFile.Release],[pPFile]
- loc_done2:
- mov eax,[pZoneId]
- mov eax,[eax]
- stdcall [eax+IZoneIdentifier.Release],[pZoneId]
- loc_exit:
- ; Удалить объект
- invoke CoUninitialize
Просмотров: 538 | Комментариев: 5
Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
ManHunter
(21.05.2023 в 20:49):
Зрители аплодируют, аплодируют, закончили аплодировать. Можно было бы упомянуть, что в Zone.Identifier кроме идентификатора содержится разная полезная информация типа ссылки на источник файла, но зачем? Только хардкор, только DeleteFile.
индеклерк
(21.05.2023 в 18:59):
invoke DeleteFile, "c:\setup.exe:Zone.Identifier"
Vladimir
(12.05.2023 в 15:19):
Знаю, можно и через PowerShell, просто нравится ваш софт за минималистичность и скорость работы. Я так ваши Total Exif Annihilator и Tiny Image Converter на кнопки приспособил, удобно.
ManHunter
(12.05.2023 в 15:10):
Вряд ли. Получается ровно столько же движений, как если разблокировать файл через меню свойств в Проводнике. А для командной строки есть Streams от Марка Руссиновича.
Vladimir
(12.05.2023 в 15:07):
Если бы вы сделали поддержку командной строки для remove_zone.exe, то было бы удобно повесить его на кнопку в Тотале. Вдруг вам захочется.
Добавить комментарий
Заполните форму для добавления комментария