Здравствуйте. Читаю туториалы по ассемблеру, взятые с WASM-a. Автор рассказал о массиве структур IMAGE_DATA_DIRECTORY, который состоит из 16 элементов. Во-первых, немножко непонятно. Объявлено 16 элементов Код (ASM): DataDirectory IMAGE_DATA_DIRECTORY 16 dup(<>) А далее идёт табличка только с 15 элементами ПараметрИнформация0Символы экспоpта1Символы импорта2Ресурсы3Исключение4Безопасность5Base relocation6Отладка7Стpока копирайта8Unknown9Thread local storage (TLS)10Загрузочная информация11Bound Import12Таблица адресов импорта13Delay Import14COM descriptorИ на странице 294 самое интересное Код (ASM): mov edi,pNTHdr assume edi:ptr IMAGE_NT_HEADERS mov edi, [edi].OptionalHeader.DataDirectory[sizeof IMAGE_DATA_DIRECTORY].VirtualAddress Зачем здесь sizeof IMAGE_DATA_DIRECTORY К какому элементу массива структур мы обращаемся и почему? Если нам нужно получить VirtualAddress символов импорта, то почему бы просто не написать Код (ASM): mov edi, [edi].OptionalHeader.DataDirectory[1].VirtualAddress
16-й элемент IMAGE_DATA_DIRECTORY в массиве DataDirectory обычно "Reserved (unknown)" и он просто опущен
http://www.wasm.ru/ и вот тут находится: 13. Туториалы Iczelion'а для печати [Iczelion, обработал krutan] →
Так к какому элементу массива структур мы обращаемся и почему? Если нам нужно получить VirtualAddress символов импорта, то почему бы просто не написать mov edi, [edi].OptionalHeader.DataDirectory[1].VirtualAddress
Все просто, вот это выражение Код (ASM): mov edi, [edi].OptionalHeader.DataDirectory[1].VirtualAddress равносильно Код (ASM): mov edi, [edi].OptionalHeader.DataDirectory[sizeof IMAGE_DATA_DIRECTORY].VirtualAddress
Почему равносильно? разве IMAGE_DATA_DIRECTORY имеет размер 1 байт и результатом выполнения операции sizeof IMAGE_DATA_DIRECTORY будет 1? О_о Там же есть 2 поля VirtualAddress и isize, каждое из которых является переменной типа DWORD (DD) и это означает что результатом выполнения sizeof IMAGE_DATA_DIRECTORY должна стать 8 (4+4=8)
Это не один байт, это умножение на единицу, тобишь адресуеца вторая от единицы и первая от нуля структура в массиве. Причем содержимое данного элемента. Так то
Эту же мануалку читаю, написал всё как говорил автор, в итоге, в этих местах ошибки: Код (Text): .while !(([EDI].OriginalFirstThink == 0) && ([EDI].TimeDateStamp == 0) && ([EDI].ForwarderChain == 0) && ([EDI].Name1 == 0) && ([EDI].FirstThunk == 0)) invoke RVAToOffset, DD_adressOfMappingFile, EDI ;добавляем файловое смещение к указателю на мэппированный файл и получаем искомый RVA, ;который будет при загрузке файла PE-загрузчиком mov EDX, EAX add EDX, DD_adressOfMappingFile invoke wsprintf, offset strTemp_1, offset strIDTemplate, [EDI].OriginalFirstThunk, [EDI].TimeDateStamp, [EDI].ForwarderChain, EDX, [EDI].FirstThunk .endw вот такие вот ошибочки выдал MASM32: Код (Text): Microsoft Windows [Version 6.1.7600] (c) Корпорация Майкрософт (Microsoft Corp.), 2009. Все права защищены. C:\Users\Dimarik>cd c:/masm32/bin c:\masm32\bin>ml /c /coff PE_1.asm Microsoft (R) Macro Assembler Version 6.14.8444 Copyright (C) Microsoft Corp 1981-1997. All rights reserved. Assembling: PE_1.asm PE_1.asm(394) : error A2154: syntax error in control-flow directive PE_1.asm(395) : error A2008: syntax error : ( PE_1.asm(401) : error A2006: undefined symbol : FirstThunk PE_1.asm(401) : error A2114: INVOKE argument type mismatch : argument : 0 PE_1.asm(401) : error A2006: undefined symbol : ForwarderChain PE_1.asm(401) : error A2006: undefined symbol : TimeDateStamp PE_1.asm(401) : error A2006: undefined symbol : OriginalFirstThunk PE_1.asm(191) : error A2006: undefined symbol : PointertoRawData PE_1.asm(57) : error A2009: syntax error in expression c:\masm32\bin> строка 395 - это начало цикла как только я с этим .while не работал и так Код (Text): .while !([edi].OriginalFirstThunk==0 && [edi].TimeDateStamp==0 && [edi].ForwarderChain==0 && [edi].Name1==0 && [edi].FirstThunk==0) (как собственно, изначально предлагал автор) и даже так: Код (Text): .while ([EDI].OriginalFirstThink != 0) && ([EDI].TimeDateStamp != 0) && ([EDI].ForwarderChain != 0) && ([EDI].Name1 != 0) && ([EDI].FirstThunk != 0)) Результата никакого. Ещё непонятно, почему это в функции wsprintf ругается на [EDI].OriginalFirstThunk и т.п. Самое главное, в самом условии цикла - компилятор на эти переменные не ругался, а через несколько строк ошибку выдал. P.S. Хотелось бы эту проблему решить через .while без использования всяких там cmp, jnz и т.п. Вот полностью код http://zalil.ru/32439206 Заранее спасибо за советы.
assume EDI:ptr IMAGE_IMPORT_DESRIPTOR естественно, перед этим в EDI был записан Relative Virtual Address IMAGE_IMPORT_DESRIPTOR