【问题标题】:Assembly x86 - Calling C functions汇编 x86 - 调用 C 函数
【发布时间】:2015-11-11 12:04:43
【问题描述】:

我想知道是否可以调用 printf 而不在数据段中声明格式数组。这个问题是关于 x86 的。

#include <stdio.h>

int main()
{
    __asm
    {
        push 1 ; number to print
        push 3710092110 ; format in ascii for %d\n
        call printf
        add esp, 8
    }

    return 0;
}

好的,所以我们需要推送格式的地址而不是格式本身,这样这样的东西应该足够接近了吧?

#include <stdio.h>

int main()
{
    __asm
    {
        push 3710092110 ; 3710092110 = format in ascii for %d\n
        push 1; argument to print
        lea edx, dword ptr[esp + 4]; get address of the format on stack
        push edx ; push the address of the format
        call printf
        add esp, 12
    }

    return 0;
}

你们碰巧有时间演示一个工作示例吗?在互联网上找不到任何关于它的信息。

【问题讨论】:

  • 是的,但是(我假设你知道),不是那个代码。
  • 这是可能的,但您需要将指针推送到格式字符串,而不是格式字符串本身。
  • 你如何判断3710092110%d\n任何 关系?
  • @Ville-ValtteriTiittanen:好吧,也许你应该在与我交谈之前测试一下。
  • @Mamma:如果你认为%d\n等于字节371009292110,你需要了解这两个转义码空终止。

标签: c assembly


【解决方案1】:

您的第二个代码 sn-p 接近但它仍然需要为格式字符串 %d\n 的内容使用不同的值。

所涉及的字符转换为十进制的 %=37、d=100、\n=10。
但是使用十六进制要容易得多:%=25h, d=64h, \n=0Ah 由于小字节序,我们必须将第一个字符放在 dword 的最低字节中以压入堆栈。我们保留最高字节零以进行必要的空终止。

%d\n  -->  000A6425h

您的代码:

#include <stdio.h>

int main()
{
    __asm
    {
        push 000A6425h ;= format in ascii for %d\n
        push 1; argument to print
        lea edx, dword ptr[esp + 4]; get address of the format on stack
        push edx ; push the address of the format
        call printf
        add esp, 12
    }

    return 0;
}

【讨论】:

    【解决方案2】:

    通过将其地址压入堆栈来传递格式字符串。所以你可以把字符串放在任何你喜欢的地方,但仍然需要传递它的地址。

    【讨论】:

      猜你喜欢
      • 2018-10-13
      • 2013-04-21
      • 2012-11-06
      • 1970-01-01
      • 2019-02-13
      • 2020-03-29
      • 2020-09-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多