注冊(cè)表之Windows開機(jī)啟動(dòng)
Windows程序開機(jī)啟動(dòng)的方式有很多,但是通過注冊(cè)表啟動(dòng)應(yīng)該是最簡(jiǎn)單的方式了。
注冊(cè)表
注冊(cè)表(Registry,繁體中文版Windows操作系統(tǒng)稱之為登錄檔)是Microsoft Windows中的一個(gè)重要的數(shù)據(jù)庫,用于存儲(chǔ)系統(tǒng)和應(yīng)用程序的設(shè)置信息。早在Windows 3.0推出OLE技術(shù)的時(shí)候,注冊(cè)表就已經(jīng)出現(xiàn)。隨后推出的Windows NT是第一個(gè)從系統(tǒng)級(jí)別廣泛使用注冊(cè)表的操作系統(tǒng)。但是,從Microsoft Windows 95操作系統(tǒng)開始,注冊(cè)表才真正成為Windows用戶經(jīng)常接觸的內(nèi)容,并在其后的操作系統(tǒng)中繼續(xù)沿用至今。

打開注冊(cè)表
打開方式很多,個(gè)人習(xí)慣用搜索方式打開,用cmd也很方便。

注冊(cè)表的數(shù)據(jù)結(jié)構(gòu)
注冊(cè)表由鍵(也叫主鍵或稱“項(xiàng)”)、子鍵(子項(xiàng))和值項(xiàng)構(gòu)成。一個(gè)鍵就是分支中的一個(gè)文件夾,而子鍵就是這個(gè)文件夾當(dāng)中的子文件夾,子鍵同樣它也是一個(gè)鍵。一個(gè)值項(xiàng)則是一個(gè)鍵的當(dāng)前定義,由名稱、數(shù)據(jù)類型以及分配的值組成。一個(gè)鍵可以有一個(gè)或多個(gè)值,每個(gè)值的名稱各不相同,如果一個(gè)值的名稱為空,則該值為該鍵的默認(rèn)值。
注冊(cè)表的數(shù)據(jù)類型主要有以下四種:顯示類型(在編輯器中)數(shù)據(jù)類型說明: REGSZ:字符串:文本字符串 REGMULTISZ:多字符串值:含有多個(gè)文本值的字符串 REGBINARY:二進(jìn)制數(shù):二進(jìn)制值,以十六進(jìn)制顯示, REG_DWORD:雙字值;一個(gè)32位的二進(jìn)制值,顯示為8位的十六進(jìn)制值。
注冊(cè)表的根鍵
從下圖中的注冊(cè)表編輯器(Win7系統(tǒng))中可以看出注冊(cè)表的根鍵有5個(gè),在Win98和95系統(tǒng)中還有一個(gè)根鍵HKEYDTNDATA。
HKEYCLASSESROOT:存儲(chǔ)在這里的信息可確保使用 Windows 資源管理器打開文件時(shí)能打開正確的程序。此項(xiàng)有時(shí)縮寫為“HKCR”。
HKEYCURRENTUSER:包含當(dāng)前登錄的用戶的配置信息的根目錄。該用戶的文件夾、屏幕顏色和“控制面板”設(shè)置都存儲(chǔ)在這里。這些信息與用戶的配置文件相關(guān)聯(lián)。此項(xiàng)有時(shí)縮寫為“HKCU”。
HKEYLOCALMACHINE:包含特定于計(jì)算機(jī)的配置信息(用于任何用戶)。此項(xiàng)有時(shí)縮寫為“HKLM”。
HKEYUSERS:包含計(jì)算機(jī)上的所有以活動(dòng)方式加載的用戶配置文件。HKEYCURRENTUSER 是 HKEYUSERS 的子項(xiàng)。HKEY_USERS 有時(shí)縮寫為“HKU”。
HKEYCURRENTCONFIG:包含有關(guān)本地計(jì)算機(jī)在系統(tǒng)啟動(dòng)時(shí)使用的硬件配置文件的信息。
HKEYDTNDATA:動(dòng)態(tài)信息,包括即插即用的硬件信息。(僅存在于 Windows 95 及 98 中)

HKEYLOCALMACHIN和HKEYUSERS根鍵是注冊(cè)表中的兩大根鍵,其余的根鍵都是他們派生的,實(shí)際上他們都是這兩大根鍵下面的某些自鍵的映射。如HKEYCLASSROOT是HKEYLOCALMACHINE下SOFTWARE/Classes子鍵的映射,HKEYCURRENTCONFIG根鍵是HKEYLOCAL_MACHINE下Config子鍵的映射。
注冊(cè)表本質(zhì)
我們看到的注冊(cè)表結(jié)構(gòu)是經(jīng)過注冊(cè)表編輯器讀取之后呈現(xiàn)給我們的,其磁盤形式并不是一個(gè)簡(jiǎn)單的大文件,而是一組稱被為HⅣE的單獨(dú)文件形式,HⅣE中文名曰“儲(chǔ)巢”。每個(gè)HⅣE文件可以被理解為一棵單獨(dú)注冊(cè)表樹,就像Windows的PE格式一樣,它也有自己的組織形式。
注冊(cè)表編程
在下面的表哥中列出了注冊(cè)表中常用的API及其功能。
API功能RegCreateKey創(chuàng)建一個(gè)KEY,并返回相應(yīng)的HKEYRegOpenKey打開注冊(cè)表,得到一個(gè)HKEY,用來作為下面這些函數(shù)的第一個(gè)參數(shù)。RegOpenKeyEx同RegOpenKey類似,一般很少用,增加了一個(gè)訪問控制類型參數(shù)。RegSetValue設(shè)置一個(gè)HKEY的默認(rèn)值RegSetValueEx設(shè)置一個(gè)HKEY除默認(rèn)值以外其它的值RegQueryValue獲取一個(gè)HKEY的默認(rèn)值RegQueryValueEx獲取一個(gè)HKEY除默認(rèn)值以外其它的值RegDeleteKey刪除一個(gè)KEY,此KEY不能包含子KEYSHDeleteKey刪除一個(gè)KEY以及所有子KEYRegDeleteValue刪除KEY里面的值RegCloseKey關(guān)閉注冊(cè)表開機(jī)啟動(dòng)
Windows通過注冊(cè)表設(shè)置開機(jī)啟動(dòng)
在注冊(cè)表中定位到“計(jì)算機(jī)\HKEYLOCALMACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run",可以看出VBoxTRay會(huì)在開機(jī)時(shí)候啟動(dòng)。

查看進(jìn)程如下:

如果想要僅下一次開機(jī)運(yùn)行,之后都不再運(yùn)行可以在“計(jì)算機(jī)\HKEYLOCALMACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce”中操作。
開機(jī)啟動(dòng)源代碼
下面的代碼通過開機(jī)自啟動(dòng)execel和本應(yīng)用程序,使用的方式是在鍵"\HKEYLOCALMACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run"寫值。同時(shí),還有注冊(cè)表常用的一些操作。
#include <Windows.h>
#include <iostream>
using namespace std;
int WriteReg(char* path, char* key, char* value);
/************************************
@ Brief: ? ? ? ?開機(jī)啟動(dòng)
@ Author: ? ? ? ?無情劍客
@ Created: ? ? ? ?2020/08/25 傳統(tǒng)節(jié)日七夕
@ Return:
************************************/
void autostart()
{
? ?//1. 開啟啟動(dòng)execel
? ?WriteReg("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", "execel", "C:\\Program Files (x86)\\Office 2007\\Office12\\EXCEL.exe");
? ?//2、得到本程序自身的全路徑
? ?TCHAR strExeFullDir[MAX_PATH];
? ?GetModuleFileName(NULL, strExeFullDir, MAX_PATH);
? ?//3. 開機(jī)啟動(dòng)當(dāng)前程序
? ?WriteReg("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", "Register", strExeFullDir);
}
/************************************
@ Brief: ? ? ? ?打開注冊(cè)表,讀取Key對(duì)應(yīng)value
@ Author: ? ? ? ?無情劍客
@ Created: ? ? ? ?2020/08/25 傳統(tǒng)節(jié)日七夕
@ Return:
************************************/
int ReadReg(char* path, char* key, char* value)
{
? ?HKEY hKey;
? ?int ret = RegOpenKeyEx(HKEY_CURRENT_USER, path, 0, KEY_EXECUTE, &hKey);
? ?if (ret != ERROR_SUCCESS)
? ?{
? ? ? ?cout << "打開注冊(cè)表失敗" << endl;
? ? ? ?return 1;
? ?}
? ?//讀取KEY
? ?DWORD dwType = REG_SZ; //數(shù)據(jù)類型
? ?DWORD cbData = 256;
? ?ret = RegQueryValueEx(hKey, key, NULL, &dwType, (LPBYTE)value, &cbData);
? ?if (ret == ERROR_SUCCESS)
? ?{
? ? ? ?cout << value << endl;
? ?}
? ?else
? ?{
? ? ? ?cout << "讀取注冊(cè)表中KEY 失敗" << endl;
? ? ? ?RegCloseKey(hKey);
? ? ? ?return 1;
? ?}
? ?RegCloseKey(hKey);
? ?return 0;
}
/************************************
@ Brief: ? ? ? ?寫注冊(cè)表,如不存在自動(dòng)創(chuàng)建
@ Author: ? ? ? ?無情劍客
@ Created: ? ? ? ?2020/08/25 傳統(tǒng)節(jié)日七夕
@ Return:
************************************/
int WriteReg(char* path, char* key, char* value)
{
? ?HKEY hKey;
? ?DWORD dwDisp;
? ?DWORD dwType = REG_SZ; //數(shù)據(jù)類型
? ?int ret = RegCreateKeyEx(HKEY_CURRENT_USER, path,0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &dwDisp);
? ?if (ret != ERROR_SUCCESS)
? ?{
? ? ? ?cout << "創(chuàng)建注冊(cè)表失敗" << endl;
? ? ? ?return 1;
? ?}
? ?ret == RegSetValueEx(hKey, key, 0, dwType, (BYTE*)value, strlen(value));
? ?if (ret != ERROR_SUCCESS)
? ?{
? ? ? ?cout << "注冊(cè)表中創(chuàng)建KEY VALUE失敗" << endl;
? ? ? ?RegCloseKey(hKey);
? ? ? ?return 1;
? ?}
? ?RegCloseKey(hKey);
? ?return 0;
}
/************************************
@ Brief: ? ? ? ?刪除注冊(cè)表
@ Author: ? ? ? ?無情劍客
@ Created: ? ? ? ?2020/08/25 傳統(tǒng)節(jié)日七夕
@ Return:
************************************/
int DelReg(char* path)
{
? ?int ret = RegDeleteKey(HKEY_CURRENT_USER, path);
? ?if (ret == ERROR_SUCCESS)
? ?{
? ? ? ?cout << "刪除成功" << endl;
? ?}
? ?else
? ?{
? ? ? ?cout << "刪除失敗" << endl;
? ? ? ?return 1;
? ?}
? ?return 0;
}
int main(int argc, char * argv[])
{
? ?char value[32] = {0};
? ?autostart();
? ?WriteReg("Software\\burning", "微信公眾號(hào)", "無情劍客");
? ?ReadReg("Software\\burning", "微信公眾號(hào)", value);
? ?// C++ 程序暫停,等待用戶輸入回車后再繼續(xù)執(zhí)行
? ?cin.get();
? ?return 0;
}
運(yùn)行結(jié)果如下,當(dāng)開機(jī)之后,Register程序和execl的都啟動(dòng)起來了。

寫在最后
注冊(cè)表之強(qiáng)大超出想象。玩過Dota的都知道Win7之后,游戲不能全屏,其實(shí)游戲畫面的分辨率就是在注冊(cè)表中設(shè)置的,因此可以通過注冊(cè)表來實(shí)現(xiàn)全屏,文件關(guān)聯(lián)設(shè)置也可以通過注冊(cè)表來實(shí)現(xiàn),Windows的用戶帳號(hào)密碼也都在注冊(cè)表中有記錄,當(dāng)然密碼是散列的,還有很多強(qiáng)大的功能。。。
注冊(cè)表設(shè)置開機(jī)啟動(dòng),很容易被檢測(cè)出來,但是如果把進(jìn)程隱藏起來,甚至于注冊(cè)表文件隱藏起來,那就不是很容易檢測(cè)了。
公眾號(hào)
更多內(nèi)容,歡迎關(guān)注我微信公眾號(hào):無情劍客。
