虚拟当前用户

星链V3的2048条波束与1Tbps:多波束相控阵的工程代价 低轨卫星通信的容量提升,核心在于多波束相控阵天线的空间复用能力。相控阵通过控制大量天线单元的相位,可在同一阵面同时形成多条独立指向的波束,从而在有限频谱内成倍提升系统容量。星链V3宣称的2048条波束与1 Tbps汇聚吞吐量,正是基于这一原理:更多波束意味着更高的频率复用系数和更灵活的资源调度。但工程实现并非免费午餐,数字背后是供电、散热、重量、发射成本及运维复杂度的急剧攀升。从用户侧看,更精细的波束也带来切换频繁、低仰角衰减等新挑战。本文从多波束相控阵的基础原理出发,拆解波束形成、频谱复用和动态调度的工程 阅读详情

 

很多时候使用注册表操作是不安全的,因此很多重要的场合是不会使用注册表操作去达到目的的。但不可否认在很多小的地方,使用注册表操作是十分方便而且直接有效的。有些内容的注册表操作时常会涉及到当前用户的操作,在注册表中就体现在了HKEY_CURRENT_USER的子项上(系统通常情况下只具有如下HKEY_CLASSES_ROOT,HKEY_CURRENT_USER,HKEY_LOCAL_MACHINE,HKEY_USERS,HKEY_CURRENT_CONFIG五个子项)。

当我们需要进行注册表操作的应用程序以进程方式运行的时候,是不用担心注册表操作失效的问题的。但是一旦应用程序以服务的方式启动,那么其针对HKEY_CURRENT_USER下的子项操作就会出现问题,基本体现是功能失效,无法操作。这是因为应用程序以服务方式运行时无法针对某一个当前用户操作。当然,如果这个注册表操作在HKEY_LOCAL_MACHINE项下可以完成,并能达到预期目的,我们就没有必要大费周章了。

要使服务运行状态下的应用程序通过注册表操作影响当前用户的状态,就必须在操作之前进行当前用户的虚拟。一般来说我们可以通过如下两个函数就可以实现了:

// 获得Explorer进程的PID
  DWORD GetExplorerPID ()
  {
   HANDLE         hProcessSnap = NULL;
   DWORD          dwRet      = 0;
   PROCESSENTRY32 pe32      = {0}; 
   hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 
   if (hProcessSnap == INVALID_HANDLE_VALUE)
    return 0; 
   pe32.dwSize = sizeof(PROCESSENTRY32); 
   if (Process32First(hProcessSnap, &pe32))
   {
    DWORD         dwPriorityClass;
    BOOL          bGotModule = FALSE;
    MODULEENTRY32 me32       = {0}; 
    do
    {
     if( _stricmp(pe32.szExeFile, "Explorer.EXE") == 0)
      return pe32.th32ProcessID;
    }
    while (Process32Next(hProcessSnap, &pe32)); 
   }
   else
    dwRet = 0;    
   CloseHandle (hProcessSnap);
   return (dwRet);
  }
  // 虚拟当前用户
  BOOL ImpersonateCurrentUser()
  {   BOOL bRet;
   HANDLE  ph;
   DWORD ExplorerPID = GetExplorerPID();
   if(ExplorerPID == 0)
   {    return 0;   }
   ph =  OpenProcess(PROCESS_ALL_ACCESS, FALSE, ExplorerPID);
   if(!ph)
   {    return 0;   }
   HANDLE token = 0;
   bRet = OpenProcessToken(ph, TOKEN_QUERY|TOKEN_DUPLICATE, &token); 
   if(!bRet)
   {    return 0;   }
   bRet = ImpersonateLoggedOnUser(token);
   return bRet;
  }

其中的api函数可能需要包含一些头文件,比如tlhelp32.h和windows.h,如何还需要其他的可以自己去msdn上查;到了这一步虚拟当前用户算是成功了。不过ImpersonateCurrentUser这个函数大家可以发现,存在句柄没有释放,当然也不能释放,如果释放,虚拟就没有作用。但是一旦这种虚拟当前用户在轮询中出现,问题就出来了,会使应用程序产生很多的句柄并且拽着不放。

出现这种情况的话,我们可以改进ImpersonateCurrentUser函数,在应用程序进行注册表操作之前先建立一个句柄,传进ImpersonateCurrentUser函数中,当注册表操作完成以后,再释放。注意一点,释放也就是杀掉句柄以后,不要忘记使用RevertToSelf();  函数返回当前用户

BOOL ImpersonateCurrentUser(HANDLE &htoken)
  {
   BOOL bRet;
   HANDLE  ph;
   DWORD ExplorerPID = GetExplorerPID();
   if(ExplorerPID == 0)
   {
    return 0;
   }
   
   ph =  OpenProcess(PROCESS_ALL_ACCESS, FALSE, ExplorerPID);
   if(!ph)
   {
    return 0;
   }
   bRet = OpenProcessToken(ph, TOKEN_QUERY|TOKEN_DUPLICATE, &htoken); 
   if(!bRet)
   {
    return 0;
   }
   bRet = ImpersonateLoggedOnUser(htoken);
   if(!bRet)
   {
    return 0;
   }
   CloseHandle(ph);
   return bRet;
  }

好像到了这一步就没有问题了,其实不然,通过这些一般来说是可以了,但是有时候还是出现问题,注册表操作无效,主要还是应用程序以服务方式运行时找当前用户的问题,也就是说到这一步还是不能确保正确。

要如何做才可以呢?在注册表中有这么一个根项HKEY_USERS,它是用来管理系统所有用户的,它的每一个子项都对应系统的一个用户,这些子项名称可以看作时那些用户的suid号。而HKEY_USERS项是服务可以直接作用的,如果我们能找到当前用户的suid,然后通过修改HKEY_USERS下该suid号下面对应的注册表项来达到本来的目的。因为HKEY_USERS下当前用户suid号对应的子项的注册表项和HKEY_CURRENT_USER是完全相同并实时更新的,改动其中一个就必然改动了另一个,那么解决方法就出来了。

BOOL  ImpersonateCurrentUser(std::string &sid)
  {
   HANDLE handle;
   char namebuf[MAX_PATH];
   DWORD buflen = MAX_PATH;
   char usid[MAX_PATH];
   char domain[MAX_PATH];
   DWORD usidlen = MAX_PATH;
   DWORD udomainsidlen = MAX_PATH;

   BOOL ret = UT::Tools::ImpersonateCurrentUser(handle);//首先模拟当前用户身份
   if(!ret)
   {
    return FALSE;
   }
   
   ret = GetUserName(namebuf, &buflen);
   if(!ret)
    return FALSE;
   SID_NAME_USE pnu;
   ret = LookupAccountName(NULL, namebuf, (SID *)usid, &usidlen, domain, &udomainsidlen, &pnu);
   if(!ret)
    return FALSE;
   char *usidstr;
   ret = ConvertSidToStringSidA((SID *)usid, &usidstr);
   if(!ret)
    return FALSE;

   sid = usidstr;

   LocalFree(usidstr);
   CloseHandle(handle);

RevertToSelf();   //返回原来的用户

   return TRUE;
  }

通过这个函数我们可以返回当前用户的suid号,再通过操作HKEY_USERS和这个suid号下对应的注册表项就可以达到我们的目的了。其实就相当于来说把原来的注册表操作中的HKEY_CURRENT_USER给替换成HKEY_USERS+suid。   注意,这个函数里要使用到头文件Sddl.h。

还是举个例子来说吧,在进程中操作注册表项HKEY_CURRENT_USER/Software/Kingsoft/Office/WPS/Addins/KSAddins.XDictHelper,我们就需要在服务中使用下面的键值了(HKEY_USERS+suid)/Software/Kingsoft/Office/WPS/Addins/KSAddins.XDictHelper。

 

通过产品的使用验证,发现以上还有有问题的。问题就在用户上,获取sid号是通过用户获取的对应的id串。但是如果用户获取的不正确呢。产品问题中暴露出来的一个问题。当一个域中某个pc,拥有同当前域用户相同名称的本地账户的时候问题就出现了。比如,域中计算机A使用域账户Test登陆,同时呢,计算机A中也有一个名叫Test的本地账户。如果还是按照上面的做法的话,看起来是没有任何错误的。但是使用起来就会发现HKEY_USERS+SUID是不存在的,为什么呢,经过调试发现,GetUserName的时候是没有错误的,取出来的用户名确实是Test,但是在LookupAccountName的时候就出现错误了。因为根据msdn的说法,其获取suid的顺序是先本地账户查找,如果查找不到就到信任的域中查找。明白了,原来当登陆域用户的时候,LookupAccountName查找suid的时候错误了。那么怎么解决呢。简单,我们在取当前用户的时候取出当前计算机登陆的域。如果可以取出,则在LookupAccountName的时候传入的用户名就不能只是username了,而应该是domainname/username。如果取出域名为空,则继续使用username来取suid了。注意哦,我根据使用的Api函数包含适当的头文件以及lib文件,Netapi32.lib和Lm.h哦 .......下面是更改后的代码:

2010-03-05

BOOL DLLMODULENAME_LIB_API ImpersonateCurrentUser(std::string &sid)
  {
   HANDLE handle;
   char namebuf[MAX_PATH];
   DWORD buflen = MAX_PATH;
   char usid[MAX_PATH];
   char domain[MAX_PATH];
   DWORD usidlen = MAX_PATH;
   DWORD udomainsidlen = MAX_PATH;

   BOOL ret = UT::Tools::ImpersonateCurrentUser(handle);//首先模拟当前用户身份
   if(!ret)
   {
    return FALSE;
   }
   
   WKSTA_USER_INFO_1* workstationInfo;
   const NET_API_STATUS status = NetWkstaUserGetInfo(NULL,1,(LPBYTE*)&workstationInfo);
   if(status == NERR_Success)
   {

    std::wstring  domainname = workstationInfo->wkui1_logon_domain;
    std::wstring  username   = workstationInfo->wkui1_username;
    NetApiBufferFree((LPBYTE*)&workstationInfo);

    std::string namedomain = UT::Tools::UTStringConvert::ToAString(domainname);
    std::string nameuser   = UT::Tools::UTStringConvert::ToAString(username);
    std::string newName = nameuser;
    if(!namedomain.empty())
    {
     newName = namedomain;
     newName += "//";
     newName += nameuser;
    }
    nameuser = newName;
    strcpy_s(domain,MAX_PATH,namedomain.c_str());
    strcpy_s(namebuf,MAX_PATH,nameuser.c_str());

   }
   else
   {
    ret = GetUserName(namebuf, &buflen);
    if(!ret)
    {
     return FALSE;
    }
   }

   SID_NAME_USE pnu;
   ret = LookupAccountName(NULL, namebuf, (SID *)usid, &usidlen, domain, &udomainsidlen, &pnu);
   if(!ret)
   {

    return FALSE;
   }
   char *usidstr;
   ret = ConvertSidToStringSidA((SID *)usid, &usidstr);
   if(!ret)
   {
    return FALSE;
   }

   sid = usidstr;

   LocalFree(usidstr);
   CloseHandle(handle);

   RevertToSelf();

   return TRUE;
  }

Linux V3H 平台开发系列讲解(串行解串篇)2.2.2 MAX9296 MAX96705 GMSL1 续篇--串行器提前配置 本文详细介绍了在Linux v3h平台上,针对Max9296解串器和解串器max96705的详解配置,验证可出图,内容包括串行器解串器介绍、链路框架、硬件连接、速率配置,以及遇到的图像异常问题及解决方法。 阅读详情

相关推荐

AVL_Cruise_interface\Simulink联合仿真

分享了AVL_Cruise通过interface模块与Simulink进行联合仿真的过程

qq_64735036的博客 2678

C/C++ 操作注册表与服务

注册表,与服务常用来注册自启动程序,开机自动运行,多用于后门。遍历注册表 HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run我们需要将服务放到 C://windows/system32/目录下,然后注册服务才能运行.

微软技术分享 1万+

步进电机

步进电机

happygrilclh的博客 2141

服务程序C#编写系统服务,注册表读写问题

默认情况下,服务与已登录的用户在不同的安全上下文中运行。服务在称为 LocalSystem 的默认系统帐户的上下文中运行,该帐户给服务提供的系统资源访问特权不同于给用户提供的。     所以服务程序访问注册表的CurrentUser时并不是你当前登陆账号下的CurrentUser,所以在你当前陆账号下的CurrentUser下建立的键值,服务程序根本无法访问到,给人的错觉就是服务程序无法读写注册表

2004v2004的专栏 3397

安装部署 Guacamole 远程桌面网关

Guacamole 是Apache基金会提供的一组基于web的远程桌面访问工具,支持 VNC、RDP、SSH、 Telnet 等协议,支持远程透传音视频。

UsamaBinLaden6976498的专栏 1963

基于 WebGoat 平台的 SQL 注入攻击

基于 WebGoat 平台的 SQL 注入攻击

Labulongdong的博客 3523

python中,将包安装到用户个人目录中、安装到虚拟环境中、安装到当前工作目录中的区别与选择

作为程序员,个人电脑中,安装Python包时,也要避免“全局”安装,通常有三种“局部”的安装方式:将包安装到用户个人目录中、安装到虚拟环境中、安装到当前工作目录中。

qiy_icbc的博客 1378

如何免费访问和使用Gemini API?

Gemini Ultra具有最先进的性能,在几个指标上超过了GPT-4的性能。它是第一个在大规模多任务语言理解基准测试中超越人类专家的模型,该基准测试57个不同学科的世界知识和解决问题的能力。Gemini是谷歌迄今为止开发的最先进、最庞大的AI模型。它为多模态而建,理解并处理不同类型的数据,比如文本、代码、音频、图像和视频。下面我们将加载Masood Aslami的图像,并用它来测试Gemini Pro Vision的多模态性。有了Gemini可以为查询提供图像、音频和文本,获得几乎完美的答案。

java_cjkl的博客 1万+

【虚拟机使用当前用户无权限,创建root账户】

【虚拟机使用当前用户无权限,创建root账户】

m0_49762804的博客 8608

使用R语言实现循环神经网络RNN进行文本生成

首先,让我们回顾一下循环神经网络(Recurrent Neural Networks,RNN)的基本概念。RNN是一种深度学习技术,特别适合处理序列数据,如时间序列和文本数据。RNN的关键特性是它的隐藏状态,这个状态可以捕捉到当前输入之前的信息。这使得RNN能够利用前面的信息来影响后续的输出,从而对序列数据进行有效的处理。

斌擎科技 725

手把手教你学simulink(95.1)--PID控制实例:基于Simulink的PID控制温度控制系统建模与仿真

温度控制是工业自动化、家用电器、医疗设备以及航空航天等领域中常见的控制问题。通过精确的温度控制,可以提高生产效率、降低能耗并确保产品质量。PID(比例-积分-微分)控制器因其结构简单、性能稳定且易于实现而被广泛应用于各种温度控制系统。本项目旨在通过MATLAB/Simulink平台设计和验证一个基于PID控制的温度控制系统,重点研究PID参数调优方法、系统动态响应特性以及稳态误差消除能力。

MHD0815的博客 793

windows c++ 服务 当前用户提权_星外虚拟主机提权实战案例

声明:该公众号大部分文章来自作者日常学习笔记,也有少部分文章是经过原作者授权和其他公众号白名单转载,未经授权,严禁转载,如需转载,联系开白。请勿利用文章内的相关技术从事非法测试,如因此产生的一切不良后果与文章作者和本公众号无关。所有话题标签:#Web安全 #漏洞复现 #工具使用 #权限提升#权限维持#防护绕过#内网安全 #实战案例#其他笔记 #资源分享0x...

weixin_39628268的博客 195

【C2000系列DSP的双向DC-DC电源】基于TMS320F28034的DC-DC项目开发流程

理解DC-DC 双向电源(基于 TMS320F28034)的开发流程,需要从功能拆解、开发步骤、验证 / 测试项

昔时扬尘处 324

使用虚拟环境virtualenv 创建虚拟环境出现PermissionError: [Errno 13] Permission denied:

使用虚拟环境virtualenv 创建虚拟环境出现PermissionError: [Errno 13] Permission denied: 原因:虚拟环境安装的目录所属用户非当前用户 解决办法:将目录及其文件的所有者改为当前用户 解决命令:sudo chown -R 当前用户 待更改用户的目录/ 当前用户查看命令:whoami ...

weixin_43903378的博客 3709

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

Python虚拟环境中pip install时没有权限问题

virtualenv Permission denied 新建的python虚拟环境的目录的所属者必须是当前用户,才不会出现这种错误 比如 virtualenv py27 sudo chown zzf py27 再进入这个虚拟环境就不会出现这个情况了 转载于:https://www.cnblogs.com/zongfa/p/8531791.html...

weixin_33725722的博客 775

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

Oracle中的虚拟表:dual

标题Oracle中的虚拟表:dual dual是Oracle中的一个虚拟表,无论什么时候,它只有一条记录:X 那这个表有什么卵用呢?还是有点卵用的:它可以拿来凑数,以满足语法要求。具体看几个例子就了然了: 1、查当前登陆用户名 2、当计算器使 3、获取一个随机数 4、拼接字符串 5、获取当前日期   格式不太友好,还可以调用个系统函数调整一下格式: 简单来说,dual就是个接盘侠,当你...

qq_39832721的博客 303

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

VirsualBox虚拟机超级用户组问题

超级用户下输入visudo命令即可编辑sudoer文件(输入nano /etc/sudoers效果是一样的)添加此行:kevin ALL=(ALL:ALL) ALL,表示为kevin用户添加sudo权限。4. ctrl+s保存,ctrl+x退出即可。终端输入su root切换为超级用户。将当前用户添加到超级用户组即可。

CCSU 25届毕业生 目前就职于移远通信 岗位是蓝牙软件工程师 学习蓝牙Spec中 文章是个人笔记 分享给大家 感谢关注~ 216

linux如何锁定某个用户,技术|vlock – 一个锁定 Linux 用户虚拟控制台或终端的好方法...

虚拟控制台是 Linux 上非常重要的功能,它们给系统用户提供了 shell 提示符,以保证用户在登录和远程登录一个未安装图形界面的系统时仍能使用。一个用户可以同时操作多个虚拟控制台会话,只需在虚拟控制台间来回切换即可。用 vlock 锁定 Linux 用户控制台或终端这篇使用指导旨在教会大家如何使用 vlock 来锁定用户虚拟控制台和终端。vlock 是什么?vlock 是一个用于锁定一个或多个...

weixin_39799290的博客 436

VisualBox启动虚拟机报错:The VM session was closed before any attempt to power it on.

VisualBox启动虚拟机报错:The VM session was closed before any attempt to power it on

qq_40078436的博客 8886

1查看当前虚拟机的ip地址

其中,inet为当前虚拟机的ip地址,netmask为当前虚拟机的也可以通过ip addr。

2401_89404250的博客 1155

Centos7 修改root用户的密码

目录 一、查看当前用户 二、使用命令修改密码 一、查看当前用户 whoami 如果不是root用户, 需要切换至root用户 二、使用命令修改密码 passwd 修改完成后, 重启虚拟机, 即可用新密码登录. ...

DZP_dream的博客 8798

更改虚拟机的系统用户名

虚拟机修改系统主机名,一招即管

qq_51505441的博客 8418

004_使用IVirtualDesktopManager操作虚拟桌面

本文翻译自MSDN博客,如有错误,还请指正。 在win10中选择虚拟桌面 win10中引进了一个新的概念叫做虚拟桌面。现在MSDN对其的指南上是这么描述的: 用户可以将若干个窗口放在一起来创建一个虚拟桌面。每个窗口是虚拟桌面的一部分。当一个虚拟桌面隐藏了,和它相关的所有窗口也会被隐藏。这就意味着允许用户创建多个工作环境并可以在它们之间切换(PS:快捷键是ctrl+win+左右方向键)。同样的,当一个虚拟桌面被激活后,和它相关的窗口会显示在屏幕上。 为了支持这个概念,应用应该避免自动将用户从一个虚拟桌

suxiaotie的博客 2028

锁定 Linux 用户虚拟控制台的好命令–volck

4、 选项 -s 或 --disable-sysrq,在禁用虚拟控制台的同时禁用 SysRq 功能,只有在与 -a 或 --all 同时使用时才起作用。选项 -c 或 --current,用于锁定当前的会话,该参数为运行 vlock 时的默认行为。3、 选项 -n 或 --new,调用时后,会在锁定用户的控制台会话前切换到一个新的虚拟控制台。选项 -a 或 --all,用于锁定所有用户的控制台会话,并禁用虚拟控制台间切换。2、 锁定所有你的虚拟控制台会话,并禁用虚拟控制台间切换,

Free雅轩的博客 236
上一篇: Win32窗体工程--监控U盘插入和拔出(1)
下一篇: 时间获取,以及时间格式字符串转化
rptrpt
博客等级 码龄19年 8粉丝 9原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值