Сейчас на форуме: zds, UniSoft (+5 невидимых)

 eXeL@B —› Программирование —› косяк при переводе с Java на С++
Посл.ответ Сообщение


Ранг: 150.3 (ветеран), 175thx
Активность: 0.160.07
Статус: Участник

Создано: 30 апреля 2013 15:22
· Личное сообщение · #1

доброго времени суток
есть игра - Minecraft, написана на Java.
музыка в ней хранится в зашифрованном виде, а я пытаюсь расшифровать её.
декомпилил код, переписал... и получил облом.
после первых 15 байт расшифровка даёт сбой, и дальше идёт мусор.
кто-нибудь может подсказать, что я не учёл?

в архиве:
1. несколько java файлов, относящихся к выводу звука. сам алго декрипта - в файле MusInputStream.java
2. пример оригинального/зашифрованного файла
3. моя программа. код ужасен, я знаю.






Ранг: 158.5 (ветеран), 219thx
Активность: 0.120.01
Статус: Участник

Создано: 30 апреля 2013 15:28 · Поправил: ZaZa
· Личное сообщение · #2

-=AkaBOSS=-
Посмотрел бегло:
Code:
  1. unsigned int hash = 0;
  2.  
  3. for (int j = 0; j < datasize; j++)
  4. {
  5. buf[j] ^= hash >> 8;
  6. hash = hash * 498729871 + 85731 * buf[j];
  7. }

Переполнения не будет?

В-общем, мне кажется проблема с типами и их границами...

-=AkaBOSS=- пишет:
массив, в котором держатся обрабатываеммые данные, я объявил как unsigned char, и это было БОЛЬШОЙ ошибкой.

Ха... я так и написал ))

-----
One death is a tragedy, one million is a statistic.


| Сообщение посчитали полезным: -=AkaBOSS=-


Ранг: 150.3 (ветеран), 175thx
Активность: 0.160.07
Статус: Участник

Создано: 30 апреля 2013 15:38
· Личное сообщение · #3

ZaZa пишет:
Переполнения не будет?

оно происходит еще на первой итерации.
но код почти один-в-один слизан с джавы.
там ведь тоже должно происходить переполнение... разве нет?



Ранг: 419.0 (мудрец), 647thx
Активность: 0.460.51
Статус: Участник
"Тибериумный реверсинг"

Создано: 30 апреля 2013 16:17
· Личное сообщение · #4

В джавах не силен, но по моему тут присутствует рекурсия:
Code:
  1.     public int read(byte[] par1ArrayOfByte, int par2, int par3) throws IOException
  2.     {
  3.         par3 = this.inputStream.read(par1ArrayOfByte, par2, par3); // <--ВОТ ТУТА
  4.  
  5.         for (int var4 = 0; var4 < par3; ++var4)
  6.         {
  7.             byte var5 = par1ArrayOfByte[par2 + var4] = (byte)(par1ArrayOfByte[par2 + var4] ^ this.hash >> 8);
  8.             this.hash = this.hash * 498729871 + 85731 * var5;
  9.         }
  10.  
  11.         return par3;
  12.     }





Ранг: 150.3 (ветеран), 175thx
Активность: 0.160.07
Статус: Участник

Создано: 30 апреля 2013 16:57
· Личное сообщение · #5

ELF_7719116 пишет:
тут присутствует рекурсия
Code:
  1. par3 = this.inputStream.read(par1ArrayOfByte, par2, par3); // <--ВОТ ТУТА


не похоже что-то
она бы так из этой рекурсии и не вылезла.
Code:
  1. // в конструкторе указано:
  2. this.inputStream = par3InputStream;
  3.  
  4. // а вызывается он (в CodecMus.java) так:
  5. new MusInputStream(this, this.url, this.urlConnection.getInputStream());


ZaZa
нельзя забывать, что хэш инициализируется на основе имени входного файла.
поэтому, к моменту начала расшифровки потока там уже есть какое-то значение.
после первой же итерации наступает переполнение (результат не умещается в регистр).
но, при этом, в джаве хэш тоже объявлен как int, и никаких проблем не возникает (джава установлена х32)
я эту задачу уже с пару недель долблю, так и не понял, где нестыковка.




Ранг: 158.5 (ветеран), 219thx
Активность: 0.120.01
Статус: Участник

Создано: 30 апреля 2013 17:04 · Поправил: ZaZa
· Личное сообщение · #6

-=AkaBOSS=-
В Java int = -2,147,483,648 to 2,147,483,647
C++ unsigned int = 0 to 4,294,967,295
C++ int = –2,147,483,648 to 2,147,483,647

Может попробовать использовать INT вместо UNSIGNED INT

-=AkaBOSS=- пишет:
нельзя забывать, что хэш инициализируется на основе имени входного файла.поэтому, к моменту начала расшифровки потока там уже есть какое-то значение.

Не доглядел... но я ведь предупреждал, что смотрел бегло

-----
One death is a tragedy, one million is a statistic.





Ранг: 136.0 (ветеран), 360thx
Активность: 0.270.14
Статус: Участник
Qt Developer

Создано: 30 апреля 2013 17:19
· Личное сообщение · #7

Открыть два отладчика и по шагам сравнивать результат.

-----
http://ntinfo.biz


| Сообщение посчитали полезным: ZaZa, Abraham, -=AkaBOSS=-


Ранг: 150.3 (ветеран), 175thx
Активность: 0.160.07
Статус: Участник

Создано: 30 апреля 2013 17:33
· Личное сообщение · #8

ZaZa пишет:
Может попробовать использовать INT вместо UNSIGNED INT

пробовал раньше, попробовал еще раз. разницы никакой.
я уже чего только не перепробовал.
даже проверял порядок присвоения здесь:
Code:
  1. byte var5 = par1ArrayOfByte[par2 + var4] = (byte)(par1ArrayOfByte[par2 + var4] ^ this.hash >> 8);

ничего не помогает

hors пишет:
Открыть два отладчика и по шагам сравнивать результат.

стратегия хорошая, но рабочий код на джаве, и даже в условиях JIT компиляции его там фиг найдёшь




Ранг: 136.0 (ветеран), 360thx
Активность: 0.270.14
Статус: Участник
Qt Developer

Создано: 30 апреля 2013 17:38
· Личное сообщение · #9

-=AkaBOSS=- пишет:
стратегия хорошая, но рабочий код на джаве, и даже в условиях JIT компиляции его там фиг найдёшь


Встроенный в eclipse отладчик для java?
Встроенный в Visual Studio отладчик для c++?

-----
http://ntinfo.biz




Ранг: 419.0 (мудрец), 647thx
Активность: 0.460.51
Статус: Участник
"Тибериумный реверсинг"

Создано: 30 апреля 2013 17:48
· Личное сообщение · #10

-=AkaBOSS=- пишет:
она бы так из этой рекурсии и не вылезла.

Эт понятно. Очевидно, строка - аналог fread.

Тогда обращаю внимание на расстановку инкремента В ОРИГИНАЛЕ
Code:
  1.  /* В ОРИГИНАЛЕ */
  2. for (int var4 = 0; var4 < par3; ++var4)

ВАШ ЦПП ВАРИАНТ
Code:
  1.  /*С++ ВАРИАНТ*/
  2. for (int j = 0; j < datasize; j++)





Ранг: 150.3 (ветеран), 175thx
Активность: 0.160.07
Статус: Участник

Создано: 30 апреля 2013 18:09 · Поправил: -=AkaBOSS=-
· Личное сообщение · #11

разобрался таки.
спасибо hors за совет про отладчик.
запустил игру, приаттачился олькой, нашел по константам нужный код, и понял, почему я дурак
массив, в котором держатся обрабатываеммые данные, я объявил как unsigned char, и это было БОЛЬШОЙ ошибкой.
переделал в char, и всё заработало.

проблема решена, тему закрываю


 eXeL@B —› Программирование —› косяк при переводе с Java на С++
Эта тема закрыта. Ответы больше не принимаются.
   Для печати Для печати