【问题标题】:Accessing parameters passed on the stack in an ASM function在 ASM 函数中访问堆栈上传递的参数
【发布时间】:2010-08-26 08:48:56
【问题描述】:

我正在编写一个要从 C 调用的汇编函数,它将调用 sidt 机器指令,并将内存地址传递给 C 函数。通过对MSVC10产生的代码的分析,我构造了如下代码(YASM语法):

SECTION    .data
SECTION    .text
GLOBAL _sidtLoad
_sidtLoad:

push        ebp  
mov         ebp,esp  
sub         esp,0C0h  
push        ebx  
push        esi  
push        edi  
lea         edi,[ebp-0C0h]  
mov         ecx,30h  
mov         eax,0CCCCCCCCh  

sidt [ebp+8]

pop         edi  
pop         esi  
pop         ebx  
add         esp,0C0h  
cmp         ebp,esp    
mov         esp,ebp  
pop         ebp  
ret  

这是 C 函数签名:

void sidtLoad (void* mem);

据我所知,一切都应该正常工作,我什至检查了传递给函数的内存地址,发现它与存储在 [ebp+8] 的地址匹配(字节反转,我认为这是字节序的结果,应由机器处理)。我已经为 sidt 指令尝试了其他参数,例如 [ebp+12]、[ebp+4]、[ebp-8] 等,但没有运气。

P.S 我在外部汇编模块中编写此代码是为了解决在使用 MSVC10 定位 x64 时缺少内联汇编的问题。然而,这个特殊的汇编函数/程序是作为 x86 运行的,这样我就可以掌握整个过程。

P.P.S 我没有使用 __sidt 内在函数,因为 Windows 驱动程序工具包 (WDK) 似乎不支持它。或者至少我无法让它与它一起工作!

【问题讨论】:

  • 你是在用户模式还是内核模式下运行? Windows 下绝对不支持直接操作 IDT - 你想做什么?
  • sidt 指令简单地将IDT 中的数据存储到指定地址。我已经初始化了一个包含正确成员的结构,并将它的地址传递给 sidtLoad() 函数。我只是想用 IDT 信息填充结构并将其打印出来。如果我使用 inline asm 调用 sidt 指令效果很好,所以我认为这不是安全访问问题。

标签: c assembly 64-bit


【解决方案1】:

您的代码会将IDT 写入内存地址ebp+8,这不是您想要的。相反,您需要类似:

mov eax, [ebp+8]
sidt [eax]

【讨论】:

    【解决方案2】:

    编译:

    int sidLoad_fake(void * mem) {
        return (int)mem;
    }
    

    组装,然后查看它从哪里提取值以放入返回寄存器。

    我认为 x86_64 上的前几个参数是在寄存器中传递的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-06-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-17
      相关资源
      最近更新 更多