⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 说明.txt

📁 第2章“BASM(Borland汇编语言)精要”中的全部示例代码。包括: 目录 描述 --------------------------------
💻 TXT
字号:
说明
~~~~~~~~~~~~~~~

本示例用于演示如何在BASM中使得“jmp proc”执行后返回到下一行。

尽管使“jmp proc”执行后返回到下一行的方法很多,但要实现如下
两个目标却是比较难于做到的:
  1. 不破坏栈结构,使proc()与当前函数有相同的入口参数(stdcall)
  2. 代码通用,不需要每次都计算地址

这样的需求可能出现在使用raw hook技术实现的API拦截上。

本例实现了满足上述需求。但它同时导致一个严重问题:由于修改了栈
上的返回地址,因此事实上当前的JmpCall()过程在执行完并返回(ret)
时,将取得一个非确定的地址值。

这在本例中的直接后果就是:代码未尾的"readln;"一行将无法执行到。

要避免这个问题,应该使用一个内存地址来暂存“当前的”返回地址,
并在“jmp proc”之后修正堆栈。例如:
______________________________________________________
var
  temp : Pointer;

  // ...
    mov  ebx, [esp]      // 当前的返回地址
    mov  temp, ebx       // 暂存到temp

    DB $E8, $0, $0, $0, $0, $8F, $04, $24, $83, $04, $24, $0C
    jmp proc

    push temp            // 重填当前例程的返回地址
@@ReturnHere:
______________________________________________________

更复杂的情况与例程的入口参数有关。由于除cdecl之外的调用约定都要求目前例
程在退出之前清除堆栈。因此上例在实用中更常见的用法会是:
______________________________________________________
  // ...
  // 1. 备份栈上的参数和返回地址(到堆)

    DB $E8, $0, $0, $0, $0, $8F, $04, $24, $83, $04, $24, $0C
    jmp proc

  // 2. 从堆中恢复参数和返回地址(到栈)
@@ReturnHere:
______________________________________________________

这其实已经使前面所列的两个目标中“代码通用”变得无法实现。如果摒弃这些
需求,那么更常见的做法是:
______________________________________________________
  // ...
  // 1. 在栈上再分配同等大小的空间
  // 2. 在栈上再制作一个入口参数块(内存复制)

    call proc            // call, 将返回到地址@@ReturnHere

@@ReturnHere:
______________________________________________________

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -