使用内核注册表实现开机启动驱动等
内核注册表
驱动创建描述符SYM_NAME后,会出现在注册表计算机\HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services中
启动项的名字为驱动的文件名,例如hevd_2

- Start:2-开机自启动、3-手动启动、4-禁用,数字越小启动越早

打开注册表ZwCreateKey和ZwOpenKey
移动驱动启动位置并修改注册表
ZwCreateKey
NTSTATUS status = STATUS_SUCCESS; HANDLE hRegKey = NULL; OBJECT_ATTRIBUTES RegAttribute = { 0 }; ULONG KeyOp = 0;
InitializeObjectAttributes(&RegAttribute, RegistryPath, OBJ_CASE_INSENSITIVE, NULL, NULL); status = ZwCreateKey(&hRegKey, KEY_ALL_ACCESS, &RegAttribute, 0, NULL, REG_OPTION_NON_VOLATILE, &KeyOp); if (NT_SUCCESS(status)) { if (KeyOp == REG_CREATED_NEW_KEY) { DbgPrint("Create New key\n"); } else if (KeyOp == REG_OPENED_EXISTING_KEY) { DbgPrint("Registry key opened\n"); } else { DbgPrint("Error\n"); } }
|
ZwOpenKey
NTSTATUS KernelReg(PUNICODE_STRING RegistryPath) { NTSTATUS status = STATUS_SUCCESS; HANDLE hRegKey = NULL; OBJECT_ATTRIBUTES RegAttribute = { 0 }; ULONG KeyOp = 0;
PVOID KeyInfo = ExAllocatePool2(POOL_FLAG_NON_PAGED, 0x1000, 'kcaH'); if (KeyInfo == NULL) { DbgPrint("Allocate Mem Failed\n"); return status; } RtlZeroMemory(KeyInfo, 0x1000); UNICODE_STRING regKeyName = { 0 }; RtlInitUnicodeString(®KeyName, L"ImagePath");
InitializeObjectAttributes(&RegAttribute, RegistryPath, OBJ_CASE_INSENSITIVE, NULL, NULL); status = ZwOpenKey(&hRegKey, KEY_ALL_ACCESS, &RegAttribute); if (!NT_SUCCESS(status)) { DbgPrint("Open Reg Key Failed\n"); return status; } status = ZwQueryValueKey(hRegKey, ®KeyName, KeyValuePartialInformation, KeyInfo, 0x1000 - 1, &KeyOp); if (!NT_SUCCESS(status)) { DbgPrint("Read Reg Key Failed\n"); ZwClose(hRegKey); ExFreePool(KeyInfo); return status; } PKEY_VALUE_PARTIAL_INFORMATION tempinfo = (PKEY_VALUE_PARTIAL_INFORMATION)KeyInfo; PWCHAR tempName = (PWCHAR)(tempinfo->Data); DbgPrint("reg: %wZ, key: %wZ, Value: %ws\n", RegistryPath,regKeyName, tempName);
ZwClose(hRegKey); ExFreePool(KeyInfo); return status; }
|

再加上ZwSetValue和之前的文件复制,就能实现这个功能了,但是需要更多的技巧来提升启动时的运行位置更早。
也可以使用微软封装函数RtlWriteRegistryValue