IPB

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

 
Reply to this topicStart new topic
> VISE Installer [*.EXE], Распаковщик
PavelDAS
Jul 6 2026, 19:47
Сообщение #1


Advanced Member
***

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



Необходим распаковщик установочных файлов.
Существует один единственный распаковщик как плагин к FAR или TC, но у него проблемы:

но у неё проблемы:
1) не распаковывает по папкам
2) не работает с многотомными
3) если есть разные группы (русская версия, английская), то файл с
таким же именем попросту переписывается.
4) пустышки (где только скрипты) не может распаковать (как повезёт, некоторые может)

исходники плагина есть тут:
https://github.com/lazyhamster/Observer/tre...rc/modules/vise

Пример многотомного исталла:
1,1 Гб https://wdfiles.ru/1vbu4


--------------------
|__--__|
***|***
___|___
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
-=CHE@TER=-
Jul 7 2026, 14:11
Сообщение #2


Walter Sullivan
***

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



Что-то посмотрел я код и так мне не захотелось с этим возиться - просто сил нет...
Там 38 разных блоков и для чтения каждого отдельный код.
Это прям абзац какая боль.
Код ниже распаковывает файлы установщика ("install.exe") - помимо всего прочего будет извлечён файл "vise32ex.dll", который можно засунуть в дизассемблер (IDA, например) и смотреть как sub_1003C460() работает. Там самая боль в том, что блоки не фиксированного размера: типа, флаг есть - читаем ещё, флага нет - не читаем. Поэтому тупо пропустить их не получится. И размеров у блоков тоже нет - это всё нужно вручную читать и считать.
Распаковщик deflate (puff) взят из zlib.

CODE

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <sys/stat.h>

/*#define DEBUG 1*/

#ifdef __HAVE_BUILTIN_SETJMP__
#include <setjmp.h>
#undef setjmp
#define setjmp __builtin_setjmp
#undef longjmp
#define longjmp __builtin_longjmp
#endif

/*
To compile this source code you'll need "puff.c" and "puff.h" files from zlib package.
Get this package from official site: http://zlib.net/
Required files can be found in /contrib/puff/ folder inside archive.
*/

#include "puff.h"
#include "puff.c"

/* VISE STOR BLDR */

#define MAGIC_VISE 0x56495345

#pragma pack(push, 1)
typedef struct {
uint32_t magic;
uint32_t offs;
} visetail;
#pragma pack(pop)

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);
}
}

void makedirs(char *path) {
char *s;
if (path) {
for (s = path; *s; s++) {
if ((*s == '\\') || (*s == '/')) {
*s = 0;
mkdir(path, 0755);
*s = '/';
}
}
}
}

void dumpdata(char *name, void *data, uint32_t size) {
FILE *f;
if (name) {
f = fopen(name, "wb");
if (f) {
if (data && size) {
fwrite(data, size, 1, f);
}
fclose(f);
}
}
}

void readdata(FILE *fl, void *data, uint32_t size) {
if (data && size) {
memset(data, 0, size);
if (fl) {
fread(data, size, 1, fl);
}
}
}

#ifdef _WIN32
#include <windows.h>
void makefiletime(char *s, uint16_t dd, uint16_t dt) {
FILETIME ft, t;
HANDLE fl;
if (s) {
DosDateTimeToFileTime(dd, dt, &t);
LocalFileTimeToFileTime(&t, &ft);
fl = CreateFile(s, FILE_WRITE_ATTRIBUTES, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if (fl != INVALID_HANDLE_VALUE) {
SetFileTime(fl, NULL, NULL, &ft);
CloseHandle(fl);
}
}
}
#else
#define makefiletime(a,b)
#endif

void vise_decrypt(uint8_t *p, uint32_t l) {
uint32_t i;
if (p && (l >= 2)) {
for (i = 0; i < l; i += 2) {
p[i] ^= p[i + 1];
p[i + 1] ^= p[i];
p[i] ^= p[i + 1];
}
}
}

int main(int argc, char *argv[]) {
uint16_t fcount, wDOSDate, wDOSTime, fcount2, w;
unsigned long ps, us;
char s[10 + 256], *t;
uint8_t *p, *u, b;
uint32_t i, sz;
visetail tail;
FILE *fl;
printf(
"VISE5 Installer unpacker v1.0\n"
"© CTPAX-X Team 2026\n"
"http://www.CTPAX-X.org/\n\n"
);
if (argc != 2) {
printf("Usage: unpkvise <filename.ext>\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, sz - sizeof(tail), SEEK_SET);
readdata(fl, &tail, sizeof(tail));
if ((tail.magic != MAGIC_VISE) || (tail.offs >= sz)) {
fclose(fl);
printf("Error: invalid input file format.\n\n");
return(3);
}
fseek(fl, tail.offs, SEEK_SET);
/* skip:
uint32_t magic; // VISE
uint32_t unknown1; // used in vise32ex.dll (product id?)
uint32_t unknown2; // part number (1, 2, 3...) -> "install.%03u"
utin32_t unknown3; // used in vise32ex.dll (this archive size? data offset?)
*/
fseek(fl, ftell(fl) + (4 * 4), SEEK_SET);
/* skip 3 strings */
for (i = 0; i < 3; i++) {
readdata(fl, &b, 1);
if (i == 1) { b &= 0x3F; }
fseek(fl, ftell(fl) + b, SEEK_SET);
}
strcpy(s, "[-VISE-]/");
t = &s[strlen(s)];
/* installer files, part 1 */
readdata(fl, &fcount, 2);
while (fcount--) {
/* read name */
readdata(fl, &b, 1);
readdata(fl, t, b);
t[b] = 0;
readdata(fl, &wDOSDate, 2);
readdata(fl, &wDOSTime, 2);
/* skip two unused values (always zero?) */
fseek(fl, ftell(fl) + (4 * 2), SEEK_SET);
readdata(fl, &sz, 4);
printf("%s\n", s);
p = (uint8_t *) malloc(sz);
if (p) {
readdata(fl, p, sz);
vise_decrypt(p, sz);
us = 0;
ps = sz;
puff(NULL, &us, p, &ps);
u = (uint8_t *) malloc(us);
if (u) {
memset(u, 0, us);
ps = sz;
puff(u, &us, p, &ps);
#ifndef DEBUG
makedirs(s);
dumpdata(s, u, us);
makefiletime(s, wDOSDate, wDOSTime);
#endif
free(u);
}
free(p);
} else {
fseek(fl, ftell(fl) + sz, SEEK_SET);
}
}
/* skip:
uint8_t - must be zero or error
uint8_t - skipped (unknown)
*/
fseek(fl, ftell(fl) + (1 * 2), SEEK_SET);
/* installer strings */
readdata(fl, &fcount, 2);
/* skip: "ENGLISH", "English" */
for (i = 0; i < 2; i++) {
readdata(fl, &w, 2);
fseek(fl, ftell(fl) + w, SEEK_SET);
}
/* skip: flag1, flag2 */
fseek(fl, ftell(fl) + (1 * 2), SEEK_SET);
/* skip:
"Select Language",
"Please select the language that you would like to use during the installation."
*/
for (i = 0; i < 2; i++) {
readdata(fl, &w, 2);
fseek(fl, ftell(fl) + w, SEEK_SET);
}
readdata(fl, &fcount2, 2);
/* skip some pair of strings (code below not tested) */
while (fcount2) {
/* unknown */
readdata(fl, &w, 2);
/* string pairs */
for (i = 0; i < 2; i++) {
readdata(fl, &w, 2);
fseek(fl, ftell(fl) + w, SEEK_SET);
}
}
/* installer data */
readdata(fl, &sz, 4);
strcpy(t, "miscdata.xyz");
printf("%s\n", s);
p = (uint8_t *) malloc(sz);
if (p) {
readdata(fl, p, sz);
vise_decrypt(p, sz);
us = 0;
ps = sz;
puff(NULL, &us, p, &ps);
u = (uint8_t *) malloc(us);
if (u) {
ps = sz;
puff(u, &us, p, &ps);
#ifndef DEBUG
makedirs(s);
dumpdata(s, u, us);
#endif
free(u);
}
free(p);
} else {
fseek(fl, ftell(fl) + sz, SEEK_SET);
}
/* setup window creation flag */
fseek(fl, ftell(fl) + 1, SEEK_SET);
/* skip unknown data */
readdata(fl, &sz, 4);
if (sz) {
fclose(fl);
printf("Error: a lot of various data should be skipped here, not supported [1].\n\n");
return(100);
}
/* some strings pairs */
readdata(fl, &sz, 4);
while (sz--) {
for (i = 0; i < 2; i++) {
readdata(fl, &w, 2);
fseek(fl, ftell(fl) + w, SEEK_SET);
}
}
/* skip unknown data */
readdata(fl, &sz, 4);
if (sz) {
fclose(fl);
printf("Error: a lot of various data should be skipped here, not supported [2].\n\n");
return(100);
}
/* skip unknown data */
readdata(fl, &sz, 4);
if (sz) {
fclose(fl);
printf("Error: a lot of various data should be skipped here, not supported [3].\n\n");
return(100);
}
/* installer files, part 2 */
readdata(fl, &fcount, 2);
while (fcount--) {
/* read name */
readdata(fl, &b, 1);
readdata(fl, t, b);
t[b] = 0;
readdata(fl, &wDOSDate, 2);
readdata(fl, &wDOSTime, 2);
/* skip two unused values (always zero?) */
fseek(fl, ftell(fl) + (4 * 2), SEEK_SET);
readdata(fl, &sz, 4);
printf("%s\n", s);
p = (uint8_t *) malloc(sz);
if (p) {
readdata(fl, p, sz);
vise_decrypt(p, sz);
us = 0;
ps = sz;
puff(NULL, &us, p, &ps);
u = (uint8_t *) malloc(us);
if (u) {
memset(u, 0, us);
ps = sz;
puff(u, &us, p, &ps);
#ifndef DEBUG
makedirs(s);
dumpdata(s, u, us);
makefiletime(s, wDOSDate, wDOSTime);
#endif
free(u);
}
free(p);
} else {
fseek(fl, ftell(fl) + sz, SEEK_SET);
}
}
/* installation types: "Support Files", "Typical Setup", "Compact Setup", "Silent Setup" */
readdata(fl, &fcount2, 2);
while (fcount2--) {
/* skip name */
readdata(fl, &w, 2);
fseek(fl, ftell(fl) + w, SEEK_SET);
/* FIXME: proper data parser, it's not 82 but variable length! */
fseek(fl, ftell(fl) + 82, SEEK_SET);
}
/* files data list */
/* FIXME: code below from sub_1003C460 routine taken from "vise32ex.dll" */
/* readdata(fl, &sz, 4);
for (i = 0; i < sz; i++) {
readdata(fl, &t, 4);
switch (t) {
case 1:
dwFileList[i] = sub_10034BD0(fl, i);
break;
case 2:
dwFileList[i] = sub_10035020(fl, i);
break;
case 3:
dwFileList[i] = sub_100356B0(fl);
break;
case 4:
dwFileList[i] = sub_10035B00(fl);
break;
case 5:
dwFileList[i] = sub_10035CB0(fl);
break;
case 6:
dwFileList[i] = sub_10035EA0(fl);
break;
case 7:
dwFileList[i] = sub_10036360(fl);
break;
case 8:
dwFileList[i] = sub_10036730(fl);
break;
case 9:
dwFileList[i] = sub_10036B10(fl);
break;
case 10:
dwFileList[i] = sub_10036EF0(fl);
break;
case 11:
dwFileList[i] = sub_100371E0(fl);
break;
case 12:
dwFileList[i] = sub_100375D0(fl);
break;
case 13:
dwFileList[i] = sub_100378C0(fl);
break;
case 14:
dwFileList[i] = sub_10037B30(fl);
break;
case 15:
dwFileList[i] = sub_10037C60(fl);
break;
case 16:
dwFileList[i] = sub_10037F60(fl);
break;
case 17:
dwFileList[i] = sub_10038310(fl);
break;
case 18:
dwFileList[i] = sub_10038490(fl);
break;
case 19:
dwFileList[i] = sub_100387C0(fl);
break;
case 21:
dwFileList[i] = sub_10038A80(fl, i);
break;
case 22:
dwFileList[i] = sub_10038F30(fl);
break;
case 23:
dwFileList[i] = sub_10039240(fl);
break;
case 24:
dwFileList[i] = sub_10039550(fl);
break;
case 25:
dwFileList[i] = sub_100398B0(fl);
break;
case 26:
dwFileList[i] = sub_10039BE0(fl);
break;
case 27:
dwFileList[i] = sub_10039E60(fl);
break;
case 28:
dwFileList[i] = sub_1003A1E0(fl);
break;
case 29:
dwFileList[i] = sub_1003A550(fl);
break;
case 30:
dwFileList[i] = sub_1003AA10(fl);
break;
case 31:
dwFileList[i] = sub_1003AD00(fl);
break;
case 32:
dwFileList[i] = sub_1003AF40(fl);
break;
case 34:
dwFileList[i] = sub_1003B1A0(fl);
break;
case 35:
dwFileList[i] = sub_1003B500(fl);
break;
case 36:
dwFileList[i] = sub_1003B9E0(fl);
break;
case 37:
dwFileList[i] = sub_1003BE20(fl);
break;
case 38:
dwFileList[i] = sub_1003C080(fl);
break;
default:
break;
}
if (!dwFileList[i]) { break; }
}*/
printf("%08X\n", (unsigned int) ftell(fl));
fclose(fl);
printf("\ndone\n\n");
return(0);
}


Спасибо сказали:
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
PavelDAS
Jul 8 2026, 15:08
Сообщение #3


Advanced Member
***

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



Создаётся только пустой файл
и бьёт ошибку на строке readdata(fl, t, cool.gif;
B не находит [-VISE-]\miscdata.xyz


--------------------
|__--__|
***|***
___|___
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
-=CHE@TER=-
Jul 8 2026, 15:36
Сообщение #4


Walter Sullivan
***

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



Это потому что я забыл смайлы отключить, когда код вставлял.
Попробуй этот вариант (делай ответить на сообщение и уже оттуда код копируй).
И что значит не находит файл "[-VISE-]\miscdata.xyz"? Программа и не должна его находить - она должна его создавать.
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
PavelDAS
Jul 8 2026, 19:58
Сообщение #5


Advanced Member
***

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



Правильное сообщение:
Создаётся только пустой файл [-VISE-]\miscdata.xyz
и бьёт ошибку на строке readdata(fl, t, B);
B не находит.

я сам заменил на b перед этим. Завтра проверю новый вариант кода твоего.


--------------------
|__--__|
***|***
___|___
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
PavelDAS
Jul 9 2026, 14:40
Сообщение #6


Advanced Member
***

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



Мда... каша из не пойми каких вызовов...

Думал уже подключить dll и вызывать методы напрямую, но их названия так и не смог отследить. xLogger много чего выводит.
Похоже, вызывается только ViseMain.

Будет время, буду через ИИшку asm код адаптировать...

miscdata.xyz -- это похоже на формы (окна) установщика на каждом шаге.


--------------------
|__--__|
***|***
___|___
User is offlineProfile CardPM
Go to the top of the page
+Quote Post

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

 



Упрощённая версия Сейчас: 16th July 2026 - 22:56