Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Delphi Новый топик    Ответить
 Сервис и HEAP_CREATE_ENABLE_EXECUTE  [new]
SOFT FOR YOU
Member [заблокирован]

Откуда:
Сообщений: 2761
Весь день сегодня убил на совершенно необъяснимую штуку.
Давайте разбираться.

Все знают, что в сервисных приложениях необходимо переопределять функцию GetServiceController, которая возвращает калбек.

Я знаю, что в Windows есть возможность выделять исполняемую память, заполнять нужными значениями и вызывать как функции. У нас есть универсальный класс сервера, я стал его модифицировать, проверять врапперы - всё отлично. Но в режиме службы при остановке возникает Exception, идентифицировать который не удалось.

Сейчас я сделал простенький проект, который иллюстрирует ситуацию. Там генерируемый код просто делает прыжок в имеющийся калбек.
Есть ли возможность избежать эксепшна? Может конечно идея изначально обречённая на провал, но хочется хотя бы понимать, почему сервис работает именно так.

Листинг публикую здесь, проект прилагаю в аттаче.
+
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.SvcMgr, Vcl.Dialogs;

type
  TService1 = class(TService)
    procedure ServiceCreate(Sender: TObject);
  private
    { Private declarations }
    FWrapper: TServiceController;
  public
    function GetServiceController: TServiceController; override;
    { Public declarations }
  end;

var
  Service1: TService1;

implementation

{$R *.dfm}

var
  ExecutableHeap: THandle;

procedure CreateExecutableHeap;
begin
  ExecutableHeap := HeapCreate($00040000{HEAP_CREATE_ENABLE_EXECUTE}, 0, 0);
end;

procedure DestroyExecutableHeap;
begin
  HeapDestroy(ExecutableHeap);
  ExecutableHeap := 0;
end;

function AllocExecutableMemory(const Size: Integer): Pointer;
begin
  Result := nil;
  if (ExecutableHeap <> 0) then
    Result := HeapAlloc(ExecutableHeap, 0, Size);
end;

// -------------------------------------------------------------

procedure ServiceController(CtrlCode: DWord); stdcall;
begin
  Service1.Controller(CtrlCode);
end;

function TService1.GetServiceController: TServiceController;
begin
  Result := FWrapper; //ServiceController;
end;

procedure TService1.ServiceCreate(Sender: TObject);
var
  Code: PByte;
begin
  Code := AllocExecutableMemory(5);
  Code[0] := $E9;
  PInteger(@Code[1])^ := Integer(@ServiceController) - Integer(Code) - 5;

  FWrapper := Pointer(Code);

  // проверка
 // FWrapper(100500);
end;


initialization
  CreateExecutableHeap;

finalization
  DestroyExecutableHeap;

end.


К сообщению приложен файл (Example.rar - 4Kb) cкачать
13 мар 18, 17:25    [21253391]     Ответить | Цитировать Сообщить модератору
 Re: Сервис и HEAP_CREATE_ENABLE_EXECUTE  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 45930

SOFT FOR YOU
Все знают, что в сервисных приложениях необходимо переопределять функцию GetServiceController

Уже смешно. Ты не поверишь, но нет, такую функцию переопределять не надо. Если в какой-то
левой библиотеке оно и сделано так, то это проблемы исключительно этой библиотеки.

Posted via ActualForum NNTP Server 1.5

13 мар 18, 17:58    [21253483]     Ответить | Цитировать Сообщить модератору
 Re: Сервис и HEAP_CREATE_ENABLE_EXECUTE  [new]
SOFT FOR YOU
Member [заблокирован]

Откуда:
Сообщений: 2761
Dimitry Sibiryakov,

Ты гонишь?
Это абстрактная функция
13 мар 18, 18:05    [21253498]     Ответить | Цитировать Сообщить модератору
 Re: Сервис и HEAP_CREATE_ENABLE_EXECUTE  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 45930

SOFT FOR YOU
Ты гонишь?

Нет, я читаю MSDN. В отличии от.

Posted via ActualForum NNTP Server 1.5

13 мар 18, 18:07    [21253506]     Ответить | Цитировать Сообщить модератору
 Re: Сервис и HEAP_CREATE_ENABLE_EXECUTE  [new]
SOFT FOR YOU
Member [заблокирован]

Откуда:
Сообщений: 2761
Dimitry Sibiryakov,

Так это класс Delphi. Читать ты конечно можешь что угодно. Но если не переопределить функцию - будет Exception.
13 мар 18, 18:25    [21253544]     Ответить | Цитировать Сообщить модератору
 Re: Сервис и HEAP_CREATE_ENABLE_EXECUTE  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 3562
SOFT FOR YOU,

Это не класс делфи. Это обычная статическая локальная функция-коллбэк
VOID WINAPI Handler(
    DWORD fdwControl 	// requested control code  
   );

параметры которой описаны в доке про RegisterServiceCtrlHandler.

А GetServiceController - это да, абстрактный метод TService, который должен возвращать указатель на нее.
Ты можешь, конечно, изобрести велосипед и забабахать код этой функции динамически, но тогда разбирайся сам.
13 мар 18, 18:33    [21253576]     Ответить | Цитировать Сообщить модератору
 Re: Сервис и HEAP_CREATE_ENABLE_EXECUTE  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 45930

SOFT FOR YOU
Так это класс Delphi.

Воот. И именно поэтому твоё пафосное "все знают, что" и далее по тексту - совершенно
невтемное. Те, кто пишут сервисы без применения классов Дельфи, совершенно справедливо
кладут на такое знание болт.

SOFT FOR YOU
Читать ты конечно можешь что угодно.

Ага, и именно сейчас у меня открыт "Intel Architecture Software Developer’s Manual",
содержимое которого недвусмысленно намекает, что ты ещё и машинный код сформировал криво.

Posted via ActualForum NNTP Server 1.5

13 мар 18, 18:35    [21253577]     Ответить | Цитировать Сообщить модератору
 Re: Сервис и HEAP_CREATE_ENABLE_EXECUTE  [new]
SOFT FOR YOU
Member [заблокирован]

Откуда:
Сообщений: 2761
YuRock,
Dimitry Sibiryakov,

Мне абсолютно всё равно, что вы читаете, используете вы стандартный класс или юзаете API. Это не важно.

Меня интересует, почему вдруг executable память стала некорректно работать. И как это исправить.
13 мар 18, 19:28    [21253664]     Ответить | Цитировать Сообщить модератору
 Re: Сервис и HEAP_CREATE_ENABLE_EXECUTE  [new]
rashid.abzalov
Member

Откуда:
Сообщений: 72
SOFT FOR YOU,

procedure ServiceController(CtrlCode: DWord); stdcall;
begin
  Service1.Controller(CtrlCode);
end;

function TService1.GetServiceController: TServiceController;
begin
  Result := ServiceController;
end;
13 мар 18, 19:42    [21253675]     Ответить | Цитировать Сообщить модератору
 Re: Сервис и HEAP_CREATE_ENABLE_EXECUTE  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 3562
rashid.abzalov,

он так не хочет осознанно, потому он этот код в 1-м сообщении темы, которое ты не читал, и закомментил.
13 мар 18, 19:51    [21253688]     Ответить | Цитировать Сообщить модератору
 Re: Сервис и HEAP_CREATE_ENABLE_EXECUTE  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 45930
Dimitry Sibiryakov
SOFT FOR YOU
Читать ты конечно можешь что угодно.

Ага, и именно сейчас у меня открыт "Intel Architecture Software Developer’s Manual",
содержимое которого недвусмысленно намекает, что ты ещё и машинный код сформировал криво.

SOFT FOR YOU
Мне абсолютно всё равно, что вы читаете, используете вы стандартный класс или юзаете API. Это не важно.

Эва... Ню-ню.
13 мар 18, 20:30    [21253722]     Ответить | Цитировать Сообщить модератору
 Re: Сервис и HEAP_CREATE_ENABLE_EXECUTE  [new]
SOFT FOR YOU
Member [заблокирован]

Откуда:
Сообщений: 2761
Dimitry Sibiryakov,

Ты хочешь сказать, у меня обычный джамп некорректный? ))
Ну-ну )
13 мар 18, 22:02    [21253856]     Ответить | Цитировать Сообщить модератору
 Re: Сервис и HEAP_CREATE_ENABLE_EXECUTE  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 45930

SOFT FOR YOU
Ты хочешь сказать, у меня обычный джамп некорректный? ))

Ты не поверишь, но именно это написано в том мануале, который я читаю.

Posted via ActualForum NNTP Server 1.5

13 мар 18, 22:21    [21253881]     Ответить | Цитировать Сообщить модератору
 Re: Сервис и HEAP_CREATE_ENABLE_EXECUTE  [new]
SOFT FOR YOU
Member [заблокирован]

Откуда:
Сообщений: 2761
Dimitry Sibiryakov,

Не поверю
13 мар 18, 23:18    [21253995]     Ответить | Цитировать Сообщить модератору
Все форумы / Delphi Ответить