У нас есть программа с реализацией определённого алгоритма. Нужно включить в неё процесс пошагового выполнения этого алгоритма. Т.е. нажимаем кнопку и выполняется одна команда ассемблера и происходит остановка, нажимаем ещё раз следующая команда исполняется. Программа при запуске должна поддерживать два режима работы: обычный и пошаговый. Как проще всего это реализовать?
Ну мне приходит на ум, после команды вставлять джамп на твой обработчик, который вместо джампа восстановит оригинальные байты и переместит джамп после следующей команды.
Гемор Для пошагового выполнения: Установи флаг трасировки TF==1 и тогда после выполнения каждой команды процессор будет генерить эксепшен. Твоя задача просто написать обработчик
У меня если в обработчике снова поднять tf то следующая остановка будет сразу после выхода из этого обработчика.
Spairos Код (Text): start: lea eax,SEHHandler push eax assume fs:nothing xor eax,eax push fs:[eax] mov fs:[eax],esp pushfd XCHG DWORD PTR [ESP],EAX OR EAX,100h ; TF=1 XCHG DWORD PTR [ESP],EAX POPFD start_alg: ;твой алгоритм nop nop nop nop nop ;конец твоего алгоритма end_alg: xor eax,eax mov fs:[eax],esp break: invoke ExitProcess,0 ret SEHHandler proc uses edx edi ebx ecx pExcept:DWORD, pFrame:DWORD, pContext:DWORD, pDispatch:DWORD mov eax,pExcept assume eax:ptr EXCEPTION_RECORD ; mov ebx,[eax].ExceptionCode mov ebx,[eax].ExceptionAddress assume eax:nothing invoke MessageBox,0,0,0,0 mov edi,pContext assume edi:ptr CONTEXT .if (ebx>offset start_alg) && (ebx<offset end_alg) or [edi].regFlag,100h .endif mov eax,ExceptionContinueExecution ret SEHHandler endp end start
1. Как можно отладить код процедуры обработки исключений? У меня Olly Debyg, и он перехватывает все исключения. 2. Когда происходит исключение используется эти строки: invoke wsprintf, addr buf, addr ifmt, [edi].regEdx ; ifmt db "%x",0 invoke SetDlgItemText, hWin, IDC_EDX, addr buf одним словом отображаю значение регистра eax в поле для редактирования. Но если данные содержат в конце нули, например 5b 3а 12 00 - они не выводятся. только 5b 3а 12, что делать? 3. Если мне нужно вывести данные, а в [edi].regEdx - содержится их адресс, то как быть (в сам код добавлять новых переменных нельзя, только в обработчики исключений), к сожалению в Olly Debug я не знаю как посмотреть работу процедуры обр. искл. но что-то мне подсказывает, что когда в дело вступает эта процедура, по этому адресу находятся другие данные, например, например следующий код приводит к ошибке: mov esi, [edi].regEdx mov ecx, [esi]
1. Думаю, самое простое -- вызывать обработчик исключений прямо, т.е. 'call hndlr', искусстевнно создавая ему разные ситуации. 2. ifmt db "%.8X",0 должно помочь.
3. Решил, был неправильно написан обработчик. Хотя там всё равно, где-то есть ошибка. Под Windows Xp все работает нормально, а под Windows 2000 программа падает (основной алгоритм работает стабильно везде), в чем дело? Вот код обработчика: DlgProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM LOCAL ps:PAINTSTRUCT, hdc:HDC, hMemDC:HDC ................................. ................................. invoke IsDlgButtonChecked, hWnd, IDC_CHK1 ;проверка на включение пошагового режима .IF eax==BST_CHECKED mov count, 0 lea eax, SEHHandler push eax assume fs:nothing xor eax, eax push fs:[eax] mov fs:[eax], esp assume fs:error pushfd xchg dword ptr [esp], eax or eax, 100h ; TF=1 xchg DWORD PTR [esp], eax popfd .ENDIF Range ;вставить макрос подсчета проходов mov esi, pMemory ;поместить в esi адрес проекции исх. файла fEncode label near ;метка для отладки .......................... .......................... invoke IsDlgButtonChecked, hWnd, IDC_CHK1 .IF eax==BST_CHECKED assume fs:nothing xor eax, eax pop fs:[eax] add esp, 4 assume fs:error .ENDIF SEHHandler proc uses eax edi ebx edx pExceptWORD, pFrameWORD, pContextWORD, pDispatchWORD mov eax, pExcept assume eax:ptr EXCEPTION_RECORD ; mov ebx,[eax].ExceptionCode mov ebx,[eax].ExceptionAddress assume eax:nothing mov edi,pContext assume edi:ptr CONTEXT or [edi].regFlag, 100h ; for Encode ----------------------------------------------- lea esi, fEncode add esi, 0ch lea edx, fEncode add edx, 030h push edx .if (ebx == esi) inc count invoke wsprintf, addr buf, addr ifmt, [edi].regEax invoke SetDlgItemText, hWin, IDC_ECX, addr buf invoke wsprintf, addr buf, addr ifmt, [edi].regEdx invoke SetDlgItemText, hWin, IDC_ECX2, addr buf invoke MessageBox, 0, addr Input, addr MSGName, MB_OK .endif .if (ebx > esi) && (ebx <= edx) inc count invoke wsprintf, addr buf, addr ifmt, [edi].regEax invoke SetDlgItemText, hWin, IDC_EAX, addr buf invoke wsprintf, addr buf, addr ifmt, [edi].regEdx invoke SetDlgItemText, hWin, IDC_EDX, addr buf mov eax, [edi].regEdi mov ecx, [eax] invoke wsprintf, addr buf, addr ifmt, ecx invoke SetDlgItemText, hWin, IDC_EDI, addr buf add esi, 4 .if (ebx > esi) mov eax, [edi].regEbx mov ecx, [eax] invoke wsprintf, addr buf, addr ifmt, ecx invoke SetDlgItemText, hWin, IDC_EBX, addr buf .endif invoke MessageBox, 0, addr Step, addr MSGName, MB_OKCANCEL .if eax==IDCANCEL xor [edi].regFlag, 100h .endif .endif pop edx .if (ebx == edx) invoke wsprintf, addr buf, addr ifmt, [edi].regEax invoke SetDlgItemText, hWin, IDC_FIN, addr buf invoke wsprintf, addr buf, addr ifmt, [edi].regEdx invoke SetDlgItemText, hWin, IDC_FIN2, addr buf invoke MessageBox, 0, addr Output, addr MSGName, MB_OK .endif ; for Decode ----------------------------------------------- lea esi, fDecode sub esi, 019h .if (ebx > edx) && (ebx < esi) xor [edi].regFlag, 100h .endif add esi, 025h lea edx, fDecode add edx, 030h push edx .if (ebx == esi) inc count invoke wsprintf, addr buf, addr ifmt, [edi].regEax invoke SetDlgItemText, hWin, IDC_ECX, addr buf invoke wsprintf, addr buf, addr ifmt, [edi].regEdx invoke SetDlgItemText, hWin, IDC_ECX2, addr buf invoke MessageBox, 0, addr Input, addr MSGName, MB_OK .endif .if (ebx > esi) && (ebx <= edx) inc count invoke wsprintf, addr buf, addr ifmt, [edi].regEax invoke SetDlgItemText, hWin, IDC_EAX, addr buf invoke wsprintf, addr buf, addr ifmt, [edi].regEdx invoke SetDlgItemText, hWin, IDC_EDX, addr buf mov eax, [edi].regEdi mov ecx, [eax] invoke wsprintf, addr buf, addr ifmt, ecx invoke SetDlgItemText, hWin, IDC_EDI, addr buf add esi, 4 .if (ebx > esi) mov eax, [edi].regEbx mov ecx, [eax] invoke wsprintf, addr buf, addr ifmt, ecx invoke SetDlgItemText, hWin, IDC_EBX, addr buf .endif invoke MessageBox, 0, addr Step, addr MSGName, MB_OKCANCEL .if eax==IDCANCEL xor [edi].regFlag, 100h .endif .endif pop edx .if (ebx == edx) invoke wsprintf, addr buf, addr ifmt, [edi].regEax invoke SetDlgItemText, hWin, IDC_FIN, addr buf invoke wsprintf, addr buf, addr ifmt, [edi].regEdx invoke SetDlgItemText, hWin, IDC_FIN2, addr buf invoke MessageBox, 0, addr Output, addr MSGName, MB_OK .endif .if (ebx > edx) xor [edi].regFlag, 100h .endif invoke wsprintf, addr buf, addr ifmt_c, count invoke SetDlgItemText, hWin, IDC_STC5, addr buf mov eax, ExceptionContinueExecution ret SEHHandler endp
Уже все перепробовал, но код по SEH данный выше не работает на Windows 2000, а на XP все в порядке. Проблемы начинаются, когда мы возвращаемся после обработки исключения обратно в основную функцию программы.... вместо этого возвращаемся куда-то в недры системных dll и программа там зацикливается.