Уроки Iczelion'а




Урок 6. Таблица импорта - часть 9


Анализ:

Программа показывает диалоговое окно открытия файла, когда пользователь выбирает Oрen в меню. Она проверяет, является ли файл верным PE и затем вызывает ShowTheFunctions.

ShowTheFunctions proc uses esi ecx ebx hDlg:DWORD, pNTHdr:DWORD LOCAL temp[512]:BYTE

Резервируем 512 байтов стэкового пространства для операций со строками.

invoke SetDlgItemText,hDlg,IDC_EDIT,0

Очищаем edit control

invoke AppendText,hDlg,addr buffer

Вставьте имя PE-файла в edit control. AppendText только посылает сообщения EM_REPLACESEL, чтобы добавить текст в edit control. Заметьте, что он посылает EM_SETSEL с wParam = -1 и lParam = 0 edit control'у, чтобы сдвинуть курсор к концу текста.

mov edi,pNTHdr assume edi:ptr IMAGE_NT_HEADERS mov edi, [edi].OptionalHeader.DataDirectory[sizeof IMAGE_DATA_DIRECTORY].VirtualAddress

Получаем RVA символов импорта. Сначала edi указывает на PE-заголовок. Мы используем его, чтобы перейти ко 2nd члену директории данных и получить значение параметра VirtualAddress.

invoke RVAToOffset,pMapping,edi mov edi,eax add edi,pMapping

Здесь скрывается одна из ловушек для новичков PE-программирования. Большинство из адресов в PE-файле - это RVA и RVA имеют значение только, когда загружены в память PE-загрузчиком. В нашем случае мы мэппируем файл в память, но не так, как это делает PE-загрузчик. Поэтому мы не можем напрямую использовать эти RVA. Каким-то образом мы должны конвертировать эти RVA в файловые смещения. Специально для этого я написал функцию RVAToOffset. Я не буду детально детально анализировать ее здесь. Достаточно сказать, что она проверяет сверяет данный RVA с RVA'ми началами и концами всех секций в PE-файле и использует значение в поле PointerToRawData из структуры IMAGE_SECTION_HEADER, чтобы сконвертировать RVA в файловое смещение.

Чтобы использовать эту функцию, вы передаете ей два параметра: указатель на мэппированный файл и RVA, которое вы хотите сконвертировать. Она возвращает в eax файловое смещение. В вышеприведенном отрывке кода мы должны добавить указатель на промэппированный файл к файловому оффсету, чтобы сконвертировать его в виртуальный адрес. Кажется сложным, не правда ли? :)




Содержание  Назад  Вперед