Модераторы: feodorv, GremlinProg, xvr, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> DebugAPI, ...разобраться с EXCEPTION_SINGLE_STEP 
:(
    Опции темы
RideX
  Дата 26.6.2005, 17:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Awaiting Authorisation
Сообщений: 94
Регистрация: 8.9.2004

Репутация: нет
Всего: 7



Здравствуйте!
Подскажите пожалуйста где ошибка, почему tracing циклится и не доходит до запуска программы?
Код

#include <windows.h>
#include <stdio.h>

int main()
{
    const char* lpApplicationName  = "Test.exe";


    HANDLE                hFile, hFileMap;
    LPVOID                pMappedFile;

    PIMAGE_DOS_HEADER    pDosh;
    PIMAGE_NT_HEADERS    pPeh;

    DWORD                ImageBase, EntryPoint;

    BYTE                old, int3 = 0xCC;
    DWORD                dwBytesRead;
    DEBUG_EVENT            DbgEvent;
    CONTEXT                Context = {0};

    STARTUPINFO            si;
    PROCESS_INFORMATION    pi;



    hFile = CreateFile (lpApplicationName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL, 0);
    if (hFile == INVALID_HANDLE_VALUE)
    {
        MessageBox(0, "Cannot open file!", "Error", MB_ICONERROR);
        ExitProcess(0);
    }
    hFileMap = CreateFileMapping (hFile, NULL, PAGE_READONLY, 0, 0, NULL);
    if (!hFileMap)
    {
        CloseHandle(hFile);
        ExitProcess(0);
    }
    pMappedFile = MapViewOfFile ( hFileMap, FILE_MAP_READ, 0, 0, 0);
    if (!pMappedFile)
    {
        CloseHandle(hFileMap);
        CloseHandle(hFile);
        ExitProcess(0);
    }

    pDosh = (PIMAGE_DOS_HEADER)pMappedFile;
    pPeh  = (PIMAGE_NT_HEADERS)((DWORD)pMappedFile + pDosh->e_lfanew);

    ImageBase  = pPeh->OptionalHeader.ImageBase;
    EntryPoint = pPeh->OptionalHeader.AddressOfEntryPoint + ImageBase;

    UnmapViewOfFile(pMappedFile);
    CloseHandle(hFileMap);
    CloseHandle(hFile);



    ZeroMemory(&si, sizeof(STARTUPINFO));
    ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
    si.cb = sizeof(STARTUPINFO);
    if(!CreateProcess(lpApplicationName, NULL, NULL, NULL, FALSE, DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS,
        NULL, NULL, &si, &pi))
    {
        MessageBox(0, "Cannot create process!", "Error", MB_ICONERROR);
        ExitProcess(0);
    }


    printf("Entry point: %08X, ", EntryPoint);

    while (WaitForDebugEvent(&DbgEvent,INFINITE))
    {
        switch (DbgEvent.dwDebugEventCode)
        {
        case EXIT_PROCESS_DEBUG_EVENT:
            CloseHandle(pi.hProcess);
            CloseHandle(pi.hThread);
            ExitProcess(0);
            break;

        case CREATE_PROCESS_DEBUG_EVENT:
            printf("set breakpoint...\n");
            ReadProcessMemory(pi.hProcess, (LPVOID)EntryPoint, &old, 1, &dwBytesRead);
            WriteProcessMemory(pi.hProcess, (LPVOID)EntryPoint, &int3, 1, &dwBytesRead);
            break;

        case EXCEPTION_DEBUG_EVENT:
            switch (DbgEvent.u.Exception.ExceptionRecord.ExceptionCode)
            {
            case EXCEPTION_BREAKPOINT:
                Context.ContextFlags = CONTEXT_CONTROL;
                GetThreadContext(pi.hThread, &Context);
                if (Context.Eip - 1 == EntryPoint)
                {
                    Context.Eip -= 1;
                    WriteProcessMemory(pi.hProcess, (LPVOID)EntryPoint, &old, 1, &dwBytesRead);
                    Context.EFlags = Context.EFlags | 0x100;
                    SetThreadContext(pi.hThread, &Context);
                    printf("Stop on Entry point and restore it...\n\nTracing...\n");
                }
                ContinueDebugEvent(DbgEvent.dwProcessId, DbgEvent.dwThreadId, DBG_CONTINUE);
                break;

            case EXCEPTION_SINGLE_STEP:
                Context.ContextFlags = CONTEXT_CONTROL;
                GetThreadContext(pi.hThread, &Context);
                Context.EFlags = Context.EFlags | 0x100;
                SetThreadContext(pi.hThread, &Context);

                Sleep(55);
                printf("\rCurrent EIP: %08X", Context.Eip);
                ContinueDebugEvent(pi.dwProcessId, pi.dwThreadId, DBG_CONTINUE);
            }
        }
        ContinueDebugEvent(DbgEvent.dwProcessId, DbgEvent.dwThreadId, DBG_EXCEPTION_NOT_HANDLED);
    }

    return 0;
}

PM   Вверх
rsm
Дата 26.6.2005, 21:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник Клуба
Сообщений: 999
Регистрация: 16.3.2005

Репутация: 4
Всего: 62



Цитата(RideX @ 26.6.2005, 19:07)
не доходит до запуска программы

Дойдет, но этого момента пройдет ооочень много времени smile
Понаблюдай за ходом работы трассировщика - он залазит в каждую функцию каждой системной библиотеки (адреса 0x77xxxxxx), пока не достигнет отмерянного пользовательскому уровню "дна" системы и не начнет "подниматься" обратно "наверх" в код трассируемой программы.

Это сообщение отредактировал(а) rsm - 26.6.2005, 21:57
PM MAIL   Вверх
RideX
Дата 27.6.2005, 18:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Awaiting Authorisation
Сообщений: 94
Регистрация: 8.9.2004

Репутация: нет
Всего: 7



Мда, даже такой простейший код, вызов одного MessageBox, не проходит. Трэйс заканчивается, а ожидаемого "ящика с сообщением" так и не появляется smile
Код

.486
.model flat,stdcall
option casemap :none

include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib

.data
 szCaption      db "Yeah!",0
 szHello        db "Hello, buddy =)",0

.code
start:
        push MB_ICONINFORMATION
        push offset szCaption
        push offset szHello
        push 0
        call MessageBoxA

        push 0
        call ExitProcess
end start

PM   Вверх
Aster!x
Дата 27.6.2005, 18:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 7.8.2004

Репутация: нет
Всего: нет



RideX

Мне лень честно говоря искать ошибки, я тут нашел у себя старый исходник,
он вроде работает, только я уже не помню что там в какой момент показывается
MessageBox, и часть кода у мя была закомментарена, я просто раскомментарил
скомпилил - вроде работает, но может есть ошибки..

Код

.386
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\comdlg32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\comdlg32.lib
includelib \masm32\lib\user32.lib

.DATA

AppName db "Win32 Debug Example no.4",0
ofn   OPENFILENAME <>
FilterString db "Executable Files",0,"*.exe",0
             db "All Files",0,"*.*",0,0
ExitProc     db "The debuggee exits",0Dh,0Ah
             db "Total Instructions executed : %lu",0
TotalInstruction dd 0
szBuff  db 32 dup (0)
format db "%08lX",0

.DATA?

buffer db 512 dup (?)
startinfo STARTUPINFO <>
pi PROCESS_INFORMATION <>
DBEvent DEBUG_EVENT <>

ALIGN DWORD
context CONTEXT <>

.CODE
start:
  mov ofn.lStructSize, SIZEOF ofn
  mov ofn.lpstrFilter, OFFSET FilterString
  mov ofn.lpstrFile, OFFSET buffer
  mov ofn.nMaxFile,512
  mov ofn.Flags, OFN_FILEMUSTEXIST or \
      OFN_PATHMUSTEXIST or OFN_LONGNAMES or \
      OFN_EXPLORER or OFN_HIDEREADONLY
  invoke GetOpenFileName, OFFSET ofn
  .if eax==TRUE
      invoke GetStartupInfo, OFFSET startinfo
      invoke CreateProcess, OFFSET buffer, NULL, NULL, NULL, FALSE, DEBUG_PROCESS or DEBUG_ONLY_THIS_PROCESS, NULL, NULL, OFFSET startinfo, OFFSET pi
      .while TRUE
      invoke WaitForDebugEvent, OFFSET DBEvent, INFINITE
          .if DBEvent.dwDebugEventCode==EXIT_PROCESS_DEBUG_EVENT
              push TotalInstruction
              push OFFSET ExitProc
              push OFFSET buffer
              call wsprintf
              invoke MessageBox, 0, OFFSET buffer, OFFSET AppName, MB_OK or MB_ICONINFORMATION
          .break
          .elseif DBEvent.dwDebugEventCode==CREATE_PROCESS_DEBUG_EVENT
              mov eax, DBEvent.u.CreateProcessInfo.lpStartAddress
              push eax
              push OFFSET format
              push OFFSET szBuff
              call wsprintf
              xor ecx, ecx
              invoke MessageBox, ecx, OFFSET szBuff, ecx, ecx
          .elseif DBEvent.dwDebugEventCode==EXCEPTION_DEBUG_EVENT
                .if DBEvent.u.Exception.pExceptionRecord.ExceptionCode==EXCEPTION_BREAKPOINT
                    mov context.ContextFlags, CONTEXT_CONTROL
                    invoke GetThreadContext, pi.hThread, OFFSET context
                    mov eax, context.regEip
                    push eax
                    push OFFSET format
                    push OFFSET szBuff
                    call wsprintf
                    xor ecx, ecx
                    invoke MessageBox, ecx, OFFSET szBuff, ecx, ecx
                    or context.regFlag,100h
                    invoke SetThreadContext,pi.hThread, OFFSET context
                    invoke ContinueDebugEvent, DBEvent.dwProcessId,DBEvent.dwThreadId,DBG_CONTINUE
                .elseif DBEvent.u.Exception.pExceptionRecord.ExceptionCode==EXCEPTION_SINGLE_STEP
                    inc TotalInstruction
                    invoke GetThreadContext,pi.hThread, OFFSET context
                    or context.regFlag,100h
                    invoke SetThreadContext,pi.hThread, OFFSET context
                    invoke ContinueDebugEvent, DBEvent.dwProcessId,DBEvent.dwThreadId,DBG_CONTINUE
                .endif
          .endif
          invoke ContinueDebugEvent, DBEvent.dwProcessId,DBEvent.dwThreadId, DBG_CONTINUE
      .endw
  .endif
  invoke CloseHandle,pi.hProcess
  invoke CloseHandle,pi.hThread
  invoke ExitProcess, 0
end start

PM MAIL   Вверх
RideX
Дата 27.6.2005, 19:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Awaiting Authorisation
Сообщений: 94
Регистрация: 8.9.2004

Репутация: нет
Всего: 7



Aster!x
Спасибо за исходник, теперь разберусь smile
PM   Вверх
rsm
Дата 27.6.2005, 20:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник Клуба
Сообщений: 999
Регистрация: 16.3.2005

Репутация: 4
Всего: 62



Aster!x
Вах, знакомые все лица! smile
Приведенный код я испробовал первым, ведь он из туторов Iczelion'а. Однако работает он аналогично коду RideX.

RideX
"Прыжки" через участки кода при трейсе можно организовать либо устанавливая\снимая брейкпойнты, либо передав контроль юзеру с тем, чтобы он сам выбирал, где перепрыгнуть, а где пройти по шагам. В принципе можно автоматизировать процесс прыжков, но для этого нужно будет анализировать код, определяя, какая инструкция идет следующей и в случае вызова функции устаналивать брейкпойнт уже за этой инструкцией.

Это сообщение отредактировал(а) rsm - 27.6.2005, 20:07
PM MAIL   Вверх
Aster!x
Дата 27.6.2005, 22:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 7.8.2004

Репутация: нет
Всего: нет



Цитата(rsm @ 27.6.2005, 20:04)
Приведенный код я испробовал первым, ведь он из туторов Iczelion'а. Однако работает он аналогично коду RideX.


Да, за основу взят код Iczelion'а, это я когда-то давно экспериментировал.
Теперь понимаю почему этот код работает у меня, я запускал его на win98.

Цитата(rsm @ 27.6.2005, 20:04)
Вах, знакомые все лица!


Чем? smile

PM MAIL   Вверх
RideX
Дата 28.6.2005, 17:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Awaiting Authorisation
Сообщений: 94
Регистрация: 8.9.2004

Репутация: нет
Всего: 7



Цитата(rsm @ 27.6.2005, 20:04)
нужно будет анализировать код, определяя, какая инструкция идет следующей

Я тоже уже про это подумал smile
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.0564 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.