首页
社区
课程
招聘
[原创]开机启动之注册表
2021-2-15 20:35 8662

[原创]开机启动之注册表

2021-2-15 20:35
8662

原理 

病毒就是一般程序,在入侵别人计算机后,如果不运行,就没有任何意义。为了能让病毒程序能够随计算机开机启动,今天就来介绍一下通过注册表实现开机启动任意程序。首先,介绍一下注册表。


注册表就像windows系统中的一个数据库,保存着系统的各种配置。比如:开机的启动方式,各种后缀名文件的默认图标显示,禁用USB端口等,这些功能的实现都可以通过注册表实现设置。

有关注册表的介绍可以参见以下教程:

https://www.freebuf.com/articles/system/256130.html

https://www.freebuf.com/articles/es/198440.html


本文的重点来了,利用注册表启动的原理:windows提供了专门的开机自启动注册表。在每次开机完成后,计算机会自动遍历自启动注册表下的键值,获取键值中的程序路径,并创建进程启动程序。所以,要想修改注册表实现开机自启动,就需要在这个注册表键值下写入我们想要启动的程序的所在路径。


有两个比较常用的实现开机自启动的注册表键值如下:

HKEY_CURRENT_USER\Software\Mircosoft\Windows\CurrentVersion\Run

HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run


主要就是根键不相同。当然了,还有一个不常用的:

HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunOnce


如果在这个键值下写入程序路径,系统会在下次开机后自启动一次。

我们可以通过API编程在以上三个注册表键下写入要启动的程序路径即可实现开机自启动。


还有一种比较隐蔽的启动方式,实现思路是通过程序启动时加载调试器,而调试器的加载可以通过设置注册表实现,其实质就是在键值下写入调试器的所在路径,而我们可以在这里写入任何程序的路径,已实现启动目的。而这个键就是:

HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options


如需要调试notepad.exe,就可以在Image File Execution Options创建子健notepad.exe,在该子健下创建名为“Debugger”的键名,键值为要启动的程序路径名(可以为调试器也可以为任意程序)。


身为萌新,在实验这个方法时第一次并没有成功。失败原因就是键名必须为“Debugger”,不能自定义名称。而且在网上查资料才发现这个方法有一个高大上的名字叫做映像劫持。


相关API介绍

//打开指定的注册表键
LSTATUS RegOpenKeyExA(
  HKEY   hKey,		//打开的注册表键的句柄,或者是五个根键(详见函数结尾)
  LPCSTR lpSubKey,	//指向子健的名称,例如:Software\Mircosoft\Windows\CurrentVersion\Run
  DWORD  ulOptions, //一般设置为0
  REGSAM samDesired,//设定访问权限标记(详见五个根键下面)
  PHKEY  phkResult  //打开注册表键的句柄,如果不再使用返回的句柄,则调用RegCloseKey来关闭它
);

//函数返回值
//如果函数返回成功,则返回零(ERROR_SUCCESS)。否则,返回值为内文件WINERROR.H定义的一个非零的错误代码。

//五个根键
//HKEY_CLASSES_ROOT 
//HKEY_CURRENT_CONFIG 
//HKEY_CURRENT_USER 
//HKEY_LOCAL_MACHINE 
//HKEY_USERS

//访问权限标志(这里只列举常见的几个,详细参考MSDN)
//编号       值										含义
// 1      KEY_CREATE_LINK							准许生成符号键
// 2      KEY_CREATE_SUB_KEY						准许生成子健
// 3      KEY_ENUMERATE_SUB_KEYS					准许生成枚举子健
// 4      KEY_EXECUTE								准许进行读操作
// 5      KEY_NOTIFY								准许更换通告
// 6      KEY_QUERY_VALUE							准许查询子健
// 7      KEY_READ								编号3,5,6的组和
// 8      KEY_SET_VALUE                           准许设置子健的数值
// 9      KEY_WRITE  								编号2,8的组合
// 10		KEY_ALL_ACCESS							提供完全访问,编号1,2,3,5,6,8的组合
// 11      KEY_WOW64_32KEY							表示64位Windows系统中的应用程序应该在32位注册表视图上运行。32位Windows操作系统会忽略该标志
// 12      KEY_WOW64_64KEY							表示64位Windows系统的应用程序应该在64位注册表视图上运行。32位Windows上忽略该标志
//在注册表项下设置指定值的数据和类型
LSTATUS RegSetValueExA(
  HKEY       hKey,			//指定一个已打开项的句柄,或一个标准项名
  LPCSTR     lpValueName,	//一个要设置的键值名称。若该名称的值并不存在于指定的注册表中,则此函数会将其加入到该项。如果此时是NULL或指向空字符串,则此函数将会设置该项的默认值或未命名的类型和数据
  DWORD      Reserved,		//保留值,必须设置为0
  DWORD      dwType,		//存储的数据类型
  const BYTE *lpData,		//指向一个缓冲区,该缓冲区包含了为指定值名称存储的数据
  DWORD      cbData			//指定由lpData参数所指向的数据大小,单位是字节
);

//返回值
//返回零表示成功;返回其他任何值都代表一个错误代码

//dwType表示的数据类型
//值										含义
//REG_BINARY								任何形式的二进制数据
//REG_DWORD								一个32位的数字
//REG_DWORD_LITTLE_ENDIAN					        一个格式为“低字节在前”的32位数字
//REG_DWORD_BIG_ENDIAN						        一个格式为“高字节在前”的32位数字
//REG_EXPAND_SZ								一个以0结尾的字符串,该字符串包含环境变量(如%PAHT%)
//EG_LINK								一个Unicode格式的带符号链接
//REG_MULTI_SZ								一个以0结尾的字符串数组,该数组以连续两个0作为终止符
//REG_ONE								未定义值类型
//REG_RESOURCE_LIST							一个设备驱动器资源列表
//REG_SZ								一个以0结尾的字符串
//创建一个子健
LSTATUS RegCreateKeyExA(
  HKEY                        hKey,				//打开的键的句柄或者五个根键
  LPCSTR                      lpSubKey,				//要创建的子健的名称
  DWORD                       Reserved,				//系统保留必须为0
  LPSTR                       lpClass,				//子健类名一般设置为NULL
  DWORD                       dwOptions,			//创建子键时的选项,通常情况下使用REG_OPTION_NON_VOLATILE宏,表示创建的子键被创建到注册表文件中,不会因为重启计算机而丢失
  REGSAM                      samDesired,			//设定访问权限标记
  const LPSECURITY_ATTRIBUTES lpSecurityAttributes,	        //设置安全属性,一般使用NULL
  PHKEY                       phkResult,			//打开注册表键的句柄,如果不再使用返回的句柄,则调用RegCloseKey来关闭它
  LPDWORD                     lpdwDisposition		        //指向DWORD的指针,该变量接收两种值,详见函数尾部(注意这是一个输出参数)
);

//返回值
//返回零表示成功;返回其他任何值都代表一个错误代码

//lpdwDisposition
//值					含义
//REG_CREATED_NEW_KEY		键之前不存在也没有被创建
//REG_OPENED_EXISTING_KEY	键之前存在并且打开后没有被改变

小例子

开机启动计算器

	//打开注册表
	if (result = RegOpenKeyEx(HKEY_CURRENT_USER,L"Software\\Microsoft\\Windows\\CurrentVersion\\Run" , 0,KEY_WRITE, &hKey))
	{
		printf("RegOpenKeyEx Error");
		return 0;
	}
	//修改注册表值,实现开机自启动
	if (ERROR_SUCCESS != RegSetValueEx(hKey,(LPCTSTR)ValueName,0,REG_SZ,(BYTE*)FileName,lstrlen((LPCTSTR)FileName)*2+1))
	{
		RegCloseKey(hKey);
		printf("RegSetValueEx Error");
		return 0;
	}

        //注意事项:在打开注册表键时一定要注意路径的设置,不要出现拼写错误,注意Unicode编码

使用映像劫持的方法在启动记事本,记事本不会启动而是启动的计算器

	TCHAR FileName[] = L"C:\\Windows\\System32\\calc.exe";
	TCHAR ValueName[] = L"Debugger";

	HKEY notepadKey = 0;
	int result = 1;
	DWORD dw = 0;
	if (result = RegCreateKeyEx(HKEY_LOCAL_MACHINE,L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\notepad.exe",0,NULL,REG_OPTION_NON_VOLATILE, KEY_WOW64_64KEY | KEY_ALL_ACCESS,NULL,&notepadKey,&dw))
	{
		printf("RegCreateKeyEx");
		return 0;
	}
	if (result = RegSetValueEx(notepadKey, (LPCTSTR)ValueName, 0, REG_SZ, (BYTE*)FileName, lstrlen((LPCTSTR)FileName) * 2 + 1))
	{
		RegCloseKey(notepadKey);
		printf("RegSetValueEx Error");
		return 0;
	}
        //注意事项:在创建子健时,注意注册表重定位问题。
        //SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\notepad.exe
        //上面的路径会被重定位为下面的路径
        //SOFTWARE\\WOW6432Node\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\notepad.exe
        //为了避免重定位可以在创建子健函数的访问标记参数中添加KEY_WOW64_64KEY访问标志

注意

最后注意一点,在成功编写好程序后,发现注册表没有写入对应的项不要奇怪,可以刷新一下注册表或者关闭后重新打开,可能就有了。或者可能就是注册表重定位问题。

在使用映像劫持的代码时,运行后杀毒软件会弹框。


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
点赞5
打赏
分享
最新回复 (9)
雪    币: 201
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
jinthree 2021-2-22 08:52
2
0
请问有些病毒对注册表加密修改IE主页,用搜索找不到内容,有什么好办法吗?
雪    币: 4427
活跃值: (2154)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
miaostart 2021-2-22 09:30
3
0
学习了,谢谢分享!
雪    币: 1807
活跃值: (676)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
君行早 2021-2-22 09:39
4
0
学习了,谢谢分享!
雪    币: 27
活跃值: (127)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Xenophon 2021-2-22 19:25
5
0
这都是基本知识。你的例子在 RegSetValueEx 成功时没调用 RegCloseKey,存在资源泄漏。
雪    币: 4781
活跃值: (3014)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
SAO 2021-2-23 12:07
6
0
Xenophon 这都是基本知识。你的例子在 RegSetValueEx 成功时没调用 RegCloseKey,存在资源泄漏。
谢谢提醒,是这样的,写的有些匆忙了
雪    币: 4781
活跃值: (3014)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
SAO 2021-2-23 12:49
7
0
jinthree 请问有些病毒对注册表加密修改IE主页,用搜索找不到内容,有什么好办法吗?
一般修改主页都是安装了某种软件。你可以在安装前做一个注册表备份,然后再安装软件,使用一款regshot工具可以拍摄注册表快照,进行对比安装软件前后注册表有什么变化
这是我的想法,学习阶段希望能帮到你
雪    币: 32182
活跃值: (7105)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
ninebell 2021-3-2 09:12
8
0
对于会调试的和编程懂原理的,基本上分析下就能找到了。。。隐蔽性待加强。
雪    币: 2927
活跃值: (2530)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
caocaofff 2021-3-2 11:03
9
0
楼主说的确实是最基础的注册表位置,还有计划任务、服务、驱动、自启动目录等很多手段呢
雪    币: 32182
活跃值: (7105)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
ninebell 2021-3-4 07:07
10
0
注册表工具多了去了,快照的,提权的,对比的,拦截的,手里就有几十个。
游客
登录 | 注册 方可回帖
返回