Rambler's Top100
"Knowledge itself is power"
F.Bacon
Поиск | Карта сайта | Помощь | О проекте | ТТХ  
 Круглый стол
  
Правила КС
>> Настройки

Фильтр вопросов
>> Новые вопросы
отслеживать по
>> Новые ответы

Избранное

Страница вопросов
Поиск по КС


Специальные проекты:
>> К л ю к в а
>> Г о л о в о л о м к и

Вопрос №

Задать вопрос
Off-topic вопросы

Помощь

 
 К н и г и
 
Книжная полка
 
 
Библиотека
 
  
  
 


Поиск
 
Поиск по КС
Поиск в статьях
Яndex© + Google©
Поиск книг

 
  
Тематический каталог
Все манускрипты

 
  
Карта VCL
ОШИБКИ
Сообщения системы

 
Форумы
 
Круглый стол
Новые вопросы

 
  
Базарная площадь
Городская площадь

 
   
С Л С

 
Летопись
 
Королевские Хроники
Рыцарский Зал
Глас народа!

 
  
ТТХ
Конкурсы
Королевская клюква

 
Разделы
 
Hello, World!
Лицей

Квинтана

 
  
Сокровищница
Подземелье Магов
Подводные камни
Свитки

 
  
Школа ОБЕРОНА

 
  
Арсенальная башня
Фолианты
Полигон

 
  
Книга Песка
Дальние земли

 
  
АРХИВЫ

 
 

Сейчас на сайте присутствуют:
 
  
 
Во Флориде и в Королевстве сейчас  13:50[Войти] | [Зарегистрироваться]
Ответ на вопрос № 8763

19-11-2001 17:36
Имеется задача: нужно объединить два *.exe файла в один так, чтобы при
открытии
этого файла запускались обе программы. Я написал программу, использующую
TFileStream, которая записывает один файл в конец другого. Однако при
открытии этого "составного" файла стартует только та программа, которая
находится в голове файла. На сколько я понимаю, при открытии файла
создается процесс и его первичный поток, который представляет первую
программу, а так как вторая программа никак не связана с первой, то она
и не запускается. Так вот, как все-таки запустить ее? Вызвать ее из
первой как еще один поток? Нужно заметить, что меня не устраивает такой
вариант, что первая программа копирует из этого составного файла тело
второй программы в другое место на жестком диске. Буду искренне рад
увидеть примеры ;)

[+] Добавить в избранные вопросы

Отслеживать ответы на этот вопрос по RSS

Ответы:


Уважаемые авторы вопросов! Большая просьба сообщить о результатах решения проблемы на этой странице.
Иначе, следящие за обсуждением, возможно имеющие аналогичные проблемы, не получают ясного представления об их решении. А авторы ответов не получают обратной связи. Что можно расценивать, как проявление неуважения к отвечающим от автора вопроса.

20-02-2005 12:03
Высылаю вам статью по этой теме!
Я тоже работаю над такой програмой только я програмирую на Си.
На этот сайт попал случайно, случайно нашол и эту статью которая возможно вам пригодится. Если что получится вышлите пожалуста ехе файл на мыло а то у меня сейчас Delfi нет. Буду также очень благодарен тем хто поможет перевести текст этой проги на СИ.
Как сделать Joiner и недостатки VisualBasic.

Part. #1

Каждый человек, который когда-либо сталкивался с использованием трояном знает что таит в себе это загадочное слово Joiner. Для несведущих объясню, Joiner - это программа, которая позволяет склеить два файла в один исполняемый. А это очень нужная процедура! Объясню на примере: кодер пишет небольшую утилу на VisualBasic, а всем кто когда-либо писал на этом "замечательном" языке должно быть известно, код которые компилит среда является т.н. р-кодом, а он в свою очередь представляет собой закодированные инструкции программы. Исполняемый файл, который получается в результате компиляции является всего лишь интерпретатором р-кода с добавлением кода программы. А весь код который который необходим для работы приложений (отображение формы, рисование контролов и т.д.) содержится в т.н виртуальных машинах, эти файлы жизненно необходимы для работы любой программы на VB. За счет того что все функции зашиты в такие вир-машины удалось значительно снизить размер исполняемого файла программы. Но так ли эффективен этот метод?

Давай рассмотрим простейшую программу на VB…При запуске среды тебе предлагают создать новый проект, выбираем Стандартный-ЕХЕ, после этого будет образован новый проект. Его уже можно запустить на выполнение, нажав клавишу F5. Программа будет выполненна очень быстро, т.к. не будет выполнена процедура компиляции и сборки програмы, как напримет в Delphi. Теперь выберим пункт меня Файл-Создать Ехе, и сохраним его например на рабочий стол. После компиляции на рабочем столе (или в папке куда сохранили) появится файл с расширение ехе, это и есть интерпретатор р-кода. Его размер будет около 14 кб (значение может варьироваться в зависимости от версии языка, например в версиии VB 1.0 он будет размером около 4 кб). Аналогичная программа на Delphi созданная с помощью Vcl будет размером под 300 кб! В чем же причина? А причина как вы уже наверно догадались кроется в использовании вир-машины посмотрим же на ее размер….а находится она по умолчанию в катологе %WinDir%\System (или %WinDir%\System32 в случае линейки НТ) и называется vbrun***.dll для версий языка 1.00-4.00 и msvbvm**.dll для версий 5.0-6.0, гже *** - номер версии языка. Смотрим размер файла и …… о боже! Его размер около 1 Мб! И этот файл необходимо таскать с собой чтоб иметь возможность запустить свою прогу на компе где он отстутсвует! А такскать его за собой, сами понимаете, доволно накладно, особенно если распространять программу вы собираетесь через интернет… Есть конечно выход из сложившейся ситуации, можно сделать для своей программы инсталлятор и распространять уже его, не опасаясь того что у конечного пользователя может не оказаться необходимых файлов. Но делать инсталятор для небольшой программы это по-моему излишество, т.к. вы придется отдать за сдрасте 200-30кб… Вот тут к вам на помощь придет программа джойнер, которая позволит вам сделать из программ на VB что-нибудь более приличное, мы просто возмем и склеим программу и вир-машину в один исполняемый файл, у которого мы также сможем установить иконку…если я Вас заинтересовал, то читайте далее….

Принцип действия

Принцип действия этой программы до безобразия прост! Берутся два файла и записываются после небольшой программы-загрузчика (принцип работы загрузчика мы рассмотрим позже), также записываются размеры этих файлов, зачем - сами потом увидите… Весь код будет оформлен на языке Delphi, в случае необходимости он может быть с легкостью перенесен на другой язык программирование, конечно кроме VB ;)

Сначала лепим на форме много рычагов и кнопок! У меня там валяются 2 - поля ввода, 1 - OpenDialog, 1 - SaveDialog и 4 - кнопки. В полях ввода мы будем отображать имена файлов для склейки. Теперь напишем код для кнопок которые будут отображать эти имена:


-----
type Info = record    //Объявляем запись с информацией о файлах
File1Size : Int64;    //Размер первого файла
File2Size : Int64;    //Размер второго файла
File1ext : string[6]; //Расширение первого файла
File2ext : string[6]; //Расширение второго файла
end;

var Infos : Info;

//Этот код открывает первый файл
procedure TForm1.Button1Click(Sender: TObject);
begin
if OpenDialog1.Execute then Edit1.Text:=OpenDialog1.FileName;
end;

//Этот код открывает второй файл
procedure TForm1.Button2Click(Sender: TObject);
begin
if OpenDialog1.Execute then Edit2.Text:=OpenDialog1.FileName;
end;

//По нажатию этой кнопки мы будем выходить из программы :)
procedure TForm1.Button3Click(Sender: TObject);
begin
Close;
end;

//Сдесь будет находиться весь основной код, который
//осуществляет склеивание файлов
procedure TForm1.Button4Click(Sender: TObject);
var
F1, //Первый файл
F2, //Второй файл
F4, //Загрузчик
F5, //Результат
F6 : TFileStream; //Файл с инфой
F3 : File of Info;
begin
//Если файлы не заданы, то выйти из процедуры
if Edit1.text='' then Exit;
if Edit2.text='' then Exit;
//Открываем склеиваемые файлы
F1:=TFileStream.Сreate(Edit1.Text,fmOpenRead);
F2:=TFileStream.Сreate(Edit2.Text,fmOpenRead);
//Открываем загрузчик
F4:=TFileStream.Сreate(ExtractFilePath(Application.ExeName)+'Loader.exe',fmOpenRead);
//Создаем результирующий файл
F5:=TFileStream.Сreate(ExtractFilePath(Application.ExeName)+'result.exe',fmOpenWrite or fmCreate);
//Заносим в запись инфу о наших файлах
Infos.File1Size:=F1.Size;
Infos.File2Size:=F2.Size;
Infos.File1Ext:=ExtractFileExt(Edit1.Text);
Infos.File2Ext:=ExtractFileExt(Edit2.Text);
//Заносим в запись инфу о наших файлах
AssignFile(F3,ExtractFilePath(Application.ExeName)+'info.dat');
Rewrite(F3);
Write(F3, Infos); 
CloseFile(F3);
//Открываем этот файл
F6:=TFileStream.create(ExtractFilePath(Application.ExeName)+'info.dat', fmOpenRead);
//Копируем в исходный файл загрузчик
F5.CopyFrom(F4,F4.Size);
//Копируем iервый файл
F5.CopyFrom(F1,F1.Size);
//Копируем второй файл
F5.CopyFrom(F2,F2.Size);
//Копируем файл с информацией
F5.CopyFrom(F6,F6.Size);
//Закрываем все открытые файлы
F1.Free; 
F2.Free;
F4.Free;
F5.Free;
F6.Free;
//Удаляем файл с информациией, т.к. он нам больше ненужен
DeleteFile(PChar(ExtractFilePath(Application.ExeName)+'Info.dat'));
end;
Это весь код! Правда несложно! Если же ты че-то непонял смотри коментарии и исходник. Теперь нам нужно сделать Загрузчик который будет извлекать и запускать склеенные файлы. Принцим его работы также прост: сначала он переписывает себя во временный каталог. Потом мы извлекаем из конца файла инфу. Потом читаем размеры файлов из заголовка. Переходим в позицию после Загрузчика и читаем первый файл длиной, которая записана в заголовке, и сохраняем его на диск, потом переходим в позицию длина Загрузчика+длина первого файла и читаем оотуда второй файл, который также сохраняем на диск. Остается просто запустить эти файлы, предварительно удалив ненужный мусор, который мы создали ;) Вот код Загрузчика:

program Loader;

uses Windows, Classes, SysUtils, ShellAPI;

type
dm = record
  File1Size : Int64;
  File2Size : Int64;
  File1Ext  : String[6];
  File2Ext  : String[6];
end;

{$R *.res}

const
LoaderSize = 53248; //размер упаковщика (После компиляции проверь и измени!!!)
HeaderSize = 32;    //размер заголовка
 
var
F1, //Первый файл
F2, //Второй файл
F3, //Заголовочный файл
F4 : TFileStream; //Главный файл
d : Dm;
f : file of dm;
 
//---------- Вырезано из Avl ----------//
function TempDir:String;
var
Buf:array[0..MAX_PATH] of Char;
begin
GetTempPath(MAX_PATH+1, @buf);
Result := buf;
end;
//---------- Вырезано из Avl ----------//

begin
//Копируем наш файл в другое место
CopyFile(PChar(ParamStr(0)), PChar(TempDir+'temp.dat'), True);
//Открываем наш файл
F4:=TFileStream.Create(TempDir+'temp.dat',fmOpenRead);
F4.Seek(F4.Size-HeaderSize,0);
//извлекаем заголовочный файл с размерами файлов в нутри нашего файла %)
F3:=TFileStream.Create(TempDir+'Header.dat',fmOpenWrite or fmCreate);
F3.CopyFrom(F4,HeaderSize);
F3.Free;

AssignFile(f,TempDir+'Header.dat');//Открываем файл
reset(f);                                         //заголовка
Read(F,d);                                       //и читаем из него
Closefile(F);                             //наши данные
F4.Seek(LoaderSize,0);            //переходим в позицию после упаковщика
//сохраняем 1-ый файл на диске
F1:=TFileStream.Create(TempDir+'file1'+d.File1Ext,fmOpenWrite or fmCreate);
F1.CopyFrom(F4,d.File1Size);
F1.Free;
//переходим в позицию после упаковщика + размер первого файла
F4.Seek(LoaderSize+d.File1Size,0);
//сохраняем 2-ой файл на диске
F2:=TFileStream.create(TempDir+'file2'+d.File1Ext,fmOpenWrite or fmCreate);
F2.CopyFrom(F4,d.File2Size);
F2.Free;
//Закоываем конечный файл
F4.Free;
//Удаляем мусор
DeleteFile(PChar(TempDir+'temp.dat'));
DeleteFile(PChar(TempDir+'Header.dat'));
//Запускаем файлы
ShellExecute(0,'open',PChar(TempDir+'file1'+d.File1Ext),'','',SW_NORMAL);
ShellExecute(0,'open',PChar(TempDir+'file2'+d.File1Ext),'','',SW_NORMAL);
end.
Ну как вам Загрузчик? Ведь тоже ОЧЕНЬ просто! А теперь я хочу заострить ваше внимание на константе LoaderSize эта константа содержит размер Загрузчика в байтах, после того как вы скомпилируете Загрузчик посмотрите его размер и впишите его в значение этой константы и перекомпилируйте снова, т.к. без этого он не будет работать!!! ВСЕ! Теперь вы можете склеивать файлы!!! И напоследок: размер Загрузчика получился довольно большой, чтобы уменьшить его раза в два можно сжать его например Upx или AsPack. Желаю вам удачного склеивания!

Я тут подумал и решил, что продолжу эту тему ;) В одной из следующих статей я раскажу как можно сделать загрузчик меньше 10 кил. и как сделать чтобы Джойнер представлял из себя один файл, а Загрузчик был зашит в тело ехе!

Исходники

av2222@ua.fm

25-04-2004 18:38
Можно толко пофантазировать следующим образом: весь файл "ляжет" в память, а потом найти сигнатуру и смещение для входа и "прыгнуть" (JMP) туда на асме. Интересно что получится...

05-05-2003 18:01
  Для того чтобы запускать программы по очереди, и чтобы удалять с диска после их закрытия, можно воспользоваться возможностями, предоставляемыми коммандными файлами (файлы типа *.bat). Я также использовал упаковщик SuperGlue32 (спасибо Sportster'у за ссылку - очень полезная программка). Первой в списке (в окне "СуперКлея") следует первая программа, потом вторая, и в конце - *.bat файл. Там же устанавливаешь параметры запуска: первые два файла не запускать, а лишь сохранять (распаковывать) на диске (установка Store), а третий (*.bat файл) - запускать (установка Run). Также можно установить запуск *.bat файла в скрытом режиме (установка Hidden), чтобы не открывалось сопуствуещее командным файлам черное окно. Содержимое *.bat файла будет примерно таковым:
    start /wait program1.exe
    start /wait program2.exe
    del program1.exe
    del program2.exe
    cls
  Команда start с параметром /wait запускает указанную программу и ждет ее закрытия, после чего передает управление следующей команде *.bat файла (если ввести start /? в коммандной строке, будут указаны все параметры команды start).
  После запуска упакованного файла, произойдет распаковывание всех трех файлов и запуск *.bat файла. Этот файл запустит первую программу. После ее закрытия будет запущена вторая программа. После закрытия второй программы, будут удалены обе программы с диска. Естественно, файлы можно удалять и после закрытия каждой программы в отдельности (жаль нельзя удалять программу сразу после ее запуска, так как Windows не разрешает стирать файл программы до ее закрытия). Однако *.bat файл не будет удален (он ведь не может сам себя удалить).
  Команда cls в конце обеспечит автоматическое закрытие черного окна *.bat файла после его завершения (даже если *.bat файл запускается скрытно, лучше оставить эту строку, чтобы программа закрылась до конца).
  А насчет запуска программ НЕ из файлов на диске, я не представляю, как это сделать.

14-05-2002 13:23
Нашел недавно еще одну подобную программу объединяющую два файла
и запускающую их по очереди: SuperGlue32 by BaNZaY.
Нашел здесь: http://bonza.narod.ru
Может у кого нибудь есть ее исходники? Очень надо!!!

P.S. Может все таки кто нибудь знает принцип построения
    exe-компрессоров или может дать ссылку на архив документации
    по этому вопросу? Жду ответов тут или на мыло!

21-02-2002 01:34 | Сообщение от автора вопроса
Здравствуйте я вот уже несколько недель бьюсь над проблемой склейки двух файлов и у меня таже проблема
Joiner и другие деревянные изделия ничем помочь не могут они запускают оба файла сразу.
Если вы нашли то что искали напишите мне буду очень признателе.
volkov-b@yandex.ru, volkov-b@rambler.ru





23-11-2001 08:32
Я пробовал такое делать и нечего хорошего не добился.
Единственое как уменя работеает это:
-сливаю два файла программно
-выполняется та которая первая
-первая же прога у меня отцепляла от себя вторую в определённый
каталог и запускала.
Только так.
Таким образо можно соединить хоть 10 файлов но будет выполнятся
только первый. А затем он разединит от общего все и будет их запускать.

21-11-2001 18:02 | Сообщение от автора вопроса
Joiner by Crash - это копия (почти) широко известной Joiner by Blade. Все там устроено просто. В начале
файла идет распаковщик, а затем программы. При запуске распаковщик КОПИРУЕТ из тела файла программы
в другое место на диске и запускает их с помощью CreateProcess() или ShellExecute(). Мне бы хотелось
запускать эти программы БЕЗ копирования. Размер склеиваемых программ может достигать скажем 5 МБ и
заниматься копированием этих программ ну никак не хочется. Да и казалось бы зачем? Ведь они и так уже
загружены в памяти!! Мне говорили на ассемблере возможно такое сделать, но я его не знаю ;) Неужели на
Delphi такого сделать нельзя?

21-11-2001 09:35
Причём эти временные файлы не удаляются по завершении работы, как я только что
выяснил! Мрак...

21-11-2001 09:33
Да, посмотрел на MJ... Он делает именно так, тупо и просто: создаёт во временном
каталоге два exe'шника, соответствующих упакованным файлам и запускает их.
А Joiner by crash я так и не понял, что это за зверь... Судя по исходникам --
что-то подобное.

21-11-2001 07:38
Есть такой сайт "Мастера Дельфи"
DELPHI.mastak.ru
Поищи там вот это -
Joiner by crash 
Программа, которая пакует 2 файла в один,
и когда запускаешь упакованыый файл,
то запускаются ранее упакованые 2 файла.
Там же можно скачать и исходники

21-11-2001 07:09
Хм... Ну готового рецепта у меня нет, увы.

Можно попробовать объединить две проги в одну, объединив и все их управляющие
структуры... Было бы интересно, я поковыряюсь. Но вряд ли это быстро. Так
что попробуй готовые решения поискать.

20-11-2001 16:40 | Сообщение от автора вопроса
Естесственно первая программа в исходниках, то есть это должна быть моя программа. втрой идет
чужая программа. она может быть вполне приличных размеров, скажем 1-5 МБ. 

20-11-2001 15:21
Какая программа у тебя в исходниках? Та, что работает первой или вторая?
Если ни одной, то ой... Это грустно.

20-11-2001 12:52 | Сообщение от автора вопроса
К сожалению я не представляю как работают упаковщики exe'шников. Программы должны исполняться
одна за другой. Сначала запускается первая программа (та, что в начале файла), заканчивает свою работу и
запускается вторая программа. Я даже примерно не представляю как это можно сделать :( Мне бы идейку или
примерчик ;)


20-11-2001 07:57
А чем плох вариант с двумя отдельными exe'шниками? Вообще говоря, структура
PE-файла (частный случай -- виндомые exe, dll и пр.) не предполагает наличия
двух программ с двумя точками входа. Типично вирусная технология :-)

Запускать программу, которая компилировалась в расчёте на исполнение в отдельном
процессе, как поток другого... Тут я не берусь предсказать последствия,
скорее всего будут многочисленные конфликты при доступе к общим объектам,
куче, например. Следовательно, надо много извращаться, чтобы такое стало
возможным.

А запустить отдельный процесс не из файла, насколько я знаю, винда не позволит.
Во всяком случае, в описании функции CreateProcess есть на эту тему совершенно
недвусмысленное замечание. Может быть можно ещё как-то создать процесс?
Не знаю.

Программы должны параллельно исполняться или одна за другой (как это делают, например
упаковщики exe'шников)? Если одна за другой, то можно придумать что-нибудь...
А если вместе, то я пас. Слишком много ненадёжного изврата придётся творить.

Добавьте свое cообщение

Вашe имя:  [Войти]
Ваш адрес (e-mail):На Королевстве все адреса защищаются от спам-роботов
контрольный вопрос:
"Мы с тобой одной крови — ты и я!". Чьи это заветные слова?
в качестве ответа на вопрос или загадку следует давать только одно слово в именительном падеже и именно в такой форме, как оно используется в оригинале.
Надоело отвечать на странные вопросы? Зарегистрируйтесь на сайте.
Тип сообщения:
Текст:
Жирный шрифт  Наклонный шрифт  Подчеркнутый шрифт  Выравнивание по центру  Список  Заголовок  Разделительная линия  Код  Маленький шрифт  Крупный шрифт  Цитирование блока текста  Строчное цитирование
  • вопрос Круглого стола № XXX

  • вопрос № YYY в тесте № XXX Рыцарской Квинтаны

  • сообщение № YYY в теме № XXX Базарной площади
  • обсуждение темы № YYY Базарной площади
  •  
     Правила оформления сообщений на Королевстве

    Страница избранных вопросов Круглого стола.
      
    Время на сайте: GMT минус 5 часов

    Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter.
    Функция может не работать в некоторых версиях броузеров.

    Web hosting for this web site provided by DotNetPark (ASP.NET, SharePoint, MS SQL hosting)  
    Software for IIS, Hyper-V, MS SQL. Tools for Windows server administrators. Server migration utilities  

     
    © При использовании любых материалов «Королевства Delphi» необходимо указывать источник информации. Перепечатка авторских статей возможна только при согласии всех авторов и администрации сайта.
    Все используемые на сайте торговые марки являются собственностью их производителей.

    Яндекс цитирования