注册表编程

木马编程DIY之注册表管理 .九九重阳了,再发篇文章,意思意思..........木马编程DIY之注册表管理   文/图 冷风 前几期分别讨论了,系统服务,文件传输,网络文本语音和其它方面的内容,现在我们来讨论在木马中注册表的实现,就我自己感觉在木马中对注册表的使用并不多,写其它程序时反倒用的不少.不过注册表还是比较重要的学会它不会吃亏呵呵,我们自己实现的效果如图所示一些基础开始前先了解一些基础知识,对后 阅读详情

一、注册表基础

1.1注册表历史背景

什么是注册表?我们可以把注册表理解成一种数据库,里面保存着各种数据,如:系统的配置信息,桌面环境,系统软件,IE浏览器等等软件的信息。在微软以前发布的操作系统中(如windows 3.X),把这些信息保存在System.ini,Win.ini等文件中,随着数据量越来越大,越来越复杂,这样ini文件难以胜任,从windows 95开始引入注册表来保存这些复杂的,海量的数据,总之我们权且把它当着一个数据库吧。

1.2注册表作用

注册表的用处一下也说不全,我作为一个程序员,站在程序员的角度来讲讲吧。对我来讲,注册表最直接的用处,就是用来保存一些配置信息,如开发的桌面软件,一定会有些配置数据需要保存,那么我们可以像Windows早期版本那个,保存在ini文件中,不过ini文件容易被人修改。如果保存在注册表中,稍稍保密些,一般使用者也不懂得怎么改。注册表另外一个常用功能是,修改其他软件的配置信息,如浏览器的个性设置,电脑桌面的主题设置,光标配置等,不过这些对开发人员来讲,好像意义不是很大,修改别人的软件配置干什么,是吧?如果你是黑客那就另当别论了。

注册表还保存着硬件的一些驱动相关信息,如COM口的数据,串口通信编程时,你是不是会为判断PC机是否有串口驱动而烦恼呀,不知道PC机上的串口逻辑号是多少很烦心呢?其实这些数据在注册表里都有,到注册表里一查就清楚了,关于如何判断PC机串口是否正常,PC现在有串口逻辑号是多少的相关技术,在本人博文《串口通信编程--多线程异步方式》里有详细的介绍,还有代码参考。

用注册表保存配置信息,那么我们得先大体认识一下注册表的组成与架构,然后再介绍一下如何创建,查询,修改注册表。

 

1.3注册表结构

        打开注册表:可能通过控制面板打开,也有很多其他途径能打开,本人常用方法是在【开始】菜单中选择【运行】命令,然后在框中输入命令regedit,如图:

然后点【确定】按钮,将会打开注册表,如图:

从图中可看出,注册表是层叠式构架的,左边的树形列表,第一级有5个根键,点开第一级接着有第二级,第三级等等,这叫项,也就是说,根键下面的是项,而项下面如果还有子级那叫子项,直到最后一级如图中路径”HKEY_CURRENT_CONFIG\SOFTWARE\FONTS”,其中Fonts是Software的子项,Fonts是最后一级,它没有子项了,再Fonts下面就是值项了,在右边一栏,值项由名称,类型,数据组成,值项就是最终保存具体数据的地方。

        所以说,注册表由:键----项----子项----值项构成,而值项由:名称,类型,数据组成,其中名称就不用说了,数据也不用说了,说说类型吧,类型是指数据的类型,数据的类型有很多种,从其他资料中切个图吧,更直观:

看到没,乱糟糟的一堆,总之对一般程序员来说,我们别管那么多,把它们分成两在类:数值型与字符型,数值型分整型与二进制型,其中整形有4字节8字节等,还分高位在前还是低位在前呢,反正自己看了,一看就懂,我也就不多说了。字符串也更不多说了,自己看一下就懂了。

        总结一下,注册表与根键、项(子项)、值项组成,根键与项是用来区别层次关系的,不具体存储数据,项下面有子项的同时还可以有值项。值项是具体存储数据的,形式是:名称、类型、值。先把这种关系捋顺了,下面看起来就容易了。

1.4各根键主要存储的信息

Ø HKEY_CLASSES_ROOT

定义了系统中所有文件类型标志和基本操作标志

Ø HKEY_CURRENT_USER

当前用户的配置信息,包括环境变量、桌面设置、网络连接,软件运行信息等

Ø HKEY_LOCAL_MACHINE

本机相关的系统信息,包括硬件信息,驱动信息,内存数据,总线数据等等。

Ø HKEY_USER

所有用户的信息。

Ø KKEY_CURRENT_CONFIG

本地计算机启动时配置的相关信息,如环境信息,桌面主题,背景色之类。

 

1.5手动操作注册表

        打开注册表编辑器:【开始】菜单选择运行命令,输入regedit,【确定】,打开注册表编辑器,你可以在上面创建,修改,删除,还有查找等等操作。都是可视化操作,自己动手操作一下就懂,不赘述。

 

二、注册表编程

本章介绍注册表的创建、修改、查询等知识。通过低层的API实现。

2.1相关函数分类

        关于注册表的函数可大致分为:项管理类,值项管理类,杖举类,实用类,安全类。项管理与值项管理不言而喻是对项与值项的增删改查操作的。杖举是对项与值项数据进行分析查找。实用类是远程操作的,操作远程计算机的注册表。安全类主要是对注册表的安全信息操作。常用的是项管理,值项管理与杖举这三类。后面我们也介绍这三类。其他的不深究,如果想了解的,可以联系我,我有相关电子档书籍。

2.2项管理函数

        很多书籍中分项,还有子项,弄得一头雾水,其实子项是相对而言的,有父项才有子项之说,所以说子项也是项,子项也可能是某项的父项,这个概念要搞清楚。

        项管理函数是对项(子项)的创建、打开、关闭、删除的几个操作,分4个函数,下面一一介绍。

2.2.1项创建函数

RegCreateKeyEx与RegCreateKey,后者请不要再用,win32以后版本都用前者。此函数的功能是在指定项下建一子项。

LONG WINAPI RegCreateKeyEx(

 __in       HKEY hKey,

 __in       LPCTSTR lpSubKey,

 __reserved DWORD Reserved,

 __in_opt   LPTSTR lpClass,

 __in       DWORD dwOptions,

 __in       REGSAM samDesired,

 __in_opt   LPSECURITY_ATTRIBUTES lpSecurityAttributes,

 __out      PHKEY phkResult,

 __out_opt  LPDWORD lpdwDisposition

);

hKey父项:打开的句柄,表明在此项下建立子项,也可以是五个(大多数windows版本是五个,也有六个的)根键之一,就是以下常量:

HKEY_CLASSES_ROOT    

HKEY_CURRENT_USER    

HKEY_LOCAL_MACHINE   

HKEY_USERS           

HKEY_CURRENT_CONFIG  

lpSubKey子项名称:你要创建的子项,接在父项下,如:” REGTEST\\GPS设备网络通道\\”.

Reserved:必须为0

lpClass:建议为NULL

dwOptions:标志创建的注册表保存在文件中还是内存中

一般取值REG_OPTION_NON_VOLATILE更多信息请查MSDN              

samDesired:访问权限,有读、写、查询等等,取KEY_ALL_ACCESS全部权限即可

lpSecurityAttributes:安全属性,不知道怎么设置,取NULL即可

phkResult:创建成功后,返回的新项的句柄

lpdwDisposition:返回状态描述,有两种状态,项原来存在|

项是新建的(REG_CREATED_NEW_KEY|REG_OPENED_EXISTING_KEY)

返回值:成功返回ERROR_SUCCESS

以下是伪代码:

HKEY hKey;

DWORD dw;

if(ERROR_SUCCESS == RegCreateKeyEx(HKEY_CURRENT_CONFIG,

" REGTEST\\GPS设备网络通道\\", 0,

NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS,

NULL, &hKey, &dw))

AfxMessageBox (_T(“创建成功”));

效果切图:

2.2.2项打开函数

        RegOpenKeyEx打开一个注册表项,语法定义如下:

LONG WINAPI RegOpenKeyEx(

 __in       HKEY hKey,   //可以是根键,也可以是打开的项

 __in_opt   LPCTSTR lpSubKey,//需要打开的子项名称

 __reserved DWORD ulOptions,//同上

 __in       REGSAM samDesired,//访问权限,同上

 __out      PHKEY phkResult//打开成功后,返回项的句柄

);

以下库伪代码:

HKEY hKey;

if(ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_CONFIG,

        " REGTEST\\GPS设备网络通道\\", 0, KEY_ALL_ACCESS, &hKey))

        AfxMessageBox(_T("打开成功"));

2.2.3项关闭函数

        RegCloseKey这个就太简单了,只有一个参数,就是关闭打开的项

LONG WINAPI RegCloseKey(

 __in HKEY hKey//传入一个打开的项的句柄

);

伪代码:

HKEY hKey;

if(ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_CONFIG,

        " REGTEST\\GPS设备网络通道\\", 0, KEY_ALL_ACCESS, &hKey)){

        if (ERROR_SUCCESS == RegCloseKey(hKey))

                  AfxMessageBox(_T("关闭成功"));

}

2.2.4项删除函数

        RegDeleteKey这个函数也简单,形参只须传入根健与子项路径即可:

LONG WINAPI RegDeleteKey(

 __in HKEY hKey,

 __in LPCTSTR lpSubKey

);

伪代码:

HKEY hKey;

if(ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_CONFIG,

        " REGTEST\\GPS设备网络通道\\", 0, KEY_ALL_ACCESS, &hKey)){

        if (ERROR_SUCCESS == RegCloseKey(hKey))

                  AfxMessageBox(_T("关闭成功"));

}

效果切图(已删除):

 

2.3值项管理函数

        值项管理函数是对注册表中的值项进行设置(增加)、查询、删除操作,一共介绍三个函数,分别是设置值、查询值、删除值。

2.3.1值设置函数

        以下为函数原型:

LONG WINAPI RegSetValueEx(

 __in    HKEY hKey, //已打开注册表项的句柄

 __in_opt  LPCTSTR lpValueName,//值项名称

 __reserved DWORD Reserved,//保留,为0

 __in    DWORD dwType,  //值项类型,前面介绍过,有整形,字符串等

 __in    const BYTE *lpData,//存放值项的值的指针,全部转换成PBYTE

 __in    DWORD cbData      //值项大小(字节)

);

以下是伪代码:

HKEY hKey;

if(ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_CONFIG,

        " REGTEST\\GPS设备网络通道\\", 0, KEY_ALL_ACCESS, &hKey)){

        DWORD nType = REG_SZ;

        char szName[] = {"我叫小王"};

        RegSetValueEx(hKey, "Name", 0, nType, (const PBYTE)szName, strlen(szName));

        nType = REG_DWORD;

        DWORD nYears = 60;

        RegSetValueEx(hKey, "Years", 0, nType, (const PBYTE)&nYears, 4);

}

效果切图:

从图中可看出,增加了两个值项,一个是字符串型,一个是整形。

 

2.3.2值查询函数

        查询打开的项的值项,函数是RegQueryValueEx,以下为函数原型:

LONG WINAPI RegQueryValueEx(

 __in        HKEY hKey,//打开项的句柄

 __in_opt    LPCTSTR lpValueName,//值项名

 __reserved  LPDWORD lpReserved,//保留,为0

 __out_opt   LPDWORD lpType,  //返回值项的值类型,如果不关心值项类型,可谓NULL

 __out_opt   LPBYTE lpData,           //装值的BUFF

 __inout_opt LPDWORD lpcbData //BUFF的长度,同时返回取得数据的长度

);

以下为伪代码:

HKEY hKey;

if(ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_CONFIG,

        " REGTEST\\GPS设备网络通道\\", 0, KEY_ALL_ACCESS, &hKey)){

        DWORD nType = 0, nLen = 100;

        char szName[100];

        RegQueryValueEx(hKey, "Name", 0, &nType, (const PBYTE)szName, &nLen);

        nType = 0;

        DWORD nYears = 0; nLen = 4;

        RegQueryValueEx(hKey, "Years", 0, &nType, (const PBYTE)&nYears, &nLen);

        int i = 0;

}

2.3.3值项删除函数

        删除打开的项的值项,首先得打开值项所属的项,然后删除值,函数原型如下:

LONG WINAPI RegDeleteValue(

 __in     HKEY hKey, //打开的项的句柄

 __in_opt LPCTSTR lpValueName//值项名字

);

以下为伪代码:

HKEY hKey;

if(ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_CONFIG,

        " REGTEST\\GPS设备网络通道\\", 0, KEY_ALL_ACCESS, &hKey)){

        RegDeleteValue(hKey, "Name");

        RegDeleteValue(hKey, "Years");

}

效果切图:

 

2.4注册表遍历

        对注册表进行查找,项、子项、值项进行分析、提取数据等操作。一般有五个函数,下面一一介绍。

2.4.1枚举子项

        该函数功能是枚举注册表中指定项的子项,提取子项信息,如子项名,修改时间,子项类型等,一次取一个,函数原型如下:

LONG WINAPI RegEnumKeyEx(

 __in HKEY hKey, //已打开的项句柄,必须有KEY_ENUMERATE_SUB_KEYS权限,

//同时也可以是几大根键值:

//HKEY_CLASSES_ROOT

//HKEY_CURRENT_CONFIG

//HKEY_CURRENT_USER

//HKEY_LOCAL_MACHINE

//HKEY_USERS

 __in DWORD dwIndex, //子项序号,第一次调用可为0,如果序号溢出将返回259号错误

 __out LPTSTR lpName, //返回子项名称的buff

 __inout      LPDWORD lpcName,//lpName的容量,函数返回后,返回lpname内容字节

 __reserved  LPDWORD lpReserved,//保留,为NULL

 __inout     LPTSTR lpClass,//返回子项类型,可以为NULL

 __inout_opt LPDWORD lpcClass,//lpClass容量,可以为NULL,同时返回装载的字节数

 __out_opt   PFILETIME lpftLastWriteTime//返回子项最后修改时间,可以为NULL

);

以下为伪代码:

char szKeyName[100]; memset(szKeyName, 0, 100);

char szClass[100]; memset(szClass, 0, 100);

HKEY hKey; long nErr = 0;

DWORD nNameLen = 100, nClassLen = 100;

FILETIME timeFile;

if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_CONFIG, " REGTEST",

0, KEY_ALL_ACCESS/*KEY_ENUMERATE_SUB_KEYS*/, &hKey)) {

                  if (ERROR_SUCCESS == (nErr = RegEnumKeyEx(HKEY_CURRENT_CONFIG/*hKey*/,

0, szKeyName, &nNameLen, NULL, szClass, &nClassLen, &timeFile)))

                           AfxMessageBox(szKeyName);

}

 

 

2.4.2枚举值项

        此函数是提取指定值项(通过序号指定)的信息,如:值,值项类型,值项名称等。

LONG WINAPI RegEnumValue(

 __in   HKEY hKey, //已打开的项句柄,必须有KEY_QUERY_VALUE权限,

//同时也可以是几大根键值:

//HKEY_CLASSES_ROOT

//HKEY_CURRENT_CONFIG

//HKEY_CURRENT_USER

//HKEY_LOCAL_MACHINE

//HKEY_USERS

 __in DWORD dwIndex, //值项序号,第一次调用可为0,如果序号溢出将返回259号错误

 __out LPTSTR lpValueName,//装值项名的buff

 __inout     LPDWORD lpcchValueName,//前一个参数的容量,同时返回其长度

 __reserved  LPDWORD lpReserved,//保留,为NULL

 __out_opt   LPDWORD lpType,//返回值项类型,有REG_SZ,REG_DWORD等类型

 __out_opt   LPBYTE lpData,//装值项值的buff

 __inout_opt LPDWORD lpcbData//lpData的容量,同时返回lpData接收的字节数

);

以下是伪代码:

char szValueName[100]; memset(szValueName, 0, 100);

BYTE pValue[100]; memset(pValue, 0, 100);

HKEY hKey; long nErr = 0;

DWORD nNameLen = 100, nValueLen = 100, nType = 0;;

FILETIME timeFile;

if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_CONFIG,

" REGTEST\\GPS设备网络通道\\", 0, KEY_ALL_ACCESS, &hKey)) {

        if (ERROR_SUCCESS == (nErr = RegEnumValue(hKey, 1, szValueName, &nNameLen,

NULL, &nType, pValue, &nValueLen))){

                  CString szResult;

                  if (REG_SZ == nType)

                           szResult.Format(_T("%s的值是:%s"), szValueName, (char*)pValue);

                  else if (REG_DWORD == nType)

                           szResult.Format(_T("%s的值是:%d"), szValueName, *((DWORD*)pValue));

                  AfxMessageBox(szResult);

        }

}

2.4.3项批量查询(提取)

        查询指定项下面的子项数据与其下值项数据,如:子项的数量,值项的数量,子项中名称最长的长度,值项中名称最长的长度。其函数原型如下:

LONG WINAPI RegQueryInfoKey(

 __in        HKEY hKey, //已打开的项句柄,必须有KEY_QUERY_VALUE权限,

//同时也可以是几大根键值:

//HKEY_CLASSES_ROOT

//HKEY_CURRENT_CONFIG

//HKEY_CURRENT_USER

//HKEY_LOCAL_MACHINE

//HKEY_USERS

 __out_opt   LPTSTR lpClass, //返回项的类型

 __inout_opt LPDWORD lpcClass,//lpClass容量,同时返回其长度

 __reserved  LPDWORD lpReserved,//保留,必须为NULL

 __out_opt   LPDWORD lpcSubKeys,//返回其下子项的数量

 __out_opt   LPDWORD lpcMaxSubKeyLen,//返回子项中名称最长的项的长度

 __out_opt   LPDWORD lpcMaxClassLen,//返回子项中类型名最长的长度

 __out_opt   LPDWORD lpcValues,//返回指定项的值项的数量

 __out_opt   LPDWORD lpcMaxValueNameLen,//返回指定项的值项中名称最长的长度

 __out_opt   LPDWORD lpcMaxValueLen,//返回指定项的值项中值的最长长度

 __out_opt   LPDWORD lpcbSecurityDescriptor,//安全描述,可以为NULL

 __out_opt   PFILETIME lpftLastWriteTime//指定项,或其下的所有项中最晚修改时间

);

以下为伪代码:

char szClassName[100]; memset(szClassName, 0, 100);

DWORD nClassLen = 0, nSubKeys = 0, nMaxSubKey = 0, nMaxClass = 0;

DWORD nValues = 0, nMaxValueNameLen = 0, nMaxValueLen = 0;

FILETIME timeFile;

HKEY hKey; long nError = 0;

if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\360desktop\\",

 0, KEY_ALL_ACCESS, &hKey)) {

        if (ERROR_SUCCESS == (nError = RegQueryInfoKey(hKey, szClassName, &nClassLen,

NULL, &nSubKeys, &nMaxSubKey, &nMaxClass, &nValues, &nMaxValueNameLen, &nMaxValueLen, NULL, &timeFile ))){

                  CString szResult;

                  szResult.Format(_T("szClassName:%s, nClassLen:%d, nSubKeys:%d, \

nMaxSubKey:%d, nMaxClass:%d,\

                                                       nValues:%d, nMaxValueNameLen:%d, nMaxValueLen:%d "), 

                                                       szClassName, nClassLen, nSubKeys, nMaxSubKey,

nMaxClass, nValues, nMaxValueNameLen, nMaxValueLen);

                  AfxMessageBox(szResult);

        }

}

 

2.4.4值项批量查询(提取)

        RegQueryMultipleValue此方法是批量查询、提取指定项下的值项数据,操作繁琐,不是很方便,不建议新手用,新手可用RegEnumValue或RegQueryValueEx一个一个提取。

RegQueryMultipleValue函数原型如下:

LONG WINAPI RegQueryMultipleValues(

 __in        HKEY hKey, //已打开的项句柄,必须有KEY_QUERY_VALUE权限,

//同时也可以是几大根键值:

//HKEY_CLASSES_ROOT

//HKEY_CURRENT_CONFIG

//HKEY_CURRENT_USER

//HKEY_LOCAL_MACHINE

//HKEY_USERS

 __out       PVALENT val_list,//数组指针,装值项信息用的,对这个参数下面详细介绍

 __in        DWORD num_vals,//val_list数组元素个数

 __out_opt   LPTSTR lpValueBuf,//装值项的值的buff,全部值项的值串行存放,配合

//val_list中的信息提取值,所以说麻烦吧

 __inout_opt LPDWORD ldwTotsize//plValueBuf容量,返回实际接收字节数

);

此函数,通过第四个参数lpValueBuf接收指定项下所有值项的值,把所有值项的值安串行方式装载,提取的时候,配合第二个参数val_list提取,VALENT结构中存储了值项的值类型,还有值在lpValueBuf中的具体位置,还有值数据在lpValueBuf中占的字节数。下面介绍一下VALENT结构原型:

typedef struct value_ent {

LPTSTR ve_valuename; //值项名称,调用RegQueryMultipleValue前必须填充,

                                           //RegQueryMultipleValue函数是通过这个名称来提取值项数据的

 DWORD    ve_valuelen;//取回的值项的值的字节数

 DWORD_PTR ve_valueptr;//值项的值在RegQueryMultipleValues参数lpValueBuf中的位置

 DWORD    ve_type;  //取回值项的值的类型

} VALENT, *PVALENT;

以下为伪代码:

char szClassName[100]; memset(szClassName, 0, 100);

VALENT pValent[3]; DWORD nValentCount = 3;

memset(pValent, 0, sizeof(pValent));

pValent[0].ve_valuename = _T("Version");//输入值项名称

pValent[1].ve_valuename = _T("uac0");

pValent[2].ve_valuename = _T("TestDword");

 

char szVale[1024]; DWORD nValueLen = 1024;

FILETIME timeFile;

HKEY hKey; long nError = 0;

if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\360desktop\\",

        0, KEY_ALL_ACCESS, &hKey)) {

        if (ERROR_SUCCESS == (nError = RegQueryMultipleValues(hKey, pValent,

                  nValentCount, szVale, &nValueLen))){

                           CString szResult;

                           for (int i = 0; i < nValentCount; ++i) {

                                    CString szTemp;

                                    if(REG_SZ == pValent[i].ve_type){

                                              szTemp.Format(_T("第%d个参数[%s]的值是:%s\r"), i,

                                                       pValent[i].ve_valuename, (char*)pValent[i].ve_valueptr);

                                    }

                                    else if (REG_DWORD == pValent[i].ve_type){

                                              szTemp.Format(_T("第%d个参数[%s]的值是:%d\r"), i,

                                                       pValent[i].ve_valuename, *((DWORD*)pValent[i].ve_valueptr));

                                    }

                                    if(!szTemp.IsEmpty())

                                              szResult += szTemp;

                  }

                  AfxMessageBox(szResult);

        }

}

注册表相关项的切图如下:

运行代码效果切图如下:

 

三、示例代码

        以上每个函数具体使用操作都写了源码,并测试通过,编译环境是VC++6.0,每个函数对应一个按钮,如图:

以下链接可下载源码:http://download.youkuaiyun.com/detail/mingojiang/4439227

不想下载的,我把代码片段粘在下面,使用时稍加修改复制到自己工程里就OK了。

void CRegTestDlg::OnAddValue()

{

        HKEY hKey;

        if(ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_CONFIG,

                  " REGTEST\\GPS设备网络通道\\", 0, KEY_ALL_ACCESS, &hKey)){

                  DWORD nType = REG_SZ;

                  char szName[] = {"我叫小王"};

                  RegSetValueEx(hKey, "Name", 0, nType,

                           (const PBYTE)szName, strlen(szName));

                  nType = REG_DWORD;

                  DWORD nYears = 60;

                  RegSetValueEx(hKey, "Years", 0, nType, (const PBYTE)&nYears, 4);

        }

}

 

void CRegTestDlg::OnDeleteValue()

{

        HKEY hKey;

        if(ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_CONFIG,

                  " REGTEST\\GPS设备网络通道\\", 0, KEY_ALL_ACCESS, &hKey)){

                  RegDeleteValue(hKey, "Name");

                  RegDeleteValue(hKey, "Years");

        }

}

 

void CRegTestDlg::OnKeyCreate()

{

        HKEY hKey;

        DWORD dw;

        if(ERROR_SUCCESS == RegCreateKeyEx(HKEY_CURRENT_CONFIG,

                  " REGTEST\\GPS设备网络通道\\", 0,

                  NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS,

                  NULL, &hKey, &dw))

                  AfxMessageBox(_T("创建成功"));

}

 

void CRegTestDlg::OnKeyOpen()

{

        HKEY hKey;

        if(ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_CONFIG,

                  " REGTEST\\GPS设备网络通道\\", 0, KEY_ALL_ACCESS, &hKey))

                  AfxMessageBox(_T("打开成功"));

}

 

void CRegTestDlg::OnKeyClose()

{

        HKEY hKey;

        if(ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_CONFIG,

                  " REGTEST\\GPS设备网络通道\\", 0, KEY_ALL_ACCESS, &hKey)){

                  if (ERROR_SUCCESS == RegCloseKey(hKey))

                           AfxMessageBox(_T("关闭成功"));

        }

}

 

void CRegTestDlg::OnKeyDelete()

{

        if(ERROR_SUCCESS == RegDeleteKey(HKEY_CURRENT_CONFIG,

                  " REGTEST\\GPS设备网络通道\\"))

                  AfxMessageBox(_T("删除成功"));

}

 

void CRegTestDlg::OnRegQueryValue()

{

        HKEY hKey;

        if(ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_CONFIG,

                  " REGTEST\\GPS设备网络通道\\", 0, KEY_ALL_ACCESS, &hKey)){

                  DWORD nType = 0, nLen = 100;

                  char szName[100];

                  RegQueryValueEx(hKey, "Name", 0, &nType, (const PBYTE)szName, &nLen);

                  nType = 0;

                  DWORD nYears = 0; nLen = 4;

                  RegQueryValueEx(hKey, "Years", 0, &nType, (const PBYTE)&nYears, &nLen);

                  int i = 0;

        }

}

 

void CRegTestDlg::OnRegEnumKey()

{

        char szKeyName[100]; memset(szKeyName, 0, 100);

        char szClass[100]; memset(szClass, 0, 100);

        HKEY hKey; long nErr = 0;

        DWORD nNameLen = 100, nClassLen = 100;

        FILETIME timeFile;

        if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_CONFIG, " REGTEST", 0,

                  KEY_ALL_ACCESS, &hKey)) {

                  if (ERROR_SUCCESS == (nErr = RegEnumKeyEx(HKEY_CURRENT_CONFIG/*hKey*/, 0,

                           szKeyName, &nNameLen, NULL, szClass, &nClassLen, &timeFile)))

                           AfxMessageBox(szKeyName);

        }

}

 

void CRegTestDlg::OnRegEnumValue()

{

        char szValueName[100]; memset(szValueName, 0, 100);

        BYTE pValue[100]; memset(pValue, 0, 100);

        HKEY hKey; long nErr = 0;

        DWORD nNameLen = 100, nValueLen = 100, nType = 0;;

        if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_CONFIG,

                  " REGTEST\\GPS设备网络通道\\", 0, KEY_ALL_ACCESS, &hKey)) {

                  if (ERROR_SUCCESS == (nErr = RegEnumValue(hKey, 1, szValueName,

                           &nNameLen, NULL, &nType, pValue, &nValueLen))){

                           CString szResult;

                           if (REG_SZ == nType) {

                                   szResult.Format(_T("%s的值是:%s"), szValueName, (char*)pValue);

                           }

                           else if (REG_DWORD == nType) {

                                    szResult.Format(_T("%s的值是:%d"), szValueName, *((DWORD*)pValue));

                           }

                           AfxMessageBox(szResult);

                  }

        }

}

 

void CRegTestDlg::OnRegQueryInfoKey()

{

        char szClassName[100]; memset(szClassName, 0, 100);

        DWORD nClassLen = 0, nSubKeys = 0, nMaxSubKey = 0, nMaxClass = 0;

        DWORD nValues = 0, nMaxValueNameLen = 0, nMaxValueLen = 0;

 

        FILETIME timeFile;

        HKEY hKey; long nError = 0;

        if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE,

                  "SOFTWARE\\360desktop\\", 0, KEY_ALL_ACCESS, &hKey)) {

                  if (ERROR_SUCCESS == (nError = RegQueryInfoKey(hKey, szClassName,

                           &nClassLen, NULL, &nSubKeys, &nMaxSubKey,

                           &nMaxClass, &nValues, &nMaxValueNameLen, &nMaxValueLen,

                           NULL, &timeFile ))){

                           CString szResult;

                           szResult.Format(_T("szClassName:%s, nClassLen:%d, nSubKeys:%d, \

                                                                          nMaxSubKey:%d, nMaxClass:%d,

                                                                nValues:%d, nMaxValueNameLen:%d, nMaxValueLen:%d "), 

                                                                szClassName, nClassLen, nSubKeys, nMaxSubKey,

                                                                nMaxClass, nValues, nMaxValueNameLen, nMaxValueLen);

                           

                           AfxMessageBox(szResult);

                  }

        }

}

 

void CRegTestDlg::OnRegQueryMutipleValue()

{

        char szClassName[100]; memset(szClassName, 0, 100);

        VALENT pValent[3]; DWORD nValentCount = 3;

        memset(pValent, 0, sizeof(pValent));

        pValent[0].ve_valuename = _T("Version");

        pValent[1].ve_valuename = _T("uac0");

        pValent[2].ve_valuename = _T("TestDword");

 

        char szVale[1024]; DWORD nValueLen = 1024;

        HKEY hKey; long nError = 0;

        if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE,

                  "SOFTWARE\\360desktop\\",0, KEY_ALL_ACCESS, &hKey)) {

                  if (ERROR_SUCCESS == (nError = RegQueryMultipleValues(hKey, pValent,

                           nValentCount, szVale, &nValueLen))){

                                    CString szResult;

                                    for (UINT i = 0; i < nValentCount; ++i) {

                                              CString szTemp;

                                              if(REG_SZ == pValent[i].ve_type){

                                                       szTemp.Format(_T("第%d个值项[%s]的值是:%s\r"), i,

                                                                pValent[i].ve_valuename, (char*)pValent[i].ve_valueptr);

                                              }

                                              else if (REG_DWORD == pValent[i].ve_type){

                                                       szTemp.Format(_T("第%d个值项[%s]的值是:%d\r"), i,

pValent[i].ve_valuename, *((DWORD*)pValent[i].ve_valueptr));

                                              }

                                              if(!szTemp.IsEmpty())

                                                       szResult += szTemp;

                           }

                           AfxMessageBox(szResult);

                  }

        }

}

 

 

转载自:blog.youkuaiyun.com/mingojiang

关于注册表编程的一些思考 本文是关于大信息安全概论有关注册表编程的一些基础了解 阅读详情

相关推荐

如何以编程的方式打开Windows 11注册表

在本文中,我将为您介绍如何使用编程的方式打开Windows 11注册表,并提供相应的源代码示例。通过以上步骤,您可以使用Python编程语言以编程的方式打开Windows 11注册表,并进行相应的读取或修改操作。请注意,在进行任何修改操作之前,请确保您了解所做的更改可能对系统造成的影响,并小心谨慎地进行操作。这些函数可以根据您的需求进行调用,以实现对注册表的读取或修改操作。函数可以打开注册表的指定项。在完成对注册表的操作后,我们应该关闭已打开的注册表项。函数,我们可以打开指定路径的注册表项。

CodeRoarX的博客 226

C# 注册表操作代码

在我们编写程序时,有时会用到注册表项,我们看到的注册表是树状结构,习惯把左边树状形式叫做文件夹,右边的叫键,对应的值叫键值。但微软对注册表左边的树状称作“项”,右边我们叫键的称作数值名称(“字符串值”、“二进制值”、“DWORD(32位)值”等),相应的键值叫做数值数据。我们的代码还是以我们自己命名习惯来写的。

b07lxh的博客 965

Windows注册表编程全攻略教程

本文还有配套的精品资源,点击获取 简介:Windows注册表是系统核心数据库,对系统运行至关重要。本教程全面介绍注册表结构、脚本编程、在VC、VB、C#中的应用及安全操作要点。学习本教程将提升系统管理与故障排查能力,帮助开发者更有效地优化和管理Windows系统。 1. 注册表核心概念和结构 在深入了解Windows操作系统之前,注册表作为一个核心组件,扮演...

weixin_30248619的博客 1221

c++ 操作注册表

1.       注册表简介 注册表是为Windows NT和Windows95中所有32位硬件/驱动和32位应用程序设计的数据文件,用于存储系统和应用程序的设置信息。16位驱动在Winnt (Windows New Technology)下无法工作,所以所有设备都通过注册表来控制,一般这些是通过BIOS(基本输入输出系统)来控制的。在Win95下,16位驱动会继续以实模式方式设备工作,它们使用

1779

VB编程中注册表操作的详细指南

在Windows操作系统中,注册表是一个庞大的数据库系统,用于存储配置信息、系统设置以及应用程序和驱动程序的相关数据。通过编程方式读写注册表可以实现对系统和应用程序的深度定制和管理。VB(Visual Basic)作为一种简单的编程语言,提供了Registry对象用于与注册表进行交互。这种操作可以执行创建、修改、删除和查询注册表项和值的命令。然而需要注意的是,直接操作注册表存在风险,比如可能会导致系统不稳定或软件冲突,因此在操作前需要确保代码的正确性和安全性。

weixin_42587866的博客 963

DevEco Studio在初始化时出现Installing pnpm@8.13.1...npm ERR! code ETIMEDOUTnpm ERR! syscall connectnpm E

npm的仓库源设置的有问题,下载不了鸿蒙相关组件,所以你的启动依赖都没有,或者以前下载过npm,使用的源改的乱七八糟了。以前安装过前端相关的node.js的话,启动的时候记得使用管理远权限。(DevEco Studio)就出错,npm显示超时。

qq_56392862的博客 2628

C++中使用RegQueryValueEx函数获取注册表中REG_SZ类型的值不正确

如下图所示,注册表的HKEY_CURRENT_USER主键下Software\\AB子键中有名称为CD,类型为REG_SZ,值为“123”的字符串 一开始我是通过下面的程序来获取名称为CD的字符串的值 #include <stdio.h> #include <windows.h> #include <windef.h> #include <winreg.h> #include <algorithm> #include <s.

崔杰城的博客 3671

UE5 Metahuman与Blender手动绑定:ARKit面部动画实战对比

面部动画是角色动画领域的核心技术,其核心原理在于通过驱动面部骨骼或混合形状来模拟真实肌肉运动,从而赋予数字角色生命力。这项技术的价值在于极大地提升了虚拟角色的表现力与沉浸感,广泛应用于游戏开发、影视制作、虚拟现实和实时交互应用。在技术实现路径上,开发者常面临工业化集成方案与高度自定义方案的选择。本文聚焦于使用行业标准的ARKit 52个面部混合形状数据,深度对比了虚幻引擎Metahuman的工业化流程与Blender手动绑定方案在视觉保真度、工作流效率、性能开销和扩展性上的差异,为不同项目规模与技术需求的团

weixin_33901926的博客 449

Windows注册表编程

通过Windows注册表实现程序自启动是Windows开发中的常见需求。注册表的基本结构和关键概念注册表操作的核心API函数实现程序自启动的完整代码示例相关的高级主题和最佳实践正确使用注册表可以增强程序的灵活性,但需要注意操作的安全性。建议仅在必要时修改注册表,并确保做好错误处理和用户提示。对于大多数应用程序,使用当前用户的Run键是最简单安全的自启动方式。如果需要更复杂的启动逻辑,可以考虑使用任务计划程序等替代方案。

静下心来,做好每一件事 803

竞拍算法(Auction Algorithm)原理及工作过程分析

因一些项目工作需要对竞拍算法进行深入了解。但百度了大部分资料都未找到一篇文章能对此算法进行较为深入的介绍。在一番努力之下,终于找打了最初提出该算法的论文,本文内容主要结合该论文对竞拍算法进行分析。 竞拍算法简介 竞拍算法(Auction Algorithm)是一种用于解决分配问题的分布式算法,经相关文献查询,最早由麻省理工学院信息和决策系统实验室的Bertsekas(教授?)提出 1,于1988年发表于期刊Annals of Operations Research。 顾名思义,竞拍算法本质就是模拟人类拍.

weixin_47546390的博客 3万+

ctfshow WEB web4

ctfshow WEB web4

weixin_68416970的博客 720

注册表编程扫盲(一)

前言        今天看了一本注册表方面的书,觉得还不错。特别还写了一章注册表编程。呵呵,我现在就我的理解把它贴上来给大家分享一下:)    什么是注册表我不用说了吧,反正大家都知道了。不知道?其实注册表就是...就是...就是那么回事了,具体我也说不清楚。有一点是可以肯定的,通过修改注册表可以产生很牛的效果,比如说自动运行啊,隐藏驱动器之类的,反正很多用拉,数不清的。又比如说现在有n多软件功能

0ffs3t 2752

如何修复Windows卡在“正在准备Windows”的问题?这里有详细步骤

如何修复Windows卡在“正在准备Windows”的问题?这里有详细步骤。

wyxtx的博客 5657

注册表编程快速入门

最近涉及到了一些注册表的编程,就把入门的一些东西整理一下,各位注册表新手一起来讨论讨论。欢迎留言! 文本的完整代码在http://download.youkuaiyun.com/detail/arvon2012/4482788 文章最后给出两个注册表编程的应用实例,可以帮助大家理解:     注册表编程是什么? 我自己的理解,就是用程序完成原本手工要做的事情。那么我们通过手工可以对注册表进行哪些操

扣的CODE 2734

LangChain学习及应用(超详细)

Model I/O 部分是与语言模型进行交互的核心组件,包括输入提示(Prompt Template)、调用模型(Model)、输出解析(Output Parser)。简单来说,就是输入、处理、输出这三个步骤。LLM 因其具有海量参数,需要花费相当的物力与时间成本进行预训练和微调,同时商用 LLM 还需要进行各种安全测试与风险评估等。因此 LLM 会存在知识滞后的问题。在专有领域,LLM 无法学习到所有的专业知识细节,因此在面向专业领域知识的提问时,无法给出可靠准确的回答。

weixin_39764056的博客 4233

YOLOv8首创原创改进:即插即用|创新的轻量化非对称多级压缩LADH检测头

总结而言,本文介绍了一种名为轻量化非对称多级压缩LADH检测头的原创改进,该改进可与YOLOv8无缝适配,并显著提升了检测器的性能。在本文中,我们介绍了一种原创改进的检测头,名为轻量化非对称多级压缩LADH检测头,它可与YOLOv8无缝适配,显著提升了检测器的性能。此外,我们引入了多级压缩的概念,通过在不同的检测层级上应用不同程度的压缩,进一步提升了检测头的轻量化特性。具体而言,我们采用了逐级减少卷积核数量和通道数量的策略,以降低模型的参数量和计算复杂度,同时保持较高的检测精度。

IbcVue的博客 2180

C++ 注册表编程

C++ 注册表编程 转自http://wenku.baidu.com/view/f369e14acf84b9d528ea7a77.html 1.基础知识注册表的组织方式跟文件目录比较相似,主要分为根键、子键和键值项三部分,与文件目录对应的话就是根目录、子目录和文件。分别介绍一下这

774

【Python机器学习】主成分分析(PCA):高维数据的“瘦身术“

主成分分析(PCA)的历史可以追溯到1901年,当时Karl Pearson首次提出了这个概念。在计算机还不存在的年代,PCA是一个纯粹的数学构想,用来简化多变量数据的分析。几十年后,当计算机出现时,PCA成为了数据分析中最早实现的算法之一。从那时起,超过一个世纪的发展中,PCA一直保持着其核心的理论框架和实用价值,这本身就是对这个方法深刻科学性的证明。在现代深度学习时代,许多人可能会认为PCA已经过时了。但事实恰好相反。

nmdbbzcl的博客 981

注册表编程详解

一、注册表编程详解  Windows 注册表中包含了系统配置、机器硬件配置、 Win32 应用程序和用户的其他配置信息。许多高级一些的功能都要通过对注册表的操作来实现。在 WinAPI 中提供了 RegCgreateKey() 、 RegOpenKey() 、 RegQueryValue() 等函数操作注册表,但是用这些函数来操作注册表使用起来非常麻烦。而利用 C ++ Builder 的 TRE

628

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

注册表和COM编程

在注册表中右键菜单的项目都包含在第一子项 HKEY_CALSS_ROOT 中。展开该项,第一个子项一般是 * ,这个统配符表示一切后缀的文件都通用。也就是说,这个子项中的一切右键菜单项,没有特别说明,会出现每一个文件的右键菜单中。 再比如.html项,就是这个项分管以.html后缀结尾的文件的右键菜单。 在一个子项的其内部,所有的右键菜单分为两部分存储 shell:通过简单地编辑注册表的项值实现一...

kekefen01的博客 2934

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

上一篇: 串口通信编程--多线程异步方式
下一篇: 判断点是否在多边型内
cbNotes
博客等级 码龄14年 295粉丝 57原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值