C函数参数神秘漂移?

时间:2016-12-08 08:00:59

标签: c function assembly parameter-passing mips

我正在使用Samba 3.6.25开展项目。 当我按照“smbclient”的源代码尝试构建我自己的SMB服务器列表实用程序时,我遇到了一件奇怪的事情:

当我调用一个函数时,它会跳过我的第一个参数并用第二个参数填充它,然后第二个填充第三个参数,如下所示。

我调用的函数是: cli_pipe.c 中的 cli_rpc_pipe_open_noauth_transport()。我在其中添加了一些调试代码:

NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
                        enum dcerpc_transport_t transport,
                        const struct ndr_syntax_id *interface,
                        struct rpc_pipe_client **presult)
{

    struct rpc_pipe_client *result;
    struct pipe_auth_data *auth;
    NTSTATUS status;

    status = cli_rpc_pipe_open(cli, transport, interface, &result);
    _DEBUG("cli = %p", cli);
    _DEBUG("transport = %p", transport);
    _DEBUG("interface = %p", interface);
    _DEBUG("presult = %p", presult);
    _DEBUG("cli->desthost = %p", cli->desthost);
    _DEBUG("cli->desthost = \"%s\"", cli->desthost);
    if (!NT_STATUS_IS_OK(status)) {
        return status;
    }
……

这就是我称之为这个功能的方式:

NTSTATUS _pipe_open_noauth(struct cli_state *cli, const struct ndr_syntax_id *intf, struct rpc_pipe_client **presult)
{
    SMBD_DEBUG("cli = %p", cli);
    SMBD_DEBUG("intf = %p", intf);
    SMBD_DEBUG("presult = %p", presult);
    SMBD_DEBUG("cli->desthost = %p", cli->desthost);
    SMBD_DEBUG("cli->desthost = \"%s\"", cli->desthost);
    return cli_rpc_pipe_open_noauth_transport(cli, 1, intf, presult);
}

以下是我在控制台中获得的内容:

--- SMBD (util_smbclient.c, 117): cli = 0xdb2b20
--- SMBD (util_smbclient.c, 118): intf = 0xda31c0
--- SMBD (util_smbclient.c, 119): presult = 0x7fe9fdc8
--- SMBD (util_smbclient.c, 120): cli->desthost = 0xdd3a50
--- SMBD (util_smbclient.c, 121): cli->desthost = "192.168.1.125"
=== Samba (rpc_client/cli_pipe.c, 2873): cli = 0x1
=== Samba (rpc_client/cli_pipe.c, 2874): transport = 0xda31c0
=== Samba (rpc_client/cli_pipe.c, 2875): interface = 0x7fe9fdc8
=== Samba (rpc_client/cli_pipe.c, 2876): presult = 0xdaf3d0

没有意义!注意到我传递的四个参数是: 0xdb2b20,0x1,0xda31c0,0x7fe9fdc8 但 cli_rpc_pipe_open_noauth_transport()得到的是: 0x1,0xda31c0,0x7fe9fdc8,0xdaf3d0

很明显第一个参数“0xdb2b20”丢失了,第二个参数取代了它。

有谁知道发生了什么,我该如何解决?

非常感谢你!

--- 其他信息:

我使用的工具链是mipsel-linux-uclibc-cc / ld / ar。我试图objdump几个目标文件,看看发生了什么。

我转储了自己的程序,这里是调用函​​数的汇编。 注意到四个参数按顺序传递:a0,a1,a2,a3:

  409bf0:   8fdc0010    lw  gp,16(s8)
  409bf4:   8fc40020    lw  a0,32(s8)
  409bf8:   24050001    li  a1,1            # store “1” in a1
  409bfc:   8fc60024    lw  a2,36(s8)
  409c00:   8fc70028    lw  a3,40(s8)
  409c04:   8f99ab74    lw  t9,-21644(gp)
  409c08:   00000000    nop
  409c0c:   0320f809    jalr    t9
  409c10:   00000000    nop
  409c14:   8fdc0010    lw  gp,16(s8)
  409c18:   03c0e821    move    sp,s8
  409c1c:   8fbf001c    lw  ra,28(sp)
  409c20:   8fbe0018    lw  s8,24(sp)
  409c24:   03e00008    jr  ra
  409c28:   27bd0020    addiu   sp,sp,32

然后我转储了smbclient,它也调用了 cli_rpc_pipe_open_noauth_transport()。 问题出现了:似乎a0不用于传递参数!!!

<cli_rpc_pipe_open_noauth>:
              …
  487840:   8fdc0018    lw  gp,24(s8)
  487844:   8fc2003c    lw  v0,60(s8)
  487848:   00000000    nop
  48784c:   afa20010    sw  v0,16(sp)
  487850:   02002021    move    a0,s0
  487854:   8fc50034    lw  a1,52(s8)
  487858:   24060001    li  a2,1    # Here, the number “1” was stored in a2 instead of a1!!!
  48785c:   8fc70038    lw  a3,56(s8)
  487860:   8f99aed0    lw  t9,-20784(gp)
  487864:   00000000    nop
  487868:   0320f809    jalr    t9  # cli_rpc_pipe_open_noauth_transport()
  48786c:   00000000    nop
  487870:   8fdc0018    lw  gp,24(s8)
  487874:   02001021    move    v0,s0
  487878:   03c0e821    move    sp,s8
  48787c:   8fbf0028    lw  ra,40(sp)
  487880:   8fbe0024    lw  s8,36(sp)
  487884:   8fb00020    lw  s0,32(sp)
  487888:   03e00008    jr  ra
  48788c:   27bd0030    addiu   sp,sp,48

最后我转储 cli_rpc_pipe_open_noauth_transport()本身,看来它的工作方式是 smbclient

0053bdac <cli_rpc_pipe_open_noauth_transport>:
  53bdac:   3c1c0087    lui gp,0x87
  53bdb0:   279c3624    addiu   gp,gp,13860
  53bdb4:   0399e021    addu    gp,gp,t9
  53bdb8:   27bdffc0    addiu   sp,sp,-64
  53bdbc:   afbf0038    sw  ra,56(sp)
  53bdc0:   afbe0034    sw  s8,52(sp)
  53bdc4:   afb00030    sw  s0,48(sp)
  53bdc8:   03a0f021    move    s8,sp
  53bdcc:   afbc0018    sw  gp,24(sp)
  53bdd0:   afc40040    sw  a0,64(s8)
  53bdd4:   afc50044    sw  a1,68(s8)
  53bdd8:   afc60048    sw  a2,72(s8)
  53bddc:   afc7004c    sw  a3,76(s8)
  53bde0:   8f848080    lw  a0,-32640(gp)
  53bde4:   00000000    nop
  53bde8:   24844da0    addiu   a0,a0,19872
  53bdec:   24050b39    li  a1,2873
  53bdf0:   8fc60044    lw  a2,68(s8)
  53bdf4:   8f99cab0    lw  t9,-13648(gp)
  53bdf8:   00000000    nop
  53bdfc:   0320f809    jalr    t9              <—— invoke cli_rpc_pipe_open()
  53be00:   00000000    nop

附加信息No.2 - 我如何编译程序

  1. 我从官方FTP服务器上下载了Samba。
  2. 配置并进行(交叉编译)
  3. 查找&#34; source3&#34;中的所有.o文件目录,然后将它们一起归档到一个.a文件中。
  4. 创建我自己的应用程序,调用Samba函数大致就像它自己的程序&#34; smbclient&#34;确实有很多-I选项可以确保编译工作
  5. 链接了Samba正式提供的libsmbclient.a,以及我自己在步骤3中存档的.a。
  6. 补充资料第3号

    此存储库的完整源代码: https://github.com/Andrew-M-C/SMB-CIFS_discovery

1 个答案:

答案 0 :(得分:1)

来自提问者的回答:

我解决了。实际上我没有解决问题本身,但尝试了另一种方法来实现我的目标。

我构建项目的方法是:首先构建Samba,然后将Samba对象和静态库文件链接到Samba存储库之外。这是我遇到问题的时候。

我改变了我的构建方式:首先覆盖原来的Samba&#34; smbclient&#34;代码与我自己的代码,然后构建Samba。 Samba Makefile将我的源文件识别为smbclient源文件,并顺利地编译和链接它们。最后,它奏效了。

请参阅我在问题中提到的GitHub存储库。