调试器学习
来源:互联网 发布:淘宝客服不回话怎么办 编辑:程序博客网 时间:2024/06/05 14:43
#include "stdafx.h"#include <stdlib.h>#define WINVER 0x0501#include <windows.h>BOOLDbgNewProcess( LPTSTR szCmdLine){STARTUPINFO StartupInfo;PROCESS_INFORMATION ProcessInfo;memset ( &StartupInfo , NULL , sizeof ( STARTUPINFO ) ) ;memset ( &ProcessInfo , NULL , sizeof ( PROCESS_INFORMATION ) ) ;StartupInfo.cb = sizeof ( STARTUPINFO ) ;//-- create the Debuggee processif( !CreateProcess( 0L, szCmdLine, (LPSECURITY_ATTRIBUTES) 0L, (LPSECURITY_ATTRIBUTES) 0L, TRUE, DEBUG_PROCESS | CREATE_NEW_CONSOLE | NORMAL_PRIORITY_CLASS, (LPVOID) 0L, (LPTSTR) 0L, &StartupInfo, &ProcessInfo ) ) {TCHAR szMsg[MAX_PATH];FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,NULL,GetLastError(),0, // Default language(LPTSTR) szMsg,MAX_PATH,NULL );printf("Failed in CreateProcess() with error:\n ");printf(szMsg);printf("\n");return( FALSE );}else{CloseHandle( ProcessInfo.hProcess );CloseHandle( ProcessInfo.hThread );}return( TRUE );}#define MAX_DBG_EVENT 9LPTSTR DbgEventName[ MAX_DBG_EVENT+1] = { "EXCEPTION_DEBUG_EVENT", "CREATE_THREAD_DEBUG_EVENT", "CREATE_PROCESS_DEBUG_EVENT", "EXIT_THREAD_DEBUG_EVENT", "EXIT_PROCESS_DEBUG_EVENT", "LOAD_DLL_DEBUG_EVENT", "UNLOAD_DLL_DEBUG_EVENT","OUTPUT_DEBUG_STRING_EVENT","RIP_EVENT", "Unknown Debug Event"};//////////////////////////////在处理完调试事件后,调试器会调用 ContinueDebugEvent API来恢复调试事件BOOL DbgMainLoop(DWORD dwWaitMS){DEBUG_EVENT DbgEvt; // debugging event information DWORD dwContinueStatus = DBG_CONTINUE; // exception continuation BOOL bExit=FALSE;while(!bExit) { // Wait for a debugging event to occur. The second parameter indicates // number of milliseconds to wait for a debugging event. If the parameter// is INFINITE the function does not return until a debugging event occurs. if(!WaitForDebugEvent(&DbgEvt, dwWaitMS)){printf("WaitForDebugEvent() returned False %d.\n",GetLastError());bExit=TRUE;continue;} // Process the debugging event code. printf("Debug event received from process %d thread %d: %s.\n",DbgEvt.dwProcessId,DbgEvt.dwThreadId,DbgEventName[DbgEvt.dwDebugEventCode>MAX_DBG_EVENT?MAX_DBG_EVENT:DbgEvt.dwDebugEventCode-1]); switch (DbgEvt.dwDebugEventCode) { case EXCEPTION_DEBUG_EVENT: // Process the exception code. When handling // exceptions, remember to set the continuation // status parameter (dwContinueStatus). This value // is used by the ContinueDebugEvent function. printf("-Debuggee breaks into debugger; press any key to continue.\n");getchar();//return TRUE;switch (DbgEvt.u.Exception.ExceptionRecord.ExceptionCode) { case EXCEPTION_ACCESS_VIOLATION: // First chance: Pass this on to the system. // Last chance: Display an appropriate error. break; case EXCEPTION_BREAKPOINT: // First chance: Display the current // instruction and register values. break; case EXCEPTION_DATATYPE_MISALIGNMENT: // First chance: Pass this on to the system. // Last chance: Display an appropriate error. break; case EXCEPTION_SINGLE_STEP: // First chance: Update the display of the // current instruction and register values. break; case DBG_CONTROL_C: // First chance: Pass this on to the system. // Last chance: Display an appropriate error. break; default:// Handle other exceptions. break;} case CREATE_THREAD_DEBUG_EVENT: // As needed, examine or change the thread's registers // with the GetThreadContext and SetThreadContext functions; // and suspend and resume thread execution with the // SuspendThread and ResumeThread functions. break;case CREATE_PROCESS_DEBUG_EVENT: // As needed, examine or change the registers of the // process's initial thread with the GetThreadContext and // SetThreadContext functions; read from and write to the // process's virtual memory with the ReadProcessMemory and // WriteProcessMemory functions; and suspend and resume // thread execution with the SuspendThread and ResumeThread // functions. Be sure to close the handle to the process image // file with CloseHandle.break; case EXIT_THREAD_DEBUG_EVENT: // Display the thread's exit code. break; case EXIT_PROCESS_DEBUG_EVENT: // Display the process's exit code. bExit=TRUE;break; case LOAD_DLL_DEBUG_EVENT: // Read the debugging information included in the newly // loaded DLL. Be sure to close the handle to the loaded DLL // with CloseHandle.break; case UNLOAD_DLL_DEBUG_EVENT: // Display a message that the DLL has been unloaded. break; case OUTPUT_DEBUG_STRING_EVENT: // Display the output debugging string. break; } // Resume executing the thread that reported the debugging event. ContinueDebugEvent(DbgEvt.dwProcessId, DbgEvt.dwThreadId, dwContinueStatus); //Enables a debugger to continue a thread that previously reported a debugging event. }return TRUE;}void Help(){ printf ( "TinyDbgr <PID of Program to Debug>|\n " "<Full Exe File Name> [Prgram Parameters]\n" ) ;}int main(int argc, char* argv[]){if(argc<=1) {Help();return -1;}if (strstr(strupr(argv[1]),".EXE"))//将字符串s转换为大写形式说明:只转换s中出现的小写字母,不改变其它字符...{//从字符串str1中查找是否有字符串str2,如果有,从str1中的str2位置起,返回str1中str2起始位置的指针,如果没有,返回null。TCHAR szCmdLine[ MAX_PATH ] ;szCmdLine[ 0 ] = '\0' ;for ( int i = 1 ; i < argc ; i++ ){ strcat ( szCmdLine , argv[ i ] ) ;if ( i < argc ){strcat ( szCmdLine , " " ) ;}}if(!DbgNewProcess(szCmdLine)){return -2;}}else{if(!DebugActiveProcess(atoi(argv[1])))//If the function succeeds, the return value is nonzero.{printf("Failed in DebugActiveProcess() with %d.\n",GetLastError());return -2;}if(argc>2 && stricmp(argv[2],"-e")==0){// try the DebugSetProcessKillOnExit() APIif(!DebugSetProcessKillOnExit(FALSE)){//Sets the action to be performed when the calling thread exits.printf("Failed in DebugSetProcessKillOnExit() with %d.\n",GetLastError());}}if(argc>2 && stricmp(argv[2],"-s")==0){DbgMainLoop(10);// try the DebugActiveProcessStop() APIif(!DebugActiveProcessStop(atoi(argv[1]))){printf("Failed in DebugActiveProcessStop() with %d.\n",GetLastError());}elseprintf("Detach debuggee successfully.\n");return 0;}}return DbgMainLoop(INFINITE);}上面是学习的小调试器代码 看看就行·························
两种方式:
1 输入PID 附加到已经启动的进程
DebugActiveProcess 实现 附加功能
BOOL WINAPI DebugSetProcessKillOnExit( _In_ BOOL KillOnExit);
If this parameter is TRUE, the thread terminates all attached processes on exit (note that this is the default). Otherwise, the thread detaches from all processes being debugged on exit.
2 打开程序调试
通过创建程序时 带调试
CreateProcess( 0L, szCmdLine, (LPSECURITY_ATTRIBUTES) 0L, (LPSECURITY_ATTRIBUTES) 0L, TRUE, DEBUG_PROCESS | CREATE_NEW_CONSOLE | NORMAL_PRIORITY_CLASS, (LPVOID) 0L, (LPTSTR) 0L, &StartupInfo, &ProcessInfo)
BOOL WINAPI WaitForDebugEvent( _Out_ LPDEBUG_EVENT lpDebugEvent, //保存 收到的调试事件 _In_ DWORD dwMilliseconds //指定等待的毫秒数 INFINITE 无限期等待);
来供 调试器等待和接收调试事件
在处理完调试事件后,调试器会调用 ContinueDebugEvent API来恢复调试事件
BOOL WINAPI ContinueDebugEvent( _In_ DWORD dwProcessId, _In_ DWORD dwThreadId, _In_ DWORD dwContinueStatus);
最后附带一个修改程序的例子:
#include "stdio.h"#include "tchar.h"#include "windows.h"int _tmain(int argc, _TCHAR* argv[]){STARTUPINFO stSi;PROCESS_INFORMATION stPi;DEBUG_EVENT stDe;int nAddrOfBreakPoint = 0x0040E813; //需要下断点的地址int nAddrOfPatch = 0x004010B8; //需要打补丁处的地址unsigned char cOldByte; //用于保存nAddrOfBreakPoint断点处的原指令unsigned char cBreakPoint = 0xCC; //int 3指令unsigned char cPatchByte = 0x75; //补丁字节 CONTEXT stThreadContext;BOOL bCreated = FALSE;BOOL bFinished = FALSE;//LPTSTR szCmdLine = _tcsdup(TEXT("mengmeng.exe"));LPTSTR szCmdLine = _T("mengmeng.exe");GetStartupInfo(&stSi);bCreated = CreateProcess(NULL,szCmdLine,NULL,NULL,FALSE,DEBUG_ONLY_THIS_PROCESS,NULL,NULL,&stSi,&stPi);if(!bCreated){MessageBox(GetActiveWindow(),TEXT("不能打开test.exe文件!"),TEXT("Result"),MB_OK);//不能打开test.exe时清除资源if(szCmdLine!=NULL) free(szCmdLine);return 0;}//开始调试运行,等待调试事件发生while(WaitForDebugEvent(&stDe,INFINITE)){//有调试事件发生switch(stDe.dwDebugEventCode){case CREATE_PROCESS_DEBUG_EVENT://写断点(int 3[0xCC])到nAddrOfBreakPoint,之前要保存原始指令ReadProcessMemory(stPi.hProcess,(LPVOID)nAddrOfBreakPoint,&cOldByte,1,NULL);WriteProcessMemory(stPi.hProcess,(LPVOID)nAddrOfBreakPoint,&cBreakPoint,1,NULL);break;case EXCEPTION_DEBUG_EVENT:if(stDe.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT){//断点异常//若不是在nAddrOfBreakPoint处中断,则继续等待stThreadContext.ContextFlags = CONTEXT_CONTROL;GetThreadContext(stPi.hThread,&stThreadContext);if(stThreadContext.Eip!=nAddrOfBreakPoint+1) break; //执行内存补丁WriteProcessMemory(stPi.hProcess,(LPVOID)0x004010B8,&cPatchByte,1,NULL);//恢复nAddrOfBreakPoint原始指令,并重新执行该指令WriteProcessMemory(stPi.hProcess,(LPVOID)nAddrOfBreakPoint,&cOldByte,1,NULL);stThreadContext.ContextFlags = CONTEXT_FULL;GetThreadContext(stPi.hThread,&stThreadContext);stThreadContext.Eip = nAddrOfBreakPoint;SetThreadContext(stPi.hThread,&stThreadContext);}break;case EXIT_PROCESS_DEBUG_EVENT: bFinished = TRUE;}ContinueDebugEvent(stPi.dwProcessId,stPi.dwThreadId,DBG_CONTINUE);//继续让被调试的程序执行if(bFinished)break;}//破解成功后清除内存资源if(szCmdLine!=NULL) free(szCmdLine);CloseHandle(stPi.hThread);CloseHandle(stPi.hProcess);return 0;}
- 调试器代码学习
- 学习使用调试器
- 调试器学习
- 调试学习
- 学习调试
- gdb调试器命令学习总结笔记
- gdb调试器命令学习总结笔记
- gdb调试器命令学习总结笔记
- gdb调试器命令学习总结笔记
- 安装调试器,学习memory controller
- gdb调试器命令学习总结笔记
- Python学习笔记--调试器debugger
- gdb调试器命令学习总结笔记
- 调试器原理之ptrace调用学习
- GDB调试器的学习(一)
- vs远程调试学习-崩溃调试学习
- 调试符号学习
- 调试api初步学习
- Opencv-2.0.0的ARM移植和使用(Ubuntu10.04 / OK6410开发板 / linux3.01)
- 让VC调试器正确显示UTF-8字符串
- sicily 1206.Stacking Cylinders
- sendfile为什么比read、writer快
- Android触摸屏失效后的操作方法
- 调试器学习
- 跟一下wpa_supplicant(3-1) connect AP
- VC工程的命令行编译法
- 回溯法_n皇后问题
- uva 10910
- struts2 18拦截器详解(十六) --- ActionMappingParametersInteceptor
- Red/System编译器实现分析(2)
- 合并K个有序链表-堆的使用
- 游戏、博彩、赚钱:三个无法割裂的话题