IPB

Добро пожаловать, гость ( Вход | Регистрация )

 
Reply to this topicStart new topic
> InstallShield расшифровка Uninst.isu
PavelDAS
Oct 9 2025, 09:00
Сообщение #1


Newbie
*

Группа: Authorized
Сообщений: 6
Регистрация: 21-September 25
Из: Minsk
Пользователь №: 18,037
Спасибо сказали: 0 раз(а)



Необходима помощь в расшифровке файлов InstallShield: Uninst.isu
Там должны храниться пути установки, реестр, ...

Пробовал как-то через IDA 9 подсмотреть, как идёт расшифровка, но не понял...

https://wdfiles.ru/2Qijh

Запуск на выполнение:
ISUninst_5_51_138.exe -fUninst.isu

Сейчас приходится использовать песочнику+отслеживать обращений, чтобы узнать что он пытается удалить.

Реестр: HKCU\SOFTWARE\Infogrames
Каталоги:
C:\Program Files\Infogrames\Bugs Bunny & Taz - Time Buster
C:\WINDOWS\Главное меню\Программы\Infogrames\Bugs Bunny & Taz - Time Busters


--------------------
|__--__|
***|***
___|___
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
-=CHE@TER=-
Oct 9 2025, 10:47
Сообщение #2


Walter Sullivan
***

Группа: Root Admin
Сообщений: 1,388
Регистрация: 4-February 08
Пользователь №: 3
Спасибо сказали: 322 раз(а)



Добро пожаловать на форум!

Формат Uninst.isu:
WORD - должно быть всегда 0xA871, иначе формат считается неверным (сигнатура?)
DWORD - должно быть меньше, либо равно 0x2010000, иначе формат считается неверным (версия?)
DWORD - флаги какие-то? контрольная сумма?

Далее идут блоки данных в формате:
WORD - размер блока (len)
BYTE[len] - блок

Первый блок - это строка "Stirling Technologies, Inc. © 1990-1995".

У всех последующих блоков размер (len) не зашифрован, зашифровано только само тело блока.
Алгоритм дешифровки:
CODE
// ISUninst_5_51_138.exe at virtual address .40A0D8:
void IS_Decrypt(void *b, DWORD size, DWORD key) {
DWORD i, *d;
BYTE *p, *k;
  size = (size > 65000) ? 65000 : size;
  d = (DWORD *) b;
  for (i = 0; i < (size / 4); i++) {
    *d -= (((i + 1) * 7) % 191) + key + 0x1429314E;
    d++;
  }
  p = (BYTE *) b;
  k = (BYTE *) &key;
  for (i = 0; i < (size % 4); i++) {
    p[size - 1 - i] -= k[i];
  }
}

В качестве ключа (key) используется 0x12A39F87, но я видел в дизассемблере, что используется также и 0xAF325DE9. От чего зависит я не знаю, рабираться глубоко не стал.
И ещё перед функцией расшифровки стоит проверка:
if (size > 65000) { size = 65000; }
Так что, подозреваю, что либо блоков более 65000 байтов не существует, либо шифруются только первые 65 тысяч байт.
После заголовка с парой блоков идёт какой-то кусок нулей затем, со смещения 0x457 снова зашифрованные блоки. В частности по смещению 0x457 после расшифровки получается блок с путём установленной программы (там не просто строка, а ещё несколько байт служебных данных перед ней).
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
PavelDAS
Oct 9 2025, 13:30
Сообщение #3


Newbie
*

Группа: Authorized
Сообщений: 6
Регистрация: 21-September 25
Из: Minsk
Пользователь №: 18,037
Спасибо сказали: 0 раз(а)



QUOTE(-=CHE@TER=- @ Oct 9 2025, 10:47) *

После заголовка с парой блоков идёт какой-то кусок нулей затем, со смещения 0x457 снова зашифрованные блоки. В частности по смещению 0x457 после расшифровки получается блок с путём установленной программы (там не просто строка, а ещё несколько байт служебных данных перед ней).


Спасибо. Попробую написать расшифровку.

Есть три файла, всегда
0xA871
0x2010000

затем
fb 12 0a 00
или
7d c8 06 00
или
b4 c1 00 00

если попортить их -- пишет, что файл повреждён.

пустой блок, не всегда нули


Похоже на картинку, или шрифт какой.
Но, в первом файле есть текст 5.00.000, а это номер версии, который дописывается сборщиком-инсталлером в конец setup.ins

Пока что можно просто пропустить этот блок smile.gif
Размер его во всех файлах одинаков.


--------------------
|__--__|
***|***
___|___
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
PavelDAS
Oct 9 2025, 21:01
Сообщение #4


Newbie
*

Группа: Authorized
Сообщений: 6
Регистрация: 21-September 25
Из: Minsk
Пользователь №: 18,037
Спасибо сказали: 0 раз(а)



Работает. В начале и конце явно какие-то служебные символы.
Полезный блок начинается как раз с 0x457

Только конец файла не понятно, как вычислить, кроме как взять реальный размер.



--------------------
|__--__|
***|***
___|___
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
-=CHE@TER=-
Oct 10 2025, 07:32
Сообщение #5


Walter Sullivan
***

Группа: Root Admin
Сообщений: 1,388
Регистрация: 4-February 08
Пользователь №: 3
Спасибо сказали: 322 раз(а)



QUOTE(PavelDAS @ Oct 9 2025, 13:30) *
если попортить их -- пишет, что файл повреждён.
Либо контрольная сумма, либо какие-то флаги, которые проверяются на возможные значения и выводится ошибка в случае, если они вне допустимых.

QUOTE(PavelDAS @ Oct 9 2025, 21:01) *
Только конец файла не понятно, как вычислить, кроме как взять реальный размер.
А так, скорее всего, и делается.

Код расшифровщика, если, вдруг, нужно.
isudcrpt.c:
CODE
#include <stdio.h>
#include <string.h>
#include <windows.h>

char *basename(char *s) {
char *r;
if (s) {
for (r = s; *r; r++) {
if ((*r == ':') || (*r == '/') || (*r == '\\')) {
s = &r[1];
}
}
}
return(s);
}

void newext(char *name, char *ext) {
char *p;
if (name && ext) {
for (; (*name == '.'); name++);
for (p = NULL; *name; name++) {
if (*name == '.') {
p = name;
}
}
strcpy(p ? p : name, ext);
}
}

// ISUninst_5_51_138.exe at virtual address .40A0D8:
void IS_Decrypt(void *b, DWORD size, DWORD key) {
DWORD i, *d;
BYTE *p, *k;
size = (size > 65000) ? 65000 : size;
d = (DWORD *) b;
for (i = 0; i < (size / 4); i++) {
*d -= (((i + 1) * 7) % 191) + key + 0x1429314E;
d++;
}
p = (BYTE *) b;
k = (BYTE *) &key;
for (i = 0; i < (size % 4); i++) {
p[size - 1 - i] -= k[i];
}
}

static char q[0x10000U];

int main(int argc, char *argv[]) {
FILE *fl, *f;
char s[260];
DWORD i, sz;
WORD w;
printf(
"InstallShield uninstall .ISU script decrypter v1.0\n"
"© CTPAX-X Team 2025\nhttp://www.CTPAX-X.org/\n\n"
);
if (argc != 2) {
printf("Usage: isudcrpt <filename.isu>\n\n");
return(1);
}
fl = fopen(argv[1], "rb");
if (!fl) {
printf("Error: can't open input file.\n\n");
return(2);
}
fseek(fl, 0, SEEK_END);
sz = ftell(fl);
fseek(fl, 0, SEEK_SET);

fread(&w, 2, 1, fl);
fread(&i, 4, 1, fl);
if ((w != 0xA871) || (i > 0x2010000)) {
fclose(fl);
printf("Error: invalid input file format.\n\n");
return(3);
}

strcpy(s, basename(argv[1]));
printf("%s -> ", s);
newext(s, ".bin");
printf("%s\n", s);
f = fopen(s, "wb");
if (!f) {
fclose(fl);
printf("Error: can't create output file.\n\n");
return(3);
}
fwrite(&w, 2, 1, f);
fwrite(&i, 4, 1, f);

fread(&i, 4, 1, fl);
fwrite(&i, 4, 1, f);

fread(&w, 2, 1, fl);
fread(q, w, 1, fl);
fwrite(&w, 2, 1, f);
fwrite(q, w, 1, f);

for (i = 0; i < 2; i++) {
fread(&w, 2, 1, fl);
fread(q, w, 1, fl);
IS_Decrypt(q, w, 0x12A39F87/*0xAF325DE9*/);
fwrite(&w, 2, 1, f);
fwrite(q, w, 1, f);
}

fread(q, 712, 1, fl);
fwrite(q, 712, 1, f);

while (ftell(fl) < sz) {
fread(&w, 2, 1, fl);
fread(q, w, 1, fl);
IS_Decrypt(q, w, 0x12A39F87/*0xAF325DE9*/);
fwrite(&w, 2, 1, f);
fwrite(q, w, 1, f);
}

fclose(f);
fclose(fl);
printf("\ndone\n\n");
return(0);
}


QUOTE(PavelDAS @ Oct 9 2025, 21:01) *
Работает. В начале и конце явно какие-то служебные символы.
В начале и конце блоков что ли? Там бинарная структура, не текстовая.
Например, по смещению 0x457 того файла что выложен был:
25 00 | BA 04 00 00 64 00 01 00 | 1B 00 | "C:\Program Files\Infogrames"
0x0025 - размер блока (все данные далее зашифрованы)
0x001B - размер блока со строкой "C:\Program Files\Infogrames"
Остальные данные - это служебные байты определяющие тип блока и дополнительные данные.
Так как в "Uninst.isu" хранятся следующие сущности:
1. Имя файла.
2. Ключ реестра.
3. Ярлык в меню "Пуск".
И так далее, то программе нужно как-то различать их. Вот эти данные служебные для этого и предназначены. Тут нужно просто статистику набрать: выводить такие данные на экран в hex виде и смотреть что совпадает у тех блоков, где, например, только имена файлов или только ключи реестра. Ну и так, собственно, весь файл и распарсиваем.
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
PavelDAS
Oct 13 2025, 09:48
Сообщение #6


Newbie
*

Группа: Authorized
Сообщений: 6
Регистрация: 21-September 25
Из: Minsk
Пользователь №: 18,037
Спасибо сказали: 0 раз(а)



QUOTE(-=CHE@TER=- @ Oct 10 2025, 07:32) *

В начале и конце блоков что ли? Там бинарная структура, не текстовая.

Это я понял. Я пишу на PHP, поэтому на нём и расшифровку написал, что скрин выше smile.gif
Позже буду вырезать лишнее, мне нужны только пути для анализа.

p.s. сейчас ещё пишу расшифровку WISE, но там всё открыто, только разобрать структуру и попытаться воссоздать изначальный файл-скрипт.

p.p.s. каким простым компилятором твой код можно собрать под windows. g++ пишет ошибки. VS ставить не планирую.


--------------------
|__--__|
***|***
___|___
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
-=CHE@TER=-
Oct 13 2025, 10:15
Сообщение #7


Walter Sullivan
***

Группа: Root Admin
Сообщений: 1,388
Регистрация: 4-February 08
Пользователь №: 3
Спасибо сказали: 322 раз(а)



QUOTE(PavelDAS @ Oct 13 2025, 09:48) *
p.s. сейчас ещё пишу расшифровку WISE, но там всё открыто, только разобрать структуру и попытаться воссоздать изначальный файл-скрипт.
Для WISE были распаковщики, причём даже с исходными кодами, типа такого (см. ссылки на E_WISE и другие программы, которые там упоминаются):
https://github.com/mnadareski/WiseUnpacker

QUOTE(PavelDAS @ Oct 13 2025, 09:48) *
p.p.s. каким простым компилятором твой код можно собрать под windows. g++ пишет ошибки. VS ставить не планирую.
Очень странно. Я под GCC собирал, но сейчас попробовал под G++ тоже без проблем собралось. Можешь написать что за ошибки?
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
PavelDAS
Oct 13 2025, 12:07
Сообщение #8


Newbie
*

Группа: Authorized
Сообщений: 6
Регистрация: 21-September 25
Из: Minsk
Пользователь №: 18,037
Спасибо сказали: 0 раз(а)



QUOTE(-=CHE@TER=- @ Oct 13 2025, 10:15) *

Для WISE были распаковщики, причём даже с исходными кодами, типа такого (см. ссылки на E_WISE и другие программы, которые там упоминаются):
https://github.com/mnadareski/WiseUnpacker

Я собрал все возможные распаковщики под разные версии, что-то работает в одном, что-то в другом.
Этот хорош, но не всё может корректно извлечь.
Использую HWUN 0.50b и 0.40b для "особых" вариации встречающиеся крайне редко, на которых все обламываются.

Я расшифровываю script.bin, там всё открыто, мне интересно что за что отвечает и собрать первоначальный wse файл smile.gif
Структура понятно, осталось констант насобирать.

QUOTE(-=CHE@TER=- @ Oct 13 2025, 10:15) *

Очень странно. Я под GCC собирал, но сейчас попробовал под G++ тоже без проблем собралось. Можешь написать что за ошибки?




--------------------
|__--__|
***|***
___|___
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
-=CHE@TER=-
Oct 13 2025, 12:18
Сообщение #9


Walter Sullivan
***

Группа: Root Admin
Сообщений: 1,388
Регистрация: 4-February 08
Пользователь №: 3
Спасибо сказали: 322 раз(а)



А у тебя точно нормально GCC настроен? Простая программа "Hello, world!" хотя бы компилируется? Потому что на твоём скриншоте GCC пишет что линковщик (ld.exe) найти не может.
На всякий случай ещё попробуй заменить в начале программы "#include <windows.h>" на такое:
CODE
#include <stdint.h>

#define DWORD uint32_t
#define WORD uint16_t
#define BYTE uint8_t
Но, повторюсь, если у тебя даже простенькая программа "Привет, мир!" не компилируется, то это не в моём коде дело.
User is offlineProfile CardPM
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0 -

 



Упрощённая версия Сейчас: 15th October 2025 - 15:19