Глядя на kernel32.dll, как он будет загружен в память, я вижу следующее экспортное порядковое таблицу:Как `kernel32.dll` экспортирует порядковый номер 0, если для поля` OrdinalBase` установлено значение 1?
(gdb) x /400hd $eax
0x776334b0 <Wow64Transition+71576>: 3 4 5 6 7 8 9 10
0x776334c0 <Wow64Transition+71592>: 11 12 13 14 15 16 17 18
0x776334d0 <Wow64Transition+71608>: 19 20 21 22 23 24 25 26
0x776334e0 <Wow64Transition+71624>: 27 28 29 30 31 32 33 34
0x776334f0 <Wow64Transition+71640>: 35 36 37 38 39 40 41 42
0x77633500 <Wow64Transition+71656>: 43 44 45 46 47 48 49 50
0x77633510 <Wow64Transition+71672>: 51 52 53 54 55 56 57 58
0x77633520 <Wow64Transition+71688>: 59 60 61 62 63 64 65 66
0x77633530 <Wow64Transition+71704>: 67 68 69 70 0 71 72 73
0x77633540 <Wow64Transition+71720>: 74 75 76 77 78 79 80 81
0x77633550 <Wow64Transition+71736>: 82 83 84 85 86 87 88 89
0x77633560 <Wow64Transition+71752>: 90 91 92 93 94 95 96 97
Как можно проверить, порядковый 0 экспортируются.
Но учитывая, что OrdinalBase поле таблицы каталога экспорта устанавливаются в 1, как может порядковый быть меньше 1 ?:
Порядкового Основание: Исходный порядковый номер для экспорта в этом изображения. Это поле указывает начальный порядковый номер для таблицы адресов экспорта . Это, как правило, устанавливаются в 1.
В документации сказано, что порядковые пристрастны, т.е .:
Экспорта порядковая таблица представляет собой массив из 16-битовых индексов в таблицу адресов экспорта . Ординалы смещены с помощью поля «Оринальная база» таблицы каталога экспорта. Другими словами, порядковая база должна быть вычтена из ординалов, чтобы получить истинные индексы в таблице адресов экспорта .
Теперь это означает, что порядковый номер 0 порождает индекс -1 в таблицу экспортных адресов?
С моей точки зрения, похоже, ординалы предварительно скорректированы (т.е. 1 вычитается из каждого), а затем «официальный» алгоритм (также указывается в PE-документы) не:
Таким образом, когда таблица указателя имя экспорта ищется и соответствие строка найдена в позиции я, алгоритм для нахождения адреса символа является:
i = Search_ExportNamePointerTable (ExportName);
ordinal =
ExportOrdinalTable [i];
SymbolRVA = ExportAddressTable [ordinal - OrdinalBase];
Единственная мысль, которая приходит на ум, я s следующее: загрузчик скорректировал ординалы в пределах экспортной таблицы ордеров при загрузке DLL в память.
Может ли кто-нибудь дать объяснение?
А как насчет алгоритма в документации PE для поиска символа RVA? Тогда этот алгоритм некорректен? Он использует ординалы как часть поиска RVA. Кроме того, каковы числа в порядковой таблице, если не правильные ординалы (соответствующие тем, которые видны с использованием самосвала)? – Shuzheng
Кроме того, вы говорите, что запись 0 является порядковым номером 4, но почему она отображает 3? – Shuzheng
@HansPassant: Кроме того, почему 1 (OrdinalBase) вычитается из каждого порядкового номера?Если бы вы могли ответить на эти вопросы, вы бы сделали Рождество в начале этого года :) – Shuzheng