Не могу расшифровать эти строки

Преамбула

Я пытаюсь дизассемблировать и реконструировать программу, автора которой давно нет. Программа предоставляет некоторые уникальные функции, которые мне еще предстоит найти где-либо еще, и... Мне любопытно и заинтриговано обратное проектирование программы. Если вы просто попытаетесь помочь мне найти другую программу... не беспокойтесь.

Эта проблема

Я использую IDA Pro с декомпилятором Hex-Rays, чтобы получить приличный псевдокод, чтобы попытаться ускорить обратное проектирование. Одна важная вещь, которая, я думаю, поможет ускорить работу, — это выяснить, что означают строки. Пока что это то, что я нахожу для строк, длина которых превышает 4 символа:

dword_131894E = 54264588;
dword_131894A = 51381002;
dword_1318946 = 51380998;
dword_1318942 = 52429571;
dword_131893E = 52298503;
runtimeVersion[0] = 836;
szIndex = 0;
do
{
  runtimeVersion[szIndex] = (runtimeVersion[szIndex] - 1) ^ (szIndex + 882) ^ 0x47;
  ++szIndex;
}
while ( szIndex < 11 );

Глядя на аналогичный псевдокод для строк, состоящих из трех символов, и используя наведения Hex-Rays для информации о типе, вот как я это понимаю:

  • runtimeVersion является константой wchar
  • это означает, что он имеет символы Unicode (UTF-16)
  • строка встроена в память, но в данном случае слабо зашифрована (XOR?)

Приведенный выше псевдокод одинаков для всех больших строк, за исключением того, что константа «882» отличается для каждой строки. Я предполагаю, что это какое-то шифрование во время компиляции или макрос, который находит строки одну за другой и «шифрует» их уникальным образом. Проблема, однако, в том, что я не могу получить правильно выглядящую строку, реплицируя псевдокод. Вот что у меня есть на С#:

ushort[] newCharArray = new ushort[rawCharacters.Length];

// Go through and decode all of the characters.
ushort i = 0;
do {
    newCharArray[i] = (ushort)((i + 882) ^ (rawCharacters[i] - 1) ^ 0x47);
    ++i;
}
while (i < 11);

'rawCharacters' - это короткий массив. Я делю каждую из этих записей двойного слова пополам и рассматриваю каждую как ushort. Я помещаю их в массив, начиная снизу вверх... Таким образом, значение, присвоенное runtimeVersion[0], сначала добавляется в мой массив, затем значение из dword_131893E, затем dword_1318942 и т. д.

Я не уверен, что мне здесь не хватает. Кажется, что это настолько просто, что это должно быть тортом, чтобы отменить и восстановить строки, но я запутался в преобразовании из псевдокода в реальный код.

Мысли?


person Toby Lawrence    schedule 11.08.2012    source источник
comment
это вообще не связано с '''расшифровкой'''. Возможно, вы имели в виду декодирование, а не дешифрование.   -  person AbiusX    schedule 11.08.2012
comment
Назовите это как хотите. Совершенно очевидно, что большие строки преобразуются из их первоначальной формы во что-то, что должно затруднить их извлечение из исполняемого файла. Для меня это шифрование... но, возможно, для вас SSL - это просто кодировка :P   -  person Toby Lawrence    schedule 11.08.2012
comment
Пробовали ли вы разные варианты, например, использовать xor по-разному или использовать другую кодировку (utf8, utf16 и т. д.)?   -  person Antimony    schedule 11.08.2012
comment
Мое первое предположение состоит в том, что вы загружаете rawCharacters неправильно. Можете ли вы включить источник, который показывает загрузку данных в ваш C# и вывод Hex-Rays объявления RuntimeVersion?   -  person Scott Chamberlain    schedule 11.08.2012
comment
Вы уверены, что найденный вами код шифрует? Я думаю, что строка хранится в зашифрованном виде в исполняемом образе, а программа раскручивает ее обратно во что-то понятное.   -  person jxh    schedule 11.08.2012
comment
Я прочитал преамбулу и сразу понял, что где-то там будет взлом системы безопасности. Также «Если вы просто попытаетесь помочь мне найти другую программу ... не беспокойтесь» - немного пахнет «не так» :(( Мне любопытно и заинтриговано, интересно, с каким приложением вы просите нас помочь взлом?   -  person Martin James    schedule 11.08.2012
comment
@TobyLawrence Как dword_131894E и другие подобные переменные связаны с проблемой? Инициализируется ли runtimeVersion из них?   -  person Ankush    schedule 11.08.2012
comment
@MartinJames Инструмент для связи OBD-II, в первую очередь с ЭБУ Volkswagen ME7.5. Большинство инструментов сканирования ожидают, что у вас будут кабели со вспомогательными микросхемами, которые обрабатывают низкоуровневые тайминги и т. д., но эта программа делает все это сама. Меня это интересует, потому что я хочу воссоздать низкоуровневый материал во встроенном проекте.   -  person Toby Lawrence    schedule 11.08.2012
comment
@Ankush Псевдокод не очень очевиден, но если вы дважды щелкните именованные переменные, они окажутся прямо над двойными словами в данных. Так, например, runtimeVersionSz находится по адресу .data:131893A, а затем сразу после него идет dword_131893E... насколько я могу судить, это странный способ декомпиляции представления этих зашифрованных константных строк.   -  person Toby Lawrence    schedule 11.08.2012


Ответы (1)


Хорошо, работая над листом бумаги, вот что я получаю:

54264588 = 0x033c030c
51381002 = 0x0310030a
51380998 = 0x03100306
52429571 = 0x03200303
52298503 = 0x031E0307
836 = 0x0344
882 = 0x0372

v = 0x0076 = 0x47 ^ 0x0372 ^ (0x0344 - 1)
2 = 0x0032 = 0x47 ^ 0x0373 ^ (0x0307 - 1)
. = 0x002E = 0x47 ^ 0x0374 ^ (0x031E - 1)
0 = 0x0030 = 0x47 ^ 0x0375 ^ (0x0303 - 1)
. = 0x0076 = 0x47 ^ 0x0376 ^ (0x0320 - 1)
5 = 0x0035 = 0x47 ^ 0x0377 ^ (0x0306 - 1)
0 = 0x0030 = 0x47 ^ 0x0378 ^ (0x0310 - 1)
7 = 0x0037 = 0x47 ^ 0x0379 ^ (0x030a - 1)
2 = 0x0032 = 0x47 ^ 0x037a ^ (0x0310 - 1)
7 = 0x0037 = 0x47 ^ 0x037b ^ (0x030c - 1)
\0 = 0x0000 = 0x47 ^ 0x037c ^ (0x033c - 1)

Поэтому строка «v2.0.50727». Я также проверил другой вариант с порядком байтов, но этот выглядит намного лучше. Итак, я знаю, что это не указывает на то, где ваш код неверен, но это должно помочь вам решить его с помощью отладчика/printf.

Изменить: добавлено последние 7 строк.

person Fenster34    schedule 11.08.2012
comment
Я думаю, вы пропустили последние 7 в строке, что делает его v2.0.50727 — текущий номер версии .NET 2. - person Iridium; 11.08.2012
comment
Я только что воспроизвел твою математическую точку. Позвольте мне вернуться к моему коду и выяснить, где я напортачил. - person Toby Lawrence; 11.08.2012
comment
Итак, проблема заключалась в том, как я интерпретировал порядок байтов в двойных словах. В примере, который я привел, я читал данные как: 0x344, 0x31e, 0x307, 0x320 и т. д. Похоже, ваш порядок (сначала два байта справа от каждого двойного слова, затем два первых байта) — вот что помогло. Спасибо, что помогли мне понять это. Это стало чертовски раздражать. :) Кроме того, извините всех, кто просмотрел вопрос и не получил достаточно информации о том, что именно я делал, чтобы дать соответствующий ответ. - person Toby Lawrence; 11.08.2012