RegCreateKeyEx非常诡异的错误

wei77316 2014-03-26 12:01:35

// 1.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <Windows.h>
#include <Shlwapi.h>
#pragma comment(lib, "Shlwapi.lib")

void MyCreateRegDword(HKEY MainKey,LPCTSTR SubKey,LPCTSTR Vname,DWORD szData)
{
HKEY hKey;
DWORD dwDisposition;
long ret0=(::RegCreateKeyEx(MainKey,SubKey,0,NULL,REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS,NULL,&hKey,&dwDisposition));
if(ret0!=ERROR_SUCCESS)//如果无法打开hKEY,则中止程序的执行
{
MessageBox(NULL,"错误:无法打开有关的hKEY",NULL,NULL);
return;
}

DWORD dwLastError;
dwLastError = szData;
if (RegSetValueEx( hKey, Vname, 0,REG_DWORD,(LPBYTE)&dwLastError ,sizeof(DWORD)))
{
MessageBox(NULL,"不能新增注册表值.",NULL,NULL);
return;
}

RegCloseKey(MainKey);
RegCloseKey(hKey);
return;
}

int main(int argc, char* argv[])
{
// SHDeleteKey(HKEY_CURRENT_USER, "AppEvents\\Schemes\\FUCK");
MyCreateRegDword(HKEY_CURRENT_USER,"AppEvents\\Schemes\\FUCK","test", 1);
return 0;
}

标题可能有点出入,具体哪里出错我也不知道
以上代码新建工程编译后完成了在HKEY_CURRENT_USER\AppEvents\Schemes下新建fuck项,并建立REG_DWORD类型的test键,赋值1
但把MyCreateRegDword函数放到dll中调用竟无法实现上述效果,fuck项都无法建立,郁闷好久,请大神解惑
...全文
529 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
clever101 2015-04-23
  • 打赏
  • 举报
回复
应该是权限不够,问题是如何提升权限呢?
wei77316 2014-03-28
  • 打赏
  • 举报
回复
是程序需要了,故意提权的,虽然以Administrator账号登录启动也可以
赵4老师 2014-03-28
  • 打赏
  • 举报
回复
为什么不让服务以Administrator账号登录启动呢?
wei77316 2014-03-28
  • 打赏
  • 举报
回复
膜拜,十二分感谢,以身相许可以不
oceanark 2014-03-28
  • 打赏
  • 举报
回复
引用 5 楼 wei77316 的回复:
[quote=引用 2 楼 zhao4zhong1 的回复:] 请判断所有函数的返回值,必要时将GetLastError()的返回值写日志。 ..... [/code]
看来只有大哥是个好人而以了,发现了个奇怪的问题,执行后并不是并写,而是在HKEY_USERS 下成功写入了键值,而HKEY_CURRENT_USER 却没有写入,百度了下,说HKEY_CURRENT_USER是HKEY_USERS。。。感觉没天理啊,求大哥帮研究研究,万分感谢[/quote] 我想我知道原因了,你的服务是LocalSystem帐号运行的吧,该帐号虽然有极高的权限,但有几个限制: 1. 不能访问网络资源; 2. 没有对应的 SID,不能访问需要登录才能访问的资源; 所以,这样的服务不能直接访问 HKEY_CURRENT_USER,读取会失败,写入则会被重定向到 HKEY_USER\.Default 下; 以下代码可以解决你的困惑

DWORD get_user_process_id()
{
    PROCESSENTRY32 proc_entry;
    DWORD explorer_pid = 0;
    DWORD agent_session_id;
 
    if (!ProcessIdToSessionId(GetCurrentProcessId(), &agent_session_id)) {
        printf("ProcessIdToSessionId for current process failed %lu", GetLastError());
        return 0;
    }
 
    HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (snap == INVALID_HANDLE_VALUE) {
        printf("CreateToolhelp32Snapshot() failed %lu", GetLastError());
        return 0;
    }
    ZeroMemory(&proc_entry, sizeof(proc_entry));
    proc_entry.dwSize = sizeof(PROCESSENTRY32);
    if (!Process32First(snap, &proc_entry)) {
        printf("Process32First() failed %lu", GetLastError());
        CloseHandle(snap);
        return 0;
    }
    do {
        if (_tcsicmp(proc_entry.szExeFile, TEXT("explorer.exe")) == 0) {
            DWORD explorer_session_id;
            if (!ProcessIdToSessionId(proc_entry.th32ProcessID, &explorer_session_id)) {
                printf("ProcessIdToSessionId for explorer failed %lu", GetLastError());
                break;
            }
             
            if (explorer_session_id == agent_session_id) {
                explorer_pid = proc_entry.th32ProcessID;
                break;
            }
        }
    } while (Process32Next(snap, &proc_entry));
 
    CloseHandle(snap);
    if (explorer_pid == 0) {
        printf("explorer.exe not found");
        return 0;
    }
    return explorer_pid;
}
调用:

DWORD user_pid;
HANDLE hprocess, htoken;
 
HKEY hkey_cur_user = NULL;
LONG status;  
 
user_pid = get_user_process_id();
 
if (!user_pid) {
    vd_printf("get_user_process_id failed");
    return false;
}
 
hprocess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, user_pid);
 
if (!OpenProcessToken(hprocess, TOKEN_ALL_ACCESS, &htoken)) {
    CloseHandle(hprocess);
    return false;
}
 
 
ImpersonateLoggedOnUser(htoken);
 
status = RegOpenCurrentUser(KEY_READ, &hkey_cur_user);
 
if (status != ERROR_SUCCESS) {
    CloseHandle(hprocess);
}
赵4老师 2014-03-26
  • 打赏
  • 举报
回复
请判断所有函数的返回值,必要时将GetLastError()的返回值写日志。 另外参考下面,尽管是VB6:
VERSION 5.00
Begin VB.Form frmMain
   BorderStyle     =   0  'None
   ClientHeight    =   885
   ClientLeft      =   0
   ClientTop       =   0
   ClientWidth     =   4680
   LinkTopic       =   "Form1"
   ScaleHeight     =   885
   ScaleWidth      =   4680
   ShowInTaskbar   =   0   'False
   StartUpPosition =   3  '窗口缺省
End
Attribute VB_Name = "frmMain"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Option Explicit

'Private Const FOLDER_PATH = "MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI_HAL"
Private Const SYNCHRONIZE As Long = &H100000
Private Const STANDARD_RIGHTS_READ = &H20000
Private Const STANDARD_RIGHTS_WRITE = &H20000
Private Const STANDARD_RIGHTS_EXECUTE = &H20000
Private Const STANDARD_RIGHTS_REQUIRED = &HF0000
Private Const STANDARD_RIGHTS_ALL = &H1F0000
Private Const KEY_QUERY_VALUE = &H1
Private Const KEY_SET_VALUE = &H2
Private Const KEY_CREATE_SUB_KEY = &H4
Private Const KEY_ENUMERATE_SUB_KEYS = &H8
Private Const KEY_NOTIFY = &H10
Private Const KEY_CREATE_LINK = &H20
Private Const KEY_READ = ((STANDARD_RIGHTS_READ Or KEY_QUERY_VALUE Or KEY_ENUMERATE_SUB_KEYS Or KEY_NOTIFY) And (Not SYNCHRONIZE))
Private Const KEY_WRITE = ((STANDARD_RIGHTS_WRITE Or KEY_SET_VALUE Or KEY_CREATE_SUB_KEY) And (Not SYNCHRONIZE))
Private Const KEY_EXECUTE = (KEY_READ)
Private Const KEY_ALL_ACCESS = ((STANDARD_RIGHTS_ALL Or KEY_QUERY_VALUE Or KEY_SET_VALUE Or KEY_CREATE_SUB_KEY Or KEY_ENUMERATE_SUB_KEYS Or KEY_NOTIFY Or KEY_CREATE_LINK) And (Not SYNCHRONIZE))
'Private Const STANDARD_RIGHTS_ALL As Long = &H1F0000
Private Const ERROR_SUCCESS = 0&
'Private Const READ_CONTROL = &H20000
'Private Const KEY_QUERY_VALUE = &H1
'Private Const KEY_SET_VALUE = &H2
'Private Const KEY_CREATE_SUB_KEY = &H4
'Private Const KEY_ENUMERATE_SUB_KEYS = &H8
'Private Const KEY_NOTIFY = &H10
'Private Const KEY_CREATE_LINK = &H20
'Private Const KEY_ALL_ACCESS = ((STANDARD_RIGHTS_ALL + KEY_QUERY_VALUE + KEY_SET_VALUE + KEY_CREATE_SUB_KEY + KEY_ENUMERATE_SUB_KEYS + KEY_NOTIFY + KEY_CREATE_LINK + READ_CONTROL) And (Not SYNCHRONIZE))

Private Const DACL_SECURITY_INFORMATION = 4&
Private Const SET_ACCESS = 2&
Private Const SUB_CONTAINERS_AND_OBJECTS_INHERIT = &H3

Private Enum SE_OBJECT_TYPE
    SE_UNKNOWN_OBJECT_TYPE = 0&
    SE_FILE_OBJECT = 1&
    SE_SERVICE = 2&
    SE_PRINTER = 3&
    SE_REGISTRY_KEY = 4&
    SE_LMSHARE = 5&
    SE_KERNEL_OBJECT = 6&
    SE_WINDOW_OBJECT = 7&
End Enum

'
Private Type TRUSTEE
    pMultipleTrustee As Long
    MultipleTrusteeOperation As Long
    TrusteeForm As Long
    TrusteeType As Long
    ptstrName As String
End Type


Private Type EXPLICIT_ACCESS
    grfAccessPermissions As Long
    grfAccessMode As Long
    grfInheritance As Long
    pTRUSTEE As TRUSTEE
End Type


Private Declare Sub BuildExplicitAccessWithName Lib "advapi32.dll" Alias _
    "BuildExplicitAccessWithNameA" _
    (ea As Any, _
    ByVal TrusteeName As String, _
    ByVal AccessPermissions As Long, _
    ByVal AccessMode As Integer, _
    ByVal Inheritance As Long)

Private Declare Function SetEntriesInAcl Lib "advapi32.dll" Alias _
    "SetEntriesInAclA" _
    (ByVal CountofExplicitEntries As Long, _
    ea As Any, _
    ByVal OldAcl As Long, _
    NewAcl As Long) As Long

Private Declare Function GetNamedSecurityInfo Lib "advapi32.dll" Alias _
    "GetNamedSecurityInfoA" _
    (ByVal ObjName As String, _
    ByVal SE_OBJECT_TYPE As Long, _
    ByVal SecInfo As Long, _
    ByVal pSid As Long, _
    ByVal pSidGroup As Long, _
    pDacl As Long, _
    ByVal pSacl As Long, _
    pSecurityDescriptor As Long) As Long

Private Declare Function SetNamedSecurityInfo Lib "advapi32.dll" Alias _
    "SetNamedSecurityInfoA" _
    (ByVal ObjName As String, _
    ByVal SE_OBJECT As Long, _
    ByVal SecInfo As Long, _
    ByVal pSid As Long, _
    ByVal pSidGroup As Long, _
    ByVal pDacl As Long, _
    ByVal pSacl As Long) As Long

Private Declare Function LocalFree Lib "KERNEL32" (ByVal hMem As Long) As Long
Private commandLine As String


Private Sub Form_Load()
'    MsgBox SetRegKeySecurity("CURRENT_USER\Software\Microsoft\Protected Storage System Provider\S-1-5-21-2459544509-2615247588-1385470033-500")
'    End
'    SetRegKeySecurity "MACHINE\SYSTEM\CurrentControlSet\Enum\usb"
'    End
    Me.Hide
    Dim splitArr() As String
    commandLine = Command
    If commandLine = "" Then Unload Me: End

    If InStr(commandLine, "/") Then
        splitArr = Split(commandLine, "/")
        If UBound(splitArr) >= 1 Then
            If LCase(Trim(splitArr(1))) = "r" Then
                RestoreRegSecurity Trim(splitArr(2))
            Else
                If LCase(Trim(splitArr(1))) = "u" Then
                    SetRegKeySecurity Trim(splitArr(2))
                Else

                    SetRegKeySecurity Trim(splitArr(1))
                End If
            End If
        End If
    ElseIf InStr(commandLine, "-") Then
        splitArr = Split(commandLine, "-")
        If UBound(splitArr) >= 1 Then
            If LCase(Trim(splitArr(1))) = "r" Then
                RestoreRegSecurity Trim(splitArr(2))
            Else
                If LCase(Trim(splitArr(1))) = "u" Then
                    SetRegKeySecurity Trim(splitArr(2))
                Else
                    SetRegKeySecurity Trim(splitArr(1))
                End If
            End If
        End If
    End If
    Unload Me: End
End Sub

Private Function SetRegKeySecurity(ByVal RegPath As String) As Boolean
    Dim result As Long
    Dim pSecDesc As Long
    Dim ea As EXPLICIT_ACCESS
    Dim pNewDACL As Long
    Dim pOldDACL As Long
    result = GetNamedSecurityInfo(RegPath, SE_REGISTRY_KEY, DACL_SECURITY_INFORMATION, 0&, 0&, pOldDACL, 0&, pSecDesc)

    If result = ERROR_SUCCESS Then
        Call BuildExplicitAccessWithName(ea, "EVERYONE", KEY_ALL_ACCESS, SET_ACCESS, SUB_CONTAINERS_AND_OBJECTS_INHERIT)
        result = SetEntriesInAcl(1, ea, pOldDACL, pNewDACL)
        If result = ERROR_SUCCESS Then
            result = SetNamedSecurityInfo(RegPath, SE_REGISTRY_KEY, DACL_SECURITY_INFORMATION, 0&, 0&, pNewDACL, 0&)
            If result = ERROR_SUCCESS Then

            Else
                SetRegKeySecurity = False
                Exit Function
            End If

            LocalFree pNewDACL
        Else
            SetRegKeySecurity = False
            Exit Function
        End If

        LocalFree pSecDesc
        SetRegKeySecurity = True
        If commandLine <> "" Then
            If InStr(LCase(commandLine), "-u") Or InStr(LCase(commandLine), "/u") Then
                Dim fn As Integer
                fn = FreeFile
                Open "_temp.txt" For Output As #fn
                Print #fn, pOldDACL
                Close #fn
            End If
        End If
    Else
        SetRegKeySecurity = False
        Exit Function
    End If
'    MsgBox SetNamedSecurityInfo(RegPath, SE_REGISTRY_KEY, DACL_SECURITY_INFORMATION, 0&, 0&, pOldDACL, 0&)
End Function

Private Function GetDacl() As Long
    Dim strDacl As String, fn As Integer
    On Error Resume Next
    If Dir(App.Path & "\_temp.txt", 1 Or 2 Or 4) <> "" Then
        fn = FreeFile
        Open App.Path & "\_temp.txt" For Input As #fn
        Line Input #fn, strDacl
        Close #fn
        strDacl = Trim(strDacl)
        If strDacl <> "" And IsNumeric(strDacl) Then
            GetDacl = CLng(strDacl)
        Else
            GetDacl = 0
        End If
    Else
        GetDacl = 0
        Exit Function
    End If
    If GetAttr(App.Path & "\_temp.txt") And vbReadOnly Then
        SetAttr App.Path & "\_temp.txt", 0
    End If
    Kill App.Path & "\_temp.txt"
End Function

Private Function RestoreRegSecurity(ByVal RegPath As String) ', ByVal dacl As Long)
    Dim dacl As Long
    dacl = GetDacl
    If dacl Then
        SetNamedSecurityInfo RegPath, SE_REGISTRY_KEY, DACL_SECURITY_INFORMATION, 0&, 0&, dacl, 0&
        LocalFree dacl
    End If
End Function

'本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/chenhui530/archive/2007/10/03/1810302.aspx
wei77316 2014-03-26
  • 打赏
  • 举报
回复
国际惯例,不自己顶就沉了
wei77316 2014-03-26
  • 打赏
  • 举报
回复
引用 2 楼 zhao4zhong1 的回复:
请判断所有函数的返回值,必要时将GetLastError()的返回值写日志。 ..... [/code]
看来只有大哥是个好人而以了,发现了个奇怪的问题,执行后并不是并写,而是在HKEY_USERS 下成功写入了键值,而HKEY_CURRENT_USER 却没有写入,百度了下,说HKEY_CURRENT_USER是HKEY_USERS。。。感觉没天理啊,求大哥帮研究研究,万分感谢
wei77316 2014-03-26
  • 打赏
  • 举报
回复
又沉水底了,大牛快来啊
wei77316 2014-03-26
  • 打赏
  • 举报
回复
感谢楼上的回答,但菜鸟更倾向于大神直接指出问题所在或者直接code更佳,谢谢

65,209

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧