- Silvio Cesare - Silvio Cesare
原文:http://www.big.net.au/~silvio/linux-anti-debugging.txt Text: http://www.big.net.au/ ~ silvio / linux-anti-debugging.txt
翻译: shutd0wn from m4in security teams Translation: shutd0wn from m4in security teams
导论: Introduction:
这篇文章介绍了在x86/Linux环境下对debug模式的检测(这些技巧不是x86/linux所特有的). 这些方法对linux下virus的改进或者一些需要保护的程序很有用。 This article describes the environment in x86/Linux debug mode for the detection of (these techniques are not unique to x86/linux) These methods improved under linux or some virus protection programs need to be useful.
欺骗反汇编: Deceive Disassembly:
该技巧使反汇编后列出经过欺骗的代码.这种方法让程序跳转到指令的中间执行,部分代码嵌在指令的中间,但是由于反汇编时会列出所有的指令,所以反汇编所得到的是很难读懂的汇编代码。 The skills listed in the disassembled code through deception. This method allows the program to jump to the instruction in the middle, partly embedded in the instruction code in the middle, but due to disassembly will list all the commands, so disassemble the get is hard to read the assembly code. (译注:这种方法在dos时代就有了,用跳转语句打乱代码,增加读代码的难度) (Annotation: In this method there is a dos era, with jump statements disrupted the code, increasing the difficulty of reading the code)
jmp antidebug1 + 2 jmp antidebug1 + 2
antidebug1: antidebug1:
.short 0xc606 . Short 0xc606
call reloc call reloc
reloc: reloc:
popl %esi popl% esi
jmp antidebug2 jmp antidebug2
antidebug2: antidebug2:
addl $(data - reloc),%esi addl $ (data - reloc),% esi
movl 0(%esi),%edi movl 0 (% esi),% edi
pushl %esi pushl% esi
jmp *%edi jmp *% edi
data: data:
.long 0 . Long 0
-- -
$ objdump -d a.out $ Objdump-d a.out
. .
. .
. .
8048340: 55 pushl %ebp 8048340: 55 pushl% ebp
8048341: 89 e5 movl %esp,%ebp 8048341: 89 e5 movl% esp,% ebp
8048343: eb 02 jmp 0x8048347 8048343: eb 02 jmp 0x8048347
8048345: 06 pushl %es 8048345: 06 pushl% es
8048346: c6 e8 00 movb $0x0,%al 8048346: c6 e8 00 movb $ 0x0,% al
8048349: 00 00 addb %al,(%eax) 8048349: 00 00 addb% al, (% eax)
804834b: 00 5e eb addb %bl,0xffffffeb(%esi) 804834b: 00 5e eb addb% bl, 0xffffffeb (% esi)
804834e: 00 81 c6 0f 00 addb %al,0xfc6(%ecx) 804834e: 00 81 c6 0f 00 addb% al, 0xfc6 (% ecx)
8048353: 00 8048353: 00
8048354: 00 8b 7e 00 56 addb %cl,0xff56007e(%ebx) 8048354: 00 8b 7e 00 56 addb% cl, 0xff56007e (% ebx)
8048359: ff 8048359: ff
804835a: e7 00 outl %eax,$0x0 804835a: e7 00 outl% eax, $ 0x0
804835c: 00 00 addb %al,(%eax) 804835c: 00 00 addb% al, (% eax)
804835e: 00 89 ec 5d c3 addb %cl,0x90c35dec(%ecx) 804835e: 00 89 ec 5d c3 addb% cl, 0x90c35dec (% ecx)
8048363: 90 8048363: 90
8048364: 90 nop 8048364: 90 nop
. .
. .
. .
探测断点: Detection of breakpoints:
设置断点是通过int3(0xcc)中断来实现的. 使用int3中断来对程序进行单步执行,从而达到跟踪调试的目的。 Set a breakpoint by int3 (0xcc) interrupts to achieve. Int3 interrupt to use single-step procedure to achieve the tracking debugging purposes. 因此可以通过检测int3中断来判断是否被跟踪。 Therefore, by testing to determine whether int3 interrupt being tracked.
void foo() void foo ()
{ {
printf("Hello\n"); printf ("Hello \ n");
} }
int main() int main ()
{ {
if ((*(volatile unsigned *)((unsigned)foo + 3) & 0xff) == 0xcc) { if ((* (volatile unsigned *) ((unsigned) foo + 3) & 0xff) == 0xcc) {
printf("BREAKPOINT\n"); printf ("BREAKPOINT \ n");
exit(1); exit (1);
} }
foo(); foo ();
} }
-- -
$ gdb $ Gdb
GDB is free software and you are welcome to distribute copies of it GDB is free software and you are welcome to distribute copies of it
under certain conditions; type "show copying" to see the conditions. under certain conditions; type "show copying" to see the conditions.
There is absolutely no warranty for GDB; type "show warranty" for details. There is absolutely no warranty for GDB; type "show warranty" for details.
GDB 4.16 (i586-debian-linux), Copyright 1996 Free Software Foundation, Inc. GDB 4.16 (i586-debian-linux), Copyright 1996 Free Software Foundation, Inc.
(gdb) file a.out (Gdb) file a.out
Reading symbols from a.out...done. Reading symbols from a.out ... done.
(gdb) break foo (Gdb) break foo
Breakpoint 1 at 0x8048373: file break.c, line 3. Breakpoint 1 at 0x8048373: file break.c, line 3.
(gdb) run (Gdb) run
Starting program: /home/silvio/src/antidebug/a.out Starting program: / home / silvio / src / antidebug / a.out
BREAKPOINT BREAKPOINT
Program exited with code 01. Program exited with code 01.
(gdb) quit (Gdb) quit
$ ./a.out $. / A.out
Hello Hello
$ $
设置伪造的断点: Set breakpoints forged:
首先,设置断点需要依靠int3(0xcc)中断. 同样,设置一个伪造的断点也需要依靠int3(0xcc),也要建立一个SIGTRAP, 因此假如我们的代码里含有signal handler我们也可以在设置断点后继续运行代码. First, set breakpoints need to rely on int3 (0xcc) interrupt. Likewise, set a breakpoint also need to rely on forged int3 (0xcc), but also to establish a SIGTRAP, so if our signal handler contains the code we can also set off point continues to run the code.
#include # Include
void handler(int signo) void handler (int signo)
{ {
} }
int main() int main ()
{ {
signal(handler, SIGTRAP); signal (handler, SIGTRAP);
__asm__(" __asm__ ("
int3 int3
"); ");
printf("Hello\n"); printf ("Hello \ n");
} }
-- -
$ gdb $ Gdb
GDB is free software and you are welcome to distribute copies of it GDB is free software and you are welcome to distribute copies of it
under certain conditions; type "show copying" to see the conditions. under certain conditions; type "show copying" to see the conditions.
There is absolutely no warranty for GDB; type "show warranty" for details. There is absolutely no warranty for GDB; type "show warranty" for details.
GDB 4.16 (i586-debian-linux), Copyright 1996 Free Software Foundation, Inc. GDB 4.16 (i586-debian-linux), Copyright 1996 Free Software Foundation, Inc.
(gdb) file a.out (Gdb) file a.out
Reading symbols from a.out...(no debugging symbols found)...done. Reading symbols from a.out ... (no debugging symbols found) ... done.
(gdb) run (Gdb) run
Starting program: /home/silvio/src/antidebug/a.out Starting program: / home / silvio / src / antidebug / a.out
(no debugging symbols found)...(no debugging symbols found)... (No debugging symbols found )...( no debugging symbols found) ...
Program received signal SIGTRAP, Trace/breakpoint trap. Program received signal SIGTRAP, Trace / breakpoint trap.
0x80483c3 in main () 0x80483c3 in main ()
(gdb) c (Gdb) c
Continuing. Continuing.
Hello Hello
Program exited with code 06. Program exited with code 06.
(gdb) quit (Gdb) quit
$ ./a.out $. / A.out
Hello Hello
探测是否被跟踪: Probe is being tracked:
这是个比较好的方法,可以用来探测运行的程序是否被跟踪,所用到ptrace[PTRACE_TRACEME] This is a better approach can be used to detect whether the program was running track, which used ptrace [PTRACE_TRACEME]
调用,它在一个进程里面不能被多次调用。 Call it a process which can not be called multiple times. 所有的调试跟踪程序都是使用这个调用来工作的:) All programs are using the debug tracing this call to work:)
int main() int main ()
{ {
if (ptrace(PTRACE_TRACEME, 0, 1, 0) < 0) { /* 译注:如不成功,PTRACE_TRACEME可以用0代替*/ if (ptrace (PTRACE_TRACEME, 0, 1, 0) <0) {/ * Annotation: If unsuccessful, PTRACE_TRACEME can use 0 instead of * /
printf("DEBUGGING... Bye\n"); printf ("DEBUGGING ... Bye \ n");
return 1; return 1;
} }
printf("Hello\n"); printf ("Hello \ n");
return 0; return 0;
} }
-- -
$ gdb $ Gdb
GDB is free software and you are welcome to distribute copies of it GDB is free software and you are welcome to distribute copies of it
under certain conditions; type "show copying" to see the conditions. under certain conditions; type "show copying" to see the conditions.
There is absolutely no warranty for GDB; type "show warranty" for details. There is absolutely no warranty for GDB; type "show warranty" for details.
GDB 4.16 (i586-debian-linux), Copyright 1996 Free Software Foundation, Inc. GDB 4.16 (i586-debian-linux), Copyright 1996 Free Software Foundation, Inc.
(gdb) file a.out (Gdb) file a.out
Reading symbols from a.out...done. Reading symbols from a.out ... done.
(gdb) run (Gdb) run
Starting program: /home/silvio/src/antidebug/a.out Starting program: / home / silvio / src / antidebug / a.out
DEBUGGING... Bye DEBUGGING ... Bye
Program exited with code 01. Program exited with code 01.
(gdb) quit (Gdb) quit
$ ./a.out $. / A.out
Hello Hello
$ $
Tidak ada komentar:
Posting Komentar