Не знаю покажется ли это кому интересным, но все таки попробую спросить.
В прошлом году Viktor1703 выложил вот здесь http://autoit-script.ru/index.php/topic,9219.msg61749.html#msg61749 очень интересный код (за что большое ему спасибо
). По его прямому назначению я им пока не пользовался, но он мне очень здорово пригодился для моих попыток поизучать структуру исполняемого файла и получить данные разных PE заголовков.
Код Viktor'а1703 я слегка изменил под свои цели - (по большому счету все это, конечно, надо бы превратить в набор удобных и понятных функций и дополнить WinAPIEx.au3). В общем суть проблемы - с получением данных из IMAGE_FILE_HEADER и IMAGE_OPTIONAL_HEADER все нормально, а вот из IMAGE_SECTION_HEADER у меня читаются неверные данные (сравнивал с тем что выдает PE Explorer ). Хотелось бы разобраться, что там не так. Для меня все эти данные, как говорится "первый раз, в первый класс" - и многое пока туманно и непонятно. Например как получить строковое имя секции.
Под спойлером - интерпретация кода Viktor'а1703, моя там только серединка ReadDataStruct(), где данными структур заполняются массивы. Если кому то будет не трудно - просьба поизучать на досуге. Может еще кому сгодятся эти наработки.
-----------------------------------------------------------
Нашел ошибочку - забыл прибавить к адресу (переменная $iAddress) размер $tIMAGE_OPTIONAL_HEADER - из-за этого было неправильное смещение для чтения данных. Вот только значение параметра VirtualAddress не совпадает. Как то его видимо нужно изменять. И имя секции строкой бы еще получить.
В прошлом году Viktor1703 выложил вот здесь http://autoit-script.ru/index.php/topic,9219.msg61749.html#msg61749 очень интересный код (за что большое ему спасибо

Код Viktor'а1703 я слегка изменил под свои цели - (по большому счету все это, конечно, надо бы превратить в набор удобных и понятных функций и дополнить WinAPIEx.au3). В общем суть проблемы - с получением данных из IMAGE_FILE_HEADER и IMAGE_OPTIONAL_HEADER все нормально, а вот из IMAGE_SECTION_HEADER у меня читаются неверные данные (сравнивал с тем что выдает PE Explorer ). Хотелось бы разобраться, что там не так. Для меня все эти данные, как говорится "первый раз, в первый класс" - и многое пока туманно и непонятно. Например как получить строковое имя секции.
Под спойлером - интерпретация кода Viktor'а1703, моя там только серединка ReadDataStruct(), где данными структур заполняются массивы. Если кому то будет не трудно - просьба поизучать на досуге. Может еще кому сгодятся эти наработки.
Код:
#include <WinAPIEx.au3>
#include <WinAPI.au3>
#include <APIConstants.au3>
Global $tagIMAGE_DOS_HEADER = '' & _
'ushort magic;' & _ ;// Сигнатура заголовка
'ushort cblp;' & _ ;// количество байт на последней странице файла
'ushort cp;' & _ ;// количество страниц в файле
'ushort crlc;' & _ ;// Relocations
'ushort cparhdr;' & _ ;// Размер заголовка в параграфах
'ushort minalloc;' & _ ;// Минимальные дополнительные параграфы
'ushort maxalloc;' & _ ;// Максимальные дополнительные параграфы
'ushort ss;' & _ ;// начальное относительное значение регистра SS
'ushort sp;' & _ ;// начальное значение регистра SP
'ushort csum;' & _ ;// контрольная сумма
'ushort ip;' & _ ;// начальное значение регистра IP
'ushort cs;' & _ ;// начальное относительное значение регистра CS
'ushort lfarlc;' & _ ;// адрес в файле на таблицу переадресации
'ushort ovno;' & _ ;// количество оверлеев
'ushort res[4];' & _ ;// Зарезервировано
'ushort oemid;' & _ ;// OEM идентифкатор
'ushort oeminfo;' & _ ;// OEM информация
'ushort res2[10];' & _ ;// Зарезервировано
'dword lfanew' ;// адрес в файле нового .exe заголовка (PE)
Global $tagIMAGE_FILE_HEADER = '' & _
'ushort Machine;' & _ ;// Машина
'ushort NumberOfSections;' & _ ;// Колличество секторов
'dword TimeDateStamp;' & _ ;// Временной штамп
'dword PointerToSymbolTable;' & _ ;// Указатель на таблицу символов
'dword NumberOfSymbols;' & _ ;// Колличество символов
'ushort SizeOfOptionalHeader;' & _ ;// Размер дополнительного заголовка
'ushort Characteristics' ;// Характеристики
Global $tagIMAGE_OPTIONAL_HEADER = '' & _
'ushort Magic;' & _ ;// Тип файла
'ubyte MajorLinkerVersion;' & _ ;// Основной номер версии компоновщика
'ubyte MinorLinkerVersion;' & _ ;// Дополнительный номер версии компоновщика
'dword SizeOfCode;' & _ ;// Размер кода раздела, в байтах, или сумма всех таких участков, если есть несколько разделов кода.
'dword SizeOfInitializedData;' & _ ;// Размер инициализированных данных раздела, в байтах, или сумма всех таких участков, если есть несколько разделов инициализируется данными.
'dword SizeOfUninitializedData;' & _ ;// Размер неинициализированных данных раздела, в байтах, или сумма всех таких участков, если есть несколько неинициализированных данных разделов.
'dword AddressOfEntryPoint;' & _ ;// Указатель на точку входа
'dword BaseOfCode;' & _ ;// Указатель на начало секции кода
'dword BaseOfData;' & _ ;// Указатель на начало секции данных
'dword ImageBase;' & _ ;// Предпочтительный адрес первого байта изображения при загрузке в память. Это значение является кратной 64 байт. Значение по умолчанию для библиотек DLL 0x10000000. Значение по умолчанию для приложений 0x00400000, за исключением Windows CE, где 0x00010000.
'dword SectionAlignment;' & _ ;// Выравнивание разделов загруженых в память, в байтах (Должно быть больше или равна FileAlignment)
'dword FileAlignment;' & _ ;// Согласование исходных данных разделов в файл изображения в байтах.
'ushort MajorOperatingSystemVersion;' & _ ;// Основной номер версии необходимых операционной системы.
'ushort MinorOperatingSystemVersion;' & _ ;// Дополнительный номер версии необходимых операционной системы.
'ushort MajorImageVersion;' & _ ;// Основной номер версии изображения.
'ushort MinorImageVersion;' & _ ;// Младший номер версии изображения.
'ushort MajorSubsystemVersion;' & _ ;// Основной номер версии подсистемы.
'ushort MinorSubsystemVersion;' & _ ;// Дополнительный номер версии подсистемы.
'dword Win32VersionValue;' & _ ;// Зарезервирован и и должен быть 0.
'dword SizeOfImage;' & _ ;// Размер изображения в байтах, включая все заголовки. Должна быть кратна SectionAlignment.
'dword SizeOfHeaders;' & _ ;// Общий размер из пунктов, округляется до кратного значения, указанного в FileAlignment
'dword CheckSum;' & _ ;// Контрольная сумма файла изображения.
'ushort Subsystem;' & _ ;// Подсистемы, необходимые для запуска этого образа.
'ushort DllCharacteristics;' & _ ;// DLL характеристики изображения.
'dword SizeOfStackReserve;' & _ ;// Количество байт, резерв для стека.
'dword SizeOfStackCommit;' & _ ;// Количество байт для совершения в стеке.
'dword SizeOfHeapReserve;' & _ ;// Количество байт, резерв для локальной массы
'dword SizeOfHeapCommit;' & _ ;// Количество байт для совершения в локальной массе
'dword LoaderFlags;' & _ ;// Этот элемент является устаревшим.
'dword NumberOfRvaAndSizes;' & _ ;// Количество каталогов в оставшейся части дополнительного заголовка. Каждая запись описывает расположение и размер.
'byte byteData[128]' ;//
Global $tagIMAGE_SECTION_HEADER = '' & _
'byte Name[8];' & _ ;// Имя секции
'dword Misc;' & _ ;// PhysicalAddress, если файл является объектным, или VirtualSize, если файл является исполняемым
'dword VirtualAddress;' & _ ;// Виртуальный адрес
'dword SizeOfRawData;' & _ ;// Размер RAW данных
'dword PointerToRawData;' & _ ;// Указатель на RAW данные
'dword PointerToRelocations;' & _ ;// Указатель на релокейшены
'dword PointerToLinenumbers;' & _ ;// Указатель на номера строк
'ushort NumberOfRelocations;' & _ ;// Колличество релокейшенов
'ushort NumberOfLinenumbers;' & _ ;// Колличество номеров строк
'dword Characteristics' ;// Характеристики
; вот так вызываем: ReadDataStruct(@SystemDir &"\user32.dll", $tagIMAGE_FILE_HEADER, 1)
; $sFile - полный путь до файла exe или dll
; $sTagStruct - глобальная переменная структуры
; $iStruct - индекс для выбора структуры 1- $tIMAGE_FILE_HEADER, 2- $tIMAGE_OPTIONAL_HEADER, 3- $tIMAGE_SECTION_HEADER
Func ReadDataStruct($sFile, $sTagStruct, $iStruct)
Local $hFile,$iAddress,$Signature,$NumberOfSections,$tIMAGE_DOS_HEADER,$tIMAGE_FILE_HEADER,$tIMAGE_OPTIONAL_HEADER,$tIMAGE_SECTION_HEADER,$aStruct, $aReturn
$hFile = _WinAPI_CreateFile($sFile, 2, 2)
;$hFile = _WinAPI_CreateFileEx($sFile, $OPEN_EXISTING, $GENERIC_READ)
If @error Then
Return SetError(@error,-1, 0);@error=1|@extended=-1
ElseIf Not $hFile Then
Return SetError(-1 , -2, 0) ;@error=-1|@extended=-2
EndIf
$tIMAGE_DOS_HEADER = READ_IMAGE_DOS_HEADER($hFile, 0) ;~ Извлекаем структуры IMAGE_DOS_HEADER из исходного файла
$iAddress = DllStructGetData($tIMAGE_DOS_HEADER, 'lfanew') ;~ Достаём адрес таблицы
$Signature = READ_SIGNATURE($hFile, $iAddress) ;~ Извлекаем сигнатуру файла
If DllStructGetData($Signature, 'Signature') <> 0x00004550 And DllStructGetData($Signature, 'Signature') <> 0x50450000 Then ;~ проверяем, если сигнатура не равна PE то возвращаем ошибку
Return SetError(-2, 0, 0)
EndIf
$iAddress += DllStructGetSize($Signature) ;~ Прибавляем к адресу таблицы размер сигнатуры
$tIMAGE_FILE_HEADER = READ_IMAGE_FILE_HEADER($hFile, $iAddress) ;~ Заполняем структуру IMAGE_FILE_HEADER, считываем по адресу (Таблица + сигнатура)
$iAddress += DllStructGetSize($tIMAGE_FILE_HEADER) ;~ Прибавляем ((таблица + сигнатура) + размер IMAGE_FILE_HEADER)
$tIMAGE_OPTIONAL_HEADER = READ_IMAGE_OPTIONAL_HEADER($hFile, $iAddress) ;~ Заполняем структуру IMAGE_OPTIONAL_HEADER
; вот это забыл добавить - отсюда и неправильные данные
$iAddress += DllStructGetSize($tIMAGE_OPTIONAL_HEADER) ;~ Прибавляем размер структуры
$NumberOfSections = DllStructGetData($tIMAGE_FILE_HEADER, 'NumberOfSections') ;~ Возвращяем число секций
;==================================================================================
;возвращаем массив со значениями полей нужной структур
;==================================================================================
Select
;=============получаем параметры структуры IMAGE_FILE_HEADER========================
Case $iStruct = 1
$aStruct=GetNameParamsStruct($sTagStruct)
If Not IsArray($aStruct) Then Return SetError(-3,0,0)
Dim $aReturn[$aStruct[0]+1][2]
$aReturn[0][0]=$aStruct[0]
For $iIndex = 1 To $aStruct[0]
$iValue=DllStructGetData($tIMAGE_FILE_HEADER, $iIndex)
$aReturn[$iIndex][0]= $aStruct[$iIndex]; имя поля структуры
$aReturn[$iIndex][1]= $iValue ; значение поля
Next
;=============получаем параметры структуры IMAGE_OPTIONAL_HEADER=====================
Case $iStruct = 2
$aStruct=GetNameParamsStruct($sTagStruct)
If Not IsArray($aStruct) Then Return SetError(-3,0,0)
Dim $aReturn[$aStruct[0]+1][2]
$aReturn[0][0]=$aStruct[0]
For $iIndex = 1 To $aStruct[0]
$iValue=DllStructGetData($tIMAGE_OPTIONAL_HEADER, $iIndex)
$aReturn[$iIndex][0]= $aStruct[$iIndex]
$aReturn[$iIndex][1]= $iValue
Next
;=============получаем параметры структуры IMAGE_SECTION_HEADER=====================
; А вот здесь данные структуры возвращаются неверные
Case $iStruct = 3
$aStruct=GetNameParamsStruct($sTagStruct)
If Not IsArray($aStruct) Then Return SetError(-3,0,0)
; массив [число секций][число полей структуры]
Dim $aReturn[$NumberOfSections][$aStruct[0]]
For $iSection = 0 To $NumberOfSections-1
; крутим столько раз, сколько существует секций
$tIMAGE_SECTION_HEADER = READ_IMAGE_SECTION_HEADER($hFile, $iAddress)
For $iIndex = 0 To $aStruct[0]-1
$iValue=DllStructGetData($tIMAGE_SECTION_HEADER, $iIndex+1)
$aReturn[$iSection][$iIndex]= $iValue
Next
$iAddress += DllStructGetSize($tIMAGE_SECTION_HEADER)
Next
;===================================================================================
EndSelect
_WinAPI_CloseHandle($hFile)
Return $aReturn
EndFunc
Func READ_IMAGE_DOS_HEADER($hFile, $MovePos)
Local $nBytes, $tIMAGE_DOS_HEADER = DllStructCreate($tagIMAGE_DOS_HEADER)
_WinAPI_SetFilePointerEx($hFile, $MovePos)
_WinAPI_ReadFile($hFile, DllStructGetPtr($tIMAGE_DOS_HEADER), DllStructGetSize($tIMAGE_DOS_HEADER),$nBytes)
Return $tIMAGE_DOS_HEADER
EndFunc
Func READ_SIGNATURE($hFile, $MovePos)
Local $nBytes, $hSignature = DllStructCreate('dword Signature')
_WinAPI_SetFilePointerEx($hFile, $MovePos)
_WinAPI_ReadFile($hFile, DllStructGetPtr($hSignature), DllStructGetSize($hSignature), $nBytes)
Return $hSignature
EndFunc
Func READ_IMAGE_FILE_HEADER($hFile, $MovePos)
Local $nBytes, $tIMAGE_FILE_HEADER = DllStructCreate($tagIMAGE_FILE_HEADER)
_WinAPI_SetFilePointerEx($hFile, $MovePos)
_WinAPI_ReadFile($hFile, DllStructGetPtr($tIMAGE_FILE_HEADER), DllStructGetSize($tIMAGE_FILE_HEADER), $nBytes)
Return $tIMAGE_FILE_HEADER
EndFunc
Func READ_IMAGE_OPTIONAL_HEADER($hFile, $MovePos)
Local $nBytes, $tIMAGE_OPTIONAL_HEADER = DllStructCreate($tagIMAGE_OPTIONAL_HEADER)
_WinAPI_SetFilePointerEx($hFile, $MovePos)
_WinAPI_ReadFile($hFile, DllStructGetPtr($tIMAGE_OPTIONAL_HEADER), DllStructGetSize($tIMAGE_OPTIONAL_HEADER), $nBytes)
Return $tIMAGE_OPTIONAL_HEADER
EndFunc
Func READ_IMAGE_SECTION_HEADER($hFile, $MovePos)
Local $nBytes, $tIMAGE_SECTION_HEADER = DllStructCreate($tagIMAGE_SECTION_HEADER)
_WinAPI_SetFilePointerEx($hFile, $MovePos)
_WinAPI_ReadFile($hFile, DllStructGetPtr($tIMAGE_SECTION_HEADER), DllStructGetSize($tIMAGE_SECTION_HEADER),$nBytes)
Return $tIMAGE_SECTION_HEADER
EndFunc
; функция для получения имен параметров структуры из строки ее tag объявления
Func GetNameParamsStruct($sStruct,$iStart=1,$iEnd=-1)
Local $aParams, $aNames, $aRet
$aParams = StringSplit($sStruct,";")
If $iEnd=-1 Then $iEnd = $aParams[0]
Dim $aNames[$aParams[0]+1]
$aNames[0] = $aParams[0]
For $i=$iStart To $iEnd
$aRet=StringSplit($aParams[$i],' ',2)
$aNames[$i]=$aRet[1]
Next
Return $aNames
EndFunc
-----------------------------------------------------------
Нашел ошибочку - забыл прибавить к адресу (переменная $iAddress) размер $tIMAGE_OPTIONAL_HEADER - из-за этого было неправильное смещение для чтения данных. Вот только значение параметра VirtualAddress не совпадает. Как то его видимо нужно изменять. И имя секции строкой бы еще получить.