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


Автор: Morinehtar 27.5.2011, 08:52
Ребятушки, возник такой вопрос....
Есть простенький код, который работает:

Код

unit Unit2;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm2 = class(TForm)
Button1: TButton;
Button2: TButton;
Edit1: TEdit;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form2: TForm2;
buf: array[1..1000] of byte;
n:Integer;
implementation

{$R *.dfm}

Procedure incr;
Begin
n:=n+1;
End;

Procedure _Print;
Begin
Form2.Edit1.Text:=inttostr(n);
End;

procedure TForm2.Button1Click(Sender: TObject);
begin
incr;
_print;
end;

procedure TForm2.Button2Click(Sender: TObject);
var
p:TProcedure;
begin
copymemory(@buf[1],@incr,Integer(@_Print)-Integer(@incr));
@p:=@buf[1];
p;
_print;
end;

end.


Чуток меняем одну процедуру:

Код

Procedure incr;
Begin
n:=n+1;
ShowMessage('rtg');
End;

И он чудесным образом перестаёт работать (Нарушение доступа) . Подскажите, может кто знает... 
Почему он перестаёт работать? Где можно прочитать об этом поподробнее?

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


Автор: Dik0n 27.5.2011, 15:12
Цитата(Morinehtar @  27.5.2011,  08:52 Найти цитируемый пост)
И он чудесным образом перестаёт работать (Нарушение доступа)

И правда, чудеса да и только smile

А если серьезно, кто так делает
во первых
Код выполняется на странице не имеющей атрибута на исполнение, ну да ладно это пол беды.
во вторых
вызов CALL указывает уже не на ShowMessage а черт знает куда, в связи с относительной адресацией.

Цитата(Morinehtar @  27.5.2011,  08:52 Найти цитируемый пост)
Где можно прочитать об этом поподробнее?

Гугли: Относительная адресация

Советую почитай, много познавательного http://wasm.ru/


Автор: bems 28.5.2011, 07:45
Цитата(Dik0n @  27.5.2011,  15:12 Найти цитируемый пост)
Код выполняется на странице не имеющей атрибута на исполнение
это же просто чтение на х86

Автор: Dik0n 28.5.2011, 10:03
Цитата(bems @  28.5.2011,  07:45 Найти цитируемый пост)
это же просто чтение на х86

какое же это чтение, внимательно смотрим на тему топика.
тут копируется полностью процедура в свой буфер и из него запускается!

Автор: CodeMonkey 28.5.2011, 10:49
Цитата(bems @  28.5.2011,  08:45 Найти цитируемый пост)
это же просто чтение на х86


http://www.transl-gunsmoker.ru/2008/12/blog-post.html.

Автор: 500mhz 28.5.2011, 12:52
код в сегменте read/write будет спокойно запускаться, не нада никаких virtualprotect
у ТС именно проблема с адресацией

Автор: bems 28.5.2011, 15:04
Цитата(Dik0n @  28.5.2011,  10:03 Найти цитируемый пост)
тут копируется полностью процедура в свой буфер и из него запускается! 
верно. Но на х86 исполнение разрешено если разрешено чтение

Цитата(CodeMonkey @  28.5.2011,  10:49 Найти цитируемый пост)
Just follow the rules, nobody gets hurt. 

я вообще так не делаю, мне это не говори smile (совсем другое дело получить доступ на запись туда откуда разрешено выполнение)
Я только сказал что в этом причины эксцепшна быть не может.

Автор: 500mhz 28.5.2011, 16:09
проблема эксцепшина что ShowMessage('rtg') вызываеться не по абсолютному адресу
в асм листинге это должно выглядить примерно так

push ptr rtg
mov eax,ShowMessage
call eax

смотря опять же как ShowMessage сделано (я в дельфи не силен)
может быть вариант mov eax,[ShowMessage]

Автор: CodeMonkey 28.5.2011, 16:28
Цитата(bems @  28.5.2011,  16:04 Найти цитируемый пост)
Я только сказал что в этом причины эксцепшна быть не может


Почему не может-то? DEP если включён - будет вылет.

Или ты в том смысле, что это не исключение, а именно завершение программы? Ну так автор и не говорил, что у него именно исключение.

Автор: 500mhz 28.5.2011, 17:08
CodeMonkey
вы о чем? проблему то уже решили - адресация
Цитата

И он чудесным образом перестаёт работать (Нарушение доступа) 

а это как раз эксцепш, и если он не обрабатываеться то будет сам понимаете что.

Автор: bems 28.5.2011, 20:38
Цитата(CodeMonkey @  28.5.2011,  16:28 Найти цитируемый пост)
DEP если включён - будет вылет.
поправочка, аппаратный DEP

Цитата(CodeMonkey @  28.5.2011,  16:28 Найти цитируемый пост)
Ну так автор и не говорил, что у него именно исключение. 
говорил что AV

Автор: Morinehtar 3.6.2011, 09:35
500mhz
Dik0n
Цитата

проблема эксцепшина что ShowMessage('rtg') вызываеться не по абсолютному адресу

Цимес в том, что вылетает внутри ShowMessage, а сам асм-код ShowMessage я сравнивал с  кодом при нормальном вызове - абсолютно идентичен.

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