MSI Lab - Форум по русификации
Основные форумы => RusMe - РусМи! => Тема начата: rususer от 13 Декабря 2010, 14:20:47
-
Здравствуйте! Хочу перевести программу Reallusion CrazyTalk Animator v1.01 PRO (подробнее о программе на офсайте (http://www.reallusion.com/crazytalk/animator/default.aspx))
Основная масса текста находится в файле: GUIResource.msx (http://ultrashare.de/f/4951/GUIResource.rar.html)
Он очень похож на обычные ресурсы исполняемых файлов, но видимо обрезан и обычные редакторы ресурсов его не открывают. Через HEX редактор все строки просматриваются.
Посоветуйте чем открыть для удобного редактирования?
Заранее блогодарен.
-
rususer, что-то ссылка у меня не открывается.
Попробуйте воспользоваться программой Radialix.
-
Спасибо попробую.
А пока вот зеркало: http://zalil.ru/30132591 (http://zalil.ru/30132591)
-------------------------
проверил. не открывает.
(http://img577.imageshack.us/img577/3278/zzzz1d.th.jpg) (http://img577.imageshack.us/img577/3278/zzzz1d.jpg)
-
rususer, сжат особым компилятором. К сожалению, без помощи "разрабов" здесь никак не обойтись
-
Да действительно это некий контейнер с файлами. Внутри: *jpg, *.bmp, *.cnt и *.ini (собственно нужный мне текст). В других продуктах на месте этого файла лежит просто куча этих внутренних файлов россыпью.
Взглянул я ещё разок на это дело из HEX редактора и начала прорисовываться структура архива. Всё как на ладони:
1. Первые 4 байта содержат информацию о количестве файлов в контейнере (пример: A7020000, переворачиваем 000002A7, переводим в десятичную систему 679)
2. Далее 4 байта с информацией о количестве символов в имене файла, которое идёт следом (преобразование такоеже как с количеством)
3. Имя файла. 1 символ занимает 2 байта (видимо юникод какойто)
4. После имени файла идут 4 байта с информацией о смещении его в этом контейнере (просто перевернуть)
5. Потом 4 байта с информацией о размере файла (перевернуть и преобразовать в десятичное значение)
6. Всё по кругу, пока не переберём всё файлы...
(http://img695.imageshack.us/img695/903/crazyx.th.png) (http://img695.imageshack.us/img695/903/crazyx.png)
Буду писать программу распаковщик.
з.ы.
Разрабы нам не помощники)). Для них мы взломщики, а не локализаторы.
-
Да действительно это некий контейнер с файлами. Внутри: *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"]
з.ы.
Разрабы нам не помощники)). Для них мы взломщики, а не локализаторы.
Это смотря как напишите.
-
rususer, красавец Сам догадался, сам расписал и сам программу напишешь. Одна просьба - когда программа будет написана, поделись с общественностью. Возможно еще кому-нибудь пригодится.
-
Готово!
(http://img98.imageshack.us/img98/4170/guiiy.jpg)
Реализовал только распаковку. CrazyTalk Animator подхватывает распакованные данные без проблем.
При распаковке рядом с архивом создаётся каталог с именем типа GUIResource.msx_unpacked и в него валятся все файлы.
Прога в аттаче.
з.ы.
Если кому нужна полная версия CrazyTalk Animator могу скинуть ссылку (на офсайте кастрированное ДЕМО)
-
rususer, молодцы!
А Вы бы не могли также дать исходный код? Очень хотелось бы понять алгоритм распаковки.
-
Язык 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