admin 管理员组文章数量: 1087675
I'm trying to load a shared library (controller process) into another process (target) using ptrace.
NOTE: Both the controller and target are using the same version of libc. /usr/lib/libc.so.6
I'm doing the following:
- Finding the dlopen address in libc in the target process - Placing this in register
r8
. - Copying the name of the library into a memory location using ptrace
POKEDATA
. Setting this address inrdi
. - Settingthe mode as
2
inrsi
register. - I'm setting the
rip
to a location where I've placed the following code -trampCodeAddr
in this example - See point 5.
asm(
"nop \n"
"nop \n"
"nop \n"
"nop \n"
"nop \n"
"nop \n"
"nop \n"
"nop \n"
"callq *%r8 \n"
"int $3"
);
This is what gets written into the memory:
Writing: 0x9090909090909090 to 0x401400
Writing: 0x1f0fc3ccd0ff41 to 0x401408
- At this point, I'm setting these registers using the ptrace SETREGS.
regs.r8 = targetdlopenAddr;
regs.rdi = libNameBuf;
regs.rsi = 2; // RTLD_NOW
regs.rip = trampCodeAddr + 2;
status = ptraceWriteRegs(targetPid, ®s);
When I issue a ptrace continue, and then check the signal info, I see the signal number is set to 11
. SIGSEGV
.
But, when I read the registers, I've an address in rax
, and when I do check /proc/<pid>/maps
, I see the .so loaded.
I'm expecting a SIGTRAP, and not a SIGSEGV.
What could be going on here?
I tried the same method to call malloc
. But, in that case, I'm getting a SIGTRAP as expected. What could be going wrong with dlopen()? Is there any other register which could be giving me more info?
Thanks for your time.
EDIT 1:
The data I set in the registers seem fine to me: (One instance, for example):
r8
: 7f92c5885d00
rdi
: 401420
rsi
:0x2
rip
:0x401402
rdi
points to a null
terminated string:
Writing: 0x63656a6e6962696c to 0x401420
Writing: 0x6f6c6c6568646574 to 0x401428
Writing: 0x6a6e490a006f732e to 0x401430
/proc//maps output in this instance:
7f92c5800000-7f92c5828000 r--p 00000000 fd:00 68452742 /usr/lib64/libc.so.6
7f92c5828000-7f92c599d000 r-xp 00028000 fd:00 68452742 /usr/lib64/libc.so.6
7f92c599d000-7f92c59f5000 r--p 0019d000 fd:00 68452742 /usr/lib64/libc.so.6
7f92c59f5000-7f92c59f6000 ---p 001f5000 fd:00 68452742 /usr/lib64/libc.so.6
7f92c59f6000-7f92c59fa000 r--p 001f5000 fd:00 68452742 /usr/lib64/libc.so.6
7f92c59fa000-7f92c59fc000 rw-p 001f9000 fd:00 68452742 /usr/lib64/libc.so.6
EDIT 2: Updated point number 4 with the actual code and what gets written.
When I get the control back to the controller program, the rip
is 0x7ffff7fcee95
. This should have been 0x40140c
. That is what I see after my malloc
returns successfully. For some reason, the call to dlopen
goes wild.
I checked that I'm writing the correct dlopen
address in r8
before callq *%r8
is called.
EDIT 3:
When ptrace gets the SIGSEGV, the RIP has 0x7f9e88bf0e95
. At this time, the maps
has:
7f9e88beb000-7f9e88c11000 r-xp 00002000 fd:00 68452740 /usr/lib64/ld-linux-x86-64.so.2
So, the offset is 0x%5e95
.
This seems to be in the open_path
. How do I narrow it down further?
EDIT 4: I sent a SIGSTOP to the target just before I know where it would crash. Then continued in GDB. This is the stacktrace I got:
(gdb) bt
#0 _dl_map_object_from_fd (name=name@entry=0x401420 "/tmp/satish/libinjectedhello.so", origname=origname@entry=0x0, fd=-1, fbp=fbp@entry=0x7ffc73974008, realname=<optimized out>,
loader=loader@entry=0x0, l_type=<optimized out>, mode=<optimized out>, stack_endp=<optimized out>, nsid=<optimized out>) at dl-load.c:1431
#1 0x00007f9f5e2b689f in _dl_map_object (loader=0x0, loader@entry=0x7f9f5e2e5220, name=name@entry=0x401420 "/tmp/satish/libinjectedhello.so", type=type@entry=2,
trace_mode=trace_mode@entry=0, mode=mode@entry=-1879048190, nsid=<optimized out>) at dl-load.c:2286
#2 0x00007f9f5e2ba3ba in dl_open_worker_begin (a=0x7ffc739746c8) at dl-open.c:577
#3 0x00007f9f5e156148 in _dl_catch_exception () from /lib64/libc.so.6
#4 0x00007f9f5e2b9afa in dl_open_worker (a=0x7ffc739746c8) at dl-open.c:796
#5 0x00007f9f5e156148 in _dl_catch_exception () from /lib64/libc.so.6
#6 0x00007f9f5e2b9f5f in _dl_open (file=<optimized out>, mode=-2147483646, caller_dlopen=0x401405, nsid=-2, argc=1, argv=0x7ffc73974af8, env=0x7ffc73974b08) at dl-open.c:898
#7 0x00007f9f5e085cbc in dlopen_doit () from /lib64/libc.so.6
#8 0x00007f9f5e156148 in _dl_catch_exception () from /lib64/libc.so.6
#9 0x00007f9f5e156213 in _dl_catch_error () from /lib64/libc.so.6
#10 0x00007f9f5e08578e in _dlerror_run () from /lib64/libc.so.6
#11 0x00007f9f5e085d71 in dlopen@GLIBC_2.2.5 () from /lib64/libc.so.6
#12 0x0000000000401405 in ?? ()
#13 0x00007f9f5e0d8c87 in nanosleep () from /lib64/libc.so.6
#14 0x00007f9f5e0d8bbe in sleep () from /lib64/libc.so.6
#15 0x000000000040124f in main ()
本文标签: assemblyCalling dlopen by setting the registers using ptrace throws SIGSEGVIntel 64Stack Overflow
版权声明:本文标题:assembly - Calling dlopen by setting the registers using ptrace throws SIGSEGV - Intel 64 - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.roclinux.cn/p/1744060428a2526627.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论