Создание своего отладчика

Тема в разделе "WASM.BEGINNERS", создана пользователем Clyde, 5 июн 2011.

  1. Clyde

    Clyde New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2009
    Сообщения:
    154
    попытался написать что-то типа мини отладчика, для начала мне хватит лишь отображения регистров, но почему-то EIP получаемый при пошаговой трассировке никогда не совпадает с точкой входа, при этом программа выполняется до конца (для теста взял обычный мессаджбокс,те однопоточное приложение).
    помогите плз разобратся, в чем загвоздка.

    Код (Text):
    1. #include <windows.h>
    2. #pragma comment(lib,"USER32.LIB")
    3. #pragma comment(lib,"KERNEL32.LIB")
    4. #pragma comment(linker,"/ENTRY:MyMain")
    5. #pragma comment(linker,"/SUBSYSTEM:WINDOWS")
    6.  
    7.  
    8.  
    9. void MyMain(void)
    10. {
    11.     char buff[1024];
    12.  
    13.     PROCESS_INFORMATION pi;
    14.     STARTUPINFOA si;
    15.     CONTEXT ctx;
    16.     DEBUG_EVENT dbe;
    17.  
    18.     DWORD realEip;
    19.  
    20.     ZeroMemory(&si,sizeof(STARTUPINFOA));
    21.     si.cb=sizeof(STARTUPINFOA);
    22.  
    23.     char* file ="C:\\file.exe";
    24.  
    25.  
    26.     CreateProcess(file, NULL, NULL, NULL, FALSE, DEBUG_PROCESS+DEBUG_ONLY_THIS_PROCESS, NULL, NULL, &si,&pi);
    27.  
    28.     while(true)
    29.  
    30.     {
    31.         WaitForDebugEvent(&dbe,INFINITE);
    32.         if(dbe.dwDebugEventCode==EXIT_PROCESS_DEBUG_EVENT)
    33.         {
    34.             MessageBoxA(0,"finished", "Cya",MB_OK);
    35.             break;
    36.         }
    37.         else if (dbe.dwDebugEventCode==EXCEPTION_DEBUG_EVENT)
    38.         {
    39.             if(dbe.u.Exception.ExceptionRecord.ExceptionCode==EXCEPTION_BREAKPOINT)
    40.             {
    41.                 ctx.ContextFlags=CONTEXT_CONTROL;
    42.                 GetThreadContext(pi.hThread,&ctx);
    43.  
    44.                 realEip=ctx.Eip;
    45.                 _asm {mov eax, realEip
    46.                       and   eax,0xffff0000
    47.                      };
    48.  
    49.                 if(realEip==0x00400000)
    50.                 {
    51.                     wsprintf(buff,"eax: %x, ebx: %x, ecx: %x, edx: %x, esp: %x, eip: %x",ctx.Eax,ctx.Ebx,ctx.Ecx,ctx.Edx,ctx.Esp,ctx.Eip);
    52.                     MessageBoxA(0,buff,"CONTEXT",MB_OK);
    53.                 }
    54.  
    55.                 ctx.EFlags |=0x100;
    56.                 SetThreadContext(pi.hThread,&ctx);
    57.                 ContinueDebugEvent(dbe.dwProcessId,dbe.dwThreadId,DBG_CONTINUE);
    58.             }
    59.             else if(dbe.u.Exception.ExceptionRecord.ExceptionCode==EXCEPTION_SINGLE_STEP)
    60.             {
    61.                 GetThreadContext(pi.hThread, &ctx);
    62.  
    63.                 realEip=ctx.Eip;
    64.                 _asm {mov eax, realEip
    65.                       and   eax,0xffff0000
    66.                      };
    67.  
    68.                 if(realEip==0x00400000 )
    69.                 {
    70.                     wsprintf(buff,"eax: %x, ebx: %x, ecx: %x, edx: %x, esp: %x, eip: %x",ctx.Eax,ctx.Ebx,ctx.Ecx,ctx.Edx,ctx.Esp,ctx.Eip);
    71.                     MessageBoxA(0,buff,"CONTEXT",MB_OK);
    72.                 }
    73.  
    74.                 ctx.EFlags |=0x100;
    75.                 SetThreadContext(pi.hThread,&ctx);
    76.                 ContinueDebugEvent(dbe.dwProcessId,dbe.dwThreadId,DBG_CONTINUE);
    77.             }
    78.  
    79.         }
    80.         ContinueDebugEvent(dbe.dwProcessId,dbe.dwThreadId,DBG_EXCEPTION_NOT_HANDLED);
    81.  
    82.     }
    83.  
    84. }
     
  2. h0t

    h0t Member

    Публикаций:
    0
    Регистрация:
    3 апр 2011
    Сообщения:
    735
    del
     
  3. Clyde

    Clyde New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2009
    Сообщения:
    154
    h0t
    успел я подсмотреть, что написано =) Не похоже на DbgBreakPoint.
    Как я понимаю, я нахожусь где-то в недрах загрузчика, но неясно, почему управление не попадает на точку входа.
     
  4. h0t

    h0t Member

    Публикаций:
    0
    Регистрация:
    3 апр 2011
    Сообщения:
    735
    Код (Text):
    1. realEip=ctx.Eip;
    2. _asm {mov eax, realEip
    3.          and    eax,0xffff0000
    4. };
    5.  
    6. if(realEip==0x00400000 )
    7. {
    не хватает команды mov realeip,eax )))
     
  5. Clyde

    Clyde New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2009
    Сообщения:
    154
    00401000 - VA точки входа, конструкцию добавил, эффекта нет по-прежнему
     
  6. h0t

    h0t Member

    Публикаций:
    0
    Регистрация:
    3 апр 2011
    Сообщения:
    735
    После создания процесса, и вызова NtContinue сбрасывается флаг трассировки.
    Я жутко протормозил(((
     
  7. Clyde

    Clyde New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2009
    Сообщения:
    154
    Честно непонятно, мы же каждый раз его восстанавливаем
    ctx.EFlags |=0x100;
    Или как решить эту проблему?
     
  8. h0t

    h0t Member

    Публикаций:
    0
    Регистрация:
    3 апр 2011
    Сообщения:
    735
    сама система его сбрасывает в итоге до ep не доходит
     
  9. klzlk

    klzlk New Member

    Публикаций:
    0
    Регистрация:
    2 июн 2011
    Сообщения:
    449
    Установить TF до запуска потока, это приведет к установке TF в стартап контексте.
     
  10. Clyde

    Clyde New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2009
    Сообщения:
    154
    Эм, и как это обойти? Ведь olly и прочие отладчики каким-то методом работают.
    Поставить int3 на точку входа и получить EXCEPTION_BREAKPOINT?
    Или так тоже не выйдет?
     
  11. h0t

    h0t Member

    Публикаций:
    0
    Регистрация:
    3 апр 2011
    Сообщения:
    735
    Установить флаг ДО запуска
    ой опоздал(((
     
  12. Clyde

    Clyde New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2009
    Сообщения:
    154
    так и не понял, как это сделать, код малость переписал

    Код (Text):
    1. void MyMain(void)
    2. {
    3.     char buff[1024];
    4.     char OldByte[4];
    5.     char NewByte=0xcc;
    6.     int BreakNum=0;
    7.  
    8.     PROCESS_INFORMATION pi;
    9.     STARTUPINFOA si;
    10.     CONTEXT ctx;
    11.     DEBUG_EVENT dbe;
    12.  
    13.     DWORD realEip;
    14.  
    15.     DWORD dwBytesRead;
    16.  
    17.     ZeroMemory(&si,sizeof(STARTUPINFOA));
    18.     si.cb=sizeof(STARTUPINFOA);
    19.  
    20.     char* file ="C:\\file.exe";
    21.  
    22.  
    23.     CreateProcess(file, NULL, NULL, NULL, FALSE, DEBUG_PROCESS+DEBUG_ONLY_THIS_PROCESS, NULL, NULL, &si,&pi);
    24.  
    25.     while(1)
    26.  
    27.     {
    28.         WaitForDebugEvent(&dbe,INFINITE);
    29.         if(dbe.dwDebugEventCode==EXIT_PROCESS_DEBUG_EVENT)
    30.         {
    31.             MessageBoxA(0,"finished", "Cya",MB_OK);
    32.             break;
    33.         }
    34.         else if (dbe.dwDebugEventCode==EXCEPTION_DEBUG_EVENT)
    35.         {
    36.             if(dbe.u.Exception.ExceptionRecord.ExceptionCode==EXCEPTION_BREAKPOINT)
    37.             {
    38.                 BreakNum++;
    39.                 if(BreakNum==1)
    40.                 {
    41.                     ReadProcessMemory(pi.hProcess, (LPCVOID)0x00401000, &OldByte, 1, &dwBytesRead);
    42.                     WriteProcessMemory(pi.hProcess,(LPVOID)0x00401000,&NewByte, 1, &dwBytesRead);
    43.                 }
    44.                 else
    45.                 {
    46.                     ctx.ContextFlags=CONTEXT_FULL;
    47.                     GetThreadContext(pi.hThread, &ctx);
    48.                     ctx.Eip--;
    49.                     ctx.EFlags |=0x100;
    50.                     SetThreadContext(pi.hThread, &ctx);
    51.                     WriteProcessMemory(pi.hProcess,(LPVOID)0x00401000,&OldByte, 1, &dwBytesRead);
    52.                     wsprintf(buff,"eax: %x, ebx: %x, ecx: %x, edx: %x, esp: %x, eip: %x",ctx.Eax,ctx.Ebx,ctx.Ecx,ctx.Edx,ctx.Esp,ctx.Eip);
    53.                     MessageBoxA(0,buff,"CONTEXT-ON BREAK",MB_OK);
    54.  
    55.                 }
    56.  
    57.  
    58.  
    59.             }
    60.             else if(dbe.u.Exception.ExceptionRecord.ExceptionCode==EXCEPTION_SINGLE_STEP)
    61.             {
    62.                ctx.ContextFlags=CONTEXT_FULL;
    63.                GetThreadContext(pi.hThread, &ctx);
    64.                     wsprintf(buff,"eax: %x, ebx: %x, ecx: %x, edx: %x, esp: %x, eip: %x",ctx.Eax,ctx.Ebx,ctx.Ecx,ctx.Edx,ctx.Esp,ctx.Eip);
    65.                     MessageBoxA(0,buff,"CONTEXT-SINGLE TRACE",MB_OK);
    66.  
    67.                 ctx.EFlags |=0x100;
    68.                 SetThreadContext(pi.hThread,&ctx);
    69.                 ContinueDebugEvent(dbe.dwProcessId,dbe.dwThreadId,DBG_CONTINUE);
    70.             }
    71.  
    72.         }
    73.         ContinueDebugEvent(dbe.dwProcessId,dbe.dwThreadId,DBG_EXCEPTION_NOT_HANDLED);
    74.  
    75.     }
    76.  
    77. }
    Итог: на 0х00401000 нормально прерываюсь в EXCEPTION_BREAKPOINT; EIP из контекста 0х00401000, устанавливаю TF(вроде верно же ставлю?), далее в пошаговой трассировке, EIP из контекста снова лежит в глубинах ядра. Что я тут делаю не так?
     
  13. h0t

    h0t Member

    Публикаций:
    0
    Регистрация:
    3 апр 2011
    Сообщения:
    735
    при снятии/установке бряка забыли ContinueDebugEvent(dbe.dwProcessId,dbe.dwThreadId,DBG_CONTINUE);
    по-моему
     
  14. Clyde

    Clyde New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2009
    Сообщения:
    154
    спасибо большое, верно!
     
  15. Clyde

    Clyde New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2009
    Сообщения:
    154