Delphi

本类阅读TOP10

·游戏外挂设计技术探讨①
·如何使用Delphi设计强大的服务器程序
·分布式网络考试系统原型分析及实现
·用DLL方式封装MDI子窗体。
·使用HOOK随心监视Windows
·Delphi 水晶报表打包解决
·url编码与解码工具附代码
·工人线程中关闭窗体的实现
·hdsi2.0 sql注入部分抓包分析语句
·Borland Delphi 2005 下载

分类导航
VC语言Delphi
VB语言ASP
PerlJava
Script数据库
其他语言游戏开发
文件格式网站制作
软件工程.NET开发
运行期间生成代码的动态执行

作者:未知 来源:月光软件站 加入时间:2005-2-28 月光软件站

运行期间生成代码的动态执行

程序要执行首先要分配内存,在Win32下每个进程的内存地址空间都是虚拟的,其内存地址不是实际的物理地址,所以使用VirtualAlloc来完成虚拟内存的分配!

  LPVOID VirtualAlloc(
    LPVOID lpAddress,
    SIZE_T dwSize,
    DWORD flAllocationType,
    DWORD flProtect
  );

lpAddress 为申请的内存的起始地址,在Win32中你可以自己指定申请内存的地址范围!Win32中每个进程的地址空间为4GB,从0X00000000到0XFFFFFFFF。那是否可以在这个范围内任意分配内存?答案是否定的!在这其中只有一部分是可以供Win32应用使用的。使用GetSystemInfo获取系统信息,其中的lpMinimumApplicationAddress、lpMaximumApplicationAddress分别是可以使用的最小地址和最大地址。当然这里可以简单的设其值为Null,套用MSDN中的一句话:“If this parameter is NULL, the system determines where to allocate the region.”,直接将其交给系统去处理!

dwSize 为申请内存大小,以字节为单位,但如果其大小不为页的整数倍,系统将会加大内存达到页的整数倍。所以尽量按页来申请。同样可以用GetSystemInfo来获取dwPageSize。如Win9X下一页为4K,即4096字节。

flAllocationType 指定申请方式,flProtect 指定内存的保护方式,具体信息可查看MSDN:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/memory/base/virtualalloc.asp

这里根据需要将两参数设为MEM_COMMIT(提交已经申请的内存)、PAGE_EXECUTE_READWRITE(执行和读写)

完成了内存分配的工作后,下面就是将待执行的代码保存到内存中。机器语言指令是多字节指令,所以接下来要做的就是将一串具体数字按字节写入内存中。

下面的代码完成了一段子程序的生成:

var
  Code:PByte;
  Str:String;
  Data:Longint;
  num:integer;

  procedure AddCode(const CodeByte:Byte);//将数据赋给指针指向的位置
  begin
    Code^:=CodeByte;
    Inc(Code);
    Inc(num);
  end;

begin
  num:=0;
  Code:=VirtualAlloc(nil, 4096, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
  AddCode($50);//PUSH EAX
  AddCode($B8);//MOV EAX
  Str:='Hello World!';
  Data:=Longint(Pointer(PChar(Str)));//取字符串地址
  AddCode(Data and $FF);
  AddCode(Data and $FF00 shr 8);
  AddCode(Data and $FF0000 shr 16);
  AddCode(Data and $FF000000 shr 24);
  AddCode($E8);//CALL
  Data:=Longint(@ShowMessage) - 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($58);//POP EAX
  AddCode($C3);//RET
  Dec(Code,num);//指针移动,返回首地址
end;

也许可以通过相应技术手册来查询相应指令的含义,但在Win32下其实有种简单的理解方法。其实只要对任意一个Win32程序进行反编译,即可获得相应指令和汇编助记符的对应关系。

用汇编代码表述其意义为:

PUSH EAX
MOV EAX,[字符串地址]
CALL ShowMessage
POP EAX
RET

接下来,通过嵌入ASM代码:
asm
  Call Code
end;
就完成了上面代码的动态调用执行。




相关文章

相关软件




月光软件程序下载编程文档电脑教程网站设计网址导航网络文学游戏天地幽默笑话生活休闲写作范文安妮宝贝
电脑技术编程开发网络专区谈天说地情感世界游戏元素分类游戏热门游戏体育运动手机专区业余爱好影视沙龙
音乐天地数码广场教育园地科学大观古今纵横谈股论金人文艺术医学保健动漫图酷二手专区地方风情各行各业

月光软件站·版权所有