#Include <WinAPIEx.au3>
#Include <APIConstants.au3>
AddResource(@ScriptDir & '\test.exe', @ScriptDir & '\1.exe', 10, 'EXE1') ;~ Добавляем ресурс в файл
RemoveResource(@ScriptDir & '\test.exe', 14) ;~ Удаляем иконки
Func AddResource($sFile, $sResFile, $sResType, $sResName, $sResLang = 0, $uFlag = 0)
Local $OutFile = ($sFile & '.EXTMP'), $nBytes, $iRead, $uSize, $uFile, $hStruct, $hUpdate, $hFile, $iSize, $tByte, $pByte, $aFile, $nFile, $sRead
Relocation($sFile, $OutFile)
$uFile = _WinAPI_CreateFile($sFile, 2, 2)
If (Not $uFile) Then Return SetError(-1, 0, 0)
_WinAPI_SetFilePointer($uFile, FileGetSize($OutFile), 0)
$uSize = FileGetSize($sFile)
If ($uFlag <> 1) Then
$hStruct = DllStructCreate("char[" & $uSize & "]")
Else
$hStruct = DllStructCreate("byte[" & $uSize & "]")
EndIf
If _WinAPI_ReadFile($uFile, DllStructGetPtr($hStruct), $uSize, $iRead) Then
_WinAPI_CloseHandle($uFile)
$hUpdate = _WinAPI_BeginUpdateResource($OutFile, False)
If $hUpdate Then
$hFile = _WinAPI_CreateFileEx($sResFile, $OPEN_EXISTING, $GENERIC_READ)
$iSize = _WinAPI_GetFileSize($hFile)
$tByte = DllStructCreate('byte[' & $iSize & ']')
$pByte = DllStructGetPtr($tByte)
If _WinAPI_ReadFile($hFile, $pByte, $iSize, $iSize) Then
If _WinAPI_UpdateResource($hUpdate, $sResType, $sResName, $sResLang, $pByte, DllStructGetSize($tByte)) Then
_WinAPI_EndUpdateResource($hUpdate, False)
EndIf
EndIf
EndIf
EndIf
$aFile = _WinAPI_CreateFile($OutFile, 2, 4)
If (Not $aFile) Then Return SetError(-3, 0, 0)
_WinAPI_SetFilePointer($aFile, 0, 2)
_WinAPI_WriteFile($aFile, DllStructGetPtr($hStruct), DllStructGetSize($hStruct), $nBytes)
_WinAPI_CloseHandle($aFile)
FileDelete($sFile)
$nFile = FileOpen($OutFile)
$sRead = FileRead($nFile)
FileClose($nFile)
FileWrite($sFile, $sRead)
FileDelete($OutFile)
EndFunc
Func RemoveResource($sFile, $sResType, $sResName = '', $sResLang = 0)
Local $OutFile = ($sFile & '.EXTMP')
Relocation($sFile, $OutFile)
Local $hSourceFile = _WinAPI_CreateFile($sFile, 2, 2)
If $hSourceFile Then
_WinAPI_SetFilePointer($hSourceFile, FileGetSize($OutFile), 0)
Local $hByte = DllStructCreate("byte[" & FileGetSize($sFile) & "]")
Local $pByte = DllStructGetPtr($hByte)
Local $iSize = DllStructGetSize($hByte)
If Not _WinAPI_ReadFile($hSourceFile, $pByte, $iSize, 0) Then
Return SetError(-1, 0, 0)
EndIf
_WinAPI_CloseHandle($hSourceFile)
Local $hUpdate = _WinAPI_BeginUpdateResource($OutFile, False)
If $hUpdate Then
If $sResName <> '' Then
If _WinAPI_UpdateResource($hUpdate, $sResType, $sResName, $sResLang, 0, 0) Then
_WinAPI_EndUpdateResource($hUpdate, False)
EndIf
Else
Local $hLoadLibrary = _WinAPI_LoadLibraryEx($sFile, $LOAD_LIBRARY_AS_DATAFILE)
Local $sEnumName = _WinAPI_EnumResourceNames($hLoadLibrary, $sResType)
For $i = 0 To UBound($sEnumName) -1
Local $sEnumLang = _WinAPI_EnumResourceLanguages($hLoadLibrary, $sResType, $sEnumName[$i])
For $l = 0 To UBound($sEnumLang) -1
_WinAPI_UpdateResource($hUpdate, $sResType, $sEnumName[$i], $sEnumLang[$l], 0, 0)
Next
Next
_WinAPI_EndUpdateResource($hUpdate, False)
_WinAPI_FreeLibrary($hLoadLibrary)
EndIF
EndIf
Local $hDestFile = _WinAPI_CreateFile($OutFile, 2, 4)
If $hDestFile Then
_WinAPI_SetFilePointer($hDestFile, 0, 2)
If Not _WinAPI_WriteFile($hDestFile, $pByte, $iSize, 0) Then
Return SetError(-2, 0, 0)
EndIf
_WinAPI_CloseHandle($hDestFile)
EndIf
EndIf
FileDelete($sFile)
$nFile = FileOpen($OutFile)
$sRead = FileRead($nFile)
FileClose($nFile)
FileWrite($sFile, $sRead)
FileDelete($OutFile)
EndFunc
Func ExtractResource($hInstance, $sExtractPath, $sResType, $sResName, $iResLanguage = 0)
Local $hResource, $aResSize, $aResLoad, $pMemRes
If $iResLanguage Then
$hResource = _WinAPI_FindResourceEx($hInstance, $sResType, $sResName, $iResLanguage)
Else
$hResource = _WinAPI_FindResource($hInstance, $sResType, $sResName)
EndIf
$iSize = _WinAPI_SizeOfResource($hInstance, $hResource)
$aResLoad = _WinAPI_LoadResource($hInstance, $hResource)
$pMemRes = _WinAPI_LockResource($aResLoad)
If @error Then
Return SetError(@error, @extended, 0)
EndIf
$tByte = DllStructCreate('byte[' & $iSize & ']', $pMemRes)
$hFile = _WinAPI_CreateFileEx($sExtractPath, $CREATE_ALWAYS, $GENERIC_WRITE)
_WinAPI_WriteFile($hFile, DllStructGetPtr($tByte), DllStructGetSize($tByte), $tByte)
If $hFile Then
_WinAPI_CloseHandle($hFile)
EndIf
EndFunc
Func Relocation($sFile, $sOutFile)
Local $hFile = _WinAPI_CreateFile($sFile, 2, 2)
If (@error) Or (Not $hFile) Then
Return SetError(-1, 0, 0)
EndIf
Local $hFileOut = _WinAPI_FileOpen($sOutFile, 0x00001000 + 0x00000002)
If (Not $hFileOut) Then
Return SetError(-2, 0, 0)
EndIf
$IMAGE_DOS_HEADER = READ_IMAGE_DOS_HEADER($hFile, 0) ;~ Извлекаем структуры IMAGE_DOS_HEADER из исходного файла
WRITE_IMAGE_DOS_HEADER($hFileOut, 0, $IMAGE_DOS_HEADER) ;~ Записываем структуру 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
WRITE_SIGNATURE($hFileOut, $iAddress, $Signature) ;~ Пишем в новый файл сигнатуру по адрессу таблицы
$iAddress += DllStructGetSize($Signature) ;~ Прибавляем к адресу таблицы размер сигнатуры
$IMAGE_FILE_HEADER = READ_IMAGE_FILE_HEADER($hFile, $iAddress) ;~ Заполняем структуру IMAGE_FILE_HEADER, считываем по адресу (Таблица + сигнатура)
WRITE_IMAGE_FILE_HEADER($hFileOut, $iAddress, $IMAGE_FILE_HEADER) ;~ Записываем в новый файл структуру 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
WRITE_IMAGE_OPTIONAL_HEADER($hFileOut, $iAddress, $IMAGE_OPTIONAL_HEADER) ;~ Записываем в новый файл структуру IMAGE_OPTIONAL_HEADER
$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) ;~ Считываем данные
WRITE_DATA($hFileOut, $DataPos, $DataStruct) ;~ Записываем в новый файл
For $i = 1 To $NumberOfSections
;~ Пишется столько раз, сколько существует секций
$IMAGE_SECTION_HEADER = READ_IMAGE_SECTION_HEADER($hFile, $iAddress) ;~ Считываем IMAGE_SECTION_HEADER из файла
WRITE_IMAGE_SECTION_HEADER($hFileOut, $iAddress, $IMAGE_SECTION_HEADER) ;~ Записываем в новый файл IMAGE_SECTION_HEADER
$PointerToRawData = DllStructGetData($IMAGE_SECTION_HEADER, 'PointerToRawData') ;~ Указатель на первую страницу в файл COFF.
$SizeOfRawData = DllStructGetData($IMAGE_SECTION_HEADER, 'SizeOfRawData') ;~ Размер инициализированных данных на диске в байтах.
$VirtualAddress = DllStructGetData($IMAGE_SECTION_HEADER, 'VirtualAddress') ;~ Адрес первого байта раздела при загрузке в память
$ByteStruct = READ_SECTION($hFile, $PointerToRawData, $SizeOfRawData) ;~ Считываем секцию
WRITE_SECTION($hFileOut, $PointerToRawData, $byteStruct) ;~ Записываем в новый файл секцию
$iAddress += DllStructGetSize($IMAGE_SECTION_HEADER)
Next
_WinAPI_CloseHandle($hFile)
_WinAPI_CloseHandle($hFileOut)
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 = '' & _
'byte 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