Комментарии 22
А чем Ваш мануал лучше того что написано на wasm.ru?
+3
При подаче материала я попытался объяснить всё более нагялядно, посредством абстраций, диаграмм и схем. Мне кажется, для первого знакомства как раз такая манера изложнения будет наиболее удачной, т.к. формирует в голове своего рода «картинку», которую легче воспринимать.
+4
Если из статьи слить воду и убрать «Сомалийские острова», ее можно сократить примерно втрое.
Кому действительно нужно писать свой парсер PE32 — обратите внимание на открытую реализацию в radare2.
Кому действительно нужно писать свой парсер PE32 — обратите внимание на открытую реализацию в radare2.
+12
x86 же.
0
А есть что-то похожее, только для elf?
+2
Для не-системщиков материал интересный, но ощущение что написан для детей.
+5
Если данная сигнатура не равна MZ, то файл не загрузится.Во времена DOS работала так же сигнатура ZM. Не знаю, работает ли одна до сих пор.
0
Нет, винда не даст такое запустить. Проверил на ХР-10.
Точно такое было? Может речь о проверке сигнатуры на 'ZM' ? для оптимизации часто делают что-то вида CMP WORD PTR [Тут адрес дос хидера], 'ZM' (т.к. ворды в памяти хранятся перевернутыми).
0
Точно, вот, посмотрите: https://ru.wikipedia.org/wiki/MZ_(формат)
0
Кажется не хватает про Relocation table.
0
+16
На самом деле статья описывает «идеальные» PE, точно соответствующие документации от MS. В «живой природе» обитает множество PE-шников, этой документации соответствующих лишь частично, но при этом работоспособных. Наиболее распространённый пример: OriginalFirstThunk == NULL (результат упаковки UPX-ом). Подобные случаи, пожалуй, наиболее интересны.
0
Сейчас читаю эту статью (освежить память по PE) — нашел ошибки.
Очевидно вместо первого вхождения SizeOfOptionalHeader должно быть NumberOfSymbols, а второе вхождение — дык вообще с опечатками: заменить «SIzeOfOptionHeader» на SizeOfOptionalHeader.
Какие 0x28 * 0x04 — очевидно же что 0x50 * 2 — выравнивание на то и выравнивание, что фиксирован размер блока и если 0x78 не влезает в 0x50 — процедура вычисления будет выглядеть на сишечке примерно (0x78 / 0x50 + 1) * 0x50. Откуда здесь всплыло 0x28 из первого примера неясно. Ошибка вводящая в заблуждение по поводу выравнивания имхо(особенно для неокрепших).
Дальше читаю. Если найду ещё — напишу…
TimeDateStamp: WORD — число хранящее дату и время создания файла.
PointerToSymbolTable: DWORD — смещение (RAW) до таблицы символов, а SizeOfOptionalHeader — это размер данной таблицы. Данная таблица призвана служить для хранения отладочной информации, но отряд не заметил потери бойца с самого начала службы. Чаще всего это поле зачищается нулями.
SIzeOfOptionHeader: WORD — размер опционального заголовка (что следует сразу за текущим) В документации указано, что для объектного файла он устанавливается в 0…
Очевидно вместо первого вхождения SizeOfOptionalHeader должно быть NumberOfSymbols, а второе вхождение — дык вообще с опечатками: заменить «SIzeOfOptionHeader» на SizeOfOptionalHeader.
Это происходит из-за размера выравнивания. 0x28 “не дотягивает” до 0x50 и как следствие, будет выгружена секция, а остальное пространство в размере 0x50-0x28 занулится. А если размер секции был бы больше размера выравнивания, то что? Например sectionSize = 0x78, а sectionAligment = 0x50, т.е. остался без изменений. В таком случае, секция занимала бы в памяти 0xA0 (0xA0 = 0x28 * 0x04) байт.
Какие 0x28 * 0x04 — очевидно же что 0x50 * 2 — выравнивание на то и выравнивание, что фиксирован размер блока и если 0x78 не влезает в 0x50 — процедура вычисления будет выглядеть на сишечке примерно (0x78 / 0x50 + 1) * 0x50. Откуда здесь всплыло 0x28 из первого примера неясно. Ошибка вводящая в заблуждение по поводу выравнивания имхо(особенно для неокрепших).
Дальше читаю. Если найду ещё — напишу…
0
RVA >= sectionVitualAddress && RVA < ALIGN_UP(sectionVirtualSize, sectionAligment)
опечатки
0
Внимание! Если вы взяли к примеру 2-ой элемент в таблице ординалов, это не значит 2 — это ординал для таблиц имён и адресов. Индексом является значение, хранящееся во втором элементе массива ординалов.
Вот это вообще непонятно что — в массиве ординалов хранятся ординалы, а не индексы! И ординал, который лежит в по индексу 2 будет однозначно соответствовать фции, которая лежит по индексу 2 с именем, которое лежит по индексу 2.
Количество значений в таблицах имён (NumberOfNames) и ординалов равны и не всегда совпадают с количеством элементов в таблице адресов (NumberOfFunctions).
Исходя из документации, которую Вы же и указали оно всегда совпадает…
DWORD NumberOfNames
The number of elements in the AddressOfNames array. This value seems always to be identical to the NumberOfFunctions field, and so is the number of exported functions.
И вот ещё:
To find all the information about the fourth function, you need to look up the fourth element in each array.
0
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
PE (Portable Executable): На странных берегах