Сейчас на форуме: bartolomeo, hgdagon (+7 невидимых) |
eXeL@B —› Программирование —› Лоадер - отладчик на ассме |
Посл.ответ | Сообщение |
|
Создано: 27 марта 2006 19:49 · Поправил: YDS · Личное сообщение · #1 Нужно создать лоадер в виде мини отладчика: сабж должен тормознуть отлаживаемый процесс, когда у того в EIP будет определенный адрес. Как сие заюзать? Начальный код на MASM-е: .486 .model flat, stdcall option casemap :none include \masm32\include\windows.inc include \masm32\include\masm32.inc include \masm32\include\user32.inc include \masm32\include\kernel32.inc include \masm32\include\shell32.inc includelib \masm32\lib\masm32.lib includelib \masm32\lib\user32.lib includelib \masm32\lib\kernel32.lib includelib \masm32\lib\shell32.lib .data App db "Proga",0 Err1 db "Program not found ",0 ; Обломов prog db "programm.exe",0 ; Имя проги bufwr DWORD 00h ; Мне нужно байт 00 поменять на 01 va DWORD 415E12h ; Это адрес, при обращении к оторому надо тормознуть процесс ипроизвести запись .data? bufr dw ? ; Байт, в который производится чтение pinfo PROCESS_INFORMATION <> ; Инфа о процессе sinfo STARTUPINFO <> ; инфа о запуске n DWORD ? ; Кол-во байтов .code .code start: invoke CreateProcess,addr prog,NULL,NULL,NULL,FALSE, CREATE_NEW_CONSOLE OR NORMAL_PRIORITY_CLASS,NULL,NULL,addr sinfo,addr pinfo ; Создаем процесс .IF eax == 0 ; Если прога не запустилась invoke MessageBox,NULL,addr Err1,addr App,MB_OK invoke ExitProcess,0 .ENDIF .WHILE TRUE .IF eip == va ; ВОТ ТУТ КАК ЗАДАТЬ ПРОВЕРКУ ОТЛАЖИВАЕМОГО ПРОЦЕССА (регистра eip MASM не знает) invoke Sleep,300 mov byte ptr [eax+20], bufwr ; из-за чего весь сыр-бор - править приходится память по ссылке invoke CloseHandle,pinfo.hThread invoke ExitProcess,0 .ENDIF .ENDW end start |
|
Создано: 27 марта 2006 20:08 · Личное сообщение · #2 YDS пишет: ВОТ ТУТ КАК ЗАДАТЬ ПРОВЕРКУ ОТЛАЖИВАЕМОГО ПРОЦЕССА (регистра eip MASM не знает) Вообще отладчик изначально написан неверно. Тебе нужен контекст отлаживаемого процесса, а у тебя процесс вообще не отлаживается, а просто тупо запускается. Почитал бы теорию чтоли... http://exelab.ru/art/?action=view&id=75 http://exelab.ru/art/?action=view&id=74 |
|
Создано: 27 марта 2006 20:21 · Поправил: YDS · Личное сообщение · #3 |
|
Создано: 27 марта 2006 22:09 · Личное сообщение · #4 М-да, вот тут http://exelab.ru/art/?action=view&id=75 код весьма интересный, только под XP не рабочий (под Win98 и не пробовал). Полазив, нашел продолжение: http://xtin.km.ru/view.shtml?id=129. Доработал с учетом последнего до такого состояния: unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Edit1: TEdit; Memo1: TMemo; Button1: TButton; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; function OpenThread(dwDesiredAccess: DWord; bInheritHandle: Bool; dwThreadId: DWord): DWord; stdcall; external 'kernel32.dll'; var Form1: TForm1; sti:tstartupinfo; lpPi:tprocessinformation; DE:_Debug_event; Cont:_Context; hProc : dword; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); begin if not CreateProcess(nil,'c:\Windows\notepad.exe',nil,nil,false,DEBUG_PROCESS or DEBUG_ONLY_THIS_PROCESS,nil,nil,StI,lpPI) then begin messageboxa(0,'Процесс не создан!','Error',MB_ICONQUESTION); halt; end; hproc := 0; While true do Begin if WaitForDebugEvent(de,INFINITE) then Begin hProc := OpenThread($1F03FF,False,DE.dwThreadid); if de.dwDebugEventCode=EXCEPTION_DEBUG_EVENT then if DE.Exception.ExceptionRecord.ExceptionCode=EXCEPTION_BREAKPOINT then Begin cont.ContextFlags:=CONTEXT_CONTROL; GetThreadContext(hProc,cont); cont.EFlags:=cont.EFlags or $100; setThreadContext(hProc,cont); end Else if DE.Exception.ExceptionRecord.ExceptionCode=EXCEPTION_SINGLE_STEP then Begin GetThreadContext(hProc,cont); cont.EFlags:=cont.EFlags or $100; setThreadContext(hProc,cont); // if (cont.eip>$400000) and (cont.eip<$600000) then Begin Memo1.Lines.Add(inttohex(cont.eip,8)); // Showmessage('OEP='+inttohex(cont.eip,8)); // halt; end; end; ContinueDebugEvent(DE.dwProcessId, DE.dwThreadid,DBG_CONTINUE); end; application.ProcessMessages; end; //конец бесконечного цикла end; end. Но все равно: вместо адресов запущенного процесса получаю EIP-ы выполняемых API. Что тут не так? |
|
Создано: 28 марта 2006 00:09 · Поправил: DillerInc · Личное сообщение · #5 YDS Точно не могу сказать,но первое,что бросается в глаза -- это функция OpenThread. За чем она тебе?Ты же создал процесс,ты в нём хозяин.И обращаться к основному потоку можно с лёгкостью через структуру TProcessInformation,которая у тебя заполнится после вызова CreateProcess: lpPi.hThread GetThreadContext(lpPi.hThread, cont); ...а не через одно место,используя функцию OpenThread . Далее мне не совсем понятно,что ты хочешь сделать с помощью команд: cont.EFlags:=cont.EFlags or $100; setThreadContext(hProc,cont); ______________ Посмотрел тот пример,указанный по ссылке -- второй пункт отпал . ----- the Power of Reversing team |
|
Создано: 28 марта 2006 09:46 · Поправил: AlexZ · Личное сообщение · #6 YDS читай тутор icezelion'a. Он есть на wasm.ru Сам делал трейсер - в ринг-3 нельзя проходить с флажком TF команду SYSENTER в XP SP-1 +1 структра контекста должна быть выровнена хотяб по dword align dword
Откопал свой сорц. Только он тормозит прогу на EIP чуть иначе - это чтоб на ХП СП-1 работало. Я уже говорил что бага не то с SYSCALL не то с SYSENTER есть на SP-1. ----- Я медленно снимаю с неё UPX... *FF_User* |
|
Создано: 28 марта 2006 10:07 · Личное сообщение · #7 //Если поправить пост и вложить файл - то он не цепляется. 331f_traicer+by+AlexZ.zip.zip ----- Я медленно снимаю с неё UPX... *FF_User* |
|
Создано: 28 марта 2006 10:14 · Личное сообщение · #8 |
|
Создано: 28 марта 2006 12:04 · Личное сообщение · #9 DillerInc пишет: OpenThread. За чем она тебе? Если процесс многопоточный, то, при exception'е в одном из побочных потоков, трейсер, который использует только структуру TProcessInformation, не сможет считать структуру Context, так как не будет иметь его указателя. И вообще в современных многомегабайтовых прогах окончание работы трейсера не дождешься. Надо юзать бряки. Хардварные конечно сложновато с их битовыми масками, но все же можно, тем более, что инфы сейчас много всякой. Самое простое - это вставлять байт CC (INT3) и при срабатывании вставлять оригинальный байт на место. Можно юзать также флажок PAGE_GUARD у атрибутов страницы памяти. При добавлении этого флага при обращении к странице памяти генерируется исключение EXCEPTION_GUARD_PAGE и флажок сбрасывается. А еще... Да много чего еще ----- Yann Tiersen best and do not fuck |
|
Создано: 28 марта 2006 12:08 · Личное сообщение · #10 |
|
Создано: 28 марта 2006 12:19 · Личное сообщение · #11 YDS пишет: Но все равно: вместо адресов запущенного процесса получаю EIP-ы выполняемых API После создания процесса прога тормозится в виндовом лоадере и ты по сути начинаешь трассировать именно его. Если очень очень долго подождешь, то увидишь адреса проги. Ты пишешь трейсер по первой статье, а тебе нужна вторая про бряки. Там сначала ожидается пока прога тормознет на EP а потом можно делать все что угодно. ----- Yann Tiersen best and do not fuck |
|
Создано: 28 марта 2006 13:36 · Личное сообщение · #12 по просьбам цепляю файл ещё раз 9a99_Traicer_by_AlexZ.zip.zip ----- Я медленно снимаю с неё UPX... *FF_User* |
|
Создано: 28 марта 2006 13:49 · Личное сообщение · #13 |
|
Создано: 28 марта 2006 14:04 · Личное сообщение · #14 |
|
Создано: 28 марта 2006 14:23 · Поправил: YDS · Личное сообщение · #15 И снова х-мм! Второй пример от HEX-а и трейсер от AlexZ работают, но только с однопотоковыми приложениями. У меня же на разборе тулза, которая при своем запуске создает три потока: первые 2 отладочных (в момент запуска оба пустых), третий - основной. Нужно перейти в конктекст последнего и вправлять мозги ему. Вопрос как это сделать. Код такой. Начало имеем стандартное: CreateProcess(nil,'c:\Tulza.exe,nil,nil,false,DEBUG_PROCESS or DEBUG_ONLY_THIS_PROCESS or Create_suspended,nil,nil,StI,lpPI) Потом пробую перебирать все триды в поисках того, у которого по адресу EP что-то есть: hproc := 0; // хэндл потока While true do Begin if WaitForDebugEvent(de,INFINITE) then begin hProc := OpenThread($1F03FF,False,DE.dwThreadid); // читаем хэндл потока readprocessmemory(hProc,pointer(x),@b[0],1,i); //читаем байт по EP - x if b[0] <> $0 then break; // там не пусто - выходим из цикла для продолжения. end; ContinueDebugEvent(DE.dwProcessId, DE.dwThreadid,DBG_CONTINUE); end; В теории вроде все как надо. На деле поток не находится. Чего делаю не так. |
|
Создано: 28 марта 2006 18:17 · Личное сообщение · #16 |
|
Создано: 28 марта 2006 19:33 · Поправил: AlexZ · Личное сообщение · #17 |
|
Создано: 28 марта 2006 20:14 · Личное сообщение · #18 |
|
Создано: 29 марта 2006 13:14 · Личное сообщение · #19 AlexZ пишет: Вообще знаешь, я не думаю что этот код является верным подходом к отладке многопоточных приложений У меня все нормально работает. Доказателство - прога, пакованая ExeCryptor'ом запускается и нормально работает. А в ExeCryptor'е потоки каждую секунду создаются,убиваются и флудят исключениями, что и фиксирует мой трейсер. AlexZ пишет: DEBUG_ONLY_THIS_PROCESS. Ну, это не дело - этот флажок убрать Мой трейсер работает с этим флажком, и насколько я понял из MSDN дебажица будет не главный тред, а процесс, который ты запустил, а иначе будет дебужится и процесс, который был создан процессом - жертвой. ----- Yann Tiersen best and do not fuck |
|
Создано: 29 марта 2006 13:20 · Личное сообщение · #20 |
|
Создано: 29 марта 2006 15:03 · Личное сообщение · #21 Перечитал мануалы: DEBUG_ONLY_THIS_PROCESS не влияет на потоки, а влияет только на количество одновременно отлаживаемых прцессов. Приаттачиваю доки, с которых я начинал писать свой отладчик, а затем полностью перешел на MSDN. Там есть пример на С и Delphi юнит из трейнера (не моего). 141b_debuggers.rar.zip ----- Yann Tiersen best and do not fuck |
|
Создано: 29 марта 2006 18:51 · Личное сообщение · #22 |
|
Создано: 29 марта 2006 18:52 · Личное сообщение · #23 При создании нового потока отладчику приходит соответствующее сообщение, в котором, в частности, указан хэндл этого потока. За подробностями - MSDN, структура DEBUG_EVENT. Флаг DEBUG_ONLY_THIS_PROCESS означает всего лишь, что если отлаживаемый процесс создаст новый (CreateProcess(...)), то отладчик не становится отладчиком еще и этого нового процесса (по умолчанию - становится). |
|
Создано: 29 марта 2006 19:06 · Личное сообщение · #24 YDS пишет: DEBUG_PROCESS or DEBUG_ONLY_THIS_PROCESS or Create_suspended ...по-моему,получается какое-то масло масляное. Если ты создаёшь процесс с флагом CREATE_SUSPENDED,то,как правильно подметил PE_Kill,главный поток создаваемого процесса не запустится,пока ты не вызовешь функцию ResumeThread. Далее на MSDN сказано,что: If this flag(DEBUG_PROCESS) is combined with DEBUG_ONLY_THIS_PROCESS, the caller debugs only the new process. ...поэтому толку от использования обоих флагов совместно -- нет. И если я не ошибаюсь,то при использовании флага DEBUG_PROCESS/DEBUG_ONLY_THIS_PROCESS процесс и так создаётся как бы в замороженном состоянии... зачем тогда CREATE_SUSPENDED ... . ----- the Power of Reversing team |
eXeL@B —› Программирование —› Лоадер - отладчик на ассме |