тест антиотладки

Тема в разделе "WASM.UNIX", создана пользователем pikofarad, 12 апр 2009.

  1. pikofarad

    pikofarad New Member

    Публикаций:
    0
    Регистрация:
    5 апр 2008
    Сообщения:
    35
    доброго времени суток.
    потестите, плз, бинарник с антиотладкой.
    конкретно интересует:
    * выводит ли "hello =)" при обычном запуске?
    * как себя ведет под strace'ом?
    * как себя ведет под gdb? (без установки бряков, банальный run)
     
  2. pikofarad

    pikofarad New Member

    Публикаций:
    0
    Регистрация:
    5 апр 2008
    Сообщения:
    35
    если будет время, проверьте, плз поведение gdb на скомпиленном непострипанном бинарнике

    Код (Text):
    1. ; --------------------------------------------------------------------
    2. ; build:
    3. ;   nasm -f elf hello.asm
    4. ;   ld -N hello.o -o hello
    5. ; --------------------------------------------------------------------
    6. bits 32
    7. section .data
    8.     msg db "hello =)",0xa,0xd,0x0
    9.     msglen equ $-msg
    10.  
    11. section .text
    12. global _start
    13.  
    14. normal:
    15.     mov eax,4
    16.     xor ebx,ebx
    17.     inc ebx
    18.     mov ecx,msg  
    19.     mov edx,msglen
    20.     int 0x80 ; print "hello =)"
    21.  
    22. exit:
    23.     xor eax,eax
    24.     inc eax
    25.     xor ebx,ebx
    26.     int 0x80
    27.  
    28. _start:
    29.     times 2 nop
    30.  
    31.     mov eax, 174
    32.     mov ebx, 5 ; SIGTRAP
    33.     mov esi, 8
    34.     xor edx,edx
    35.     push 0
    36.     push 0x10
    37.     push 0
    38.     push 0x10000000
    39.     push normal
    40.     mov ecx,esp
    41.     int 0x80
    42.  
    43.     mov eax, 174
    44.     mov ebx, 2 ; SIGINT
    45.     mov esi, 8
    46.     xor edx,edx
    47.     push 0
    48.     push 0x10
    49.     push 0
    50.     push 0x10000000
    51.     push exit
    52.     mov ecx,esp
    53.     int 0x80
    54.  
    55.     mov byte [_start], 0xcc
    56.     jmp _start
     
  3. Mecid

    Mecid New Member

    Публикаций:
    0
    Регистрация:
    20 мар 2009
    Сообщения:
    27
    не под gdb не в обычной среде не пашет
     
  4. pikofarad

    pikofarad New Member

    Публикаций:
    0
    Регистрация:
    5 апр 2008
    Сообщения:
    35
    Mecid, а что у тебя за системка?
     
  5. AndreyMust19

    AndreyMust19 New Member

    Публикаций:
    0
    Регистрация:
    20 окт 2008
    Сообщения:
    714
    HELLO:
    HTEditor ругается:
    'error while reading ELF: Zero count for section headers'
    то есть считает формат неправильным.
    Я вообще, не советовал бы баловаться с форматом, у gdb других корявостей намного больше.
    Этот файл в gdb я еще не проверял.

    2-ой пример:
    Твой пример - это привязка к поглощению сигналов гнудебагером, которые принимает программа. Такой анти-gdb прием я уже пробовал. Точно могу сказать:
    Если поглощение сигналов SIGINT и SIGTRAP выключено, то программа будет отлаживаться нормально. Если сигналы поглощаются, то gdb перехватит первого из них. Так что если кто-то пошлет твоей программе сигнал SIGTRAP / SIGINT, а обработчик сигнала управления не получит - знай - его поглотил gdb.
    Наличие / отсутствие отладочной информации тут роли не играет.
    В книге КК "Исследование компьютерных вирусов" (точное название не помню) есть статья про антиотладку для gdb.

    P.S. В твоем примере используются int 0x80. Не во всех UNIX-системах для системных вызовов используется int 0x80, поэтому это непереносимо.

    Добавил:
    Завтра проведу исследование
     
  6. pikofarad

    pikofarad New Member

    Публикаций:
    0
    Регистрация:
    5 апр 2008
    Сообщения:
    35
    собственно, выводит он это потому, что бинарник пострипан, никаких извращений с форматом)

    неверно:
    Код (Text):
    1. (gdb) handle SIGTRAP nostop pass noprint
    2. SIGTRAP is used by the debugger.
    3. Are you sure you want to change it? (y or n) y
    4. Signal        Stop  Print   Pass to program Description
    5. SIGTRAP       No    No  Yes     Trace/breakpoint trap
    6. (gdb) disassemble normal
    7. Dump of assembler code for function normal:
    8. 0x08048080 <normal+0>:  mov    eax,0x4
    9. 0x08048085 <normal+5>:  xor    ebx,ebx
    10. 0x08048087 <normal+7>:  inc    ebx
    11. 0x08048088 <normal+8>:  mov    ecx,0x804816c
    12. 0x0804808d <normal+13>: mov    edx,0xb
    13. 0x08048092 <normal+18>: int    0x80
    14. End of assembler dump.
    15. (gdb) hb *0x08048087
    16. Hardware assisted breakpoint 1 at 0x8048087
    17. (gdb) r
    18. Starting program: /home/pikofarad/src/demo/hello
    19.  
    20. Program terminated with signal SIGTRAP, Trace/breakpoint trap.
    21. The program no longer exists.
    22. You can't do that without a process to debug.
    пока что интересует только linux

    удачи ;)
     
  7. Mecid

    Mecid New Member

    Публикаций:
    0
    Регистрация:
    20 мар 2009
    Сообщения:
    27
    У меня убунту
    HTE Говорит то же что и AndreyMust19
     
  8. pikofarad

    pikofarad New Member

    Публикаций:
    0
    Регистрация:
    5 апр 2008
    Сообщения:
    35
    машина 64-хбитная?
     
  9. AndreyMust19

    AndreyMust19 New Member

    Публикаций:
    0
    Регистрация:
    20 окт 2008
    Сообщения:
    714
    Ну чтож, попробовал.

    Первый пример:

    * FreeBSd 5.2.1
    hello не запускается
    Говорит, что-то "0 - неизвестный тип, неожиданный '(' "

    * Linux 2.4.26, dsl
    * Linux knoppix_debian 2.6.17 #4 SMP
    hello запускается, выводит 'hello =)'
    Под gdb:
    Загружается нормально.
    При выполнении (r) срабатывает бряк:
    Program received signal SIGTRAP, Trace/breakpoint trap.
    0x0804809c in ?? ()
    Чтобы не поглощать сигнал SIGTRAP, нужно ввести команду:
    handle SIGTRAP pass
    После продолжения работы программа спокойно выводит:
    hello =)

    Команду 'handle SIGTRAP nostop pass noprint' не пробывал. Но надо только включить pass, чтобы отладчик не поглощал сигнал, а отдавал программе. Завтра попробую эту команду.

    P.S. Приведенный тобой исходник компилируется только nasm'ом? В таком случае на FreeBSD я его не могу скомпилировать. А нельзя ли как-то его скомпилировать с помощью as - заставить понимать Intel-синтаксис? Или перепиши исходник для AT&T синтаксиса.
     
  10. Mecid

    Mecid New Member

    Публикаций:
    0
    Регистрация:
    20 мар 2009
    Сообщения:
    27
    если вас интересует антиотладка для gdb могу привести пару приемов
     
  11. AndreyMust19

    AndreyMust19 New Member

    Публикаций:
    0
    Регистрация:
    20 окт 2008
    Сообщения:
    714
    Mecid, я тебя обгоню, пожалуй :)
    - close(3);
    - значение переменной окружения с именем '0'
    Ну и остальные приемы, пригодные для любых других отладчиков.
    Есть статья КК "антиотладчка в мире UNIX".
     
  12. Mecid

    Mecid New Member

    Публикаций:
    0
    Регистрация:
    20 мар 2009
    Сообщения:
    27
    ну тогда я дополню
    1.если запускать под отладчиком итендификатор сессии и итендификатор родительского процусса неравны то есть
    if(getppid()!=getsid(0))printf("GDB detect\n");
    2.еще можно заняться самотрассировкой
     
  13. pikofarad

    pikofarad New Member

    Публикаций:
    0
    Регистрация:
    5 апр 2008
    Сообщения:
    35
    обратите внимание как себя ведет gdb с пострипанной и непострипанной версиями
    Код (Text):
    1. /* -----------------------------------
    2.  * build:
    3.  *   as -o hello.o hello.s
    4.  *   ld -N hello.o -o hello
    5.  *-----------------------------------*/
    6.  
    7. msg: .asciz "hello =)\n"
    8. msglen = .-msg
    9.  
    10. .global _start
    11.  
    12. normal:
    13.     movl    $4,%eax
    14.     xorl    %ebx,%ebx
    15.     incl    %ebx
    16.     movl    $msg,%ecx
    17.     movl    $msglen,%edx
    18.     int     $0x80
    19.  
    20. exit:
    21.     xorl    %eax,%eax
    22.     incl    %eax
    23.     xorl    %ebx,%ebx
    24.     int     $0x80
    25.  
    26. _start:
    27.     nop
    28.     nop
    29.  
    30.     movl    $174,%eax
    31.     movl    $5,%ebx
    32.     movl    $8,%esi
    33.     xorl    %edx,%edx
    34.     pushl   $0
    35.     pushl   $0x10
    36.     pushl   $0
    37.     pushl   $0x10000000
    38.     pushl   $normal
    39.     movl    %esp,%ecx
    40.     int     $0x80
    41.  
    42.     movl    $174,%eax
    43.     movl    $2,%ebx
    44.     movl    $8,%esi
    45.     xorl    %edx,%edx
    46.     pushl   $0
    47.     pushl   $0x10
    48.     pushl   $0
    49.     pushl   $0x10000000
    50.     pushl   $exit
    51.     movl    %esp,%ecx
    52.     int     $0x80
    53.  
    54.     movb    $0xcc,_start
    55.     jmp     _start
     
  14. pikofarad

    pikofarad New Member

    Публикаций:
    0
    Регистрация:
    5 апр 2008
    Сообщения:
    35
    если интересно, могу выложить антиотладку, которой у криса не было
     
  15. AndreyMust19

    AndreyMust19 New Member

    Публикаций:
    0
    Регистрация:
    20 окт 2008
    Сообщения:
    714
    pikofarad
    Хм... Команда strip вроде бы как только отладочную информацию вырезает. Впрочем я заметил что gdb без этой информации заметно худеет в функционале (бряки на функции ставить больше нельзя, дизассемблер не работает). Но не думаю что отсутствие отладочной инфы преумножит кол-во антиотладочных приемов.
    Новый исходник попробую - скомпилирую на FreeBSD и посмотрю что там будет (впрочем, не думаю что что-либо изменится).
    Да, да, да, давай, выкладывай! До завтра.
     
  16. pikofarad

    pikofarad New Member

    Публикаций:
    0
    Регистрация:
    5 апр 2008
    Сообщения:
    35
    не, не strip, а sstrip из набора ELF Kickers, что секции удаляет из исполняемого файла. Остается только инфа о сегментах
     
  17. pikofarad

    pikofarad New Member

    Публикаций:
    0
    Регистрация:
    5 апр 2008
    Сообщения:
    35
    Код (Text):
    1. #include <stdio.h>
    2. #include <linux/ptrace.h>
    3. #include <sys/wait.h>
    4. #include <sys/user.h>
    5. #include <stddef.h>
    6. #include <signal.h>
    7.  
    8. void foo()
    9. {
    10.     printf("hello\n");
    11. }
    12.  
    13. int main()
    14. {
    15.     struct user_regs_struct regs;
    16.     unsigned int i,drX;
    17.     int signal;
    18.  
    19.     pid_t child = fork();
    20.     switch (child)
    21.     {
    22.         case 0: // child
    23.             if (ptrace(PTRACE_TRACEME)==-1) perror("ptrace");
    24.             foo();
    25.             asm ("int $3");
    26.             return 1;
    27.  
    28.         case -1:
    29.             perror("fork");
    30.             return -1;
    31.  
    32.         default: // parent
    33.             while (1){
    34.                 wait(&signal);
    35.                 if (WIFEXITED(signal)) break;
    36.                 for (i=0; i<3; ++i){
    37.                     drX = ptrace(PTRACE_PEEKUSR, child, offsetof(struct user, u_debugreg[i]), 0);
    38.                     if (drX){
    39.                         printf("under debug\n");
    40.                         kill(child, SIGKILL);
    41.                         return -1;
    42.                     }
    43.                 }
    44.                 ptrace(PTRACE_SINGLESTEP, child, 0, 0);
    45.             }
    46.     }
    47.     return 0;
    48. }
     
  18. Mecid

    Mecid New Member

    Публикаций:
    0
    Регистрация:
    20 мар 2009
    Сообщения:
    27
    эт типа антиотладочный трюк???под гдб и без него выводит хеллоу
     
  19. pikofarad

    pikofarad New Member

    Публикаций:
    0
    Регистрация:
    5 апр 2008
    Сообщения:
    35
    этот код палит установку хардварных брякпоинтов. Попробуй поставить на что-нить внутри foo() и вылетит птичка ;)
     
  20. AndreyMust19

    AndreyMust19 New Member

    Публикаций:
    0
    Регистрация:
    20 окт 2008
    Сообщения:
    714
    Код, выложенный в 13-м посте:

    Под FreeBSD пишет:
    Trace/BPT trap (core dumped)
    Под Linux падает:
    Segmentation fault

    В gdb обнаруживается, что программа умирает из-за сигнала SIGSEGV (нарушение доступа), возникающего по адресу 0x080480E5:
    Program received signal SIGSEGV. Segmentation fault.
    0x080480E5 in _start ()
    По этому адресу распологается команда:
    movb $0xCC, 0x8048099
    Исключение возникает из-за того, что эта команда пытается записать CCh в сегмент только для чтения.

    Надо покопаться в исходнике. Если заменить
    movb $0xcc,_start
    на:
    int $0x03
    То все работает:
    hello запускается и выводит 'hello =)'.
    Под GDB ведет себя также, как я описывал ранее.

    Пропатченный файл под FreeBSD не работает:
    Trace/BPT trap (core dumped)
    В GDB тоже:
    после ввода 'handle SIGTRAP pass' и 'c' на экране появляется.
    Program terminated with signal SIGTRAP, Trace/breakpoint trap.
    The program no longer exists.
    Это выводит отладчик. Возможно что системные вызовы в FreeBSD осуществляются не через int 0x80. Может какая-то другая причина.

    pikofarad, #17
    Выходит, отлаживаемый процесс сам может изменять свое состояние, используя те же ptrace-функции!? Н-р, он может сам выйти из под отладки.