Что нового

Прочитать данные API структуры IMAGE_SECTION_HEADER

erlik

Продвинутый
Сообщения
317
Репутация
84
Не знаю покажется ли это кому интересным, но все таки попробую спросить.
В прошлом году Viktor1703 выложил вот здесь http://autoit-script.ru/index.php/topic,9219.msg61749.html#msg61749 очень интересный код (за что большое ему спасибо :ok:). По его прямому назначению я им пока не пользовался, но он мне очень здорово пригодился для моих попыток поизучать структуру исполняемого файла и получить данные разных PE заголовков.
Код 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 не совпадает. Как то его видимо нужно изменять. И имя секции строкой бы еще получить.
 

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
erlik
Я так понял Вам нужно получить данные о секции в PE файле?

Имя секции
Указатель на данные
Размер данных
Виртуальный адрес
Виртуальный размер
Характеристика
 
Автор
E

erlik

Продвинутый
Сообщения
317
Репутация
84
Viktor1703
Да, точнее все 10 полей структуры IMAGE_SECTION_HEADER (тут теперь проблем нет). Ошибку я нашел и исправил (сам виноват - недоглядел). С VirtualAddress тоже разобрался - нужно к нему еще ImageBase из IMAGE_OPTIONAL_HEADER прибавлять - тогда все точно выходит. Осталось только строковые имена секций получить. уфф...
---------------
...И тут меня спас
Код:
BinaryToString()
. :IL_AutoIt_1: В общем чего хотел - почти сделал. :smile: Всем спасибо.
 

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Код:
#Include <WinAPIEx.au3>
#Include <APIConstants.au3>

GetInfo('Filename.exe')


Func GetInfo($sFile)
    Local $hFile = _WinAPI_CreateFile($sFile, 2, 2)
    If (@error) Or (Not $hFile) Then
        Return SetError(-1, 0, 0)
    EndIf
    $IMAGE_DOS_HEADER = READ_IMAGE_DOS_HEADER($hFile, 0) ;~ Извлекаем структуры IMAGE_DOS_HEADER из исходного файла
    $iAddress = DllStructGetData($IMAGE_DOS_HEADER, 'lfanew') ;~ Достаём адрес таблицы
    $Signature = READ_SIGNATURE($hFile, $iAddress) ;~ Извлекаем сигнатуру файла
    If DllStructGetData($Signature, 'Signature') <> 0x00004550 And DllStructGetData($Signature, 'Signature') <> 0x50450000 Then ;~ проверяем, если сигнатура не равна PE то возвращаем ошибку
        Return SetError(-3, 0, 0)
    EndIf
    $iAddress += DllStructGetSize($Signature) ;~ Прибавляем к адресу таблицы размер сигнатуры
    $IMAGE_FILE_HEADER = READ_IMAGE_FILE_HEADER($hFile, $iAddress) ;~ Заполняем структуру IMAGE_FILE_HEADER, считываем по адресу (Таблица + сигнатура)
    $iAddress += DllStructGetSize($IMAGE_FILE_HEADER) ;~ Прибавляем ((таблица + сигнатура) + размер IMAGE_FILE_HEADER)
    $IMAGE_OPTIONAL_HEADER = READ_IMAGE_OPTIONAL_HEADER($hFile, $iAddress) ;~ Заполняем структуру IMAGE_OPTIONAL_HEADER
    If DllStructGetData($IMAGE_OPTIONAL_HEADER, 'Magic') <> 0x10b And DllStructGetData($IMAGE_OPTIONAL_HEADER, 'Magic') <> 0x20b Then ;~ Проверяем магическое число, если 0x10b и 0x20b то файл является исполняемым
        Return SetError(-4, 0, 0)
    EndIf
    $NumberOfSections = DllStructGetData($IMAGE_FILE_HEADER, 'NumberOfSections') ;~ Возвращяем число секций
    $iAddress += DllStructGetSize($IMAGE_OPTIONAL_HEADER) ;~ Прибавляем размер структуры
    $SizeOfHeaders = DllStructGetData($IMAGE_OPTIONAL_HEADER, 'SizeOfHeaders') ;~ Размер заголовка
    ;SizeOf IMAGE_SECTION_HEADER ==> 40
    $RemainderSize = $SizeOfHeaders - ($iAddress + $NumberOfSections * 40) ;~ Размер заголовка - (адресс + колличество секций и * на размер IMAGE_SECTION_HEADER = ( 40 ))
    $DataPos = ($iAddress + $NumberOfSections * 40)
    $DataStruct = READ_DATA($hFile, $DataPos, $RemainderSize) ;~ Считываем данные
    For $i = 1 To $NumberOfSections
        ;~ Пишется столько раз, сколько существует секций
        $IMAGE_SECTION_HEADER = READ_IMAGE_SECTION_HEADER($hFile, $iAddress) ;~ Считываем IMAGE_SECTION_HEADER из файла
		$Name = DllStructGetData($IMAGE_SECTION_HEADER, 'Name') ;~ Имя секции.
		$VirtualSize = DllStructGetData($IMAGE_SECTION_HEADER, 'Misc')
		$VirtualAddress = DllStructGetData($IMAGE_SECTION_HEADER, 'VirtualAddress') ;~ Адрес первого байта раздела при загрузке в память
		$SizeOfRawData = DllStructGetData($IMAGE_SECTION_HEADER, 'SizeOfRawData') ;~ Размер инициализированных данных на диске в байтах.
        $PointerToRawData = DllStructGetData($IMAGE_SECTION_HEADER, 'PointerToRawData') ;~ Указатель на первую страницу в файл COFF.
        $PointerToRelocation = DllStructGetData($IMAGE_SECTION_HEADER, 'PointerToRelocations')
        $PointerToNumbLine = DllStructGetData($IMAGE_SECTION_HEADER, 'PointerToLinenumbers')
        $CountRelocation = DllStructGetData($IMAGE_SECTION_HEADER, 'NumberOfRelocations')
        $CountNumbLine = DllStructGetData($IMAGE_SECTION_HEADER, 'NumberOfLinenumbers')
        $Characteristics = DllStructGetData($IMAGE_SECTION_HEADER, 'Characteristics')

		MsgBox(0, '', 'Имя секции: ' & $Name & @CRLF & _
					  'Виртуальный размер: ' & $VirtualSize & @CRLF & _
					  'Виртуальный адресс: ' & $VirtualAddress & @CRLF & _
					  'Размер RAW данных: ' & $SizeOfRawData & @CRLF & _
					  'Указатель на RAW данные: ' & $PointerToRawData & @CRLF & _
					  'Указатель на релокейшены: ' & $PointerToRelocation & @CRLF & _
					  'Указатель на номера строк: ' & $PointerToNumbLine & @CRLF & _
					  'Колличество релокейшенов: ' & $CountRelocation & @CRLF & _
					  'Колличество номеров строк: ' & $CountNumbLine & @CRLF & _
					  'Характеристики: ' & $Characteristics)

        $iAddress += DllStructGetSize($IMAGE_SECTION_HEADER)
    Next
    _WinAPI_CloseHandle($hFile)
EndFunc

Func READ_SECTION($hFile, $MovePos, $iSize)
    Local $nBytes, $byteStruct = DllStructCreate("byte[" & $iSize & "]")
    _WinAPI_SetFilePointer($hFile, $MovePos)
    _WinAPI_ReadFile($hFile, DllStructGetPtr($byteStruct), $iSize, $nBytes)
    Return $byteStruct
EndFunc

Func WRITE_SECTION($hFile, $MovePos, $byteStruct)
    Local $nBytes
    _WinAPI_SetFilePointer($hFile, $MovePos)
    _WinAPI_WriteFile($hFile, DllStructGetPtr($byteStruct), DllStructGetSize($byteStruct), $nBytes)
EndFunc

Func READ_DATA($hFile, $MovePos, $iSize)
    Local $nBytes, $byteStruct = DllStructCreate("byte[" & $iSize & "]")
    _WinAPI_SetFilePointer($hFile, $MovePos)
    _WinAPI_ReadFile($hFile, DllStructGetPtr($byteStruct), $iSize, $nBytes)
    Return $byteStruct
EndFunc

Func WRITE_DATA($hFile, $MovePos, $byteStruct)
    Local $nBytes
    _WinAPI_SetFilePointer($hFile, $MovePos)
    _WinAPI_WriteFile($hFile, DllStructGetPtr($byteStruct), DllStructGetSize($byteStruct), $nBytes)
EndFunc

Func READ_IMAGE_DOS_HEADER($hFile, $MovePos)
    Local $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)

    Local $nBytes, $tIMAGE_DOS_HEADER = DllStructCreate($tagIMAGE_DOS_HEADER)
    _WinAPI_SetFilePointer($hFile, $MovePos)
    _WinAPI_ReadFile($hFile, DllStructGetPtr($tIMAGE_DOS_HEADER), DllStructGetSize($tIMAGE_DOS_HEADER),$nBytes)
    Return $tIMAGE_DOS_HEADER
EndFunc

Func WRITE_IMAGE_DOS_HEADER($hFile, $MovePos, $IMAGE_DOS_HEADER)
    Local $nBytes
    _WinAPI_SetFilePointer($hFile,$MovePos)
    Return _WinAPI_WriteFile($hFile, DllStructGetPtr($IMAGE_DOS_HEADER), DllStructGetSize($IMAGE_DOS_HEADER), $nBytes)
EndFunc

Func READ_SIGNATURE($hFile, $MovePos)
    Local $nBytes, $hSignature = DllStructCreate('dword Signature')
    _WinAPI_SetFilePointer($hFile,$MovePos)
    _WinAPI_ReadFile($hFile, DllStructGetPtr($hSignature), DllStructGetSize($hSignature), $nBytes)
    Return $hSignature
EndFunc

Func WRITE_SIGNATURE($hFile, $MovePos, $Signature)
    Local $nBytes
    _WinAPI_SetFilePointer($hFile, $MovePos)
    Return _WinAPI_WriteFile($hFile, DllStructGetPtr($Signature), DllStructGetSize($Signature), $nBytes)
EndFunc

Func READ_IMAGE_FILE_HEADER($hFile, $MovePos)
    Local $tagIMAGE_FILE_HEADER = '' & _
    'ushort Machine;' & _                 ;// Машина
    'ushort NumberOfSections;' & _        ;// Колличество секторов
    'dword TimeDateStamp;' & _            ;// Временной штамп
    'dword PointerToSymbolTable;' & _     ;// Указатель на таблицу символов
    'dword NumberOfSymbols;' & _          ;// Колличество символов
    'ushort SizeOfOptionalHeader;' & _    ;// Размер дополнительного заголовка
    'ushort Characteristics'              ;// Характеристики

    Local $nBytes, $tIMAGE_FILE_HEADER = DllStructCreate($tagIMAGE_FILE_HEADER)
    _WinAPI_SetFilePointer($hFile, $MovePos)
    _WinAPI_ReadFile($hFile, DllStructGetPtr($tIMAGE_FILE_HEADER), DllStructGetSize($tIMAGE_FILE_HEADER), $nBytes)
    Return $tIMAGE_FILE_HEADER
EndFunc

Func WRITE_IMAGE_FILE_HEADER($hFile, $MovePos, $IMAGE_FILE_HEADER)
    Local $nBytes
    _WinAPI_SetFilePointer($hFile,$MovePos)
    Return _WinAPI_WriteFile($hFile, DllStructGetPtr($IMAGE_FILE_HEADER), DllStructGetSize($IMAGE_FILE_HEADER), $nBytes)
EndFunc

Func READ_IMAGE_OPTIONAL_HEADER($hFile, $MovePos)
    Local $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]'                      ;//

    Local $nBytes, $tIMAGE_OPTIONAL_HEADER = DllStructCreate($tagIMAGE_OPTIONAL_HEADER)
    _WinAPI_SetFilePointer($hFile, $MovePos)
    _WinAPI_ReadFile($hFile, DllStructGetPtr($tIMAGE_OPTIONAL_HEADER), DllStructGetSize($tIMAGE_OPTIONAL_HEADER), $nBytes)
    Return $tIMAGE_OPTIONAL_HEADER
EndFunc

Func WRITE_IMAGE_OPTIONAL_HEADER($hFile, $MovePos, $IMAGE_OPTIONAL_HEADER)
    Local $nBytes
    _WinAPI_SetFilePointer($hFile, $MovePos)
    Return _WinAPI_WriteFile($hFile, DllStructGetPtr($IMAGE_OPTIONAL_HEADER), DllStructGetSize($IMAGE_OPTIONAL_HEADER), $nBytes)
EndFunc

Func READ_IMAGE_SECTION_HEADER($hFile, $MovePos)
    Local $tagIMAGE_SECTION_HEADER = '' & _
    'char Name[8];' & _                       ;// Имя секции
    'dword Misc;' & _                         ;// Виртуальный размер
    'dword VirtualAddress;' & _               ;// Виртуальный адресс
    'dword SizeOfRawData;' & _                ;// Размер RAW данных
    'dword PointerToRawData;' & _             ;// Указатель на RAW данные
    'dword PointerToRelocations;' & _         ;// Указатель на релокейшены
    'dword PointerToLinenumbers;' & _         ;// Указатель на номера строк
    'ushort NumberOfRelocations;' & _         ;// Колличество релокейшенов
    'ushort NumberOfLinenumbers;' & _         ;// Колличество номеров строк
    'dword Characteristics'                   ;// Характеристики

    Local $nBytes, $tIMAGE_SECTION_HEADER = DllStructCreate($tagIMAGE_SECTION_HEADER)
    _WinAPI_SetFilePointer($hFile, $MovePos)
    _WinAPI_ReadFile($hFile, DllStructGetPtr($tIMAGE_SECTION_HEADER), DllStructGetSize($tIMAGE_SECTION_HEADER),$nBytes)
    Return $tIMAGE_SECTION_HEADER
EndFunc

Func WRITE_IMAGE_SECTION_HEADER($hFile, $MovePos, $IMAGE_SECTION_HEADER)
    Local $nBytes
    If $MovePos <> 0 Then _WinAPI_SetFilePointer($hFile, $MovePos)
    Return _WinAPI_WriteFile($hFile, DllStructGetPtr($IMAGE_SECTION_HEADER), DllStructGetSize($IMAGE_SECTION_HEADER), $nBytes)
EndFunc

Func _WinAPI_FileOpen($sFile,$uStyle)
    Local $tOPENFILE = DllStructCreate('byte cBytes;byte fFixedDisk;ushort nErrCode;ushort Reserved1;ushort Reserved2;char szPathName[260]')
    Local $hRet = DllCall('Kernel32.dll', 'hwnd', 'OpenFile', 'str', $sFile, 'ptr', DllStructGetPtr($tOPENFILE), 'long', $uStyle)
    If (@error) Or (Not IsArray($hRet)) Then
        Return SetError(@error, @extended, 0)
    EndIf
    Return $hRet[0]
EndFunc
 
Верх