Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Склеивание  (Прочитано 8317 раз)
0 Пользователей и 1 Гость смотрят эту тему.
bacho_sun
Гость
« : 15-04-2008 10:24 » 

Приветствую
Ребята подскажите как осуществить склеивание двух файлов exe.
У меня есть исходники на bcb обоих.
Нужно , чтобы при запуске один файл копировал из своего тела другой exe в какуюто папку.
Кто сталкивался с этим помогите пожалуйста.

Записан
Алексей++
кот глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #1 : 15-04-2008 10:43 » 

склеивание тут ни при чём Улыбаюсь

второй экзешник надо в виде ресурса (блок данных) вставить в исходник первого. А первый создаст файл и зальёт в него блок данных, получится второй файл на диске
Подробности не подскажу, никогда не заталкивал блок данных в ресурсы ))
Записан

RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #2 : 15-04-2008 12:59 » 

В BCB это проблематично. Скажем, в 6-м нет редактора ресурсов - его заменяет ImageEditor и, соотв., ничего кроме графики он не позволяет загрузить. Возможно как-то иначе можно...
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #3 : 15-04-2008 14:46 » 

Хммм... можно просто дубово-элементарно сделать. Надо только точно знать размер первого скомпилированного файла.
Потом:

1. копируем оба файла в один результат обзываем как первый экзешник

2. первый экзешник открывает себя для чтения и с позиции "своя длинна" копирует всё в другй EXE файл.

3. запускает его ... ну дальше фантазия
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
zubr
Команда клуба

by
Offline Offline
Пол: Мужской

« Ответ #4 : 15-04-2008 14:53 » 

В BCB это проблематично. Скажем, в 6-м нет редактора ресурсов - его заменяет ImageEditor и, соотв., ничего кроме графики он не позволяет загрузить. Возможно как-то иначе можно...
Неужели? Не может быть. Стройки под рукой нет, но думаю как и в Delphi в каталоге Bin есть программка brcc32.exe, которая позволяет создавать res-файлы.
bacho_sun, у меня есть такой проект, но на Delphi, если устроит скину пример.
Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #5 : 15-04-2008 15:27 » 

Попробовал так:

test.rc:
Код: (Text)
test RCDATA test.exe

brcc32 -fotest.res @test.rc

Получил test.res и подключил его к проекту.

Следующий код получает указатель на ресурс:
Код: (C++)
    HRSRC rc = FindResource(0, "test", RT_RCDATA);
    HGLOBAL test = LoadResource(0, rc);

После использования его надо освободить:
Код: (C++)
    FreeResource(test);

В загрузку ресурса стоит добавить проверку.
« Последнее редактирование: 15-04-2008 15:30 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
zubr
Команда клуба

by
Offline Offline
Пол: Мужской

« Ответ #6 : 15-04-2008 16:11 » 

У борланда есть удобный класс TResourceStream
Код:
res=TResourceStream(HINSTANCE, "test", "RCDATA");
res.SaveToFile(....
res.Free;
Записан
Алексей++
кот глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #7 : 15-04-2008 17:56 » 

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

zubr
Команда клуба

by
Offline Offline
Пол: Мужской

« Ответ #8 : 15-04-2008 21:22 » 

А еще можно один экзешник запускать из другого не сохраняя его на диске,  из памяти процесса, то же относится и к длл.
Записан
Алексей++
кот глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #9 : 16-04-2008 03:11 » 

zubr, а покажи, как
Записан

zubr
Команда клуба

by
Offline Offline
Пол: Мужской

« Ответ #10 : 16-04-2008 05:39 » 

Алексей1153++, тебя дельфийский код устроит? Переводить в C времени нет.
Записан
Алексей++
кот глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #11 : 16-04-2008 06:27 » 

давай
Записан

zubr
Команда клуба

by
Offline Offline
Пол: Мужской

« Ответ #12 : 16-04-2008 08:16 » 

Код:
program RunFromResurs;

uses
  SysUtils, Windows, Classes;

{$R Resurs.RES} 

type
  PIMAGE_NT_HEADERS = ^IMAGE_NT_HEADERS;
  IMAGE_NT_HEADERS = packed record
    Signature       : DWORD;
    FileHeader      : IMAGE_FILE_HEADER;
    OptionalHeader  : IMAGE_OPTIONAL_HEADER;
  end;
  PIMAGE_SECTION_HEADER = ^IMAGE_SECTION_HEADER;
  IMAGE_SECTION_HEADER = packed record
    Name            : packed array [0..IMAGE_SIZEOF_SHORT_NAME-1] of Char;
    PhysicalAddress : DWORD; // or VirtualSize (union);
    VirtualAddress  : DWORD;
    SizeOfRawData   : DWORD;
    PointerToRawData : DWORD;
    PointerToRelocations : DWORD;
    PointerToLinenumbers : DWORD;
    NumberOfRelocations : WORD;
    NumberOfLinenumbers : WORD;
    Characteristics : DWORD;
  end;
  PIMAGE_DOS_HEADER = ^IMAGE_DOS_HEADER;
  IMAGE_DOS_HEADER = packed record      { DOS .EXE header }
    e_magic         : WORD;             { Magic number }
    e_cblp          : WORD;             { Bytes on last page of file }
    e_cp            : WORD;             { Pages in file }
    e_crlc          : WORD;             { Relocations }
    e_cparhdr       : WORD;             { Size of header in paragraphs }
    e_minalloc      : WORD;             { Minimum extra paragraphs needed }
    e_maxalloc      : WORD;             { Maximum extra paragraphs needed }
    e_ss            : WORD;             { Initial (relative) SS value }
    e_sp            : WORD;             { Initial SP value }
    e_csum          : WORD;             { Checksum }
    e_ip            : WORD;             { Initial IP value }
    e_cs            : WORD;             { Initial (relative) CS value }
    e_lfarlc        : WORD;             { File address of relocation table }
    e_ovno          : WORD;             { Overlay number }
    e_res           : packed array [0..3] of WORD; { Reserved words }
    e_oemid         : WORD;             { OEM identifier (for e_oeminfo) }
    e_oeminfo       : WORD;             { OEM information; e_oemid specific }
    e_res2          : packed array [0..9] of WORD; { Reserved words }
    e_lfanew        : Longint;          { File address of new exe header }
  end;

function ZwUnmapViewOfSection(SectionHandle: THandle;
  p: Pointer): DWord; stdcall; external 'ntdll.dll';

function protect(characteristics: ULONG): ULONG;
const  mapping: array [0..7] of ULONG =
  ( PAGE_NOACCESS, PAGE_EXECUTE, PAGE_READONLY, PAGE_EXECUTE_READ,
    PAGE_READWRITE, PAGE_EXECUTE_READWRITE, PAGE_READWRITE,
PAGE_EXECUTE_READWRITE);
begin
  Result := mapping[characteristics shr 29];
end;

function RunFromResurs(ResName, ResType:string): Cardinal;
var
  res:TResourceStream;
  pi: TProcessInformation;
  si: TStartupInfo;
  x, p, q: Pointer;
  nt: PIMAGE_NT_HEADERS;
  context: TContext;
  sect: PIMAGE_SECTION_HEADER;
  i:Integer;
  nb:Cardinal;
begin
 si.cb := SizeOf(si);
 ZeroMemory(@si, SizeOf(si));
 CreateProcess(nil, PChar('cmd.exe'), nil, nil, FALSE, CREATE_SUSPENDED, nil, nil, si, pi);

 context.ContextFlags := CONTEXT_INTEGER;
 GetThreadContext(pi.hThread,  context);

 ReadProcessMemory(pi.hProcess, PChar(context.ebx) + 8, @x, sizeof (x), nb);

 ZwUnmapViewOfSection(pi.hProcess, x);

 res:=TResourceStream.Create(HINSTANCE, PChar(ResName), PChar(ResType));
 try
  p:=res.Memory;

  if p = nil then exit;


  nt := PIMAGE_NT_HEADERS(PCHAR(p) + PIMAGE_DOS_HEADER(p).e_lfanew);

  q := VirtualAllocEx( pi.hProcess,
                       Pointer(nt.OptionalHeader.ImageBase),
                       nt.OptionalHeader.SizeOfImage,
                       MEM_RESERVE or MEM_COMMIT, PAGE_EXECUTE_READWRITE);

  WriteProcessMemory(pi.hProcess, q, p, nt.OptionalHeader.SizeOfHeaders, nb);

  sect := PIMAGE_SECTION_HEADER(nt);
  Inc(PIMAGE_NT_HEADERS(sect));

  for I := 0 to nt.FileHeader.NumberOfSections - 1 do
  begin
   WriteProcessMemory(pi.hProcess, PCHAR(q) + sect.VirtualAddress,
                           PCHAR(p) + sect.PointerToRawData, sect.SizeOfRawData, nb);
   VirtualProtectEx( pi.hProcess, PCHAR(q) + sect.VirtualAddress,
                          sect.SizeOfRawData, protect(sect.Characteristics), @x);
   Inc(sect);
  end;

  WriteProcessMemory(pi.hProcess, PCHAR(context.Ebx) + 8, @q, sizeof(q), nb);

  context.Eax := ULONG(q) + nt.OptionalHeader.AddressOfEntryPoint;

  SetThreadContext(pi.hThread, context);

  ResumeThread(pi.hThread);
  Result := pi.hProcess;
 finally
   res.Free;
 end;
end; 

begin
 RunFromResurs('Test', 'EXEFILE');
end.
« Последнее редактирование: 16-04-2008 08:19 от zubr » Записан
Алексей++
кот глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #13 : 16-04-2008 08:47 » 

ага. Так я и думал Отлично
Шутю, дома вникать стану, без бутылки кефира тут низя
Записан

bacho_sun
Гость
« Ответ #14 : 16-04-2008 10:08 » 

Ребята огромное всем вам спасибо. Благодарю от всего сердца. И признаюсь мне нравится этот форум. Спасибо вам.
zubr спасибо тебе, я к сожалению Delphy не изучал, но всеравно спасибо.
Жаль, что не могу реально всех вас пригласить на пиво.
Еще раз спасибо
Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #15 : 16-04-2008 11:01 » 

Да, до Грузии далековато... Больше гари - меньше ям

bacho_sun, заходи еще.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Алексей++
кот глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #16 : 16-04-2008 11:57 » 

а на пиво они сами придут - тока позови Отлично
Записан

DrGluck
Постоялец

ru
Offline Offline
Пол: Мужской

« Ответ #17 : 17-04-2008 07:38 » 

Вот хоть нормальный человек нормальный вопрос задал. Не зря воевали.
Записан

Good user - dead user
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines