C
crazymoon
Unregistered / Unconfirmed
GUEST, unregistred user!
我有一个思路。
在一个程序中,将一个函数的内容从内存中读出来,保存在文件中。
注: 似乎连续两个函数在内存中的位置是紧邻的,从而可以确定前一个函数的内存长度。
在另一个程序中,从上个文件中读取函数内容,并在内存申请一块空间,
将其放进去,控制程序直接运行这一段函数,这种思路有可行吗?
请高手赐教!
以下是我做的一些尝试:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button3: TButton;
Memo1: TMemo;
Edit1: TEdit;
Button4: TButton;
Button1: TButton;
Button2: TButton;
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
private
public
Procedure;
procedure MsgInt(x:integer);
end;
var
P1,P2ointer;
bointer;
v:integer;
Form1: TForm1;
CodeByte;
Str:String;
Data:Longint;
num:integer;
oa:integer;
procedure Test1;
procedure Test2;
procedure xx;
implementation
uses ex;
{$R *.dfm}
procedure SavePointerContent2File(Pointer;Size:integer;FName:string);
var Mstrm:TmemoryStream;
begin
//将内存内容写入流文件
Mstrm:=TmemoryStream.Create ;
MStrm.Write(P^,Size);
MStrm.SaveToFile(FName) ;
MStrm.Free ;
end;
procedure ReadPointerContent2File(var Dest;FName:string);
var Mstrm:TmemoryStream;
begin
//从流文件中读取
Mstrm:=TmemoryStream.Create ;
MStrm.LOadFromFile(FName) ;
Mstrm.Position:=0;
MStrm.ReadBuffer(Dest,Mstrm.Size);
MStrm.Free ;
end;
procedure AddCode(const CodeByte:Byte);//将数据赋给指针指向的位置
begin
Code^:=CodeByte;
Inc(Code);
Inc(num);
end;
procedure RunCode;
asm
Call Code
end;
procedure Test(PA:Integer);
begin
{执行机器码,每执行一个字节,移动指针,并计数;
最后,移动指针,返回原位置}
num:=0;
Code:=VirtualAlloc(nil, 4096, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
AddCode($E8);//CALL
Data:=Longint(PA) - Longint(Code) - 4;//计算Showmessage的相对地址
AddCode(Data and $FF);
AddCode(Data and $FF00 shr 8);
AddCode(Data and $FF0000 shr 16);
AddCode(Data and $FF000000 shr 24);
AddCode($C3);//RET
Dec(Code,num);//指针移动,返回首地址
RunCode;
end;
procedure CallTest(PAointer);
begin
{执行机器码,每执行一个字节,移动指针,并计数;
最后,移动指针,返回原位置}
num:=0;
Code:=VirtualAlloc(nil, 4096, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
AddCode($E8);//CALL
Data:=Longint(Integer(PA)) - Longint(Code) - 4;//计算Showmessage的相对地址
AddCode(Data and $FF);
AddCode(Data and $FF00 shr 8);
AddCode(Data and $FF0000 shr 16);
AddCode(Data and $FF000000 shr 24);
AddCode($C3);//RET
Dec(Code,num);//指针移动,返回首地址
RunCode;
end;
procedure Test1;
begin
showmessage('xxxxxxxxxxxxxxx1');
end;
procedure xx;
var x:string;
begin
showmessage('xxx1');
end;
procedure Test2;
begin
showmessage('OK2');
end;
procedure TForm1.MsgInt(x: integer);
begin
showmessage(inttostr(x));
end;
procedure TForm1.Button3Click(Sender: TObject);
var Mstrm:TmemoryStream;
PSize:integer;
begin
P1:=Ptr(integer(@Test1));
P2:=Ptr(integer(@Test2));
PSize:=integer(p2)-integer(p1);
v:=Integer(VirtualAlloc (nil,PSize,MEM_COMMIT, PAGE_EXECUTE_READWRITE));
if v=0 then showmessage('nil');
p:=ptr(v);
Move(P1, p,PSize);
p;
//Test(v);
// CallTest(P);
end;
procedure TForm1.Button4Click(Sender: TObject);
var xx:Array of byte;
begin
P1:=Ptr(integer(@Test1));
P2:=Ptr(integer(@Test2));
CallTest(P1);
end;
在一个程序中,将一个函数的内容从内存中读出来,保存在文件中。
注: 似乎连续两个函数在内存中的位置是紧邻的,从而可以确定前一个函数的内存长度。
在另一个程序中,从上个文件中读取函数内容,并在内存申请一块空间,
将其放进去,控制程序直接运行这一段函数,这种思路有可行吗?
请高手赐教!
以下是我做的一些尝试:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button3: TButton;
Memo1: TMemo;
Edit1: TEdit;
Button4: TButton;
Button1: TButton;
Button2: TButton;
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
private
public
Procedure;
procedure MsgInt(x:integer);
end;
var
P1,P2ointer;
bointer;
v:integer;
Form1: TForm1;
CodeByte;
Str:String;
Data:Longint;
num:integer;
oa:integer;
procedure Test1;
procedure Test2;
procedure xx;
implementation
uses ex;
{$R *.dfm}
procedure SavePointerContent2File(Pointer;Size:integer;FName:string);
var Mstrm:TmemoryStream;
begin
//将内存内容写入流文件
Mstrm:=TmemoryStream.Create ;
MStrm.Write(P^,Size);
MStrm.SaveToFile(FName) ;
MStrm.Free ;
end;
procedure ReadPointerContent2File(var Dest;FName:string);
var Mstrm:TmemoryStream;
begin
//从流文件中读取
Mstrm:=TmemoryStream.Create ;
MStrm.LOadFromFile(FName) ;
Mstrm.Position:=0;
MStrm.ReadBuffer(Dest,Mstrm.Size);
MStrm.Free ;
end;
procedure AddCode(const CodeByte:Byte);//将数据赋给指针指向的位置
begin
Code^:=CodeByte;
Inc(Code);
Inc(num);
end;
procedure RunCode;
asm
Call Code
end;
procedure Test(PA:Integer);
begin
{执行机器码,每执行一个字节,移动指针,并计数;
最后,移动指针,返回原位置}
num:=0;
Code:=VirtualAlloc(nil, 4096, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
AddCode($E8);//CALL
Data:=Longint(PA) - Longint(Code) - 4;//计算Showmessage的相对地址
AddCode(Data and $FF);
AddCode(Data and $FF00 shr 8);
AddCode(Data and $FF0000 shr 16);
AddCode(Data and $FF000000 shr 24);
AddCode($C3);//RET
Dec(Code,num);//指针移动,返回首地址
RunCode;
end;
procedure CallTest(PAointer);
begin
{执行机器码,每执行一个字节,移动指针,并计数;
最后,移动指针,返回原位置}
num:=0;
Code:=VirtualAlloc(nil, 4096, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
AddCode($E8);//CALL
Data:=Longint(Integer(PA)) - Longint(Code) - 4;//计算Showmessage的相对地址
AddCode(Data and $FF);
AddCode(Data and $FF00 shr 8);
AddCode(Data and $FF0000 shr 16);
AddCode(Data and $FF000000 shr 24);
AddCode($C3);//RET
Dec(Code,num);//指针移动,返回首地址
RunCode;
end;
procedure Test1;
begin
showmessage('xxxxxxxxxxxxxxx1');
end;
procedure xx;
var x:string;
begin
showmessage('xxx1');
end;
procedure Test2;
begin
showmessage('OK2');
end;
procedure TForm1.MsgInt(x: integer);
begin
showmessage(inttostr(x));
end;
procedure TForm1.Button3Click(Sender: TObject);
var Mstrm:TmemoryStream;
PSize:integer;
begin
P1:=Ptr(integer(@Test1));
P2:=Ptr(integer(@Test2));
PSize:=integer(p2)-integer(p1);
v:=Integer(VirtualAlloc (nil,PSize,MEM_COMMIT, PAGE_EXECUTE_READWRITE));
if v=0 then showmessage('nil');
p:=ptr(v);
Move(P1, p,PSize);
p;
//Test(v);
// CallTest(P);
end;
procedure TForm1.Button4Click(Sender: TObject);
var xx:Array of byte;
begin
P1:=Ptr(integer(@Test1));
P2:=Ptr(integer(@Test2));
CallTest(P1);
end;