首页
社区
课程
招聘
读[加密解密三]补丁篇的利用ntdll.ntcontinue做跳板 有问题 求解!
发表于: 2011-5-22 03:25 4490

读[加密解密三]补丁篇的利用ntdll.ntcontinue做跳板 有问题 求解!

2011-5-22 03:25
4490
有问题的地方用红色标注了!

/*******************************************************
 /* 《加密与解密》第三版配套实例
 /* 18.2.3 利用调试寄存器机制
 /* 	       2.利用ntdll.ntcontinue作为跳板
 /* 
 /*  Code by 罗  翼 2004
 /*  Modified by kanxue 2008
 /* (c)  看雪软件安全网站 www.pediy.com 2000-2008
********************************************************/
#include <windows.h>

#define BREAK_ENTRYPOINT 0x401000          //程序入口点
#define BREAK_POINT1     0x040138D          //需要中断的地址
#define SZFILENAME       ".\\TraceMe_asp.exe"  //目标文件名

	
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    PSTR szCmdLine, int iCmdShow)
{		
	
	STARTUPINFO				si ;
	PROCESS_INFORMATION		pi ;
	ZeroMemory(&si, sizeof(STARTUPINFO)) ;
	ZeroMemory(&pi, sizeof(PROCESS_INFORMATION)) ;
	si.cb = sizeof(STARTUPINFO) ;
	
	BOOL	WhileDoFlag=TRUE;
	BYTE    ReadBuffer[MAX_PATH]={0};
	
	
	if( !CreateProcess(SZFILENAME, 
        NULL, 
        NULL,  
        NULL,  
        FALSE,   
        DEBUG_PROCESS|DEBUG_ONLY_THIS_PROCESS, 
        NULL,          
        NULL,          
        &si,            
        &pi )        
		) 
	{
        MessageBox(NULL, "CreateProcess Failed.", "ERROR", MB_OK); 
        return FALSE; 
    } 
	
	DEBUG_EVENT		DBEvent ;
	CONTEXT			Regs ;
	DWORD			dwState, dwBpCnt, dwSSCnt, dwAddrProc ;
	
	dwBpCnt = dwSSCnt = 0 ;

	Regs.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS ;
	
	while (WhileDoFlag) {
		WaitForDebugEvent (&DBEvent, INFINITE);
		dwState = DBG_EXCEPTION_NOT_HANDLED ;
		switch (DBEvent.dwDebugEventCode)
		{
		case	EXCEPTION_DEBUG_EVENT:
			switch (DBEvent.u.Exception.ExceptionRecord.ExceptionCode)
			{
			case	EXCEPTION_BREAKPOINT:
				{
					++dwBpCnt ;
					if (dwBpCnt == 1)
					{
						//通过dwBPCnt计数器判断出接收到的是第一个调试信息。
						//得到ntdll.ntContinue的地址,并且设置Dr0 的值等于该地址
						GetThreadContext(pi.hThread, &Regs) ;
						Regs.Dr0 = (DWORD)(GetProcAddress(GetModuleHandle("ntdll.dll"), "NtContinue") );
						Regs.Dr7 = 0x101 ;
						SetThreadContext(pi.hThread, &Regs) ;
						dwState = DBG_CONTINUE ;
					}
					break ;
				}
			case	EXCEPTION_SINGLE_STEP :
				{
					++dwSSCnt ;
					if (dwSSCnt == 1)
					{
						//当收到第一个EXCEPTION_SINGLE_STEP异常信号,表示中断在ntdll.ntContinue函数
						//把Dr0设置成程序的入口地址
						
						GetThreadContext(pi.hThread, &Regs) ;
						Regs.Dr0 = Regs.Dr7 = 0 ;
						SetThreadContext(pi.hThread, &Regs) ;
						
						ReadProcessMemory(pi.hProcess, (LPCVOID)(Regs.Esp+4), &dwAddrProc, sizeof(DWORD), NULL) ;
[COLOR="Red"]						ReadProcessMemory(pi.hProcess, (LPCVOID)dwAddrProc, &Regs, sizeof(CONTEXT), NULL) ;//这里为什么 [esp+4] 会指向一个 CONTEXT 结构体啊?[/COLOR]						
						Regs.Dr0 = BREAK_ENTRYPOINT ;
						Regs.Dr7 = 0x101 ;
						
						WriteProcessMemory(pi.hProcess, (LPVOID)dwAddrProc, &Regs, sizeof(CONTEXT), NULL) ;
						
						dwState = DBG_CONTINUE ;
					}
					else if (dwSSCnt == 2)
					{   //第二次中断在起先设置的入口点,在BREAK_POINT1处设置硬件断点
						
						GetThreadContext(pi.hThread, &Regs) ;
						Regs.Dr0 = BREAK_POINT1;
						Regs.Dr7 = 0x101 ;
						SetThreadContext(pi.hThread, &Regs) ;
						dwState = DBG_CONTINUE ;
					}
					else if (dwSSCnt == 3)
					{
						//第三次中断,己到指定的地址,读取EBP寄存器指向的内存数据
						GetThreadContext(pi.hThread, &Regs) ;
						Regs.Dr0 = Regs.Dr7 = 0 ;
						//WriteProcessMemory(pi.hProcess, (LPVOID)Regs.Eip,&WriteData, 2,NULL);	//打补丁
						ReadProcessMemory(pi.hProcess, (LPCVOID)(Regs.Ebp), &ReadBuffer, sizeof(ReadBuffer), NULL) ;
						MessageBox (0, (char *)ReadBuffer, "test", MB_OK);						
						SetThreadContext(pi.hThread, &Regs) ;
						dwState = DBG_CONTINUE ;
					}
					break ;
				}				 
			}
			break ;

		case	EXIT_PROCESS_DEBUG_EVENT :
				WhileDoFlag=FALSE;
				break ;
		}
		
		ContinueDebugEvent(pi.dwProcessId, pi.dwThreadId, dwState) ;
	} //.end while
	
	CloseHandle(pi.hProcess) ;
	CloseHandle(pi.hThread)  ;
	return TRUE;
}

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (2)
雪    币: 234
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
基础知识

一byte为4个二进制位
esp为堆栈指针

所以:

出栈一个esp+4
入栈一个esp-4
2011-5-22 09:48
0
雪    币: 248
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
原来是堆栈。
看来得补补这方面的知识了。
谢楼上!
2011-5-22 10:15
0
游客
登录 | 注册 方可回帖
返回
//