探索黑客技术攻防,实战研究与安全创新

导航菜单

编写Windows系统锁屏图片更改工具

之前美化Windows系统,在更改屏幕锁定图片的时候,发现每次手动更改比较麻烦,并且发现其中原理也非常简单,所用到的技术也清晰明了:对注册表的操作,突破权限复制文件,调用系统函数锁屏和简单的MFC界面操作,于是索性写个小软件,以后再用的时候方便,我的系统是win7系统,在其上可以使用。原理浅析我们从网上可以看到一些方法介绍,首先我们要修改注册表,注册表是MicrosoftWindows用于存储系统和应用程序的设置信息的一个重要的数据库。进入注册表:


HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows/CurrentVersion/Authentication/LogonUI/Background

看是否有OEMBackground这个键,没有就新建,数据类型为REG_DWORD,将其值设置为1,然后选择图片,命名为backgroundDefault.jpg放置在C:\Windows\System32\oobe\info\backgrounds目录下。如果没有这个目录就新建,然后把图片复制过去。

最后检查一下计算机配置-管理模块-系统-登录模块是否始终选择自定义登录背景,没有的话就勾选上,然后就可以了。原理就是这样了,我们可以猜到在代码中我们要对注册表进行操作,对文件目录操作,由于是系统目录,还需要突破系统权限。还需要调用系统函数,来进行锁屏测试,下面是代码的详细说明。代码解析我们先说说选择图像目录的功能,选择图像目录我们可以调用CFileDialog类,在这个类中我们可以使用GetPathName()等函数来获取所选图片的路径,继而自己写个函数来获取它的文件名,路径等信息。

核心代码如下:


CFileDialogccFileDlg(TRUE,NULL,NULL,
OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT|OFN_ALLOWMULTISELECT,
_T("Imagefiles(*.png;*.jpg)|*.png;*.jpg|Allfiles(*.*)|*.*||"),NULL);
if(ccFileDlg.DoModal()==IDOK)
{
CStringstrPathName=ccFileDlg.GetPathName();
CStringstrDir=strPathName.Left(strPathName.ReverseFind('\\'));
strPathName.Replace("\\","\\\\");
CStrings=GetFileName(strPathName);
CopyFile(strPathName,"C:\\backgroundDefault.jpg",false);
SHFILEOPSTRUCTfileop;
fileop.hwnd=this->m_hWnd;
fileop.wFunc=FO_COPY;//拷贝
fileop.pFrom="C:\\backgroundDefault.jpg";//从哪里拷贝
fileop.pTo=
"C:\\Windows\\System32\\oobe\\info\\backgrounds\\backgroundDefault.jpg";//拷贝到哪里
fileop.fFlags=FOF_NOCONFIRMMKDIR;//FOF_SILENT;
SHFileOperation(&fileop);//执行
AfxMessageBox("图片选择成功!");
}

经过测试,如果用copyfile函数来直接将文件复制到windows目录下,虽然不会有错误信息,但是文件不能被复制过去,这与系统目录的权限保护有关,那么我们如何突破呢?经过测试,在Windows的shellapi文件中定义了一个名为SHFileOperation()的外壳函数,用它可以实现各种文件操作,并且不会因为权限限制而复制不过去。

而这里我是先把任何名字的图片复制到C盘目录下,自动重命名为backgroundDefault,而如果先重命名的话,若再次选通目录下的图片重命名会有冲突问题,所有copyfile第三个参数设为false,这样自动覆盖就没有了这个冲突,然后再把C盘目录下的文件复制到指定目录下。接下来是对注册表的操作,对注册表的打开、删除、查询、新建、设置等都有对应的windowsAPI,下面是核心代码,看看函数名也知道是对应干什么的了:


LONGRegOpenKeyEx(
HKEYhKey,//需要打开的主键的名称
LPCTSTRlpSubKey,//需要打开的子键的名称
DWORDulOptions,//保留,设为0
REGSAMsamDesired,//安全访问标记,也就是权限
PHKEYphkResult//得到的将要打开键的句柄
);
LONGRegSetValueEx(
HKEYhKey,
LPCTSTRlpValueName,
DWORDReserved,
DWORDdwType,
CONSTBYTE*lpData,
DWORDcbData
);
核心代码如下:
LONG
HKEY
lRetCode,mRetCode,nRetCode;
hKey1,hKey;
DWORD
dwDisposition;
char*b=(LPSTR)(LPCTSTR)"OEMBackground";
LONG
lRetCode1;
lRetCode1=RegOpenKeyEx(HKEY_LOCAL_MACHINE,
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Authentication\\LogonUI\\Backgr
ound",
0,
KEY_SET_VALUE|KEY_WOW64_64KEY,&hKey1);
if(lRetCode1!=ERROR_SUCCESS){
AfxMessageBox(_T("子键不存在,正在创建!"));
mRetCode=RegCreateKeyEx(HKEY_LOCAL_MACHINE,
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Authentication\\LogonUI\\Background",0,
b,REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS,
NULL,&hKey1,&dwDisposition);
if(mRetCode!=ERROR_SUCCESS)
{
AfxMessageBox(_T("创建失败!"));return;}
}
DWORDdwData;
dwData=1;
DWORDdwSize=sizeof(DWORD);
nRetCode=RegSetValueEx(hKey1,"OEMBackground",0,REG_DWORD,(LPBYTE)
&dwData,dwSize);
if(nRetCode!=ERROR_SUCCESS)
{
AfxMessageBox(_T("修改失败!"));
return;
}


else{MessageBox("操作完成!注意图像大小必须大于等于屏幕大小,程序不提供图像扩放功能!");}GetDlgItem(IDC_BUTTON3)->EnableWindow(true);这里注意RegOpenKeyEx里要加入KEY_WOW64_64KEY来指出是32位操作系统还是64位操作系统,这样写入注册表不会出错,否则会因为重定向问题而不能向注册表内写入值,即使最后RegSetValueEx()函数返回的值为0。接着执行锁屏测试的代码只需要一行,非常好懂:system("rundll32.exeuser32.dll,LockWorkStation");而MFC界面设计与美化之类的没什么技术含量,就不多讲了,所有的核心代码就是这些了。测试截图打开软件界面

图片1.png

点击选择目录按钮,选择要更换的图片,,因为已经存在,所以会有如图提示,接着会出现所示的提示。接着我们打开注册表可以看到一开始所指定键值为0,我们要将其修改为1,点击修改按钮

图片2.png

接着点击锁屏测试,会调用系统函数,来执行锁屏功能,我们就可以看到自己所更改的锁屏图片的效果了。

经过测试,本程序可以实现Win7系统的锁屏图片更改,通过这次MFC编程写了一个小的软件,其意义不仅是方便了操作,更重要的是在于温习了一些编程技术,温故而知新。