Пример #1
0
int _tmain(int argc, _TCHAR* argv[])
{
	if( argc<2 ) {
		Usage();
		return 1;
	}

	if( 0 == strncmp(argv[1], "-g", 2)  )
	{
		// generate test files and registry values
		return Generate();
	}
	else if( 0 == strncmp(argv[1], "-c", 2) )
	{
		// check generated files
		return Check();
	}
	else if( 0 == strncmp(argv[1], "-s", 2) )
	{
		//
		return ShowRegValue();
	}
	else if( 0 == strncmp(argv[1], "-d", 2) )
	{
		return DeleteValue();
	}
	else
	{
		Usage();
		return 1;
	}

	return 0;
}
BOOL CHandleException::HandleInt3Exception()//处理INT3异常
{
    BOOL                    bRet;
    CCPointInfo             tempPointInfo;
    CCPointInfo*            pResultPointInfo = NULL;
    char                    CodeBuf[24] = {0};
    /*
    过滤初始断点,当新进程的初始线程在自己的上下文中初始化时,作为进程初始化的一个步骤,
    ntdll.dll中的LdrpInitializeProcess函数会检查正在初始化的进程是否处于被调试状态(检查
    PEB的BeingDebugged字段),如果是,他会调用DbgBreakPoint()触发一个断点异常,
    目的是中断到调试器,称为初始断点。
    */
    //先过掉系统的INT3断点
    if (m_IsSystemInt3 == TRUE)
    {
        m_IsSystemInt3 = FALSE;
        return TRUE;
    }

    //程序刚启动,停在OEP处
    if(m_DbgInfo.ExceptionRecord.ExceptionAddress == m_lpOepAddr
            && m_bIsStart == TRUE)
    {
        m_bIsStart = FALSE;
        //枚举目标进程的模块,并写入 g_DllList
        EnumDestMod();
    }

    memset(&tempPointInfo, 0, sizeof(CCPointInfo));
    tempPointInfo.lpPointAddr = m_DbgInfo.ExceptionRecord.ExceptionAddress;
    tempPointInfo.ptType = ORD_POINT;

    if(!FindPointInList(tempPointInfo, &pResultPointInfo, TRUE))
    {
        //没有找到对应断点,则说明不是用户或者调试器的断点
        //返回FALSE,调试器不处理,交给系统继续分派异常
        return FALSE;
    }
    else    //找到了断点
    {
        ShowBreakPointInfo(pResultPointInfo);
        BOOL bRet = WriteProcessMemory(m_hProcess, //写回原来的字节
                                       m_pFindPoint->lpPointAddr,
                                       &(m_pFindPoint->u.chOldByte), 1, NULL);

        if (bRet == FALSE)
        {
            printf("WriteProcessMemory error!\r\n");
            return FALSE;
        }
        //获取当前线程的Context
        UpdateContextFromThread();
        //0xcc 向前减去
        m_Context.Eip--;
        m_Eip = (LPVOID)m_Context.Eip;

        if (m_pFindPoint->isOnlyOne == TRUE)    //是一次性断点
        {
            g_ptList.remove(m_pFindPoint);
            delete m_pFindPoint;
            m_pFindPoint = nullptr;
        }

        //
        else //不是一次性断点,就会是用户设置的断点,
            //需要设置单步,被调试进程再运行就会触发单步异常,到单步中异常中去处理,
        {
            //设置单步#define TF 0x100 标志寄存器TF位
            m_Context.EFlags |= TF;
            m_isNeedResetPoint = TRUE;   //
        }
    }

    //更新线程的Context
    UpdateContextToThread();

    //是否是单步记录模式,Trace功能
    if (m_isStepRecordMode == TRUE)
    {
        bRet = ReadProcessMemory(m_hProcess, (LPVOID)m_Context.Eip, CodeBuf, 24, NULL);
        if (bRet == FALSE)
        {
            printf("ReadProcessMemory error!");
            return FALSE;
        }
        //记录指令
        RecordCode(m_Context.Eip, CodeBuf);
        return TRUE;
    }

    //显示反汇编代码
    m_lpDisAsmAddr = m_DbgInfo.ExceptionRecord.ExceptionAddress;
    ShowAsmCode();
    ShowRegValue(NULL);

    //等待用户输入
    bRet = FALSE;
    while (bRet == FALSE)
    {
        bRet = WaitForUserInput();
    }
    return TRUE;
}
BOOL CHandleException::HandleAccessException()//处理访问异常部分  内存断点
{
    BOOL                    bRet;
    DWORD                   dwAccessAddr;       //读写地址
    DWORD                   dwAccessFlag;       //读写标志
    BOOL                    isExceptionFromMemPoint = FALSE;    //异常是否由内存断点设置引起,默认为否
    CCPointInfo*            pPointInfo = NULL;                  //命中的断点
    BOOL                    isHitMemPoint = FALSE;

    //EXCEPTION_ACCESS_VIOLATION
    //If this value is zero, the thread attempted to read the inaccessible data.
    //If this value is 1, the thread attempted to write to an inaccessible address.
    //If this value is 8, the thread causes a user-mode data execution prevention (DEP) violation.

    dwAccessFlag = m_DbgInfo.ExceptionRecord.ExceptionInformation[0];
    dwAccessAddr = m_DbgInfo.ExceptionRecord.ExceptionInformation[1];
    //根据 访问地址 到“断点-分页表”中去查找
    //同一个内存分页可能有多个断点
    //如果没有在“断点-分页表”中查找到,则说明这个异常不是断点引起的
    list<CCPointPage*>::iterator it = g_PointPageList.begin();
    int nSize = g_PointPageList.size();

    //遍历链表中每个节点,将每个匹配的“断点-分页记录”都添加到g_ResetMemBp链表中
    for ( int i = 0; i < nSize; i++ )
    {
        CCPointPage* pPointPage = *it;
        //如果在“断点-分页表”中查找到
        //再根据断点表中信息判断是否符合用户所下断点信息
        if (pPointPage->dwPageAddr == (dwAccessAddr & 0xfffff000))//判断触发异常的地址在不在断点表中
        {
            CCResetMemBp *p = new CCResetMemBp;
            p->dwAddr = pPointPage->dwPageAddr;
            p->nID = pPointPage->nPtNum;
            g_ResetMemBp.push_back(p);

            //暂时恢复内存页原来的属性
            BOOL bDoOnce = FALSE;
            if (!bDoOnce)
            {
                //这些操作只需要执行一次
                bDoOnce = TRUE;
                isExceptionFromMemPoint = TRUE;
                TempResumePageProp(pPointPage->dwPageAddr); //暂时恢复页面属性
                //设置单步,在单步中将断点设回
                UpdateContextFromThread();
                m_Context.EFlags |= TF;
                UpdateContextToThread();
            }

            //先找到断点序号对应的断点
            list<CCPointInfo*>::iterator it2 = g_ptList.begin();
            for ( int j = 0; j < g_ptList.size(); j++ )
            {
                pPointInfo = *it2;
                if (pPointInfo->nPtNum == pPointPage->nPtNum)
                {
                    break;
                }
                it2++;
            }

            //再判断是否符合用户所下断点信息,断点类型和断点范围均相符
            if (isHitMemPoint == FALSE)
            {
                if (dwAccessAddr >= (DWORD)pPointInfo->lpPointAddr &&
                        dwAccessAddr < (DWORD)pPointInfo->lpPointAddr +
                        pPointInfo->dwPointLen)
                {
                    if ( pPointInfo->ptAccess == ACCESS ||
                            (pPointInfo->ptAccess == WRITE && dwAccessFlag == 1) )
                    {
                        isHitMemPoint = TRUE;
                        //                             break;
                    }
                }
            }
        }
        it++;
    }

    //如果异常不是由内存断点设置引起,则调试器不处理
    if (isExceptionFromMemPoint == FALSE)
    {
        return FALSE;
    }

    //如果命中内存断点,则暂停,显示相关信息并等待用户输入
    if (isHitMemPoint)
    {
        ShowBreakPointInfo(pPointInfo);
        //显示反汇编代码
        m_lpDisAsmAddr = m_DbgInfo.ExceptionRecord.ExceptionAddress;
        ShowAsmCode();
        ShowRegValue(NULL);

        //等待用户输入
        bRet = FALSE;
        while (bRet == FALSE)
        {
            bRet = WaitForUserInput();
        }
    }
    return TRUE;
}
Пример #4
0
int Generate()
{
	char sBuf[255];
	DWORD dwSize;
	HANDLE hFile = NULL;
	BOOL fReturnValue;

	const char szxReplacedFile[] = "c:\\testFileIsReplaced";
	const char szxMovedFileWithRepl[] = "c:\\testFileShouldBeMovedW";
	const char szxMovedFile[] = "c:\\testFileShouldBeMoved";
	const char szxNewMovedFile[] = "c:\\testFileIsMoved";
	const char szxDeletedFile[] = "c:\\testFileShouldBeDeleted";

	memset(sBuf, 0xaa, sizeof(sBuf));

	// create the first file for moving
	hFile = CreateFile(
		szxMovedFile,
		FILE_ALL_ACCESS,
		0,
		NULL,
		CREATE_ALWAYS,
		FILE_ATTRIBUTE_NORMAL,
		NULL);
	if(NULL == hFile) {
		printf("Can't create the %s file, err=%ld \n", szxMovedFile, GetLastError());
		return 1;
	}
	WriteFile(hFile, sBuf, sizeof(sBuf), &dwSize, NULL);
	CloseHandle(hFile);

	// create the second file for removing
	hFile = CreateFile(
		szxDeletedFile,
		FILE_ALL_ACCESS,
		0,
		NULL,
		CREATE_ALWAYS,
		FILE_ATTRIBUTE_NORMAL,
		NULL);
	if(NULL == hFile) {
		printf("Can't create the %s file, err=%ld \n", szxDeletedFile, GetLastError());
		return 1;
	}
	WriteFile(hFile, sBuf, sizeof(sBuf), &dwSize, NULL);
	CloseHandle(hFile);

	hFile = CreateFile(
		szxReplacedFile,
		FILE_ALL_ACCESS,
		0,
		NULL,
		CREATE_ALWAYS,
		FILE_ATTRIBUTE_NORMAL,
		NULL);
	if(NULL == hFile) {
		printf("Can't create the %s file, err=%ld \n", szxReplacedFile, GetLastError());
		return 1;
	}
	WriteFile(hFile, sBuf, sizeof(sBuf), &dwSize, NULL);
	CloseHandle(hFile);


	hFile = CreateFile(
		szxMovedFileWithRepl,
		FILE_ALL_ACCESS,
		0,
		NULL,
		CREATE_ALWAYS,
		FILE_ATTRIBUTE_NORMAL,
		NULL);
	if(NULL == hFile) {
		printf("Can't create the %s file, err=%ld \n", szxMovedFileWithRepl, GetLastError());
		return 1;
	}
	WriteFile(hFile, sBuf, sizeof(sBuf), &dwSize, NULL);
	CloseHandle(hFile);


	fReturnValue = MoveFileEx(
		szxDeletedFile,
		NULL,
		MOVEFILE_DELAY_UNTIL_REBOOT);
	if( !fReturnValue ) {
		printf("Can't move the %s file, err=%ld \n", szxDeletedFile, GetLastError());
		return 1;
	}

	ShowRegValue();

	fReturnValue = MoveFileEx(
		szxMovedFile,
		szxNewMovedFile,
		MOVEFILE_DELAY_UNTIL_REBOOT);
	if( !fReturnValue ) {
		printf("Can't move the %s file, err=%ld \n", szxMovedFile, GetLastError());
		return 1;
	}

	ShowRegValue();

	fReturnValue = MoveFileEx(
		szxMovedFileWithRepl,
		szxReplacedFile,
		MOVEFILE_DELAY_UNTIL_REBOOT|MOVEFILE_REPLACE_EXISTING);
	if( !fReturnValue ) {
		printf("Can't move the %s file, err=%ld \n", szxMovedFileWithRepl, GetLastError());
		return 1;
	}

	ShowRegValue();

	return 0;
}