I am working a project using Samba 3.6.25. When I follow the source code of “smbclient” trying to build my own SMB server listing utility, I met a strange thing:
When I invoke a function, it skipped my first parameter and fill it with second one instead, and then the second the third, as so on.
The function I invoke is: cli_rpc_pipe_open_noauth_transport() in cli_pipe.c. I added some debug codes in it:
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;
}
……
And this is how I call this function:
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);
}
Here is what I get in the console:
--- 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
It did not make sense! Noticed that the four parameters I passed are: 0xdb2b20, 0x1, 0xda31c0, 0x7fe9fdc8 But what cli_rpc_pipe_open_noauth_transport() got was: 0x1, 0xda31c0, 0x7fe9fdc8, 0xdaf3d0
It was quite obvious that the first parameter “0xdb2b20” was missing, and the second one had taken its place.
Do anyone know what was going on and how could I fix it?
Thank you very much in advance!
——— Additional information:
The toolchain I was using was mipsel-linux-uclibc-cc/ld/ar. I tried to objdump several target files to see what was going on.
I dumped my own program, here is the assembles invoking the function. Noticed that the four parameters were passed in sequence: 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
Then I dumped smbclient, which also invoked cli_rpc_pipe_open_noauth_transport(). Here came the problem: it seemed that a0 was NOT used to pass parameter!!!
<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
Finally I dump cli_rpc_pipe_open_noauth_transport() itself, appears that it worked in the way smbclient did:
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
Additional information No.2 -- How I compile my program
Additional information No.3
The complete source of this repository: https://github.com/Andrew-M-C/SMB-CIFS_discovery
Answer from questioner here:
I solved it. Actually I have not solved the problem itself, but tried another way to achieve my goal.
The older way I built my project is: firstly build Samba, then link Samba object and static library files outside Samba repository. This was when I met the problem.
I have changed the way I built: firstly override the original Samba "smbclient" codes with my own ones, then build Samba. Samba Makefile recognize my source file as smbclient source file and smoothly compile and link them. Finally, it worked.
Please refer to the GitHub repository I mentioned in the question.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With