Viktor1703
AutoIT Гуру
- Сообщения
- 1,535
- Репутация
- 413
Не давно мне понадобилось записывать данные в конец исполняющего файла (далее stub), но как быть если их нужно будет прочитать из самого себя, для этого написал функцию которая узнаёт размер исполняющего файла без оверлея
1. Если нужно извлечь оверлей из стороннего исполняющего файла, необходимо указать в единственный параметр путь к файлу (как в примере выше).
2. Если нужно извлечь оверлей из самого себя, вызвать функцию без параметра.
3. Узнать адрес с которого начинается оверлей.
4. Узнать размер оверлея
5. Не большой тест, скомпилируйте пример
Запустите полученный исполняющий файл, убедитесь что размер оверлея равен нулю, откройте файл в HEX редакторе, добавьте несколько байт в самый конец файла, сохраните, запустите полученный файл и вы увидите сколько байт вы добавили в конец исполняющего файла. Данный пример особенно пригодится тем кто любит строить свои билдеры которые в ходе выполнения извлекают из себя стаб и добавляют в него некую информацию.
P.S. Если вы используете AutoIt v3.3.10.2 то в оверлее после компиляции ни чего не будет, так как скрипт добавляется в ресурсы исполняющего файла, если же версию AutoIt v3.3.8.1 и ниже, то изначально в оверлее будет некоторое количество байт, так как там уже хранится скрипт.
Вот простой пример
Test.exe - файл в который будут записываться данные
Write.exe - файл который будет записывать данные
Запустите Test.exe и убедитесь что в него ни чего не записано, в 'Размер данных в оверлее' должно стоять 0 (ноль), запустите Write.exe, введите в поле текст и нажмите OK, далее снова запустите Test.exe, теперь вы увидите размер данных в оверлее и сами данные.
Код:
#Include <WinAPIEx.au3>
#Region Global Variables
#Region IMAGE_DOS_HEADER
Global Const $tagPE_IMAGE_DOS_HEADER = 'word e_magic;' & _
'word e_cblp;' & _
'word e_cp;' & _
'word e_crlc;' & _
'word e_cparhdr;' & _
'word e_minalloc;' & _
'word e_maxalloc;' & _
'word e_ss;' & _
'word e_sp;' & _
'word e_csum;' & _
'word e_ip;' & _
'word e_cs;' & _
'word e_lfarlc;' & _
'word e_ovno;' & _
'word e_res[4];' & _
'word e_oemid;' & _
'word e_oeminfo;' & _
'word e_res2[10];' & _
'long e_lfanew;'
#EndRegion
#Region IMAGE_FILE_HEADER
Global Const $tagPE_IMAGE_FILE_HEADER = 'word Machine;' & _
'word NumberOfSections;' & _
'dword TimeDateStamp;' & _
'dword PointerToSymbolTable;' & _
'dword NumberOfSymbols;' & _
'word SizeOfOptionalHeader;' & _
'word Characteristics;'
#EndRegion
#Region IMAGE_OPTIONAL_HEADER
If (Not @AutoItX64) Then
Global $tagPE_IMAGE_OPTIONAL_HEADER = 'word Magic;' & _
'byte MajorLinkerVersion;' & _
'byte MinorLinkerVersion;' & _
'dword SizeOfCode;' & _
'dword SizeOfInitializedData;' & _
'dword SizeOfUninitializedData;' & _
'dword AddressOfEntryPoint;' & _
'dword BaseOfCode;' & _
'dword BaseOfData;' & _
'dword ImageBase;' & _
'dword SectionAlignment;' & _
'dword FileAlignment;' & _
'word MajorOperatingSystemVersion;' & _
'word MinorOperatingSystemVersion;' & _
'word MajorImageVersion;' & _
'word MinorImageVersion;' & _
'word MajorSubsystemVersion;' & _
'word MinorSubsystemVersion;' & _
'dword Win32VersionValue;' & _
'dword SizeOfImage;' & _
'dword SizeOfHeaders;' & _
'dword CheckSum;' & _
'word Subsystem;' & _
'word DllCharacteristics;' & _
'dword SizeOfStackReserve;' & _
'dword SizeOfStackCommit;' & _
'dword SizeOfHeapReserve;' & _
'dword SizeOfHeapCommit;' & _
'dword LoaderFlags;' & _
'dword NumberOfRvaAndSizes;'
Else
Global $tagPE_IMAGE_OPTIONAL_HEADER = 'word Magic;' & _
'byte MajorLinkerVersion;' & _
'byte MinorLinkerVersion;' & _
'dword SizeOfCode;' & _
'dword SizeOfInitializedData;' & _
'dword SizeOfUninitializedData;' & _
'dword AddressOfEntryPoint;' & _
'dword BaseOfCode;' & _
'ptr ImageBase;' & _
'dword SectionAlignment;' & _
'dword FileAlignment;' & _
'word MajorOperatingSystemVersion;' & _
'word MinorOperatingSystemVersion;' & _
'word MajorImageVersion;' & _
'word MinorImageVersion;' & _
'word MajorSubsystemVersion;' & _
'word MinorSubsystemVersion;' & _
'dword Win32VersionValue;' & _
'dword SizeOfImage;' & _
'dword SizeOfHeaders;' & _
'dword CheckSum;' & _
'word Subsystem;' & _
'word DllCharacteristics;' & _
'ptr SizeOfStackReserve;' & _
'ptr SizeOfStackCommit;' & _
'ptr SizeOfHeapReserve;' & _
'ptr SizeOfHeapCommit;' & _
'dword LoaderFlags;' & _
'dword NumberOfRvaAndSizes;'
EndIf
#EndRegion
#Region IMAGE_NT_HEADER
Global Const $tagPE_IMAGE_NT_HEADER = 'dword Signature;' & $tagPE_IMAGE_FILE_HEADER & $tagPE_IMAGE_OPTIONAL_HEADER
#EndRegion
#Region IMAGE_SECTION_HEADER
Global Const $tagPE_IMAGE_SECTION_HEADER = 'byte Name[8];' & _
'dword VirtualSize;' & _
'dword VirtualAddress;' & _
'dword SizeOfRawData;' & _
'dword PointerToRawData;' & _
'dword PointerToRelocations;' & _
'dword PointerToLinenumbers;' & _
'word NumberOfRelocations;' & _
'word NumberOfLinenumbers;' & _
'dword Characteristics;'
#EndRegion
#EndRegion
$iSizeOfImage = __pe_GetSizeOfImage(@ScriptDir & '\Test.exe')
Switch @error
Case 1
ConsoleWrite('Не удалось получить указатель на модуль' & @LF)
Case 2
ConsoleWrite('Не удалось извлечь дескриптор указанного модуля' & @LF)
Case 3
ConsoleWrite('Файл не является исполняющим' & @LF)
Case 4
ConsoleWrite('Не верная сигнатура' & @LF)
EndSwitch
ConsoleWrite($iSizeOfImage & @CRLF)
Func __pe_GetSizeOfImage($vModuleName = '')
Local $hmod, $pImageBase, $tIdh, $iAddr, $tInh, $tIfh, $tIoh, $tIsh
If ($vModuleName <> '') Then
$hmod = _WinAPI_LoadLibrary($vModuleName)
If ((Not $hmod) And @error) Then
Return SetError(1, 0, 0)
EndIf
$pImageBase = _WinAPI_GetModuleHandle($vModuleName)
If ((Not $pImageBase) And @error) Then
_WinAPI_CloseHandle($hmod)
Return SetError(2, 0, 0)
EndIf
_WinAPI_CloseHandle($hmod)
Else
$pImageBase = _WinAPI_GetModuleHandle($vModuleName)
If ((Not $pImageBase) And @error) Then
Return SetError(2, 0, 0)
EndIf
EndIf
$tIdh = DllStructCreate($tagPE_IMAGE_DOS_HEADER, $pImageBase)
If (DllStructGetData($tIdh, 'e_magic') <> 0x5A4D) Then
Return SetError(3, 0, 0)
EndIf
$iAddr = ($pImageBase + DllStructGetData($tIdh, 'e_lfanew'))
$tInh = DllStructCreate($tagPE_IMAGE_NT_HEADER, $iAddr)
If (DllStructGetData($tInh, 'Signature') <> 0x4550) Then
Return SetError(4, 0, 0)
EndIf
$iAddr = (DllStructGetPtr($tIdh) + DllStructGetData($tIdh, 'e_lfanew') + DllStructGetSize(DllStructCreate('long')))
$tIfh = DllStructCreate($tagPE_IMAGE_FILE_HEADER, $iAddr)
$iAddr = (DllStructGetPtr($tIfh) + DllStructGetSize(DllStructCreate($tagPE_IMAGE_FILE_HEADER)))
$tIoh = DllStructCreate($tagPE_IMAGE_OPTIONAL_HEADER, $iAddr)
$iAddr = (DllStructGetPtr($tIoh) + DllStructGetData($tIfh, 'SizeOfOptionalHeader'))
$tIsh = DllStructCreate($tagPE_IMAGE_SECTION_HEADER, $iAddr)
$iAddr = (DllStructGetPtr($tIsh) + ((DllStructGetData($tIfh, 'NumberOfSections') - 1) * DllStructGetSize(DllStructCreate($tagPE_IMAGE_SECTION_HEADER))))
$tIsh = DllStructCreate($tagPE_IMAGE_SECTION_HEADER, $iAddr)
Return (DllStructGetData($tIsh, 'PointerToRawData') + DllStructGetData($tIsh, 'SizeOfRawData'))
EndFunc
1. Если нужно извлечь оверлей из стороннего исполняющего файла, необходимо указать в единственный параметр путь к файлу (как в примере выше).
2. Если нужно извлечь оверлей из самого себя, вызвать функцию без параметра.
3. Узнать адрес с которого начинается оверлей.
Код:
$iOverlay = __pe_GetSizeOfImage(...)
4. Узнать размер оверлея
Код:
;~ Для стороннего файла
$sFile = @ScriptDir & '\Test.exe'
$iFileSize = FileGetSize($sFile)
$iOverlay = __pe_GetSizeOfImage($sFile)
$iOverlaySize = ($iFileSize - $iOverlay)
;~ Для самого себя
If @Compiled Then
MsgBox(0, 'Размер данных в оверлее', FileGetSize(@ScriptFullPath) - __pe_GetSizeOfImage())
EndIf
5. Не большой тест, скомпилируйте пример
Код:
#Include <WinAPIEx.au3>
#Region Global Variables
#Region IMAGE_DOS_HEADER
Global Const $tagPE_IMAGE_DOS_HEADER = 'word e_magic;' & _
'word e_cblp;' & _
'word e_cp;' & _
'word e_crlc;' & _
'word e_cparhdr;' & _
'word e_minalloc;' & _
'word e_maxalloc;' & _
'word e_ss;' & _
'word e_sp;' & _
'word e_csum;' & _
'word e_ip;' & _
'word e_cs;' & _
'word e_lfarlc;' & _
'word e_ovno;' & _
'word e_res[4];' & _
'word e_oemid;' & _
'word e_oeminfo;' & _
'word e_res2[10];' & _
'long e_lfanew;'
#EndRegion
#Region IMAGE_FILE_HEADER
Global Const $tagPE_IMAGE_FILE_HEADER = 'word Machine;' & _
'word NumberOfSections;' & _
'dword TimeDateStamp;' & _
'dword PointerToSymbolTable;' & _
'dword NumberOfSymbols;' & _
'word SizeOfOptionalHeader;' & _
'word Characteristics;'
#EndRegion
#Region IMAGE_OPTIONAL_HEADER
If (Not @AutoItX64) Then
Global $tagPE_IMAGE_OPTIONAL_HEADER = 'word Magic;' & _
'byte MajorLinkerVersion;' & _
'byte MinorLinkerVersion;' & _
'dword SizeOfCode;' & _
'dword SizeOfInitializedData;' & _
'dword SizeOfUninitializedData;' & _
'dword AddressOfEntryPoint;' & _
'dword BaseOfCode;' & _
'dword BaseOfData;' & _
'dword ImageBase;' & _
'dword SectionAlignment;' & _
'dword FileAlignment;' & _
'word MajorOperatingSystemVersion;' & _
'word MinorOperatingSystemVersion;' & _
'word MajorImageVersion;' & _
'word MinorImageVersion;' & _
'word MajorSubsystemVersion;' & _
'word MinorSubsystemVersion;' & _
'dword Win32VersionValue;' & _
'dword SizeOfImage;' & _
'dword SizeOfHeaders;' & _
'dword CheckSum;' & _
'word Subsystem;' & _
'word DllCharacteristics;' & _
'dword SizeOfStackReserve;' & _
'dword SizeOfStackCommit;' & _
'dword SizeOfHeapReserve;' & _
'dword SizeOfHeapCommit;' & _
'dword LoaderFlags;' & _
'dword NumberOfRvaAndSizes;'
Else
Global $tagPE_IMAGE_OPTIONAL_HEADER = 'word Magic;' & _
'byte MajorLinkerVersion;' & _
'byte MinorLinkerVersion;' & _
'dword SizeOfCode;' & _
'dword SizeOfInitializedData;' & _
'dword SizeOfUninitializedData;' & _
'dword AddressOfEntryPoint;' & _
'dword BaseOfCode;' & _
'ptr ImageBase;' & _
'dword SectionAlignment;' & _
'dword FileAlignment;' & _
'word MajorOperatingSystemVersion;' & _
'word MinorOperatingSystemVersion;' & _
'word MajorImageVersion;' & _
'word MinorImageVersion;' & _
'word MajorSubsystemVersion;' & _
'word MinorSubsystemVersion;' & _
'dword Win32VersionValue;' & _
'dword SizeOfImage;' & _
'dword SizeOfHeaders;' & _
'dword CheckSum;' & _
'word Subsystem;' & _
'word DllCharacteristics;' & _
'ptr SizeOfStackReserve;' & _
'ptr SizeOfStackCommit;' & _
'ptr SizeOfHeapReserve;' & _
'ptr SizeOfHeapCommit;' & _
'dword LoaderFlags;' & _
'dword NumberOfRvaAndSizes;'
EndIf
#EndRegion
#Region IMAGE_NT_HEADER
Global Const $tagPE_IMAGE_NT_HEADER = 'dword Signature;' & $tagPE_IMAGE_FILE_HEADER & $tagPE_IMAGE_OPTIONAL_HEADER
#EndRegion
#Region IMAGE_SECTION_HEADER
Global Const $tagPE_IMAGE_SECTION_HEADER = 'byte Name[8];' & _
'dword VirtualSize;' & _
'dword VirtualAddress;' & _
'dword SizeOfRawData;' & _
'dword PointerToRawData;' & _
'dword PointerToRelocations;' & _
'dword PointerToLinenumbers;' & _
'word NumberOfRelocations;' & _
'word NumberOfLinenumbers;' & _
'dword Characteristics;'
#EndRegion
#EndRegion
If @Compiled Then
$iSizeOfImage = __pe_GetSizeOfImage()
Switch @error
Case 0
MsgBox(0, '', 'Адрес оверлея: ' & $iSizeOfImage & @CRLF & 'Размер данных в оверлее: ' & (FileGetSize(@ScriptFullPath) - $iSizeOfImage) & ' байт')
Case 1
MsgBox(0, '', 'Не удалось получить указатель на модуль')
Case 2
MsgBox(0, '', 'Не удалось извлечь дескриптор указанного модуля')
Case 3
MsgBox(0, '', 'Файл не является исполняющим')
Case 4
MsgBox(0, '', 'Не верная сигнатура')
EndSwitch
EndIf
Func __pe_GetSizeOfImage($vModuleName = '')
Local $hmod, $pImageBase, $tIdh, $iAddr, $tInh, $tIfh, $tIoh, $tIsh
If ($vModuleName <> '') Then
$hmod = _WinAPI_LoadLibrary($vModuleName)
If ((Not $hmod) And @error) Then
Return SetError(1, 0, 0)
EndIf
$pImageBase = _WinAPI_GetModuleHandle($vModuleName)
If ((Not $pImageBase) And @error) Then
_WinAPI_CloseHandle($hmod)
Return SetError(2, 0, 0)
EndIf
_WinAPI_CloseHandle($hmod)
Else
$pImageBase = _WinAPI_GetModuleHandle($vModuleName)
If ((Not $pImageBase) And @error) Then
Return SetError(2, 0, 0)
EndIf
EndIf
$tIdh = DllStructCreate($tagPE_IMAGE_DOS_HEADER, $pImageBase)
If (DllStructGetData($tIdh, 'e_magic') <> 0x5A4D) Then
Return SetError(3, 0, 0)
EndIf
$iAddr = ($pImageBase + DllStructGetData($tIdh, 'e_lfanew'))
$tInh = DllStructCreate($tagPE_IMAGE_NT_HEADER, $iAddr)
If (DllStructGetData($tInh, 'Signature') <> 0x4550) Then
Return SetError(4, 0, 0)
EndIf
$iAddr = (DllStructGetPtr($tIdh) + DllStructGetData($tIdh, 'e_lfanew') + DllStructGetSize(DllStructCreate('long')))
$tIfh = DllStructCreate($tagPE_IMAGE_FILE_HEADER, $iAddr)
$iAddr = (DllStructGetPtr($tIfh) + DllStructGetSize(DllStructCreate($tagPE_IMAGE_FILE_HEADER)))
$tIoh = DllStructCreate($tagPE_IMAGE_OPTIONAL_HEADER, $iAddr)
$iAddr = (DllStructGetPtr($tIoh) + DllStructGetData($tIfh, 'SizeOfOptionalHeader'))
$tIsh = DllStructCreate($tagPE_IMAGE_SECTION_HEADER, $iAddr)
$iAddr = (DllStructGetPtr($tIsh) + ((DllStructGetData($tIfh, 'NumberOfSections') - 1) * DllStructGetSize(DllStructCreate($tagPE_IMAGE_SECTION_HEADER))))
$tIsh = DllStructCreate($tagPE_IMAGE_SECTION_HEADER, $iAddr)
Return (DllStructGetData($tIsh, 'PointerToRawData') + DllStructGetData($tIsh, 'SizeOfRawData'))
EndFunc
Запустите полученный исполняющий файл, убедитесь что размер оверлея равен нулю, откройте файл в HEX редакторе, добавьте несколько байт в самый конец файла, сохраните, запустите полученный файл и вы увидите сколько байт вы добавили в конец исполняющего файла. Данный пример особенно пригодится тем кто любит строить свои билдеры которые в ходе выполнения извлекают из себя стаб и добавляют в него некую информацию.
P.S. Если вы используете AutoIt v3.3.10.2 то в оверлее после компиляции ни чего не будет, так как скрипт добавляется в ресурсы исполняющего файла, если же версию AutoIt v3.3.8.1 и ниже, то изначально в оверлее будет некоторое количество байт, так как там уже хранится скрипт.
Вот простой пример
Test.exe - файл в который будут записываться данные
Write.exe - файл который будет записывать данные
Запустите Test.exe и убедитесь что в него ни чего не записано, в 'Размер данных в оверлее' должно стоять 0 (ноль), запустите Write.exe, введите в поле текст и нажмите OK, далее снова запустите Test.exe, теперь вы увидите размер данных в оверлее и сами данные.