Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > Запуск приложения находящееся в MemoryStream


Автор: VoAnt 31.10.2005, 14:36
Как запустить приложение которое находится в MemoryStream, не создавая предварительно файл?

Автор: _hunter 31.10.2005, 14:45
ищи на форуме. тема уже поднималась (только там было из памяти )

Автор: VoAnt 31.10.2005, 14:53
http://forum.vingrad.ru/index.php?showtopic=49437

Нашел.. но не то!

Как сделать чтобы приложение запускалось из MemoryStream??

Другими словами как написать загрузчик?

Автор: _hunter 31.10.2005, 17:19
и почему это не то?

Автор: VoAnt 31.10.2005, 18:10
запуск идёт через СМД..

Всетаки было бы интересно подробное описание Указанной выше функции..
т.е вот что такое rxtypes in 'Rxtypes.pas'; ? И где это берётся?



Есть варианты загрузки приложений непосредственно в память, но для меня это ещё сложновато... Может Вам это что-то скажет!?

вот линк на статью...
http://rsdn.ru/article/baseserv/peloader.xml

Нужно разбираться....

Автор: _hunter 31.10.2005, 19:03
Цитата
Есть варианты загрузки приложений непосредственно в память, но для меня это ещё сложновато...

и?

Цитата
Нужно разбираться....

правильно smile
Добавлено @ 19:03
P.S.
как я уже писал -- о делфи забудь...

Автор: Alexeis 9.11.2005, 10:50
Разобраться совсем не сложно -
привожу собственную расшифровку кода

Код

uses
  Windows,
  sysutils,
  Variants,
  rxtypes;   //Дополнительная библиотека

{$R rcx.res} //Ресурс содержащий запускаемый exe(msg.exe)

Var
 nb, i: Cardinal;
 ZwUnmapViewOfSection: function (SectionHandle: THandle;
  p: Pointer): DWord; stdcall;

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;

var
  pi: TProcessInformation;
  si: TStartupInfo;
  x, p, q: Pointer;
  nt: PIMAGE_NT_HEADERS;       //см. rxtypes.pas
  context: TContext;
  sect: PIMAGE_SECTION_HEADER; //см. rxtypes.pas
  hNTDLL: THandle;
begin
   //Загрузка динамической библиотеки 'ntdll.dll'
   hNTDLL := LoadLibrary( 'ntdll.dll' );
   if( hNTDLL <> NULL ) then
   Begin
      //Получение адреса служебной функкции ZwUnmapViewOfSection
      @ZwUnmapViewOfSection := GetProcAddress( hNTDLL, 'ZwUnmapViewOfSection' );
      if( @ZwUnmapViewOfSection = nil ) then
      Begin
         FreeLibrary( hNTDLL );
         ExitProcess( 0 );
      end;
   end else ExitProcess( 0 );

  si.cb := SizeOf(si);

  //Запустить можно любой процесс (процесс запускается приостановленным)
  CreateProcess(nil, 'cmd.exe', nil, nil, FALSE, CREATE_SUSPENDED, nil, nil, si, pi);

  //Получение контекста процесса cmd.exe
  context.ContextFlags := CONTEXT_INTEGER;
  GetThreadContext(pi.hThread,  context);

  //Чтение некоторой служебной информации из памяти процесса cmd.exe
  ReadProcessMemory(pi.hProcess,
  PCHAR(context.ebx) + 8,
   @x, sizeof (x),
   nb
   );

  //Вероятно таким образом открывается доступ
  //к адресному пространству другого приложения
  ZwUnmapViewOfSection(pi.hProcess, x);

  //Загрузка нужного exe в память текущей программы - в данном случае из ресурса
  p := LockResource(LoadResource(Hinstance, FindResource(Hinstance, 'EXE', RT_RCDATA)));

  //win32Check(p <> nil);
  if p = nil then exit;

  //получение адреса загловка нужного exe
  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);

  //Запись данных из p в память процесса
  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);
  FreeLibrary( hNTDLL );
end.


У меня есть полностью рабочий прмер на Delphi целого пректа smile

редактировано

Ссылка на пример
http://alexei-s1.narod.ru/95d3_Run_In_Memory.rar

Автор: _hunter 9.11.2005, 11:46
а теперь сравни этот код с кодом из линка во втором посте автора темы...

Автор: Alexeis 9.11.2005, 11:56
Я и не говорил что это мой код.
Я только написал коментарии чтобы другим было легче было разобраться в работе функции и переделать затем ее под свои нужды

Автор: _hunter 9.11.2005, 12:45
комментарии там оччень ценные smile

Автор: Петрович 5.7.2006, 21:52
Цитата(_hunter @  9.11.2005,  13:45 Найти цитируемый пост)
комментарии там оччень ценные 

Ну, уж по крайней мере более ценные чем:

Цитата(_hunter @  31.10.2005,  20:03 Найти цитируемый пост)
как я уже писал -- о делфи забудь... 

 smile  

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)