Форум программистов, компьютерный форум, киберфорум
VBA
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.74/34: Рейтинг темы: голосов - 34, средняя оценка - 4.74
114 / 11 / 1
Регистрация: 01.05.2014
Сообщений: 133

Как подружить ассемблер и vba?

16.01.2016, 14:43. Показов 7374. Ответов 40
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
хочу передать свой небольшой опыт, может кому пригодится (2 дня мучений), как можно передавать ваши данные в asm (byref и byval) и вызывать из vba ваши собственные процедуры и функции на asm. кроме того как возвращать значения из asm процедур. к сожалению по форуму похожей информации я не нашёл
Повторяю, информация краткая, не все вопросы освещены, может кто изложит подробнее.
Вызов процедур и функций api, я думаю не у кого не вызывает особых затруднений.
Visual Basic
1
2
3
4
5
6
dim Hndl as long
Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Sub apiUsing()
    perem=CloseHandle(Hndl)
End Sub
без особых проблем
свои написанные на asm функции лучше включать в .DLL библиотеки а далее то же самое
пример на masm, код линейный для облегчения восприятия.
Функция этой библиотеки PrWord принимает от VBA программы, две byref переменные (ссылки) на строковые значения 2х последовательных элементов массива, переводит эти адреса в ASCII символы и выводит эти адреса через MessageBox, после этого записывает эти значения по полученным byref адресам.
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
.386
.model flat,stdcall
option casemap:none
include windows.inc
include user32.inc
include kernel32.inc
includelib user32.lib
includelib kernel32.lib
.DATA
    Mem1                    DD 0
    Mem2            DD 0
    Mem1str         db 0,0,0,0,0,0,0,0,0
    Mem2str         db 0,0,0,0,0,0,0,0,0    
.code
DllEntry proc hInstance:HINSTANCE, reason:DWORD, reserved1:DWORD
    mov  eax,TRUE
    ret
DllEntry Endp
PrWord proc perMess:dword, perMess1:dword
    mov ebx,[perMess]; двойное вложение адресов.(2х ступенчатая ссылка) считывает адрес пересылаемого адреса
    mov eax,[ebx]; считываем адрес, реального адреса переменной
    mov [Mem1],eax; сохраняем во временный буфер итд
    mov esi,offset Mem1
    mov ebx,[perMess1]
    mov eax,[ebx]
    mov Mem2,eax
    mov ebx,offset Mem1str
    Call prMes
    invoke MessageBoxA,NULL,offset Mem1str,offset pMess, NULL
    mov esi,offset Mem2
    mov ebx,offset Mem2str
    Call prMes
    invoke MessageBoxA,NULL,offset Mem2str,offset pMess, NULL
    mov esi,[Mem2]
    mov eax,dword ptr [Mem2str]
    mov [esi],eax
    mov eax,dword ptr [Mem2str+4]
    mov [esi+4],eax
    mov esi,[Mem1]
    mov eax,dword ptr [Mem1str]
    mov [esi],eax
    mov eax,dword ptr [Mem1str+4]
    mov [esi+4],eax
    ret
prMes: mov cx,4 ; перевод 4 байтных значений в ASCII si -источник bx -буфер
nexb:   mov al,byte ptr[esi]
    mov ah,al
    and ax,0ff0h
    shr al,4
    cmp al,10
    sbb al,69h
    das
    mov [ebx],byte ptr al
    inc ebx
    mov al,ah   
    cmp al,10
    sbb al,69h
    das
    mov [ebx],byte ptr al
    inc ebx
    inc esi
    dec cx
    jnz nexb
    retn
    ret
PrWord endp
End DllEntry
код VBA
программа создаёт стриноговый массив,заносит в 1ый и 2ой элементы значения, выводит их до выполнения PrWord и после с измененными значениями.
Visual Basic
1
2
3
4
5
6
7
8
9
Private Declare Function RPr Lib "G:\Progecte\ddd.DLL" (ByRef perMess As String, ByRef perMess1 As String) As Long
Dim kk(25) As String
Sub VBArefsub()
    kk(0) = "12345678"
    kk(1) = "12345678"
    Debug.Print kk(0), kk(1)
    l = PrWord(kk(0), kk(1))
    Debug.Print kk(0), kk(1)
End Sub
Пересылка byval вообще без проблем передаётся адрес копии пересылаемой переменной те есть в пересылаемых данных уже адрес копии данных. без 2йного вложения и как следствие оригинальные данные вы изменить не сможете.
возвращение данных из asm - перед return запишите данные в eax.
Не получилось возвращать значения типа стринг, VBA вылетает. я думаю что возращается макс 4 х байтовое значение, ссылки на буфер в памяти вернуть не удаётся. Может у когото получится. опишите как.
Забавные моменты которые выяснились, когда запускаешь программу, огромные разброс адресов двух соседних элементов массива, (вообще непонятно почему) больше 30000000h байт.
Спасибо за внимание жду дополнений
3
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
16.01.2016, 14:43
Ответы с готовыми решениями:

Ассемблер в паскале: как загрузить массив во встроенный ассемблер и произвести над любым из его чисел сложение(вычитание).
хочу написать программу в паскале с использованием встроенного ассемблера, но прежде чем начать споткнулся на таких вопросах:Не знаю как...

Как подружить VB и 1С?
А никто из здешних не пытался сдружить 1С и ВБ? Насколько это реально и имеет смысл? Я хотел бы всю бизнес-логику уложить в ActiveX и...

Как подружить клиентов 8.0.5 и 9.0.2?
На компе(2000) установлен сервер 9 , 9iDS. Как установить клиента 8 0 5 , чтобы настройки клиента 9 не слетали. Те нужно совместное...

40
 Аватар для Estimable
195 / 14 / 1
Регистрация: 02.01.2017
Сообщений: 223
17.12.2018, 10:54
Студворк — интернет-сервис помощи студентам
Да... Всё это в вопросительной интонации. Забыл поставить знаки вопроса)

Добавлено через 32 секунды
Спасибо.
0
 Аватар для Estimable
195 / 14 / 1
Регистрация: 02.01.2017
Сообщений: 223
19.01.2019, 09:04
Спустя некоторое время я решил расказать как работать с компаунд файлом xls.
Начнём с теории.

Весь компаунд фаил xls состоит из блоков(т.н. секторов) по 512 байт (иногда 4096 байт).
Поэтому размер файла должен без остатка делится на 512(4096), если нет lock bytes.


Основную часть документа составляет содержимое книги эксель(глабольное описание книги+содержимое листов),
содержимое книги vba (модули vba и что-то ещё), информация о документе внутренняя и внешняя и др.

Остальная часть (довольно внушительная) это таблицы которые соединяют воедино все секторы данных
в документе, Т.к секторы данных(рабочей книги, книги vba и др.) лежат в файле в разных
местах.

В основном такая разрозненность и дырки внутри секторов(типа FFFFFFFF) возникают из-за того,
что программы при сохранении документа, дополнют его или затирают некоторые места а не переписывают фаил целиком.
Это было придуманно для ускорения сохранения. Но вы разумеется можете расположить все секторы последовательно.

Мы будем рассматривать только строение рабочей книги, макросы например можно записать просто скопировав
данные из готового файла xls.

Начнём со строения этих таблиц и постепенно доберёмся до строения рабочей книги.
Я прилагаю самописный декомпилятор xls файлов, чтобы помочь вам разобраться в строении этих таблиц.

Всего таблиц 4 вида, я буду называть их в соответствии с нотацией OpenOffice, которая содержится в
приложеных ранее файлах: compdocfileformat.pdf и excelfileformat.pdf. Вот их имена(в порядке убывания
старшинства): Msat, Sat, Ssat, Directory.

Как и всё в документе, они тоже состоят из секторов и тоже раскиданы по файлу.Начать их обьеденять можно
начав с самой старшей таблицы - Msat. Её назначение - соединение всех секторов таблицы Sat.
Есть несколько версий её происхождения раскажу об этом позже, а то затрудню
понимание статьи.

Таблица Msat используется один раз, как только она будет собрана, о ней можно будет забыть.
Её прелесть в том что последние 4 байта каждого сектора содержат номер следующего сектора, который подсоединяется
к текущему.

Дам схематическое обозначение, такое же как в моём xls декомпиляторе. Таблицу msat я расположил вертикально,
а границы её секторов очерчены полосой. секторы msat тут маленькие - 16 байт или 4 четырёх байтовых номера.
Всего три сектора Msat.
Таблицу sat я расположил горизонтально. Тут размер её сектора тоже уменьшен, до 32 байт или 8 четырёх байтовых
номеров. Секторы sat тут разделены пустым пространством. Всего 8 секторов Sat.



Msat Sat

01000000 FDFFFFFF 02000000 03000000 04000000
05000000 06000000 07000000 08000000


02000000 09000000 0A000000 0B000000 0C000000
0D000000 0E000000 0F000000 10000000



03000000 11000000 12000000 13000000 14000000
15000000 16000000 17000000 18000000


7F1A0000 <- последний 4х байтовый номер это ссылка на следующий сектор ssat
-------------------------------------------------------

04000000 19000000 1A000000 1B000000 1C000000
1D000000 1E000000 1F000000 20000000


05000000 21000000 22000000 23000000 24000000
25000000 26000000 27000000 28000000


06000000 29000000 2A000000 2B000000 2C000000
2D000000 2E000000 2F000000 30000000


801A0000 <- последний 4х байтовый номер это ссылка на следующий сектор ssat
-------------------------------------------------------

07000000 31000000 32000000 33000000 34000000
35000000 36000000 37000000 38000000


08000000 39000000 3A000000 3B000000 3C000000
3D000000 FEFFFFFF FFFFFFFF FFFFFFFF


FFFFFFFF <-дырка



FFFFFFFF <-дырка
-------------------------------------------------------



Из этой схемы видно что последний номер в таблице msat это не номер - это указатель на следующий сектор.
Кроме случая когда в последнем номере будет дырка - FFFFFFFF. Когда данные в таблице msat заканчиваются,
то остальные 4х байтовые номера в секторе заполняются значением FFFFFFFF.

Вы можете найти дырки и в таблице sat в строке 3D000000 FEFFFFFF FFFFFFFF FFFFFFFF. В данном случае они
тоже применяются для заполнения оставшейся части сектора.

Так же дырки могут возникать и среди нормальных номеров в Msat и в Sat, тогда эти дырки не учитываются
при составлении секторов, и на них не бывает ссылок.


В таблице sat вы видите что перед оканчивающими дырками в строке 3D000000 FEFFFFFF FFFFFFFF FFFFFFFF
стоит метка FEFFFFFF. Это метка "конец цепочки секторов". Так как цепочка у нас одна. То у неё одна концовка.
Потом поймёте про цепочки.

Если бы цепочка была не одна, то метка FEFFFFFF встречалась бы в sat несколько раз.
В самом начале таблицы Sat вы видите метку FDFFFFFF означающую что этот номер используется таблицей Sat,
эта метка всегда ставится в самом начале таблицы Sat. Ещё она встречается среди нормальных номеров таблицы
sat. Пока на этот счёт не распространяюсь, т.к мне самому непонятно зачем она ставится среди номеров sat.

Вы увидели схему в моём представлении и уже в составленом виде, в реальности т.е внутри файла всё выглядит
по-другому и вам надо составить все секторы самому.

Msat начинается с 4ch(76го) байта заголовка.Помните что счёт в файле идёт от нуля, если вы считаете от единицы то
это 77й байт. Открываем фаил в любом hex редакторе и рассматриваем заголовок. Он тоже является
сектором = 512байт(или 4096 тогда остальные байты после с 512го по 4096 заполняются нулями).


D0 CF 11 E0 A1 B1 1A E1 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 3E 00 03 00 FE FF 09 00
06 00 00 00 00 00 00 00 00 00 00 00 9A 02 00 00
01 00 00 00 00 00 00 00 00 10 00 00 D4 4C 01 00
02 00 00 00 7F 36 00 00 05 00 00 00 ^ ^ ^ ^
в заголовке по смещению 3сh находится номер следующего сектора msat

00 00 00 00<-здесь начинается Msat
72 00 00 00 F3 00 00 00 74 01 00 00 F5 01 00 00
76 02 00 00 F7 02 00 00 78 03 00 00 F9 03 00 00
7A 04 00 00 FB 04 00 00 7C 05 00 00 FD 05 00 00 000
7E 06 00 00 FF 06 00 00 80 07 00 00 F1 07 00 00 00 00
72 08 00 00 F3 08 00 00 74 09 00 00 F5 09 00 00 00 00
76 0A 00 00 F7 0A 00 00 78 0B 00 00 F9 0B 00 00 00 00
7A 0C 00 00 FB 0C 00 00 7C 0D 00 00 FD 0D 00 00 00 00
7E 0E 00 00 FF 0E 00 00 80 0F 00 00 F1 0F 00 00 00 00
72 10 00 00 F3 10 00 00 74 11 00 00 F5 11 00 00 000
76 12 00 00 F7 12 00 00 78 13 00 00 F9 13 00 00
7A 14 00 00 FB 14 00 00 7C 15 00 00 FD 15 00 00
7E 16 00 00 FF 16 00 00 80 17 00 00 F1 17 00 00
72 18 00 00 F3 18 00 00 74 19 00 00 F5 19 00 00
76 1A 00 00 F7 1A 00 00 78 1B 00 00 F9 1B 00 00
7A 1C 00 00 FB 1C 00 00 7C 1D 00 00 FD 1D 00 00
7E 1E 00 00 FF 1E 00 00 80 1F 00 00 F1 1F 00 00
72 20 00 00 F3 20 00 00 74 21 00 00 F5 21 00 00
76 22 00 00 F7 22 00 00 78 23 00 00 F9 23 00 00
7A 24 00 00 FB 24 00 00 7C 25 00 00 FD 25 00 00
7E 26 00 00 FF 26 00 00 80 27 00 00 F1 27 00 00
72 28 00 00 F3 28 00 00 74 29 00 00 F5 29 00 00
76 2A 00 00 F7 2A 00 00 78 2B 00 00 F9 2B 00 00
7A 2C 00 00 FB 2C 00 00 7C 2D 00 00 FD 2D 00 00
7E 2E 00 00 FF 2E 00 00 80 2F 00 00 F1 2F 00 00
72 30 00 00 F3 30 00 00 74 31 00 00 F5 31 00 00
76 32 00 00 F7 32 00 00 78 33 00 00 F9 33 00 00
7A 34 00 00 FB 34 00 00 7C 35 00 00 FD 35 00 00
^ ^ ^ ^
последний четырёхбайтовый номер в заголовке не является
указателем на следующий номер msat.


В заголовке размещены только 109 номеров MSAT, а в обычном секторе их помещается 128.
видите что последний номер в заголовке это не указатель, как следовало бы ожидать,
а просто номер. В заголовке правило указателя Msat не соблюдается, вместо этого
номер следующего сектора указан по смещению 3сh(т.е 60й байт считая от нуля).
Здесь может стоять значение FEFFFFFF "конец цепочки секторов", если не существует
других msat секторов кроме заголовка.


Итак следующий сектор msat имеет номер D4 4C 01 00. Нам надо его считать.
Чтобы его считать надо найти где он расположен в файле.
Его позиция в файле выводится из его номера по формуле offset=(number+1h)*200h
или дословно:
позиция в файле = номер сектора+1(т.е после заголовка, а не от начала файла)*512байтов
(т.к как нам надо получить растояние в байтах).



-перевернём байты нашего номера D44C0100 (т.к в файле применяется обратный порядок
расположения байт, что в разных файлах встречается довольно часто)=00014CD4h

-добавим шестнадцатеричную единицу(заголовочный сектор) 00014CD4h+1h=00014CD5h

-умножим на шестнадцатеричное 200h(или на 512 байт) 00014CD5h*200h=299AA00h


значит следующий сектор MSAT по адресу 299AA00h или 43624960й байт в файле
идём по этому смещению.

7E 36 00 00 00 37 00 00 71 37 00 00 F2 37 00 00
73 38 00 00 F4 38 00 00 75 39 00 00 F6 39 00 00
77 3A 00 00 F8 3A 00 00 79 3B 00 00 FA 3B 00 00
7B 3C 00 00 FC 3C 00 00 7D 3D 00 00 FE 3D 00 00
7F 3E 00 00 00 3F 00 00 71 3F 00 00 F2 3F 00 00
73 40 00 00 F4 40 00 00 75 41 00 00 F6 41 00 00
77 42 00 00 F8 42 00 00 79 43 00 00 FA 43 00 00 111
7B 44 00 00 FC 44 00 00 7D 45 00 00 FE 45 00 00 11 11
7F 46 00 00 00 47 00 00 71 47 00 00 F2 47 00 00 11 11
73 48 00 00 F4 48 00 00 75 49 00 00 F6 49 00 00 11
77 4A 00 00 F8 4A 00 00 79 4B 00 00 FA 4B 00 00 11
7B 4C 00 00 FC 4C 00 00 7D 4D 00 00 FE 4D 00 00 11
7F 4E 00 00 00 4F 00 00 71 4F 00 00 F2 4F 00 00 11111111
73 50 00 00 F4 50 00 00 75 51 00 00 F6 51 00 00
77 52 00 00 F8 52 00 00 79 53 00 00 FA 53 00 00
7B 54 00 00 FC 54 00 00 7D 55 00 00 FE 55 00 00
7F 56 00 00 00 57 00 00 71 57 00 00 F2 57 00 00
73 58 00 00 F4 58 00 00 75 59 00 00 F6 59 00 00
77 5A 00 00 F8 5A 00 00 79 5B 00 00 FA 5B 00 00
7B 5C 00 00 FC 5C 00 00 7D 5D 00 00 FE 5D 00 00
7F 5E 00 00 00 5F 00 00 71 5F 00 00 F2 5F 00 00
73 60 00 00 F4 60 00 00 75 61 00 00 F6 61 00 00
77 62 00 00 F8 62 00 00 79 63 00 00 FA 63 00 00
7B 64 00 00 FC 64 00 00 7D 65 00 00 FE 65 00 00
7F 66 00 00 00 67 00 00 71 67 00 00 F2 67 00 00
73 68 00 00 F4 68 00 00 75 69 00 00 F6 69 00 00
77 6A 00 00 F8 6A 00 00 79 6B 00 00 FA 6B 00 00
7B 6C 00 00 FC 6C 00 00 7D 6D 00 00 FE 6D 00 00
7F 6E 00 00 00 6F 00 00 71 6F 00 00 F2 6F 00 00
73 70 00 00 F4 70 00 00 75 71 00 00 F6 71 00 00
77 72 00 00 F8 72 00 00 79 73 00 00 FA 73 00 00
7B 74 00 00 FC 74 00 00 7D 75 00 00 FF 75 00 00
^ ^ ^ ^
последний четырёхбайтовый номер в секторе msat является
указателем на следующий номер msat.


И вот мы видим продолжение нашей таблицы msat. Легко заметить похожий тип номеров
и характерный их прирост через один номер.
Номеров в секторе 128 и последний номер уже является указателем.

следуя формуле offset=(number+1h)*200h вычислим смещение следующего сектора Msat

-перевернём байты нашего номера FF 75 00 00 =000075FFh

-добавим шестнадцатеричную единицу 000075FFh+1h=00007600h

-умножим на шестнадцатеричное 200h(или на десятичное 512) 00007600h*200h=EC0000h


значит следующий сектор MSAT по адресу EC0000h. Продолжим наш путь.

FE 75 00 00 80 76 00 00 F1 76 00 00 72 77 00 00
F3 77 00 00 74 78 00 00 F5 78 00 00 76 79 00 00
F7 79 00 00 78 7A 00 00 F9 7A 00 00 7A 7B 00 00
FB 7B 00 00 7C 7C 00 00 FD 7C 00 00 7E 7D 00 00
FF 7D 00 00 80 7E 00 00 F1 7E 00 00 72 7F 00 00
F3 7F 00 00 74 80 00 00 F5 80 00 00 76 81 00 00 222
F7 81 00 00 78 82 00 00 F9 82 00 00 7A 83 00 00 22 222
FB 83 00 00 7C 84 00 00 FD 84 00 00 7E 85 00 00 22
FF 85 00 00 80 86 00 00 F1 86 00 00 72 87 00 00 22
F3 87 00 00 74 88 00 00 F5 88 00 00 76 89 00 00 22
F7 89 00 00 78 8A 00 00 F9 8A 00 00 7A 8B 00 00 22
FB 8B 00 00 7C 8C 00 00 FD 8C 00 00 7E 8D 00 00 22222222
FF 8D 00 00 80 8E 00 00 F1 8E 00 00 72 8F 00 00
F3 8F 00 00 74 90 00 00 F5 90 00 00 76 91 00 00
F7 91 00 00 78 92 00 00 F9 92 00 00 7A 93 00 00
FB 93 00 00 7C 94 00 00 FD 94 00 00 7E 95 00 00
FF 95 00 00 80 96 00 00 F1 96 00 00 72 97 00 00
F3 97 00 00 74 98 00 00 F5 98 00 00 76 99 00 00
F7 99 00 00 78 9A 00 00 F9 9A 00 00 7A 9B 00 00
FB 9B 00 00 7C 9C 00 00 FD 9C 00 00 7E 9D 00 00
FF 9D 00 00 80 9E 00 00 F1 9E 00 00 72 9F 00 00
F3 9F 00 00 74 A0 00 00 F5 A0 00 00 76 A1 00 00
F7 A1 00 00 78 A2 00 00 F9 A2 00 00 7A A3 00 00
FB A3 00 00 7C A4 00 00 FD A4 00 00 7E A5 00 00
FF A5 00 00 80 A6 00 00 F1 A6 00 00 72 A7 00 00
F3 A7 00 00 74 A8 00 00 F5 A8 00 00 76 A9 00 00
F7 A9 00 00 78 AA 00 00 F9 AA 00 00 7A AB 00 00
FB AB 00 00 7C AC 00 00 FD AC 00 00 7E AD 00 00
FF AD 00 00 80 AE 00 00 F1 AE 00 00 72 AF 00 00
F3 AF 00 00 74 B0 00 00 F5 B0 00 00 76 B1 00 00
F7 B1 00 00 78 B2 00 00 F9 B2 00 00 7A B3 00 00
FB B3 00 00 7C B4 00 00 FD B4 00 00 7F B5 00 00
^ ^ ^ ^
последний четырёхбайтовый номер в секторе msat является
указателем на следующий номер msat.


Всё понятно, давайте дальше.

7FB50000=0000b57f=0000b57fh+1h=B580h*200 h=16B0000h

Идём по этому смещению:



73 B7 00 00 F4 B7 00 00 75 B8 00 00 F6 B8 00 00
77 B9 00 00 F8 B9 00 00 79 BA 00 00 FA BA 00 00
7B BB 00 00 FC BB 00 00 7D BC 00 00 FE BC 00 00
7F BD 00 00 00 BE 00 00 71 BE 00 00 F2 BE 00 00
73 BF 00 00 F4 BF 00 00 75 C0 00 00 F6 C0 00 00
77 C1 00 00 F8 C1 00 00 79 C2 00 00 FA C2 00 00
7B C3 00 00 FC C3 00 00 7D C4 00 00 FE C4 00 00 333
7F C5 00 00 00 C6 00 00 71 C6 00 00 F2 C6 00 00 33 333
73 C7 00 00 F4 C7 00 00 75 C8 00 00 F6 C8 00 00 333
77 C9 00 00 F8 C9 00 00 79 CA 00 00 FA CA 00 00 33
7B CB 00 00 FC CB 00 00 7D CC 00 00 FE CC 00 00 333
7F CD 00 00 00 CE 00 00 71 CE 00 00 F2 CE 00 00 33 333
73 CF 00 00 F4 CF 00 00 75 D0 00 00 F6 D0 00 00 333
77 D1 00 00 F8 D1 00 00 79 D2 00 00 FA D2 00 00
7B D3 00 00 FC D3 00 00 7D D4 00 00 FE D4 00 00
7F D5 00 00 00 D6 00 00 71 D6 00 00 F2 D6 00 00
73 D7 00 00 F4 D7 00 00 75 D8 00 00 F6 D8 00 00
77 D9 00 00 F8 D9 00 00 79 DA 00 00 FA DA 00 00
7B DB 00 00 FC DB 00 00 7D DC 00 00 FE DC 00 00
7F DD 00 00 00 DE 00 00 71 DE 00 00 F2 DE 00 00
73 DF 00 00 F4 DF 00 00 75 E0 00 00 F6 E0 00 00
77 E1 00 00 F8 E1 00 00 79 E2 00 00 FA E2 00 00
7B E3 00 00 FC E3 00 00 7D E4 00 00 FE E4 00 00
7F E5 00 00 00 E6 00 00 71 E6 00 00 F2 E6 00 00
73 E7 00 00 F4 E7 00 00 75 E8 00 00 F6 E8 00 00
77 E9 00 00 F8 E9 00 00 79 EA 00 00 FA EA 00 00
7B EB 00 00 FC EB 00 00 7D EC 00 00 FE EC 00 00
7F ED 00 00 00 EE 00 00 71 EE 00 00 F2 EE 00 00
73 EF 00 00 F4 EF 00 00 75 F0 00 00 F6 F0 00 00
77 F1 00 00 F8 F1 00 00 79 F2 00 00 FA F2 00 00
7B F3 00 00 FC F3 00 00 7D F4 00 00 FF F4 00 00
^ ^ ^ ^
последний четырёхбайтовый номер в секторе msat является
указателем на следующий номер msat.


FFF40000 =0000f4ff=0000f4ffh+1h=F500h*200h=1EA000 0h


FE F4 00 00 80 F5 00 00 F1 F5 00 00 72 F6 00 00
F3 F6 00 00 74 F7 00 00 F5 F7 00 00 76 F8 00 00
F7 F8 00 00 78 F9 00 00 F9 F9 00 00 7A FA 00 00
FB FA 00 00 7C FB 00 00 FD FB 00 00 7E FC 00 00
FF FC 00 00 80 FD 00 00 F1 FD 00 00 72 FE 00 00
F3 FE 00 00 74 FF 00 00 F5 FF 00 00 76 00 01 00
F7 00 01 00 78 01 01 00 F9 01 01 00 7A 02 01 00 44
FB 02 01 00 7C 03 01 00 FD 03 01 00 7E 04 01 00 444
FF 04 01 00 80 05 01 00 F1 05 01 00 72 06 01 00 4444
F3 06 01 00 74 07 01 00 F5 07 01 00 76 08 01 00 44 44
F7 08 01 00 78 09 01 00 F9 09 01 00 7A 0A 01 00 44 44
FB 0A 01 00 7C 0B 01 00 FD 0B 01 00 7E 0C 01 00 44444444
FF 0C 01 00 80 0D 01 00 F1 0D 01 00 72 0E 01 00 44
F3 0E 01 00 74 0F 01 00 F5 0F 01 00 76 10 01 00 44
F7 10 01 00 78 11 01 00 F9 11 01 00 7A 12 01 00
FB 12 01 00 7C 13 01 00 FD 13 01 00 7E 14 01 00
FF 14 01 00 80 15 01 00 F1 15 01 00 72 16 01 00
F3 16 01 00 74 17 01 00 F5 17 01 00 76 18 01 00
F7 18 01 00 78 19 01 00 F9 19 01 00 7A 1A 01 00
FB 1A 01 00 7C 1B 01 00 FD 1B 01 00 7E 1C 01 00
FF 1C 01 00 80 1D 01 00 F1 1D 01 00 72 1E 01 00
F3 1E 01 00 74 1F 01 00 F5 1F 01 00 76 20 01 00
F7 20 01 00 78 21 01 00 F9 21 01 00 7A 22 01 00
FB 22 01 00 7C 23 01 00 FD 23 01 00 7E 24 01 00
FF 24 01 00 80 25 01 00 F1 25 01 00 72 26 01 00
F3 26 01 00 74 27 01 00 F5 27 01 00 76 28 01 00
F7 28 01 00 78 29 01 00 F9 29 01 00 7A 2A 01 00
FB 2A 01 00 7C 2B 01 00 FD 2B 01 00 7E 2C 01 00
FF 2C 01 00 80 2D 01 00 F1 2D 01 00 72 2E 01 00
F3 2E 01 00 74 2F 01 00 F5 2F 01 00 76 30 01 00
F7 30 01 00 78 31 01 00 F9 31 01 00 7A 32 01 00
FB 32 01 00 7C 33 01 00 FD 33 01 00 7F 34 01 00
^ ^ ^ ^
последний четырёхбайтовый номер в секторе msat является
указателем на следующий номер msat.

7F340100=0001347f=0001347fh+1h=13480h*20 0h=2690000h





7E 34 01 00 00 35 01 00 71 35 01 00 F2 35 01 00
73 36 01 00 F4 36 01 00 75 37 01 00 F6 37 01 00
77 38 01 00 F8 38 01 00 79 39 01 00 FA 39 01 00
7B 3A 01 00 FC 3A 01 00 7D 3B 01 00 FE 3B 01 00
7F 3C 01 00 00 3D 01 00 71 3D 01 00 F2 3D 01 00
73 3E 01 00 F4 3E 01 00 75 3F 01 00 F6 3F 01 00
77 40 01 00 F8 40 01 00 79 41 01 00 FA 41 01 00
7B 42 01 00 FC 42 01 00 7D 43 01 00 FE 43 01 00 555555
7F 44 01 00 00 45 01 00 71 45 01 00 F2 45 01 00 55
73 46 01 00 F4 46 01 00 75 47 01 00 F6 47 01 00 55555
77 48 01 00 F8 48 01 00 79 49 01 00 FA 49 01 00 55
7B 4A 01 00 FC 4A 01 00 7D 4B 01 00 FE 4B 01 00 55
7F 4C 01 00 FF FF FF FF FF FF FF FF FF FF FF FF 55
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 55555
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
^ ^ ^ ^
последний четырёхбайтовый номер в секторе msat =ffffffff
значит это последний сектор msat

У нас вышло 5 секторов мсат (кроме нулевого - заголовочного) можно проверить эту цифру.
В заголовке по смещению 48h находится количество msat секторов кроме заголовка.
унас =5. Вот эта строка заголовка: 02 00 00 00 7F 36 00 00 05 00 00 00
^ ^ ^ ^
количество секторов msat кроме заголовка

Теперь составим секторы msat вместе:
0
 Аватар для Estimable
195 / 14 / 1
Регистрация: 02.01.2017
Сообщений: 223
19.01.2019, 09:04
00 00 00 00<-здесь начинается Msat
72 00 00 00 F3 00 00 00 74 01 00 00 F5 01 00 00
76 02 00 00 F7 02 00 00 78 03 00 00 F9 03 00 00
7A 04 00 00 FB 04 00 00 7C 05 00 00 FD 05 00 00 000
7E 06 00 00 FF 06 00 00 80 07 00 00 F1 07 00 00 00 00
72 08 00 00 F3 08 00 00 74 09 00 00 F5 09 00 00 00 00
76 0A 00 00 F7 0A 00 00 78 0B 00 00 F9 0B 00 00 00 00
7A 0C 00 00 FB 0C 00 00 7C 0D 00 00 FD 0D 00 00 00 00
7E 0E 00 00 FF 0E 00 00 80 0F 00 00 F1 0F 00 00 00 00
72 10 00 00 F3 10 00 00 74 11 00 00 F5 11 00 00 000
76 12 00 00 F7 12 00 00 78 13 00 00 F9 13 00 00
7A 14 00 00 FB 14 00 00 7C 15 00 00 FD 15 00 00
7E 16 00 00 FF 16 00 00 80 17 00 00 F1 17 00 00
72 18 00 00 F3 18 00 00 74 19 00 00 F5 19 00 00
76 1A 00 00 F7 1A 00 00 78 1B 00 00 F9 1B 00 00
7A 1C 00 00 FB 1C 00 00 7C 1D 00 00 FD 1D 00 00
7E 1E 00 00 FF 1E 00 00 80 1F 00 00 F1 1F 00 00
72 20 00 00 F3 20 00 00 74 21 00 00 F5 21 00 00
76 22 00 00 F7 22 00 00 78 23 00 00 F9 23 00 00
7A 24 00 00 FB 24 00 00 7C 25 00 00 FD 25 00 00
7E 26 00 00 FF 26 00 00 80 27 00 00 F1 27 00 00
72 28 00 00 F3 28 00 00 74 29 00 00 F5 29 00 00
76 2A 00 00 F7 2A 00 00 78 2B 00 00 F9 2B 00 00
7A 2C 00 00 FB 2C 00 00 7C 2D 00 00 FD 2D 00 00
7E 2E 00 00 FF 2E 00 00 80 2F 00 00 F1 2F 00 00
72 30 00 00 F3 30 00 00 74 31 00 00 F5 31 00 00
76 32 00 00 F7 32 00 00 78 33 00 00 F9 33 00 00
7A 34 00 00 FB 34 00 00 7C 35 00 00 FD 35 00 00

7E 36 00 00 00 37 00 00 71 37 00 00 F2 37 00 00
73 38 00 00 F4 38 00 00 75 39 00 00 F6 39 00 00
77 3A 00 00 F8 3A 00 00 79 3B 00 00 FA 3B 00 00
7B 3C 00 00 FC 3C 00 00 7D 3D 00 00 FE 3D 00 00
7F 3E 00 00 00 3F 00 00 71 3F 00 00 F2 3F 00 00
73 40 00 00 F4 40 00 00 75 41 00 00 F6 41 00 00
77 42 00 00 F8 42 00 00 79 43 00 00 FA 43 00 00 111
7B 44 00 00 FC 44 00 00 7D 45 00 00 FE 45 00 00 11 11
7F 46 00 00 00 47 00 00 71 47 00 00 F2 47 00 00 11 11
73 48 00 00 F4 48 00 00 75 49 00 00 F6 49 00 00 11
77 4A 00 00 F8 4A 00 00 79 4B 00 00 FA 4B 00 00 11
7B 4C 00 00 FC 4C 00 00 7D 4D 00 00 FE 4D 00 00 11
7F 4E 00 00 00 4F 00 00 71 4F 00 00 F2 4F 00 00 11111111
73 50 00 00 F4 50 00 00 75 51 00 00 F6 51 00 00
77 52 00 00 F8 52 00 00 79 53 00 00 FA 53 00 00
7B 54 00 00 FC 54 00 00 7D 55 00 00 FE 55 00 00
7F 56 00 00 00 57 00 00 71 57 00 00 F2 57 00 00
73 58 00 00 F4 58 00 00 75 59 00 00 F6 59 00 00
77 5A 00 00 F8 5A 00 00 79 5B 00 00 FA 5B 00 00
7B 5C 00 00 FC 5C 00 00 7D 5D 00 00 FE 5D 00 00
7F 5E 00 00 00 5F 00 00 71 5F 00 00 F2 5F 00 00
73 60 00 00 F4 60 00 00 75 61 00 00 F6 61 00 00
77 62 00 00 F8 62 00 00 79 63 00 00 FA 63 00 00
7B 64 00 00 FC 64 00 00 7D 65 00 00 FE 65 00 00
7F 66 00 00 00 67 00 00 71 67 00 00 F2 67 00 00
73 68 00 00 F4 68 00 00 75 69 00 00 F6 69 00 00
77 6A 00 00 F8 6A 00 00 79 6B 00 00 FA 6B 00 00
7B 6C 00 00 FC 6C 00 00 7D 6D 00 00 FE 6D 00 00
7F 6E 00 00 00 6F 00 00 71 6F 00 00 F2 6F 00 00
73 70 00 00 F4 70 00 00 75 71 00 00 F6 71 00 00
77 72 00 00 F8 72 00 00 79 73 00 00 FA 73 00 00
7B 74 00 00 FC 74 00 00 7D 75 00 00 FF 75 00 00

FE 75 00 00 80 76 00 00 F1 76 00 00 72 77 00 00
F3 77 00 00 74 78 00 00 F5 78 00 00 76 79 00 00
F7 79 00 00 78 7A 00 00 F9 7A 00 00 7A 7B 00 00
FB 7B 00 00 7C 7C 00 00 FD 7C 00 00 7E 7D 00 00
FF 7D 00 00 80 7E 00 00 F1 7E 00 00 72 7F 00 00
F3 7F 00 00 74 80 00 00 F5 80 00 00 76 81 00 00 222
F7 81 00 00 78 82 00 00 F9 82 00 00 7A 83 00 00 22 222
FB 83 00 00 7C 84 00 00 FD 84 00 00 7E 85 00 00 22
FF 85 00 00 80 86 00 00 F1 86 00 00 72 87 00 00 22
F3 87 00 00 74 88 00 00 F5 88 00 00 76 89 00 00 22
F7 89 00 00 78 8A 00 00 F9 8A 00 00 7A 8B 00 00 22
FB 8B 00 00 7C 8C 00 00 FD 8C 00 00 7E 8D 00 00 22222222
FF 8D 00 00 80 8E 00 00 F1 8E 00 00 72 8F 00 00
F3 8F 00 00 74 90 00 00 F5 90 00 00 76 91 00 00
F7 91 00 00 78 92 00 00 F9 92 00 00 7A 93 00 00
FB 93 00 00 7C 94 00 00 FD 94 00 00 7E 95 00 00
FF 95 00 00 80 96 00 00 F1 96 00 00 72 97 00 00
F3 97 00 00 74 98 00 00 F5 98 00 00 76 99 00 00
F7 99 00 00 78 9A 00 00 F9 9A 00 00 7A 9B 00 00
FB 9B 00 00 7C 9C 00 00 FD 9C 00 00 7E 9D 00 00
FF 9D 00 00 80 9E 00 00 F1 9E 00 00 72 9F 00 00
F3 9F 00 00 74 A0 00 00 F5 A0 00 00 76 A1 00 00
F7 A1 00 00 78 A2 00 00 F9 A2 00 00 7A A3 00 00
FB A3 00 00 7C A4 00 00 FD A4 00 00 7E A5 00 00
FF A5 00 00 80 A6 00 00 F1 A6 00 00 72 A7 00 00
F3 A7 00 00 74 A8 00 00 F5 A8 00 00 76 A9 00 00
F7 A9 00 00 78 AA 00 00 F9 AA 00 00 7A AB 00 00
FB AB 00 00 7C AC 00 00 FD AC 00 00 7E AD 00 00
FF AD 00 00 80 AE 00 00 F1 AE 00 00 72 AF 00 00
F3 AF 00 00 74 B0 00 00 F5 B0 00 00 76 B1 00 00
F7 B1 00 00 78 B2 00 00 F9 B2 00 00 7A B3 00 00
FB B3 00 00 7C B4 00 00 FD B4 00 00 7F B5 00 00

73 B7 00 00 F4 B7 00 00 75 B8 00 00 F6 B8 00 00
77 B9 00 00 F8 B9 00 00 79 BA 00 00 FA BA 00 00
7B BB 00 00 FC BB 00 00 7D BC 00 00 FE BC 00 00
7F BD 00 00 00 BE 00 00 71 BE 00 00 F2 BE 00 00
73 BF 00 00 F4 BF 00 00 75 C0 00 00 F6 C0 00 00
77 C1 00 00 F8 C1 00 00 79 C2 00 00 FA C2 00 00
7B C3 00 00 FC C3 00 00 7D C4 00 00 FE C4 00 00 333
7F C5 00 00 00 C6 00 00 71 C6 00 00 F2 C6 00 00 33 333
73 C7 00 00 F4 C7 00 00 75 C8 00 00 F6 C8 00 00 333
77 C9 00 00 F8 C9 00 00 79 CA 00 00 FA CA 00 00 33
7B CB 00 00 FC CB 00 00 7D CC 00 00 FE CC 00 00 333
7F CD 00 00 00 CE 00 00 71 CE 00 00 F2 CE 00 00 33 333
73 CF 00 00 F4 CF 00 00 75 D0 00 00 F6 D0 00 00 333
77 D1 00 00 F8 D1 00 00 79 D2 00 00 FA D2 00 00
7B D3 00 00 FC D3 00 00 7D D4 00 00 FE D4 00 00
7F D5 00 00 00 D6 00 00 71 D6 00 00 F2 D6 00 00
73 D7 00 00 F4 D7 00 00 75 D8 00 00 F6 D8 00 00
77 D9 00 00 F8 D9 00 00 79 DA 00 00 FA DA 00 00
7B DB 00 00 FC DB 00 00 7D DC 00 00 FE DC 00 00
7F DD 00 00 00 DE 00 00 71 DE 00 00 F2 DE 00 00
73 DF 00 00 F4 DF 00 00 75 E0 00 00 F6 E0 00 00
77 E1 00 00 F8 E1 00 00 79 E2 00 00 FA E2 00 00
7B E3 00 00 FC E3 00 00 7D E4 00 00 FE E4 00 00
7F E5 00 00 00 E6 00 00 71 E6 00 00 F2 E6 00 00
73 E7 00 00 F4 E7 00 00 75 E8 00 00 F6 E8 00 00
77 E9 00 00 F8 E9 00 00 79 EA 00 00 FA EA 00 00
7B EB 00 00 FC EB 00 00 7D EC 00 00 FE EC 00 00
7F ED 00 00 00 EE 00 00 71 EE 00 00 F2 EE 00 00
73 EF 00 00 F4 EF 00 00 75 F0 00 00 F6 F0 00 00
77 F1 00 00 F8 F1 00 00 79 F2 00 00 FA F2 00 00
7B F3 00 00 FC F3 00 00 7D F4 00 00 FF F4 00 00

FE F4 00 00 80 F5 00 00 F1 F5 00 00 72 F6 00 00
F3 F6 00 00 74 F7 00 00 F5 F7 00 00 76 F8 00 00
F7 F8 00 00 78 F9 00 00 F9 F9 00 00 7A FA 00 00
FB FA 00 00 7C FB 00 00 FD FB 00 00 7E FC 00 00
FF FC 00 00 80 FD 00 00 F1 FD 00 00 72 FE 00 00
F3 FE 00 00 74 FF 00 00 F5 FF 00 00 76 00 01 00
F7 00 01 00 78 01 01 00 F9 01 01 00 7A 02 01 00 44
FB 02 01 00 7C 03 01 00 FD 03 01 00 7E 04 01 00 444
FF 04 01 00 80 05 01 00 F1 05 01 00 72 06 01 00 4444
F3 06 01 00 74 07 01 00 F5 07 01 00 76 08 01 00 44 44
F7 08 01 00 78 09 01 00 F9 09 01 00 7A 0A 01 00 44 44
FB 0A 01 00 7C 0B 01 00 FD 0B 01 00 7E 0C 01 00 44444444
FF 0C 01 00 80 0D 01 00 F1 0D 01 00 72 0E 01 00 44
F3 0E 01 00 74 0F 01 00 F5 0F 01 00 76 10 01 00 44
F7 10 01 00 78 11 01 00 F9 11 01 00 7A 12 01 00
FB 12 01 00 7C 13 01 00 FD 13 01 00 7E 14 01 00
FF 14 01 00 80 15 01 00 F1 15 01 00 72 16 01 00
F3 16 01 00 74 17 01 00 F5 17 01 00 76 18 01 00
F7 18 01 00 78 19 01 00 F9 19 01 00 7A 1A 01 00
FB 1A 01 00 7C 1B 01 00 FD 1B 01 00 7E 1C 01 00
FF 1C 01 00 80 1D 01 00 F1 1D 01 00 72 1E 01 00
F3 1E 01 00 74 1F 01 00 F5 1F 01 00 76 20 01 00
F7 20 01 00 78 21 01 00 F9 21 01 00 7A 22 01 00
FB 22 01 00 7C 23 01 00 FD 23 01 00 7E 24 01 00
FF 24 01 00 80 25 01 00 F1 25 01 00 72 26 01 00
F3 26 01 00 74 27 01 00 F5 27 01 00 76 28 01 00
F7 28 01 00 78 29 01 00 F9 29 01 00 7A 2A 01 00
FB 2A 01 00 7C 2B 01 00 FD 2B 01 00 7E 2C 01 00
FF 2C 01 00 80 2D 01 00 F1 2D 01 00 72 2E 01 00
F3 2E 01 00 74 2F 01 00 F5 2F 01 00 76 30 01 00
F7 30 01 00 78 31 01 00 F9 31 01 00 7A 32 01 00
FB 32 01 00 7C 33 01 00 FD 33 01 00 7F 34 01 00

7E 34 01 00 00 35 01 00 71 35 01 00 F2 35 01 00
73 36 01 00 F4 36 01 00 75 37 01 00 F6 37 01 00
77 38 01 00 F8 38 01 00 79 39 01 00 FA 39 01 00
7B 3A 01 00 FC 3A 01 00 7D 3B 01 00 FE 3B 01 00
7F 3C 01 00 00 3D 01 00 71 3D 01 00 F2 3D 01 00
73 3E 01 00 F4 3E 01 00 75 3F 01 00 F6 3F 01 00
77 40 01 00 F8 40 01 00 79 41 01 00 FA 41 01 00
7B 42 01 00 FC 42 01 00 7D 43 01 00 FE 43 01 00 555555
7F 44 01 00 00 45 01 00 71 45 01 00 F2 45 01 00 55
73 46 01 00 F4 46 01 00 75 47 01 00 F6 47 01 00 55555
77 48 01 00 F8 48 01 00 79 49 01 00 FA 49 01 00 55
7B 4A 01 00 FC 4A 01 00 7D 4B 01 00 FE 4B 01 00 55
7F 4C 01 00 FF FF FF FF FF FF FF FF FF FF FF FF 55
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 55555
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF

Это есть наша таблица msat. Она содержит 749 номеров. В xls декомпиляторе эти номера выстроены в
столбик. В привидённом ранее примере
------------------------------------------------------
Msat Sat

01000000 FDFFFFFF 02000000 03000000 04000000
05000000 06000000 07000000 08000000


02000000 09000000 0A000000 0B000000 0C000000
0D000000 0E000000 0F000000 10000000



03000000 11000000 12000000 13000000 14000000
15000000 16000000 17000000 18000000

* * *

7F1A0000 <- последний 4х байтовый номер это ссылка на следующий сектор ssat
-------------------------------------------------------
видно что один номер раскрывает один сектор таблицы SAT.
Т.е 128 номеров(у нас маленький примерчик всего с 8ю номерами).







Теперь можно составить все сектора таблицы sat.
-------------------------------------------------------------------------------------------
Кстати вы наверное догадались зачем всё же была придумана таблица msat? Ведь можно же было
её не использовать и сделать последний номер таблицы sat указателем на следующий сектор,
чтобы её легко было соединять.
Зачем вся эта путаница? Видимо компаунд файлы настолько выросли в размере, что одним
номером sat нельзя было обращаться к любому сектору большого документа. И придумали
таблицу таблиц(Msat), у которой с помощью одного номера можно адресовать в 128 раз больший файл
чем с помощью Sat. Напоминает интеловскую страничную адресацию, когда программисты немогли
додуматься как выйти из одного мегабайта памяти. А потом придумали страничную адресацию.
-----------------------------------------------------------------------------------------------
0
 Аватар для Estimable
195 / 14 / 1
Регистрация: 02.01.2017
Сообщений: 223
19.01.2019, 09:05
Как составляется таблица Sat?
Берём самый первый номер таблицы Msat. У нас он = 00000000h. Можно перевернуть, если очень хочется.
и по той же самой формуле: offset=(number+1h)*200h находим где этот сектор распологается в файле.

00000000h+1h=00000001h=00000001h*200h=20 0h

по смещению 200h находим начальный сектор Sat

метка начала таблицы Sat
v v v v
FD FF FF FF D3 4C 01 00 03 00 00 00 04 00 00 00
05 00 00 00 06 00 00 00 07 00 00 00 08 00 00 00
09 00 00 00 0A 00 00 00 0B 00 00 00 0C 00 00 00
0D 00 00 00 0E 00 00 00 0F 00 00 00 10 00 00 00
11 00 00 00 12 00 00 00 13 00 00 00 14 00 00 00
15 00 00 00 16 00 00 00 17 00 00 00 18 00 00 00 0000000
19 00 00 00 1A 00 00 00 1B 00 00 00 1C 00 00 00 00 00
1D 00 00 00 1E 00 00 00 1F 00 00 00 20 00 00 00 00 00
21 00 00 00 22 00 00 00 23 00 00 00 24 00 00 00 00 00
25 00 00 00 26 00 00 00 27 00 00 00 28 00 00 00 00 00
29 00 00 00 2A 00 00 00 2B 00 00 00 2C 00 00 00 00 00
2D 00 00 00 2E 00 00 00 2F 00 00 00 30 00 00 00 0000000
31 00 00 00 32 00 00 00 33 00 00 00 34 00 00 00
35 00 00 00 36 00 00 00 37 00 00 00 38 00 00 00
39 00 00 00 3A 00 00 00 3B 00 00 00 3C 00 00 00
3D 00 00 00 3E 00 00 00 3F 00 00 00 40 00 00 00
41 00 00 00 42 00 00 00 43 00 00 00 44 00 00 00
45 00 00 00 46 00 00 00 47 00 00 00 48 00 00 00
49 00 00 00 4A 00 00 00 4B 00 00 00 4C 00 00 00
4D 00 00 00 4E 00 00 00 4F 00 00 00 50 00 00 00
51 00 00 00 52 00 00 00 53 00 00 00 54 00 00 00
55 00 00 00 56 00 00 00 57 00 00 00 58 00 00 00
59 00 00 00 5A 00 00 00 5B 00 00 00 5C 00 00 00
5D 00 00 00 5E 00 00 00 5F 00 00 00 60 00 00 00
61 00 00 00 62 00 00 00 63 00 00 00 64 00 00 00
65 00 00 00 66 00 00 00 67 00 00 00 68 00 00 00
69 00 00 00 6A 00 00 00 6B 00 00 00 6C 00 00 00
6D 00 00 00 6E 00 00 00 6F 00 00 00 70 00 00 00
71 00 00 00 73 00 00 00 FD FF FF FF 74 00 00 00
75 00 00 00 76 00 00 00 77 00 00 00 78 00 00 00
79 00 00 00 7A 00 00 00 7B 00 00 00 7C 00 00 00
7D 00 00 00 7E 00 00 00 7F 00 00 00 80 00 00 00

В Sate, последний номер не является указателем. Следующий сектор ищется по следующему номеру Msat.
Следующему за тем с помощью которого мы попали сюда. За номером 00000000h идёт 72000000.
следовательно 72000000 = 00000072=00000072h+1h=00000073h*200h=E60 0h

следующий сектор sat находим по смещению E600h

81 00 00 00 82 00 00 00 83 00 00 00 84 00 00 00
85 00 00 00 86 00 00 00 87 00 00 00 88 00 00 00
89 00 00 00 8A 00 00 00 8B 00 00 00 8C 00 00 00
8D 00 00 00 8E 00 00 00 8F 00 00 00 90 00 00 00
91 00 00 00 92 00 00 00 93 00 00 00 94 00 00 00
95 00 00 00 96 00 00 00 97 00 00 00 98 00 00 00
99 00 00 00 9A 00 00 00 9B 00 00 00 9C 00 00 00 000000
9D 00 00 00 9E 00 00 00 9F 00 00 00 A0 00 00 00 00
A1 00 00 00 A2 00 00 00 A3 00 00 00 A4 00 00 00 00
A5 00 00 00 A6 00 00 00 A7 00 00 00 A8 00 00 00 00
A9 00 00 00 AA 00 00 00 AB 00 00 00 AC 00 00 00 00
AD 00 00 00 AE 00 00 00 AF 00 00 00 B0 00 00 00 00
B1 00 00 00 B2 00 00 00 B3 00 00 00 B4 00 00 00 00
B5 00 00 00 B6 00 00 00 B7 00 00 00 B8 00 00 00 000000
B9 00 00 00 BA 00 00 00 BB 00 00 00 BC 00 00 00
BD 00 00 00 BE 00 00 00 BF 00 00 00 C0 00 00 00
C1 00 00 00 C2 00 00 00 C3 00 00 00 C4 00 00 00
C5 00 00 00 C6 00 00 00 C7 00 00 00 C8 00 00 00
C9 00 00 00 CA 00 00 00 CB 00 00 00 CC 00 00 00
CD 00 00 00 CE 00 00 00 CF 00 00 00 D0 00 00 00
D1 00 00 00 D2 00 00 00 D3 00 00 00 D4 00 00 00
D5 00 00 00 D6 00 00 00 D7 00 00 00 D8 00 00 00
D9 00 00 00 DA 00 00 00 DB 00 00 00 DC 00 00 00
DD 00 00 00 DE 00 00 00 DF 00 00 00 E0 00 00 00
E1 00 00 00 E2 00 00 00 E3 00 00 00 E4 00 00 00
E5 00 00 00 E6 00 00 00 E7 00 00 00 E8 00 00 00
E9 00 00 00 EA 00 00 00 EB 00 00 00 EC 00 00 00
ED 00 00 00 EE 00 00 00 EF 00 00 00 F0 00 00 00
F1 00 00 00 F2 00 00 00 F4 00 00 00 FD FF FF FF
F5 00 00 00 F6 00 00 00 F7 00 00 00 F8 00 00 00
F9 00 00 00 FA 00 00 00 FB 00 00 00 FC 00 00 00
FD 00 00 00 FE 00 00 00 FF 00 00 00 00 01 00 00

Следующий номер в msat'е(3й если считать по-нормальному)= F3 00 00 00
F3000000=000000f3=000000f3h+1h=000000f4h *200h=1E800h

01 01 00 00 02 01 00 00 03 01 00 00 04 01 00 00
05 01 00 00 06 01 00 00 07 01 00 00 08 01 00 00
09 01 00 00 0A 01 00 00 0B 01 00 00 0C 01 00 00
0D 01 00 00 0E 01 00 00 0F 01 00 00 10 01 00 00
11 01 00 00 12 01 00 00 13 01 00 00 14 01 00 00
15 01 00 00 16 01 00 00 17 01 00 00 18 01 00 00
19 01 00 00 1A 01 00 00 1B 01 00 00 1C 01 00 00 000000000
1D 01 00 00 1E 01 00 00 1F 01 00 00 20 01 00 00 00 00
21 01 00 00 22 01 00 00 23 01 00 00 24 01 00 00 00 00
25 01 00 00 26 01 00 00 27 01 00 00 28 01 00 00 00 00
29 01 00 00 2A 01 00 00 2B 01 00 00 2C 01 00 00 00 00
2D 01 00 00 2E 01 00 00 2F 01 00 00 30 01 00 00 00 00
31 01 00 00 32 01 00 00 33 01 00 00 34 01 00 00 00 00
35 01 00 00 36 01 00 00 37 01 00 00 38 01 00 00 000000000
39 01 00 00 3A 01 00 00 3B 01 00 00 3C 01 00 00
3D 01 00 00 3E 01 00 00 3F 01 00 00 40 01 00 00
41 01 00 00 42 01 00 00 43 01 00 00 44 01 00 00
45 01 00 00 46 01 00 00 47 01 00 00 48 01 00 00
49 01 00 00 4A 01 00 00 4B 01 00 00 4C 01 00 00
4D 01 00 00 4E 01 00 00 4F 01 00 00 50 01 00 00
51 01 00 00 52 01 00 00 53 01 00 00 54 01 00 00
55 01 00 00 56 01 00 00 57 01 00 00 58 01 00 00
59 01 00 00 5A 01 00 00 5B 01 00 00 5C 01 00 00
5D 01 00 00 5E 01 00 00 5F 01 00 00 60 01 00 00
61 01 00 00 62 01 00 00 63 01 00 00 64 01 00 00
65 01 00 00 66 01 00 00 67 01 00 00 68 01 00 00
69 01 00 00 6A 01 00 00 6B 01 00 00 6C 01 00 00
6D 01 00 00 6E 01 00 00 6F 01 00 00 70 01 00 00
71 01 00 00 72 01 00 00 73 01 00 00 75 01 00 00
FD FF FF FF 76 01 00 00 77 01 00 00 78 01 00 00
79 01 00 00 7A 01 00 00 7B 01 00 00 7C 01 00 00
7D 01 00 00 7E 01 00 00 7F 01 00 00 80 01 00 00


Следующий номер в msat'е(4й если считать по-нормальному)= 74 01 00 00
74010000=00000174=00000174h+1h=00000175h *200h=2EA00h

81 01 00 00 82 01 00 00 83 01 00 00 84 01 00 00
85 01 00 00 86 01 00 00 87 01 00 00 88 01 00 00
89 01 00 00 8A 01 00 00 8B 01 00 00 8C 01 00 00
8D 01 00 00 8E 01 00 00 8F 01 00 00 90 01 00 00
91 01 00 00 92 01 00 00 93 01 00 00 94 01 00 00
95 01 00 00 96 01 00 00 97 01 00 00 98 01 00 00
99 01 00 00 9A 01 00 00 9B 01 00 00 9C 01 00 00 000000000000
9D 01 00 00 9E 01 00 00 9F 01 00 00 A0 01 00 00 00 00 00
A1 01 00 00 A2 01 00 00 A3 01 00 00 A4 01 00 00 00 00 00
A5 01 00 00 A6 01 00 00 A7 01 00 00 A8 01 00 00 00 00 00
A9 01 00 00 AA 01 00 00 AB 01 00 00 AC 01 00 00 00 00 00
AD 01 00 00 AE 01 00 00 AF 01 00 00 B0 01 00 00 00 00 00
B1 01 00 00 B2 01 00 00 B3 01 00 00 B4 01 00 00 00 00 00
B5 01 00 00 B6 01 00 00 B7 01 00 00 B8 01 00 00 000000000000
B9 01 00 00 BA 01 00 00 BB 01 00 00 BC 01 00 00
BD 01 00 00 BE 01 00 00 BF 01 00 00 C0 01 00 00
C1 01 00 00 C2 01 00 00 C3 01 00 00 C4 01 00 00
C5 01 00 00 C6 01 00 00 C7 01 00 00 C8 01 00 00
C9 01 00 00 CA 01 00 00 CB 01 00 00 CC 01 00 00
CD 01 00 00 CE 01 00 00 CF 01 00 00 D0 01 00 00
D1 01 00 00 D2 01 00 00 D3 01 00 00 D4 01 00 00
D5 01 00 00 D6 01 00 00 D7 01 00 00 D8 01 00 00
D9 01 00 00 DA 01 00 00 DB 01 00 00 DC 01 00 00
DD 01 00 00 DE 01 00 00 DF 01 00 00 E0 01 00 00
E1 01 00 00 E2 01 00 00 E3 01 00 00 E4 01 00 00
E5 01 00 00 E6 01 00 00 E7 01 00 00 E8 01 00 00
E9 01 00 00 EA 01 00 00 EB 01 00 00 EC 01 00 00
ED 01 00 00 EE 01 00 00 EF 01 00 00 F0 01 00 00
F1 01 00 00 F2 01 00 00 F3 01 00 00 F4 01 00 00
F6 01 00 00 FD FF FF FF F7 01 00 00 F8 01 00 00
F9 01 00 00 FA 01 00 00 FB 01 00 00 FC 01 00 00
FD 01 00 00 FE 01 00 00 FF 01 00 00 00 02 00 00


Ну в общем суть ясна.
Ещё если мы считываем последний заголовочный номер. Т.е 109й в заголовке. У нас
он = FD 35 00 00. То он образует вполне нормальный сектор Sat. В отличие от последнего номера
в секторе Msat, находящегося вне заголовка.
Например в 1м секторе у нас последний номер = FF 75 00 00. Этот номер нельзя превратить в смещение
и сектор sat он не образует. Так что у секторов msat, которые не входят в заголовок последние номера
можно удалить, чтобы они не мешались. Итак, будем считать, что мы составили почти всю таблицу Sat.
И сейчас строим последний её сектор. Рассмотрим сектор 5 таблицы Msat

7E 34 01 00 00 35 01 00 71 35 01 00 F2 35 01 00
73 36 01 00 F4 36 01 00 75 37 01 00 F6 37 01 00
77 38 01 00 F8 38 01 00 79 39 01 00 FA 39 01 00
7B 3A 01 00 FC 3A 01 00 7D 3B 01 00 FE 3B 01 00
7F 3C 01 00 00 3D 01 00 71 3D 01 00 F2 3D 01 00
73 3E 01 00 F4 3E 01 00 75 3F 01 00 F6 3F 01 00
77 40 01 00 F8 40 01 00 79 41 01 00 FA 41 01 00
7B 42 01 00 FC 42 01 00 7D 43 01 00 FE 43 01 00 555555
7F 44 01 00 00 45 01 00 71 45 01 00 F2 45 01 00 55
73 46 01 00 F4 46 01 00 75 47 01 00 F6 47 01 00 55555
77 48 01 00 F8 48 01 00 79 49 01 00 FA 49 01 00 55
из этого номера Msat 7B 4A 01 00 FC 4A 01 00 7D 4B 01 00 FE 4B 01 00 55
получится последний сектор Sat->7F 4C 01 00 FF FF FF FF FF FF FF FF FF FF FF FF 55
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 55555
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF

Последним номером, способным образовать сектор Sat будет являтся номер,
который стоит последним к дыркам FF FF FF FF.
7F 4C 01 00=00014с7f=00014c7fh+1h=14C80h*200h=299 0000h


Вот этот 669 сектор Sat:


81 4C 01 00 82 4C 01 00 83 4C 01 00 84 4C 01 00
85 4C 01 00 86 4C 01 00 87 4C 01 00 88 4C 01 00
89 4C 01 00 8A 4C 01 00 8B 4C 01 00 8C 4C 01 00
8D 4C 01 00 8E 4C 01 00 8F 4C 01 00 90 4C 01 00
91 4C 01 00 92 4C 01 00 93 4C 01 00 94 4C 01 00
95 4C 01 00 96 4C 01 00 97 4C 01 00 98 4C 01 00
99 4C 01 00 9A 4C 01 00 9B 4C 01 00 9C 4C 01 00 669669 669669 669 669 669 669 669 669 669
9D 4C 01 00 9E 4C 01 00 9F 4C 01 00 A0 4C 01 00 669 669 669 669 669 669 669 669 669 669
A1 4C 01 00 A2 4C 01 00 A3 4C 01 00 A4 4C 01 00 669 669 669 669 669 669 669 669 669
A5 4C 01 00 A6 4C 01 00 A7 4C 01 00 A8 4C 01 00 669 669 669 669 669 669 669
A9 4C 01 00 AA 4C 01 00 AB 4C 01 00 AC 4C 01 00 669 669 669 669 669 669 669 669 669
AD 4C 01 00 AE 4C 01 00 AF 4C 01 00 B0 4C 01 00 669 669 669 669 669 669 669 669 669 669 669
B1 4C 01 00 B2 4C 01 00 B3 4C 01 00 B4 4C 01 00 669669 669669 669669669 669 669 669 669 669 669
B5 4C 01 00 B6 4C 01 00 B7 4C 01 00 B8 4C 01 00
B9 4C 01 00 BA 4C 01 00 BB 4C 01 00 BC 4C 01 00
BD 4C 01 00 BE 4C 01 00 BF 4C 01 00 C0 4C 01 00
C1 4C 01 00 C2 4C 01 00 C3 4C 01 00 C4 4C 01 00
C5 4C 01 00 C6 4C 01 00 C7 4C 01 00 C8 4C 01 00
C9 4C 01 00 CA 4C 01 00 CB 4C 01 00 CC 4C 01 00
CD 4C 01 00 CE 4C 01 00 CF 4C 01 00 D0 4C 01 00
D1 4C 01 00 D2 4C 01 00 FE FF FF FF DC 4C 01 00
E6 4C 01 00 D6 4C 01 00 D7 4C 01 00 D8 4C 01 00
D9 4C 01 00 DA 4C 01 00 DB 4C 01 00 DD 4C 01 00
E4 4C 01 00 DE 4C 01 00 DF 4C 01 00 E0 4C 01 00
E1 4C 01 00 E2 4C 01 00 E3 4C 01 00 E5 4C 01 00
F1 4C 01 00 E7 4C 01 00 FE FF FF FF E8 4C 01 00
E9 4C 01 00 EA 4C 01 00 EB 4C 01 00 EC 4C 01 00
ED 4C 01 00 EE 4C 01 00 EF 4C 01 00 F0 4C 01 00
F2 4C 01 00 F4 4C 01 00 F3 4C 01 00 F5 4C 01 00
FE FF FF FF fe ff ff ff FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF

здесь последний значащий номер это последняя FEFFFFFF "конец цепочки секторов".
я обозначил её маленькими цифрами в третьей снизу строке, второй номер слева.

Теперь когда вы построили таблицу Sat, то о таблице msat можно забыть. Или удалить её
освободив полезное пространство в памяти.

Sat это основная таблица для составления секторов данных листов эксель,таблицы директорий,
таблицы ssat и др.

Казалось бы всё хорошо, но микрософт была придумана ещё одна подлость - таблица ssat.
Когда программисты поняли как много дырок остаётся в файле и сколько это занимает места они
захотели сделать уменьшенные сектора (64байта). Т.к любой номер в таблице sat указывает на
стандартный сектор(у нас 512байт), то для маленьких секторов пришлось создать ещё одну таблицу
- Ssat. А сами маленькие секторы упаковать в большие. Создав поток "мини-контейнер". Я не упомянал ранее,
что все полезные данные в файле(не таблицы) хранятся в виде т.н. потоков. Которые разделены
на стандартные сектора по 512 байт. Если размер потока меньше 4096 байт, то он хранится в мини-контейнере
и разделён на минисектора по 64 байта. Мини контейнер это тоже поток, в основном его
секторы лежат последовательно, но иногда он разорван, т.е происходит смещение его мини-секторов,
но об этом позже.
0
 Аватар для Estimable
195 / 14 / 1
Регистрация: 02.01.2017
Сообщений: 223
19.01.2019, 09:06
Как получить таблицу Ssat?

Первый её номер указан в заголовке по смещению 3сh. Если мини контейнера не образовалось и не образовалось
таблицы ssat. То по смещению 3ch будет стоять FEFFFFFF.

У нас там стоит D44C0100h. Этот номер означает не только смещение которое можно вывести
но ещё и порядковый номер в таблице Sat.

Тут начинается самое интересное. Каждый номер в таблице sat обозначает следующий сектор, который
подсоединяется к текущему.
Отсюда вырисовывается основное назначение Sat. Sat служит неким руководством по составлению
цепочек секторов находящихся в файле.

Тут я могу заметить что неплохо бы пронумеровать каждый номер в таблице Sat для наглядности,
(это есть в xls декомпиляторе). При программировании особенно на ассемблере, это не так уж и
нужно. Т.к вы можете считывать таблицу четырьмя байтами и никогда не собьётесь.

Так вот, составляем таблицу Ssat спомощью Sat:

1)привычный нам способ вычисления смещения внутри файла

D44C0100=00014CD4=00014CD4h+1h=14CD5h*20 0h=299AA00h

Вот мы нашли нулевой сектор таблицы Ssat

01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00
05 00 00 00 06 00 00 00 07 00 00 00 08 00 00 00
09 00 00 00 0A 00 00 00 0B 00 00 00 0C 00 00 00
0D 00 00 00 0E 00 00 00 0F 00 00 00 10 00 00 00
11 00 00 00 12 00 00 00 13 00 00 00 14 00 00 00
15 00 00 00 16 00 00 00 17 00 00 00 18 00 00 00
19 00 00 00 1A 00 00 00 1B 00 00 00 1C 00 00 00
1D 00 00 00 1E 00 00 00 1F 00 00 00 20 00 00 00
FE FF FF FF 22 00 00 00 23 00 00 00 24 00 00 00
25 00 00 00 FE FF FF FF 27 00 00 00 FE FF FF FF
29 00 00 00 2A 00 00 00 2B 00 00 00 2C 00 00 00
2D 00 00 00 2E 00 00 00 2F 00 00 00 30 00 00 00 0 0 0
31 00 00 00 32 00 00 00 33 00 00 00 34 00 00 00 0 0
35 00 00 00 36 00 00 00 37 00 00 00 FE FF FF FF 0 0
39 00 00 00 3A 00 00 00 3B 00 00 00 3C 00 00 00 0 0
3D 00 00 00 3E 00 00 00 3F 00 00 00 40 00 00 00 0 0
41 00 00 00 42 00 00 00 43 00 00 00 44 00 00 00 0 0 0
45 00 00 00 46 00 00 00 47 00 00 00 FE FF FF FF
49 00 00 00 4A 00 00 00 4B 00 00 00 4C 00 00 00
4D 00 00 00 4E 00 00 00 4F 00 00 00 50 00 00 00
51 00 00 00 52 00 00 00 53 00 00 00 54 00 00 00
55 00 00 00 56 00 00 00 57 00 00 00 FE FF FF FF
59 00 00 00 5A 00 00 00 5B 00 00 00 5C 00 00 00
5D 00 00 00 5E 00 00 00 5F 00 00 00 60 00 00 00
61 00 00 00 62 00 00 00 63 00 00 00 64 00 00 00
65 00 00 00 66 00 00 00 67 00 00 00 68 00 00 00
69 00 00 00 6A 00 00 00 FE FF FF FF 6C 00 00 00
6D 00 00 00 6E 00 00 00 FE FF FF FF 70 00 00 00
FE FF FF FF 72 00 00 00 73 00 00 00 74 00 00 00
75 00 00 00 76 00 00 00 77 00 00 00 78 00 00 00
79 00 00 00 7A 00 00 00 7B 00 00 00 7C 00 00 00
7D 00 00 00 7E 00 00 00 7F 00 00 00 80 00 00 00





2)первый(следующий) сектор найдём используя таблицу Sat

- перевернём значение D44C0100 полученное из заголовка =00014CD4
- превратим в десятичное 00014CD4h=85204

найдём номер с порядковым номером 85204 в sat. как это сделать если
вы не пронумеровали номера внутри sat?
Попробуем сразу впрыгнуть туда.

-какой это приблизительно сектор sat? 85204/128=665,65625 отбросим дробную часть = 665
-какой это сектор msat? если sat сектор>109, то вычтем заголовочные 109 номеров=665-109=556,
556 номеров находятся за заголовком, 556/127номеров= 4,377952755905512 = 4й сектор
4+1=5. Незнаю в чём тут дело но наличие дробной части всегда велит добавлять 1
итого 5 сектор msat
-расчитаем коррекцию сектора sat. Так как последний номер каждого сектора мсат,
исключая заголовочный не образует сектора sat то для этих пустых номеров
нужна коррекция, она = количеству секторов мсат находящихся за заголовком
т.е 4,377952755905512, отбросим дробную часть = 4. Дробная часть нас не волнует,
т.к не достигает последнего номера в мsat секторе.
Точный Sat сектор=665+4(коррекция)=669
-смещение номера внутри msat. Найдём начальный номер этого сектора.
4сектора по 128номеров=512=512+109номеров из заголовка=621номер является первым
отнимем наш номер от начального 669-621=48 номер от начала сектора msat
-смещение нашего номера внутри сектора Sat. Найдём первый номер этого сектора.
665*128=85120. Отнимем наш от начального 85204-85120=84


посмотрим 5й сектор мсат:


7E 34 01 00 00 35 01 00 71 35 01 00 F2 35 01 00
73 36 01 00 F4 36 01 00 75 37 01 00 F6 37 01 00
77 38 01 00 F8 38 01 00 79 39 01 00 FA 39 01 00
7B 3A 01 00 FC 3A 01 00 7D 3B 01 00 FE 3B 01 00
7F 3C 01 00 00 3D 01 00 71 3D 01 00 F2 3D 01 00
73 3E 01 00 F4 3E 01 00 75 3F 01 00 F6 3F 01 00
77 40 01 00 F8 40 01 00 79 41 01 00 FA 41 01 00
7B 42 01 00 FC 42 01 00 7D 43 01 00 FE 43 01 00 555555
7F 44 01 00 00 45 01 00 71 45 01 00 F2 45 01 00 55
73 46 01 00 F4 46 01 00 75 47 01 00 F6 47 01 00 55555
77 48 01 00 F8 48 01 00 79 49 01 00 FA 49 01 00 55
7B 4A 01 00 FC 4A 01 00 7D 4B 01 00 FE 4B 01 00 55
48 номер внутри сектора мсат----->7F 4C 01 00 FF FF FF FF FF FF FF FF FF FF FF FF 55
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 55555
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF


открываем этот 48 номер, который 669 сектор sat

81 4C 01 00 82 4C 01 00 83 4C 01 00 84 4C 01 00
85 4C 01 00 86 4C 01 00 87 4C 01 00 88 4C 01 00
89 4C 01 00 8A 4C 01 00 8B 4C 01 00 8C 4C 01 00
8D 4C 01 00 8E 4C 01 00 8F 4C 01 00 90 4C 01 00
91 4C 01 00 92 4C 01 00 93 4C 01 00 94 4C 01 00
95 4C 01 00 96 4C 01 00 97 4C 01 00 98 4C 01 00
99 4C 01 00 9A 4C 01 00 9B 4C 01 00 9C 4C 01 00 669669 669669 669 669 669 669 669 669 669
9D 4C 01 00 9E 4C 01 00 9F 4C 01 00 A0 4C 01 00 669 669 669 669 669 669 669 669 669 669
A1 4C 01 00 A2 4C 01 00 A3 4C 01 00 A4 4C 01 00 669 669 669 669 669 669 669 669 669
A5 4C 01 00 A6 4C 01 00 A7 4C 01 00 A8 4C 01 00 669 669 669 669 669 669 669
A9 4C 01 00 AA 4C 01 00 AB 4C 01 00 AC 4C 01 00 669 669 669 669 669 669 669 669 669
AD 4C 01 00 AE 4C 01 00 AF 4C 01 00 B0 4C 01 00 669 669 669 669 669 669 669 669 669 669 669
B1 4C 01 00 B2 4C 01 00 B3 4C 01 00 B4 4C 01 00 669669 669669 669669669 669 669 669 669 669 669
B5 4C 01 00 B6 4C 01 00 B7 4C 01 00 B8 4C 01 00
B9 4C 01 00 BA 4C 01 00 BB 4C 01 00 BC 4C 01 00
BD 4C 01 00 BE 4C 01 00 BF 4C 01 00 C0 4C 01 00
C1 4C 01 00 C2 4C 01 00 C3 4C 01 00 C4 4C 01 00
C5 4C 01 00 C6 4C 01 00 C7 4C 01 00 C8 4C 01 00
C9 4C 01 00 CA 4C 01 00 CB 4C 01 00 CC 4C 01 00
CD 4C 01 00 CE 4C 01 00 CF 4C 01 00 D0 4C 01 00
D1 4C 01 00 D2 4C 01 00 FE FF FF FF DC 4C 01 00
E6 4C 01 00 D6 4C 01 00 D7 4C 01 00 D8 4C 01 00
^ D9 4C 01 00 DA 4C 01 00 DB 4C 01 00 DD 4C 01 00
| E4 4C 01 00 DE 4C 01 00 DF 4C 01 00 E0 4C 01 00
| E1 4C 01 00 E2 4C 01 00 E3 4C 01 00 E5 4C 01 00
| F1 4C 01 00 E7 4C 01 00 FE FF FF FF E8 4C 01 00
| E9 4C 01 00 EA 4C 01 00 EB 4C 01 00 EC 4C 01 00
| ED 4C 01 00 EE 4C 01 00 EF 4C 01 00 F0 4C 01 00
| F2 4C 01 00 F4 4C 01 00 F3 4C 01 00 F5 4C 01 00
| FE FF FF FF fe ff ff ff FF FF FF FF FF FF FF FF
| FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
| FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
|
вот он наш 84 номер внутри сектора Sat

теперь можем присоединить следующий сектор к SSat.

1)считаем первый(не нулевой) сектор ssat
перевернём E64C0100=00014CE6=00014CE6h+1h=14CE7h*20 0h=299CE00
он по смещению 299CE00


81 00 00 00 82 00 00 00 83 00 00 00 84 00 00 00
85 00 00 00 86 00 00 00 87 00 00 00 88 00 00 00
89 00 00 00 8A 00 00 00 8B 00 00 00 8C 00 00 00
8D 00 00 00 8E 00 00 00 8F 00 00 00 90 00 00 00
91 00 00 00 92 00 00 00 93 00 00 00 94 00 00 00
95 00 00 00 96 00 00 00 97 00 00 00 98 00 00 00
99 00 00 00 9A 00 00 00 9B 00 00 00 9C 00 00 00
9D 00 00 00 9E 00 00 00 9F 00 00 00 FE FF FF FF
A1 00 00 00 A2 00 00 00 A3 00 00 00 A4 00 00 00
A5 00 00 00 A6 00 00 00 A7 00 00 00 A8 00 00 00
A9 00 00 00 FE FF FF FF AB 00 00 00 AC 00 00 00 11111111111111
AD 00 00 00 AE 00 00 00 AF 00 00 00 B0 00 00 00
B1 00 00 00 B2 00 00 00 B3 00 00 00 B4 00 00 00
B5 00 00 00 B6 00 00 00 B7 00 00 00 B8 00 00 00
B9 00 00 00 BA 00 00 00 BB 00 00 00 BC 00 00 00
BD 00 00 00 BE 00 00 00 BF 00 00 00 C0 00 00 00
C1 00 00 00 FE FF FF FF C3 00 00 00 FE FF FF FF
C5 00 00 00 FE FF FF FF C7 00 00 00 C8 00 00 00
C9 00 00 00 CA 00 00 00 CB 00 00 00 CC 00 00 00
CD 00 00 00 CE 00 00 00 FE FF FF FF D0 00 00 00
D1 00 00 00 D2 00 00 00 FE FF FF FF D4 00 00 00
D5 00 00 00 D6 00 00 00 FE FF FF FF D8 00 00 00
FE FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF


2)второй сектор найдём используя таблицу Sat

- перевернём значение E64C0100 полученное из предыдущего порядкового номера =00014CE6
- превратим в десятичное 00014CD4h=85222

найдём номер с порядковым номером 85222 в sat. Я уже понял что никто ничто не пронумеровал
поэтому по той же схеме.

-какой это приблизительно сектор sat? 85222/128=665,796875 отбросим дробную часть = 665
-какой это сектор msat? если sat сектор>109, то вычтем заголовочные 109 номеров=556,
556 номеров находятся за заголовком, 556/127номеров= 4,377952755905512 = 4й сектор
4+1=5. Незнаю в чём тут дело но наличие дробной части всегда велит добавлять 1
-расчитаем коррекцию сектора sat. Так как последний номер каждого сектора мсат,
исключая заголовочный не образует сектора sat то для этих пустых номеров
нужна коррекция, она = количеству секторов мсат находящихся за заголовком
т.е 4,377952755905512, отбросим дробную часть = 4. Дробная часть нас не волнует,
т.к не достигает последнего номера в мsat секторе.
Точный Sat сектор=665+4(коррекция)=669
-смещение номера внутри msat. Найдём начальный номер этого сектора.
4сектора*128номеров=512+109номеров из заголовка=621номер является первым
отнимем наш номер от начального 669-621=48 номер от начала сектора msat
-смещение нашего номера внутри сектора Sat. Найдём первый номер этого сектора.
665*128=85120. Отнимем наш от начального 85222-85120=102


посмотрим 5й сектор мсат:


7E 34 01 00 00 35 01 00 71 35 01 00 F2 35 01 00
73 36 01 00 F4 36 01 00 75 37 01 00 F6 37 01 00
77 38 01 00 F8 38 01 00 79 39 01 00 FA 39 01 00
7B 3A 01 00 FC 3A 01 00 7D 3B 01 00 FE 3B 01 00
7F 3C 01 00 00 3D 01 00 71 3D 01 00 F2 3D 01 00
73 3E 01 00 F4 3E 01 00 75 3F 01 00 F6 3F 01 00
77 40 01 00 F8 40 01 00 79 41 01 00 FA 41 01 00
7B 42 01 00 FC 42 01 00 7D 43 01 00 FE 43 01 00 555555
7F 44 01 00 00 45 01 00 71 45 01 00 F2 45 01 00 55
73 46 01 00 F4 46 01 00 75 47 01 00 F6 47 01 00 55555
77 48 01 00 F8 48 01 00 79 49 01 00 FA 49 01 00 55
7B 4A 01 00 FC 4A 01 00 7D 4B 01 00 FE 4B 01 00 55
48 номер внутри сектора мсат----->7F 4C 01 00 FF FF FF FF FF FF FF FF FF FF FF FF 55
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 55555
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF


открываем этот 48 номер, который 669 сектор sat

81 4C 01 00 82 4C 01 00 83 4C 01 00 84 4C 01 00
85 4C 01 00 86 4C 01 00 87 4C 01 00 88 4C 01 00
89 4C 01 00 8A 4C 01 00 8B 4C 01 00 8C 4C 01 00
8D 4C 01 00 8E 4C 01 00 8F 4C 01 00 90 4C 01 00
91 4C 01 00 92 4C 01 00 93 4C 01 00 94 4C 01 00
95 4C 01 00 96 4C 01 00 97 4C 01 00 98 4C 01 00
99 4C 01 00 9A 4C 01 00 9B 4C 01 00 9C 4C 01 00 669669 669669 669 669 669 669 669 669 669
9D 4C 01 00 9E 4C 01 00 9F 4C 01 00 A0 4C 01 00 669 669 669 669 669 669 669 669 669 669
A1 4C 01 00 A2 4C 01 00 A3 4C 01 00 A4 4C 01 00 669 669 669 669 669 669 669 669 669
A5 4C 01 00 A6 4C 01 00 A7 4C 01 00 A8 4C 01 00 669 669 669 669 669 669 669
A9 4C 01 00 AA 4C 01 00 AB 4C 01 00 AC 4C 01 00 669 669 669 669 669 669 669 669 669
AD 4C 01 00 AE 4C 01 00 AF 4C 01 00 B0 4C 01 00 669 669 669 669 669 669 669 669 669 669 669
B1 4C 01 00 B2 4C 01 00 B3 4C 01 00 B4 4C 01 00 669669 669669 669669669 669 669 669 669 669 669
B5 4C 01 00 B6 4C 01 00 B7 4C 01 00 B8 4C 01 00
B9 4C 01 00 BA 4C 01 00 BB 4C 01 00 BC 4C 01 00
BD 4C 01 00 BE 4C 01 00 BF 4C 01 00 C0 4C 01 00
C1 4C 01 00 C2 4C 01 00 C3 4C 01 00 C4 4C 01 00
C5 4C 01 00 C6 4C 01 00 C7 4C 01 00 C8 4C 01 00
C9 4C 01 00 CA 4C 01 00 CB 4C 01 00 CC 4C 01 00
CD 4C 01 00 CE 4C 01 00 CF 4C 01 00 D0 4C 01 00
D1 4C 01 00 D2 4C 01 00 FE FF FF FF DC 4C 01 00
E6 4C 01 00 D6 4C 01 00 D7 4C 01 00 D8 4C 01 00
D9 4C 01 00 DA 4C 01 00 DB 4C 01 00 DD 4C 01 00
E4 4C 01 00 DE 4C 01 00 DF 4C 01 00 E0 4C 01 00
E1 4C 01 00 E2 4C 01 00 E3 4C 01 00 E5 4C 01 00
F1 4C 01 00 E7 4C 01 00 FE FF FF FF <------------+
E8 4C 01 00 |
E9 4C 01 00 EA 4C 01 00 EB 4C 01 00 EC 4C 01 00 |
ED 4C 01 00 EE 4C 01 00 EF 4C 01 00 F0 4C 01 00 |
F2 4C 01 00 F4 4C 01 00 F3 4C 01 00 F5 4C 01 00 |
FE FF FF FF fe ff ff ff FF FF FF FF FF FF FF FF |
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF |
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF |
|
вот он наш 102 номер внутри сектора Sat

Тут мы видим значение FE FF FF FF, что значит "конец цепочки секторов".
Значит второго сектора ssat не будет.
Составим все сектора Ssat:

01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00
05 00 00 00 06 00 00 00 07 00 00 00 08 00 00 00
09 00 00 00 0A 00 00 00 0B 00 00 00 0C 00 00 00
0D 00 00 00 0E 00 00 00 0F 00 00 00 10 00 00 00
11 00 00 00 12 00 00 00 13 00 00 00 14 00 00 00
15 00 00 00 16 00 00 00 17 00 00 00 18 00 00 00
19 00 00 00 1A 00 00 00 1B 00 00 00 1C 00 00 00
1D 00 00 00 1E 00 00 00 1F 00 00 00 20 00 00 00
FE FF FF FF 22 00 00 00 23 00 00 00 24 00 00 00
25 00 00 00 FE FF FF FF 27 00 00 00 FE FF FF FF
29 00 00 00 2A 00 00 00 2B 00 00 00 2C 00 00 00
2D 00 00 00 2E 00 00 00 2F 00 00 00 30 00 00 00 0 0 0
31 00 00 00 32 00 00 00 33 00 00 00 34 00 00 00 0 0
35 00 00 00 36 00 00 00 37 00 00 00 FE FF FF FF 0 0
39 00 00 00 3A 00 00 00 3B 00 00 00 3C 00 00 00 0 0
3D 00 00 00 3E 00 00 00 3F 00 00 00 40 00 00 00 0 0
41 00 00 00 42 00 00 00 43 00 00 00 44 00 00 00 0 0 0
45 00 00 00 46 00 00 00 47 00 00 00 FE FF FF FF
49 00 00 00 4A 00 00 00 4B 00 00 00 4C 00 00 00
4D 00 00 00 4E 00 00 00 4F 00 00 00 50 00 00 00
51 00 00 00 52 00 00 00 53 00 00 00 54 00 00 00
55 00 00 00 56 00 00 00 57 00 00 00 FE FF FF FF
59 00 00 00 5A 00 00 00 5B 00 00 00 5C 00 00 00
5D 00 00 00 5E 00 00 00 5F 00 00 00 60 00 00 00
61 00 00 00 62 00 00 00 63 00 00 00 64 00 00 00
65 00 00 00 66 00 00 00 67 00 00 00 68 00 00 00
69 00 00 00 6A 00 00 00 FE FF FF FF 6C 00 00 00
6D 00 00 00 6E 00 00 00 FE FF FF FF 70 00 00 00
FE FF FF FF 72 00 00 00 73 00 00 00 74 00 00 00
75 00 00 00 76 00 00 00 77 00 00 00 78 00 00 00
79 00 00 00 7A 00 00 00 7B 00 00 00 7C 00 00 00
7D 00 00 00 7E 00 00 00 7F 00 00 00 80 00 00 00

81 00 00 00 82 00 00 00 83 00 00 00 84 00 00 00
85 00 00 00 86 00 00 00 87 00 00 00 88 00 00 00
89 00 00 00 8A 00 00 00 8B 00 00 00 8C 00 00 00
8D 00 00 00 8E 00 00 00 8F 00 00 00 90 00 00 00
91 00 00 00 92 00 00 00 93 00 00 00 94 00 00 00
95 00 00 00 96 00 00 00 97 00 00 00 98 00 00 00
99 00 00 00 9A 00 00 00 9B 00 00 00 9C 00 00 00
9D 00 00 00 9E 00 00 00 9F 00 00 00 FE FF FF FF
A1 00 00 00 A2 00 00 00 A3 00 00 00 A4 00 00 00
A5 00 00 00 A6 00 00 00 A7 00 00 00 A8 00 00 00
A9 00 00 00 FE FF FF FF AB 00 00 00 AC 00 00 00 11111111111111
AD 00 00 00 AE 00 00 00 AF 00 00 00 B0 00 00 00
B1 00 00 00 B2 00 00 00 B3 00 00 00 B4 00 00 00
B5 00 00 00 B6 00 00 00 B7 00 00 00 B8 00 00 00
B9 00 00 00 BA 00 00 00 BB 00 00 00 BC 00 00 00
BD 00 00 00 BE 00 00 00 BF 00 00 00 C0 00 00 00
C1 00 00 00 FE FF FF FF C3 00 00 00 FE FF FF FF
C5 00 00 00 FE FF FF FF C7 00 00 00 C8 00 00 00
C9 00 00 00 CA 00 00 00 CB 00 00 00 CC 00 00 00
CD 00 00 00 CE 00 00 00 FE FF FF FF D0 00 00 00
D1 00 00 00 D2 00 00 00 FE FF FF FF D4 00 00 00
D5 00 00 00 D6 00 00 00 FE FF FF FF D8 00 00 00
FE FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
0
 Аватар для Estimable
195 / 14 / 1
Регистрация: 02.01.2017
Сообщений: 223
19.01.2019, 09:07
Как видите в Ssate перед дырками тоже стоит значение FEFFFFFF "Конец цепочки секторов".
Не трудно заметить что FEFFFFFF встречается здесь несколько раз, а точнее 18. Значит
здесь 18 цепочек секторов.
Таблица ssat используется только для поиска потоков(<4096).
Суть поиска такая же как в Sat: каждый номер указывает на следующий сектор, который
подсоединяется к текущему. Каждый её номер тоже желательно пронумеровать.
Помните что из номера Ssat мы получим смещение сектора не в файле а в мини-контейнере.
А чтобы вычислить смещение сектора в файле, надо знать ещё смещение мини-контейнера и
учесть поправку на разорванность миниконтейнера

Формула нахождения мини-секторов по ssat:
offset=offsetминиконтейнера+поправкаНАра зорванность+(number*40h)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;
Эту вставку я сделал когда уже дописал всю статью, но вспомнил, что необратил ваше внимание
на очень важную деталь. Можете просмотреть бегло, чтобы пока не затруднять восприятие статьи.

Чтобы разьяснить вам поправку на разорванность приведу участок таблицы Sat содержащий
поток"Миниконтейнер" из своего декомпилятора.
Надпись до первого двоеточия ":" даёт пояснение чей это сектор
Цифры до второго двоеточия ":" обозначают порядковый номер
Цифры до третьего третьего ":" обозначают адрес этого номера в файле
Последние 8 hex цифр это сам номер таблицы SAT

0:200h:FDFFFFFF
Directory:1:204h:09000000
SSAT_table:2:208h:15000000
MiniContainer:3:20Ch:04000000
MiniContainer:4:210h:05000000
MiniContainer:5:214h:06000000
MiniContainer:6:218h:07000000
MiniContainer:7:21Ch:08000000
MiniContainer:8:220h:0A000000
Directory:9:224h:12000000
MiniContainer:10:228h:0B000000
MiniContainer:11:22Ch:0C000000
MiniContainer:12:230h:0D000000
MiniContainer:13:234h:0E000000
MiniContainer:14:238h:0F000000
MiniContainer:15:23Ch:10000000
MiniContainer:16:240h:11000000
MiniContainer:17:244h:13000000
Directory:18:248h:1D000000
MiniContainer:19:24Ch:14000000
MiniContainer:20:250h:16000000
SSAT_table:21:254h:FEFFFFFF
MiniContainer:22:258h:17000000
MiniContainer:23:25Ch:18000000
MiniContainer:24:260h:19000000
MiniContainer:25:264h:1A000000
MiniContainer:26:268h:1B000000
MiniContainer:27:26Ch:1C000000
MiniContainer:28:270h:1E000000
Directory:29:274h:FEFFFFFF
MiniContainer:30:278h:1F000000
MiniContainer:31:27Ch:20000000
MiniContainer:32:280h:FEFFFFFF
33:284h:FFFFFFFF

Видно что MiniContainer распологается с 3го по 32 номер в таблице SAT. Но на 9м номере
в него вклинивается таблица Directory, на 18м тоже, на 21м SSAT_table и на
29м опять directory. Такие вставки вызывают смещения минисекторов и мы должны это учитывать.
Один номер таблицы sat указывает на один 512ти байтный сектор или на 8мь 64х байтных
минисекторов.

Так как миниконтейнер начинается на третьем номере, то здесь распологаются его минисектора:
c нулевого по седьмой, у них нет поправки,т.к их строй не нарушался.
На четвёртом номере - минисектора с 8го по 15й, поправки нет.
На пятом номере - минисектора с 16го по 23й,поправки нет
На шестом номере - минисектора с 24го по 31й,поправки нет
На седьмом номере - минисектора с 32го по 39й,поправки нет
На восьмом номере - минисектора с 40го по 47й,поправки нет

на девятом номере идёт разрыв миниконтейнера.
Тут появляется поправка равная размеру одного sat сектора=512 байт. Эта поправка
будет применима ко всем последующим минисекторам.

На десятом номере - минисектора с 48го по 55й,поправка на размер 1го сат сектора=512байт
На одиннадцатом номере - минисектора с 56го по 63й,поправка на размер 1го сат сектора=512байт
На двенадцатом номере - минисектора с 64го по 71й,поправка на размер 1го сат сектора=512байт
На тринадцатом номере - минисектора с 72го по 79й,поправка на размер 1го сат сектора=512байт
На четырнадцатом номере - минисектора с 80го по 87й,поправка на размер 1го сат сектора=512байт
На пятнадцатом номере - минисектора с 88го по 95й,поправка на размер 1го сат сектора=512байт
На шестнадцатом номере - минисектора с 96го по 103й,поправка на размер 1го сат сектора=512байт
На семнадцатом номере - минисектора с 104го по 111й,поправка на размер 1го сат сектора=512байт

на восемнадцатом номере идёт разрыв миниконтейнера.
Дальше поправка увеличится на размер ещё одного сектора, т.е 512+512=1024 байта

На девятнадцатом номере минисектора с 112го по 119й,поправка на размер 2х сат секторов=1024байта
На двадцатом номере минисектора с 120го по 127й,поправка на размер 2х сат секторов=1024байта
итд
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;





Заметили что в формуле исчезла единица? Потому что заголовочный сектор нас теперь не
интересует. Ещё 200h изменилось на 40h. Потому что в Ssate ищутся 64байтные(40h) сектора,
а не 512(200h).
Offset мини-контейнера можно найти в другом месте. Об этом ниже. Пример поиска 64битного
сектора по Ssat тоже будет представлен ниже.




Теперь три основные таблицы собраны. Но как же мы найдём по ним наши листы эксель и vba?
Есть ещё одна таблица описывающая содержимое нашего документа эксель. Она называется
Directory. Внутри документа эксель имеется древообразная структура. Напоминающая
ту которую мы наблюдаем в windows.Например когда откроем проводник.
Папка содержит файлы и папки, в этих папках есть свои файлы и папки итд итп.

Рассмотрим пустой документ эксель.
Здесь есть папка Root Entry(её не видно при обычном пользовании экселем).
Внутри неё находятся фаил Workbook, фаил SummaryInformation, фаил DocumentSummaryInformation.
__
/ \_______
| |
| |
| |
|___________|
Root Entry

|
________________________________________ __________________
| | |
V V V
_____ _____ _____
| \ | \ | \
| | | | | |
| | | | | |
| | | | | |
| | | | | |
|______| |______| |______|

Workbook SummaryInformation DocumentSummaryInformation.





Квадратик  в названии это непечатный юникод символ, а точнее байты 0500h. Незабудте
потом поставить
эти байты в начале имён файлов SummaryInformation и DocumentSummaryInformation.


А вот структура пустого документа Эксель. Но уже содержащего один макрос. И один
модуль в котором он записан.


__
/ \_______
| |
| |
| |
|___________|
Root Entry
|
v
**************************************** **************************************** *****
* mini container *
* | *
* ________________________________________ _____________________ *
* | | | | | *
* V V V V V *
* _____ _____ _____ _____ *
*| \ | \ __ | \ | \ *
*| | | | / \_______ | | | | *
*| | | | | | | | | | *
*| | | | | | | | | | *
*| | | | | | | | | | *
*|______| |______| |___________| |______| |______| *
*CompObj Workbook _VBA_PROJECT_CUR SummaryInformation DocumentSummaryInformation.*
* | *
* V *
* ________________________________________ ___ *
* | | | *
* V V V *
* _____ _____ *
* __ | \ | \ *
* / \_______ | | | | *
* | | | | | | *
* | | | | | | *
* | | | | | | *
* |___________| |______| |______| *
* VBA PROJECT PROJECTwm *
* | *
* | *
* +-----------------------------+ *
* | *
* ________________________________________ __________________ *
* | | | | | | | *
* V V V V V V V *
* _____ _____ _____ _____ _____ _____ _____ *
*| \ | \ | \ | \ | \ | \ | \ *
*| | | | | | | | | | | | | | *
*| | | | | | | | | | | | | | *
*| | | | | | | | | | | | | | *
*| | | | | | | | | | | | | | *
*|______| |______| |______| |______| |______| |______| |______| *
* dir Лист1 Лист2 лист3 Module1 Эта книга _VBA_PROJECT *
**************************************** **************************************** *****
Папка Root Entry расположена над большим квадратом из звёздочек.
Этот квадрат - схематическое изображение мини контейнера. Все
папки и файлы находятся в мини контейнере. Т.к все файлы меньше 4096байт.
Поэтому доступ к ним будет осуществлятся так:
1)сначала найдём мини контейнер через Sat.
2)найдём файлы в мини-контейнере используя Ssat.

В нашем первом примере ни один файл не находился в мини-контейнере. Т.к все
файлы были ровно 4096 байт. Если никто не находится в мини-контейнере, значит
он не существует.


Квадратик  перед именем CompObj это два байта 0100h, не забудте их там поставить.
Насчёт имён скажу что они не могут быть длиннее 31буквы. Имена записываются в
юникоде. Т.е одна буква это два байта.
Нельзя в одной папке иметь два одинаковых имени (как и в windows папке).
0
 Аватар для Estimable
195 / 14 / 1
Регистрация: 02.01.2017
Сообщений: 223
19.01.2019, 09:08
Далее нам необходимо условится, что файлы мы будем называть ПОТОКАМИ, а
папки ХРАНИЛИЩАМИ. Т.к в любой документации к компаунд файлам употребляется эта
терминология.
_____
| \
| |
| |
| |
| |
|______|
То что записано на наших листах эксель находится в потоке Workbook.
Но пока об этом рано говорить. Соберём все секторы таблицы Directory
и рассмотрим их структуру.

В заголовке по смещению 30h находится номер первого сектора таблицы
Directory. Он у нас равен 01000000
Используя знакомую формулу offset=(number+1h)*200h
вычислим смещение 01000000=00000001h->00000001h+1h=2h->2h*200h=400h
Идём по смещению 400h в файле:

52 00 6F 00 6F 00 74 00 20 00 45 00 6E 00 74 00
72 00 79 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
16 00 05 00 FF FF FF FF FF FF FF FF 02 00 00 00
20 08 02 00 00 00 00 00 C0 00 00 00 00 00 00 46
00 00 00 00 40 3F E1 CF AF D7 C3 01 70 1D 41 85
CE D6 C3 01 D5 4C 01 00 40 36 00 00 00 00 00 00
57 00 6F 00 72 00 6B 00 62 00 6F 00 6F 00 6B 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
12 00 02 01 15 00 00 00 FF FF FF FF FF FF FF FF
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 02 00 00 00 C6 64 94 02 00 00 00 00
5F 00 56 00 42 00 41 00 5F 00 50 00 52 00 4F 00
4A 00 45 00 43 00 54 00 5F 00 43 00 55 00 52 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
22 00 01 01 01 00 00 00 13 00 00 00 12 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 E0 8F AC 82 CE D6 C3 01 70 1D 41 85
CE D6 C3 01 00 00 00 00 00 00 00 00 00 00 00 00
56 00 42 00 41 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
08 00 01 00 FF FF FF FF FF FF FF FF 05 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 30 91 F6 82 CE D6 C3 01 90 C5 32 85
CE D6 C3 01 00 00 00 00 00 00 00 00 00 00 00 00









Разложим сектор на составляющие:

52 00 6F 00 6F 00 74 00 20 00 45 00 6E 00 74 00
72 00 79 00 00 00 00 00 00 00 00 00 00 00 00 00 64 байта для имени(хранилища или потока)
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 и 4х стопорных нулей
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

16 00 количество байт отданых под имя
05 куда осуществляется вход(00-никуда,01-хранилище,02-поток,05-корневое хранилище)
00 цвет узла(применяется для ускорения доступа к узлу: 00-красный,01-чёрный )
FF FF FF FF порядковый номер левого брата
FF FF FF FF порядковый номер правого брата
02 00 00 00 порядковый номер центрального ребёнка
20 08 02 00 00 00 00 00 C0 00 00 00 00 00 00 46 идентификатор хранилища(можно поставить нули)

00 00 00 00 флаги хранилища(можно записать нули)
40 3F E1 CF AF D7 C3 01(время создания можно поставить нули)
70 1D 41 85
CE D6 C3 01 <-----время модификации------^ (можно поставить нули)
D5 4C 01 00 первый сектор потока(в корневом хранилище это первый сектор мини контейнера)

40 36 00 00 00 00 00 00 размер потока в байтах(тут определяется как хранится поток:
просто в файле если>=4096 или в мини-контейнере если<4096)
________________________________________ _______
57 00 6F 00 72 00 6B 00 62 00 6F 00 6F 00 6B 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Информация
12 00 02 01 15 00 00 00 FF FF FF FF FF FF FF FF
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 об
00 00 00 00 02 00 00 00 C6 64 94 02 00 00 00 00
________________________________________ _______
5F 00 56 00 42 00 41 00 5F 00 50 00 52 00 4F 00 остальных
4A 00 45 00 43 00 54 00 5F 00 43 00 55 00 52 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3х потоках
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
22 00 01 01 01 00 00 00 13 00 00 00 12 00 00 00 хранится
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 E0 8F AC 82 CE D6 C3 01 70 1D 41 85 в том же
CE D6 C3 01 00 00 00 00 00 00 00 00 00 00 00 00
________________________________________ _______
56 00 42 00 41 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 виде.
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
08 00 01 00 FF FF FF FF FF FF FF FF 05 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 30 91 F6 82 CE D6 C3 01 90 C5 32 85
CE D6 C3 01 00 00 00 00 00 00 00 00 00 00 00 00


Получается что в секторе таблицы директорий хранится информация
о 4х потоках\хранилищах.
Цвет узла ускоряет открытие файла excel. Но в документации сказано, что
можно везде ставить чёрный, если вам это обременительно.
Сейчас скажу про порядковые номера братьев и центрального сына
Вы должны пронумеровать каждый поток по мере появления его в таблице
директорий. Например в этом секторе 4 члена(хранилища или потоки)
вы их нумеруете от нуля. Т.е первый здесь 0 последний 3. В следующем
секторе начальный будет 4, конечный 7 итд.
Например: Смотрите на цифры справа от директорий.

52 00 6F 00 6F 00 74 00 20 00 45 00 6E 00 74 00
72 00 79 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
16 00 05 00 FF FF FF FF FF FF FF FF 02 00 00 00 0
20 08 02 00 00 00 00 00 C0 00 00 00 00 00 00 46
00 00 00 00 40 3F E1 CF AF D7 C3 01 70 1D 41 85
CE D6 C3 01 D5 4C 01 00 40 36 00 00 00 00 00 00
________________________________________ _______
57 00 6F 00 72 00 6B 00 62 00 6F 00 6F 00 6B 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
12 00 02 01 15 00 00 00 FF FF FF FF FF FF FF FF 1
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 02 00 00 00 C6 64 94 02 00 00 00 00
________________________________________ _______
5F 00 56 00 42 00 41 00 5F 00 50 00 52 00 4F 00
4A 00 45 00 43 00 54 00 5F 00 43 00 55 00 52 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 2
22 00 01 01 01 00 00 00 13 00 00 00 12 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 E0 8F AC 82 CE D6 C3 01 70 1D 41 85
CE D6 C3 01 00 00 00 00 00 00 00 00 00 00 00 00
________________________________________ _______
56 00 42 00 41 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3
08 00 01 00 FF FF FF FF FF FF FF FF 05 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 30 91 F6 82 CE D6 C3 01 90 C5 32 85
CE D6 C3 01 00 00 00 00 00 00 00 00 00 00 00 00



В этих трёх четырёхбайтовых полях начинающихся по смещению 44h от начала каждой директории
(FF FF FF FF FF FF FF FF 02 00 00 00)
указывается кто куда входит, основываясь на порядковых номерах
директорий(которые у нас справа от директорий).

Структура тут похожа на генеалогическое древо. Н.р

У самой первой директории(корневой) нет братьев. Поэтому два поля(инфа о братьях)
будут содержать дырки FFFFFFFF.

__
/ \_______
| |
| |
| |
|___________|
Root Entry

|
________________________________________ __________________
| | |
V V V
_____ _____ _____
| \ | \ | \
| | | | | |
| | | | | |
| | | | | |
| | | | | |
|______| |______| |______|

Workbook SummaryInformation DocumentSummaryInformation.


Но есть сын SummaryInformation, причём центральный. Т.к среди своих собратьев
он стоит по середине. У этого сына есть левый брат(стоящий слева)- Workbook и
правый брат(стоящий справа от него)-DocumentSummaryInformation.
У каждого члена указывается центральный сын и два брата. Официально говорится
что на одной линии может быть только 3 члена на одной линии. Но в микрософтовском
руководстве говорится что бывают исключения. Даже в нашем примере с VBA видно,
что на одной линии сидят семь братьев.

________________________________________ __________________
| | | | | | |
V V V V V V V
_____ _____ _____ _____ _____ _____ _____
| \ | \ | \ | \ | \ | \ | \
| | | | | | | | | | | | | |
| | | | | | | | | | | | | |
| | | | | | | | | | | | | |
| | | | | | | | | | | | | |
|______| |______| |______| |______| |______| |______| |______|
dir Лист1 Лист2 лист3 Module1 Эта книга _VBA_PROJECT

В этих трёх полях информация о братьях и сыновьях содержится ввиде ссылок
на порядковые номера членов корневого хранилища.

Обычно чем короче имя тем брат стоит левее, чем длинее тем правее.
Если имена одинаковой длинны то они сравниваются посимвольно по расположению
в кодировочной таблице UTF. Причём при сравнении все буквы имени превращаются
в заглавные.

Время создания и время модификации читайте в основном документе.
Хотя...
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;

Поле временного отпечатка это беззнаковое 64битное целое значение включающее время прошедшее с 00 часов 00 минут 00сек
-7
1 января 1601 года(грегорианский календарь). Одна единица этого значения равна 100 наносекундам(10 секунд). Отсюда
следует что каждая следующая секунда повышает этот временной отпечаток на 10 миллионов единиц.
Во время получения даты из временного отпечатка надо учитывать високосные года следуя правилам:


- Если год делится на 4 и на 100 и на 400 значит он високосный (н.р 2000 високосный).
- Если год делится на 4 и на 100 значит он не високосный (н.р 1900 не високосный )
- Если год делится только на 4, значит он високосный.

Пример 64битное(8байт) значение: 01A5E403C2D59C00h

________________________________________ ________________________________________ ________________________________________ ___________
|_____________Шаги вычисления_______________|__________форм ула________________|______ результат_____________________|
|превратим в десятичное | |t0 = 118751670000000000
|Вычислим секунды |t1 = t0 / 10,000,000 |t1 = 118751670000000000/10000000=11875167000,0секунд
|дробные секунды(т.е милисекунды) | |30*0,0сек = 0мсек----------------------------^
|Вычислим минуты |t2 = t1 / 60 |t2 = 11875167000/60=197919450,0минут
|дробные минуты(т.е секунды) | |60*0,0мин = 0сек--------------^
|Вычислим целые часы |t3 = t2 / 60 |t3 = 197919450/60=3298657,5часов
|дробные часы(т.е минуты) | |60*0,5часа = 30мин--------^
|Вычислим сутки |t4 = t3 / 24 |t4 = 3298657/24=137444,0416666667суток
| | | V-------------------^
|дробные сутки(т.е часы) | |24*0,0416666667часов= 1,0000000008часов
-------------------------------------------------------------------------------------------------------------------------
|Вычислим целые года |t9=t4/365 |t9=137444/365(366)=376,558904109589(потеря точности из-за высокосного года)
|дробный год(т.е месяц) | |месяц здесь не вычисляется т.к потеря точности из-за налич високосных лет)
|Найдём год |ryear = 1601 + кол-во лет в t9 |ryear = 1601 + 376 = 1977
|Вычислим колво остальных суток в году |t5 = колво суток–(колво суток |
|(после 01.01.1977) |от 01.01.1601 до 01.01.1977) |t5 = 137444 – 137331 = 113
|Вычислим количество месяцев |t5/30(31) |113/30(31)=3,766666666666667(потеря точности)
|найдём месяц |rmonth = 1 + кол-во месяцев в t5 |rmonth = 1 + 3 = 4 = Январь+3месяца=апрель
|Вычислим остаток дней в Апреле |t6 = колво суток–(колво дней |
| |от 01.01.1977 до 01.04.1977) |t6 = 113 – 90 = 23
|День апреля |rday = 1 + t6 |rday = 1 + 23 = 24
------------------------------------------------------------------------------------------------------------------------
Итог: 24.04.1977 01:30:00:00<дробные секунды(т.е милисекунды)
^ ^ ^дробные минуты(т.е секунды)
| дробные часы(т.е минуты)
дробные сутки(т.е часы)

Описано не очень подробно, но в оригинале ещё меньше подробностей.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;
0
 Аватар для Estimable
195 / 14 / 1
Регистрация: 02.01.2017
Сообщений: 223
19.01.2019, 09:08
По номеру первого сектора потока и его размеру можно начать собирать поток.
Сначала оценивается размер чтобы узнать где его искать и как вычислять смещение
в файле. Если он меньше 4096 байт, то поток хранится в мини-контейнере и
для поиска используется Ssat и формула offset=offsetминиконтейнера+поправкаНАра зрыв+(number*40h)
,если больше либо = 4096, то хранится в файле в свободном виде и ищется
с помощью Sat по формуле offset=(number+1h)*200h.

Помните что у таблицы Ssat единственное назначение это поиск коротких потоков
в мини-контейнере.


Но правило размера 4096 не применяется при поиске самого мини-контейнера.
Какого бы он не был размера, но ищется он всегда только через Sat.

Номер первого сектора мини-контейнера всегда указан в инфе о корневом хранилище.
Это надо запомнить.

Продолжим собирать сектора Directory.

В заголовке по смещению 30h находится номер первого сектора таблицы
Directory. Он у нас равен 01000000. Мы вытащили первый сектор таблицы.
Теперь посмотрим в Sate, где следующий сектор.

перевернём 01000000 =00000001h->превратим в десятичное = 1.
Теперь будем впрыгивать в нужный нам мсат->сат->номер_сат.
Помните что нумерация сат не обязательна. Н.р если таблица сат
собрана, то в ассемблере можно извлечь нужный номер путём
индексной адресации.

нр

lea ebx,80222*4;искомый 4хбайтовый номер
mov edi,offset dword ptr[SAT];размещение самого первого номера Sat
mov eax,dword ptr [edi+ebx]


ну а мы для наглядности продолжим

-какой это приблизительно сектор sat? 1/128=0,0078125 отбросим дробную часть = 0
-какой это сектор msat? если sat сектор<109, то 0вой
-расчитаем коррекцию сектора sat. в заголовке нет коррекции
-смещение номера внутри msat. такое же как сектор сат
-смещение нашего номера внутри сектора Sat. Найдём первый номер этого сектора.
0*128=0. Отнимем наш от начального 1-0=1

MSAT

00 00 00 00<-здесь 0 смещение во мсат
72 00 00 00 F3 00 00 00 74 01 00 00 F5 01 00 00
76 02 00 00 F7 02 00 00 78 03 00 00 F9 03 00 00
7A 04 00 00 FB 04 00 00 7C 05 00 00 FD 05 00 00 000
7E 06 00 00 FF 06 00 00 80 07 00 00 F1 07 00 00 00 00
72 08 00 00 F3 08 00 00 74 09 00 00 F5 09 00 00 00 00
76 0A 00 00 F7 0A 00 00 78 0B 00 00 F9 0B 00 00 00 00
7A 0C 00 00 FB 0C 00 00 7C 0D 00 00 FD 0D 00 00 00 00
7E 0E 00 00 FF 0E 00 00 80 0F 00 00 F1 0F 00 00 00 00
72 10 00 00 F3 10 00 00 74 11 00 00 F5 11 00 00 000
76 12 00 00 F7 12 00 00 78 13 00 00 F9 13 00 00
7A 14 00 00 FB 14 00 00 7C 15 00 00 FD 15 00 00
7E 16 00 00 FF 16 00 00 80 17 00 00 F1 17 00 00
72 18 00 00 F3 18 00 00 74 19 00 00 F5 19 00 00
76 1A 00 00 F7 1A 00 00 78 1B 00 00 F9 1B 00 00
7A 1C 00 00 FB 1C 00 00 7C 1D 00 00 FD 1D 00 00
7E 1E 00 00 FF 1E 00 00 80 1F 00 00 F1 1F 00 00
72 20 00 00 F3 20 00 00 74 21 00 00 F5 21 00 00
76 22 00 00 F7 22 00 00 78 23 00 00 F9 23 00 00
7A 24 00 00 FB 24 00 00 7C 25 00 00 FD 25 00 00
7E 26 00 00 FF 26 00 00 80 27 00 00 F1 27 00 00
72 28 00 00 F3 28 00 00 74 29 00 00 F5 29 00 00
76 2A 00 00 F7 2A 00 00 78 2B 00 00 F9 2B 00 00
7A 2C 00 00 FB 2C 00 00 7C 2D 00 00 FD 2D 00 00
7E 2E 00 00 FF 2E 00 00 80 2F 00 00 F1 2F 00 00
72 30 00 00 F3 30 00 00 74 31 00 00 F5 31 00 00
76 32 00 00 F7 32 00 00 78 33 00 00 F9 33 00 00
7A 34 00 00 FB 34 00 00 7C 35 00 00 FD 35 00 00


SAT здесь первое смещение в Sat
V V V V
FD FF FF FF D3 4C 01 00 03 00 00 00 04 00 00 00
05 00 00 00 06 00 00 00 07 00 00 00 08 00 00 00
09 00 00 00 0A 00 00 00 0B 00 00 00 0C 00 00 00
0D 00 00 00 0E 00 00 00 0F 00 00 00 10 00 00 00
11 00 00 00 12 00 00 00 13 00 00 00 14 00 00 00
15 00 00 00 16 00 00 00 17 00 00 00 18 00 00 00 0000000
19 00 00 00 1A 00 00 00 1B 00 00 00 1C 00 00 00 00 00
1D 00 00 00 1E 00 00 00 1F 00 00 00 20 00 00 00 00 00
21 00 00 00 22 00 00 00 23 00 00 00 24 00 00 00 00 00
25 00 00 00 26 00 00 00 27 00 00 00 28 00 00 00 00 00
29 00 00 00 2A 00 00 00 2B 00 00 00 2C 00 00 00 00 00
2D 00 00 00 2E 00 00 00 2F 00 00 00 30 00 00 00 0000000
31 00 00 00 32 00 00 00 33 00 00 00 34 00 00 00
35 00 00 00 36 00 00 00 37 00 00 00 38 00 00 00
39 00 00 00 3A 00 00 00 3B 00 00 00 3C 00 00 00
3D 00 00 00 3E 00 00 00 3F 00 00 00 40 00 00 00
41 00 00 00 42 00 00 00 43 00 00 00 44 00 00 00
45 00 00 00 46 00 00 00 47 00 00 00 48 00 00 00
49 00 00 00 4A 00 00 00 4B 00 00 00 4C 00 00 00
4D 00 00 00 4E 00 00 00 4F 00 00 00 50 00 00 00
51 00 00 00 52 00 00 00 53 00 00 00 54 00 00 00
55 00 00 00 56 00 00 00 57 00 00 00 58 00 00 00
59 00 00 00 5A 00 00 00 5B 00 00 00 5C 00 00 00
5D 00 00 00 5E 00 00 00 5F 00 00 00 60 00 00 00
61 00 00 00 62 00 00 00 63 00 00 00 64 00 00 00
65 00 00 00 66 00 00 00 67 00 00 00 68 00 00 00
69 00 00 00 6A 00 00 00 6B 00 00 00 6C 00 00 00
6D 00 00 00 6E 00 00 00 6F 00 00 00 70 00 00 00
71 00 00 00 73 00 00 00 FD FF FF FF 74 00 00 00
75 00 00 00 76 00 00 00 77 00 00 00 78 00 00 00
79 00 00 00 7A 00 00 00 7B 00 00 00 7C 00 00 00
7D 00 00 00 7E 00 00 00 7F 00 00 00 80 00 00 00

Значит следуюющий сектор по номеру D3 4C 01 00

Выкатываем этот сектор
D34C0100=00014CD3=00014CD3h+1h=14CD4h*20 0h=299A800

4D 00 6F 00 64 00 75 00 6C 00 65 00 31 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
10 00 02 00 0A 00 00 00 0F 00 00 00 FF FF FF FF
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 22 08 00 00 00 00 00 00
________________________________________ _______
5F 00 5F 00 53 00 52 00 50 00 5F 00 32 00 00 00 11 11
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
10 00 02 01 09 00 00 00 0B 00 00 00 FF FF FF FF
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 21 00 00 00 40 01 00 00 00 00 00 00
________________________________________ _______
5F 00 5F 00 53 00 52 00 50 00 5F 00 33 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
10 00 02 01 FF FF FF FF FF FF FF FF FF FF FF FF
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 26 00 00 00 67 00 00 00 00 00 00 00
________________________________________ _______
2D 04 42 04 30 04 1A 04 3D 04 38 04 33 04 30 04
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
12 00 02 01 0C 00 00 00 0D 00 00 00 FF FF FF FF
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 28 00 00 00 DC 03 00 00 00 00 00 00

идём по этому номеру, чтобы узнать следующий сектор
D34C0100=00014CD3=85203

-какой это приблизительно сектор sat? 85203/128=665,6484375 отбросим дробную часть = 665
-какой это сектор msat? если sat сектор>109, то вычтем заголовочные 109 номеров=556,
556 номеров находятся за заголовком, 556/127номеров= 4,377952755905512 = 4й сектор
4+1=5. Незнаю в чём тут дело но наличие дробной части всегда велит добавлять 1
-расчитаем коррекцию сектора sat. Так как последний номер каждого сектора мсат,
исключая заголовочный не образует сектора sat то для этих пустых номеров
нужна коррекция, она = количеству секторов мсат находящихся за заголовком
т.е 4,377952755905512, отбросим дробную часть = 4. Дробная часть нас не волнует,
т.к не достигает последнего номера в мsat секторе.
Точный Sat сектор=665+4(коррекция)=669
-смещение номера внутри msat. Найдём начальный номер этого сектора.
4сектора*128номеров=512+109номеров из заголовка=621номер является первым
отнимем наш номер от начального 669-621=48 номер от начала сектора msat
-смещение нашего номера внутри сектора Sat. Найдём первый номер этого сектора.
665*128=85120. Отнимем наш от начального 85203-85120=83

посмотрим 5й сектор мсат:


7E 34 01 00 00 35 01 00 71 35 01 00 F2 35 01 00
73 36 01 00 F4 36 01 00 75 37 01 00 F6 37 01 00
77 38 01 00 F8 38 01 00 79 39 01 00 FA 39 01 00
7B 3A 01 00 FC 3A 01 00 7D 3B 01 00 FE 3B 01 00
7F 3C 01 00 00 3D 01 00 71 3D 01 00 F2 3D 01 00
73 3E 01 00 F4 3E 01 00 75 3F 01 00 F6 3F 01 00
77 40 01 00 F8 40 01 00 79 41 01 00 FA 41 01 00
7B 42 01 00 FC 42 01 00 7D 43 01 00 FE 43 01 00 555555
7F 44 01 00 00 45 01 00 71 45 01 00 F2 45 01 00 55
73 46 01 00 F4 46 01 00 75 47 01 00 F6 47 01 00 55555
77 48 01 00 F8 48 01 00 79 49 01 00 FA 49 01 00 55
7B 4A 01 00 FC 4A 01 00 7D 4B 01 00 FE 4B 01 00 55
48 номер внутри сектора мсат----->7F 4C 01 00 FF FF FF FF FF FF FF FF FF FF FF FF 55
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 55555
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF


открываем этот 48 номер, который 669 сектор sat

81 4C 01 00 82 4C 01 00 83 4C 01 00 84 4C 01 00
85 4C 01 00 86 4C 01 00 87 4C 01 00 88 4C 01 00
89 4C 01 00 8A 4C 01 00 8B 4C 01 00 8C 4C 01 00
8D 4C 01 00 8E 4C 01 00 8F 4C 01 00 90 4C 01 00
91 4C 01 00 92 4C 01 00 93 4C 01 00 94 4C 01 00
95 4C 01 00 96 4C 01 00 97 4C 01 00 98 4C 01 00
99 4C 01 00 9A 4C 01 00 9B 4C 01 00 9C 4C 01 00 669669 669669 669 669 669 669 669 669 669
9D 4C 01 00 9E 4C 01 00 9F 4C 01 00 A0 4C 01 00 669 669 669 669 669 669 669 669 669 669
A1 4C 01 00 A2 4C 01 00 A3 4C 01 00 A4 4C 01 00 669 669 669 669 669 669 669 669 669
A5 4C 01 00 A6 4C 01 00 A7 4C 01 00 A8 4C 01 00 669 669 669 669 669 669 669
A9 4C 01 00 AA 4C 01 00 AB 4C 01 00 AC 4C 01 00 669 669 669 669 669 669 669 669 669
AD 4C 01 00 AE 4C 01 00 AF 4C 01 00 B0 4C 01 00 669 669 669 669 669 669 669 669 669 669 669
B1 4C 01 00 B2 4C 01 00 B3 4C 01 00 B4 4C 01 00 669669 669669 669669669 669 669 669 669 669 669
B5 4C 01 00 B6 4C 01 00 B7 4C 01 00 B8 4C 01 00
B9 4C 01 00 BA 4C 01 00 BB 4C 01 00 BC 4C 01 00
BD 4C 01 00 BE 4C 01 00 BF 4C 01 00 C0 4C 01 00
C1 4C 01 00 C2 4C 01 00 C3 4C 01 00 C4 4C 01 00
C5 4C 01 00 C6 4C 01 00 C7 4C 01 00 C8 4C 01 00
C9 4C 01 00 CA 4C 01 00 CB 4C 01 00 CC 4C 01 00
CD 4C 01 00 CE 4C 01 00 CF 4C 01 00 D0 4C 01 00
D1 4C 01 00 D2 4C 01 00 FE FF FF FF DC 4C 01 00 <-+
E6 4C 01 00 D6 4C 01 00 D7 4C 01 00 D8 4C 01 00 |
D9 4C 01 00 DA 4C 01 00 DB 4C 01 00 DD 4C 01 00 |
E4 4C 01 00 DE 4C 01 00 DF 4C 01 00 E0 4C 01 00 |
E1 4C 01 00 E2 4C 01 00 E3 4C 01 00 E5 4C 01 00 |
F1 4C 01 00 E7 4C 01 00 FE FF FF FF E8 4C 01 00 |
E9 4C 01 00 EA 4C 01 00 EB 4C 01 00 EC 4C 01 00 |
ED 4C 01 00 EE 4C 01 00 EF 4C 01 00 F0 4C 01 00 |
F2 4C 01 00 F4 4C 01 00 F3 4C 01 00 F5 4C 01 00 |
FE FF FF FF fe ff ff ff FF FF FF FF FF FF FF FF |
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF |
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF |
|
вот он наш 102 номер внутри сектора Sat

Выкатываем этот сектор
DC 4C 01 00=00014CDC =00014CDC+1=14CDDh*200h=299BA00

1B 04 38 04 41 04 42 04 31 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0C 00 02 01 0E 00 00 00 FF FF FF FF FF FF FF FF
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 38 00 00 00 D8 03 00 00 00 00 00 00
________________________________________ _______
1B 04 38 04 41 04 42 04 32 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0C 00 02 01 08 00 00 00 04 00 00 00 FF FF FF FF
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 48 00 00 00 D8 03 00 00 00 00 00 00
________________________________________ _______
1B 04 38 04 41 04 42 04 33 00 00 00 00 00 00 00 22 22
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 22 22
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 22
0C 00 02 01 FF FF FF FF FF FF FF FF FF FF FF FF 22
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 58 00 00 00 85 04 00 00 00 00 00 00
________________________________________ _______
5F 00 5F 00 53 00 52 00 50 00 5F 00 34 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
10 00 02 01 06 00 00 00 07 00 00 00 FF FF FF FF
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 6B 00 00 00 E4 00 00 00 00 00 00 00

Ну вобщем суть ясна. Ещё 3 сектора выкатаю сразу


5F 00 5F 00 53 00 52 00 50 00 5F 00 35 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
10 00 02 00 FF FF FF FF FF FF FF FF FF FF FF FF
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 6F 00 00 00 42 00 00 00 00 00 00 00
________________________________________ _______
5F 00 56 00 42 00 41 00 5F 00 50 00 52 00 4F 00
4A 00 45 00 43 00 54 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1A 00 02 00 FF FF FF FF FF FF FF FF FF FF FF FF
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 71 00 00 00 A6 0B 00 00 00 00 00 00
________________________________________ _______
64 00 69 00 72 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
08 00 02 00 FF FF FF FF FF FF FF FF FF FF FF FF
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 A0 00 00 00 4C 02 00 00 00 00 00 00
________________________________________ _______
5F 00 5F 00 53 00 52 00 50 00 5F 00 30 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
10 00 02 01 FF FF FF FF 10 00 00 00 FF FF FF FF
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 AA 00 00 00 C2 05 00 00 00 00 00 00


5F 00 5F 00 53 00 52 00 50 00 5F 00 31 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
10 00 02 00 FF FF FF FF FF FF FF FF FF FF FF FF
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 C2 00 00 00 7A 00 00 00 00 00 00 00
________________________________________ _______
50 00 52 00 4F 00 4A 00 45 00 43 00 54 00 77 00
6D 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
14 00 02 00 FF FF FF FF FF FF FF FF FF FF FF FF
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 C4 00 00 00 6B 00 00 00 00 00 00 00
________________________________________ _______
50 00 52 00 4F 00 4A 00 45 00 43 00 54 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
10 00 02 01 03 00 00 00 11 00 00 00 FF FF FF FF
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 C6 00 00 00 27 02 00 00 00 00 00 00
________________________________________ _______
05 00 53 00 75 00 6D 00 6D 00 61 00 72 00 79 00
49 00 6E 00 66 00 6F 00 72 00 6D 00 61 00 74 00
69 00 6F 00 6E 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
28 00 02 01 FF FF FF FF 14 00 00 00 FF FF FF FF
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 CF 00 00 00 E0 00 00 00 00 00 00 00

05 00 44 00 6F 00 63 00 75 00 6D 00 65 00 6E 00
74 00 53 00 75 00 6D 00 6D 00 61 00 72 00 79 00
49 00 6E 00 66 00 6F 00 72 00 6D 00 61 00 74 00
69 00 6F 00 6E 00 00 00 00 00 00 00 00 00 00 00
38 00 02 00 FF FF FF FF FF FF FF FF FF FF FF FF
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 D3 00 00 00 00 01 00 00 00 00 00 00
________________________________________ _______
01 00 43 00 6F 00 6D 00 70 00 4F 00 62 00 6A 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
12 00 02 00 FF FF FF FF FF FF FF FF FF FF FF FF
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 D7 00 00 00 61 00 00 00 00 00 00 00
________________________________________ _______
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 FF FF FF FF FF FF FF FF FF FF FF FF
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
________________________________________ _______
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 FF FF FF FF FF FF FF FF FF FF FF FF
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0
 Аватар для Estimable
195 / 14 / 1
Регистрация: 02.01.2017
Сообщений: 223
19.01.2019, 09:09
Ну вот и вся таблица директорий собрана.
Обратите внимание что последние две директории
пустые. Такими директориями эксель заполняет
остаток сектора таблицы Directory.


Переходим к потокам, тут то мы и испробуем Ssat
и мини-контейнер.

Смотрим на самую первую директорию(корневое хранилище)

52 00 6F 00 6F 00 74 00 20 00 45 00 6E 00 74 00
72 00 79 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
16 00 05 00 FF FF FF FF FF FF FF FF 02 00 00 00
20 08 02 00 00 00 00 00 C0 00 00 00 00 00 00 46
00 00 00 00 40 3F E1 CF AF D7 C3 01 70 1D 41 85
CE D6 C3 01 D5 4C 01 00 40 36 00 00 00 00 00 00
^ ^ ^ ^
номер сектора мини-контейнера

нас интересуют 4 байта, которые начинаются с растояния в
12 байт от конца директории(смещение 74h от начала).
Здесь находится номер сектора мини-контейнера. Если тут
стоит FEFFFFFF(а в его размере стоят нули) значит мини-контейнера
в документе нет.
У нас он есть. Поток "Мини-контейнер", ищется с помощью таблицы Sat
А сектора "Мини-контейнер"'а ищутся с помощью Ssat.

Итак, прежде чем составлять сектора потоков, мы должны
извлечь номер начального сектора мини-контейнера если он существует.
Чтобы получить из него смещение.

D54C0100=00014CD5=00014CD5h+1h=14CD6*200 h=299AC00





Попробуем составить какой-нибудь поток находящийся в
мини-контейнере.

_____
| \
| |
| |
| |
| |
|______|
Например поток Module1, он у нас находится в
первом секторе(следующий за нулевым).

M o d u l e 1
4D 00 6F 00 64 00 75 00 6C 00 65 00 31 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
10 00 02 00 0A 00 00 00 0F 00 00 00 FF FF FF FF
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 22 08 00 00 00 00 00 00

Пока я собираю потоки непоследовательно,
т.к поток workbook здесь очень громоздкий. А у меня
цель показать вам поиск потока в мини-контейнере.
Потом разберём пустой документ где всё будет последовательно.

По смещению 74h от начала директории находим
номер начала потока 00 00 00 00.
Следующие за ним 8 байт(смещение 78h) говорят что его
размер 2082байта. Это меньше 4096, значит он расположен
в мини-контейнере.

Помните что последние 12 байт директории папок(нр root entry и VBA)
содержат нули. Т.е их номер 0 и размер 0. Т.е они нигде не
ищутся, не имеют секторов и существуют лишь номинально.

Переворачиваем полученный номер.
00000000=00000000

Ранее мы получили смещение мини-контейнера(из директории корневого
хранилища)=299AC00

Поправку на разрыв миниконтейнера будем считать = 0,
т.е предположим что поток "миниконтейнер" у нас сплошной.
Хорошо бы перед открытием файла сделать предварительный прогон
собирающий поправки на разрыв миниконтейнера для каждого сектора.



Расчитаем смещение начального сектора Module1 внутри файла:
offset=offsetминиконтейнера+0+(number*40 h)

отсюда:offset=299AC00+0+(00000000h*40h)= 299AC00h

Вот нулевой сектор Module1 в мини-контейнере
(сектора в мини-контейнере по 64байта):
01 16 01 00 06 F0 00 00 00 04 05 00 00 D4 00 00
00 B0 01 00 00 FF FF FF FF 6D 05 00 00 49 07 00 нулевой
00 00 00 00 00 01 00 00 00 73 CO 09 2D 00 00 FF
FF 03 00 00 00 00 00 00 00 B6 00 FF FF 01 01 00

Какой сектор следующий можно узнать из 0го номера Ssat
(каждый номер таблицы Ssat необходимо было пронумеровать,
а то впрыгивать в ssat более тяжёлая задача).


Смотрим следующий номер сектора Module1
V V V V
01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00
05 00 00 00 06 00 00 00 07 00 00 00 08 00 00 00
09 00 00 00 0A 00 00 00 0B 00 00 00 0C 00 00 00
0D 00 00 00 0E 00 00 00 0F 00 00 00 10 00 00 00
11 00 00 00 12 00 00 00 13 00 00 00 14 00 00 00
15 00 00 00 16 00 00 00 17 00 00 00 18 00 00 00
19 00 00 00 1A 00 00 00 1B 00 00 00 1C 00 00 00
1D 00 00 00 1E 00 00 00 1F 00 00 00 20 00 00 00
FE FF FF FF 22 00 00 00 23 00 00 00 24 00 00 00
25 00 00 00 FE FF FF FF 27 00 00 00 FE FF FF FF
29 00 00 00 2A 00 00 00 2B 00 00 00 2C 00 00 00
2D 00 00 00 2E 00 00 00 2F 00 00 00 30 00 00 00 0 0 0
31 00 00 00 32 00 00 00 33 00 00 00 34 00 00 00 0 0
35 00 00 00 36 00 00 00 37 00 00 00 FE FF FF FF 0 0
39 00 00 00 3A 00 00 00 3B 00 00 00 3C 00 00 00 0 0
3D 00 00 00 3E 00 00 00 3F 00 00 00 40 00 00 00 0 0
41 00 00 00 42 00 00 00 43 00 00 00 44 00 00 00 0 0 0
45 00 00 00 46 00 00 00 47 00 00 00 FE FF FF FF
49 00 00 00 4A 00 00 00 4B 00 00 00 4C 00 00 00
4D 00 00 00 4E 00 00 00 4F 00 00 00 50 00 00 00
51 00 00 00 52 00 00 00 53 00 00 00 54 00 00 00
55 00 00 00 56 00 00 00 57 00 00 00 FE FF FF FF
59 00 00 00 5A 00 00 00 5B 00 00 00 5C 00 00 00
5D 00 00 00 5E 00 00 00 5F 00 00 00 60 00 00 00
61 00 00 00 62 00 00 00 63 00 00 00 64 00 00 00
65 00 00 00 66 00 00 00 67 00 00 00 68 00 00 00
69 00 00 00 6A 00 00 00 FE FF FF FF 6C 00 00 00
6D 00 00 00 6E 00 00 00 FE FF FF FF 70 00 00 00
FE FF FF FF 72 00 00 00 73 00 00 00 74 00 00 00
75 00 00 00 76 00 00 00 77 00 00 00 78 00 00 00
79 00 00 00 7A 00 00 00 7B 00 00 00 7C 00 00 00
7D 00 00 00 7E 00 00 00 7F 00 00 00 80 00 00 00

Переворачиваем полученный номер.
01000000=00000001
отсюда:offset=299AC00+0+(00000001h*40h)= 299AC40h

00 00 00 FF FF FF FF 00 00 00 00 FF FF 04 00 FF
FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 первый
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00


нулевой номер указывал что следующий сектор получ из
первого номера, посмотрим первый номер
V V V V
01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00
05 00 00 00 06 00 00 00 07 00 00 00 08 00 00 00
09 00 00 00 0A 00 00 00 0B 00 00 00 0C 00 00 00
0D 00 00 00 0E 00 00 00 0F 00 00 00 10 00 00 00
11 00 00 00 12 00 00 00 13 00 00 00 14 00 00 00
15 00 00 00 16 00 00 00 17 00 00 00 18 00 00 00
19 00 00 00 1A 00 00 00 1B 00 00 00 1C 00 00 00
1D 00 00 00 1E 00 00 00 1F 00 00 00 20 00 00 00
FE FF FF FF 22 00 00 00 23 00 00 00 24 00 00 00
25 00 00 00 FE FF FF FF 27 00 00 00 FE FF FF FF
29 00 00 00 2A 00 00 00 2B 00 00 00 2C 00 00 00
2D 00 00 00 2E 00 00 00 2F 00 00 00 30 00 00 00 0 0 0
31 00 00 00 32 00 00 00 33 00 00 00 34 00 00 00 0 0
35 00 00 00 36 00 00 00 37 00 00 00 FE FF FF FF 0 0
39 00 00 00 3A 00 00 00 3B 00 00 00 3C 00 00 00 0 0
3D 00 00 00 3E 00 00 00 3F 00 00 00 40 00 00 00 0 0
41 00 00 00 42 00 00 00 43 00 00 00 44 00 00 00 0 0 0
45 00 00 00 46 00 00 00 47 00 00 00 FE FF FF FF
49 00 00 00 4A 00 00 00 4B 00 00 00 4C 00 00 00
4D 00 00 00 4E 00 00 00 4F 00 00 00 50 00 00 00
51 00 00 00 52 00 00 00 53 00 00 00 54 00 00 00
55 00 00 00 56 00 00 00 57 00 00 00 FE FF FF FF
59 00 00 00 5A 00 00 00 5B 00 00 00 5C 00 00 00
5D 00 00 00 5E 00 00 00 5F 00 00 00 60 00 00 00
61 00 00 00 62 00 00 00 63 00 00 00 64 00 00 00
65 00 00 00 66 00 00 00 67 00 00 00 68 00 00 00
69 00 00 00 6A 00 00 00 FE FF FF FF 6C 00 00 00
6D 00 00 00 6E 00 00 00 FE FF FF FF 70 00 00 00
FE FF FF FF 72 00 00 00 73 00 00 00 74 00 00 00
75 00 00 00 76 00 00 00 77 00 00 00 78 00 00 00
79 00 00 00 7A 00 00 00 7B 00 00 00 7C 00 00 00
7D 00 00 00 7E 00 00 00 7F 00 00 00 80 00 00 00


там номер 02000000

Переворачиваем полученный номер.
02000000=00000002
отсюда:offset=299AC00+0+(00000002h*40h)= 299AC80h


00 00 00 00 00 00 00 10 00 00 00 03 00 00 00 05
00 00 00 07 00 00 00 FF FF FF FF FF FF FF FF 01 второй
01 08 00 00 00 FF FF FF FF 78 00 00 00 02 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

первый номер указывал что следующий сектор получ из
второго номера, посмотрим второй номер
V V V V
01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00
05 00 00 00 06 00 00 00 07 00 00 00 08 00 00 00
09 00 00 00 0A 00 00 00 0B 00 00 00 0C 00 00 00
0D 00 00 00 0E 00 00 00 0F 00 00 00 10 00 00 00
11 00 00 00 12 00 00 00 13 00 00 00 14 00 00 00
15 00 00 00 16 00 00 00 17 00 00 00 18 00 00 00
19 00 00 00 1A 00 00 00 1B 00 00 00 1C 00 00 00
1D 00 00 00 1E 00 00 00 1F 00 00 00 20 00 00 00
FE FF FF FF 22 00 00 00 23 00 00 00 24 00 00 00
25 00 00 00 FE FF FF FF 27 00 00 00 FE FF FF FF
29 00 00 00 2A 00 00 00 2B 00 00 00 2C 00 00 00
2D 00 00 00 2E 00 00 00 2F 00 00 00 30 00 00 00 0 0 0
31 00 00 00 32 00 00 00 33 00 00 00 34 00 00 00 0 0
35 00 00 00 36 00 00 00 37 00 00 00 FE FF FF FF 0 0
39 00 00 00 3A 00 00 00 3B 00 00 00 3C 00 00 00 0 0
3D 00 00 00 3E 00 00 00 3F 00 00 00 40 00 00 00 0 0
41 00 00 00 42 00 00 00 43 00 00 00 44 00 00 00 0 0 0
45 00 00 00 46 00 00 00 47 00 00 00 FE FF FF FF
49 00 00 00 4A 00 00 00 4B 00 00 00 4C 00 00 00
4D 00 00 00 4E 00 00 00 4F 00 00 00 50 00 00 00
51 00 00 00 52 00 00 00 53 00 00 00 54 00 00 00
55 00 00 00 56 00 00 00 57 00 00 00 FE FF FF FF
59 00 00 00 5A 00 00 00 5B 00 00 00 5C 00 00 00
5D 00 00 00 5E 00 00 00 5F 00 00 00 60 00 00 00
61 00 00 00 62 00 00 00 63 00 00 00 64 00 00 00
65 00 00 00 66 00 00 00 67 00 00 00 68 00 00 00
69 00 00 00 6A 00 00 00 FE FF FF FF 6C 00 00 00
6D 00 00 00 6E 00 00 00 FE FF FF FF 70 00 00 00
FE FF FF FF 72 00 00 00 73 00 00 00 74 00 00 00
75 00 00 00 76 00 00 00 77 00 00 00 78 00 00 00
79 00 00 00 7A 00 00 00 7B 00 00 00 7C 00 00 00
7D 00 00 00 7E 00 00 00 7F 00 00 00 80 00 00 00


там номер 03000000

Переворачиваем полученный номер.
03000000=00000003
отсюда:offset=299AC00+0+(00000003h*40h)= 299ACC0h

00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF
00 00 00 00 4D 45 00 00 FF FF FF FF FF FF 00 00 третий
00 00 FF FF 00 00 00 00 FF FF 01 01 00 00 00 00
DF 00 FF FF 00 00 00 00 FF FF FF FF FF FF FF FF


второй номер указывал что следующий сектор получ из
третьего номера, посмотрим третий номер
V V V V
01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00
05 00 00 00 06 00 00 00 07 00 00 00 08 00 00 00
09 00 00 00 0A 00 00 00 0B 00 00 00 0C 00 00 00
0D 00 00 00 0E 00 00 00 0F 00 00 00 10 00 00 00
11 00 00 00 12 00 00 00 13 00 00 00 14 00 00 00
15 00 00 00 16 00 00 00 17 00 00 00 18 00 00 00
19 00 00 00 1A 00 00 00 1B 00 00 00 1C 00 00 00
1D 00 00 00 1E 00 00 00 1F 00 00 00 20 00 00 00
FE FF FF FF 22 00 00 00 23 00 00 00 24 00 00 00
25 00 00 00 FE FF FF FF 27 00 00 00 FE FF FF FF
29 00 00 00 2A 00 00 00 2B 00 00 00 2C 00 00 00
2D 00 00 00 2E 00 00 00 2F 00 00 00 30 00 00 00 0 0 0
31 00 00 00 32 00 00 00 33 00 00 00 34 00 00 00 0 0
35 00 00 00 36 00 00 00 37 00 00 00 FE FF FF FF 0 0
39 00 00 00 3A 00 00 00 3B 00 00 00 3C 00 00 00 0 0
3D 00 00 00 3E 00 00 00 3F 00 00 00 40 00 00 00 0 0
41 00 00 00 42 00 00 00 43 00 00 00 44 00 00 00 0 0 0
45 00 00 00 46 00 00 00 47 00 00 00 FE FF FF FF
49 00 00 00 4A 00 00 00 4B 00 00 00 4C 00 00 00
4D 00 00 00 4E 00 00 00 4F 00 00 00 50 00 00 00
51 00 00 00 52 00 00 00 53 00 00 00 54 00 00 00
55 00 00 00 56 00 00 00 57 00 00 00 FE FF FF FF
59 00 00 00 5A 00 00 00 5B 00 00 00 5C 00 00 00
5D 00 00 00 5E 00 00 00 5F 00 00 00 60 00 00 00
61 00 00 00 62 00 00 00 63 00 00 00 64 00 00 00
65 00 00 00 66 00 00 00 67 00 00 00 68 00 00 00
69 00 00 00 6A 00 00 00 FE FF FF FF 6C 00 00 00
6D 00 00 00 6E 00 00 00 FE FF FF FF 70 00 00 00
FE FF FF FF 72 00 00 00 73 00 00 00 74 00 00 00
75 00 00 00 76 00 00 00 77 00 00 00 78 00 00 00
79 00 00 00 7A 00 00 00 7B 00 00 00 7C 00 00 00
7D 00 00 00 7E 00 00 00 7F 00 00 00 80 00 00 00


там номер 04000000

Переворачиваем полученный номер.
04000000=00000004
отсюда:offset=299AC00+0+(00000004h*40h)= 299AD00h


FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF четвёртый
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF

третий номер указывал что следующий сектор получ из
четвёртого номера, посмотрим четвёртый номер

01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00
V V V V
05 00 00 00 06 00 00 00 07 00 00 00 08 00 00 00
09 00 00 00 0A 00 00 00 0B 00 00 00 0C 00 00 00
0D 00 00 00 0E 00 00 00 0F 00 00 00 10 00 00 00
11 00 00 00 12 00 00 00 13 00 00 00 14 00 00 00
15 00 00 00 16 00 00 00 17 00 00 00 18 00 00 00
19 00 00 00 1A 00 00 00 1B 00 00 00 1C 00 00 00
1D 00 00 00 1E 00 00 00 1F 00 00 00 20 00 00 00
FE FF FF FF 22 00 00 00 23 00 00 00 24 00 00 00
25 00 00 00 FE FF FF FF 27 00 00 00 FE FF FF FF
29 00 00 00 2A 00 00 00 2B 00 00 00 2C 00 00 00
2D 00 00 00 2E 00 00 00 2F 00 00 00 30 00 00 00 0 0 0
31 00 00 00 32 00 00 00 33 00 00 00 34 00 00 00 0 0
35 00 00 00 36 00 00 00 37 00 00 00 FE FF FF FF 0 0
39 00 00 00 3A 00 00 00 3B 00 00 00 3C 00 00 00 0 0
3D 00 00 00 3E 00 00 00 3F 00 00 00 40 00 00 00 0 0
41 00 00 00 42 00 00 00 43 00 00 00 44 00 00 00 0 0 0
45 00 00 00 46 00 00 00 47 00 00 00 FE FF FF FF
49 00 00 00 4A 00 00 00 4B 00 00 00 4C 00 00 00
4D 00 00 00 4E 00 00 00 4F 00 00 00 50 00 00 00
51 00 00 00 52 00 00 00 53 00 00 00 54 00 00 00
55 00 00 00 56 00 00 00 57 00 00 00 FE FF FF FF
59 00 00 00 5A 00 00 00 5B 00 00 00 5C 00 00 00
5D 00 00 00 5E 00 00 00 5F 00 00 00 60 00 00 00
61 00 00 00 62 00 00 00 63 00 00 00 64 00 00 00
65 00 00 00 66 00 00 00 67 00 00 00 68 00 00 00
69 00 00 00 6A 00 00 00 FE FF FF FF 6C 00 00 00
6D 00 00 00 6E 00 00 00 FE FF FF FF 70 00 00 00
FE FF FF FF 72 00 00 00 73 00 00 00 74 00 00 00
75 00 00 00 76 00 00 00 77 00 00 00 78 00 00 00
79 00 00 00 7A 00 00 00 7B 00 00 00 7C 00 00 00
7D 00 00 00 7E 00 00 00 7F 00 00 00 80 00 00 00


там номер 05000000

Переворачиваем полученный номер.
05000000=00000005
отсюда:offset=299AC00+0+(00000005h*40h)= 299AD40h

FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF пятый
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF 28 00 00 00 00 00

Вобщем здесь тоже ничего сложного. Выведу
сектора Сначала до самого конца потока, т.е до туда где
цепочка Module1 в Ssat кончится меткой FEFFFFFF


01 16 01 00 06 F0 00 00 00 04 05 00 00 D4 00 00
00 B0 01 00 00 FF FF FF FF 6D 05 00 00 49 07 00 нулевой
00 00 00 00 00 01 00 00 00 73 CO 09 2D 00 00 FF
FF 03 00 00 00 00 00 00 00 B6 00 FF FF 01 01 00

00 00 00 FF FF FF FF 00 00 00 00 FF FF 04 00 FF
FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 первый
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

00 00 00 00 00 00 00 10 00 00 00 03 00 00 00 05
00 00 00 07 00 00 00 FF FF FF FF FF FF FF FF 01 второй
01 08 00 00 00 FF FF FF FF 78 00 00 00 02 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF
00 00 00 00 4D 45 00 00 FF FF FF FF FF FF 00 00 третий
00 00 FF FF 00 00 00 00 FF FF 01 01 00 00 00 00
DF 00 FF FF 00 00 00 00 FF FF FF FF FF FF FF FF

FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF четвёртый
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF

FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF пятый
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF 28 00 00 00 00 00

36 0A FF FF FF FF 00 00 00 00 1A 94 FF FF FF FF
00 00 00 00 1A 4C FF FF FF FF 00 00 00 00 1A 4C шестой
FF FF FF FF 00 00 FF FF 01 01 00 00 00 00 00 00
01 00 00 00 88 02 00 00 01 01 C8 02 00 00 38 00

00 00 FF FF FF FF 02 83 14 02 FF FF FF FF 08 00
FF FF 30 00 00 00 00 00 FF FF FF FF FF FF 00 00 седьмой
00 00 FF FF FF FF FF FF FF FF 00 00 00 00 1D 00
00 00 25 00 00 00 0B 12 18 02 FF FF FF FF 00 00

00 60 00 00 00 00 FF FF FF FF FF FF FF FF 00 00
00 00 00 00 00 00 B0 00 00 00 24 FF 6B 00 FF FF восьмой
FF FF FF FF FF FF FF FF 00 00 10 00 10 00 00 00
84 00 00 03 00 00 60 84 22 02 FF FF FF FF 7A FF


FF FF 02 00 FF FF 00 00 00 00 00 00 00 00 40 04
FE FF 60 01 00 00 70 FF FF FF 03 00 FF FF 20 00 девятый
00 00 00 00 00 00 FF FF FF FF 50 01 00 00 АО 02
00 00 FF FF FF FF FF FF FF FF FF FF FF FF FF FF

FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF десятый
FF FF FF FF FF FF FF FF FF FF 78 00 00 00 FF FF
FF FF FF FF FF FF FO 01 00 00 FF FF FF FF FF FF

FF FF 08 02 00 00 FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF одиннадцатый
FF FF FF FF FF FF FF FF FF FF FF FF FF FF 88 01
00 00 90 00 00 00 FF FF FF FF FF FF FF FF FF FF

FF FF FF FF FF FF D8 01 00 00 50 01 00 00 78 01
00 00 90 00 00 00 04 00 FF FF FF FF FF FF 40 04 двенадцатый
FE FF FF FF FF FF 6C FF FF 1F 03 00 FF FF 20 00
00 00 FF FF FF FF АО 01 00 00 60 01 00 00 04 00

FF FF FF FF FF FF 40 04 FE FF B0 01 00 00 6A FF
FF FF 02 00 FF FF 20 00 00 00 FF FF FF FF C8 01 тринадцатый
00 00 88 01 00 00 05 00 FF FF FF FF FF FF 40 04
FE FF FF FF FF FF 68 FF FF 1F 02 00 FF FF 20 00

00 00 FF FF FF FF 68 02 00 00 B0 01 00 00 05 00
FF FF FF FF FF FF FF FF FF FF 28 02 00 00 FF FF четырнадцатый
FF FF FF FF FF FF FF FF FF FF 01 00 FF FF 40 04
FE FF FF FF FF FF 64 FF FF FF 09 00 FF FF 20 00

00 00 01 00 00 00 40 04 FE FF 20 02 00 00 54 FF
FF FF ОС 00 FF FF 20 00 00 00 00 00 00 00 40 04 пятнадцатый
FE FF 38 02 00 00 44 FF FF FF ОС 00 FF FF 20 00
00 00 00 00 00 00 40 04 FE FF 50 02 00 00 34 FF

FF FF ОС 00 FF FF 20 00 00 00 00 00 00 00 40 04
FE FF FF FF FF FF 24 FF FF FF ОС 00 FF FF 20 00 шестнадцатый
00 00 00 00 00 00 78 02 00 00 80 01 00 00 09 00
FF FF 0C 00 FF FF FF FF FF FF 60 01 00 00 OD 00

00 00 08 00 00 00 FF FF FF FF 10 00 00 00 FF FF
FF FF 08 00 00 00 OA 00 00 00 00 00 00 00 60 84 семнадцатый
24 02 FF FF FF FF 74 FF FF FF 03 00 FF FF 00 00
00 00 FF FF FF FF FF FF FF FF CO 02 00 00 FF FF

FF FF B8 02 00 00 01 00 01 00 00 00 00 00 00 00
00 00 00 00 00 00 38 00 00 00 FF FF FF FF FF FF восемнадцатый
FF FF FF FF FF FF FF FF FF FF FF FF FF FF 38 00
00 00 FF FF FF FF FF FF FF FF FF FF FF FF FF FF

FF FF FF FF FF FF FF FF FF FF FF FF FF FF 08 00
00 00 00 00 00 00 00 00 00 00 08 00 04 00 FF FF девятнадцатый
FF FF 00 00 00 00 FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF 02 00

00 00 00 00 F4 47 5A 41 05 00 01 24 00 2A 00 5C
00 52 00 66 00 66 00 66 00 66 00 2A 00 30 00 ЗА двадцатый
00 34 00 31 00 35 00 61 00 34 00 38 00 31 00 31
00 01 12 00 2A 00 5C 00 52 00 31 00 2A 00 23 00

32 00 38 00 35 00 01 10 00 2A 00 5C 00 52 00 31
00 2A 00 23 00 64 00 66 00 01 10 00 2A 00 5C 00 двадцать первый
52 00 31 00 2A 00 23 00 64 00 66 00 DF 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 двадцать второй
00 00 00 00 00 00 00 00 00 FE CA 01 00 10 00 22
81 08 00 06 00 02 00 00 00 00 00 00 80 08 00 08

00 00 00 10 00 00 00 00 80 08 00 08 00 00 00 18
00 00 00 00 80 09 00 00 00 00 00 FF FF FF FF 00 двадцать третий
81 08 00 14 00 15 00 48 00 00 00 00 81 08 00 12
00 10 00 20 00 00 00 00 81 08 00 24 00 30 00 70

00 00 00 00 80 09 00 00 00 00 00 FF FF FF FF 00
80 09 00 00 00 00 00 FF FF FF FF 00 81 08 00 0A двадцать четвёртый
00 OA 00 38 00 00 00 00 81 08 00 12 00 14 00 АО
00 00 00 00 83 08 00 08 00 08 00 B8 00 00 00 00

81 08 00 02 00 02 00 CO 00 00 00 00 81 08 00 OA
00 OA 00 60 00 00 00 00 80 09 00 00 00 00 00 FF двадцать пятый
FF FF FF 04 81 08 00 02 00 03 00 08 00 00 00 FF
FF FF FF 01 01 DO 00 00 00 96 04 38 00 00 00 00

00 6F 00 FF FF 70 00 00 00 5D 00 F2 04 78 00 00
00 5D 00 F2 04 АО 02 00 00 FF 00 20 00 22 02 FE двадцать шестой
00 AC 00 01 00 AC 00 00 01 92 00 00 00 00 2A 30
8C FF 00 20 00 22 02 FE 00 C8 00 74 73 20 61 6E

64 FF 00 20 00 24 02 FE 00 AC 00 01 00 AD 00 FF
FF 00 00 92 00 00 31 00 00 FF 00 20 00 24 02 FE двадцать седьмой
00 C8 00 6C 6C 20 55 73 65 B6 00 OE 00 26 26 26
26 26 26 26 26 26 26 26 26 26 26 20 00 24 02 20

00 22 02 20 00 28 02 2C 00 2A 02 02 00 00 00 00
00 FF FF FF FF 60 00 00 00 20 00 24 02 AC 00 АО двадцать восьмой
OF OD 00 AC 00 00 00 05 00 9C 00 2D 00 31 00 30
00 20 00 24 02 27 00 24 02 6В 00 FF FF 78 00 00

00 FF FF FF FF 70 00 00 00 FF FF FF FF 00 00 01
CF B0 00 41 74 74 72 69 62 75 74 00 65 20 56 42 двадцать девятый
5F 4E 61 6D 00 65 20 3D 20 22 4D 6F 64 00 75 6C
65 31 22 0D 0A 53 00 75 62 20 69 6E 73 65 72 00

74 28 29 0D 0A 44 69 6D 00 20 78 20 41 73 20 49
6E АО 74 65 67 65 72 03 44 79 01 22 00 4C 6F 6E тридцатый
67 0D 0A 0D 0A 20 46 6F 72 20 79 00 86 31 20 00
54 6F 20 36 35 35 33 35 05 03 26 78 05 26 32 35

36 0D 0A 00 41 63 74 69 76 65 53 68 00 65 65 74
2E 43 65 6C 6C 80 73 28 79 2C 20 78 29 00 23 1С тридцать первый
22 26 OA 00 00 82 01 55 4E 65 78 80 74 20 78 OD
OA 49 66 00 5C 41 00 9D 20 34 30 30 30 00 2D 30

80 20 54 68 65 6E 0D 0A 01 71 00 79 0D 0A 45 6E
64 20 49 78 66 OD OA 02 2E 00 OF 03 11 00 C3 OD тридцать второй
00 OA 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0
 Аватар для Estimable
195 / 14 / 1
Регистрация: 02.01.2017
Сообщений: 223
19.01.2019, 09:10
_____
| \
| |
| |
| |
| |
|______|
Вот мы и считали маленький поток Module1 находящийся в мини-контейнере,
используя Ssat. Что здесь и как, я не знаю, надо читать инфу о том
как хранится информация в module1.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;
Наверняка тут есть ошибка, т.к я предположил что поправки на разрыв миниконтейнера не существует,
а она есть. Поэтому поток выглядит не совсем так. Чтобы считать его правильно
надо считать мини-контейнер целиком, а потом уже считывать сектора потоков из него используя таблицу
SSat и тогда можно обойтись без всяких поправок. В моём декомпиляторе всё считывается последовательно:
открыть номер мсат->открыть номер sat->в нём ищутся потоки,миниконтейнер,таблицаssat,таблица directory
поэтому мне приходится делать два предварительных прогона:1)поиск поправок к минисекторам методом впрыгивания
2)поиск существующих директорий тоже методом впрыгивания(т.к описание директорий может лежать
ниже,чем сами директории).
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;

_____
| \
| |
| |
| |
| |
|______|
Займёмся теперь разбором пустого файла xls. В нём содержатся потоки Workbook,
_____ _____
| \ | \
| | | |
| | | |
| | | |
| | | |
|______| |______|
SummaryInformation и DocumentSummaryInformation.

Потоки SummaryInformation и DocumentSummaryInformation являются приложениями
любых компаунд файлов(word,access итд.). Т.е они не являются конкретно экселевским
продуктом. Значит наше основное внимание должно быть направленно на поток Workbook.
А об SummaryInformation и DocumentSummaryInformation я раскажу ниже.

__________________
| \
| Globals substream \
| \
|_____________________|
| |
| Sheet1 substream | /|
| | / |______________
|_____________________| / | поток Workbook
| | \ ______________|
| Sheet2 substream | \ |
| | \|
|_____________________|
| |
| Sheet3 substream |
| . . . |
|_____________________|


Поток Workbook содержит подпоток globals substream и несколько подпотоков
Sheet substream по одному на каждый лист.
Если у вас в экселе 4 листа. То в workbook будет 5 подпотоков,
если 5 листов, то будет 6 подпотоков. Если один, то два подпотока.
Внутри подпотока информация хранится в виде т.н записей.
Запись это группа байт отвечающих за одно действие, н.р выделение
ячейки, изменение ширины столбца, изменение высоты строки,
переключение между листами.

Каждый подпоток в workbook начинается записью BOF(Begin of file)
а заканчивается записью EOF(end of file).

Записи в подпотоках должны быть выстроены в определённом порядке.


Сначала приведу их порядок для подпотока Workbook globals

________________________________________ _______
|ИМ ГРУПЫ|ИМ ПОДГРПЫ|ОБЯЗ|ОРИГ НАЗВАНИЕ |ОПОЗНАВ|
|ОБЯЗ/НЕТ| ОБЯЗ/НЕТ |ЗАПC|ЗАПИСИ |БАЙТЫ |
|======================================= ========|
| +|BOF |0809h |Метка: начало
|-----------------------------------------------|
|File и|WRITEPROT |0086h |Фаил защищён от записи
|Рrotection и|FILEPASS |002Fh |Содержит информац о пароле на чтение\запись
|Block и|WRITEACCESS |005Ch |Имя пользователя последний раз сохранившего запороленный фаил
| - и|FILESHARING |005Bh |CRC пароля,имя пользователя,установка только чтение
|-----------------------------------------------|
| -|CODEPAGE |0042h |Кодировка всех текстовых строк в документе
| -|DSF |0161h |Метка фаил excel 2003 содержит Workbook от excel 1997
| -|TABID |не изв.|не описано
| -|FNGROUPCOUNT |не изв.|не описано
|-----------------------------------------------|
|Workbook и|WINDOWPROTECT |0019H |метка:книга или лист защищён от изменения
|Protection и|PROTECT |0012h |то же
|Block и|PASSWORD |0013h |16битная CRC пароля
| - и|PROT4REV |01AFh |описание не точное: 1-защищена часть книги,0-никакая часть книги не защищена
| и|PROT4REVPASS |01BCh |описание не точное:>0 - 16битная CRC пароля части книги,=0 - нет пароля
|-----------------------------------------------|
| +|WINDOW1 |003Dh |Каким видится окно Экселя на рабочем столе
| -|BACKUP |0040h |если 1 - делать копию текущего файла перед сохранением
| -|HIDEOBJ |008Dh |Режим отображения обьектов на всех листах:0-показывать всё,1-показывать только рамки,2-не показывать обьекты
| -|DAТЕ MODE |0022h |С какого даты идёт времяисчесление в книге:0-c 31 декабря 1899, 1-с 1 января 1904
| -|PRECISION |000Eh |1-Формулы в книге используют реальные значения ячеек,0-формулы используют уже вычисленные значения.
| -|REFRESHALL |01B7h |не описано
| -|BOOKBOOL |00DAh |0-сохранять ссылки на другие документы xls,1-не сохранять ссылки на другие документы xls
|-----------------------------------------------|
|Font Block +|FONT1 |0031h |много параметров для каждого использованого шрифта в листах эксель
| + -|FONT2 |0031h |
| -|И.Т.Д |0031h |
|-----------------------------------------------|
|Format Block +|FORMAT1 |041Eh |форматы значений используемых в ячейках
| - -|FORMAT2 |041Eh |
| -|И.Т.Д |041Eh |
|-----------------------------------------------|
|XF Block +|XF1 |00E0h |Выравнивание данных,вращение данных,пернос и автоподбор ширины текста в ячейках
| + -|XF2 |00E0h |
| -|И.Т.Д |00E0h |
|-----------------------------------------------|
|Style Block +|STYLE1 |0293h |Сохраняет имя для пользовательского стиля данных в ячейке
| + -|STYLE2 |0293h |или подробные характеристики системного стиля данных
| -|И.Т.Д |0293h |
|-----------------------------------------------|
| -|PALETTE |0092h |Доступные цвета в палитрах текста, фона ячейки их порядок и расцветка экселевских окошек
| +|USESELFS |0160h |Какой язык используется в формулах:0-англ,1-системный
|-----------------------------------------------|
|Sheet Block +|SHEET1 |0085h |Описывает характеристики всех страниц внутри книги:Адрес начала страницы,видимость,тип,имя страницы unicode
| + -|SHEET2 |0085h |
| -|И.Т.Д |0085h |
|-----------------------------------------------|
| -|COUNTRY |008Ch |установки страны на компьютере, установки страны в документе
|-----------------------------------------------|
|Link Table|EXTERNALBOOK+|EXTERNALBOOK |01AEh | в
| |Blocks1 |----------------------| н
| | + -|EXTERNALNAME1 |0023h | е
| - | -|EXTERNALNAME2 |0023h | ш
| | -|И.Т.Д |0023h | н
| | |----------------------| и
| | +|XCT1 |0059h | е
| | +|CRN1 |005Ah |
| | -|CRN2 |005Ah | с
| | -|И.Т.Д |005Ah | в
| | |----------------------| я
| | -|XCT2 |0059h | з
| | -|CRN4 |005Ah | и
| | -|CRN5 |005Ah |
| | -|И.Т.Д |005Ah | к
| | |----------------------| н
| | -|XCT3 |0059h | и
| | -|CRN7 |005Ah | г
| | -|CRN8 |005Ah |
| | -|И.Т.Д |005Ah | e
| -----------------------------| | x
| |EXTERNALBOOK+|EXTERNALBOOK |01AEh | c
| |Blocks1 |----------------------| e
| | - -|EXTERNALNAME1 |0023h | l
| | -|EXTERNALNAME2 |0023h |
| | -|И.Т.Д |0023h |
| | |----------------------|
| | +|XCT1 |0059h |
| | +|CRN1 |005Ah |
| | -|CRN2 |005Ah |
| | -|И.Т.Д |005Ah |
| | |----------------------|
| | -|XCT2 |0059h |
| | -|CRN4 |005Ah |
| | -|CRN5 |005Ah |
| | -|И.Т.Д |005Ah |
| | |----------------------|
| | -|XCT3 |0059h |
| | -|CRN7 |005Ah |
| | -|CRN8 |005Ah |
| | -|И.Т.Д |005Ah |
| -----------------------------| |
| | - И.Т.Д | . . . | . . . |
| -----------------------------| |
| +|EXTERNSHEET |0017h |
| -|DEFINED NAME1 |0018h |
| -|DEFINED NAME2 |0018h |
| -|DEFINED NAME3 |0018h |
| -|И.Т.Д |0018h |
|-----------------------------------------------|
|Shared +|SST |00FCH |Содержимое текстовых ячеек всех листов хранится здесь.1)общ кол-во текст ячеек 2)сколько из них не повторяются 3)сам текст из ячеек
|String Table -|EXTSST |00FFH |смещение этих этих строк внутри подпотока workbook globals.
| - | | |
|-----------------------------------------------|
| +|EOF |000Ah |
|_______________________________________ ________|



Теперь для подпотоков листов(Sheet substream)

________________________________________ _______
|ИМЯ |ИМЯ |О|ОРИГИНАЛЬНОЕ |ОПОЗНАВ|
|ГРУППЫ |ПОДГРП|Б|НАЗВАНИЕ | |
|ОБЯЗ/НЕТ|ОБ/НЕ |З|ЗАПИСИ |БАЙТЫ |
|======================================= ========|
| +|BOF |0809h |Метка: начало
|-----------------------------------------------|
| -|INDEX |020Bh |указатель на первую исп строку,позиция перв записи defcolwidth в листе,позиции dbcell
|-----------------------------------------------|
|Calculation и|UNCALCED |005Eh |метка:формула не пересчитывается перед сохранением
|Settings и|CALCCOUNT |000Ch |максимальное количество циклов пересчёта в формуле
|Block и|CALCMODE |000Dh |1-автоматический пересчёт формул,0-ручной,-1-автоматически,кроме таблиц
| - и|REFMODE |000Fh |формат адреса в формуле:0-"R1C1:R2C2", 1-"$A$1:$B$2"
| и|DELTA |0010h |64битное число с плав точк(сопроцесс) показывающее максимальный результат формулы при котором прекращаются циклы пересчёта
| и|ITERATION |0011h |1-циклы пересчёта в формуле включены,0-выключены
| и|SAFERECALC |005Fh |1-пересчитывать все формулы на листе перед сохранением,0-не пересчитывать
------------------------------------------------|
| -|PRINTHEADERS |002Ah |1-область печати листа захватывает номера строк и буквы столбцов 0-не захватывает
| -|PRINTGRIDLINES |002Bh |1-печатать сетку ячеек, 0-не печатать сетку
| -|GRIDSET |0082h |устанавливалась ли предыдущая опция(PRINTGRIDLINES)1-да,0-нет
| -|GUTS |0080h |Режим расположения outline символов строк и столбцов.
| -|DEFAULTROWHEIGHT |0225h |Запись для всех строк на листе кроме тех которые изменены пользоват.2-байта дополнит характерист строчек,2байта высота строчек
| -|SHEETPR |0081h |множество характеристик листов:разрывы листов,применение стилей листов,маштабируемость на печати и др
------------------------------------------------|
|Page и|HORIZONTALPAGEBREAKS |001Bh |указатели перед каким и после какого row index делать разрывы страниц для печати
|Settings и|VERTICALPAGEBREAKS |001Ah |то же но для column index для печати
|Block и|HEADER |0014h |Текстовая строка заголовок для этого листа для печати
| - и|FOOTER |0015h |Текстовая строка примечание для этого листа для печати
| и|HCENTER |0083h |Центровать страницу горизонтально для печати:1-центровать стр горизонт.0-выравнивать по лев краю
| и|VCENTER |0084h |Центровать страницу вертикально для печати:1-ценровать стр вертикально 0-выравнивать по верхнему краю
| и|LEFTMARGIN |0026h |64битное число с плав точк(сопроцесс) обознач левый край страницы в дробных от дюйма.
| и|RIGHTMARIGIN |0027h |64битное число с плав точк(сопроцесс) обознач правый край страницы в дробных от дюйма.
| и|TOPMARGIN |0028h |64битное число с плав точк(сопроцесс) обознач верхний край страницы в дробных от дюйма.
| и|BOTTOMMARGIN |0029h |64битное число с плав точк(сопроцесс) обознач нижний край страницы в дробных от дюйма.
| и|PLS |004Dh |Внутренние установки принтера. Подробности не известны.
| и|PAGESETUP |00A1h |Похоже на содержимое меню фаил->параметры страницы.
| и|BITMAP |00E9h |Размещение и состав BMP картинки на листе
------------------------------------------------|
|Worksheet и|PROTECT |0012h |1-страница защищена от изменения,0-не защищена.
|Protection и|OBJECTPROTECT |0063h |1-обьекты листа защищены,0-не защищены
|Block и|SCENPROTECT |00DDh |1-сценарии листа защищены,0-не защищены
| - и|PASSWORD |0013h |16 битная CRC пароля листа.
------------------------------------------------|
| -|DEFCOLWIDTH |0055h |Ширина остальных столбцов на листе(кроме специально обозначеных в colwidth,colinfo,standardwith)
|-----------------------------------------------|
|Colinfo +|COLINFO1 |007Dh |Отмечает диапазоны столбцов с изменённой шириной и измененным форматированием(указатель на XF запись в Global substream)
|Block -|COLINFO2 |007Dh |
| - -|И.Т.Д |007Dh |
|-----------------------------------------------|
| -|SORT |0090h |Сохраняет условие последней сортировки ячеек на листе.
| +|DIMENSION |0200h |Сохраняет прямоугольник ячеек которые были изменены на листе.
|-----------------------------------------------|
|Row |Rows +|ROW1 |0208h |Много параметров для каждой задействованной строки ячеек на листе
| | + -|ROW2 |0208h |
| | -|И.Т.Д. |0208h |
| ----------------------------------------|
|Blocks1|Cell или|BLANK(+XF) |0201h |Представляет пустую ячейку,которая подчиняется XF записи.
| - |Blocks или|BOOLERR(+XF) |0205h |Представляет логическое значение или код ошибки находятся в ячейке и какое форматиров в ячейке(указатель на XF запись)
| | - или|LABEL(+XF) |0204h |Запись устарела.Прямое представление unicode строки находящейся в ячейке.(По-новому строки располагаются в global substream а LABELSST указавыет на них.)
| | или|LABELSST(+XF) |00FDh |Не прямое представление Unicode строки строки находящейся в ячейке.(Строки располагаются в записи SST в global substream а LABELSST указавыет на них.)
| | или|MULBLANK(+XF) |00BEh |Отмечает диапазон пустых ячеек в строке,которые подчиняются XF записи.
| | или|MULRK(+XF) |00BDh |Модифицированное представление Integer,Single значений находящиеся в диапазоне ячеек.
| | или|NUMBER(+XF) |0203h |Представляет Double значение находящееся в ячейке.
| | или|RK(+XF) |027Eh |Модифицированное представление Integer,Single значений находящихся в ячейке.
| | или|RSTRING(+XF) |00D6h |Запись устарела.Прямое представление unicode строки находящейся в ячейке и использующей reach text formatting.(По-новому строки располагаются в global substream а LABELSST указавыет на них.)
| |---------------------------------------|
| |Formula +|FORMULA |0006h |Представляет данные о формуле находящейся в ячейке:в какой ячейке, высчитаный результат,сама формула
| |Cell |----------------------------|в виде RPN представления(удобного для высчитывания в компьютере.-сначало действие, потом операнды чтоб легко перескакивать в процедуру.(помните что в стеке обратный порядок))элементами формулы.
| |Block или|ARRAY |0221h |Представляет диапазон ячеек на которые действует FORMULA.
| | или|SHAREDFMLA |04BCh |Похоже на предыдущее.Разница не понятна.
| | или|DAТАTABLE |0236h |Прямоугольник содержащий формулы(в виде RPN представления элементами формулы). В котором каждая формула для соответсвующей ячейки.
| | или|запись отсутствует | -- |Моя пометка, означающая что после записи FORMULA, не может быть никакой из записей:ARRAY,SHAREDFMLA,DAТАTABLE.
| | |----------------------------|
| | -|STRING |0207h |Результат формулы в виде unicode строки.
| ----------------------------------------|
| +|DBCELL |00D7h |Представляет смещения строк внутри потока Workbook.
|-----------------------------------------------|
|Row |Rows +|ROW1 |0208h | С
| | + -|ROW2 |0208h | л
| | -|И.Т.Д. |0208h | е
| ----------------------------------------| д
|Blocks2|Cell или|BLANK |0201h | у
| - |Blocks или|BOOLERR |0205h | ю
| | - или|LABEL |0204h | щ
| | или|LABELSST |00FDh | и
| | или|MULBLANK |00BEh | й
| | или|MULRK |00BDh |
| | или|NUMBER |0203h | с
| | или|RK |027Eh | т
| | или|RSTRING |00D6h | р
| |---------------------------------------| о
| |Formula +|FORMULA |0006h | к
| |Cell |----------------------------| о
| |Block или|ARRAY |0221h | в
| | или|SHAREDFMLA |04BCh | ы
| | или|DAТАTABLE |0236h | й
| | или|запись отсутствует | -- |
| | |----------------------------| б
| | -|STRING |0207h | л
| ----------------------------------------| о
| +|DBCELL |00D7h | к.
|-----------------------------------------------|
| И.Т.Д. | . . . |. . .|
|-----------------------------------------------|
|Worksheet View +|WINDOW2+ |023Eh |Много параметров о том как выглядит этот лист:показыв ли формулы,показ ли решётка,как заморожен ли Tsplitter(разбивка окна на 4 части)
|Settings Block -|SCL |00A0h |Увеличение страницы достигается путём соотношения нумератор:денумератор
| + -|PANE |0041h |Информация о положении граней Tsplitter'а(разбиение окна excel на 4 мелких окна).
| ---------------------------------------|
| |Selection+|SELECTION1 |001Dh |Выделение ячейки или диапазона ячеек на листе. И их положение по отношению к граням Tsplitter'а.
| |block -|SELECTION2 |001Dh |след дипазон
| | - -|И.Т.Д. |001Dh |след дипазон
|-----------------------------------------------|
| -|STANDARDWIDTH |0099h |Ширина остальных столбцов на листе(кроме специально обозначеных в colwidth,colinfo)
|-----------------------------------------------|
|Merged cells +|MERGEDCELLS1 |00E5h |Диапазон соединённых ячеек.
|block -|MERGEDCELLS2 |00E5h |
| - -|И.Т.Д. |00E5h |
|-----------------------------------------------|
| -|LABELRANGES |015Fh |Все диапазоны ячеек с метками. Не знаю что это.
| -|PHONETICPR |00EFh |Установки для диалогового окна "Asian phonetic settings".
------------------------------------------------|
|Conditional +|CFHEADER1 |01B0h |список диапазонов использующих условное форматирование.
|Formatting +|CFRULE1 |01B1h |Тип условного форматироватия(шрифт:жирность, подчёркнутость,выравнивание,границы ячеек,защита ячеек)ссылающийся на один диапазон из списка диапазонов в CFHEADER
|Table -|CFRULE2 |01B1h |
| - -|И.Т.Д. |01B1h |
| |----------------------------|
| -|CFHEADER2 |01B0h |
| -|CFRULE3 |01B1h |
| -|CFRULE4 |01B1h |
| -|И.Т.Д. |01B1h |
| |----------------------------|
| |И.Т.Д. |01B0h |
| -| |01B1h |
| -| |01B1h |
| -| |01B1h |
------------------------------------------------|
|Hyperlink +|HYPERLINK1 |01B8H |ячейка или диапазон ячеек и гиперссылка в ней
|Table -|QUICKTIP1 |0800h |пояснение к этой ссылке при наведении на неё курсора мыши
| - |----------------------------|
| -|HYPERLINK2 |01B8H |
| -|QUICKTIP2 |0800h |
| |----------------------------|
| -|И.Т.Д. |01B8H |
| -| |0800h |
------------------------------------------------|
|Data Validity +|DATAVALIDATIONS |01B2h |не знаю что это
|Table +|DATAVALIDATION1 |01BEh |
| - -|DATAVALIDATION2 |01BEh |
| -|DATAVALIDATION3 |01BEh |
| -|И.Т.Д. |01BEh |
------------------------------------------------|
| -|SHEETLAYOUT |0862h |цвет ярлычка страницы(на котором написано её имя)
| -|SHEETPROTECTION |0867h |дополнительные опции защиты листа
| -|RANGEPROTECTION |0868h |защита диапазонов ячеек
| +|EОF |000AH |
|_______________________________________ ________|

Схема таблицы становится не сложной если внимательно к ней присмотреться:
в самой левой колонке находятся блоки, в некоторых из них есть подблоки(правее),
следом идут записи(ещё правее). Самый последний столбец это опознаватели записей,
т.е по этим цифрам можно определить название записи. За таблицой распологается
приблизительное назначение этих записей.

В кождой колонке есть отметки: +, -, и, или. Означающие обязательность нахождения
этих записей в потоке workbook. Если блок помечен как "-", а в подблоке встречается
знак "+". Это означает, что наличие блока не обязательно. Но раз уж если он
существует или вы пишете его в поток, то подблок со знаком "+" обязательно должен в
нём присутствовать. Такая же система действует и на записи. Ещё, знак "и" означает
что точно одна из этих записей должна присутствовать в блоке, а остальные по желанию.
Знак "или" означает что из записей должна присутствовать только одна, остальные не
могут. Если у блока нет названия, то это не блок, т.е это записи не вошедшие в
какой-либо блок.
Если у вас возникают вопросы обратитесь к странице 85-86
документа excelfileformat.pdf.
0
 Аватар для Estimable
195 / 14 / 1
Регистрация: 02.01.2017
Сообщений: 223
19.01.2019, 09:10
_____
| \
| |
| |
| |
| |
|______|
Соберём поток Workbook. Вы помните как это делается?
1)Собираем таблицу Msat. Начальные 109 номеров находятся в заголовке по смещению 4Ch.
Номер следующего сектора находим в заголовке по смещению 44h(если, конечно,
там нет значения FEFFFFFF,говорящее что следующих секторов не существует). Из него выводим
смещение в файле по формуле:offset=(number+1h)*200h.Считывае м этот сектор Msat.
Теперь каждый последний номер в секторе указывает на следующий сектор Msat.
Смещение в файле выводится сами знаете по какой формуле. В последнем секторе последний
номер будет равен FFFFFFFFh.
2)Собираем таблицу Sat. Используя каждый номер из таблицы msat, выводим смещения секторов
Sat. Собираем все полученные сектора и последовательно нумеруем(от 0) каждый номер из
таблицы Sat.
3)Собираем таблицу Ssat, если она существует в файле(это можно узнать посмотрев значение
в заголовке по смещению 3Ch, если там нет FEFFFFFF,то она существует). Номер первого
сектора берём по смещению 3Ch. Этот номер имеет двойной смысл.а)из него выводится
смещение начального сектора Ssat в файле.б)Он указывает на порядковый номер(вы не забыли
пронумеровать их?) в таблице Sat в котором записан следующий номер сектора Ssat.
Остальные сектора ищутся по таблице Sat. В которой каждый номер имеет такой же двойной
смысл:а)вывод. смещения,б)порядковый номер таблицы Sat в котором будет написан номер
следующего сектора.Пронумеруйте все номера таблицы Ssat.
4)Собираем таблицу директорий. Она собирается подобно таблице Ssat.Номер первого
сектора берём из заголовка по смещению 30h.Здесь каждый номер имеет двоякий смысл.
Если не знаете какой, читайте пункт 3.
5)Информация о мини-контейнере,которая нам необходима это поправки для каждого
его минисектора которые возникают из-за разрыва миниконтейнера(в Sat) и смещение в
файле.Оно выводится из четырёх байт находящихся по смещению 74h от начала таблицы
директорий(т.е смещение 74h внутри директории "Root Entry").Если тут значение FEFFFFFF,
значит мини-контейнера нет, как и таблицы Ssat. Если есть, то смещение выводится по формуле
offset=(number+1h)*200h.
6)Собираем Потоки.По смещению 78h от начала директории каждого потока в восьми байтах
находится размер этого потока. Если размер меньше 4096 байт, значит поток находится в
мини-контейнере и ищется с помощью таблицы Ssat.Если больше или равен 4096, то
поток находится в файле и ищется с помощью таблицы Sat.
а)Поиск с помощью Sat: по смещению 74h от начала директории каждого потока хранится
первый номер сектора этого потока. Этот номер имеет двойной смысл: из него
выводится смещение по формуле:offset=(number+1h)*200h и порядковый номер в таблице Sat в
котором указан номер следующего сектора этого потока. Остальные сектора ищутся
по таблице Sat. В которой каждый номер имеет такой же двойной смысл:
вывод смещения и порядковый номер таблицы Sat в котором будет написан номер
следующего сектора.
б)Поиск с помощью Ssat. Помните, что с помощью Ssat мы ищем маленькие сектора(64байта)
внутри мини-контейнера. Процедура похожа на поиск в Sat, только формула вывода смещения
другая.
Смещение 74h от начала директории даст нам номер первого сектора, там опять двойной
смысл. Смещение здесь вычислим по формуле:offset=offsetминиконтейнера+попр авканаразрыв+(number*40h)
offsetминиконтейнера мы сохранили в пункте 5. Ну а следующие сектора мы ищем
используя таблицу Ssat. В Ssat каждый номер тоже имеет двойной смысл. И
здесь смещение каждого следующего сектора мы будем находить по
формуле: offset=offsetминиконтейнера+поправканара зрыв+(number*40h).

Всё, допустим мы прошли все эти этапы сборки и собрали все сектора
потока Workbook (в пустом документе).
Вот они, разложенные по секторам:

Workbook
09 08 10 00 00 06 05 00 46 18 CD 07 C9 80 00 00
06 02 00 00 E1 00 02 00 B0 04 C1 00 02 00 00 00
E2 00 00 00 5C 00 70 00 06 00 00 57 69 6E 6E 65
72 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
20 20 20 20 20 20 20 20 42 00 02 00 B0 04 61 01
02 00 00 00 C0 01 00 00 3D 01 06 00 01 00 02 00
03 00 9C 00 02 00 0E 00 19 00 02 00 00 00 12 00
02 00 00 00 13 00 02 00 00 00 AF 01 02 00 00 00
BC 01 02 00 00 00 3D 00 12 00 78 00 78 00 F8 25
98 1C 38 00 02 00 00 00 01 00 58 02 40 00 02 00
00 00 8D 00 02 00 00 00 22 00 02 00 00 00 0E 00
02 00 01 00 B7 01 02 00 00 00 DA 00 02 00 00 00
31 00 1A 00 C8 00 00 00 FF 7F 90 01 00 00 00 00
00 00 05 01 41 00 72 00 69 00 61 00 6C 00 31 00
1A 00 C8 00 00 00 FF 7F 90 01 00 00 00 00 00 00
05 01 41 00 72 00 69 00 61 00 6C 00 31 00 1A 00
C8 00 00 00 FF 7F 90 01 00 00 00 00 00 00 05 01
41 00 72 00 69 00 61 00 6C 00 31 00 1A 00 C8 00
00 00 FF 7F 90 01 00 00 00 00 00 00 05 01 41 00
72 00 69 00 61 00 6C 00 1E 04 2F 00 05 00 15 00
01 23 00 2C 00 23 00 23 00 30 00 22 00 40 04 2E
00 22 00 3B 00 5C 00 2D 00 23 00 2C 00 23 00 23
00 30 00 22 00 40 04 2E 00 22 00 1E 04 39 00 06
00 1A 00 01 23 00 2C 00 23 00 23 00 30 00 22 00
40 04 2E 00 22 00 3B 00 5B 00 52 00 65 00 64 00
5D 00 5C 00 2D 00 23 00 2C 00 23 00 23 00 30 00
22 00 40 04 2E 00 22 00 1E 04 3B 00 07 00 1B 00
Workbook
01 23 00 2C 00 23 00 23 00 30 00 2E 00 30 00 30
00 22 00 40 04 2E 00 22 00 3B 00 5C 00 2D 00 23
00 2C 00 23 00 23 00 30 00 2E 00 30 00 30 00 22
00 40 04 2E 00 22 00 1E 04 45 00 08 00 20 00 01
23 00 2C 00 23 00 23 00 30 00 2E 00 30 00 30 00
22 00 40 04 2E 00 22 00 3B 00 5B 00 52 00 65 00
64 00 5D 00 5C 00 2D 00 23 00 2C 00 23 00 23 00
30 00 2E 00 30 00 30 00 22 00 40 04 2E 00 22 00
1E 04 6B 00 2A 00 33 00 01 5F 00 2D 00 2A 00 20
00 23 00 2C 00 23 00 23 00 30 00 22 00 40 04 2E
00 22 00 5F 00 2D 00 3B 00 5C 00 2D 00 2A 00 20
00 23 00 2C 00 23 00 23 00 30 00 22 00 40 04 2E
00 22 00 5F 00 2D 00 3B 00 5F 00 2D 00 2A 00 20
00 22 00 2D 00 22 00 22 00 40 04 2E 00 22 00 5F
00 2D 00 3B 00 5F 00 2D 00 40 00 5F 00 2D 00 1E
04 6B 00 29 00 33 00 01 5F 00 2D 00 2A 00 20 00
23 00 2C 00 23 00 23 00 30 00 5F 00 40 04 5F 00
2E 00 5F 00 2D 00 3B 00 5C 00 2D 00 2A 00 20 00
23 00 2C 00 23 00 23 00 30 00 5F 00 40 04 5F 00
2E 00 5F 00 2D 00 3B 00 5F 00 2D 00 2A 00 20 00
22 00 2D 00 22 00 5F 00 40 04 5F 00 2E 00 5F 00
2D 00 3B 00 5F 00 2D 00 40 00 5F 00 2D 00 1E 04
7B 00 2C 00 3B 00 01 5F 00 2D 00 2A 00 20 00 23
00 2C 00 23 00 23 00 30 00 2E 00 30 00 30 00 22
00 40 04 2E 00 22 00 5F 00 2D 00 3B 00 5C 00 2D
00 2A 00 20 00 23 00 2C 00 23 00 23 00 30 00 2E
00 30 00 30 00 22 00 40 04 2E 00 22 00 5F 00 2D
00 3B 00 5F 00 2D 00 2A 00 20 00 22 00 2D 00 22
00 3F 00 3F 00 22 00 40 04 2E 00 22 00 5F 00 2D
00 3B 00 5F 00 2D 00 40 00 5F 00 2D 00 1E 04 7B
00 2B 00 3B 00 01 5F 00 2D 00 2A 00 20 00 23 00
2C 00 23 00 23 00 30 00 2E 00 30 00 30 00 5F 00
Workbook
40 04 5F 00 2E 00 5F 00 2D 00 3B 00 5C 00 2D 00
2A 00 20 00 23 00 2C 00 23 00 23 00 30 00 2E 00
30 00 30 00 5F 00 40 04 5F 00 2E 00 5F 00 2D 00
3B 00 5F 00 2D 00 2A 00 20 00 22 00 2D 00 22 00
3F 00 3F 00 5F 00 40 04 5F 00 2E 00 5F 00 2D 00
3B 00 5F 00 2D 00 40 00 5F 00 2D 00 1E 04 1C 00
A4 00 17 00 00 22 24 22 23 2C 23 23 30 5F 29 3B
5C 28 22 24 22 23 2C 23 23 30 5C 29 1E 04 21 00
A5 00 1C 00 00 22 24 22 23 2C 23 23 30 5F 29 3B
5B 52 65 64 5D 5C 28 22 24 22 23 2C 23 23 30 5C
29 1E 04 22 00 A6 00 1D 00 00 22 24 22 23 2C 23
23 30 2E 30 30 5F 29 3B 5C 28 22 24 22 23 2C 23
23 30 2E 30 30 5C 29 1E 04 27 00 A7 00 22 00 00
22 24 22 23 2C 23 23 30 2E 30 30 5F 29 3B 5B 52
65 64 5D 5C 28 22 24 22 23 2C 23 23 30 2E 30 30
5C 29 1E 04 37 00 A8 00 32 00 00 5F 28 22 24 22
2A 20 23 2C 23 23 30 5F 29 3B 5F 28 22 24 22 2A
20 5C 28 23 2C 23 23 30 5C 29 3B 5F 28 22 24 22
2A 20 22 2D 22 5F 29 3B 5F 28 40 5F 29 1E 04 2E
00 A9 00 29 00 00 5F 28 2A 20 23 2C 23 23 30 5F
29 3B 5F 28 2A 20 5C 28 23 2C 23 23 30 5C 29 3B
5F 28 2A 20 22 2D 22 5F 29 3B 5F 28 40 5F 29 1E
04 3F 00 AA 00 3A 00 00 5F 28 22 24 22 2A 20 23
2C 23 23 30 2E 30 30 5F 29 3B 5F 28 22 24 22 2A
20 5C 28 23 2C 23 23 30 2E 30 30 5C 29 3B 5F 28
22 24 22 2A 20 22 2D 22 3F 3F 5F 29 3B 5F 28 40
5F 29 1E 04 36 00 AB 00 31 00 00 5F 28 2A 20 23
2C 23 23 30 2E 30 30 5F 29 3B 5F 28 2A 20 5C 28
23 2C 23 23 30 2E 30 30 5C 29 3B 5F 28 2A 20 22
2D 22 3F 3F 5F 29 3B 5F 28 40 5F 29 E0 00 14 00
00 00 00 00 F5 FF 20 00 00 00 00 00 00 00 00 00
00 00 C0 20 E0 00 14 00 01 00 00 00 F5 FF 20 00
Workbook
00 F4 00 00 00 00 00 00 00 00 C0 20 E0 00 14 00
01 00 00 00 F5 FF 20 00 00 F4 00 00 00 00 00 00
00 00 C0 20 E0 00 14 00 02 00 00 00 F5 FF 20 00
00 F4 00 00 00 00 00 00 00 00 C0 20 E0 00 14 00
02 00 00 00 F5 FF 20 00 00 F4 00 00 00 00 00 00
00 00 C0 20 E0 00 14 00 00 00 00 00 F5 FF 20 00
00 F4 00 00 00 00 00 00 00 00 C0 20 E0 00 14 00
00 00 00 00 F5 FF 20 00 00 F4 00 00 00 00 00 00
00 00 C0 20 E0 00 14 00 00 00 00 00 F5 FF 20 00
00 F4 00 00 00 00 00 00 00 00 C0 20 E0 00 14 00
00 00 00 00 F5 FF 20 00 00 F4 00 00 00 00 00 00
00 00 C0 20 E0 00 14 00 00 00 00 00 F5 FF 20 00
00 F4 00 00 00 00 00 00 00 00 C0 20 E0 00 14 00
00 00 00 00 F5 FF 20 00 00 F4 00 00 00 00 00 00
00 00 C0 20 E0 00 14 00 00 00 00 00 F5 FF 20 00
00 F4 00 00 00 00 00 00 00 00 C0 20 E0 00 14 00
00 00 00 00 F5 FF 20 00 00 F4 00 00 00 00 00 00
00 00 C0 20 E0 00 14 00 00 00 00 00 F5 FF 20 00
00 F4 00 00 00 00 00 00 00 00 C0 20 E0 00 14 00
00 00 00 00 F5 FF 20 00 00 F4 00 00 00 00 00 00
00 00 C0 20 E0 00 14 00 00 00 00 00 01 00 20 00
00 00 00 00 00 00 00 00 00 00 C0 20 E0 00 14 00
01 00 AA 00 F5 FF 20 00 00 F8 00 00 00 00 00 00
00 00 C0 20 E0 00 14 00 01 00 A8 00 F5 FF 20 00
00 F8 00 00 00 00 00 00 00 00 C0 20 E0 00 14 00
01 00 09 00 F5 FF 20 00 00 F8 00 00 00 00 00 00
00 00 C0 20 E0 00 14 00 01 00 AB 00 F5 FF 20 00
00 F8 00 00 00 00 00 00 00 00 C0 20 E0 00 14 00
01 00 A9 00 F5 FF 20 00 00 F8 00 00 00 00 00 00
00 00 C0 20 93 02 04 00 10 80 04 FF 93 02 04 00
11 80 07 FF 93 02 04 00 00 80 00 FF 93 02 04 00
12 80 05 FF 93 02 04 00 13 80 03 FF 93 02 04 00
Workbook
14 80 06 FF 60 01 02 00 01 00 85 00 12 00 76 08
00 00 00 00 05 01 1B 04 38 04 41 04 42 04 31 00
85 00 12 00 7D 09 00 00 00 00 05 01 1B 04 38 04
41 04 42 04 32 00 85 00 12 00 84 0A 00 00 00 00
05 01 1B 04 38 04 41 04 42 04 33 00 8C 00 04 00
07 00 07 00 C1 01 08 00 C1 01 00 00 80 38 01 00
FC 00 08 00 00 00 00 00 00 00 00 00 FF 00 02 00
08 00 0A 00 00 00 09 08 10 00 00 06 10 00 46 18
CD 07 C9 80 00 00 06 02 00 00 0B 02 10 00 00 00
00 00 00 00 00 00 00 00 00 00 2E 09 00 00 0D 00
02 00 01 00 0C 00 02 00 64 00 0F 00 02 00 01 00
11 00 02 00 00 00 10 00 08 00 FC A9 F1 D2 4D 62
50 3F 5F 00 02 00 01 00 2A 00 02 00 00 00 2B 00
02 00 00 00 82 00 02 00 01 00 80 00 08 00 00 00
00 00 00 00 00 00 25 02 04 00 00 00 FF 00 81 00
02 00 C1 04 14 00 00 00 15 00 00 00 83 00 02 00
00 00 84 00 02 00 00 00 A1 00 22 00 00 00 FF 00
01 00 01 00 01 00 04 00 00 00 00 00 00 00 00 00
00 00 E0 3F 00 00 00 00 00 00 E0 3F 00 00 55 00
02 00 08 00 00 02 0E 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 3E 02 12 00 B6 00 00 00 00 00
40 00 00 00 00 00 00 00 00 00 00 00 1D 00 0F 00
03 00 00 00 00 00 00 01 00 00 00 00 00 00 00 EF
00 06 00 00 00 37 00 00 00 0A 00 00 00 09 08 10
00 00 06 10 00 46 18 CD 07 C9 80 00 00 06 02 00
00 0B 02 10 00 00 00 00 00 00 00 00 00 00 00 00
00 35 0A 00 00 0D 00 02 00 01 00 0C 00 02 00 64
00 0F 00 02 00 01 00 11 00 02 00 00 00 10 00 08
00 FC A9 F1 D2 4D 62 50 3F 5F 00 02 00 01 00 2A
00 02 00 00 00 2B 00 02 00 00 00 82 00 02 00 01
00 80 00 08 00 00 00 00 00 00 00 00 00 25 02 04
00 00 00 FF 00 81 00 02 00 C1 04 14 00 00 00 15
Workbook
00 00 00 83 00 02 00 00 00 84 00 02 00 00 00 A1
00 22 00 00 00 FF 00 01 00 01 00 01 00 04 00 00
00 00 00 00 00 00 00 00 00 E0 3F 00 00 00 00 00
00 E0 3F 00 00 55 00 02 00 08 00 00 02 0E 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 3E 02 12
00 B6 00 00 00 00 00 40 00 00 00 00 00 00 00 00
00 00 00 1D 00 0F 00 03 00 00 00 00 00 00 01 00
00 00 00 00 00 00 EF 00 06 00 00 00 37 00 00 00
0A 00 00 00 09 08 10 00 00 06 10 00 46 18 CD 07
C9 80 00 00 06 02 00 00 0B 02 10 00 00 00 00 00
00 00 00 00 00 00 00 00 3C 0B 00 00 0D 00 02 00
01 00 0C 00 02 00 64 00 0F 00 02 00 01 00 11 00
02 00 00 00 10 00 08 00 FC A9 F1 D2 4D 62 50 3F
5F 00 02 00 01 00 2A 00 02 00 00 00 2B 00 02 00
00 00 82 00 02 00 01 00 80 00 08 00 00 00 00 00
00 00 00 00 25 02 04 00 00 00 FF 00 81 00 02 00
C1 04 14 00 00 00 15 00 00 00 83 00 02 00 00 00
84 00 02 00 00 00 A1 00 22 00 00 00 FF 00 01 00
01 00 01 00 04 00 00 00 00 00 00 00 00 00 00 00
E0 3F 00 00 00 00 00 00 E0 3F 00 00 55 00 02 00
08 00 00 02 0E 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 3E 02 12 00 B6 06 00 00 00 00 40 00
00 00 00 00 00 00 00 00 00 00 1D 00 0F 00 03 1B
00 02 00 00 00 01 00 1B 00 1B 00 02 02 EF 00 06
00 00 00 37 00 00 00 0A 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Workbook
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Workbook
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

Внутри потока множество записей. Рассмотрим их строение.
В самом начале потока мы видим такие строки.
09 08 10 00 00 06 05 00 46 18 CD 07 C9 80 00 00
06 02 00 00 E1 00 02 00 B0 04 C1 00 02 00 00 00
E2 00 00 00 5C 00 70 00 06 00 00 57 69 6E 6E 65
0
 Аватар для Estimable
195 / 14 / 1
Регистрация: 02.01.2017
Сообщений: 223
19.01.2019, 09:12
Первые два байта(любой записи)это её опознаватель.
В данном случае 09 08 это BOF. Посмотрите таблицы записей которые
я выложил выше. Подпотоки в Workbook начинаются с 0809h.
09 08 = перевёрнутое 0809h. Т.к файле это хранится в
перевёрнутом виде.
Следующие два байта: 10 00 это последующий размер записи.
Переворачиваем 10 00=0010h=16десятеричное.Значит хвост
записи = 16байтам.
Вот эти следующие 16 байт(счёт от единицы)
00 06 05 00 46 18 CD 07 C9 80 00 00 06 02 00 00

В хвосте записи хранится основная информация.
Здесь:
00 06 - версия BIFF(в Excel 2003 идёт BIFF версии 8, но в файле она указыв верс 6.).
05 00 - Начало какого подпотока(у нас Workbook globals).
46 18 - Версия сборки(не знаю про что это).
CD 07 - Год выпуска этой версии Excel.(CD 07=07CD=1997десятеричное).
C9 80 00 00 - четыре байта это флаги истории(их расшифровка не известна).
06 02 00 00 - самая младшая версия эксель в которой можно считать все записи этого файла.
Как видите вход в подпоток или поток описывается 16 байтами.


После этих 16 байт начинается следующая запись:
E1 00 02 00 B0 04
опоз раз данные
нава мер
тель

Этого опознавателя записи в openoffice нет, надо читать микрософтовские доки.
Но хорошо что записи из этого блока, помечены "-". Т.е не обязательно должны быть
в подпотоке Workbook globals.

Эту запись я тоже не знаю.

C1 00 02 00 00 00
опоз раз данные
нава мер
тель

эту тоже
E2 00 00 00
опоз раз
нава мер
тель

Как видите у этой записи нулевой размер хвоста, а значит он отсутсутствует.

Вот следующая запись. Называется WRITEACCESS и находится в file protection block.
Здесь находится имя пользователя создавшего этот документ:Winner.
За размером записи видим 2байта:0600 это размер строки, здесь она сжатая unicode, что
почти одно и тоже что однобайтовая ANSI. Различие в том что все нулевые байты не
пишутся.
надпись =6 байт. 57 69 6E 6E 65 72.
Остальные байты записи заполнены 20ками.

опоз
нава размер колво сжат текстовая строка
тель букв ость
5C00 7000 0600 00 57 69 6E 6E 65
72 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
20 20 20 20 20 20 20 20

Следующая запись называется CODEPAGE.
42 00 02 00 B0 04
опоз раз данные
нава мер
тель

Хвост тут говорит о том, какая используется кодировочная таблица в документе:
B004=04B0. На странице 145 в документе excelefileformat видим. Что 04B0 соответствует
UTF16(BIFF8).

Следующая запись DSF(double stream file или двухпоточный фаил).
61 01 02 00 00 00
опоз раз данные
нава мер
тель
Эта запись рассказывает, присутсвует ли в файле ещё и рабочая книга от предыдущей версии
эксель. 00 00 - значит не присутсвует. А если 01 00 - то присутсв книга от BIFF5.

Эти три записи не известны.Возможно что две из них это TABID и FNGROUPCOUNT.
C0 01 00 00
3D 01 06 00 01 00 02 00 03 00
9C 00 02 00 0E 00
опоз раз данные
нава мер
тель
Эти записи не помечены, как обязательные судя по нотации OpenOffice.


Следующая запись WINDOWPROTECT
19 00 02 00 00 00
опоз раз данные
нава мер
тель
00 00 - Означает книга не защищена паролем.


Следующая запись PROTECT
12 00 02 00 00 00
опоз раз данные
нава мер
тель
00 00 - Означает книга не защищена от изменения.

Следующая запись PASSWORD
13 00 02 00 00 00
опоз раз данные
нава мер
тель
00 00 - Означает что у книги нет контрольной суммы пароля, значит нет и самого
пароля. Смотрите в документе excelefileformat, как вычисляется контрольная сумма
пароля.

Следующая запись PROT4REV
AF 01 02 00 00 00
опоз раз данные
нава мер
тель
00 00 - Означает никакая часть книги не защищена.В документе excelefileformat
об этой записи упомянуто вскользь.


Следующая запись PROT4REVPASS
BC 01 02 00 00 00
опоз раз данные
нава мер
тель
00 00 - Означает что у части книги нет контрольной суммы пароля. Значит нет
и пароля на часть книги.

Следующая запись WINDOW1
3D 00 12 00 78 00 78 00 F8 25 98 1C 38 00 02 00 00 00 01 00 58 02
опоз раз данные
нава мер
тель
Запись расказывает каким видится окно эксель на рабочем столе.
78 00=0078 - горизонтальная позиция окна на раб столе (выражено в 1/20 доле)
78 00=0078 - вертикальная позиция окна на раб столе (выражено в 1/20 доле)
F8 25=25f8 - ширина окна на раб столе (выражено в 1/20 доле)
98 1C=1с98 - высота окна на раб столе (выражено в 1/20 доле)
следующие два байта это флаги, поэтому разложим их побитно:
38 00=0038= 0011 1000b
^^ ^ ^^окно не скрыто
|| | окно не минимизировано
|| горизонтальная полоса прокрутки не скрыта
|вертикальная полоса прокрутки не скрыта
панель ярлычков с названиями листов не скрыта
02 00=0002 -какая страница активна в данный момент(тут счёт страниц от 0)
00 00=0000 -какое название страницы стоит первым в панели ярлычков страниц(внизу страницы)
00 01=0100 -количество выбранных страниц в панели ярлычков(кол-во подсвеченных листов)
58 02=0258 - ширина ярлычковой панели с названиями листов(выражено в 1/100 доле от ширины окна)

Следующая запись BACKUP
40 00 02 00 00 00
опоз раз данные
нава мер
тель
00 00 - Означает не создавать копию файла перед сохранением

Следующая запись HIDEOBJ
8D 00 02 00 00 00
опоз раз данные
нава мер
тель
00 00 - Означает показывать все объекты на листах

Следующая запись DAТЕ MODE
22 00 02 00 00 00
опоз раз данные
нава мер
тель
00 00 - Означает времяисчисление(летоисчисление)в документе c 31 декабря 1899

Следующая запись PRECISION
0E 00 02 00 01 00
опоз раз данные
нава мер
тель
01 00 - Означает формулы во всех листах используют реальные значения ячеек.

Следующая запись REFRESHALL
B7 01 02 00 00 00
опоз раз данные
нава мер
тель
Эта запись не описана в документе.

Следующая запись BOOKBOOL
DA 00 02 00 00 00
опоз раз данные
нава мер
тель
00 00 - Означает если возникнут ссылки на другие документы, то их необходимо
сохранять.

Дальше начинается блок шрифтов с четырьмя идентичными записями FONT.
Почему их четыре? Возможно каждая исп для своей цели.
31 00 1A 00 C8 00 00 00 FF 7F 90 01 00 00 00 00 00 00 05 01 41 00 72 00 69 00 61 00 6C 00
31 00 1A 00 C8 00 00 00 FF 7F 90 01 00 00 00 00 00 00 05 01 41 00 72 00 69 00 61 00 6C 00
31 00 1A 00 C8 00 00 00 FF 7F 90 01 00 00 00 00 00 00 05 01 41 00 72 00 69 00 61 00 6C 00
31 00 1A 00 C8 00 00 00 FF 7F 90 01 00 00 00 00 00 00 05 01 41 00 72 00 69 00 61 00 6C 00
опоз раз данные
нава мер
тель

где:
C8 00=00c8 - высота шрифта в 1/20 точки
00 00=0000-флаги шрифта, поэтому разложим их побитно:
00000000 00000000b
^^^^^ ^нет курсива
||||нет перечёркнутости
|||нет выхода за линию
||не отбрасывает тень
|нет сжатости шрифта
нет растянутости шрифта
FF 7F=7FFF - системный цвет шрифта(смотрите стр 195 докум. excelefileformat)
90 01=0190 - жирность шрифта(десятичн от 100 до 1000).190h(400dec)это нормальный шрифт
2BCh(700dec)это жирный шрифт. a<--
00 00=00 00 - положение шрифта обычное.Если 0001-шрифт для степени числа(т.е вверху).2
Если 0002-шрифт для основания числа(т.е внизу) 2
00 - тип подстрочного пространства(т.е расстояния между строками).00-нормальное. a<--
01-одинарное.02-двойное.21-одинарный счёт.22-двойной счёт.
00-семейство шрифта.00-не известно.01-Roman. 02-Swiss. 03-Modern. 04-Script.05-Decorative.
00-Кодировка ANSI latin. для других смотрите стр 172 докум. excelefileformat
00-Этот байт не используется
05 01 41 00 72 00 69 00 61 00 6C 00
^ ^ ^само имя в двухбайтовой unicode кодировке(здесь Arial)
| имя не сжато
размер имени в буквах


Дальше идут 15 записей FORMAT из блока format

1E 04 2F 00 05 00 15 00 01 23 00 2C 00 23 00 23 00 30 00 22 00 40 04 2E 00 22 00 3B 00 5C
00 2D 00 23 00 2C 00 23 00 23 00 30 00 22 00 40 04 2E 00 22 00

1E 04 39 00 06 00 1A 00 01 23 00 2C 00 23 00 23 00 30 00 22 00 40 04 2E 00 22 00 3B 00 5B
00 52 00 65 00 64 00 5D 00 5C 00 2D 00 23 00 2C 00 23 00 23 00 30 00 22 00 40 04 2E 00 22
00

1E 04 3B 00 07 00 1B 00 01 23 00 2C 00 23 00 23 00 30 00 2E 00 30 00 30 00 22 00 40 04 2E
00 22 00 3B 00 5C 00 2D 00 23 00 2C 00 23 00 23 00 30 00 2E 00 30 00 30 00 22 00 40 04 2E
00 22 00

1E 04 45 00 08 00 20 00 01 23 00 2C 00 23 00 23 00 30 00 2E 00 30 00 30 00 22 00 40 04 2E
00 22 00 3B 00 5B 00 52 00 65 00 64 00 5D 00 5C 00 2D 00 23 00 2C 00 23 00 23 00 30 00 2E
00 30 00 30 00 22 00 40 04 2E 00 22 00

1E 04 6B 00 2A 00 33 00 01 5F 00 2D 00 2A 00 20 00 23 00 2C 00 23 00 23 00 30 00 22 00 40
04 2E 00 22 00 5F 00 2D 00 3B 00 5C 00 2D 00 2A 00 20 00 23 00 2C 00 23 00 23 00 30 00 22
00 40 04 2E 00 22 00 5F 00 2D 00 3B 00 5F 00 2D 00 2A 00 20 00 22 00 2D 00 22 00 22 00 40
04 2E 00 22 00 5F 00 2D 00 3B 00 5F 00 2D 00 40 00 5F 00 2D 00

1E 04 6B 00 29 00 33 00 01 5F 00 2D 00 2A 00 20 00 23 00 2C 00 23 00 23 00 30 00 5F 00 40
04 5F 00 2E 00 5F 00 2D 00 3B 00 5C 00 2D 00 2A 00 20 00 23 00 2C 00 23 00 23 00 30 00 5F
00 40 04 5F 00 2E 00 5F 00 2D 00 3B 00 5F 00 2D 00 2A 00 20 00 22 00 2D 00 22 00 5F 00 40
04 5F 00 2E 00 5F 00 2D 00 3B 00 5F 00 2D 00 40 00 5F 00 2D 00

1E 04 7B 00 2C 00 3B 00 01 5F 00 2D 00 2A 00 20 00 23 00 2C 00 23 00 23 00 30 00 2E 00 30
00 30 00 22 00 40 04 2E 00 22 00 5F 00 2D 00 3B 00 5C 00 2D 00 2A 00 20 00 23 00 2C 00 23
00 23 00 30 00 2E 00 30 00 30 00 22 00 40 04 2E 00 22 00 5F 00 2D 00 3B 00 5F 00 2D 00 2A
00 20 00 22 00 2D 00 22 00 3F 00 3F 00 22 00 40 04 2E 00 22 00 5F 00 2D 00 3B 00 5F 00 2D
00 40 00 5F 00 2D 00

1E 04 7B 00 2B 00 3B 00 01 5F 00 2D 00 2A 00 20 00 23 00 2C 00 23 00 23 00 30 00 2E 00 30
00 30 00 5F 00 40 04 5F 00 2E 00 5F 00 2D 00 3B 00 5C 00 2D 00 2A 00 20 00 23 00 2C 00 23
00 23 00 30 00 2E 00 30 00 30 00 5F 00 40 04 5F 00 2E 00 5F 00 2D 00 3B 00 5F 00 2D 00 2A
00 20 00 22 00 2D 00 22 00 3F 00 3F 00 5F 00 40 04 5F 00 2E 00 5F 00 2D 00 3B 00 5F 00 2D
00 40 00 5F 00 2D 00

1E 04 1C 00 A4 00 17 00 00 22 24 22 23 2C 23 23 30 5F 29 3B 5C 28 22 24 22 23 2C 23 23 30
5C 29

1E 04 21 00 A5 00 1C 00 00 22 24 22 23 2C 23 23 30 5F 29 3B 5B 52 65 64 5D 5C 28 22 24 22
23 2C 23 23 30 5C 29

1E 04 22 00 A6 00 1D 00 00 22 24 22 23 2C 23 23 30 2E 30 30 5F 29 3B 5C 28 22 24 22 23 2C
23 23 30 2E 30 30 5C 29

1E 04 27 00 A7 00 22 00 00 22 24 22 23 2C 23 23 30 2E 30 30 5F 29 3B 5B 52 65 64 5D 5C 28
22 24 22 23 2C 23 23 30 2E 30 30 5C 29

1E 04 37 00 A8 00 32 00 00 5F 28 22 24 22 2A 20 23 2C 23 23 30 5F 29 3B 5F 28 22 24 22 2A
20 5C 28 23 2C 23 23 30 5C 29 3B 5F 28 22 24 22 2A 20 22 2D 22 5F 29 3B 5F 28 40 5F 29

1E 04 2E 00 A9 00 29 00 00 5F 28 2A 20 23 2C 23 23 30 5F 29 3B 5F 28 2A 20 5C 28 23 2C 23
23 30 5C 29 3B 5F 28 2A 20 22 2D 22 5F 29 3B 5F 28 40 5F 29

1E 04 3F 00 AA 00 3A 00 00 5F 28 22 24 22 2A 20 23 2C 23 23 30 2E 30 30 5F 29 3B 5F 28 22
24 22 2A 20 5C 28 23 2C 23 23 30 2E 30 30 5C 29 3B 5F 28 22 24 22 2A 20 22 2D 22 3F 3F 5F
29 3B 5F 28 40 5F 29

1E 04 36 00 AB 00 31 00 00 5F 28 2A 20 23 2C 23 23 30 2E 30 30 5F 29 3B 5F 28 2A 20 5C 28
23 2C 23 23 30 2E 30 30 5C 29 3B 5F 28 2A 20 22 2D 22 3F 3F 5F 29 3B 5F 28 40 5F 29 E0 00
14 00 00 00 00 00 F5 FF 20 00 00 00 00 00 00 00 00 00 00 00 C0 20

У каждой записи FORMAT. Сразу после опознавателя и размера записи идёт двухбайтовый
индекс по которому будут к ней обращатся другие записи. Затем до самого конца
двухбайтовая unicode строка.





Рассмотрим самую короткую запись FORMAT:
1E 04 2F 00 05 00 15 00 01 23 00 2C 00 23 00 23 00 30 00 22 00 40 04 2E 00 22 00 3B 00 5C
опоз раз индекс колво сжатость 00 2D 00 23 00 2C 00 23 00 23 00 30 00 22 00 40 04 2E 00 22 00
нава мер букв несжат двадцать одна буква или сорок два байта(#,##0"@.";\-#,##0"@.")
тель (hex)

Эти записи содержат настройки форматов зависящие от страны.
В самом экселе вы можете их увидеть. Нажав правой кнопкой мыши на ячейку->формат ячеек->
все форматы.


Дальше идут 20 записей XF из блока XF

E0 00 14 00 01 00 00 00 F5 FF 20 00 00 F4 00 00 00 00 00 00 00 00 C0 20
E0 00 14 00 01 00 00 00 F5 FF 20 00 00 F4 00 00 00 00 00 00 00 00 C0 20
E0 00 14 00 02 00 00 00 F5 FF 20 00 00 F4 00 00 00 00 00 00 00 00 C0 20
E0 00 14 00 02 00 00 00 F5 FF 20 00 00 F4 00 00 00 00 00 00 00 00 C0 20
E0 00 14 00 00 00 00 00 F5 FF 20 00 00 F4 00 00 00 00 00 00 00 00 C0 20
E0 00 14 00 00 00 00 00 F5 FF 20 00 00 F4 00 00 00 00 00 00 00 00 C0 20
E0 00 14 00 00 00 00 00 F5 FF 20 00 00 F4 00 00 00 00 00 00 00 00 C0 20
E0 00 14 00 00 00 00 00 F5 FF 20 00 00 F4 00 00 00 00 00 00 00 00 C0 20
E0 00 14 00 00 00 00 00 F5 FF 20 00 00 F4 00 00 00 00 00 00 00 00 C0 20
E0 00 14 00 00 00 00 00 F5 FF 20 00 00 F4 00 00 00 00 00 00 00 00 C0 20
E0 00 14 00 00 00 00 00 F5 FF 20 00 00 F4 00 00 00 00 00 00 00 00 C0 20
E0 00 14 00 00 00 00 00 F5 FF 20 00 00 F4 00 00 00 00 00 00 00 00 C0 20
E0 00 14 00 00 00 00 00 F5 FF 20 00 00 F4 00 00 00 00 00 00 00 00 C0 20
E0 00 14 00 00 00 00 00 F5 FF 20 00 00 F4 00 00 00 00 00 00 00 00 C0 20

E0 00 14 00 00 00 00 00 01 00 20 00 00 00 00 00 00 00 00 00 00 00 C0 20

E0 00 14 00 01 00 AA 00 F5 FF 20 00 00 F8 00 00 00 00 00 00 00 00 C0 20
E0 00 14 00 01 00 A8 00 F5 FF 20 00 00 F8 00 00 00 00 00 00 00 00 C0 20
E0 00 14 00 01 00 09 00 F5 FF 20 00 00 F8 00 00 00 00 00 00 00 00 C0 20
E0 00 14 00 01 00 AB 00 F5 FF 20 00 00 F8 00 00 00 00 00 00 00 00 C0 20
E0 00 14 00 01 00 A9 00 F5 FF 20 00 00 F8 00 00 00 00 00 00 00 00 C0 20


Рассмотрим одну из этих записей:
E0 00 14 00 01 00 AA 00 F5 FF 20 00 00 F8 00 00 00 00 00 00 00 00 C0 20
опоз раз
нава мер
тель

01 00 - ссылка на порядковый номер одной из записей FONT.
AA 00- ссылка на индекс который указывался в записи FORMAT.
F5 FF=FFF5-здесь 3 шестнадцатеричные цифры(FFF)это ссылка на родительский стиль XF
тут всегда FFF, последняя цифра это битовые флаги защиты:5=0101b
^^^
||ячейка заблокирована
|формула не скрыта
стиль XF
20=20 это битовые флаги выравнивания = 00100000b
^^^^^^^^
|||||горизонтальное выравнивание - обычное(смотрите стр 219)
||||text is wrapped at right border-текст свернулся к правой границе?
|вертикальное выравнивание-по нижнему краю(смотрите стр 220)
не выключать последнюю строку при распространённом выравнивании(не знаю про что это)

00=00 это значение вращения текста - вращения нет(если значен от1до90 то вращение противчасовой)
от91до180 то вращен по часовой
255-буквы перевёрнуты верхногами но не были вращены


00=00 флаги переноса и автоподбора ширины 00000000b
^^^^^^^^
||||значение отступа в ячейке при правом или левом выравнивании
|||автоподбор ширины(0-нет,1-да)
||бит не описан,возможно перенос текста
направление текста(00-по контексту,01-слева напрво,10-справа налево)

F8=F8 флаги родительского стиля XF.
Точно не понял, но похоже что эти значения зависят от того что мы
используем во флагах защиты(пятый байт,там где у нас F5)стиль XF или ячейка XF.
И это отрубание опций срабатывает только когда стиль XF. Читайте стр 219.

11111000b
^^^^^^
|||||не использовать флаги числового формата
||||использовать флаги шрифта
|||использовать флаги гориз и верт выравн,автоподб ширин,отступ,ориентац,вращ и направлен
||использовать флаги границ
|использовать флаги стиля фона
использовать флаги защиты


00 00 флаги стиля границ ячейки(щестнадцатеричные): 0000h(байты не переставлены)
^^^^
|||стиль верхней границы от 0 до D
||стиль нижней границы от 0 до D
|стиль левой границы от 0 до D
стиль правой границы от 0 до D



00 00=00 00 флаги стиля границ ячейки(двоичные):0000 0000 0000 0000b(байты переставлены)
^^^^ ^^^^ ^^^^ ^^^^
|||| |||| |цветовой индекс для левой границы(стр 195)
||цветовой индекс для правой границы(стр 195)
|Диагональная линия из левого верхнего до правого нижнего угла
Диагональная линия из левого нижнего до правого верхнего угла

00 00 00 00=00 00 00 00 продолжение: флаги стиля границ ячейки+палитра(двоичные):

0000 0000 0000 0000 0000 0000 0000 0000b(байты переставлены)
^^^^ ^^х! !!!* **** **++ ++++ +^^^ ^^^^
|||| || ! !!!* **** **++ ++++ +цветовой индекс для левой границы(стр 195)
|||| || ! !!!* **** **цветовой индекс для правой границы(стр 195)
|||| || ! !!!цветовой индекс для диагональной границы(стр 195)
|||| || стиль диагональн границы от 0 до D
палитра ячейки(стр 25)

C0 20=20С0 флаги палитры и фона ячейки:

0010 0000 1100 0000(байты переставлены)
хх++ ++++ +^^^ ^^^^
++ ++++ +цветовой индекс для палитры(стр 195)
цветовой индекс для палитры фона(стр 195)

Вот такие сложные записи XF. Обратите внимание что почти везде указывается что байты переставлены.
Так указано в руководстве. По хорошему всё это надо было бы привести к непереставленному виду.
Т.е так как это распологается в файле.

Добавлено через 50 секунд
Следующие записи STYLE
93 02 04 00 10 80 04 FF
93 02 04 00 11 80 07 FF
93 02 04 00 00 80 00 FF
93 02 04 00 12 80 05 FF
93 02 04 00 13 80 03 FF
93 02 04 00 14 80 06 FF

Записи STYLE задают стиль записям XF. Записи STYLE бывают 2х видов. Встроенного или
пользовательского стиля. Рассмотрим одну из записей.

93 02 04 00 10 80 04 FF
опоз раз
нава мер
тель

10 80=8010 это битовые флаги 1000 0000 0001 0000
^ ^^^^^^^^^^^^^^
| указатель на стиль XF записи(10h)
тип стиля(0-пользовательский,1-встроенный). Этот бит говорит
как интерпретировать последующие байты. Если тут 0, т.е
пользовательский стиль, то остальные байты это юникод
строка.Если тут 1, т.е встроенный стиль,то следующий байт
это идентификатор встроенного стиля. И ещё в один байт пишется
значение "уровень стиля" требуемое этим идентификатором, либо
он пустой и тут значение FF.
04-идентификатор встроенного стиля "Currency".
------------------------------------------------------------------
Вот сноска всех встроенных стилей(не пользовательских):
00-Нормальный 05-процент
01-Уровень строки(требует след байт) 06-кавычки[0]
02-Уровень столбца(требует след байт) 07-Currency[0]
03-запятая 08-Гиперссылка
04-Currency 09-последующая гиперссылка
-------------------------------------------------------------------

FF-последний байт пуст, т.к стиль "Currency" не требует уровня стиля.

-------------------------------------------------------
Сноска значений уровня стиля:
FF-нет значения
от 00 до 06(его требуют стили 01 и 02)
или от 01 до 07 для outline level
-------------------------------------------------------


В этой записи я ничего не понял, возможно потом перепишу.


Следующяя запись USESELFS
60 01 02 00 01 00
опоз раз
нава мер
тель

Здесь два байта говорят какой язык используется при записи формул.
01 00=0001 - системный(у нас русский). Если 0000-то английский.

Следующие записи SHEET
85 00 12 00 76 08 00 00 00 00 05 01 1B 04 38 04 41 04 42 04 31 00
85 00 12 00 7D 09 00 00 00 00 05 01 1B 04 38 04 41 04 42 04 32 00
85 00 12 00 84 0A 00 00 00 00 05 01 1B 04 38 04 41 04 42 04 33 00

Пожалуй это самые важные записи для начала чтения документа.

Эти записи описывают количество и название листов, содержащихся в документе эксель.
По одной записи на каждый лист. Раз записей три, значит у нас три листа и следовательно
ещё 3 подпотока, кроме этого.

Рассмотрим строение:
85 00 12 00 76 08 00 00 00 00 05 01 1B 04 38 04 41 04 42 04 31 00
опоз раз
нава мер
тель

76 08=0876 - это смещение подпотока этого листа в потоке Workbook. Декомпилятор
пишет что у меня абсолютный адрес первого листа 0A76. Но так как
поток Workbook начинается c 200h. То смещение подпотока в потоке
как раз равняется этому значению.A76h-200h=876h.
0000-видимость листа.(0000-видимый,0001-скрытый,0002-очень скрытый,подчиняется только макросам).

0000-тип листа.(0000-рабочий лист,0002-схема,0006-модуль VBA)

05 01 1B 04 38 04 41 04 42 04 31 00 -название листа юникод
^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
| | имя листа:"Лист1"
| |
| юникод строка не сжатая
пять букв в имени

Мой hex редактор не прочитал тут unicode имя. Поэтому я открыл Word->вставка->символ->
шрифт Arial->раздел:кириллица. Тут действительно имя листа. Только буква "Л" имеет код:
041B. А буква "и" код 0438. Выходит что байты переставлены.

Следующяя запись COUNTRY
8C 00 04 00 07 00 07 00
опоз раз
нава мер
тель
Эта запись содержит информацию о языковых установках
компьютера, на котором был создан этот фаил.
07 00=0007 - язык интерфейса эксель(названия менюшек и кнопок).Здесь Россия.
07 00=0007 - язык в операционной системе.Здесь Россия.
список языков на странице 149 док. excelfileformat.pdf

Следующей записи нет в документе openoffice
C1 01 08 00 C1 01 00 00 80 38 01 00
опоз раз
нава мер
тель

Следующяя запись SST
FC 00 08 00 00 00 00 00 00 00 00 00
опоз раз
нава мер
тель

Эта запись очень важна. Так как в ней складываются все текстовые строки со всех ячеек всех
листов документа. Если строки в некоторых ячейках повторяются, то в SST откладывается
только одна из них. В BIFF8 текстовые строки больше не хранятся в подпотоках листов,
там содержатся лишь ссылки(записи LABELSST) на эту строку и её номер в записи SST подпотока
workbook global.

Рассмотрим строку:
(В данном случае она нулевая,т.к не единой текстовой строки нет в пустом документе).
00 00 00 00=00 00 00 00 - общее количество текстовых строк в документе(вместе с повторяющимися)
00 00 00 00=00 00 00 00 - количество строк в этой записи(не будут повторяться).
XX XX XXXXXXXXXXXXX - Дальше должны идти сами строки unicode(у нас их нет).
XX XX XXXXXXXXXXXXX
. . .
А в подпотоках листов в записях LABELSST к этим строкам обращаются по их порядковому номеру
(начиная от 0).



Следующяя запись EXTSST
FF 00 02 00 08 00
опоз раз
нава мер
тель
Эта запись сопровождает запись SST. Её цель ускорить поиск строк при открытии файла в Excel.
Но она не обязательна. В ней хранятся смещения восьмистрочковых(обычно) порций SST
относительно потока workbook и относительно записи SST
08 00 =0008 - количество строчек в одной порции(не должно быть меньше 8)

Затем каждая 8ми строчковая порция SST описывается 6ю байтами.
первые два - смещение этой порции относительно Workbook.
вторые два - смещение этой порции относительно записи SST. Если эта строка SST
переходит в продолженную запись(т.е разбита). То здесь содержится 0000.
третие два - всегда содержат 0000. Это похоже на разделитель.


Про продолженную запись скажу лишь что она имеет опзнаватель 003С, остальное позже.

Как видим здесь не описывается не одна порция строчек.


Следующяя запись EOF
0A 00 00 00
опоз раз
нава мер
тель

Она значает конец подпотока. В данном случае конец Workbook globals.

Далее пойдут подпотоки листов
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;
0
 Аватар для Estimable
195 / 14 / 1
Регистрация: 02.01.2017
Сообщений: 223
19.01.2019, 09:13
Подпотоки листов довольно маленькие в пустом файле Xls.

BOF
09 08 10 00 00 06 10 00 46 18 CD 07 C9 80 00 00 06 02 00 00
опоз раз данные
нава мер
тель

Здесь почти всё также как у Globals.
00 06 - версия BIFF(в Excel 2003 идёт BIFF версии 8, но в файле она указыв верс 6.).
10 00 - Начало какого подпотока(у нас Sheet or Dialog).
46 18 - Версия сборки(не знаю про что это).
CD 07 - Год выпуска этой версии Excel.(CD 07=07CD=1997десятеричное).
C9 80 00 00 - четыре байта это флаги истории(их расшифровка не известна).
06 02 00 00 - самая младшая версия эксель в которой можно считать все записи этого файла.

запись INDEX
0B 02 10 00 00 00 00 00 00 00 00 00 00 00 00 00 2E 09 00 00
опоз раз данные
нава мер
тель

00 00 00 00-эти четыре байта не используются
00 00 00 00-указатель на первую используемую строку на этом листе
00 00 00 00-указатель на последнюю используемую строку на листе
(точнее откуда начинается неиспользуемое пространство т.е последн строка+1)
2E 09 00 00=0000092E - позиция записи DEFCOLWIDTH(ширина столбцов на листе) относительно
потока Workbook. Если записи DEFCOLWIDTH в листе не существует,
значит здесь ставится позиция где она могла бы существовать.
Мы можем найти позицию записи DEFCOLWIDTH в файле. Для этого
смещение потока Workbook в файле = 200h добавим к этому смещению.
200h+92Eh=B2E.Посмотрим адрес B2E в hex редакторе. Здесь находятся
байты:5500 или 0055(перевёрн.).Всё верно это опознаватель записи
DEFCOLWIDTH.
дальше ещё
могут быть - это массив смещений всех 32х строчковых блоков этого листа
четырёхбайтовые внутри записи dbcell(пока не понял).
поля

далее запись CALCMODE
0D 00 02 00 01 00
опоз раз данные
нава мер
тель

0100=0001 формулы расчитываются на листе автоматически(если 0000 то в ручную, после нажатия
кнопки Enter в ячейке;FFFF-автоматический расчёт кроме таблиц множественных
операций,что это я не знаю).


далее запись CALCCOUNT
0C 00 02 00 64 00
опоз раз данные
нава мер
тель
64 00=0064=100десятичное - максимальное количество циклов пересчёта в формуле.
Когда формула ссылается сама на себя, то кол-во циклов
пересчёта это очень важная величина.

REFMODE
0F 00 02 00 01 00
опоз раз данные
нава мер
тель
01 00=0001 режим аресации в формуле будет "$A$1:$B$2"(если 0000 то "R1C1:R2C2")

ITERATION
11 00 02 00 00 00
опоз раз данные
нава мер
тель
0000 - циклы пересчёта в формуле запрещены(1 - разрешены)

DELTA
10 00 08 00 FC A9 F1 D2 4D 62 50 3F
опоз раз данные
нава мер
тель

FC A9 F1 D2 4D 62 50 3F=0.001десятичное - 64битное число с плав точк(сопроцесс)
показывающее максимальный результат формулы
при котором прекращаются циклы пересчёта.
В ручную я не смог посмотреть что это за число, а загрузив эти байты в ollyDedug
я увидел, что это число соответствует 0целых 1й тысячной. Как будто число должно
уменьшатся, а не возрастать.Впрочем возникла одна догадка. Что поледний байт должен
быть либо C0, либо 40. Я писал об этом раньше, когда рассматривал Double числа,
которые эксель посылает в DLL.
Я увидел что 3F очень близко к 40. и добавил единицу к этому байту
получилось - FC A9 F1 D2 4D 62 50 40 это соответствует 65.536. Но так как единица добавлена
в первые три байта(последние три байта т.к число перевёрнуто), там где формируется
двоичная запятая. То скорее всего запятую надо будет перенести и получится 65536.

В общем сюда заносится Double число, за вычетом единицы. И за нехватающей позицией запятой.
Может быть это некая компрессия.

Следующая запись SAFERECALC
5F 00 02 00 01 00
опоз раз данные
нава мер
тель

01 00=00 01-пересчитывать все формулы на листе перед сохранением(00 00-не пересчитывать).

PRINTHEADERS
2A 00 02 00 00 00
опоз раз данные
нава мер
тель

00 00-область печати листа не захватывает номера строк и буквы столбцов, 01 00-захватывает.

PRINTGRIDLINES
2B 00 02 00 00 00
опоз раз данные
нава мер
тель
00 00-не выводить сетку ячеек на печать (01 00-печатать сетку ячеек)

GRIDSET
82 00 02 00 01 00
опоз раз данные
нава мер
тель

устанавливалась ли предыдущая опция(PRINTGRIDLINES)01 00-да,00 00-нет

GUTS (отвечает за размеры квадратиков с буквами столбцов и квадратиков с цифрами строк)
80 00 08 00 00 00 00 00 00 00 00 00
опоз раз данные
нава мер
тель
00 00-ширина квадратиков строк(на листе-слева)
00 00-высота квадратиков столбцов(на листе-сверху)
00 00-количество видимых квадратиков строк(если 00 00 - функция не используется)
00 00-количество видимых квадратиков столбцов(если 00 00 - функция не используется)

DEFAULTROWHEIGHT(высота всех строчек на листе, размер которых не изменён записью ROW)
25 02 04 00 00 00 FF 00
опоз раз данные
нава мер
тель

00 00=00 00 - два байта это битовые флаги:
0000 0000 0000 0000
^^^^стандартная высота шрифта и высота строки соответств. друг другу(если 1 то наоборот)
||строка не скрыта(если 1 то наоборот)
|выше строки не имеется дополнительное пространство(если 1 то наоборот)
ниже строки не имеется дополнительное пространство(если 1 то наоборот)

FF 00=00FF - стандартная высота не занятых строк в 1/20 доле точки
(для строк я эти значения пока не расшифровываю, только для столбцов
там их ширина меняется с шагом в 36десятичное от b6h, возможно что и для
строк есть какой-то шаг).


SHEETPR
81 00 02 00 C1 04
опоз раз данные
нава мер
тель

C1 04=04С1 - это битовые флаги

0000 0100 1100 0001
^^хх ^^х^ ^^^^ ххх^показывать разрывы страниц
|| || | |||стандартный лист(диалоговый лист)
|| || | ||для квадратиков букв столбцов и для квадратиков цифр строк стиль не задан(1-задан)
|| || | |если есть кнопки в верхней внешней зоне (рядом с серыми квадратиками содержащ буквы столбцов)
|| || | |то здесь: они ниже этих квадратиков(если 0-выше)
|| || | если есть кнопки в левой внешней зоне (рядом с серыми квадратиками содержащ номера строк)
|| || | то здесь: кнопки правее этих квадратиков(если 0-левее)
|| || маштабировать область печати листа в процентах(1-маштабировать область печати в зависимости от количества листов)
|| |показывать нумерацию строк в левой внешней зоне(0-скрывать нумерацию)
|| скрывать литерацию столбцов в верхней внешней зоне(1-показывать)
|экселевская оценка выражения(1-lotus оценка выражения)
Экселевский редактор формул(1-lotus редактор формул)


HEADER (Текстовая строка заголовок для этого листа при выводе на печать)
14 00 00 00
опоз раз данные
нава мер
тель

Здесь данные отсутствуют, т.к размер нулевой. А если данные есть, то это текстовая unicode
строка, которая появляется вверху каждого листа при выводе документа на печать.
Текстовая строка может содержать управляющие символы:

&& знак & является управляющим, когда он встречается в тесте, то он удваивается &&
&L Начало левой секции заголовочной надписи
&C Начало центральной секции заголовочной надписи
&R Начало правой секции заголовочной надписи
&P Номер текущей страницы
&N Количество страниц
&D Текущая дата
&T Текущее время
&В Жирность теста включена/выключена
&I Курсивность текста включена/выключена
&U Подчёркивание включено/выключено
&E Двойное подчёркивание включено/выключено
&S Зачёркнутость включена/выключена
&A Имя листа
&F Имя файла без пути(без указания папок и подпапок)
&Z Путь к файлу, без имени(папки и подпапки, которые ведут к файлу)
&G Картинка
&H Затемнённость теста включена/выключена
&O Вылезающий текст включен/выключен
&X Надписывание включено/выключено
&Y Подписывание включено/выключено

&"<fonitname>" Установить новый шрифт под именем <fontname>
&"<fontname>,<fontstyle>" Установить новый шрифт под именем <fontname> и стилем <fontstyle> . Обычные значения <fontstyle>
"Regular", "Bold", "Italic","Bold Italic". Но иногда некоторые из них не работают это зависит от установок шрифта, тогда
тогда ставьте "Standard" или "Oblique"
&<fontheight> Установить высоту шрифта, выраженную в точках (<fontheight> это десятичное значение).

И соответственно вы должны подсчитать и проставить количество символов во всей строке,
учитывая эти комманды.



FOOTER (Текстовая строка примечание для этого листа для печати)
15 00 00 00
опоз раз данные
нава мер
тель

Тут данных тоже нет, значит на печати у листов не будет надписи внизу листа.
Тут используются те же управляющие символы, что и в записи header.


HCENTER(Центровать страницу горизонтально для печати)
83 00 02 00 00 00
опоз раз данные
нава мер
тель
00 00-выравнивать по лев краю(1-центровать стр горизонт).


VCENTER(Центровать страницу вертикально для печати)
84 00 02 00 00 00
опоз раз данные
нава мер
тель
00 00-выравнивать по верхнему краю(00 01-ценровать стр вертикально)

PAGESETUP
A1 00 22 00 00 00 FF 00 01 00 01 00 01 00 04 00 00 00 00 00 00 00 00 00 00 00 E0 3F 00 00 00 00 00 00 E0 3F 00 00
опоз раз данные
нава мер
тель

00 00-размер страницы неопределён. См размеры страницы на 194 странице документа excelfileformat.pdf
FF 00=00ff=255-маштабирующий фактор в процентах
01 00=0001 номер начальной страницы
01 00=0001-установить ширину листа исходя из этого количества страниц
01 00=0001-установить высоту листа исходя из этого количества страниц
04 00=0004 это битовые флаги

0000 0000 0000 0100
!!^х ^^^^ ^^^^печатать страницу в колонке(1-печатать страницу в строке)
!!| |||| ||ориентация альбомная(1-книжный)
!!| |||| |размер страницы,маштабирующий фактор,ориентация страницы,разрешение печати и
!!| |||| |номер копий не установлены.
!!| |||| печать цветная(1-печать чёрно-белая)
!!| |||стандартное качество печати(1-пониженное качество)
!!| ||не печатать пометки для ячеек(1-печатать)
!!| |использовать флаг ориентации указанный во втором справа бите(1-ориентация по-умолчанию)
!!| автоматическая нумерация страниц(использовать номер начальной странице указанный в 9м и 10м
!!| байте этой записи т.е 01 00)
!!печатать пометки как отображаются(печатать пометки в конце листа)
печатать ошибки, так как они отображаются(01-не печатать ошибки,печатать ошибки как "--"
11-печатать ошибки как "#N/A")

00 00-разрешение печати
00 00-вертикальное разрешение печати

00 00 00 00 00 00 E0 3F-заголовочный отступ на странице в виде Double числа(то ли 0.5 то ли 32768)
00 00 00 00 00 00 E0 3F-нижний отступ на странице в виде Double числа(то ли 0.5 то ли 32768)
00 00-количество копий для печати


DEFCOLWIDTH Ширина остальных столбцов на листе(кроме специально обозначеных в colwidth,colinfo,standardwith)
55 00 02 00 08 00
опоз раз данные
нава мер
тель
08 00=0008 - ширина столбцов выраженная ввиде ширины цифры "0" в стандартном шрифте.
8 означает что ширина столбца 8.43 исходя из "0" в шрифте Arial 10го размера.
Как точно это высчитывается в руководстве не описано.

DIMENSION (задействованная,на данный момент, зона листа - т.е прямоугольник в котором хоть
что-то есть)
00 02 0E 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
опоз раз данные
нава мер
тель

00 00 00 00-указатель на первую используемую строку
00 00 00 00-указатель на последнюю используемую строку+1
00 00-указатель на первый используемый столбец
00 00-указатель на последний используемый столбец
00 00-эти два байта не используются


WINDOW2+(как выглядит этот лист)
3E 02 12 00 B6 00 00 00 00 00 40 00 00 00 00 00 00 00 00 00 00 00
опоз раз данные
нава мер
тель

B6 00=00B6 - это битовые флаги
0000 0000 1011 0110
^^^^ ^^^^ ^^^^показывать результаты формул(1-показывать сами формулы)
|||| |||| ||показывать сетку на ячейках(0-не показывать сетку)
|||| |||| |показывать заголовки листов(не показывать заголовки листов)
|||| |||| границы разделённых окон не заморожены(1-заморожены)разделённые окна
|||| |||| возникают при потягивании за маленькие бегунки в правом верхнем и
|||| |||| правом нижнем углу окна.В delfi это называется Tsplitter.А в excel - Panes.
|||| |||показывать нули в ячейках(0-не показывать)
|||| ||системный цвет сетки ячеек(0-цвет сетки выбирается в ручную)
|||| |нумерация(литерация) столбцов слева направо(1-нумерация столбцов справа налево)
|||| символы во внешней зоне отображать(1-не отображать)
|||сохранять состояние разделённости окон Tsplitter если хотябы одно из 4рёх было удалено
|||(1-не сохранять разделённость)
||этот лист не выбран(1-выбран)
|лист не активен(1-активен). Чем отличается от того что лист выбран\не выбран не знаю.
не показывать разрывы страниц(1-показывать)

00 00-указатель на первую видимую строку
00 00-указатель на первый видимый столбец
40 00=0040-указатель на 6ти байтовый цвет для сетки ячеек(см стр 195 excelfileformat).
Правда там не сказано какой это цвет, а только что он используется в записи window2
00 00-два байта не используются.
00 00-маштабирующий фактор увеличения для страницы не в режиме разрыва страницы 0=60%
00 00-маштабирующий фактор увеличения для страницы в режиме разрыва страницы 0=100%

SELECTION (Выделение ячейки или диапазона ячеек на листе. И их положение по отношению к граням Tsplitter'а.)
1D 00 0F 00 03 00 00 00 00 00 00 01 00 00 00 00 00 00 00
опоз раз данные
нава мер
тель

03 - опознаватель разделённого окна Tsplitter. Мне логика понятна так как я сам
программировал Tsplitter средствами Winapi(в winapi нет такого элемента, это просто очень
маленькое окошко-бегунок которое реагирует когда над ним пробегает курсор мыши).
Получается что окно листа эксель всегда подразумевается разбитым на 4ре окна, только
остальные 3 мы не видим. И начинаем всегда с правого нижнего(3го)окна.Чтобы верхний
бегунок вытягивал границу окон которые находятся над ним, а боковой вытягивал
границу окон которая находится за ним. Хотя возможен и другой вариант, но судя
по положению бегунков в экселе это делается именно так.

00 00-указатель на строку <}какая выделена
00 00-указатель на столбец <} ячейка сейчас
00 00-указатель на следующий выделенный диапазон.
01 00-сколько диапазонов выделено

00 00-строка начало выделения<}эти выделенного
00 00-строка конец выделения <} 6 байт каждого диапазона
00-столбец начало выделения <} будут для
00-столбец конец выделения <} повторяться

Здесь хотелось бы обратить внимание на два момента. Синим цветом на листе можно выделять ячейку или
прямоугольник содержащий несколько ячеек курсором мыши. Можно выделять несколько не связаных ячеек
или не связанных прямоугольников удерживая клавишу Shift на клавиатуре. По этому требуется писать тут
сколько диапазонов выделено и какой следующий диапазон. Второй момент что тут надо писать
какая ячейка активна в данный момент(активная ячейка ещё и помечается утолщёнными границами),
на практике это означает куда отскочит выделение(какая ячейка станет активной), когда вы будете
нажимать стрелки на клавиатуре.





PHONETICPR
EF 00 06 00 00 00 37 00 00 00
опоз раз данные
нава мер
тель


00 00-указатель на шрифт который содержит символы специального произношения азиатских букв.
37 00=0037 это битовые флаги
0000 0000 0011 0111
!! VV^^
!! VVяпонское произношение не использ(00-катакана урезанный,01-катакана расширенный,10-хирагана)
!! выравнивание азиатских букв(с особ произношен) слева или сверху(00-не определено,
!! 10-по центру,11-распределённый по ширине)
значение этих двух бит не известно но они всегда = 11

00 00-списка диапазона таких ячеек не существует.
Если в документе существуют несколько таких диапазонов то на каждый будет приходится по 6
байт(как в конце записи SELECTION).



EOF
0A 00 00 00
опоз раз
нава мер
тель

конец подпотока Sheet1 substream.
0
 Аватар для Estimable
195 / 14 / 1
Регистрация: 02.01.2017
Сообщений: 223
19.01.2019, 09:14
Ещё два подпотока листов имеют почти идентичные записи, за исключением
смещений записей DEFCOLWIDTH внутри записей INDEX, то что выбран лист3(у меня лист3
потому что фаил автосохранился, когда я его просматривал)
а не какой-то из двух других. Запись window2 у третьего листа немного
отличается. Напомню опознаватель у неё 023E а в файле 3E02 дальше
размер 1200 и затем в двух байтах флагов B6 00 есть изменение.
В замен B600 в подпотоке третьего листа стоит B606. Можете
разложить эти два байта по битам и увидите что установлены два бита:
"лист выбран" и "лист активирован". Но по поводу выбору листа
недостаточно установить эти биты в одной из записей window2, а в остальных
двух записях снять эти биты. Надо ещё сделать пометку об активном листе
в global substream. Но об этом позже.Когда начнём эксперименты.

После последней записи EOF в потоке workbook следует 1140 нулевых байтов "00".
Это дополнение до 4096 байт этого потока. Не знаю насколько обязательно это
правило, ведь в том примере, где у нас был пустой фаил с одним макросом. Там
поток workbook был маленький(3033байта) и находился в мини-контейнере. Отсюда вывод
старайтесь дополнять поток до 4096 - ошибки в этом не будет. Да и кроме того
пустое место в потоке позволит эксперементировать с записями.


Я обещал упомянуть про продолженные записи. Итак любая запись в любом из
подпотоков workbook, и в globals в том числе не может быть длиннее 8228 байт(начиная с
начального байта опознователя). Если запись превышает этот размер. То следом за записью
ставится добавочная запись с опознавателем 003С. Если добавочная запись, тоже превышает
8228 байт, то за ней ставится следующая добавочная запись:



Запись1 продолженная запись записи1 ещё продолженная запись записи1
-------------------------- -------------------------- --------------------------
|опознаватель|размер|данные| |опознаватель|размер|данные| |опознаватель|размер|данные| ИТД
| любой |до8224| | | 003C |до8224| | | 003C |до8224| |
-------------------------- -------------------------- --------------------------


Текстовая строка unicode не может разделится на месте опций, а только когда
появится первая буква. Если в остаток записи не влезает участок юникод строки
даже всего с одной буквой, то юникод строка полностью перекидывается в продолженную
запись. А на её месте в первой записи будут нули. Этот момент мне не совсем ясен.

В начале продолженной записи которая продолжает unicode строку всегда ставится
байт сжатость/не сжатость. И он имеет право отличаться от изначального своего
варианта. Возможна ситуация, когда в первой записи строка была из двухбайтовых
символов, а в продолженной записи стала из сжатых однобайтовых и наоборот.
На странице 148 документа excelfileformat.pdf можно встретить разбитие записи
которая содержит formating runs и они тоже разбиваются особым образом.

Кроме этих двух исключительных случаев остальные записи должны разбиваться в каком
угодно месте после начала данных и в продолженной записи должен тупо идти следующий
байт.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;

_____
| \
| |
| |
| |
| |
|______|
Что же из себя представляет поток DocumentSummaryInformation. Как и следует из
названия это информация о документе. Т.е о компаунд файле, а не об экселе.
Предположим мы уже собрали все его сектора.

DocumentSummaryInformation
FE FF 00 00 05 00 02 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 01 00 00 00 02 D5 CD D5
9C 2E 1B 10 93 97 08 00 2B 2C F9 AE 30 00 00 00
D0 00 00 00 09 00 00 00 01 00 00 00 50 00 00 00
0F 00 00 00 58 00 00 00 17 00 00 00 64 00 00 00
0B 00 00 00 6C 00 00 00 10 00 00 00 74 00 00 00
13 00 00 00 7C 00 00 00 16 00 00 00 84 00 00 00
0D 00 00 00 8C 00 00 00 0C 00 00 00 B2 00 00 00
02 00 00 00 E3 04 00 00 1E 00 00 00 01 00 00 00
00 00 00 00 03 00 00 00 41 0A 0A 00 0B 00 00 00
00 00 00 00 0B 00 00 00 00 00 00 00 0B 00 00 00
00 00 00 00 0B 00 00 00 00 00 00 00 1E 10 00 00
03 00 00 00 06 00 00 00 CB E8 F1 F2 31 00 06 00
00 00 CB E8 F1 F2 32 00 06 00 00 00 CB E8 F1 F2
33 00 0C 10 00 00 02 00 00 00 1E 00 00 00 06 00
00 00 CB E8 F1 F2 FB 00 03 00 00 00 03 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

DocumentSummaryInformation
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
DocumentSummaryInformation
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
DocumentSummaryInformation
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
DocumentSummaryInformation
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
DocumentSummaryInformation
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
DocumentSummaryInformation
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
DocumentSummaryInformation
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00


__________________
| \
| HEADER \
| \
|_____________________|
| |
| | /|
| PropertySet stream | / |______________
| | / | поток DocumentSummaryInformation
| | \ ______________|
|_____________________| \ |
| | \|
| |
UserDefinedPropertySet|
| stream |
| |
|_____________________|



Здесь тоже есть записи, которые называются свойствами.
DocumentSummaryInformation состоит из заголовка(48 либо 68 байт).
И подпотоков. Размер заголовка зависит от того сколько в нём подпотоков.
Если один то 48, если два то 68.
Первый обязательный он называется PropertySet stream, второй не обязательный
он называется UserDefinedPropertySet stream.
У этих двух подпотоков есть свои маленькие заголовочки по 8 байт.


Заголовок потока у нас = 48 байт это прямо следует из его 25го байта=01
FE FF 00 00 05 00 02 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 01 00 00 00 02 D5 CD D5
9C 2E 1B 10 93 97 08 00 2B 2C F9 AE 30 00 00 00

FE FF - перевёрнутый порядок расположения байтов в потоке(FFFE-прямой порядок).
00 00 - версия подпотока свойств(propertySet substream).
05 - старшая версия операционной системы создавшая этот компаунд фаил.
00 - младшая версия операционной системы создавшая этот компаунд фаил.
02 00 - тип операционной системы(это значение неизменно).
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - идентификатор приложения(это значение неизменно).
01 00 00 00-сколько подпотоков содержит этот поток(DocumentSummaryInformation)
если 01 00 00 00, то только PropertySet stream, если 02 00 00 00
то propertyset stream и UserDefinedPropertySet stream
02 D5 CD D5 9C 2E 1B 10 93 97 08 00 2B 2C F9 AE - опознаватель подпотока PropertySet stream(значение постоянно)
а у подпотока UserDefinedPropertySet stream опознаватель 05 D5 CD D5 9C 2E 1B 10 93 97 08 00 2B 2C F9 AE
как видите он отличается только передним байтом:05 вместо 02.
30 00 00 00 - смещение подпотока PropertySet stream в этом потоке(DocumentSummaryInformation)





если бы имелся подпоток UserDefinedPropertySet stream,
то дальше бы шёл его опознаватель:
05 D5 CD D5 9C 2E 1B 10 93 97 08 00 2B 2C F9 AE
а затем его четырёхбайтовое смещение внутри потока DocumentSummaryInformation
и засчёт этого размер заголовка вырос бы до 68байт.


;;;;;;;;;;подпоток PropertySet stream;;;;;;;;;;;;;;;;;;;;;;;;;

Восемь байт своего заголовка:
----------------------

D0 00 00 00 указывает что подпоток кончается по смещению 208десятичное
от начала подпотока PropertySet stream, а если вы хотите вычислить
смещение в потоке DocumentSummaryInformation, то
смещение_в_потоке=количество_байт_в_заго ловке+смещение в PropertySet stream
т.е 208+48=256байт будет занимать PropertySet stream
09 00 00 00 указывает что в подпотоке 9 свойств(счёт от единицы).
9 свойств означает что далее следуют 9 восьмибайтовых указателей, а
за ними сами 9 свойств разного размера.
(максимальное количество существующих свойств в DocumentSummaryInformation
исчисляется 29ю, согласно документу ms-oshared).


Указатели на свойства:
-----------------------

УКАЗАТЕЛЬ НА ПЕРВОЕ СВОЙСТВО
находится по смещению 50h от начала PropertySet Stream
v v v v
01 00 00 00 50 00 00 00
^ ^ ^ ^
свойство GKPIDDSI_CODEPAGE



УКАЗАТЕЛЬ НА ВТОРОЕ СВОЙСТВО
находится по смещению 58h от начала PropertySet Stream
v v v v
0F 00 00 00 58 00 00 00
^ ^ ^ ^
свойство GKPIDDSI_COMPANY



УКАЗАТЕЛЬ НА ТРЕТЬЕ СВОЙСТВО
находится по смещению 64h от начала PropertySet Stream
v v v v
17 00 00 00 64 00 00 00
^ ^ ^ ^
свойство GKPIDDSI_VERSION



УКАЗАТЕЛЬ НА ЧЕТВЁРТОЕ СВОЙСТВО
находится по смещению 6Ch от начала PropertySet Stream
v v v v
0B 00 00 00 6C 00 00 00
^ ^ ^ ^
свойство GKPIDDSI_SCALE


УКАЗАТЕЛЬ НА ПЯТОЕ СВОЙСТВО
находится по смещению 74h от начала PropertySet Stream
v v v v
10 00 00 00 74 00 00 00
^ ^ ^ ^
свойство GKPIDDSI_LINKSDIRTY


УКАЗАТЕЛЬ НА ШЕСТОЕ СВОЙСТВО
находится по смещению 7Сh от начала PropertySet Stream
v v v v
13 00 00 00 7C 00 00 00
^ ^ ^ ^
свойство GKPIDDSI_SHAREDDOC


УКАЗАТЕЛЬ НА СЕДЬМОЕ СВОЙСТВО
находится по смещению 84h от начала PropertySet Stream
v v v v
16 00 00 00 84 00 00 00
^ ^ ^ ^
свойство GKPIDDSI_HYPERLINKSCHANGED

УКАЗАТЕЛЬ НА ВОСЬМОЕ СВОЙСТВО
находится по смещению 8Сh от начала PropertySet Stream
v v v v
0D 00 00 00 8C 00 00 00
^ ^ ^ ^
свойство GKPIDDSI_DOCPARTS

УКАЗАТЕЛЬ НА ДЕВЯТОЕ СВОЙСТВО
находится по смещению B2h от начала PropertySet Stream
v v v v
0C 00 00 00 B2 00 00 00
^ ^ ^ ^
свойство GKPIDDSI_HEADINGPAIR
0
 Аватар для Estimable
195 / 14 / 1
Регистрация: 02.01.2017
Сообщений: 223
19.01.2019, 09:14
Сами свойства:
----------------
ПЕРВОЕ СВОЙСТВО это GKPIDDSI_CODEPAGE
и оно находится по смещению 50h или 80дес байт
от начала подпотока PropertySet Stream.
Сколько байт оно занимает можно узнать
отняв смещение в первом указателе от
смещения во втором указателе:58h-50h=8h(8дес)
т.е восемь байт:
02 00 00 00 E3 04 00 00 (58h-50h=8байт)
+ + ! ! * * ^ ^
+ + ! ! * * два байта не используются
+ + ! ! сама кодировка.здесь 04e3h=1251дес. Т.е Windows ansi 1251, это простая однобайтовая кодировка ansi.
+ + набивка типа данных до 4х байт
тип данных:0002 это Integer(двухбайтовое беззнаковое)


ВТОРОЕ СВОЙСТВО это GKPIDDSI_COMPANY (64h-58h=12 байт)
1E 00 00 00 01 00 00 00 00 00 00 00
+ + ! ! : : : : ^ # # #
+ + ! ! : : : : ^ три байта набивки до кратности 4м байтам
+ + ! ! : : : : здесь должна была бы быть строка в однобайтовой кодировке с именем компании и стопорным нулём.Сейчас здесь только стопорный 00.
+ + ! ! поле количество байт в текстовой строке вместе со стопорным нулём.
+ + набивка типа данных до 4х байт
тип данных:001E это текстовая строка в однобайтовой кодировке


ТРЕТЬЕ СВОЙСТВО это GKPIDDSI_VERSION (6Ch-64h=8 байт)
03 00 00 00 41 0A 0A 00
+ + ! ! : : ^ ^
+ + ! ! : : младшая версия приложения создавшего этот компаунд фаил
+ + ! ! старшая версия приложения создавшего этот компаунд фаил
+ + набивка типа данных до 4х байт
тип данных:0003 это Long(четырёх байтовое беззнаковое)

ЧЕТВЁРТОЕ СВОЙСТВО это GKPIDDSI_SCALE(74h-6Ch=8 байт)
0B 00 00 00 00 00 00 00
+ + ! ! + + + +
+ + ! ! + + + +
+ + ! ! это значение всегда должно быть FALSE т.е = 00 00 00 00
+ + набивка типа данных до 4х байт
тип данных boolean
Что это такое, в оригинале не сказано.Какая-то маштабируемость.

ПЯТОЕ СВОЙСТВО это GKPIDDSI_LINKSDIRTY(7Ch-74h=8 байт)
0B 00 00 00 00 00 00 00
+ + ! ! + + + +
+ + ! ! + + + +
+ + ! ! тип False(true когда хотя бы один из 4х байт не равен нулю)
+ + набивка типа данных до 4х байт
тип данных boolean
В этом свойстве отмечается требуется ли обновлять связи с другими приложениями
после открытия этого файла. Это не связи книги эксель, а что-то другое.

ШЕСТОЕ СВОЙСТВО это GKPIDDSI_SHAREDDOC(84h-7Ch=8 байт)
0B 00 00 00 00 00 00 00
+ + ! ! + + + +
+ + ! ! + + + +
+ + ! ! это значение всегда должно быть FALSE т.е = 00 00 00 00
+ + набивка типа данных до 4х байт
тип данных boolean


СЕДЬМОЕ СВОЙСТВО это GKPIDDSI_HYPERLINKSCHANGED(8Ch-84h=8 байт)
0B 00 00 00 00 00 00 00
+ + ! ! + + + +
+ + ! ! + + + +
+ + ! ! Тип FALSE ,изменяется на TRUE если в подпотоке UserDefinedPropertySet stream изменилось свойство PID_HLINKS
+ + набивка типа данных до 4х байт
тип данных boolean
Так как у нас нет этого подпотока, то тут всегда False.
А говорится тут про гиперссылки, которые могут самопроизвольно менятся


ВОСЬМОЕ СВОЙСТВО это GKPIDDSI_DOCPARTS(B2H-8CH=38байт)
Это свойство тесно связано со следующим свойством GKPIDDSI_HEADINGPAIR

1E 10 00 00 03 00 00 00 06 00 00 00 CB E8 F1 F2 31 00 06 00 00 00 CB E8 F1 F2 32 00 06 00 00 00 CB E8 F1 F2 33 00
+ + ! ! : : : : ! ! ! ! # # # # # # ! ! ! ! # # # # # # ! ! ! ! # # # # # #
+ + ! ! : : : : ! ! ! ! # # # # # # ! ! ! ! # # # # # # ! ! ! ! сама строка вместе со стопорным 00("Лист3")
+ + ! ! : : : : ! ! ! ! # # # # # # ! ! ! ! # # # # # # размер третьей строки в байтах, учитывая стопорный байт 00
+ + ! ! : : : : ! ! ! ! # # # # # # ! ! ! ! сама строка вместе со стопорным 00("Лист2")
+ + ! ! : : : : ! ! ! ! # # # # # # размер второй строки в байтах, учитывая стопорный байт 00
+ + ! ! : : : : ! ! ! ! сама строка вместе со стопорным 00("Лист1")
+ + ! ! : : : : размер первой строки в байтах, учитывая стопорный байт 00
+ + ! ! Количество строк
+ + набивка типа данных до 4х байт
тип данных:массив строк в однобайтовой кодировке с указанием размера для каждой
Как видите это свойство имеет непосредственное отношение к экселю. Здесь хранится
название наших листов, которое отображается на ярлычках.

ДЕВЯТОЕ СВОЙСТВО это GKPIDDSI_HEADINGPAIR(размер смотрите ниже)
Так как он последний элемент в подпотоке PropertySet Stream и
после него нет свойств, то его размер высчитывается исходя из общего размера
подпотока. Мы его вытащили из маленького заголовка PropertySet Stream.
Размер подпотока = D0 00 00 00. Отсюда:
размер последнего свойства=размер подпотока-смещение последнего свойства в подпотоке т.е
D0H-B2H=1Eh т.е 30байт

0C 10 00 00 02 00 00 00 отсюда 1E 00 00 00 06 00 00 00 CB E8 F1 F2 FB 00 03 00 00 00 03 00 00 00
+ + ! ! : : : : формат % % ! ! * * * * # # # # # # + + * * ^ ^ ^ ^
+ + ! ! : : : : строки % % ! ! * * * * # # # # # # + + * * 3 строки из GKPIDDSI_DOCPARTS ассоциировано с этим заголовком
+ + ! ! : : : : может % % ! ! * * * * # # # # # # + + набивка типа данных до 4х байт
+ + ! ! : : : : повторятся % % ! ! * * * * # # # # # # тип тип данных:0003 это Long(четырёх байтовое беззнаковое)
+ + ! ! : : : : % % ! ! * * * * сама строка вместе со стопорным 00("Листы")
+ + ! ! : : : : % % ! ! размер строки в байтах, учитывая стопорный байт 00
+ + ! ! : : : : % % набивка типа данных до 4х байт
+ + ! ! : : : : тип данных: строка в однобайтовой кодировке
+ + ! ! количество элементов 2
+ + набивка типа данных до 4х байт
тип данных: 100С=вектор

Из всего DocumentSummaryInformation очень важны, только два последних свойства:
GKPIDDSI_DOCPARTS и GKPIDDSI_HEADINGPAIR. Потому как тут происходят
изменения при добавлении и удалении листов.

далее за этими свойствами документ дополняется нулевыми байтами до 4096.
Скажу что это опять же не обязательно потому как в нашем примере разбора пустого
файла поток DocumentSummaryInformation имел размер всего 256 байт и распологался
в мини контейнере.



Приведу cписок свойств которые могут присутствовать в подпотоке property set.
Это выписка из документа MS-OSHARED.
________________________________________ ________________________________________ ________________________________________ ________________________________
|Всеми свойствами можно принебречь, кроме GKPIDDSI_CODEPAGE, которое обязательно |
|должно присутствовать в подпотоке, если уж подпоток property set был |
|создан. |
|Все типы строк должны использовать кодовую страницу указанную в |
|GKPIDDSI_CODEPAGE. Для двухбайтовой строки(Lpwstr) GKPIDDSI_CODEPAGE должен содержать | |
|(0x04B0) т.е установлен на кодировку CP_WINUNICODE . Свойства в подпотоке могут распологаться в |
|любом порядке. |
| |
| |
|-------------------------------------------------------------------------------------------------------------------------------------------------------|
|Имя свойства Опознаватель Размер Описание |
|-------------------------------------------------------------------------------------------------------------------------------------------------------|
|GKPIDDSI_CODEPAGE 00000001h 2б(тип:0002)+2б(набивка:000 В документе указана непонятная ссылка |
| +2б(код страница)+2б(набивка:0000) go.microsoft.com/fwlink/?LinkId=89840 |
| ,но похоже что это те же кодировки что |
| и на странице 145 в документе excelefileformat |
|-------------------------------------------------------------------------------------------------------------------------------------------------------|
|GKPIDDSI_CATEGORY 00000002h 2б(тип:001E или 001F)+2б(набивка:0000) строка в одно или двухбайтовой кодировке |
| +строка(4б колво символов+сама строка содержащая имя категории документа. |
| +набивка до кратн 4 байтам) |
|-------------------------------------------------------------------------------------------------------------------------------------------------------|
|GKPIDDSI_PRESFORMAT 00000003h 2б(тип:001E или 001F)+2б(набивка:0000) строка содержащая формат документа. Запись не обязательна. |
| +строка(4б колво символов+сама строка Может иметь одно из следующих значений: |
| +набивка до кратн 4 байтам) Empty string, On-screen Show, On-screen Show (4:3), |
| Letter Paper (8.5x11 in), Ledger Paper (11x17 in), |
| A3 Paper (297x420 mm), A4 Paper (21297 mm), |
| B4(ISO) Paper (250x353 mm), B5(ISO) Paper (176x250 mm), |
| B4(JIS) Paper (257x364 mm),B5(JIS) Paper (182x257 mm), |
| Hagaki Card (100x148 mm), 35mm Slides, Overhead, Banner, |
| Custom, On-screen Show (16:9), On-screen Show (16:10) |
|-------------------------------------------------------------------------------------------------------------------------------------------------------|
|GKPIDDSI_BYTECOUNT 00000004h 2б(тип:0003)+2б(набивка:0000) Размер документа в байтах.Запись не обязательна. |
| +4б(целое знаковое значение) |
|-------------------------------------------------------------------------------------------------------------------------------------------------------|
|GKPIDDSI_LINECOUNT 00000005h 2б(тип:0003)+2б(набивка:0000) Количество текстовых строк в документе.Запись не обязательна. |
| +4б(целое знаковое значение) |
|-------------------------------------------------------------------------------------------------------------------------------------------------------|
|GKPIDDSI_PARACOUNT 00000006h 2б(тип:0003)+2б(набивка:0000) Количество параграфов в документе.Запись не обязательна. |
| +4б(целое знаковое значение) |
|-------------------------------------------------------------------------------------------------------------------------------------------------------|
|GKPIDDSI_SLIDECOUNT 00000007h 2б(тип:0003)+2б(набивка:0000) Количество слайдов в документе.Запись не обязательна. |
| +4б(целое знаковое значение) |
|-------------------------------------------------------------------------------------------------------------------------------------------------------|
|GKPIDDSI_NOTECOUNT 00000008h 2б(тип:0003)+2б(набивка:0000) Количество пометок(м.б замечаний) в документе. |
| +4б(целое знаковое значение) Запись не обязательна. |
|-------------------------------------------------------------------------------------------------------------------------------------------------------|
|GKPIDDSI_HIDDENCOUNT 00000009h 2б(тип:0003)+2б(набивка:0000) Количество скрытых слайдов в документе.Запись не обязательна. |
| +4б(целое знаковое значение) |
|-------------------------------------------------------------------------------------------------------------------------------------------------------|
|GKPIDDSI_MMCLIPCOUNT 0000000Ah 2б(тип:0003)+2б(набивка:0000) Количество мультимедийных клипов в документе. |
| +4б(целое знаковое значение) Запись не обязательна. |
|-------------------------------------------------------------------------------------------------------------------------------------------------------|
|GKPIDDSI_SCALE 0000000Bh 2б(тип:000B)+2б(набивка:0000) Какое-то значение маштабирования. В ms-oshared сказано, |
| +4б(логическое значение) что оно всегда должно быть false, т.е должно быть равно 0. |
|-------------------------------------------------------------------------------------------------------------------------------------------------------|
|GKPIDDSI_HEADINGPAIR 0000000Ch 2б(тип:0С10)+2б(набивка:0000) Каждый элемент этой записи содержит строку названия и количество|
| +4б(количество элементов) частей документа из записи GKPIDDSI_DOCPARTS к которым она |
| +строки в 2х или 1но байтовой кодировке. применима. Сумма количеств частей документа во всех элементах |
| Для каждой:2б(тип:001E или 001F) этой записи должна быть равна количеству элементов |
| +2б(набивка:0000)+4б колво символов в записи GKPIDDSI_DOCPARTS. |
| +сама строка+2б(тип:0003)+2б(набивка:0000) |
| +4б целое значение |
|-------------------------------------------------------------------------------------------------------------------------------------------------------|
|GKPIDDSI_DOCPARTS 0000000Dh 2б(тип:1E10)+2б(набивка:0000) Каждый строковый элемент указывает на часть документа. |
| +4б(количество строк)+строки в 2х или Элементы выстроены в том порядке, в котором они в котором они |
| 1но байтовой кодировке.Для каждой: существуют в записи GKPIDDSI_HEADINGPAIR. Например: первый |
| 2б(тип:001E или 001F)+2б(набивка:0000) элемент записи heading pair vector говорит, что с ним связано |
| +4б колво символов+сама строка+2б(тип:0003) 4 документа из этой записи. Элементы с 1го по 4й |
| группируются под этим заголовком. Следующий элемент записи |
| heading pair vector говорит что три части документа связаны |
| с ним. И части документа с 5го по 7йгрупируются уже под этим |
| заголовком итд. |
|-------------------------------------------------------------------------------------------------------------------------------------------------------|
|GKPIDDSI_MANAGER 0000000Eh 2б(тип:001E или 001F)+2б(набивка:0000) Строка содержащая имя хозяина документа. |
| +строка(4б колво символов+сама строка |
| +набивка до кратн 4 байтам) |
|-------------------------------------------------------------------------------------------------------------------------------------------------------|
|GKPIDDSI_COMPANY 0000000Fh 2б(тип:001E или 001F)+2б(набивка:0000) Строка содержащая компанию в которй был создан документ. |
| +строка(4б колво символов+сама строка |
| +набивка до кратн 4 байтам) |
|-------------------------------------------------------------------------------------------------------------------------------------------------------|
|GKPIDDSI_LINKSDIRTY 00000010h 2б(тип:000B)+2б(набивка:0000) Это свойство устанавливается в TRUE (любое не нулевое значение) |
| +4б(логическое значение) Если любое значение для свойств linked properties из подпотока |
| User Defined Property Set было изменено вне приложения которое |
| обновляет связи при загрузке документа. |
|-------------------------------------------------------------------------------------------------------------------------------------------------------|
|GKPIDDSI_CCHWITHSPACES 00000011h 2б(тип:0003)+2б(набивка:0000) Целое значение содержащее общее количество символов в |
| +4б(целое знаковое значение) документе, включая пробелы.Запись не обязательна. |
|-------------------------------------------------------------------------------------------------------------------------------------------------------|
|GKPIDDSI_SHAREDDOC 00000013h 2б(тип:000B)+2б(набивка:0000) Значение разделяемых документов, всегда должно быть |
| +4б(логическое значение) FALSE (00000000). |
|-------------------------------------------------------------------------------------------------------------------------------------------------------|
|GKPIDDSI_LINKBASE 00000014h Не известно Запись должна отсутствовать.Так как она была перенесена в |
| подпоток User Defined Property Set под именем _PID_LINKBASE. |
|-------------------------------------------------------------------------------------------------------------------------------------------------------|
|GKPIDDSI_HLINKS 00000015h Не известно Запись должна отсутствовать.Так как она была перенесена в |
| подпоток User Defined Property Set под именем _PID_HLINKS. |
|-------------------------------------------------------------------------------------------------------------------------------------------------------|
|GKPIDDSI_HYPERLINKSCHANGED 00000016h 2б(тип:000B)+2б(набивка:0000) Это значение должно быть TRUE (любое не нулевое значение) если |
| +4б(логическое значение) свойство _PID_HLINKS property из подпотока |
| User Defined Property Set изменилось вне приложения обновляющего|
| гиперссылки в документе при загрузке документа. |
|-------------------------------------------------------------------------------------------------------------------------------------------------------|
|GKPIDDSI_VERSION 00000017h 2б(тип:0003)+2б(набивка:0000) Версия приложения создавшей подпоток property set storage. |
| +4б(целое знаковое значение) Два старших байта содержат большую версию. Два младших байта |
| содержат меньшую версию. Старшая версия должна быть не нулевой, |
| а младшая может быть нулевой(0000) |
|-------------------------------------------------------------------------------------------------------------------------------------------------------|
|GKPIDDSI_DIGSIG 00000018h 2б(тип:0041)+2б(набивка:0000) Цифровая подпись проектов vba.Запись не обязательна и должна |
| +4б(размер подписи в байтах) отсутствовать если в документе нет vba макросов. |
| +4б(размер информ о подписи и набивки) |
| +4б(смещение подписи в этой записи, |
| обычно=00000008)+4б(размер буфера подписи) |
| +4б(смещение буфера подписи) |
| +4б(размер сертификата подписи) |
| +4б(смещение сертификата подписи) |
| +4б(размер буфера имени проекта, |
| обычно=00000000) |
| +4б(смещение буфера имени проекта) |
| +4б(временной отпечаток,обычно=00000000) |
| +4б(размер временного отпечатка) |
| +4б смещение временного отпечатка |
| +буфер подписи(разн размер) |
| +сертификат подписи(разн размер) |
| +буфер имени(разн размер) |
| +буфер временного отпечатка(разн размер) |
| +набивка до кратности 4м байтам |
|-------------------------------------------------------------------------------------------------------------------------------------------------------|
|GKPIDDSI_CONTENTTYPE 0000001Ah 2б(тип:001E или 001F)+2б(набивка:0000) Строка описывающая содержание файла. Запись не обязательна. |
| +строка(4б колво символов+сама строка |
| +набивка до кратн 4 байтам) |
|-------------------------------------------------------------------------------------------------------------------------------------------------------|
|GKPIDDSI_CONTENTSTATUS 0000001Bh 2б(тип:001E или 001F)+2б(набивка:0000) Строка содержащая статус документа. Запись не обязательна. |
| +строка(4б колво символов+сама строка |
| +набивка до кратн 4 байтам) |
|-------------------------------------------------------------------------------------------------------------------------------------------------------|
|GKPIDDSI_LANGUAGE 0000001Ch 2б(тип:001E или 001F)+2б(набивка:0000) Запись должна отсутствовать. |
| +строка(4б колво символов+сама строка |
| +набивка до кратн 4 байтам) |
|-------------------------------------------------------------------------------------------------------------------------------------------------------|
|GKPIDDSI_DOCVERSION 0000001Dh 2б(тип:001E или 001F)+2б(набивка:0000) Запись должна отсутствовать. |
| +строка(4б колво символов+сама строка |
| +набивка до кратн 4 байтам) |
|_______________________________________ ________________________________________ ________________________________________ ________________________________|
0
 Аватар для Estimable
195 / 14 / 1
Регистрация: 02.01.2017
Сообщений: 223
19.01.2019, 09:17
Допустим что у нас существует подпоток UserDefinedPropertySet stream,
он начинается сразу же за вышеописанными свойствами подпотока PropertySet stream
Допустим он выглядит вот так(эти данные я взял из документа ms-oshared):

20 04 00 00 09 00 00 00 ........ .......
00 00 00 00 50 00 00 00 01 00 00 00 D2 00 00 00 ....P...........
02 00 00 00 DA 00 00 00 03 00 00 00 E6 00 00 00 ................
04 00 00 00 B6 03 00 00 05 00 00 00 CA 03 00 00 ................
06 00 00 00 D2 03 00 00 07 00 00 00 DA 03 00 00 ................
07 00 00 01 FA 03 00 00 06 00 00 00 02 00 00 00 ................
0E 00 00 00 5F 50 49 44 5F 4C 49 4E 4B 42 41 53 ...._PID_LINKBAS
45 00 03 00 00 00 0C 00 00 00 5F 50 49 44 5F 48 E........._PID_H
4C 49 4E 4B 53 00 04 00 00 00 0B 00 00 00 44 65 LINKS.........De
70 61 72 74 6D 65 6E 74 00 05 00 00 00 10 00 00 partment........
00 44 6F 63 75 6D 65 6E 74 20 6E 75 6D 62 65 72 .Document number
00 06 00 00 00 09 00 00 00 41 70 70 72 6F 76 65 .........Approve
64 00 07 00 00 00 10 00 00 00 43 72 69 74 69 63 d.........Critic
61 6C 53 65 63 74 69 6F 6E 00 02 00 00 00 E4 04 alSection.......
00 00 41 00 00 00 02 00 00 00 00 00 00 00 41 00 ..A...........A.
00 00 C8 02 00 00 24 00 00 00 03 00 00 00 69 00 ......$.......i.
67 00 03 00 00 00 0C 00 00 00 03 00 00 00 00 00 g...............
00 00 03 00 00 00 05 00 00 00 1F 00 00 00 01 00 ................
00 00 00 00 79 32 1F 00 00 00 1B 00 00 00 53 00 ....y2........S.
6B 00 69 00 70 00 4C 00 65 00 76 00 65 00 6C 00 k.i.p.L.e.v.e.l.
56 00 65 00 72 00 69 00 66 00 69 00 63 00 61 00 V.e.r.i.f.i.c.a.
74 00 69 00 6F 00 6E 00 53 00 74 00 61 00 72 00 t.i.o.n.S.t.a.r.
74 00 00 00 00 00 03 00 00 00 14 00 3C 00 03 00 t...........<...
00 00 09 00 00 00 03 00 00 00 00 00 00 00 03 00 ................
00 00 05 00 00 00 1F 00 00 00 1F 00 00 00 43 00 ..............C.
3A 00 5C 00 4D 00 69 00 63 00 72 00 6F 00 73 00 :.\.M.i.c.r.o.s.
6F 00 66 00 74 00 4F 00 66 00 66 00 69 00 63 00 o.f.t.O.f.f.i.c.
65 00 4F 00 72 00 67 00 43 00 68 00 61 00 72 00 e.O.r.g.C.h.a.r.
74 00 2E 00 76 00 73 00 64 00 00 00 00 00 1F 00 t...v.s.d.......
00 00 01 00 00 00 00 00 79 32 03 00 00 00 64 00 ........y2....d.
32 00 03 00 00 00 06 00 00 00 03 00 00 00 00 00 2...............
00 00 03 00 00 00 05 00 00 00 1F 00 00 00 1C 00 ................
00 00 68 00 74 00 74 00 70 00 3A 00 2F 00 2F 00 ..h.t.t.p.:././.
77 00 77 00 77 00 2E 00 77 00 69 00 6E 00 67 00 w.w.w...w.i.n.g.
74 00 69 00 70 00 74 00 6F 00 79 00 73 00 2E 00 t.i.p.t.o.y.s...
63 00 6F 00 6D 00 2F 00 00 00 1F 00 00 00 01 00 c.o.m./.........
00 00 00 00 79 32 03 00 00 00 4A 00 41 00 03 00 ....y2....J.A...
00 00 03 00 00 00 03 00 00 00 00 00 00 00 03 00 ................
00 00 05 00 00 00 1F 00 00 00 01 00 00 00 00 00 ................
79 32 1F 00 00 00 14 00 00 00 5F 00 56 00 65 00 y2........_.V.e.
72 00 69 00 66 00 69 00 63 00 61 00 74 00 69 00 r.i.f.i.c.a.t.i.
6F 00 6E 00 5F 00 53 00 74 00 65 00 70 00 73 00 o.n._.S.t.e.p.s.
00 00 03 00 00 00 3E 00 25 00 03 00 00 00 00 00 ......>.%.......
00 00 03 00 00 00 00 00 00 00 03 00 00 00 05 00 ................
00 00 1F 00 00 00 31 00 00 00 68 00 74 00 74 00 ......1...h.t.t.
70 00 3A 00 2F 00 2F 00 65 00 6E 00 2E 00 61 00 p.:././.e.n...a.
64 00 61 00 74 00 75 00 6D 00 2E 00 63 00 6F 00 d.a.t.u.m...c.o.
6D 00 2F 00 61 00 63 00 63 00 6F 00 75 00 6E 00 m./.a.c.c.o.u.n.
74 00 69 00 6E 00 67 00 2F 00 6D 00 61 00 6E 00 t.i.n.g./.m.a.n.
61 00 67 00 65 00 72 00 6C 00 69 00 73 00 74 00 a.g.e.r.l.i.s.t.
2E 00 68 00 74 00 6D 00 6C 00 00 00 00 00 1F 00 ..h.t.m.l.......
00 00 0F 00 00 00 65 00 6D 00 61 00 69 00 6C 00 ......e.m.a.i.l.
41 00 64 00 64 00 72 00 65 00 73 00 73 00 65 00 A.d.d.r.e.s.s.e.
73 00 00 00 00 00 03 00 00 00 28 00 6B 00 03 00 s.........(.k...
00 00 FF FF FF FF 03 00 00 00 03 04 00 00 03 00 ................
00 00 04 00 00 00 1F 00 00 00 01 00 00 00 00 00 ................
79 32 1F 00 00 00 19 00 00 00 5F 00 53 00 6B 00 y2........_.S.k.
69 00 70 00 2D 00 6C 00 65 00 76 00 65 00 6C 00 i.p.-.l.e.v.e.l.
5F 00 56 00 65 00 72 00 69 00 66 00 69 00 63 00 _.V.e.r.i.f.i.c.
61 00 74 00 69 00 6F 00 6E 00 00 00 00 00 1E 00 a.t.i.o.n.......
00 00 0C 00 00 00 41 63 63 6F 75 6E 74 69 6E 67 ......Accounting
00 00 03 00 00 00 05 00 00 00 0B 00 00 00 00 00 ................
00 00 1E 00 00 00 18 00 00 00 53 69 67 6E 20 74 ..........Sign t
68 65 20 61 70 70 72 6F 76 61 6C 20 66 6F 72 6D he approval form
00 00 1E 00 00 00 1C 00 00 00 53 6B 69 70 4C 65 ..........SkipLe
76 65 6C 56 65 72 69 66 69 63 61 74 69 6F 6E 53 velVerificationS
74 61 72 74 00 00 00 00 tart....

Если мы будем считать что подпоток UserDefinedPropertySet stream
существует, то представим что заголовок всего потока у нас не 48 а 68 байт,
там добавится 16ти байтовый опознаватель подпотока
UserDefinedPropertySet stream = 05 D5 CD D5 9C 2E 1B 10 93 97 08 00 2B 2C F9 AE
и его 4х байтовое смещение внутри всего потока.

Начнём разбор UserDefinedPropertySet stream. Его структура схожа с PropertySet stream

Восемь байт своего заголовка:
----------------------

20 04 00 00 09 00 00 00

Здесь:

20 04 00 00 указывает что подпоток кончается по смещению 420h(1056десятичное)
от начала подпотока UserDefinedPropertySet stream.
09 00 00 00 указывает что в подпотоке 9 свойств(счёт от единицы).
9 свойств означает что далее следуют 9 восьмибайтовых указателей, а
за ними сами 9 свойств разного размера.


Указатели на свойства(9штук):
-----------------------
00 00 00 00 50 00 00 00 01 00 00 00 D2 00 00 00
02 00 00 00 DA 00 00 00 03 00 00 00 E6 00 00 00
04 00 00 00 B6 03 00 00 05 00 00 00 CA 03 00 00
06 00 00 00 D2 03 00 00 07 00 00 00 DA 03 00 00
07 00 00 01 FA 03 00 00

УКАЗАТЕЛЬ НА ПЕРВОЕ СВОЙСТВО
находится по смещению 50h от начала UserDefinedPropertySet stream
v v v v
00 00 00 00 50 00 00 00
^ ^ ^ ^
свойство Dictionary


УКАЗАТЕЛЬ НА ВТОРОЕ СВОЙСТВО
находится по смещению D2h от начала UserDefinedPropertySet stream
v v v v
01 00 00 00 D2 00 00 00
^ ^ ^ ^
свойство CodePage


УКАЗАТЕЛЬ НА ТРЕТЬЕ СВОЙСТВО
находится по смещению DAh от начала UserDefinedPropertySet stream
v v v v
02 00 00 00 DA 00 00 00
^ ^ ^ ^
свойство пользователя "_PID_LINKBASE" (строится по форме linkbase об этом ниже)



УКАЗАТЕЛЬ НА ЧЕТВЁРТОЕ СВОЙСТВО
находится по смещению E6h от начала UserDefinedPropertySet stream
v v v v
03 00 00 00 E6 00 00 00
^ ^ ^ ^
свойство пользователя "_PID_HLINKS" (строится по форме hyperlinks об этом ниже)



УКАЗАТЕЛЬ НА ПЯТОЕ СВОЙСТВО
находится по смещению 3B6h от начала UserDefinedPropertySet stream
v v v v
04 00 00 00 B6 03 00 00
^ ^ ^ ^
свойство пользователя "Department" (нет формы, т.к это свойство придумано пользователем)



УКАЗАТЕЛЬ НА ШЕСТОЕ СВОЙСТВО
находится по смещению 3CAh от начала UserDefinedPropertySet stream
v v v v
05 00 00 00 CA 03 00 00
^ ^ ^ ^
свойство пользователя "Document number" (нет формы, т.к это свойство придумано пользователем)


УКАЗАТЕЛЬ НА СЕДЬМОЕ СВОЙСТВО
находится по смещению 3D2h от начала UserDefinedPropertySet stream
v v v v
06 00 00 00 D2 03 00 00
^ ^ ^ ^
свойство пользователя "Approved" (нет формы, т.к это свойство придумано пользователем)


УКАЗАТЕЛЬ НА ВОСЬМОЕ СВОЙСТВО
находится по смещению 3DAh от начала UserDefinedPropertySet stream
v v v v
07 00 00 00 DA 03 00 00
^ ^ ^ ^
свойство пользователя "CriticalSection" (нет формы, т.к это свойство придумано пользователем).



УКАЗАТЕЛЬ НА ДЕВЯТОЕ СВОЙСТВО
находится по смещению 3FAh от начала UserDefinedPropertySet stream
v v v v
07 00 00 01 FA 03 00 00
^ ^ ^ ^
свойство Linked


Сами свойства:
----------------
ПЕРВОЕ СВОЙСТВО это Dictionary
и оно находится по смещению 50h или 80дес байт
от начала подпотока UserDefinedPropertySet stream.
Сколько байт оно занимает можно узнать
отняв смещение в первом указателе от
смещения во втором указателе2h-50h=82h(130дес)
т.е сто тридцать байт:

06 00 00 00 02 00 00 00 ................
0E 00 00 00 5F 50 49 44 5F 4C 49 4E 4B 42 41 53 ...._PID_LINKBAS
45 00 03 00 00 00 0C 00 00 00 5F 50 49 44 5F 48 E........._PID_H
4C 49 4E 4B 53 00 04 00 00 00 0B 00 00 00 44 65 LINKS.........De
70 61 72 74 6D 65 6E 74 00 05 00 00 00 10 00 00 partment........
00 44 6F 63 75 6D 65 6E 74 20 6E 75 6D 62 65 72 .Document number
00 06 00 00 00 09 00 00 00 41 70 70 72 6F 76 65 .........Approve
64 00 07 00 00 00 10 00 00 00 43 72 69 74 69 63 d.........Critic
61 6C 53 65 63 74 69 6F 6E 00 alSection.......

Т.к UserDefinedPropertySet stream имеет не много зарезервированных
свойств=5(со своими опознавателями),то остальные опознаватели можно
использовать для задания своих собственных свойств(т.е подпунктов
на вкладке свойств). Для этого и создан подпоток UserDefinedPropertySet stream
Вы не можете использовать тут опознаватели:
00000000h(Dictionary),00000001h(codepage ),01000007h(Linked).
А остальные указатели из диапазона 00000000h - ffffffffh используются свободно.
Ещё добавлю что 2 опознавателя:00000002h(linkbase) и 00000003h(hyperlinks) тоже
зарезервированы, но они обязательно должны иметь имя назначенное пользователём.



Свои свойства задаются в свойстве Dictionary таким образом:
опознаватель и рядом строка его имени
опознаватель и рядом строка его имени
опознаватель и рядом строка его имени
опознаватель и рядом строка его имени
итд


Разберём это свойство:
06 00 00 00 - количество описываемых свойств в Dictionary


02 00 00 00 0E 00 00 00 5F 50 49 44 5F 4C 49 4E 4B 42 41 53 45 00
^ ^ ^ ^ * * * * v v v v v v v v v v v v v v
| | | | * * * * имя нашего свойства("_PID_LINKBASE")
| | | | 14 байт в имени
Назначаем для нашего свойства опознаватель 02h


03 00 00 00 0C 00 00 00 5F 50 49 44 5F 48 4C 49 4E 4B 53 00
^ ^ ^ ^ * * * * v v v v v v v v v v v v
| | | | * * * * имя нашего свойства("_PID_HLINKS")
| | | | 12 байт в имени
Назначаем для нашего свойства опознаватель 03h


04 00 00 00 0B 00 00 00 44 65 70 61 72 74 6D 65 6E 74 00
^ ^ ^ ^ * * * * v v v v v v v v v v v
| | | | * * * * имя нашего свойства("Department")
| | | | 11 байт в имени
Назначаем для нашего свойства опознаватель 04h


05 00 00 00 10 00 00 00 44 6F 63 75 6D 65 6E 74 20 6E 75 6D 62 65 72 00
^ ^ ^ ^ * * * * v v v v v v v v v v v v v v v v
| | | | * * * * имя нашего свойства("Document number")
| | | | 16 байт в имени
Назначаем для нашего свойства опознаватель 05h

06 00 00 00 09 00 00 00 41 70 70 72 6F 76 65 64 00
^ ^ ^ ^ * * * * v v v v v v v v v
| | | | * * * * имя нашего свойства("Approved")
| | | | 9 байт в имени
Назначаем для нашего свойства опознаватель 06h

07 00 00 00 10 00 00 00 43 72 69 74 69 63 61 6C 53 65 63 74 69 6F 6E 00
^ ^ ^ ^ * * * * v v v v v v v v v v v v v v
| | | | * * * * имя нашего свойства("CriticalSection")
| | | | 16 байт в имени
Назначаем для нашего свойства опознаватель 07h

ВТОРОЕ СВОЙСТВО это CODEPAGE
и оно находится по смещению D2h или 210дес байт
от начала подпотока UserDefinedPropertySet stream.
Сколько байт оно занимает можно узнать
отняв смещение во втором указателе от
смещения в третьем указателеAh-D2h=8h(8дес)
т.е восемь байт:
02 00 00 00 E4 04 00 00
+ + ! ! * * ^ ^
+ + ! ! * * два байта не используются
+ + ! ! сама кодировка.здесь 04e4h=1252дес. Т.е Windows ansi 1252, это простая однобайтовая кодировка ansi.
+ + набивка типа данных до 4х байт
тип данных:0002 это Integer(двухбайтовое беззнаковое)


ТРЕТЬЕ СВОЙСТВО это "_PID_LINKBASE" (строится по форме linkbase) (E6h-DAh=12 байт)
41 00 00 00 02 00 00 00 00 00 00 00
+ + ! ! : : : : ^ ^ ^ ^
+ + ! ! : : : : осталась только набивка а данных нет
+ + ! ! количество байт в строке включая набивку до кратн 4м байтам
+ + набивка типа данных до 4х байт
тип данных:4100 это (двоичные данные/флаги с набивкой 00 до кратн 4м байтам)
Что должно быть в этом свойстве я не знаю, т.к в ms-oshared ничего по этому поводу
не сказано. Возможно идёт речь о каких-то основных связях.


ЧЕТВЁРТОЕ СВОЙСТВО это "_PID_HLINKS" (строится по форме hyperlinks)(3B6h-E6Ch=720 байт)
Здесь сохраняются все ссылки, которые есть в документе
41 00 .A.
00 00 C8 02 00 00 24 00 00 00 03 00 00 00 69 00 ......$.......i.
67 00 03 00 00 00 0C 00 00 00 03 00 00 00 00 00 g...............
00 00 03 00 00 00 05 00 00 00 1F 00 00 00 01 00 ................
00 00 00 00 79 32 1F 00 00 00 1B 00 00 00 53 00 ....y2........S.
6B 00 69 00 70 00 4C 00 65 00 76 00 65 00 6C 00 k.i.p.L.e.v.e.l.
56 00 65 00 72 00 69 00 66 00 69 00 63 00 61 00 V.e.r.i.f.i.c.a.
74 00 69 00 6F 00 6E 00 53 00 74 00 61 00 72 00 t.i.o.n.S.t.a.r.
74 00 00 00 00 00 03 00 00 00 14 00 3C 00 03 00 t...........<...
00 00 09 00 00 00 03 00 00 00 00 00 00 00 03 00 ................
00 00 05 00 00 00 1F 00 00 00 1F 00 00 00 43 00 ..............C.
3A 00 5C 00 4D 00 69 00 63 00 72 00 6F 00 73 00 :.\.M.i.c.r.o.s.
6F 00 66 00 74 00 4F 00 66 00 66 00 69 00 63 00 o.f.t.O.f.f.i.c.
65 00 4F 00 72 00 67 00 43 00 68 00 61 00 72 00 e.O.r.g.C.h.a.r.
74 00 2E 00 76 00 73 00 64 00 00 00 00 00 1F 00 t...v.s.d.......
00 00 01 00 00 00 00 00 79 32 03 00 00 00 64 00 ........y2....d.
32 00 03 00 00 00 06 00 00 00 03 00 00 00 00 00 2...............
00 00 03 00 00 00 05 00 00 00 1F 00 00 00 1C 00 ................
00 00 68 00 74 00 74 00 70 00 3A 00 2F 00 2F 00 ..h.t.t.p.:././.
77 00 77 00 77 00 2E 00 77 00 69 00 6E 00 67 00 w.w.w...w.i.n.g.
74 00 69 00 70 00 74 00 6F 00 79 00 73 00 2E 00 t.i.p.t.o.y.s...
63 00 6F 00 6D 00 2F 00 00 00 1F 00 00 00 01 00 c.o.m./.........
00 00 00 00 79 32 03 00 00 00 4A 00 41 00 03 00 ....y2....J.A...
00 00 03 00 00 00 03 00 00 00 00 00 00 00 03 00 ................
00 00 05 00 00 00 1F 00 00 00 01 00 00 00 00 00 ................
79 32 1F 00 00 00 14 00 00 00 5F 00 56 00 65 00 y2........_.V.e.
72 00 69 00 66 00 69 00 63 00 61 00 74 00 69 00 r.i.f.i.c.a.t.i.
6F 00 6E 00 5F 00 53 00 74 00 65 00 70 00 73 00 o.n._.S.t.e.p.s.
00 00 03 00 00 00 3E 00 25 00 03 00 00 00 00 00 ......>.%.......
00 00 03 00 00 00 00 00 00 00 03 00 00 00 05 00 ................
00 00 1F 00 00 00 31 00 00 00 68 00 74 00 74 00 ......1...h.t.t.
70 00 3A 00 2F 00 2F 00 65 00 6E 00 2E 00 61 00 p.:././.e.n...a.
64 00 61 00 74 00 75 00 6D 00 2E 00 63 00 6F 00 d.a.t.u.m...c.o.
6D 00 2F 00 61 00 63 00 63 00 6F 00 75 00 6E 00 m./.a.c.c.o.u.n.
74 00 69 00 6E 00 67 00 2F 00 6D 00 61 00 6E 00 t.i.n.g./.m.a.n.
61 00 67 00 65 00 72 00 6C 00 69 00 73 00 74 00 a.g.e.r.l.i.s.t.
2E 00 68 00 74 00 6D 00 6C 00 00 00 00 00 1F 00 ..h.t.m.l.......
00 00 0F 00 00 00 65 00 6D 00 61 00 69 00 6C 00 ......e.m.a.i.l.
41 00 64 00 64 00 72 00 65 00 73 00 73 00 65 00 A.d.d.r.e.s.s.e.
73 00 00 00 00 00 03 00 00 00 28 00 6B 00 03 00 s.........(.k...
00 00 FF FF FF FF 03 00 00 00 03 04 00 00 03 00 ................
00 00 04 00 00 00 1F 00 00 00 01 00 00 00 00 00 ................
79 32 1F 00 00 00 19 00 00 00 5F 00 53 00 6B 00 y2........_.S.k.
69 00 70 00 2D 00 6C 00 65 00 76 00 65 00 6C 00 i.p.-.l.e.v.e.l.
5F 00 56 00 65 00 72 00 69 00 66 00 69 00 63 00 _.V.e.r.i.f.i.c.
61 00 74 00 69 00 6F 00 6E 00 00 00 00 00

Здесь
41 00 00 00 C8 02 00 00 24 00 00 00
+ + ! ! : : : : ^ ^ ^ ^
+ + ! ! : : : : количество элементов vthyperlink, а ссылок соответственно 24h(36дес)/6=6
+ + ! ! количество байт в строке включая набивку до кратн 4м байтам(2с8h=712 байт)
+ + набивка типа данных до 4х байт
тип данных:4100 это (двоичные данные с набивкой 00 до кратн 4м байтам)

Гиперссылки хранятся внутри структур vthyperlink в которых, кроме самих ссылок,
содержатся их описания. Всего в одной структуре содержится 6 элементов:
dwHash, dwApp, dwOfficeArt, dwInfo, hlink1, and hlink2

dwHash-контрольная сумма ссылки
dwApp, dwOfficeArt, dwInfo - значения в этих элементах определяют где расположена ссылка
ссылка может распологаться в shape(кнопка,флажок,список и др),
в картинке, в тексте и др. местах.
hlink1,hlink2 - куда указывает ссылка: на закладку(в этом же документе), на заголовок(в этом же документе),
на другой фаил, на другой ссайт, на фаил на сайте итд итп.

03 00 00 00 00 69 00 67 03 00 00 00 0С 00 00 00 03 00 00 00 00 00 00 00 03 00 00 00 05 00 00 00 1F 00 00 00 01 00 00 00 00 00 79 32 1F 00 00 00 1B 00 00 00 53 00
+ + ! ! : : : : ^ ^ v v : : : : ^ ^ v v : : : : ^ ^ v v : : : : ^ ^ v v : : : : * * + + ^ ^ v v : : : : 6B 00 69 00 70 00 4C 00 65 00 76 00 65 00 6C 00
+ + ! ! : : : : ^ ^ v v : : : : ^ ^ v v : : : : ^ ^ v v : : : : ^ ^ v v : : : : * * + + ^ ^ v v : : : : 56 00 65 00 72 00 69 00 66 00 69 00 63 00 61 00
+ + ! ! : : : : ^ ^ v v : : : : ^ ^ v v : : : : ^ ^ v v : : : : ^ ^ v v : : : : * * + + ^ ^ v v : : : : 74 00 69 00 6F 00 6E 00 53 00 74 00 61 00 72 00
+ + ! ! : : : : ^ ^ v v : : : : ^ ^ v v : : : : ^ ^ v v : : : : ^ ^ v v : : : : * * + + ^ ^ v v : : : : 74 00 00 00
+ + ! ! : : : : ^ ^ v v : : : : ^ ^ v v : : : : ^ ^ v v : : : : ^ ^ v v : : : : * * + + ^ ^ v v : : : : # # # # # # # # # # # # # # # #
+ + ! ! : : : : ^ ^ v v : : : : ^ ^ v v : : : : ^ ^ v v : : : : ^ ^ v v : : : : * * + + ^ ^ v v : : : : сама строка("SkipLevelVerificationStart")
+ + ! ! : : : : ^ ^ v v : : : : ^ ^ v v : : : : ^ ^ v v : : : : ^ ^ v v : : : : * * + + ^ ^ v v кол-во байт в строке hlink2(расположение ссылки) с 0000
+ + ! ! : : : : ^ ^ v v : : : : ^ ^ v v : : : : ^ ^ v v : : : : ^ ^ v v : : : : * * + + ^ ^ набивка
+ + ! ! : : : : ^ ^ v v : : : : ^ ^ v v : : : : ^ ^ v v : : : : ^ ^ v v : : : : * * + + тип
+ + ! ! : : : : ^ ^ v v : : : : ^ ^ v v : : : : ^ ^ v v : : : : ^ ^ v v : : : : * * эти байты не описаны
+ + ! ! : : : : ^ ^ v v : : : : ^ ^ v v : : : : ^ ^ v v : : : : ^ ^ v v : : : : строка
+ + ! ! : : : : ^ ^ v v : : : : ^ ^ v v : : : : ^ ^ v v : : : : ^ ^ v v кол-во байт в строке hlink1(цель ссылки) с 0000
+ + ! ! : : : : ^ ^ v v : : : : ^ ^ v v : : : : ^ ^ v v : : : : ^ ^ набивка
+ + ! ! : : : : ^ ^ v v : : : : ^ ^ v v : : : : ^ ^ v v : : : : тип
+ + ! ! : : : : ^ ^ v v : : : : ^ ^ v v : : : : ^ ^ v v dwinfo ссылка наход в документе а не в shape обьекте
+ + ! ! : : : : ^ ^ v v : : : : ^ ^ v v : : : : ^ ^ набивка
+ + ! ! : : : : ^ ^ v v : : : : ^ ^ v v : : : : тип
+ + ! ! : : : : ^ ^ v v : : : : ^ ^ v v dwOfficeArt пуст так как ссылка не из shape обьекта
+ + ! ! : : : : ^ ^ v v : : : : ^ ^ набивка
+ + ! ! : : : : ^ ^ v v : : : : тип
+ + ! ! : : : : ^ ^ v v dwAPP указывает на PlcFld
+ + ! ! : : : : ^ ^ набивка
+ + ! ! : : : : тип
+ + ! ! Элемент dwHash. Алгоритм вычисления довольно мудрёный:сначала каждую unicode
+ + ! ! строку hlink превращают в 4х байтовое значение(по собственному алгоритму), потом их
+ + ! ! xorят между собой(т.е обращают биты hlink1 об hlink2 (раздел 2.4.2 в ms-oshared))
+ + набивка типа данных до 4х байт
тип данных:0300 это (целое знаковое значение)

Я разобрал только одну структуру vthyperlink, а их там 6 и они идут друг за другом,
тут много неясного и в ms-oshared это не описывается. Всё обьяснение должно присутствовать
в документе MS-DOC т.к имеется множество ссылок на него.
В hlink1 обычно вот такие значения:"C:\MicrosoftOfficeOrgChart.vsd " или "http://www.wingtiptoys.com/" т.е пути
В hlink2:"_Verification_Steps","SkipLevelV erificationStart" или "emailAddresses" т.е надписи

ОСТАЛЬНЫЕ СВОЙСТВА ПОЛЬЗОВАТЕЛЯ это просто строки и в документе их описание пропущено,
кроме связки свойств criticalsection и linked, которое я абсолютно не понял. Эта информация
находится в разделе 3.2.3.4 документа ms-oshared.
0
 Аватар для Estimable
195 / 14 / 1
Регистрация: 02.01.2017
Сообщений: 223
19.01.2019, 09:18
Приведу зарезервированные свойства для подпотока UserDefinedPropertySet stream
________________________________________ ________________________________________ ________________________________________ _______________________________
|Имя свойства Опознаватель Размер Описание |
|-------------------------------------------------------------------------------------------------------------------------------------------------------|
|DICTIONARY 00000000h 4б(целое число отображ кол-во входов) Свойство dictionary служит для добавления свойств придуманных |
| +для каждого входа: пользователем. |
| |
| 4б(идентификатор свойства) Задаётся новый идентификатор(за исключением зарезервированных, |
| +4б(длинна имени свойства в символах т.е тех, которые содержатся в этой таблице) |
| вместе со стопорным 00) и ему приписывается любое имя в однобайтовой кодировке. |
| +строка имени свойства в двух |
| или однобайт кодировке(разн размера) |
| +стопорный 00(или 0000 для unicode) |
| |
| +набивка до кратности 4м байтам |
|-------------------------------------------------------------------------------------------------------------------------------------------------------|
|CODEPAGE 00000001h 2б(тип:0002)+2б(набивка:0000) В документе указана непонятная ссылка |
| +2б(код страница)+2б(набивка:0000) go.microsoft.com/fwlink/?LinkId=89840 |
| ,но похоже что это те же кодировки что |
| и на странице 145 в документе excelefileformat |
|-------------------------------------------------------------------------------------------------------------------------------------------------------|
|LINKBASE 00000002h 2б(тип:4100)+2б(набивка:0000) Свойство linkbase требует придуманного пользователем имени. |
| +байтовая строка неопредел длинны Описания этого свойства в документе ms-oshared нет. |
| +набивка до кратн 4 байтам) |
|-------------------------------------------------------------------------------------------------------------------------------------------------------|
|HYPERLINKS 00000003h 2б(тип:4100)+2б(набивка:0000) Описание ссылок которые имеются в документе. |
| +4б(количество байт в строке) Свойство hyperlinks требует придуманного пользователем имени. |
| +4б количество элементов из Каждая ссылка описывается 6ю элементами:dwhash,dwAPP, |
| структур vthyperlink dwOfficeArt,dwInfo,hlink1,hlink2. |
| Толкового описания этого свойства нет в ms-oshared. Но есть |
| в каждой структуре: указание, что оно содержится в документе ms-doc |
| Элемент dwhash:2б(тип:0300)+2б(набивка:0000) |
| +4б(контрольная сумма эл-тов hlink1 xor hlink2) |
| Элемент dwAPP:2б(тип:0300)+2б(набивка:0000) |
| +4б(не известное значение) |
| Элемент dwOfficeArt:2б(тип:0300)+2б(набивка:0000 ) |
| +4б(не известное значение) |
| Элемент dwInfo:2б(тип:0300)+2б(набивка:0000) |
| +4б(не известное значение) |
| Элемент hlink1:2б(тип:1f00)+2б(набивка:0000) |
| +4б(кол во символов в строке включая стопорный 0000) |
| +сама строка в двухбайт кодировке(разн размер) |
| Элемент hlink2:2б(тип:1f00)+2б(набивка:0000) |
| +4б(кол во символов в строке включая стопорный 0000) |
| +сама строка в двухбайт кодировке(разн размер) |
| |
| +набивка до кратн 4 байтам) |
|-------------------------------------------------------------------------------------------------------------------------------------------------------|
|LINKED 01000007h с этим свойством я не разобрался, известно что оно действует |
| в паре. В нашем примере оно в паре с criticalsection. Почему? я не знаю |
| т.к не единой ссылки на criticalsection в свойстве linked нет. Но |
| подозрения вызывает опознаватель 00000007 т.к он похож на 01000007 |
| Быть может что опознаватель свойства linked это 01000000h, а не |
| 01000007h и в остальных младших шестнадцатеричных разрядах пишется |
| опознаватель свойства с которым свойство linked будет действовать в паре|
|-------------------------------------------------------------------------------------------------------------------------------------------------------|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Добавлено через 39 секунд
_____
| \
| |
| |
| |
| |
|______|
Переходим к потоку SummaryInformation. Как вы догадались SummaryInformation тоже
содержит свойства. Свойства о происхождении документа. Судя по описанию в ms-oleps
он имеет заголовок и всего один подпоток с таким же именем как
в DocumenrSummaryInformation: PropertySetStream.

__________________
| \
| HEADER \
| \
|_____________________|
| |
| | /|
| | / |______________
| | / | поток SummaryInformation
| | \ ______________|
| PropertySet stream | \ |
| | \|
| |
| |
| |
| |
|_____________________|


Рассмотрим поток SummaryInformation из нашего примера

FE FF 00 00 05 00 02 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 01 00 00 00 E0 85 9F F2
F9 4F 68 10 AB 91 08 00 2B 27 B3 D9 30 00 00 00
B0 00 00 00 07 00 00 00 01 00 00 00 40 00 00 00
04 00 00 00 48 00 00 00 08 00 00 00 68 00 00 00
12 00 00 00 78 00 00 00 0C 00 00 00 90 00 00 00
0D 00 00 00 9C 00 00 00 13 00 00 00 A8 00 00 00
02 00 00 00 E3 04 00 00 1E 00 00 00 16 00 00 00
4D 69 63 72 6F 73 6F 66 74 20 43 6F 72 70 6F 72
61 74 69 6F 6E 00 00 00 1E 00 00 00 07 00 00 00
66 72 61 75 65 72 00 66 1E 00 00 00 10 00 00 00
4D 69 63 72 6F 73 6F 66 74 20 45 78 63 65 6C 00
40 00 00 00 80 BE B5 FA 70 B5 BB 01 40 00 00 00
00 64 31 B2 A0 BE C0 01 03 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
SummaryInformation
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
SummaryInformation
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
SummaryInformation
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
SummaryInformation
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
SummaryInformation
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
SummaryInformation
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
SummaryInformation
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00




Начнём разбор не пустых строк:
FE FF 00 00 05 00 02 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 01 00 00 00 E0 85 9F F2
F9 4F 68 10 AB 91 08 00 2B 27 B3 D9 30 00 00 00

B0 00 00 00 07 00 00 00 01 00 00 00 40 00 00 00
04 00 00 00 48 00 00 00 08 00 00 00 68 00 00 00
12 00 00 00 78 00 00 00 0C 00 00 00 90 00 00 00
0D 00 00 00 9C 00 00 00 13 00 00 00 A8 00 00 00

02 00 00 00 E3 04 00 00 1E 00 00 00 16 00 00 00
4D 69 63 72 6F 73 6F 66 74 20 43 6F 72 70 6F 72
61 74 69 6F 6E 00 00 00 1E 00 00 00 07 00 00 00
66 72 61 75 65 72 00 66 1E 00 00 00 10 00 00 00
4D 69 63 72 6F 73 6F 66 74 20 45 78 63 65 6C 00

40 00 00 00 80 BE B5 FA 70 B5 BB 01 40 00 00 00
00 64 31 B2 A0 BE C0 01 03 00 00 00 00 00 00 00

Здесь заголовок всегда 48 байт. Он очень похож на заголовок из DocumentSummaryInformation
и отличается только опознавателем подпотока.

FE FF - перевёрнутый порядок расположения байтов в потоке(FFFE-прямой порядок).
00 00 - версия подпотока свойств(propertySet substream).
05 - старшая версия операционной системы создавшая этот компаунд фаил.
00 - младшая версия операционной системы создавшая этот компаунд фаил.
02 00 - тип операционной системы(это значение неизменно).
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - идентификатор приложения(это значение неизменно).
01 00 00 00-сколько подпотоков содержит этот поток(DocumentSummaryInformation),
это значение неизвестно, т.к подпоток здесь всегда один.
E0 85 9F F2 F9 4F 68 10 AB 91 08 00 2B 27 B3 D9 - опознаватель подпотока PropertySet stream(значение постоянно)
30 00 00 00 - смещение подпотока PropertySet stream в этом потоке(DocumentSummaryInformation).


;;;;;;;;;;подпоток PropertySet stream;;;;;;;;;;;;;;;;;;;;;;;;;


Восемь байт своего заголовка:
----------------------


B0 00 00 00- указывает что подпоток кончается по смещению 176десятичное
от начала подпотока PropertySet stream, а если вы хотите вычислить
смещение в потоке SummaryInformation, то
смещение_в_потоке=количество_байт_в_заго ловке+смещение в PropertySet stream
т.е 176+48=224байт будет занимать PropertySet stream
07 00 00 00-указывает что в подпотоке 7 свойств(счёт от единицы).
7 свойств означает что далее следуют 7 восьмибайтовых указателей, а
за ними сами 7 свойств разного размера.
(максимальное количество существующих свойств в SummaryInformation
исчисляется 22мя(включая специальные), согласно документу ms-oleps).
0
 Аватар для Estimable
195 / 14 / 1
Регистрация: 02.01.2017
Сообщений: 223
19.01.2019, 09:19
Указатели на свойства:
-----------------------

УКАЗАТЕЛЬ НА ПЕРВОЕ СВОЙСТВО
находится по смещению 40h от начала PropertySet Stream
v v v v
01 00 00 00 40 00 00 00
^ ^ ^ ^
свойство PIDDSI_CODEPAGE



УКАЗАТЕЛЬ НА ВТОРОЕ СВОЙСТВО
находится по смещению 48h от начала PropertySet Stream
v v v v
04 00 00 00 48 00 00 00
^ ^ ^ ^
свойство PIDSI_AUTHOR



УКАЗАТЕЛЬ НА ТРЕТЬЕ СВОЙСТВО
находится по смещению 68h от начала PropertySet Stream
v v v v
08 00 00 00 68 00 00 00
^ ^ ^ ^
свойство PIDSI_LASTAUTHOR



УКАЗАТЕЛЬ НА ЧЕТВЁРТОЕ СВОЙСТВО
находится по смещению 78h от начала PropertySet Stream
v v v v
12 00 00 00 78 00 00 00
^ ^ ^ ^
свойство PIDSI_APPNAME


УКАЗАТЕЛЬ НА ПЯТОЕ СВОЙСТВО
находится по смещению 90h от начала PropertySet Stream
v v v v
0C 00 00 00 90 00 00 00
^ ^ ^ ^
свойство PIDSI_CREATE_DTM


УКАЗАТЕЛЬ НА ШЕСТОЕ СВОЙСТВО
находится по смещению 9Сh от начала PropertySet Stream
v v v v
0D 00 00 00 9C 00 00 00
^ ^ ^ ^
свойство PIDSI_LASTSAVE_DTM


УКАЗАТЕЛЬ НА СЕДЬМОЕ СВОЙСТВО
находится по смещению A8h от начала PropertySet Stream
v v v v
13 00 00 00 A8 00 00 00
^ ^ ^ ^
свойство PIDSI_DOC_SECURITY


Сами свойства:
----------------
ПЕРВОЕ СВОЙСТВО это PIDDSI_CODEPAGE
и оно находится по смещению 40h или 64дес байт
от начала подпотока PropertySet Stream.
Сколько байт оно занимает можно узнать
отняв смещение в первом указателе от
смещения во втором указателе:48h-40h=8h(8дес)
т.е восемь байт:
02 00 00 00 E3 04 00 00(48h-40h=8байт)
+ + ! ! * * ^ ^
+ + ! ! * * два байта не используются
+ + ! ! сама кодировка.здесь 04e3h=1251дес. Т.е Windows ansi 1251, это простая однобайтовая кодировка ansi.
+ + набивка типа данных до 4х байт
тип данных:0002 это Integer(двухбайтовое беззнаковое)

Надо сказать что оно в точности повторяет свойство GKPIDDSI_CODEPAGE в потоке documentsummaryinformation





ВТОРОЕ СВОЙСТВО это PIDSI_AUTHOR
и оно находится по смещению 48h или 72дес байт
от начала подпотока PropertySet Stream.
Сколько байт оно занимает можно узнать
отняв смещение во втором указателе от
смещения в третьем указателе:68h-48h=20h(32дес)
т.е 32 байта:
1E 00 00 00 16 00 00 00 4D 69 63 72 6F 73 6F 66 74 20 43 6F 72 70 6F 72 61 74 69 6F 6E 00 00 00
+ + ! ! : : : : ^ #
+ + ! ! : : : : ^ один байта набивки до кратности 4м байтам
+ + ! ! : : : : Строка с надписью(Microsoft Corporation)
+ + ! ! поле количество байт в текстовой строке.
+ + набивка типа данных до 4х байт
тип данных:001E это текстовая строка в однобайтовой кодировке



ТРЕТЬЕ СВОЙСТВО это PIDSI_LASTAUTHOR
и оно находится по смещению 68h или 104дес байт
от начала подпотока PropertySet Stream.
Сколько байт оно занимает можно узнать
отняв смещение в третьем указателе от
смещения в четвёртом указателе:78h-68h=10h(16дес)
т.е 16 байт:
1E 00 00 00 07 00 00 00 66 72 61 75 65 72 00 66
+ + ! ! : : : : ^ ^
+ + ! ! : : : : ^ 0 байт набивки до кратности 4м байтам
+ + ! ! : : : : Строка с надписью(frauer f)
+ + ! ! поле количество байт в текстовой строке.
+ + набивка типа данных до 4х байт
тип данных:001E это текстовая строка в однобайтовой кодировке

ЧЕТВЁРТОЕ СВОЙСТВО это PIDSI_APPNAME
и оно находится по смещению 78h или 120дес байт
от начала подпотока PropertySet Stream.
Сколько байт оно занимает можно узнать
отняв смещение в четвёртом указателе от
смещения в пятом указателе:90h-78h=18h(24дес)
т.е 24 байта:
1E 00 00 00 10 00 00 00 4D 69 63 72 6F 73 6F 66 74 20 45 78 63 65 6C 00
+ + ! ! : : : : ^ ^
+ + ! ! : : : : ^ 0 байт набивки до кратности 4м байтам
+ + ! ! : : : : Строка с надписью(Microsoft Excel)
+ + ! ! поле количество байт в текстовой строке.
+ + набивка типа данных до 4х байт
тип данных:001E это текстовая строка в однобайтовой кодировке




ПЯТОЕ СВОЙСТВО это PIDSI_CREATE_DTM
и оно находится по смещению 90h или 144дес байт
от начала подпотока PropertySet Stream.
Сколько байт оно занимает можно узнать
отняв смещение в пятом указателе от
смещения в шестом указателе:9Сh-90h=0Сh(12дес)
т.е 12 байт:
40 00 00 00 80 BE B5 FA 70 B5 BB 01
+ + ! ! : : : : : : : :
+ + ! ! само время
+ + набивка типа данных до 4х байт
тип данных:4000 это файловое время(как высчитывается время сказано в докум. MS-DTYP, оно немного
отличается стартовой точкой отсчёта от того что используется в таблице директорий, но алгоритм
должен быть похожим).



ШЕСТОЕ СВОЙСТВО СВОЙСТВО это PIDSI_LASTSAVE_DTM
и оно находится по смещению 9Ch или 156дес байт
от начала подпотока PropertySet Stream.
Сколько байт оно занимает можно узнать
отняв смещение в шестом указателе от
смещения в седьмом указателе:A8h-9Ch=0Сh(12дес)
т.е 12 байт:
40 00 00 00 00 64 31 B2 A0 BE C0 01
+ + ! ! : : : : : : : :
+ + ! ! само время
+ + набивка типа данных до 4х байт
тип данных:4000 это файловое время


СЕДЬМОЕ СВОЙСТВО это PIDSI_DOC_SECURITY
Так как он последний элемент в подпотоке PropertySet Stream и
после него нет свойств, то его размер высчитывается исходя из общего размера
подпотока. Мы его вытащили из маленького заголовка PropertySet Stream.
Размер подпотока = B0 00 00 00. Отсюда:
размер последнего свойства=размер подпотока-смещение последнего свойства в подпотоке т.е
B0H-A8H=8h т.е 8байт:
03 00 00 00 00 00 00 00
+ + ! ! : : : :
+ + ! ! битовые флаги защиты установленные создавшим этот документ приложением, могут употреблятся в комбинациях
+ + ! ! 00000001h - Защищено паролем,00000002h-только чтение(рекомендуется),
+ + ! ! 00000004h - только чтение(ставится принудительно),00000008h - описание запрещено
+ + ! ! 00000000h - ничего не запрещено
+ + набивка типа данных до 4х байт
тип данных:0003 это Long(четырёх байтовое беззнаковое)


далее за этими свойствами документ дополняется нулевыми байтами до 4096.
Помните что это необязательно. Для нас это даже полезно т.к даёт нам пространство для
экспериментов.


Приведу cписок свойств которые могут присутствовать в подпотоке property set.
Это выписка из документа MS-OLEPS.
0
 Аватар для Estimable
195 / 14 / 1
Регистрация: 02.01.2017
Сообщений: 223
19.01.2019, 09:20
________________________________________ ________________________________________ ________________________________________ ________________________________
|Свойства для подпотока property set в потоке SummaryInformation определены в нижеприведённой таблице.Допускается использование любого свойства |
|в подпотоке, включая специальные свойства: Dictionary,CodePage,Locale,Behavior.Они помечены звёздочкой |
|-------------------------------------------------------------------------------------------------------------------------------------------------------|
|Имя свойства Опознаватель Размер Описание |
|-------------------------------------------------------------------------------------------------------------------------------------------------------|
|*BEHAVIOR 80000003h 2б(тип:0013)+2б(набивка:0000) 4х байтовое значение представляет режим задания имён свойств в |
| +4б(целое беззнаковое значение) в свойстве dictionary. Здесь всего два значения: |
| 00000000-регистр букв имени свойств безразличен |
| 00000001-регистр букв имени свойств имеет важное значение. |
|-------------------------------------------------------------------------------------------------------------------------------------------------------|
|*LOCALE 80000000h 2б(тип:0013)+2б(набивка:0000) 4х байтовое значение представляет код языка. Коды представлены |
| +4б(целое беззнаковое значение) в документе [MS-LCID]. Скорее всего одни двух байтовые+ |
| +2х байтовая набивка 0000. |
|-------------------------------------------------------------------------------------------------------------------------------------------------------|
|*DICTIONARY 00000000h 4б(целое число отображ кол-во входов) Точно такое же свойство как в |
| +для каждого входа: documentsummaryinformation->userdefinedpropertysetstream. |
| Назначение своих придуманных свойств, используя свободные |
| 4б(идентификатор свойства) опознаватели.Здесь их гораздо меньше, т.е те которые не входят |
| +4б(длинна имени свойства в символах в эту таблицу. |
| вместе со стопорным 00) Строка имени почти всегда однобайтовая, кроме свойства codepage,|
| +строка имени свойства в двух там двухбайтовая. |
| или однобайт кодировке(разн размера) |
| +стопорный 00(или 0000 для unicode) |
| |
| +набивка до кратности 4м байтам |
|-------------------------------------------------------------------------------------------------------------------------------------------------------|
|*CODEPAGE 00000001h 2б(тип:0002)+2б(набивка:0000) В документе указана непонятная ссылка |
| +2б(код страница)+2б(набивка:0000) go.microsoft.com/fwlink/?LinkId=89840 |
| ,но похоже что это те же кодировки что |
| и на странице 145 в документе excelefileformat |
|-------------------------------------------------------------------------------------------------------------------------------------------------------|
|PIDSI_TITLE 00000002h 2б(тип:001E)+2б(набивка:0000) строка в однобайтовой кодировке содержащая имя документа. |
| +строка(4б колво символов+сама строка |
| +набивка до кратн 4 байтам) |
|-------------------------------------------------------------------------------------------------------------------------------------------------------|
|PIDSI_SUBJECT 00000003h 2б(тип:001E)+2б(набивка:0000) строка в однобайтовой кодировке содержащая тему документа. |
| +строка(4б колво символов+сама строка |
| +набивка до кратн 4 байтам) |
|-------------------------------------------------------------------------------------------------------------------------------------------------------|
|PIDSI_AUTHOR 00000004h 2б(тип:001E)+2б(набивка:0000) строка в однобайтовой кодировке содержащая имя автора документа.|
| +строка(4б колво символов+сама строка |
| +набивка до кратн 4 байтам) |
|-------------------------------------------------------------------------------------------------------------------------------------------------------|
|PIDSI_KEYWORDS 00000005h 2б(тип:001E)+2б(набивка:0000) строка в однобайтовой кодировке содержащая |
| +строка(4б колво символов+сама строка ключевые слова относящиеся к документу(типа хэштеги) |
| +набивка до кратн 4 байтам) |
|-------------------------------------------------------------------------------------------------------------------------------------------------------|
|PIDSI_COMMENTS 00000006h 2б(тип:001E)+2б(набивка:0000) строка в однобайтовой кодировке содержащая |
| +строка(4б колво символов+сама строка комментарии относящиеся к документу. |
| +набивка до кратн 4 байтам) |
|-------------------------------------------------------------------------------------------------------------------------------------------------------|
|PIDSI_TEMPLATE 00000007h 2б(тип:001E)+2б(набивка:0000) строка в однобайтовой кодировке содержащая |
| +строка(4б колво символов+сама строка имя шаблона с которого создавался документ. |
| +набивка до кратн 4 байтам) (в каждой программе должны быть свои специфические шаблоны) |
|-------------------------------------------------------------------------------------------------------------------------------------------------------|
|PIDSI_LASTAUTHOR 00000008h 2б(тип:001E)+2б(набивка:0000) строка в однобайтовой кодировке содержащая |
| +строка(4б колво символов+сама строка имя прошлого автора документа. |
| +набивка до кратн 4 байтам) |
|-------------------------------------------------------------------------------------------------------------------------------------------------------|
|PIDSI_REVNUMBER 00000009h 2б(тип:001E)+2б(набивка:0000) номер ревизии этой версии документа |
| +строка(4б колво символов+сама строка (в каждой программе должны быть свои номера ревизий) |
| +набивка до кратн 4 байтам) |
|-------------------------------------------------------------------------------------------------------------------------------------------------------|
|PIDSI_EDITTIME 0000000Ah 2б(тип:0040)+2б(набивка:0000) Данные содержащие время и дату последней модификации документа. |
| +8байтное беззнаковое целое |
| |
|-------------------------------------------------------------------------------------------------------------------------------------------------------|
|PIDSI_LASTPRINTED 0000000Bh 2б(тип:0040)+2б(набивка:0000) Данные содержащие время и дату последней распечатки документа. |
| +8байтное беззнаковое целое |
| |
|-------------------------------------------------------------------------------------------------------------------------------------------------------|
|PIDSI_CREATE_DTM 0000000Ch 2б(тип:0040)+2б(набивка:0000) Данные содержащие время и дату создания документа. |
| +8байтное беззнаковое целое |
| |
|-------------------------------------------------------------------------------------------------------------------------------------------------------|
|PIDSI_LASTSAVE_DTM 0000000Dh 2б(тип:0040)+2б(набивка:0000) Данные содержащие время и дату последнего сохранения документа. |
| +8байтное беззнаковое целое |
| |
|-------------------------------------------------------------------------------------------------------------------------------------------------------|
|PIDSI_PAGECOUNT 0000000Eh 2б(тип:0003)+2б(набивка:0000) Количество страниц в документе. |
| +4б(целое знаковое значение) |
|-------------------------------------------------------------------------------------------------------------------------------------------------------|
|PIDSI_WORDCOUNT 0000000Fh 2б(тип:0003)+2б(набивка:0000) Количество слов в документе. |
| +4б(целое знаковое значение) |
|-------------------------------------------------------------------------------------------------------------------------------------------------------|
|PIDSI_CHARCOUNT 00000010h 2б(тип:0003)+2б(набивка:0000) Количество символов в документе(наверное включая пробел |
| +4б(целое знаковое значение) и не печатные символы). |
|-------------------------------------------------------------------------------------------------------------------------------------------------------|
|PIDSI_THUMBNAIL 00000011h 2б(тип:0047)+2б(набивка:0000) Приложениезависимый тип данных буфера обмена представл части |
| +4б(размер поля формат и данные) содержимого документа. |
| +4б(приложениезависимыйформатданных) |
| +4б(данные разного размера) |
| +набивка нолями до кратности 4м байтам |
|-------------------------------------------------------------------------------------------------------------------------------------------------------|
|PIDSI_APPNAME 00000012h 2б(тип:001E)+2б(набивка:0000) Имя приложения в котором был создан этот документ |
| +строка(4б колво символов+сама строка |
| +набивка до кратн 4 байтам) |
|-------------------------------------------------------------------------------------------------------------------------------------------------------|
|PIDSI_DOC_SECURITY 00000013h 2б(тип:0003)+2б(набивка:0000) битовые флаги защиты установленные создавшим этот документ |
| +4б(целое знаковое значение) приложением, могут употреблятся в комбинациях |
| 00000001h - Защищено паролем, |
| 00000002h-только чтение(рекомендуется), |
| 00000004h - только чтение(ставится принудительно), |
| 00000008h - описание запрещено |
| 00000000h - ничего не запрещено |
|-------------------------------------------------------------------------------------------------------------------------------------------------------|

В заключение этого материала, приведу вам описание заголовка компаунд файла. Я его оставил на
потом, т.к не хотел перегружать вас излишними подробностями с самого начала.
________________________________________ ________________________________________ ________________________________
|__Смещение__|______Размер______|_______ _____________________Значение___________ _________________________________|
| 0 | 8байт |Подпись компаунд файла D0 CF 11 E0 A1 B1 1A E1 |
| 8 | 16байт |Уникальный идентификатор этого файла(не представляет интереса и может быть=0) |
| 24 | 2байта |Номер версии компаунд файла(часто равен 003E) |
| 26 | 2байта |Номер версии формата файла(м.б.excel,access),(часто равен 0003) |
| 28 | 2байта |Очерёдность размещения байтов(FEFF - задом наперёд Intel, FFFE - прямой IBM 360)|
| 30 | 2байта |Размер сектора в компаунд файле ввиде степени двойки(стд), |
| | | стд 7 |
| | |размер сектора=2 байт. Минимальное значение равно 7, т.е 2 =128байт, |
| | | 9 |
| | |часто используется 9я степень, т.е 2 =512 |
| 32 | 2байта |Размер укороченных секторов в контейнере коротких потоков, представлен в виде |
| | |степени двойки.Максимальный размер здесь соответствует установленному размеру |
| | |обычного сектора. Но чаще используется значение 6 т.е |
| | | 6 |
| | | 2 = 64 байта. |
| 34 | 10байт |Не используются. |
| 44 | 4байта |Общий размер секторов используемый в таблице номеров секторов(SAT). |
| 48 | 4байта |Номер первого сектора ПОТОКА содержащего таблицу директорий. |
| 52 | 4байта |Не используются |
| 56 | 4байта |Минимальный размер стандартного ПОТОКА в байтах (минимальный и часто |
| | |используемый = 4096, если поток меньше 4096 байт значение сохраняется в |
| | |коротком потоке).(помните, что значения шестнадцатеричные т.е 4096 это 1000h) |
| 60 | 4байта |Номер первого сектора в таблице номеров коротких секторов |
| | |Или -2 (концовка цепочки секторов,если коротких секторов нет). |
| 64 | 4байта |Общее количество секторов используемое в таблице номеров коротких секторов |
| 68 | 4байта |номер первого сектора в таблице_таблицы номеров или -2 если |
| | |не используется дополнительных секторов. |
| 72 | 4байта |Общее количество секторов используемое в таблице_таблицы номеров |
| 76 | 436байт |Первая часть таблицы_таблицы номеров содержащая 109 номеров |
-----------------------------------------------------------------------------------------------------------------

Вот и всё. Часть информации я привёл довольно поверхностно особенно о подпотоке userdefinedpropertysetStream в
потоке documentsummaryinformation. Эта информация дана просто для сводки. При декомпиляции xls документов мне
не разу не встречался этот подпоток. Хотя всякое может быть.

Чтобы начать создавать потоки а потом их упаковать в компаунд фаил мы должны занятся экспериментами
в этом нам помогут xls декомпилятор, любой hex редактор и патчер(желательно ips формата, тк его
проще понимать).






О декомпиляторе. Нужен чтобы понять примерную структуру компаунд файла xls. Показать в нём строение
4х таблиц:Msat(расположена вертикально в столбце A, c 25й строки вниз), Sat(столбцы с C по J , каждый
сектор расположен рядом с номером Msat, который его открывает),Ssat если она существует(столбцы с L по S,
каждый сектор расположен рядом с номером Sat, который её открывает),Directory(столбцы с T по V,каждый сектор
расположен в одной строке с номером Sat, который её открывает),потоки(столбец W по IV, в трёх потоках
распознаются записи - это workbook,summaryinformation и documentsummaryinformation(включая подпоток
userdefinedproperty stream)). Практически у каждого номера, а в потоках и у каждого байта
проставлены файловые смещения и вы можете проверить информацию, используя эти смещения в hex редакторе.

Декомпилятор довольно медленный. Поэтому добавлена возможность отключать просмотр и распознавание
потоков. В этом режиме вам будет доступен только просмотр таблиц,которые есть в файле.
Эта функция работает при нажатии на флажок в ячейке B2.






Чтобы просмотреть его работу декомпилятора - создайте небольшой фаил xls и откройте его в декомпиляторе.
Либо просмотрите в нём приложенные файлы:Пустой.xls,Пустой VBA.xls,Несколько Msat.xls(находится в отдельном
архиве т.к имеет размер 6мегабайт).
Вложения
Тип файла: zip XLS_Decompiler4.zip (301.8 Кб, 6 просмотров)
Тип файла: zip несколько мсат.zip (6.96 Мб, 3 просмотров)
0
 Аватар для Estimable
195 / 14 / 1
Регистрация: 02.01.2017
Сообщений: 223
19.01.2019, 09:25
тут вся статья сместилась(незнаю какая проблема у этого форума) и поэтому я приложил копью этой статьи в файле xls_decompiler4.zip
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
19.01.2019, 09:25

Как подружить юниты
Добрый день. Учить с++ начал относительно недавно. Создал уже простенький тетрис на сдандартных формах. Чтобы двигаться дальше, надо...

Как подружить Qt с VS2012?
Как побороть ? Делал всё по инструкции на хабре, но при запуске VS получаю :

Как подружить VB и Exel?
Есть вот такая вещь!!! Option Explicit Dim objExcel As Excel.Application Dim objBook As Excel.Workbook Dim objSheet As...

Как подружить Qt и Objective-C
Доброе время суток, уважаемые форумчане. Создал тему сию в разделе по Objective-C, но, к сожалению, ответа пока не дождался... Возможно,...

Как подружить C++ и SQL
Много написано на тему как подружить SQL и C++. Скачиваешь амальгаму и оттуда берешь два файла: sqlite.h и sqlite.c Всё классно, но...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Про "Windows must die!"
kumehtar 04.11.2026
Знаете, чет накатило. . . . Когда-то это было почти боевым кличем: мол, нормальный человек сидит на DOS, OS/ 2 или Linux, а вот это вот - Must Die. А теперь человек произносит «мастдай» с усмешкой - и. . .
Красочные поля с номером страницы svg+background-image
russiannick 04.11.2026
Красочные поля с номером страницы не менее важны чем в эпоху бумажных книг. Посему спешу представить почтеннейшей публике этот важный инструмент который эти поля и формирует. В процессе разработки. . .
Вступаем в новую фазу генерации favicons, векторную.
russiannick 02.11.2026
Теперь нет нужды скрывать что используется простой svg. Исходный код изображения помещаем в поле и жмем кнопку. Исходник преобразуется в вид корректный для помещения в favicon или в url(). Нажатие. . .
Генератор паролей (вариант №4)
Maks 01.11.2026
После публикации 3-го варианта генератора паролей, разослал его своим коллегам (с целью оценки), в итоге были получены следующие рекомендации: 1. Вернуть возможность использования знаков | 1 l I;. . .
Генератор паролей (вариант №3)
Maks 30.10.2026
Финальная версия генератора паролей 1С. Доработка решения в этот раз коснулась только визуальной части, а именно, добавлен реквизит ДопПараметры (тип Булево), который скрывает/ отображает реквизиты:. . .
Магическое мышление и магия, современная наука не отличима от магии (говорит ИИ Джемени)
zorxor 30.10.2026
Джемени, расскажи, пожалуйста, что такое магическое мышление, что такое магия, почему современная наука чем-то напоминает магию? Фраза «Любая достаточно развитая технология неотличима от магии». . .
За какое время ИИ может подобрать пароль по хешу (рассказывает Джемени ИИ)
zorxor 30.10.2026
Расскажи, Джемени, если известен хэш МД5, например, за сколько ИИ сможет подобрать соответствующий пароль? Искусственный интеллект (ИИ) может подобрать простой или средний по сложности пароль по. . .
Кто убил Suno? Почему наше солнышко погасло? (диалог с ИИ Джемени)
zorxor 30.10.2026
Как убивали Suno. Хронология. «Убийство» музыкальной нейросети Suno — это затяжной процесс, в котором технологический хайп стартапа разбился о жесткую реальность судебных исков от гигантов. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru