Автор Тема: проблема открытия файла специфического формата  (Прочитано 13045 раз)

Оффлайн rususer

  • Новичок
  • *
  • Сообщений: 5
Здравствуйте! Хочу перевести программу Reallusion CrazyTalk Animator v1.01 PRO (подробнее о программе на офсайте)
Основная масса текста находится в файле: GUIResource.msx
Он очень похож на обычные ресурсы исполняемых файлов, но видимо обрезан и обычные редакторы ресурсов его не открывают. Через HEX редактор все строки просматриваются.
 Посоветуйте чем открыть для удобного редактирования?

Заранее блогодарен.

Оффлайн VIPer

  • Модератор
  • Ветеран
  • *****
  • Сообщений: 1063
rususer, что-то ссылка у меня не открывается.

Попробуйте воспользоваться программой Radialix.

СССР

Оффлайн rususer

  • Новичок
  • *
  • Сообщений: 5
Спасибо попробую.
А пока вот зеркало: http://zalil.ru/30132591

-------------------------
проверил. не открывает.
« Последнее редактирование: 13 Декабря 2010, 16:19:28 от rususer »

Оффлайн VIPer

  • Модератор
  • Ветеран
  • *****
  • Сообщений: 1063
rususer, сжат особым компилятором. К сожалению, без помощи "разрабов" здесь никак не обойтись

СССР

Оффлайн rususer

  • Новичок
  • *
  • Сообщений: 5
Да действительно это некий контейнер с файлами. Внутри: *jpg, *.bmp, *.cnt и *.ini (собственно нужный мне текст). В других продуктах на месте этого файла лежит просто куча этих внутренних файлов россыпью.
 Взглянул я ещё разок на это дело из HEX редактора и начала прорисовываться структура архива. Всё как на ладони:
1. Первые 4 байта содержат информацию о количестве файлов в контейнере (пример: A7020000, переворачиваем 000002A7, переводим в десятичную систему 679)
2. Далее 4 байта с информацией о количестве символов в имене файла, которое идёт следом (преобразование такоеже как с количеством)
3. Имя файла. 1 символ занимает 2 байта (видимо юникод какойто)
4. После имени файла идут 4 байта с информацией о смещении его в этом контейнере (просто перевернуть)
5. Потом 4 байта с информацией о размере файла (перевернуть и преобразовать в десятичное значение)
6. Всё по кругу, пока не переберём всё файлы...

Буду писать программу распаковщик.

з.ы.
Разрабы нам не помощники)). Для них мы взломщики, а не локализаторы.
« Последнее редактирование: 13 Декабря 2010, 19:09:48 от rususer »

Оффлайн mcmimik

  • Постоялец
  • ***
  • Сообщений: 106
    • http://mcmimik.blogspot.com
Цитата: rususer
Да действительно это некий контейнер с файлами. Внутри: *jpg, *.bmp, *.cnt и *.ini (собственно нужный мне текст). В других продуктах на месте этого файла лежит просто куча этих внутренних файлов россыпью.
 Взглянул я ещё разок на это дело из HEX редактора и начала прорисовываться структура архива. Всё как на ладони:
1. Первые 4 байта содержат информацию о количестве файлов в контейнере (пример: A7020000, переворачиваем 000002A7, переводим в десятичную систему 679)
2. Далее 4 байта с информацией о количестве символов в имене файла, которое идёт следом (преобразование такоеже как с количеством)
3. Имя файла. 1 символ занимает 2 байта (видимо юникод какойто)
4. После имени файла идут 4 байта с информацией о смещении его в этом контейнере (просто перевернуть)
5. Потом 4 байта с информацией о размере файла (перевернуть и преобразовать в десятичное значение)
6. Всё по кругу, пока не переберём всё файлы...
[a href="http://img695.imageshack.us/img695/903/crazyx.png" target="_blank"]

Цитировать
з.ы.
Разрабы нам не помощники)). Для них мы взломщики, а не локализаторы.
Это смотря как напишите.

Оффлайн shkiper

  • Модератор
  • Ветеран
  • *****
  • Сообщений: 1095
rususer, красавец  Сам догадался, сам расписал и сам программу напишешь. Одна просьба - когда программа будет написана, поделись с общественностью. Возможно еще кому-нибудь пригодится.
DJ, sex, music and a rhythm...

Оффлайн rususer

  • Новичок
  • *
  • Сообщений: 5
Готово!

Реализовал только распаковку. CrazyTalk Animator подхватывает распакованные данные без проблем.
При распаковке рядом с архивом создаётся каталог с именем типа GUIResource.msx_unpacked и в него валятся все файлы.
Прога в аттаче.

з.ы.
Если кому нужна полная версия CrazyTalk Animator могу скинуть ссылку (на офсайте кастрированное ДЕМО)
« Последнее редактирование: 14 Декабря 2010, 09:45:23 от rususer »

Оффлайн VIPer

  • Модератор
  • Ветеран
  • *****
  • Сообщений: 1063
rususer, молодцы!

А Вы бы не могли также дать исходный код? Очень хотелось бы понять алгоритм распаковки.
« Последнее редактирование: 14 Декабря 2010, 15:17:34 от VIPer »

СССР

Оффлайн rususer

  • Новичок
  • *
  • Сообщений: 5
Язык AutoIt, код:
Что-то в стандартном теге[code] всё криво, а в цитате не держит отступы слева
Цитировать
; ----------------------------------------------------------------------------
; AutoIt Version: 3.3.6.1
; Author: ynbIpb
; ScriptName: Reallusion's MSX Unpacker v.0.1 (14.12.2010)
; Script Function: Editing Reallusion's Arhive
; ----------------------------------------------------------------------------

#NoTrayIcon
#include
<ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <ProgressConstants.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>

$sProgName = "MSX Unpacker v.0.1"

$Form1 = GUICreate($sProgName, 260, 114)
$Input1 = GUICtrlCreateInput("", 4, 4, 252, 21, BitOR($ES_READONLY, $ES_LEFT, $ES_AUTOHSCROLL))
$Progress1 = GUICtrlCreateProgress(4, 29, 252, 17)
GUICtrlSetState ($Progress1, $GUI_HIDE) ; скрываем прогрессбар
$Button1 = GUICtrlCreateButton("Pack", 4, 54, 60, 25)
GUICtrlSetState ($Button1, $GUI_DISABLE) ; отключаем кнопку, так как функционал упаковки не готов.
$Button2 = GUICtrlCreateButton("Unpack", 196, 54, 60, 25)
$Label1 = GUICtrlCreateLabel("Reallusion's MSX Unpacker v.0.1  ( icq: 221221576 )", 4, 93, 252, 17)
;GUICtrlSetBkColor($Label1, 0xFFFF00)
GUISetState(@SW_SHOW)

While 1
   $nMsg = GUIGetMsg()
   Switch $nMsg
       Case $GUI_EVENT_CLOSE
           Exit
       Case
$Button2
           _unpack()
   EndSwitch
WEnd


; функция распаковки контейнера
Func _unpack()
   GUICtrlSetData ($Input1, ""); очищаем инпут
   GUICtrlSetData ($Label1, ""); очищаем лейбл
   $sMsxFilePath = FileOpenDialog ("Select MSX file", @ScriptDir, "Reallusion's MSX Archive (*.msx)", 1)
   If $sMsxFilePath = "" Then ; если ничего не выбрано, то возвращаемся из функции
       GUICtrlSetData ($Label1, "File not selected.")
       Return
   EndIf

   GUICtrlSetData ($Input1, $sMsxFilePath) ; установливаем путь к файлу в инпут
   $hMsxFile = FileOpen ($sMsxFilePath, 16) ; открываем файл для чтения в бинарном режиме
   $bMsxFile = FileRead ($hMsxFile); читаем файл в память
   FileClose ($hMsxFile) ; закрываем файл
   $iFlesQty = Dec (Hex (_Rotate (BinaryMid ($bMsxFile, 1 , 4)))); получаем количество файлов
   If $iFlesQty = 0 Then Return ; если количество равно нулю, то возвращаемся из функции
   $iStartPos = 5 ; позиция с которой начинаются данные файлов
   GUICtrlSetState ($Progress1, $GUI_SHOW) ; отображаем прогресс
   GUICtrlSetData ($Label1, "Please Wait...")
   For $i= 1 To $iFlesQty ; крутим цикл столько раз, сколько файлов в архиве
       $iStrLen = Dec (Hex (_Rotate (BinaryMid ($bMsxFile, $iStartPos , 4)))); читаем количество символов
       $iStartPos += 4 ; прибавляем к позиции сдвиг на 4 байта
       $sFileName = BinaryMid ($bMsxFile, $iStartPos , $iStrLen * 2) ; читаем из архива фразмент с именем файла, количество символов умножено на 2, так как 1 символ 2 байта
       $sFileName = BinaryToString ($sFileName, 2) ; преобразуем бинарные данные в строку, учитывая, что это UTF16 Little Endian
       $iStartPos += $iStrLen * 2 ; сдвигаемся
       $iFileOffset = Dec (Hex (_Rotate (BinaryMid ($bMsxFile, $iStartPos , 4)))); читаем оффсет файла в архиве
       $iStartPos += 4 ; сдвигаемся
       $iFileSize = Dec (Hex (_Rotate (BinaryMid ($bMsxFile, $iStartPos , 4)))); читаем размер файла
       $iStartPos += 4 ; сдвигаемся
       $hUnpackedFile = FileOpen ($sMsxFilePath & "_unpacked\" & $sFileName, 2+8+16) ; открываем файл для записи c затиранием старого в бинарном режиме, создавая директорию, если её нет
       If $hUnpackedFile = -1 Then
           GUICtrlSetData ($Label1, "Error!")
           Return
       EndIf

       FileWrite ($hUnpackedFile, BinaryMid ($bMsxFile, $iFileOffset+1, $iFileSize))
       FileClose ($hUnpackedFile) ; закрываем файл
       $iPercent = Ceiling ($i * 100 / $iFlesQty) ; расчитываем процент выполнения и сразу округляем его до целого числа
       If $iPercent > GUICtrlRead ($Progress1) Then GUICtrlSetData ($Progress1, $iPercent) ; если значение больше имеющегося, то устанавливаем его на прогресс
       sleep (50); небольшая задержка, чтоб не грузить процессор
   Next
   GUICtrlSetState ($Progress1, $GUI_HIDE) ; скрываем прогрессбар
   GUICtrlSetData ($Label1, "Done!")
EndFunc

; ~~~~~~~~~~~~~~~~~~ функция переворачивания байтов ~~~~~~~~~~~~~~~~~~~
; $bBbytesToRotate - бинарные данные, которые надо перевернуть
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Func _Rotate($bBytesToRotate)
   If IsBinary ($bBytesToRotate) = 0 Then Return "" ; если переданные данные не являются бинарными, возвращаем из функции пустоту
   $iLenB = BinaryLen ($bBytesToRotate) ; определяем количество байт
   $sRotatedBytes = Binary (""); объявляем переменную, в которой будет перевёрнутое значение
   For $i = $iLenB To 1 step -1; крутим цикл от максимального значения до 1
       $sRotatedBytes &= BinaryMid ($bBytesToRotate, $i, 1); выбираем по 1 байту с конца
   Next
   Return
$sRotatedBytes; возвращаем перевёрнутые байты
EndFunc
« Последнее редактирование: 14 Декабря 2010, 15:48:31 от rususer »