在Linux下,可以使用strace精确跟踪内核系统调用。
ltrace也可以用于跟踪库调用。
我想知道是否有可能检测我的可执行文件是否在straceltrace下运行吗?

这是strace可执行文件的ltracediff输出的示例。 br />
$ strace diff
execve("/usr/bin/diff", ["diff"], [/* 43 vars */]) = 0
brk(0)                                  = 0x110a000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fcbc13f6000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=122500, ...}) = 0
mmap(NULL, 122500, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fcbc13d8000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/librt.so.1", O_RDONLY|O_CLOEXEC) = 3
read(3, "7ELF
$ ltrace diff
__libc_start_main(0x402310, 1, 0x7fff876fcf28, 0x4151d0, 0x415260 <unfinished ...>
strrchr("diff", '/')                                             = NULL
setlocale(6, "")                                                 = "en_US.UTF-8"
bindtextdomain("diffutils", "/usr/share/locale")                 = "/usr/share/locale"
textdomain("diffutils")                                          = "diffutils"
sigaltstack(0x7fff876fccd0, 0, 1, 0x736c6974756666, 3)           = 0
dcgettext(0, 0x4183d7, 5, -1, 3)                                 = 0x4183d7
dcgettext(0, 0x4183e5, 5, 0, 1)                                  = 0x4183e5
sigemptyset(0x7fff876fccf8)                                      = 0
sigaction(11, 0x7fff876fccf0, NULL)                              = 0
re_set_syntax(264966, 0x7fff876fcb88, 0, -1, 0)                  = 0
malloc(16)                                                       = 0x016e1160
memset(0x016e1160, 'q4312078q0', 16)                                   = 0x016e1160
getopt_long(1, 0x7fff876fcf28, "0123456789abBcC:dD:eEfF:hHiI:lL:"..., 0x00417360, NULL) = -1
malloc(1)                                                        = 0x016e1180
dcgettext(0, 0x415598, 5, 8, 3)                                  = 0x415598
error(0, 0, 0x415598, 0x7fff876fd469, 1diff: missing operand after `diff'
)                         = 0
dcgettext(0, 0x415878, 5, 0, 0x7fad1793c700)                     = 0x415878
error(2, 0, 0x415878, 0x7fff876fd469, 1diff: Try `diff --help' for more information.
 <unfinished ...>
+++ exited (status 2) +++
q4312078qq4312078qq4312078qq4312078qq4312078qq4312078qq4312078qq4312078qq4312078q>q4312078qq4312078qq4312078qq4312078q0!q4312078qq4312078qq4312078qq4312078qq4312078qq4312078q"..., 832) = 832 fstat(3, {st_mode=S_IFREG|0644, st_size=31784, ...}) = 0 mmap(NULL, 2129016, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fcbc0fce000 mprotect(0x7fcbc0fd5000, 2093056, PROT_NONE) = 0 mmap(0x7fcbc11d4000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x6000) = 0x7fcbc11d4000 close(3) = 0 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3 read(3, "7ELFq4312078qq4312078qq4312078qq4312078qq4312078qq4312078qq4312078qq4312078qq4312078qq4312078q>q4312078qq4312078qq4312078qq4312078q0q4312078qq4312078qq4312078qq4312078qq4312078q"..., 832) = 832 fstat(3, {st_mode=S_IFREG|0755, st_size=1811160, ...}) = 0 mmap(NULL, 3925240, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fcbc0c0f000 mprotect(0x7fcbc0dc4000, 2093056, PROT_NONE) = 0 mmap(0x7fcbc0fc3000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1b4000) = 0x7fcbc0fc3000 mmap(0x7fcbc0fc9000, 17656, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fcbc0fc9000 close(3) = 0 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) open("/lib/x86_64-linux-gnu/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3 read(3, "7ELFq4312078qq4312078qq4312078qq4312078qq4312078qq4312078qq4312078qq4312078qq4312078qq4312078q>q4312078qq4312078qq4312078qq4312078q0lq4312078qq4312078qq4312078qq4312078qq4312078qq4312078q"..., 832) = 832 fstat(3, {st_mode=S_IFREG|0755, st_size=135398, ...}) = 0 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fcbc13d7000 mmap(NULL, 2212936, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fcbc09f2000 mprotect(0x7fcbc0a0a000, 2093056, PROT_NONE) = 0 mmap(0x7fcbc0c09000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x17000) = 0x7fcbc0c09000 mmap(0x7fcbc0c0b000, 13384, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fcbc0c0b000 close(3) = 0 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fcbc09f1000 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fcbc09f0000 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fcbc09ef000 arch_prctl(ARCH_SET_FS, 0x7fcbc09f0700) = 0 mprotect(0x7fcbc0fc3000, 16384, PROT_READ) = 0 mprotect(0x7fcbc0c09000, 4096, PROT_READ) = 0 mprotect(0x7fcbc11d4000, 4096, PROT_READ) = 0 mprotect(0x61b000, 4096, PROT_READ) = 0 mprotect(0x7fcbc13f8000, 4096, PROT_READ) = 0 munmap(0x7fcbc13d8000, 122500) = 0 set_tid_address(0x7fcbc09f09d0) = 32425 set_robust_list(0x7fcbc09f09e0, 0x18) = 0 futex(0x7fff27e5992c, FUTEX_WAIT_BITSET_PRIVATE|FUTEX_CLOCK_REALTIME, 1, NULL, 7fcbc09f0700) = -1 EAGAIN (Resource temporarily unavailable) rt_sigaction(SIGRTMIN, {0x7fcbc09f8750, [], SA_RESTORER|SA_SIGINFO, 0x7fcbc0a01cb0}, NULL, 8) = 0 rt_sigaction(SIGRT_1, {0x7fcbc09f87e0, [], SA_RESTORER|SA_RESTART|SA_SIGINFO, 0x7fcbc0a01cb0}, NULL, 8) = 0 rt_sigprocmask(SIG_UNBLOCK, [RTMIN RT_1], NULL, 8) = 0 getrlimit(RLIMIT_STACK, {rlim_cur=8192*1024, rlim_max=RLIM_INFINITY}) = 0 brk(0) = 0x110a000 brk(0x112b000) = 0x112b000 open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=7216624, ...}) = 0 mmap(NULL, 7216624, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fcbc030d000 close(3) = 0 sigaltstack({ss_sp=0x61c5e0, ss_flags=0, ss_size=8192}, NULL) = 0 open("/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=2570, ...}) = 0 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fcbc13f5000 read(3, "# Locale name alias data base.\n#"..., 4096) = 2570 read(3, "", 4096) = 0 close(3) = 0 munmap(0x7fcbc13f5000, 4096) = 0 open("/usr/share/locale/en_US/LC_MESSAGES/diffutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/share/locale/en/LC_MESSAGES/diffutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/share/locale-langpack/en_US/LC_MESSAGES/diffutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/share/locale-langpack/en/LC_MESSAGES/diffutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory) rt_sigaction(SIGSEGV, {0x40b3c0, [], SA_RESTORER|SA_STACK|SA_NODEFER|SA_RESETHAND|SA_SIGINFO, 0x7fcbc0c454a0}, NULL, 8) = 0 write(2, "diff: ", 6diff: ) = 6 write(2, "missing operand after `diff'", 28missing operand after `diff') = 28 write(2, "\n", 1 ) = 1 write(2, "diff: ", 6diff: ) = 6 write(2, "Try `diff --help' for more infor"..., 39Try `diff --help' for more information.) = 39 write(2, "\n", 1 ) = 1 exit_group(2) = ?


#1 楼

可以通过以下事实检测到ptrace:一个进程只能调用一次ptrace
如果ptrace()可执行文件或调试器已经调用过strace,我们可以在运行时对其进行检测。 br />
但是,破解这段代码并不难。首先,可以仅通过NOP调用ptrace()
其次,可以使用ptrace()用我们自己的ptrace()调用替换LD_PRELOAD调用

评论


解决gdb的另一种方法是遍历ptrace调用(下一个),然后将%eax设置为零(设置$ eax = 0)。

–恐怖
13年4月25日在18:24



另一种方法是跳过代码或设置$ pc跳过它。

– 0xC0000022L♦
13年4月27日在3:15

当然,您可以只检查LD_PRELOAD。或者让它setuid。

–锑
2014-2-17在18:34

如果它调用execve(2),将导致该进程停止。

– dlitz
18-10-7在22:12

#2 楼

除了ptrace技巧外,您还可以检查/ proc / PID / cmdline,引发SIGTRAP,使用getppid,...

您可能要检查pangu(发现者:我是作者)。


Pangu是一个小工具集,可与GNU项目中的调试相关工具配合使用,尤其是在GNU / Linux x86上。


评论


您是否设法为Android ndk编译了asm?我收到错误的指示错误

– xDragonZ
16年1月23日在23:40

为x86而不是arm进行编译

– jvoisin
16年1月26日在17:41

#3 楼

其他评论者建议的方式也是可能的。但是,所有这些文件都是可拦截的,如果您读取文件,可以将其拦截,并且您的程序将获得不同的结果,如果您检查LD_PRELOAD是否已设置,则可以先取消设置它,然后再访问它,等等。虽然是另一回事,但也可能有不同的利用方式。