日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

金山卫士开源软件之旅(十) KSafeMainproject的分析 1

發布時間:2023/12/19 综合教程 27 生活家
生活随笔 收集整理的這篇文章主要介紹了 金山卫士开源软件之旅(十) KSafeMainproject的分析 1 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

上一次看金山開源到如今已有一兩個月了。期間看到QQ群里大家對它非常是熱情。

近期有時間想看看金山的主界面projectKSafeMain,自己水平有限,總結的東西淺顯。但還是愿意拿來與大家分享。希望對大家有幫助。

轉載請標明是引用于 http://blog.csdn.net/chenyujing1234

歡迎大家提出問題討論。

1、超鏈接的增加

上圖中紅色標注的地方就是超鏈接的地方。

它的實現是在dlgfile_header.xml文件里。

eg:

求助這個button:

<link class="linktext5" pos="-238,6" href="http://www.ijinshan.com/safe/help.html?fr=client" crtext="FFFFFF">求助</link>

標紅色的部分表此控制的類型為 linktext5,它是定義在def_style.xml文件里.

通過cursor節點的屬性實現放上去有手的開關的功能。

那么是哪里調用了此文件里呢?

在bkwinres.rc2中有

即,我們把此文件定義為509了。

而在dlg_main.xml中對調用了ID為509的XML文件

2、修復漏洞的實現

2、1 界面創建方法

首先綁定dlg_main.xml里的 <tabctrl id="136"

在bkwinres.h中有

#define IDC_TAB_MAIN 136

在beikesafemaindlg.h中有

BK_NOTIFY_MAP(IDC_RICHVIEW_WIN)
//BK_NOTIFY_ID_COMMAND(IDCANCEL, OnBkBtnClose)
BK_NOTIFY_ID_COMMAND(IDC_BTN_SYS_CLOSE, OnBkBtnClose)
BK_NOTIFY_ID_COMMAND(IDC_BTN_SYS_MAX, OnBkBtnMax)
BK_NOTIFY_ID_COMMAND(IDC_BTN_SYS_MIN, OnBkBtnMin)
BK_NOTIFY_TAB_SELCHANGE(IDC_TAB_MAIN, OnBkTabMainSelChange)
BK_NOTIFY_MAP_END()

BOOL CBeikeSafeMainDlg::OnBkTabMainSelChange(int nTabItemIDOld, int nTabItemIDNew)
{

	DEBUG_TRACE(L"Tab Change %d, %d
", nTabItemIDOld, nTabItemIDNew);

	BOOL bRet = FALSE;

	if (m_bFirstPageChange)
	{
		if (0 != nTabItemIDNew)
		{
			PostMessage(MSG_APP_DELAY_EXAM, FALSE);
		}

		m_bFirstPageChange = FALSE;
	}



	bRet = TRUE;
	switch (nTabItemIDNew)
	{
	case 0:
		if (m_bPage0NeverShowed)
		{
			PostMessage(MSG_APP_DELAY_NAVIGATE_IE);
			PostMessage(MSG_APP_DELAY_EXAM, TRUE);

			m_bPage0NeverShowed = FALSE;
		}

		break;

	case 1:
		break;

	case 2:		
		break;
	case 3:    // 修復漏洞
		m_viewVulfix.ShowWindow(SW_SHOW);
		if(!m_bVulfixInited || m_bVulfixRescanRequired)
		{
			BOOL toRescan = TRUE;
			if(m_bVulfixRescanRequired && theEngine && theEngine->m_isRepairing)
			{
				toRescan = FALSE;
			}			
			m_bVulfixInited = TRUE;
			m_bVulfixRescanRequired = FALSE;
			if(toRescan)
				m_viewVulfix.m_viewSoftVul.InitEnv();
		}
		break;
	case  4://系統優化
	case  5://清理
	case  6://網盾
	case  8:// 打開軟件管理
	default:
		break;
	}

	return TRUE;
}






能夠得知近好改動漏洞后進入的case是:

case 3:

處理的第一條是 m_viewVulfix.ShowWindow(SW_SHOW);

m_viewVulfix是CBeikeSafeMainDlg中的成員:

// 修復漏洞頁面里的view
CEmbeddedViewm_viewVulfix;

CEmbeddedView也CBeikeSafeMainDlg一樣都是繼承自CBkDialogViewImpl。

每一個CBkDialogViewImpl的實例中都有三個成員,各自是m_bkHeader、m_bkBody和m_bkFooter,它們分別代表窗體的頭部、中間和底部,

它們各自界面元素的載入是在 CBkDialogViewImpl::Load 。

它的類定義非常easy:

class CEmbeddedView 
	: public CBkDialogViewImpl<CEmbeddedView>
	, public CIconAnimate<CEmbeddedView>
{
public:
	//  做漏洞掃描動作的類
	CBeikeVulfixHandler m_viewSoftVul;

那么m_viewVulfix是在哪里創建的呢?

(1) CBeikeSafeMainDlg::OnInitDialog 的一開始就初始化了這個變量
BOOL CBeikeSafeMainDlg::OnInitDialog(CWindow /*wndFocus*/, LPARAM /*lInitParam*/)
{

	SetIcon(::LoadIcon((HMODULE)&__ImageBase, MAKEINTRESOURCE(IDI_BEIKESAFE)));
	SetIcon(::LoadIcon((HMODULE)&__ImageBase, MAKEINTRESOURCE(IDI_SMALL)), FALSE);

	_Module.SetActiveWindow(m_hWnd);
	// 創建修復漏洞頁面的view
	InitVulFix();

它主要是載入界面元素,并創建list控件.

void CBeikeSafeMainDlg::InitVulFix()
{
	// 創建 m_viewVulfix 窗體
	m_viewVulfix.Create(GetViewHWND(), NULL, WS_CHILD|WS_CLIPCHILDREN, 0, 3000);
	// 從 dlg_vul_main.xml 文件里載入控件
	ATLVERIFY( m_viewVulfix.Load( IDR_BK_VULDLG_MAIN ) );
	// 設置修復漏洞處理邏輯類m_viewSoftVul的父窗體
	m_viewVulfix.m_viewSoftVul.SetMainDlg( this );
	// 創建列名為:嚴重程序、補丁名稱、補丁描寫敘述、發面日期、狀態的列表控件
	m_viewVulfix.Init(m_hWnd);
}
(2) dlg_vul_main.xml文件分析

主要分為兩大部分:

掃描或修復狀態、掃描結果.

從XML文件里能夠看到 掃描中與repairing是同一塊,臨時把repairing隱藏起來。

repairing有五個部分:

2、2 button處理函數的實現

掃描結果顯示的效果圖是:

在 case 3:的處理中顯示完界面后主要就是調用掃描漏洞的工作:

if(toRescan)
m_viewVulfix.m_viewSoftVul.InitEnv();

它主要完畢 :

初始化掃描引擎;

載入ksafevul.dll中的API函數, 創建CVulEngine中的IVulEnvironment 接口;

解發開始掃描的消息。

void CBeikeVulfixHandler::InitEnv()
{
	if(!theEngine)
	{
		// 初始化掃描引擎
		theEngine = new CVulEngine;	
		// 載入ksafevul.dll中的API函數, 創建CVulEngine中的IVulEnvironment 接口
		theEngine->_InitFunctions();

		m_WinInfo.Init();
		//m_WinInfo64 = IsWin64();
	}
	// 解發開始掃描的消息
	PostMessage( WMH_SCAN_START, 0, 0);
}
(2、2、1)非常多人反映ksafevul.dll 載入不到。此dll的得到金山是提供源代碼的。

大家能夠用VS2005打開 beikesafevul.sln

(2、2、1、1)首先編譯BeikeUtilsproject。

會出現下面報錯:

1>d:自己的經驗總結自己的經驗總結金山開源osspcmanagersrcpublishcommon/registrywow.h(18) : error C2146: 語法錯誤 : 缺少“;”(在標識符“OpenKeyEx”的前面)
1>d:自己的經驗總結自己的經驗總結金山開源osspcmanagersrcpublishcommon/registrywow.h(18) : error C4430: 缺少類型說明符 - 假定為 int。注意: C++ 不支持默認 int
1>d:自己的經驗總結自己的經驗總結金山開源osspcmanagersrcpublishcommon/registrywow.h(19) : error C4430: 缺少類型說明符 - 假定為 int。注意: C++ 不支持默認 int

解決方法請參考我的還有一篇文章:(里面有相同的出錯的處理)

金山衛士開源軟件之旅(一) VS 2005環境下編譯

(2、2、1、2) 其他的project都順利編譯通過,僅僅有兩個projectksafevul、VulfixLib出現報錯:

envutils.h(428) : error C3861: “IsWin64”: 找不到標識符

它是用來推斷系統是不是64位用的。

既然源代碼沒有提供此函數,那么我們自己來實現吧:

考慮到調用到此函數的cpp文件都包括了BeikeUtils.h文件,我決定在BeikeUtils 中加入此函數體

BeikeUtils.h中加入

// 推斷是不是64位的系統
// 返回值: TRUE 是64位系統;FALSE 不是64位系統
BOOL IsWin64();

BeikeUtils.cpp里加入

BOOL IsWin64()
{
	#define IS_64BIT_OS (sizeof(void *) == 8)
	return IS_64BIT_OS;
}

ksafevulproject編譯通過后就生成了ksafevul.dll.這樣大家就能夠調試掃描漏洞與修復漏洞的過程了。

(2、2、2) WMH_SCAN_START消息的回調函數例如以下:
void CBeikeVulfixHandler::OnBkBtnScan()
{
	if(m_firstInited)
	{
		// Clean downloaded files 
		BOOL bSave = BKSafeConfig::Get_Vulfix_SaveDownFile();
		if( !bSave )
			theEngine->m_fixLog.CleanFiles(FALSE, NULL);
		m_firstInited = FALSE;
		SetItemVisible(1015, !theEngine->IsSystemSupported());
	}
	// 把掃描結果列表清空
	ResetListCtrl(m_wndListCtrlVul);
	// 調用引擎起一線程開始掃描
	if( theEngine->ScanVul( m_RefWin.m_hWnd ) )
	{
		// 界面處理
		m_dwScanBeginTime = GetTickCount();
		m_bScanStarted = FALSE;

		m_nScanState = 0;
		m_nTotalItem = 0;
		m_nCurrentItem = 0;
		_SetDisplayState(SCANSTATE_SCANNING);
		_SetScanProgress( 0 );
		m_RefWin.SetTimer(0, 200, NULL);
		m_wndListCtrlVul.SetEmptyString(BkString::Get(IDS_VULFIX_5027));
		m_RefWin.StartIconAnimate( IDC_IMG_VULFIX_SCAN_ANIMATION, IDC_PROGRESS_VULFIX_SCANNING, 300);
		SetItemDWordAttribute(IDC_PROGRESS_VULFIX_SCANNING, "showpercent", 0);
	}
}

以上基本的工作是調用ScanVul創建一線程完畢掃描

bool CVulEngine::ScanVul(HWND hWnd)
{
	if(m_hThreadVulScan)
		_SafeTerminateThread( m_hThreadVulScan, FALSE );

	m_bVulScanCanceled = FALSE;
	m_hThreadVulScan = CreateThread(NULL, 0, ThreadFunc_Scan, (void*)hWnd, 0, NULL);
	return m_hThreadVulScan!=NULL;
}

DWORD WINAPI CVulEngine::ThreadFunc_Scan( LPVOID lpParam )
{
	HWND hWnd = (HWND)lpParam;
	theEngine->_ScanVul(hWnd);	
	return 0;
}

void CVulEngine::_ScanVul(HWND hWnd)
{
	DWORD dwFlags = _GetScanFlags();
	CWindowVulfixObserver observer( hWnd);
	if(!m_pVulScan)
		// 創建掃描組件IVulfix
		m_pVulScan = CreateVulFix();
	
	HRESULT hr = E_POINTER;
	if(m_pVulScan)
	{
		// 設計掃描組件的觀察者對象
		m_pVulScan->SetObserver(&observer);
		// 運行掃描(要持續一段時間)
		hr = m_pVulScan->Scan(dwFlags);
		DEBUG_TRACE(_T("CVulEngine::_ScanVul ScanVul %x(%x) 
"), hr, dwFlags);
		m_pVulScan->SetObserver(NULL);
	}
	// 通知掃描完畢
	_RelayMessage(hWnd, WMH_SCAN_DONE, m_bVulScanCanceled, hr);
}

(2、2、3) DLL也載入到了,為什么修復漏洞不是沒有掃描的結果呢。

我也被這個問題困擾著,從KSafeMainproject中我們僅僅能知道

hr = m_pVulScan->Scan(dwFlags);

返回了失敗.所以沒有掃描結果。

但原因是什么呢?我決定對此打破砂鍋。

(2、2、3、1)Scan的實如今VulfixLIbproject中(在上面的(2、2、1)中講到)

說是掃描,事實上是從數據庫文件 office64.dat、office.dat、soft.dat、system64.dat、system.dat中讀取漏洞列表

看到這里更堅定了我對對金山的開源的失望是對的。

//  從數據庫文件 office64.dat、office.dat、soft.dat、system64.dat、system.dat中讀取漏洞列表
HRESULT CImplVulfix::Scan(DWORD dwFlags)
{
	TIME_CHECK( _T("CImplVulfix::Scan ") );
	m_Canceled = FALSE;
	T_ComInit __init__com__;
	HRESULT hr ; 	
	do
	{
		// 把數據庫和補丁列表清除
		Reset();
		GetLangID();
		
		CSysEnv& sysEnv = singleton<CSysEnv>::Instance();
		sysEnv.Init();
		if( FAILED( hr=sysEnv.IsSupported(FALSE) ) )
			break;
		
		Init();
		m_objIgnore.LoadIgnoreDB();

		CString filenameSystem, filenameOffice, filenameSoft;
		GetXmlDBFileName(VTYPE_WINDOWS, filenameSystem, IsWin64());
		GetXmlDBFileName(VTYPE_OFFICE, filenameOffice, FALSE);
		GetXmlDBFileName(VTYPE_SOFTLEAK, filenameSoft, FALSE);
		if( !PathFileExists(filenameSystem) && !PathFileExists(filenameOffice) && !PathFileExists(filenameSoft) )
		{
			hr = KERR_LOAD_FILE;
			break;
		}
		// 創建OS Filter
		m_pFilterOS = CreateOSFilter(sysEnv.m_WinVer, dwFlags);
		// 初始化OS Filter
		InitOSFilter( m_pFilterOS, sysEnv.m_WinVer, dwFlags);
		if( m_pFilterOS->WaitComplete() )
		{
			// 設計數據庫對象的觀察者
			m_dbOS.SetObserver( m_Observer );
			m_dbOffice.SetObserver( m_Observer );
			m_dbSoft.SetObserver( m_Observer );
			m_pFilterOS->SetIIgnore( &m_objIgnore );
			
			CString filename;
			try
			{
				FixLocale();

				//BOOL bWin64 = IsWin64();
				//PVOID OldValue = NULL;
				//if(bWin64)
				//	Wow64DisableWow64FsRedirection(&OldValue);
				
				// 從data目錄里的文件加載數據庫數據
				!m_Canceled && m_dbOffice.Load( filenameOffice, m_pFilterOS, dwFlags );
				!m_Canceled && sysEnv.IsLangSupported() && sysEnv.IsOsSupported() && m_dbOS.Load( filenameSystem, m_pFilterOS, dwFlags );
				!m_Canceled && m_dbSoft.Load( filenameSoft, NULL, dwFlags);

				//if(bWin64)
				//	Wow64RevertWow64FsRedirection(OldValue);
			}
			catch (...)
			{
				hr = KERR_LOAD_FILE;
			}
			
			CSimpleArray<LPTUpdateItem> arrLeaks;
			CSimpleArray<TReplacedUpdate*> arrReplaced;		
			// 從數據庫中獲得列表 
			m_dbOS.GetUnfixedLeakList( arrLeaks, m_arrFixedVuls, m_arrInvalid, arrReplaced );
			m_dbOffice.GetUnfixedLeakList( arrLeaks, m_arrFixedVuls, m_arrInvalid, arrReplaced );

			const CSimpleArray<int> &arrExpired = m_dbOS.GetExpiredIds();
			CSimpleArray<int> arrReplacedId;
			for(int i=0; i<arrReplaced.GetSize(); ++i)
			{
				arrReplacedId.Add( arrReplaced[i]->nKBID );
			}
			
			// select soft ignored vuls 
			CSimpleArray<LPTVulSoft> arrSoftLeaks;
			m_dbSoft.GetUnfixedLeakList( arrSoftLeaks );
			for(int i=0; i<arrSoftLeaks.GetSize(); ++i)
			{
				LPTVulSoft ps = arrSoftLeaks[i];
				ps->isIgnored = m_objIgnore.IsIgnored( ps->nID );
				if( ps->isIgnored )
				{
					LPTUpdateItem pu = new TUpdateItem;
					pu->m_nType = VTYPE_SOFTLEAK;
					pu->nID = ps->nID;
					pu->strName = ps->matchedItem.strName;
					pu->strDescription = ps->strDescription;
					pu->strWebpage = ps->matchedItem.strWebpage;
					pu->nWarnLevel = ps->nLevel;
					pu->strPubdate = ps->strPubdate;

					m_arrIgnoredVuls.Add( pu );
					m_arrIgnoredVulsFromSoft.Add( pu );
				}
				else
					m_arrSoftLeaks.Add( ps );
			}
			
			// select installable, ignored , expired 
			for(int i=0; i<arrLeaks.GetSize(); ++i )
			{
				LPTUpdateItem &pi = arrLeaks[i];
				pi->isExpired = arrExpired.Find( pi->nID )!=-1;

				if(pi->isExpired)
					m_arrInvalid.Add( pi );
				else if(pi->isIgnored)
					m_arrIgnoredVuls.Add( pi );
				else
				{
					bool bReplaced = arrReplacedId.Find( pi->nID )!=-1;
					if(!bReplaced)
						m_arrLeaks.Add( pi );
				}
			}
			
			// find correct replace relationship 
			for(int i=0; i<arrReplaced.GetSize(); ++i)
			{
				TReplacedUpdate* pu = arrReplaced[i];
				BOOL bInstalled = FindArrayIndex( m_arrFixedVuls, pu->nKBID )!=-1;
				if( !bInstalled )
				{
					if( FindArrayIndex(m_arrFixedVuls, pu->nKBID2)!=-1 
						|| FindArrayIndex(m_arrLeaks, pu->nKBID2)!=-1
						|| FindArrayIndex(m_arrIgnoredVuls, pu->nKBID2)!=-1 )
						m_arrReplacedUpdates.Add( pu );
				}
			}

			// - 保存最后無漏洞時間, 使得下次不再提示有風險 
			// -- 非高速掃描的結果才有效果 
			if( RequireUsingInterface() && !(dwFlags & VULSCAN_EXPRESS_SCAN) )
			{
				BOOL hasMustLeak = FALSE;
				const CSimpleArray<LPTUpdateItem> &arrLeaks = GetResults();
				for(int i=0; i<arrLeaks.GetSize(); ++i)
				{
					if(arrLeaks[i]->nWarnLevel>0)
					{
						hasMustLeak = TRUE;
						break;
					}
				}
				CString strVal;
				if(!hasMustLeak)
				{
					T_Date date;
					GetLatestPackgeDate(date.nYear, date.nMonth, date.nDay);
					strVal.Format(_T("%04d-%02d-%02d"), date.nYear, date.nMonth, date.nDay);
				}
				WriteVulConfig(_T("VulScan"), _T("LastSafePkgDate"), strVal);
			}			
		}
		
		hr = KERR_NONE;
	} while (FALSE);
	return hr;
}

(2、2、3、2) 僅僅須要把數據庫文件拷到KSafeMainproject文件夾下就可以得到掃描結果。

圖一中的整個目錄data拷到圖二中就可以

圖一:

圖二:

總結

以上是生活随笔為你收集整理的金山卫士开源软件之旅(十) KSafeMainproject的分析 1的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。