![]() |
Добро пожаловать, гость ( Вход | Регистрация )
![]() ![]() |
![]() |
Axsis |
![]()
Сообщение
#1
|
Advanced Member ![]() ![]() ![]() Группа: CTPAX-X Сообщений: 121 Регистрация: 6-February 08 Пользователь №: 374 Спасибо сказали: 149 раз(а) ![]() |
В InstallShield'е 2011 изменили формат cab/hdr файлов (навскидку увидел что имена файлов теперь хранятся в unicode, возможно есть и другие изменения), соответственно старые распаковщики не у дел.
Слил с оффсайта триал самого InstallShield'а 2011 и достал оттуда ISCabView последней версии, который с новыми файлами умеет работать. Штука весьма неудобная, но до обновления неофициальных утилит думаю может пригодиться: http://ifolder.ru/20772418 PS: да, он распаковывает новый 3DMark11 ![]() Спасибо сказали:
|
-=CHE@TER=- |
![]()
Сообщение
#2
|
Walter Sullivan ![]() ![]() ![]() Группа: Root Admin Сообщений: 1,360 Регистрация: 4-February 08 Пользователь №: 3 Спасибо сказали: 313 раз(а) ![]() |
О! Спасибо большое!
А можно узнать как он распаковывает? Потому что из Temp я могу перехватить только data1.cab и data1.hdr, но они очень маленькие и при попытке распаковать из них .DAT файлы программа падает с ошибкой. Мне нужно как-то data2.cab достать из .EXE файла установщика. У меня есть программа IsXunpack.exe которая может разбивать .EXE файлы InstallShield на .HDR и .CAB, но она за 06.04.2004 и с новыми не работает... [OffTopic] |
Axsis |
![]()
Сообщение
#3
|
Advanced Member ![]() ![]() ![]() Группа: CTPAX-X Сообщений: 121 Регистрация: 6-February 08 Пользователь №: 374 Спасибо сказали: 149 раз(а) ![]() |
Оооо... Версий инсталлшилда великое множество, но глобально их можно поделить на 2 типа. Но раз уж затронули эту тему, то обо всём по порядку:
Во-первых как получить сам оверлей для ковыряния оного? Программ довольно много, но наиболее правильно это делает ВНЕЗАПНО 7zip (у меня версия 9.20, за более ранние не ручаюсь, но вроде он давно уже умеет разбирать exe на секции). Правда, он привередлив и распаковывает далеко не все exe, а по-моему только те у которых есть цифровая подпись. Но учитывая что IS платный и пользуются им только крупные разработчики и издатели, то подпись есть на большинстве инсталляторов. Итак, среди распакованных файлов находим файл с загадочным именем "[0]" - это и есть оверлей, он то нам и нужен. Плюс 7zip'а в том, что он, в отличие от других подобных прог, извлекает только то что нам нужно - без отладочной информации, которая в новых инсталляторах идёт после последней секции файла и перед оверлеем, и без самой цифровой подписи, которая идёт после оверлея. (Точнее, всё это сохраняется в отдельных файлах). Оверлеи, как я уже писал, бывают двух типов - с заголовком "InstallShield" и без заголовка вообще. Файлы с заголовком опишу чуть позже, там тоже несколько разновидностей, шифрование, сжатие и т.д и т.п. В 3DMark'ах (не только в 11, но и в предыдущих) используется второй тип - раньше его брала IsXunpack.exe, но теперь имена файлов и здесь в юникоде, так что облом. Я эти файлы распаковываю с помощью скриптов для QuickBMS. Для новой версии понадобилась лишь лёгкая модификация скрипта ![]() Для старых версий (без юникода; действие аналогично IsXunpack): CODE # is_type2.bms get END ASIZE math END -= 8 do get NAME string get FULLNAME string get VERSION string get SIZE string savepos OFFSET log FULLNAME OFFSET SIZE math OFFSET += SIZE goto OFFSET while OFFSET < END Для новых версий (с именами в юникоде): CODE # is_type2u.bms get FILES long # Догадались добавить количество файлов... for I = 0 < FILES get NAME unicode get FULLNAME unicode get VERSION unicode get SIZE unicode savepos OFFSET log FULLNAME OFFSET SIZE math OFFSET += SIZE goto OFFSET next I В принципе ничего сложного, файлы с заголовком опишу чуть позже, там всё несколько хитрее. Но и для них тоже есть скрипт ![]() А то тягать инсталляторы из темпа как-то не по-нашенски ![]() [OffTopic] Спасибо сказали:
|
-=CHE@TER=- |
![]()
Сообщение
#4
|
Walter Sullivan ![]() ![]() ![]() Группа: Root Admin Сообщений: 1,360 Регистрация: 4-February 08 Пользователь №: 3 Спасибо сказали: 313 раз(а) ![]() |
Спасибо большое!
Всё распаковал (разве что выяснилось, что чистый (консольный) 7za.exe не умеет распаковывать - надо было именно GUI версию брать). Однако: 1) Запускаю выложенный тобой IsCabView.exe 2) File -> Open, выбираю data1.hdr 3) В панели-дереве слева: Components -> data -> Files 4) В правой панели выбираю любой файл - data0001.dat или data0002.dat 5) Tools -> Extract File 6) Жму "Сохранить" и программа падает с фатальной ошибкой (два окна с руганью подряд) Для работы IsCabView.exe нужно что-то ещё? Второй файл уже не нужен - на форуме Extractor.ru его выложили, но мне хотелось бы до конца с IS разобраться, чтобы в будущем не париться... |
Axsis |
![]()
Сообщение
#5
|
Advanced Member ![]() ![]() ![]() Группа: CTPAX-X Сообщений: 121 Регистрация: 6-February 08 Пользователь №: 374 Спасибо сказали: 149 раз(а) ![]() |
QUOTE Для работы IsCabView.exe нужно что-то ещё? Та нет вроде. Только что распаковал у себя оба dat файла. Учитывая что она написана на С, то могут понадобиться только библиотеки из vc_redist, скорее всего 2008 версии. (в импорте присутствуют mfc90u.dll, msvcr90.dll, но если бы у тебя их не было, она бы не загрузилась ![]() Обнови, может поможет. http://www.microsoft.com/downloads/en/deta...&displaylang=en Спасибо сказали:
|
-=CHE@TER=- |
![]()
Сообщение
#6
|
Walter Sullivan ![]() ![]() ![]() Группа: Root Admin Сообщений: 1,360 Регистрация: 4-February 08 Пользователь №: 3 Спасибо сказали: 313 раз(а) ![]() |
Не помогло.
Ещё проверил на другой машине (там тоже Windows XP SP3 + все обновления) - тоже самое. Может надо какую-нибудь примочку IS в систему ставить? Типа ядра установщика? Сдаётся мне, что из-за этого установщик-то и не работает. Ошибка лезет в mfc90u.dll внутри какой-то функции вызванной по ординалу (адрес .419224 в программе). |
Axsis |
![]()
Сообщение
#7
|
Advanced Member ![]() ![]() ![]() Группа: CTPAX-X Сообщений: 121 Регистрация: 6-February 08 Пользователь №: 374 Спасибо сказали: 149 раз(а) ![]() |
Мда, странно, тоже проверил на XP SP3 - падает. Проверил версии библиотек - у меня на компе версия mfc90u.dll 9.00.30729.4974, самое свежее что смог найти на сайте microsoft - 9.00.30729.4148 - Microsoft Visual C++ 2008 Service Pack 1 Redistributable Package ATL Security Update Но даже с ней на XP падает. Откуда у меня взялась версия 9.00.30729.4974 - хз.
Файлы находятся не в windows\system32\ a в windows\winsxs\..., взял оттуда эту новую версию, положил в папку с IsCabView. Не помогло - программа грузит ту что установлена в системе в winsxs. ![]() Запустил под олькой, падает на адресе 78A608EB, из-за того что EAX=0. CODE CPU Disasm Address Hex dump Command Comments 78A608E4 |. 53 PUSH EBX ; /lParam 78A608E5 |. 57 PUSH EDI ; |wParam 78A608E6 |. 68 66040000 PUSH 466 ; |Msg = WM_USER+102. 78A608EB |. FF70 20 PUSH DWORD PTR DS:[EAX+20] ; |hWnd 78A608EE |. FF15 601A9E78 CALL DWORD PTR DS:[<&USER32.SendMessageW>] ; \USER32.SendMessageW Отправил в стек 0, пропустил эту инструкцию, и программа продолжила работать и распаковала выбранный файл. Найти бы способ заставить IsCabView грузить dll, лежащую рядом с ней - можно было б подсунуть ей пропатченную версию, а то патчить системную в winsxs как-то не хочется. ![]() Спасибо сказали:
|
-=CHE@TER=- |
![]()
Сообщение
#8
|
Walter Sullivan ![]() ![]() ![]() Группа: Root Admin Сообщений: 1,360 Регистрация: 4-February 08 Пользователь №: 3 Спасибо сказали: 313 раз(а) ![]() |
Самый простой способ:
Меняем имя mfc90u.dll на xfc90u.dll в: - имени этого .DLL файла - внутри этого .DLL файла - в импорте .EXE программы Должно, по идее, заработать. Выложи, кстати, куда-нибудь свою версию этой библиотеки (с которой работает). Добавлено: Засада. У меня другой адрес (версия 9.0.21022.8), но я нашёл этот код и заменил на xor eax, eax / push eax - программа вообще перестала окно обновлять, а после закрытия зависла в процессах... Оставил библиотеку нетронутой, только переименовал, программа всё равно висит - то ли сам IsCabView.exe проверяет свою целостность, то ли ещё что... |
Axsis |
![]()
Сообщение
#9
|
Advanced Member ![]() ![]() ![]() Группа: CTPAX-X Сообщений: 121 Регистрация: 6-February 08 Пользователь №: 374 Спасибо сказали: 149 раз(а) ![]() |
Та похоже, что версия всё-таки не причём - глянул у себя на компе в отладчике - этот код в mfc90u вообще не выполняется, так как срабатывает условный переход чуть выше в этой функции.
Даже не знаю, неужели XP уже не поддерживается? Думаю ещё попробовать всё-таки установить InstallShield на XP и проверить. Но на своём-то компе я его не ставил, а ISCabView работает... ![]() |
-=CHE@TER=- |
![]()
Сообщение
#10
|
Walter Sullivan ![]() ![]() ![]() Группа: Root Admin Сообщений: 1,360 Регистрация: 4-February 08 Пользователь №: 3 Спасибо сказали: 313 раз(а) ![]() |
Есть такая утилита как InstallShield 5.x/6.x Cabinet Compression & Maintenance Util (i5comp.exe / i6comp.exe). У меня к ней даже где-то исходные коды на сях валяются, попробую поковырять...
Добавлено: Ha-ha! I tricked you! © Laura, Silent Hill 2 Распаковщик: i6compx.zip Unicode, правда, не поддерживается (тупо переводится в ANSI с заменой на "_" левых символов), но главное, что оно всё правильно распаковывает. Флаг 0x04000000 я поставил от балды, т.к. не знаю какой там должен быть правильный, чтобы по нему определить наличие отсутствия Unicode. Кстати, это новая версия (у меня её не было) и там нет необходимости в ZD*.DLL файлах для распаковки - соответствующая библиотека статически слинкована с программой, что очень удобно. Спасибо сказали:
|
Axsis |
![]()
Сообщение
#11
|
Advanced Member ![]() ![]() ![]() Группа: CTPAX-X Сообщений: 121 Регистрация: 6-February 08 Пользователь №: 374 Спасибо сказали: 149 раз(а) ![]() |
Итак, возвращаясь к теме распаковки InstallShield'а с заголовком, а то моё "чуть позже" и так затянулось...
![]() Давным-давно были версии IS, в которых файлы в оверлее лежали в открытом виде. Потом разработчики сделали шифрование каждого файла в псевдоархиве. Потом они сделали шифрование не целиком всего файла, а блоками по 1024 байта, видимо, чтоб не грузить файл в память целиком. И последнее нововведение - файлы теперь ещё и сжаты перед шифрованием (zlib). Скрипт поддерживает все (вроде) данные типы. Однако, когда я реализовал расшифровку средствами самого BMS, то работало оно жутко медленно - у меня скорость была порядка 1 Мб в секунду, и ждать, например, по полторы-две минуты на расшифровке 100 мегабайтного файла быстро надоело. Поэтому, почитав в очередной раз справку по QuickBMS, я решил переписать функцию расшифровки на асме и вызывать её из скрипта. Быстрее стало в буквальном смысле на порядок, тот же файл распаковался примерно за 10 сек. Собственно рабочая версия скрипта: CODE IDString "InstallShield\x00" #Get ASZ ASize Set MEMORY_FILE2 binary "\x55\x89\xE5\x8B\x75\x08\x8B\x7D\x10\x8B\x4D\x14\xC1\xE9\x02\x36\x81\x34\x8F\xEC\xCA\x79\xF8\x85\xC9\x74\x03\x49\xEB\xF1\x31\xD2\x31\xDB\x8A\x04\x31\xC0\xC0\x04\x32\x04\x3A\x42\x3B\x55\x14\x75\x02\x31\xD2\x43\x3B\x5D\x18\x75\x04\x31\xDB\x31\xD2\x88\x04\x31\x41\x3B\x4D\x0C\x75\xDC\x5D\xC3" Get FILES Long GoTo 0x1C 0 SEEK_CUR For i = 0 < FILES GetDString NAME 0x100 Get DUMMY Long Get TYPE Long Get DUMMY Long Get SIZE Long Get DUMMY Long Get DUMMY Long Get COMPRESSED Long GetDString DUMMY2 0x1C SavePos OFFSET If TYPE == 0 Log NAME OFFSET SIZE ElseIf TYPE == 2 Set CHUNKSZ Short 0 CallFunction DecryptFile ElseIf TYPE == 6 Set CHUNKSZ Short 1024 CallFunction DecryptFile Else Print "Unsupported type (%TYPE%) of file %NAME%" EndIf Math OFFSET += SIZE GoTo OFFSET Next i StartFunction DecryptFile Set KEY NAME StrLen KEYSZ NAME Log MEMORY_FILE OFFSET SIZE ################################################################### # IShield.DeCrypt (&Buffer, BufferSize, &Key, KeySize, ChunkSize) # ################################################################### CallDll MEMORY_FILE2 0 cdecl "" MEMORY_FILE SIZE &KEY KEYSZ CHUNKSZ If COMPRESSED == 0 Log NAME 0 SIZE MEMORY_FILE Else ComType zlib CLog NAME 0 SIZE 0x10000000 MEMORY_FILE EndIf EndFunction При расшифровке QuickBMS спросит можно ли вызвать функцию из MEMORY_FILE2 - нужно ему разрешить ![]() Ну и тестовая версия с расшифровкой на самом BMS: CODE IDString "InstallShield\x00" #Get ASZ ASize Get FILES Long GoTo 0x1C 0 SEEK_CUR For i = 0 < FILES GetDString NAME 0x100 Get DUMMY Long Get TYPE Long Get DUMMY Long Get SIZE Long Get DUMMY Long Get DUMMY Long Get COMPRESSED Long GetDString DUMMY2 0x1C SavePos OFFSET If TYPE == 0 Log NAME OFFSET SIZE ElseIf TYPE == 2 Set CHUNKSZ Short 0 CallFunction DecryptFile ElseIf TYPE == 6 Set CHUNKSZ Short 1024 CallFunction DecryptFile Else Print "Unsupported type (%TYPE%) of file %NAME%" EndIf Math OFFSET += SIZE GoTo OFFSET Next i StartFunction DecryptFile Set KEY1 NAME Set KEY2 Binary \xEC\xCA\x79\xF8 StrLen KEYSZ NAME Set CO 0 # CHUNK_OFFSET Set KO 0 # KEY_OFFSET String KEY1 ^ KEY2 # Print "New KEY1 is %KEY1%" Log MEMORY_FILE OFFSET SIZE For j = 0 < SIZE GetVarChr TMP1 MEMORY_FILE j # Decrypt stage 1 # Set TMP2 Byte TMP1 Math TMP1 r 4 Math TMP2 l 4 Math TMP1 | TMP2 # Decrypt stage 2 # GetVarChr TMP2 KEY1 KO Math TMP1 ^ TMP2 Math KO += 1 If KO == KEYSZ Math KO = 0 EndIf Math CO += 1 If CO == CHUNKSZ Math CO = 0 Math KO = 0 EndIf PutVarChr MEMORY_FILE j TMP1 Next j If COMPRESSED == 0 Log NAME 0 SIZE MEMORY_FILE Else ComType zlib CLog NAME 0 SIZE 0x10000000 MEMORY_FILE EndIf EndFunction Повторюсь, эта версия довольно медленная и никак не сообщает работает она или же висит. Я пробовал добавить вывод некоего "прогресс-бара", но тогда скрипт работает ещё медленнее. ![]() PS: И сам алгоритм шифрования: DecodedData = ByteSwap(EncodedData) XOR (FileName.ext XOR 0xECCA79F8). ByteSwap - обмен местами младших и старших 4 бит в байте, как в 3Дмарках. FileName.ext - имя сохраняемого файла, используется как ключ, поэтому регистр важен. В EncodedData либо весь файл сразу, либо блоками по 1024 байта - в зависимости от версии IS. Спасибо сказали:
|
-=CHE@TER=- |
![]()
Сообщение
#12
|
Walter Sullivan ![]() ![]() ![]() Группа: Root Admin Сообщений: 1,360 Регистрация: 4-February 08 Пользователь №: 3 Спасибо сказали: 313 раз(а) ![]() |
Спасибо большое!
Убрал твой код в codebox, а то он сильно страницу форума раздувал. Однако, когда я реализовал расшифровку средствами самого BMS, то работало оно жутко медленно - у меня скорость была порядка 1 Мб в секунду, и ждать, например, по полторы-две минуты на расшифровке 100 мегабайтного файла быстро надоело. Хех, поэтому я до сих пор предпочитаю классические языки программирования. У меня для каждого типа распаковщика есть шаблон (по сути уже написанная когда-то программа). В 5 минут из неё выкидывается лишнее и добавляется что надо. Все дела.Поэтому, почитав в очередной раз справку по QuickBMS, я решил переписать функцию расшифровки на асме и вызывать её из скрипта. Ты бы код своей функции (я так понимаю это .DLL файл?) выложил тоже чтобы не писать если понадобится.Кстати, вопрос: FileName.ext XOR 0xECCA79F8 FileName.ext же может быть сколь угодно длинным - как его на DWORD-то XOR'ить?.. Что-то я не понял этот момент совсем. |
Axsis |
![]()
Сообщение
#13
|
Advanced Member ![]() ![]() ![]() Группа: CTPAX-X Сообщений: 121 Регистрация: 6-February 08 Пользователь №: 374 Спасибо сказали: 149 раз(а) ![]() |
Кстати, вопрос: FileName.ext XOR 0xECCA79F8 FileName.ext же может быть сколь угодно длинным - как его на DWORD-то XOR'ить?.. Что-то я не понял этот момент совсем. Немного некорректно выразился, там не 0xECCA79F8 а массив байт 0xEC, 0xCA, 0x79, 0xF8. Длина имени любая, 5-ый символ в строке xor'ится опять первым байтом массива, 6-й - вторым, и т.д. Если вставить байтики из "Set MEMORY_FILE2 binary "\x55\x89\xE5\x8B\x75\x08..." в ольку, то можно получить примерно следующее: CODE CPU Disasm Address Hex dump Command Comments 00401000 /. 55 PUSH EBP 00401001 |. 89E5 MOV EBP,ESP 00401003 |. 8B75 08 MOV ESI,DWORD PTR SS:[EBP+8] 00401006 |. 8B7D 10 MOV EDI,DWORD PTR SS:[EBP+10] 00401009 |. 8B4D 14 MOV ECX,DWORD PTR SS:[EBP+14] 0040100C |. C1E9 02 SHR ECX,2 0040100F |> 36:81348F ECCA79F8 /XOR DWORD PTR SS:[ECX*4+EDI],F879CAEC 00401017 |. 85C9 |TEST ECX,ECX 00401019 |. 74 03 |JE SHORT 0040101E 0040101B |. 49 |DEC ECX 0040101C |.^ EB F1 \JMP SHORT 0040100F 0040101E |> 31D2 XOR EDX,EDX 00401020 |. 31DB XOR EBX,EBX 00401022 |> 8A0431 /MOV AL,BYTE PTR DS:[ESI+ECX] 00401025 |. C0C0 04 |ROL AL,4 00401028 |. 32043A |XOR AL,BYTE PTR DS:[EDI+EDX] 0040102B |. 42 |INC EDX 0040102C |. 3B55 14 |CMP EDX,DWORD PTR SS:[EBP+14] 0040102F |. 75 02 |JNE SHORT 00401033 00401031 |. 31D2 |XOR EDX,EDX 00401033 |> 43 |INC EBX 00401034 |. 3B5D 18 |CMP EBX,DWORD PTR SS:[EBP+18] 00401037 |. 75 04 |JNE SHORT 0040103D 00401039 |. 31DB |XOR EBX,EBX 0040103B |. 31D2 |XOR EDX,EDX 0040103D |> 880431 |MOV BYTE PTR DS:[ESI+ECX],AL 00401040 |. 41 |INC ECX 00401041 |. 3B4D 0C |CMP ECX,DWORD PTR SS:[EBP+0C] 00401044 |.^ 75 DC \JNE SHORT 00401022 00401046 |. 5D POP EBP 00401047 \. C3 RETN Нормального исходника нет, так как писал и сразу отлаживал непосредственно в ольке. ![]() Спасибо сказали:
|
Axsis |
![]()
Сообщение
#14
|
Advanced Member ![]() ![]() ![]() Группа: CTPAX-X Сообщений: 121 Регистрация: 6-February 08 Пользователь №: 374 Спасибо сказали: 149 раз(а) ![]() |
Есть такая утилита как InstallShield 5.x/6.x Cabinet Compression & Maintenance Util (i5comp.exe / i6comp.exe). У меня к ней даже где-то исходные коды на сях валяются, попробую поковырять... Добавлено: Распаковщик: i6compx.zip Unicode, правда, не поддерживается (тупо переводится в ANSI с заменой на "_" левых символов), но главное, что оно всё правильно распаковывает. Флаг 0x04000000 я поставил от балды, т.к. не знаю какой там должен быть правильный, чтобы по нему определить наличие отсутствия Unicode. Кстати, это новая версия (у меня её не было) и там нет необходимости в ZD*.DLL файлах для распаковки - соответствующая библиотека статически слинкована с программой, что очень удобно. Недавно понадобилось распаковать одну прогу, обнаружил что имена директорий в CAB'ах там обрабатываются отдельно - при распаковке каталога от его имени остаётся только первый символ (т.к. тот же юникод, и второй байт, равный 0, считается как конец строки). Глянул исходник, вроде нашел где надо поправить, только вот в Visual Studio 2010 проект не захотел импортироваться ![]() Похоже, обработка имён каталогов идёт тут (i6comp.c): CODE LPDIRARRAY DirsArrayBuild(DFTABLE DFT) { LPDIRARRAY pDs; DWORD i; pDs = Alloc(sizeof(DIRARRAY) + pCabDesc->cDirs * sizeof(LPSTR)); for (i = 0; i < pCabDesc->cDirs; i++) pDs->Dirs[i] = strdup(GetString(DFT, DFT[i])); pDs->Count = pCabDesc->cDirs; return pDs; } По аналогии с твоим фиксом для имён файлов, здесь должно быть что-то вроде CODE LPDIRARRAY DirsArrayBuild(DFTABLE DFT) { LPDIRARRAY pDs; DWORD i; char stmp[MAX_PATH]; // CXTP pDs = Alloc(sizeof(DIRARRAY) + pCabDesc->cDirs * sizeof(LPSTR)); for (i = 0; i < pCabDesc->cDirs; i++) // CXTP/ if(CabHdr.Version & 0x04000000){ stmp[0] = '\0'; WideCharToMultiByte(CP_ACP, 0, GetString(DFT, DFT[i]), -1, stmp, MAX_PATH, "_", NULL); pDs->Dirs[i] = strdup(stmp); }else{ pDs->Dirs[i] = strdup(GetString(DFT, DFT[i])); } // /CXTP pDs->Count = pCabDesc->cDirs; return pDs; } Спасибо сказали:
|
-=CHE@TER=- |
![]()
Сообщение
#15
|
Walter Sullivan ![]() ![]() ![]() Группа: Root Admin Сообщений: 1,360 Регистрация: 4-February 08 Пользователь №: 3 Спасибо сказали: 313 раз(а) ![]() |
Ага, спасибо, исправил и пересобрал - лежит там же. Пробуй. Мне, увы, проверить не на чем.
Спасибо сказали:
|
Axsis |
![]()
Сообщение
#16
|
Advanced Member ![]() ![]() ![]() Группа: CTPAX-X Сообщений: 121 Регистрация: 6-February 08 Пользователь №: 374 Спасибо сказали: 149 раз(а) ![]() |
Фокус не удался.
![]() Там походу имена каталогов привязаны к именам так называемых файловых групп. Чтоб всё работало, там надо либо патчить GetString() либо править все её вызовы. Спасибо сказали:
|
-=CHE@TER=- |
![]()
Сообщение
#17
|
Walter Sullivan ![]() ![]() ![]() Группа: Root Admin Сообщений: 1,360 Регистрация: 4-February 08 Пользователь №: 3 Спасибо сказали: 313 раз(а) ![]() |
Это макрос из "is6cab.h":
CODE #define GetString(ptr, ofs) ( (LPSTR) (((BYTE*)ptr) + ((DWORD)ofs)) ) Я вот, подумал, может тупо UNICODE версию собрать? Кстати, почему у тебя в 2010 не собирается? Что за ошибка-то? Попробуй вот эту версию заимпортить - я вручную пересобрал проект: i6comp2x.zip |
Axsis |
![]()
Сообщение
#18
|
Advanced Member ![]() ![]() ![]() Группа: CTPAX-X Сообщений: 121 Регистрация: 6-February 08 Пользователь №: 374 Спасибо сказали: 149 раз(а) ![]() |
Ну в смысле переделать его в функцию с проверкой if(CabHdr.Version & 0x04000000), и либо возвращать указатель на строку (как сейчас и есть), либо конвертировать исходную строку из юникода в ascii в память и возвращать указатель на неё.
Ну или правда сделать юникодную версию i17comp ![]() Что прошлые версии, что эта - открываю в VS2010 проект, предлагает сконвертировать из старого в свой формат, соглашаюсь, и всё - пустое окно студии ни ошибок не пишет - ничего. Думаю, быть может из-за того что она у меня Express? Если попытаться создать проект из файлов - что-то ругается про .NET 4 ![]() |
-=CHE@TER=- |
![]()
Сообщение
#19
|
Walter Sullivan ![]() ![]() ![]() Группа: Root Admin Сообщений: 1,360 Регистрация: 4-February 08 Пользователь №: 3 Спасибо сказали: 313 раз(а) ![]() |
Возвращаясь к этой теме 11 лет спустя.
Мне пришло письмо с просьбой помочь не только с распаковкой, но и запаковкой назад (это нужно, чтобы не переписывать сложную логику установки оригинального пакета) новых InstallShield, которые в Unicode имена файлов хранят. Кстати, кому интересно только для распаковки есть программа: https://github.com/lifenjoiner/ISx И более навороченная версия: https://github.com/twogood/unshield В описании к обеим указано, что они основаны на i5comp/i6comp. Но так как там нет упаковки от слова "совсем", а мне браться за исходные коды i6comp очень не хотелось, то, в итоге, сделал другое решение, которое опишу здесь, возможно, кому-нибудь ещё пригодится. 1. Есть штатная утилита "ISCAB.exe" для запаковки, распаковки, удаления и добавления файлов в .CAB архивы, но последняя версия InstallShield, где эта утилита была, это InstallShield 2009, которая Unicode не поддерживала. Но мы это поправим, поэтому ищем в Интернете установочный пакет InstallShield 2009 версии Premier Edition или Professional (главное, не Express Edition) и берём оттуда файл "ISCAB.exe". 2. Далее идём вот сюда (ссылка) и берём там архив "ISCABViewer2016" - оттуда нужно два файла: "ISTools.dll" и "MediaBuild40.dll" (возможно, эти файлы можно взять из InstallShield 2016). 3. Кидаем файлы из п.1 и п.2 в один каталог. Далее исправляем в "MediaBuild40.dll" следующие байты любым шестнадцатеричным (hex) редактором (смещение: старый_байт новый_байт): CODE InstallShield 2016 / MediaBuild40.dll / 23.0.0.511 ; offset:old new ; allow to run under Windows NT 5+ (2000/XP+) instead 6+ (Vista+) 00000170: 06 05 00000178: 06 05 ; fix invalid memory operations 00023765: 8B 8D 000239EB: A1 B8 00023A04: A1 B8 Я не знаю почему, но в этой .DLL делаются какие-то странные операции с памятью и я откровенно не понимаю как оно, вообще, могло работать. Ну, да ладно, починили. 4. Теперь нужно распаковать пакет перед изменением. Пусть у нас будет каталог C:\DATA\, тогда размещаем файлы следующим образом: CODE C:\DATA\ISCab\ ISTools.dll MediaBuild40.dll ISCAB.exe C:\DATA\files\ layout.bin data2.cab data1.cab ISSetup.dll setup.exe data1.hdr setup.ini 0x0409.ini setup.inx setup.iss C:\DATA\files2\ layout.bin data2.cab data1.cab ISSetup.dll setup.exe data1.hdr setup.ini 0x0409.ini setup.inx setup.iss Обращаю ваше внимание, что содержимое каталогов "files" и "files2" должно быть одинаковым перед началом перепаковки! Если список файлов не совпадает с вашими - ничего страшного, просто положите все файлы установщика, какие у вас есть, в каталог "files" и сделайте копию в "files2". 5. Перед распаковкой нужно создать список файлов внутри .CAB архивов вызвав в консоли (как работать с консолью описано здесь) из каталога C:\DATA\ следующую команду: CODE ISCab\ISCAB.exe files\data1.cab -lx -ifiles.ini 6. Неочевидный момент - почему-то распаковщик не будет работать, если файлы упакованы в .CAB архивах не просто так, а с путями. Поэтому открываем файл "files.ini" и смотрим, есть ли там пути, и, если есть, то создаём их. Например, если видим такое: CODE [ProgramFiles(x86)] File1="CompanyName\SoftwareName\config.exe" Это значит, что придётся создавать в каталоге C:\DATA\ путь "CompanyName\SoftwareName" - получится такое: C:\DATA\CompanyName\SoftwareName\ Иначе распаковка будет останавливаться с ошибкой и вы не распакуете все файлы! Я глубоко вопрос не изучал, возможно, "ISCAB.EXE" просто не был рассчитан на распаковку с путями. 7. Теперь файлы можно распаковывать следующей командой (из того же каталога C:\DATA\): CODE ISCab\ISCAB.exe files\data1.cab -x -ifiles.ini 8. Всё готово - можно заменять нужные файлы. 9. Перед упаковкой назад делаем копию файла "files.ini" в "files2.ini", находим там строчки: CODE [<Disk1>Disk1 Files(1)] File1="layout.bin" File2="data1.hdr" File3="data1.cab" [<Disk1>Disk1 Files(2)] File1="setup.exe" File2="ISSetup.dll" File3="0x0409.ini" [<Disk1>Disk1 Files(3)] File1="setup.inx" [<Disk1>Disk1 Files(4)] File1="setup.ini" И все такие строчки (секции [<Disk#>Disk# Files(#)] с именами файлов далее) удаляем, либо комментируем добавляя в начало строки символ ";". Если этого не сделать упаковка будет вылетать с ошибкой! 10. Вот теперь можно упаковывать назад командой (всё из того же каталога C:\DATA\): CODE ISCab\ISCAB.exe files2\data1.cab -a -ifiles2.ini Обратите внимание, что вместо "files" в обоих случаях стоит "files2" - во-первых, мы не трогаем оригинальный архив, на случай если что-то пойдёт не так, чтобы можно было снова распаковать оригинал, а, во-вторых, в качестве листинга файлов используется "files2.ini", где мы убрали секции Disk# мешающие запаковке. В общем-то, это всё, можно тестировать результат из каталога "files2". Обратите внимание, чтобы при распаковке/упаковке в консоль не выводились ошибки - это будет означать что операция была аварийно прервана и не дошла до конца! Теоретически можно сократить файл "files2.ini" только до одной записи - секции и файла, который нужен, распаковать (опция "-x"), удалить (опция "-r"), затем добавить новый (опция "-a"), а не перепаковывать весь архив. Но я такое не пробовал, возможно, там есть какие-то подводные камни - если кто захочет, то может поэкспериментировать. Для автоматизации п.6 (создание каталогов) и п.9 (удаление лишнего) можно воспользоваться вот таким скриптом: iconvert.vbs: CODE Option Explicit Dim objFS, objFile, objTempFile, objRE, objDir, objMatches Dim isCopy, strLine, strPath, I, S Set objFS = CreateObject("Scripting.FileSystemObject") Set objFile = objFS.OpenTextFile("files.ini") Set objTempFile = objFS.CreateTextFile("files2.ini", True) ' http://www.script-coding.com/WSH/RegExp.html Set objRE = CreateObject("VBScript.RegExp") objRE.IgnoreCase = False isCopy = False Set objDir = CreateObject("Scripting.FileSystemObject") Do Until objFile.AtEndOfStream strLine = objFile.ReadLine ' not empty line If (Len(Trim(strLine)) > 0) Then ' section? objRE.Pattern = "^\s*\[.*\]\s*$" If (objRE.Test(strLine)) Then ' section name objRE.Pattern = "<Disk\d+>Disk\d+\s+Files\(\d+\)" ' do not copy reserved section isCopy = Not objRE.Test(strLine) Else ' line value objRE.Pattern = "^\s*File\d+\s*=\s*""(.+)""\s*$" If (objRE.Test(strLine)) Then ' create folders Set objMatches = objRE.Execute(strLine) strPath = objMatches.Item(0).SubMatches(0) For I = 1 To Len(strPath) If (Mid(strPath, I, 1) = "\") Then S = Mid(strPath, 1, I - 1) ' folder do not exists If (Not objDir.FolderExists(S)) Then objDir.CreateFolder S End If End If Next End If End If End If ' Write the modified line to the temporary file If (isCopy = True) Then objTempFile.WriteLine(strLine) End If Loop ' Close both files objFile.Close objTempFile.Close |
![]() ![]() |
Упрощённая версия | Сейчас: 12th September 2024 - 10:57 |