对于Windows在操作系统方面,注册表中保存了大量的系统配置,如常见的IE主页保存在HKEY_LOCAL_MACHINE\Software\Mircosoft\Internet Explorer\Main下的Start Page另一个例子是禁止磁盘驱动器自动运行AutoRun注册表中的功能HKEY_CURRENT_ USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer下的NoDriveTypeAutoRun设置在中间;还有很多系统配置,如图像劫持、文件关联等,可以直接在注册表中配置。
有许多常见的安全工具需要操作注册表,这里介绍通过注册表获得Windows系统启动时的启动项。在注册表的启动项目中,除了正常的系统工具和软件工具外,病毒和木马还会使用注册表的启动项目悄然跟随Windows启动和启动,从而实现自启动功能。以下是编写枚举注册表启动项目的工具,进一步学习注册表操作中使用的工具API函数的相关流程。
1. 程序界面及相关代码
注册表中有很多地方可以用来完成启动。这里只介绍注册表中许多可以完成启动的位置之一。这里的程序采用对话框的形式,界面如图1所示。
图1
在此界面中使用CListCtrl控件,用户可以添加并相应设置。这里有一个关于CListCtrl具体如下:
VOIDCManageRunDlg::InitRunList(){//设置扩展样式m_RunList.SetExtendedStyle(m_RunList.GetExtendedStyle()|LVS_EX_GRIDLINES//有网格|LVS_EX_FULLROWSELECT);///选行//在ListCtrl中插入新列m_RunList.InsertColumn(0,"NO.");m_RunList.InsertColumn(1,"键值名称");m_RunList.InsertColumn(2,"键值");/*LVSCW_AUTOSIZE_USEHEADER:列的宽度自动匹配为标题文本如果该值用于最后一列,则列宽设置为ListCtrl剩余的长度*/m_RunList.SetColumnWidth(0,LVSCW_AUTOSIZE_USEHEADER);m_RunList.SetColumnWidth(1,LVSCW_AUTOSIZE_USEHEADER);m_RunList.SetColumnWidth(2,LVSCW_AUTOSIZE_USEHEADER);}2. 启动项目枚举
这个例子主要是通过枚举注册表“HKEY_LOCAL_MACHINE\Software\Microso ft\Windows\CurrentVersion\Run”子键下的键值项可以跟随Windows启动而启动的程序。在运行软件“注册表启动项管理”之后,应显示上述注册表键位置下所有启动项的内容,其代码如下:
#defineREG_RUN"Software\\Microsoft\\Windows\\CurrentVersion\\Run\\"VOIDCManageRunDlg::ShowRunList(){//清空ListCtrl中的所有项m_RunList.DeleteAllItems();DWORDdwType=0;DWORDdwBufferSize=MAXBYTE;DWORDdwKeySize=MAXBYTE;charszValueName[MAXBYTE]={0};charszValueKey[MAXBYTE]={0};HKEYhKey=NULL;LONGlRet=RegOpenKeyEx(HKEY_LOCAL_MACHINE,REG_RUN,0,KEY_ALL_ACCESS,&hKey);if(lRet!=ERROR_SUCCESS){return;}inti=0;CStringstrTmp;while(TRUE){//枚举键项lRet=RegEnumValue(hKey,i,szValueName,&dwBufferSize,NULL,&dwType,(unsignedchar*)szValueKey,&dwKeySize);//不退出循环if(lRet==ERROR_NO_MORE_ITEMS){break;}///显示列表控件strTmp.Format("%d",i);m_RunList.InsertItem(i,strTmp);m_RunList.SetItemText(i,1,szValueName);m_RunList.SetItemText(i,2,szValueKey);ZeroMemory(szValueKey,MAXBYTE);ZeroMemory(szValueName,MAXBYTE);dwBufferSize=MAXBYTE;dwKeySize=MAXBYTE;i ;}RegCloseKey(hKey);}当显示注册表中的自启动项目时,它将不可避免地进行一定的操作或处理。对于注册表启动项目的管理,有三个常见的功能,之一个是屏蔽启动项目,然后删除启动项目,最后添加启动项目(这三个是平行关系,而不是顺序)。这里的程序只完成后两个功能,即删除启动项目和添加启动项目。删除启动项目和屏蔽启动项目之间存在差异别在于屏蔽启动项是可恢复的,而删除启动项是不可恢复的。至于屏蔽启动项,此功能将留给您。
3. 添加启动项的代码
只需跟随需要Windows启动的软件添加至“HKEY_LOCAL_MACHINE\Software\Micro soft\Windows\CurrentVersion\Run”代码如下:
voidCManageRunDlg::OnBtnAdd(){//TODO:AddyourcontrolnotificationhandlercodehereCRegAddRegAdd;RegAdd.DoModal();///判断输入是否完整if(strlen(RegAdd.m_szKeyName)>0&&strlen(RegAdd.m_szKeyValue)>0){HKEYhKey=NULL;LONGlRet=RegOpenKeyEx(HKEY_LOCAL_MACHINE,REG_RUN,0,KEY_ALL_ACCESS,&hKey);if(lRet!=ERROR_SUCCESS){return;}RegSetValueEx(hKey,RegAdd.m_szKeyName,0,REG_SZ,(constunsignedchar*)RegAdd.m_szKeyValue,strlen(RegAdd.m_szKeyValue) sizeof(char));RegCloseKey(hKey);ShowRunList();}else{AfxMessageBox("请输入完整的内容");}}在代码中,CRegAdd添加启动项对应的窗口代码如下:
voidCRegAdd::OnBtnOk(){//TODO:AddyourcontrolnotificationhandlercodehereZeroMemory(m_szKeyName,MAXBYTE);ZeroMemory(m_szKeyValue,MAX_PATH);GetDlgItemText(IDC_EDIT_KEYNAME,m_szKeyName,MAXBYTE);GetDlgItemText(IDC_EDIT_KEYVALUE,m_szKeyValue,MAX_PATH);EndDialog(0);}4. 删除启动项的代码
删除启动项的实现代码比添加启动项的代码要简单,但是在删除的时候涉及一个关于CListCtrl控件编程,即选择列表框中的启动项。这是一个编程控件的问题。在代码中获得选定的启动项后,删除它非常简单。代码如下:
voidCManageRunDlg::OnBtnDel(){//TODO:AddyourcontrolnotificationhandlercodeherePOSITIONpos=m_RunList.GetFirstSelectedItemPosition();intnSelected=-1;while(pos){nSelected=m_RunList.GetNextSelectedItem(pos);}if(-1==nSelected){AfxMessageBox("请选择要删除的启动项");return;}charszKeyName[MAXBYTE]={0};m_RunList.GetItemText(nSelected,1,szKeyName,MAXBYTE);HKEYhKey=NULL;LONGlRet=RegOpenKeyEx(HKEY_LOCAL_MACHINE,REG_RUN,0,KEY_ALL_ACCESS,&hKey);RegDeleteValue(hKey,szKeyName);RegCloseKey(hKey);ShowRunList();}对于注册表启动项的管理软件就编写到这里,大家可以将其他的可以让软件开机启动的注册表子键添加到软件中去,这样启动项管理软件就更加强大、更加完美了。但是,当不断深入对注册表的了解时,会发现更多的可以让软件随机启动的子键,这样就需要每次将新发现的子键添加到代码中,而每次改动代码是非常繁琐的。那么,有没有什么好的 *** 可以在每次添加子键的同时不改变代码本身呢?可以把要枚举的注册表子键保存到一个文件中,然后让程序去该文件中读取这些子键,最后通过API函数列举注册表。这样,每当注册表中有新的需要列举的内容时,只需修改保存注册表键的文件,而不需要修改程序本身。