2012-06-21 129 views
11

通过strace,可以看到某个文件描述符和特定命令的ioctl调用。第三个参数是一个结构,但strace显示它是一个指向内存的原始指针。 strace的输出例如:解释strace输出

open("/dev/node", O_RDWR) = 3 
ioctl(3, 0x108, 0x8f0eb18) = 0 
close(3) 

有没有办法(strace的期权或其他工具)来看看是什么结构,或原始指针后面至少价值?

+0

它是否给你的地址指令?如果是这样的话,在GDB中添加一个断点然后查看内存非常简单......如何确定实际结构我不是很确定。 – Matt

+0

我的意思是,如果我将它写入我的程序中,它看起来像这样: 'ioctl(dev_node,IOCTL_CODE,&ioctl_struct)',其中第三个参数是Ioctl_Buf_Struct类型的结构。当我们在上面的例子中看到strace用于二进制程序时,我会好奇地知道0x8f0eb18地址背后的内容:在那里发送的结构是什么,或者至少它的值是什么。 gdb可以在这里帮忙吗? –

+0

那么......如果你运行这个程序,在那个命令之前停止,那么你可以通过解引用指针来找到这些值。使用strace查找所有malloc调用,直到找到返回该指针的那个。这会告诉你结构的大小。然后可以用已知大小查看内存,然后以二进制形式重现该结构。你可能永远不知道结构是什么,但你可以找到它的值。 – Matt

回答

2

在gdb中,如果你调用的ioctl之前就停了,你可以再输入:

(gdb) p *(ioctl_struct *) 0x8f0eb18 

这将告诉您如何内存位置映射到ioctl_struct的内容。

1

我遇到了一个类似的问题:想要检查一个系统调用ioctlvde_switch(它创建一个TUN/TAP虚拟网络接口),为了知道我在做什么错了我的代码做同样的事情vde_switch,但在程序上)

通过运行:

sudo strace vde_switch -tap tap0 

我能够知道,作为特里Greentail,即所取得的系统调用是ioctl(5, TUNSETIFF, 0x7fffa99404e0)和指针将是一个参考到类型struct ifreq的结构。在我的代码中,我有类似ioctl(tapfd, TUNSETIFF, &ifr_dev)的东西。

起初,我试图让一个系统调用GDB停止,设置:catch syscall ioctl(我已经运行GDB为gdb --args vde_switch -tap tap0),但每当抓被打,GDB没有表现出约ioctl的参数信息。与此挣扎了一会儿后,我决定运行GDB内部strace的,如:

gdb --args strace vde_witch -tap -tap0 

虽然没有断点这样干过,输出显示正在使用该文件描述:

open("/dev/net/tun", O_RDWR)   = 9 
ioctl(9, TUNSETIFF, 0x7fffffffe350)  = 0 

所以,我想另一时间:gdb --args strace vde_witch -tap -tap0和设置条件断点:

b ioctl if $rdi==9 

调用约定(我是一个AMD64)使用RDI˚F或者第一个参数,RSI第二和RDX第三(见System V AMD64 ABI。)最后,当断点被击中,我是能够检查ifreq结构:

Breakpoint 6, ioctl() at ../sysdeps/unix/syscall-template.S:81 
81  ../sysdeps/unix/syscall-template.S: File or directory not found. 

(gdb) p (struct ifreq) *$rdx 
$5 = {ifr_ifrn = {ifrn_name = "tap0", '\000' <repete 11 vezes>}, ifr_ifru = {ifru_addr = {sa_family = 4098, sa_data = '\000' <repete 13 vezes>}, ifru_dstaddr = {sa_family = 4098, sa_data = '\000' <repete 13 vezes>}, ifru_broadaddr = {sa_family = 4098, sa_data = '\000' <repete 13 vezes>}, ifru_netmask = {sa_family = 4098, sa_data = '\000' <repete 13 vezes>}, ifru_hwaddr = {sa_family = 4098, sa_data = '\000' <repete 13 vezes>}, ifru_flags = 4098, ifru_ivalue = 4098, ifru_mtu = 4098, ifru_map = {mem_start = 4098, mem_end = 0, base_addr = 0, irq = 0 '\000', dma = 0 '\000', port = 0 '\000'}, ifru_slave = "\002\020", '\000' <repete 13 vezes>, ifru_newname = "\002\020", '\000' <repete 13 vezes>, ifru_data = 0x1002 <Address 0x1002 out of bounds>}}