попытался написать что-то типа мини отладчика, для начала мне хватит лишь отображения регистров, но почему-то EIP получаемый при пошаговой трассировке никогда не совпадает с точкой входа, при этом программа выполняется до конца (для теста взял обычный мессаджбокс,те однопоточное приложение). помогите плз разобратся, в чем загвоздка. Код (Text): #include <windows.h> #pragma comment(lib,"USER32.LIB") #pragma comment(lib,"KERNEL32.LIB") #pragma comment(linker,"/ENTRY:MyMain") #pragma comment(linker,"/SUBSYSTEM:WINDOWS") void MyMain(void) { char buff[1024]; PROCESS_INFORMATION pi; STARTUPINFOA si; CONTEXT ctx; DEBUG_EVENT dbe; DWORD realEip; ZeroMemory(&si,sizeof(STARTUPINFOA)); si.cb=sizeof(STARTUPINFOA); char* file ="C:\\file.exe"; CreateProcess(file, NULL, NULL, NULL, FALSE, DEBUG_PROCESS+DEBUG_ONLY_THIS_PROCESS, NULL, NULL, &si,&pi); while(true) { WaitForDebugEvent(&dbe,INFINITE); if(dbe.dwDebugEventCode==EXIT_PROCESS_DEBUG_EVENT) { MessageBoxA(0,"finished", "Cya",MB_OK); break; } else if (dbe.dwDebugEventCode==EXCEPTION_DEBUG_EVENT) { if(dbe.u.Exception.ExceptionRecord.ExceptionCode==EXCEPTION_BREAKPOINT) { ctx.ContextFlags=CONTEXT_CONTROL; GetThreadContext(pi.hThread,&ctx); realEip=ctx.Eip; _asm {mov eax, realEip and eax,0xffff0000 }; if(realEip==0x00400000) { 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); MessageBoxA(0,buff,"CONTEXT",MB_OK); } ctx.EFlags |=0x100; SetThreadContext(pi.hThread,&ctx); ContinueDebugEvent(dbe.dwProcessId,dbe.dwThreadId,DBG_CONTINUE); } else if(dbe.u.Exception.ExceptionRecord.ExceptionCode==EXCEPTION_SINGLE_STEP) { GetThreadContext(pi.hThread, &ctx); realEip=ctx.Eip; _asm {mov eax, realEip and eax,0xffff0000 }; if(realEip==0x00400000 ) { 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); MessageBoxA(0,buff,"CONTEXT",MB_OK); } ctx.EFlags |=0x100; SetThreadContext(pi.hThread,&ctx); ContinueDebugEvent(dbe.dwProcessId,dbe.dwThreadId,DBG_CONTINUE); } } ContinueDebugEvent(dbe.dwProcessId,dbe.dwThreadId,DBG_EXCEPTION_NOT_HANDLED); } }
h0t успел я подсмотреть, что написано =) Не похоже на DbgBreakPoint. Как я понимаю, я нахожусь где-то в недрах загрузчика, но неясно, почему управление не попадает на точку входа.
Код (Text): realEip=ctx.Eip; _asm {mov eax, realEip and eax,0xffff0000 }; if(realEip==0x00400000 ) { не хватает команды mov realeip,eax )))
Честно непонятно, мы же каждый раз его восстанавливаем ctx.EFlags |=0x100; Или как решить эту проблему?
Эм, и как это обойти? Ведь olly и прочие отладчики каким-то методом работают. Поставить int3 на точку входа и получить EXCEPTION_BREAKPOINT? Или так тоже не выйдет?
так и не понял, как это сделать, код малость переписал Код (Text): void MyMain(void) { char buff[1024]; char OldByte[4]; char NewByte=0xcc; int BreakNum=0; PROCESS_INFORMATION pi; STARTUPINFOA si; CONTEXT ctx; DEBUG_EVENT dbe; DWORD realEip; DWORD dwBytesRead; ZeroMemory(&si,sizeof(STARTUPINFOA)); si.cb=sizeof(STARTUPINFOA); char* file ="C:\\file.exe"; CreateProcess(file, NULL, NULL, NULL, FALSE, DEBUG_PROCESS+DEBUG_ONLY_THIS_PROCESS, NULL, NULL, &si,&pi); while(1) { WaitForDebugEvent(&dbe,INFINITE); if(dbe.dwDebugEventCode==EXIT_PROCESS_DEBUG_EVENT) { MessageBoxA(0,"finished", "Cya",MB_OK); break; } else if (dbe.dwDebugEventCode==EXCEPTION_DEBUG_EVENT) { if(dbe.u.Exception.ExceptionRecord.ExceptionCode==EXCEPTION_BREAKPOINT) { BreakNum++; if(BreakNum==1) { ReadProcessMemory(pi.hProcess, (LPCVOID)0x00401000, &OldByte, 1, &dwBytesRead); WriteProcessMemory(pi.hProcess,(LPVOID)0x00401000,&NewByte, 1, &dwBytesRead); } else { ctx.ContextFlags=CONTEXT_FULL; GetThreadContext(pi.hThread, &ctx); ctx.Eip--; ctx.EFlags |=0x100; SetThreadContext(pi.hThread, &ctx); WriteProcessMemory(pi.hProcess,(LPVOID)0x00401000,&OldByte, 1, &dwBytesRead); 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); MessageBoxA(0,buff,"CONTEXT-ON BREAK",MB_OK); } } else if(dbe.u.Exception.ExceptionRecord.ExceptionCode==EXCEPTION_SINGLE_STEP) { ctx.ContextFlags=CONTEXT_FULL; GetThreadContext(pi.hThread, &ctx); 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); MessageBoxA(0,buff,"CONTEXT-SINGLE TRACE",MB_OK); ctx.EFlags |=0x100; SetThreadContext(pi.hThread,&ctx); ContinueDebugEvent(dbe.dwProcessId,dbe.dwThreadId,DBG_CONTINUE); } } ContinueDebugEvent(dbe.dwProcessId,dbe.dwThreadId,DBG_EXCEPTION_NOT_HANDLED); } } Итог: на 0х00401000 нормально прерываюсь в EXCEPTION_BREAKPOINT; EIP из контекста 0х00401000, устанавливаю TF(вроде верно же ставлю?), далее в пошаговой трассировке, EIP из контекста снова лежит в глубинах ядра. Что я тут делаю не так?
при снятии/установке бряка забыли ContinueDebugEvent(dbe.dwProcessId,dbe.dwThreadId,DBG_CONTINUE); по-моему
http://z0mbie.daemonlab.org/tracingr.txt для тех кто интересуется этой темой, у зомбы тоже неплохо описано