首页 > 逆向调试 > 系统即时调试器注册表设置

系统即时调试器注册表设置

最近几天比较闲,于是想扩展一下原来写的PE工具,发现那个太差了,不好意思拿出手,所以现在又模仿了PETools的一些功能。今天做了一下那个调试功能:把选中的进程附加到系统的即时调试器。

一开始我以为是要用DebugActiveProcess这个API来附加到进程,后来发现DebugActiveProcess这个API是用来将自己附加到指定进程。也就是说,如果你自己是调试器,去调用DebugActiveProcess才有意义。于是就不知道该怎么办了。后来,用OD简单分析了一下PETools的这个功能,大概是这样一个步骤。
首先是获取系统即时调试器的路径,假定为szDebuggerPath,然后取得目标进程PID,然后生成这样一个命令行参数:szDebuggerPath -p PID。如:

"C:\Program Files\Microsoft Visual Studio\Common\MSDev98\Bin\msdev.exe" -p 1234

然后,用CreateProcess函数来执行这个参数。dwCreationFlags指定为CREATE_NEW_CONSOLE。MSDN这么解释这个参数:
The new process has a new console, instead of inheriting its parent’s console (the default). For more information, see Creation of a Console.

0041F5A3    55              PUSH EBP
0041F5A4    8BEC            MOV EBP,ESP
0041F5A6    81EC 60020000   SUB ESP,260
0041F5AC    53              PUSH EBX
0041F5AD    8365 FC 00      AND DWORD PTR SS:[EBP-4],0
0041F5B1    56              PUSH ESI
0041F5B2    8B35 10144000   MOV ESI,DWORD PTR DS:[<&USER32.MessageBo>; user32.MessageBoxA
0041F5B8    BB 88154000     MOV EBX,00401588                         ; pe tools v1.5.800.2006 rc7
0041F5BD    6A 34           PUSH 34
0041F5BF    53              PUSH EBX
0041F5C0    68 F8454000     PUSH 004045F8                            ; 警告: 调试进程的话可能会导致丢失数据.\n你确认要用调试器附加进程吗?
0041F5C5    FF75 08         PUSH DWORD PTR SS:[EBP+8]
0041F5C8    FFD6            CALL ESI
0041F5CA    83F8 06         CMP EAX,6
0041F5CD    74 07           JE SHORT 0041F5D6
0041F5CF    33C0            XOR EAX,EAX
0041F5D1    E9 93000000     JMP 0041F669
0041F5D6    57              PUSH EDI
0041F5D7    8D85 A0FDFFFF   LEA EAX,DWORD PTR SS:[EBP-260]
0041F5DD    FF75 0C         PUSH DWORD PTR SS:[EBP+C]
0041F5E0    FF35 288D4300   PUSH DWORD PTR DS:[438D28]
0041F5E6    68 EC454000     PUSH 004045EC                            ; %s -p %ld
0041F5EB    50              PUSH EAX
0041F5EC    FF15 14144000   CALL DWORD PTR DS:[<&USER32.wsprintfA>]  ; user32.wsprintfA
0041F5F2    83C4 10         ADD ESP,10
0041F5F5    33C0            XOR EAX,EAX
0041F5F7    8D7D AC         LEA EDI,DWORD PTR SS:[EBP-54]
0041F5FA    C745 A8 4400000>MOV DWORD PTR SS:[EBP-58],44
0041F601    6A 10           PUSH 10
0041F603    59              POP ECX
0041F604    F3:AB           REP STOS DWORD PTR ES:[EDI]
0041F606    33C9            XOR ECX,ECX
0041F608    8D7D F0         LEA EDI,DWORD PTR SS:[EBP-10]
0041F60B    894D EC         MOV DWORD PTR SS:[EBP-14],ECX
0041F60E    AB              STOS DWORD PTR ES:[EDI]
0041F60F    AB              STOS DWORD PTR ES:[EDI]
0041F610    AB              STOS DWORD PTR ES:[EDI]
0041F611    8D45 EC         LEA EAX,DWORD PTR SS:[EBP-14]
0041F614    50              PUSH EAX                                 ; 1
0041F615    8D45 A8         LEA EAX,DWORD PTR SS:[EBP-58]
0041F618    50              PUSH EAX                                 ; 2
0041F619    51              PUSH ECX                                 ; 3
0041F61A    51              PUSH ECX                                 ; 4
0041F61B    6A 10           PUSH 10                                  ; 5
0041F61D    51              PUSH ECX                                 ; 6
0041F61E    51              PUSH ECX                                 ; 7
0041F61F    8D85 A0FDFFFF   LEA EAX,DWORD PTR SS:[EBP-260]
0041F625    51              PUSH ECX                                 ; 8
0041F626    50              PUSH EAX                                 ; 9
0041F627    51              PUSH ECX                                 ; 10
0041F628    FF15 F8114000   CALL DWORD PTR DS:[<&KERNEL32.CreateProc>; kernel32.CreateProcessA
0041F62E    85C0            TEST EAX,EAX
0041F630    75 0B           JNZ SHORT 0041F63D
0041F632    FF15 34114000   CALL DWORD PTR DS:[<&KERNEL32.GetLastErr>; ntdll.RtlGetLastWin32Error
0041F638    8945 FC         MOV DWORD PTR SS:[EBP-4],EAX
0041F63B    EB 10           JMP SHORT 0041F64D
0041F63D    FF75 F0         PUSH DWORD PTR SS:[EBP-10]
0041F640    8B3D F4114000   MOV EDI,DWORD PTR DS:[<&KERNEL32.CloseHa>; kernel32.CloseHandle
0041F646    FFD7            CALL EDI
0041F648    FF75 EC         PUSH DWORD PTR SS:[EBP-14]
0041F64B    FFD7            CALL EDI
0041F64D    837D FC 00      CMP DWORD PTR SS:[EBP-4],0
0041F651    5F              POP EDI
0041F652    74 12           JE SHORT 0041F666
0041F654    6A 10           PUSH 10
0041F656    53              PUSH EBX
0041F657    68 CC454000     PUSH 004045CC                            ; 无法附加调试器 !!!
0041F65C    FF75 08         PUSH DWORD PTR SS:[EBP+8]
0041F65F    FFD6            CALL ESI
0041F661  ^ E9 69FFFFFF     JMP 0041F5CF
0041F666    6A 01           PUSH 1
0041F668    58              POP EAX
0041F669    5E              POP ESI
0041F66A    5B              POP EBX
0041F66B    C9              LEAVE
0041F66C    C3              RETN

那么,如何来获取即时调试器的路径呢?在OD里面没有找到。但是OD有一个功能,就是“选项”->“即时调试器”菜单设置可以把OD自己设置为即时调试器。记得在某书上提及过这个信息存放在注册表里面(书名忘了),那就用RegMon监控一下吧。

最后得出结果,信息存放于HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug下面的Debugger。里面还有几个参数,简单处理一下就OK了。下面是我的一段代码:(获取即时调试器代码就自己DIY吧)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
// 将指定进程附加到即时调试器
// Author: 代码疯子
// Blog: http://www.programlife.net/
void CKsPeToolDlg::OnDebugProcess()
{
	// TODO: 在此添加命令处理程序代码
	DWORD dwRow = m_lsProcess.GetNextItem(-1, LVNI_SELECTED);
	DWORD dwMsgRes = MessageBox(
		TEXT("警告: 调试进程的话可能会导致丢失数据.\r\n")
		TEXT("你确认要用调试器调试附加进程吗?"),
		TEXT("调试进程"),
		MB_YESNO | MB_DEFBUTTON2 | MB_ICONWARNING);
	if (dwMsgRes == IDYES)
	{
		CString szPid = m_lsProcess.GetItemText(dwRow, 1);
		TCHAR szPath[MAX_PATH + 20];
		TCHAR szDebugPath[MAX_PATH];
		DWORD dwPid = _tstoi(szPid.GetBuffer(szPid.GetLength()));
		GetDebuggerPath(szDebugPath, sizeof(szDebugPath));
		wsprintf(szPath, TEXT("%s -p %d"), szDebugPath, dwPid);
 
		STARTUPINFO StartupInfo = {0};
		StartupInfo.cb = sizeof(STARTUPINFO);
		PROCESS_INFORMATION ProcessInfo = {0};
		BOOL bResult = CreateProcess(
			NULL,
			szPath,
			NULL,
			NULL,
			FALSE,
			CREATE_NEW_CONSOLE,
			NULL,
			NULL,
			&StartupInfo,
			&ProcessInfo);
		if (bResult)
		{
			CloseHandle(ProcessInfo.hThread);
			CloseHandle(ProcessInfo.hProcess);
		}
		else
		{
			MessageBox(TEXT("无法载入调试器!"), TEXT("错误提示"), 
				MB_ICONWARNING);
		}
	}
}

几个截图:简单模仿一下PETools的一些功能:
简单模仿PETools功能
调试时给一个警告提示:
调试警告提示
附加到即时调试器:
附加到即时调试器——VC6


觉得文章还不错?点击此处对作者进行打赏!


本文地址: 程序人生 >> 系统即时调试器注册表设置
作者:代码疯子(Wins0n) 本站内容如无声明均属原创,转载请保留作者信息与原文链接,谢谢!


更多



分类: 逆向调试 标签: , ,
  1. 本文目前尚无任何评论.