系统安全:注册表

 

注册表(Registry),用于存储系统和应用的设置信息,简单来说它就是一个专门存储此类信息的数据库。这不太相同于我们经常接触的DBMS,但将其与一般的DB相类比,是有助于理解的。

 

注册表出现开始,只是一个简单的小文件。在windowns 3操作系统中称为reg.dat,用于存放某些文件类型的应用程序关联,而大部分的设置信息放在了win.ini,system.ini等初始化.ini文件中。

 

随着系统需求的升级,设置信息的维护和管理变得越来越复杂,而且如果.ini文件被破坏,系统的正常启动也会受到阻碍,到了让人无法忍受的地步。也因此,出现了渐渐发展到现在的注册表。

 

注册表是windows的一个核心数据库,存放着各种参数,直接控制着windowns的启动、硬件驱动程序的装载以及一些windows应用程序的运行。

 

举个实际例子,你现在的默认浏览器,以及浏览器的主页设置。都会存到注册表中,换句话说,如果我修改了你的注册表相应的信息,那你的默认浏览器,及默认主页都会被修改。

 

这篇文章,我们来通过python3简单地对注册表进行操作,来实现一些有趣的东西。

 

首先,手动打开查看注册表的方法。win + R,运行regedit(registry edit),就可以打开注册表编辑器。

 

    

 

左边的五个称为“根键”,根键下层键称为“子键”。当你选中某个键的时候,在右侧就会显示出来对应的键值,可以理解成我们熟悉的key-value。键值由名称,类型和数据组成。(这里的“键值”也是一个完整的键,他也有key【名称】和value【数据】)

 

我们拿上面浏览器的默认主页为例,寻找HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main,点击查看它的键值:

 

其中有一项Start Page:

 

可以很清晰的看到了,我的IE浏览器的主页是three six zero的。

 

我们放下主页先不谈,返回来说“根键”,如上显示总共有五种。

 

HKEY_CLASSES_ROOT,包含windows中使用的程序与扩展名的连接信息,以及COM类注册信息。

HKEY_CURRENT_USER,当前登录用户设置信息。

HKEY_LOCAL_MACHINE,包含硬件、软件相关所有内容,也包含硬件以及驱动硬件所需的驱动程序信息。

HKEY_USERS,包含current user中的所有设置信息、桌面设置信息,以及网络连接信息。

HKEY_CURRENT_CONFIG,收集程序运行所需信息。

 

在此中,我们会来一起玩两个实例,来了解对注册表的基本操作。

 

首先,第一个例子,读取计算机浏览器的浏览记录。

 

不管是你上铺还是下铺的兄弟,大晚上打开电脑偷偷盯着屏幕痴笑的人都很可疑。你有想知道他在看什么吗?

 

IE浏览器的浏览记录,在注册表中的位置是:HKEY_CURRENT_USER\SOFTWARE\Microsoft\Internet Explorer\TypedUrls。(除了IE外,其他浏览器的浏览记录存放点不同,可以对应的去查询。)

 

先手动打开来看下:

 

(还好没什么不好的浏览记录.......虚惊一场)

                                       

 

那现在就来看看怎么用代码把它弄出来吧。

 

python 标准库winreg(windows registry),python2中是_winreg。

 

打开python IDLE,按F1键。打开python文档,搜索winreg。

 

 

先看他的第一段介绍。

 

These functions expose the Windows registry API to Python. Instead of using an integer as the registry handle, a handle object is used to ensure that the handles are closed correctly, even if the programmer neglects to explicitly close them.

Changed in version 3.3: Several functions in this module used to raise a WindowsError, which is now an alias of OSError.

 

这些方法将windows注册表API暴露给python,用句柄对象代替integer数字作为注册表句柄来确保句柄能够正确的关闭,即使程序没有直接关闭他们。(即使程序忽视了直接了当清楚的关闭他们。)

 

3.3的更改:此模块中的几个抛出WindowsError错误的方法,现在取别名OSError。

 

我这里不是机器翻译的哈,纯人工,就当学英语了。

 

为什么要看这段话呢?因为里面有个名词,“句柄”。我解释不好,大家可以去搜索搜索,简单了解下。

 

我的泛泛理解,你可以把它当成指针,或者说地址,他就是一个对象的标识。你想得到它的信息,甚至修改或者删除它,首先要拿到他的句柄handle。

 

内存中,数据的地址是一直变化的,那我们需要的时候怎么找到它呢?这就不需要你自己去找了,只要有他的句柄,我们就能间接的对它进行处理。

 

这之中,我们先来看最基本的第一个函数:

 

两个方法的区别不知,估计不大,不然也不会如此心胸开阔的写在一起。

 

我们看到方法returning a handle object,返回一个句柄对象。

 

没错,我们就通过openkey来得到操作句柄,看参数key是之前已打开的键,或者是“根键”其中之一。sub_key是所打开子键的字符串,reserved是个整数,还必须是0,我们就不管了。access是对这个键的访问权限,图中例子参数的默认值KEY_READ,对此权限打开的键,只能读取,不能修改。至于权限的类型,在文档的下面部分也有涉及:

实现的功能不同,所需权限也不同,当然all access就是给所有权限了。

 

方法如果失败,会抛出OSError。

 

所以,对于我们当前要实现对TypedUrls键的读取,获取句柄的代码应该是这样的(只是进行简单的读取操作,后面两个默认参数不管了):

handle = winreg.OpenKey(winreg.HKEY_CURRENT_USER, r"SOFTWARE\Microsoft\Internet Explorer\TypedUrls")

 

读取怎么办呢?下一个方法:

看方法名字也就知道了,枚举value值。参数key是已打开的键,或者是预定义的根键。我们读取的是已经打开的TypedUrls键的值,也因此这里的key就是我们上面刚刚得到的handle。index是一个标识所检索value值的下标。

 

这个函数的返回是一个元组tuple,有三部分

0,value值的名称,string类型。

1,value值,类型由value值本身的类型决定。

2,value值的类型,是一个整数。

 

这里的整数并不是说注册表值的类型是一个整数,注册表值的type有很多,例如我们当前url的类型:

    

SZ,它就是字符串类型。而在winreg这个模块中用一个整数代表SZ。(第三个返回值就是这个意思)

 

对于值的类型,文档中也有提及:

 

只要和value值对应上就没有什么问题。

 

方法了解后,开始读取数据,这时问题来了,参数index指明下标,也就是说EnumValue只能得到一条数据,怎么全读取出来呢?那就循环吧。for index in range(1024),多写点。

 

万一没有那么多数据呢?他就会抛出那个OSError,我们特殊处理一下就完了。

 

try:
    for i in range(1024):
        print(winreg.EnumValue(handle, i))
except OSError:
    print("That's all")
winreg.CloseKey(handle)

结束后调用CloseKey()关闭句柄(忘记也没关系,最开始我们就了解了,程序忽视了close也能正确的关闭,这是handle object的功劳)。

 

也可以直接调用句柄的Close()方法关掉,如handle.Close()。(一样的)

 

运行看看:

 

我们看到返回的tuple分别是,名称,值,以及值的类型。(winreg模块中SZ类型用1代表。)

 

完整代码:

import winreg

handle = winreg.OpenKey(winreg.HKEY_CURRENT_USER, r"SOFTWARE\Microsoft\Internet Explorer\TypedUrls")
##The result is a tuple of 3 items:
##0 A string that identifies the value name
##1 An object that holds the value data, and whose type depends on the underlying
##registry type
##2 An integer that identifies the type of the value data
try:
    for i in range(1024):
        print(winreg.EnumValue(handle, i))
except OSError:
    print("That's all")
winreg.CloseKey(handle)

 

第二个例子,关闭计算机防火墙。这个就麻烦一些,如果上面的例子涉及到查询,此例子就是更新了。

 

防火墙的设置键路径:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy

 

我们关注其中的两项,就分别对应于两个网络的防火墙。

 

我们以StandardProfile为例,首先获得句柄,可以用上面的OpenKey,完全没问题,access注意修改。这里我们看另一个函数,CreateKey:

CreateKey创建或者打开指定键,返回句柄。我们可以通过它来添加自己的注册表,如果键存在,CreateKey效果就和Open的效果一样了。

 

还有一个CreateKey的扩展:

无太大差别,只是在access参数的指定上。默认是WRITE写权限,这和Open不同(只读)。

 

我们来看StandarProfile的值,EnableFireWall为1,是开启状态。换句话说,我们将其改成0,就达到了关闭防火墙的目的。

 

首先,获取句柄:

handle = winreg.CreateKey(winreg.HKEY_LOCAL_MACHINE, subKey)

 

怎样修改它的值呢?

 

参数说明:

key无需多提,就是上面刚刚得到的handle。sub_key是欲修改值的键名(string),也就是“EnableFirewall”。值的类型type要和实际对应REG_QWORD(64位数字),最后value就是修改后的值了。

                       

                                       

这里问题来了,我们看到setvalue的value参数是一个string。不对啊,我们先来看setvalue的扩展,然后再来说他们的区别。

 

看第一句:将数据存储进打开的注册表键的value字段里面。这个才是我们想要的功能啊,那上面那个setvalue呢?

 

setvalue的功能要上一级,它是给子键赋值的。换句话说,如果用setvalue,就会在“standarprofile”的下层出现一个名为“EnableFirewall”的子键。

                                                     

 

OK,知道了区别,我们也就选好了方法,要用SetValueEx函数。value参数的值要和实际对应,当然也要和type参数对应。

 

完整代码:

subKey =r"SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile"
#Firewall running when off is 1
off = 0
handle = winreg.CreateKey(winreg.HKEY_LOCAL_MACHINE, subKey)
winreg.SetValueEx(handle, "EnableFirewall", 0, winreg.REG_QWORD, off)
winreg.CloseKey(handle)

 

这里运行需要管理员权限运行。如果不是exe程序,你可以先用管理员权限运行IDLE再通过IDLE运行它。运行成功后,你就可以打开注册表,看看有没有改变。

 

会发现,注册表已经改变了,但是计算机的防火墙还是开着。

 

 

这是为什么呢?

 

我们最开始说过,计算机在启动的时候,一些配置信息从注册表中读取出来,然后进行相应的操作。防火墙的状态就是其中一项,计算机读取出来Enable为1,所以你的防火墙才会开启。

 

那怎样让他起作用呢?

 

对,当计算机下次启动后,防火墙就处于关闭状态了,然而计算机用户并不知道。这时候,偷偷关闭你防火墙的那个家伙就能悄悄摸摸的侵入,搜集你的信息。

 

对于数据库的操作,如果我们掌握了增删改查四个基本的操作,也就基本上能够得到大多数想要的数据,无非方法笨点,多写几条语句。

 

除去上面的两个例子,我们还有一个操作没有涉及到,Delete删除。现在就来:

没什么特殊说的,注意文档中异常上面那句话——“这个方法不能删除拥有子键的键”。

 

我们还是拿最开始的浏览记录说明好了。

    

 

我们就来删除url26这条信息。

 

NO BB, SHOW CODE:

handle = winreg.OpenKey(winreg.HKEY_CURRENT_USER, r"SOFTWARE\Microsoft\Internet Explorer\TypedUrls", reserved=0, access=winreg.KEY_ALL_ACCESS)
winreg.DeleteValue(handle, "url26")
winreg.CloseKey(handle)

运行完之后,你再看。

 

最后,当程序运行出现【拒绝访问】的错误,首先看access参数的设定,二来确定程序运行的权限,也就是说是否是管理员权限运行的。如果还是不行,最终要确定,计算机登录的当前用户是否有权限执行此操作。(这也是为什么要控制计算机需要先获得权限,控制的越全面,需要的权限也就越高的原因所在。)

 

完。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值