【发布时间】:2017-07-25 23:25:30
【问题描述】:
这个程序中有一个函数,它当前返回一个 1。我希望它返回一个 0。
由此我推断:我们可以将偏移量添加到程序计数器uregs[R_PC]+arg0,以找到返回值的地址。
我分配了一个 32 位的“0”,我尝试将其中的 2 个字节写入返回值所在的地址(我们的函数期望返回一个 BOOL16,所以我们只需要 2 个字节的 0):
sudo dtrace -p "$(getpid)" -w -n '
int *zero;
BEGIN { zero=alloca(4); *zero=0; }
pid$target::TextOutA:return {
copyout(zero, uregs[R_PC]+arg0, 2);
}'
我当然明白:
dtrace:启用探测 ID 2 时出错(ID 320426:pid60498:gdi32.dll.so:TextOutA:return):在 DIF 偏移量 60 处的操作 #1 中的地址无效 (0x41f21c)
uregs[R_PC] 大概是一个用户空间地址。可能copyout() 想要一个内核地址。
如何将用户空间地址uregs[R_PC] 转换为内核空间? 我知道使用copyin() 我们可以将存储在用户空间地址的数据读取到内核空间。但这并没有给我们该内存的内核地址。
或者:还有其他方法可以使用 DTrace 更改返回值吗?
【问题讨论】:
-
我没有看到
arg0 + u_regs[R_PC];如何为您获取返回值的地址。那是两个地址。添加它们似乎没有任何意义。怎么知道返回值的地址?它很可能通过寄存器传递。实际返回的值在arg1。见docs.oracle.com/cd/E19253-01/817-6223/chp-pid/index.html -
我从文档中的理解是
u_regs[R_PC]是程序计数器,而arg0是程序计数器的偏移量。因此,u_regs[R_PC]将是一个 绝对 地址,arg0是一个相对偏移量,您可以将其添加到该绝对地址,以获得不同的绝对地址。 -
对于
arg1:当然这包含值,但我的意图是在函数返回之前修改值。我们在 DTrace (copyout()) 中修改数据的唯一工具要求我们知道数据的地址。
标签: dtrace