创建高权限进程

C#利用服务创建具有System权限指定Session的进程 1. 起因 因为需要在锁屏界面和UAC界面搞点事情,经过测试,发现锁屏和系统弹出UAC 均是切换到了Windows 的安全桌面,一般Windows在启动后(这里说的Windows指的是Vista之后的)会有一个Default和一个安全桌面。这里的Default 就是普通程序运行的桌面,在弹出UAC 或者 锁屏的时候Windows则会自动切换到 安全桌面,不同桌面的消息等是隔离的。Windows... 阅读详情
文章作者:sinister
信息来源:白细胞

Author:  sinister
Email:   sinister@whitecell.org
Homepage: http://www.whitecell.org  
Date:   2006-02-12




// 
// 写这个初衷是为了让 Windows 任务管理器可以结束掉一些服务
// 和僵死进程,用 pslist/pskill 之类工具无法获得象任务管理
// 器那样丰富的信息,还得来回切换,麻烦的很。最初想写个 驱动
// 监视任务管理器运行,使用 SYSTEM 进程 TOKEN 替换来达到目的。
// 后来觉得通用性不好,就改用了这种方法。此方法还可使 regedit 
// 查看、编辑 SAM 等注册表键,何乐而不为。
//
// wssrun taskmgr.exe
// wssrun regedit.exe
//


#include 
#include 
#include 
#include 
#include 
#include 
#include 

#pragma comment(lib,"Shlwapi.lib")


/////////////////////////////////////////////////////////////////
// 函数类型 :自定义工具函数
// 函数模块 : 
////////////////////////////////////////////////////////////////
// 功能 :提升当前进程权限
// 注意 :
/////////////////////////////////////////////////////////////////
// 作者 : sinister
// 发布版本 : 1.00.00
// 发布日期 : 2006.2.09
/////////////////////////////////////////////////////////////////
// 重  大  修  改  历  史
////////////////////////////////////////////////////////////////
// 修改者 :
// 修改日期 :
// 修改内容 :
/////////////////////////////////////////////////////////////////

BOOL
EnableDebugPriv( LPCTSTR szPrivilege )
{
  HANDLE hToken;
  LUID sedebugnameValue;
  TOKEN_PRIVILEGES tkp;

  if ( !OpenProcessToken( GetCurrentProcess(),
                  TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
                  &hToken ) )
  {
   return FALSE;
  }
  if ( !LookupPrivilegeValue( NULL, szPrivilege, &sedebugnameValue ) )
  {
   CloseHandle( hToken );
   return FALSE;
  }

  tkp.PrivilegeCount = 1;
  tkp.Privileges[0].Luid = sedebugnameValue;
  tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

  if ( !AdjustTokenPrivileges( hToken, FALSE, &tkp, sizeof tkp, NULL, NULL ) )
  {
   CloseHandle( hToken );
   return FALSE;
  }

  return TRUE;
}

/////////////////////////////////////////////////////////////////
// 函数类型 :自定义工具函数
// 函数模块 : 
////////////////////////////////////////////////////////////////
// 功能 :通过指定进程名得到其进程 ID
// 注意 : 
/////////////////////////////////////////////////////////////////
// 作者 : sinister
// 发布版本 : 1.00.00
// 发布日期 : 2006.2.09
/////////////////////////////////////////////////////////////////
// 重  大  修  改  历  史
////////////////////////////////////////////////////////////////
// 修改者 :
// 修改日期 :
// 修改内容 :
/////////////////////////////////////////////////////////////////

DWORD
GetProcessId( LPCTSTR szProcName )
{
  PROCESSENTRY32 pe;  
  DWORD dwPid;
  DWORD dwRet;
  BOOL bFound = FALSE;

  //
  // 通过 TOOHLP32 函数枚举进程
  //

  HANDLE hSP = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
  if ( hSP )
  {
   pe.dwSize = sizeof( pe );

   for ( dwRet = Process32First( hSP, &pe );
       dwRet;
       dwRet = Process32Next( hSP, &pe ) )
   {
    //
    // 使用 StrCmpNI 比较字符传,可忽略大小写
    //
    if ( StrCmpNI( szProcName, pe.szExeFile, strlen( szProcName ) ) == 0 )
    {
      dwPid = pe.th32ProcessID;
      bFound = TRUE;
      break;
    }
   }

   CloseHandle( hSP );

   if ( bFound == TRUE )
   {
    return dwPid;
   }
  }

  return NULL;
}

/////////////////////////////////////////////////////////////////
// 函数类型 :自定义工具函数
// 函数模块 : 
////////////////////////////////////////////////////////////////
// 功能 : 创建具有高权限的进程
// 注意 :
/////////////////////////////////////////////////////////////////
// 作者 : sinister
// 发布版本 : 1.00.00
// 发布日期 : 2006.2.09
/////////////////////////////////////////////////////////////////
// 重  大  修  改  历  史
////////////////////////////////////////////////////////////////
// 修改者 :
// 修改日期 :
// 修改内容 :
/////////////////////////////////////////////////////////////////

BOOL
CreateSystemProcess( LPTSTR szProcessName )
{
  HANDLE hProcess;
  HANDLE hToken, hNewToken;
  DWORD dwPid;

  PACL pOldDAcl = NULL;
  PACL pNewDAcl = NULL;
  BOOL bDAcl;
  BOOL bDefDAcl;
  DWORD dwRet;

  PACL pSacl = NULL;
  PSID pSidOwner = NULL;
  PSID pSidPrimary = NULL;
  DWORD dwAclSize = 0;
  DWORD dwSaclSize = 0;
  DWORD dwSidOwnLen = 0;
  DWORD dwSidPrimLen = 0;

  DWORD dwSDLen;
   EXP LICIT_ACCESS ea;
  PSECURITY_DESCRIPTOR pOrigSd = NULL;
  PSECURITY_DESCRIPTOR pNewSd = NULL;

  STARTUPINFO si;
  PROCESS_INFORMATION pi;

  BOOL bError;

  if ( !EnableDebugPriv( "SeDebugPrivilege" ) )
  {
    printf ( "EnableDebugPriv() to failed!\n" );

   bError = TRUE;
   goto Cleanup;
  }

  //
  // 选择 WINLOGON 进程
  //
  if ( ( dwPid = GetProcessId( "WINLOGON.EXE" ) ) == NULL )
  {
   printf( "GetProcessId() to failed!\n" );  

   bError = TRUE;
   goto Cleanup;
  }

  hProcess = OpenProcess( PROCESS_QUERY_INFORMATION, FALSE, dwPid );
  if ( hProcess == NULL )
  {
   printf( "OpenProcess() = %d\n", GetLastError() );  

   bError = TRUE;
   goto Cleanup;
  }

  if ( !OpenProcessToken( hProcess, READ_CONTROL | WRITE_DAC, &hToken ) )
  {
   printf( "OpenProcessToken() = %d\n", GetLastError() );

   bError = TRUE;
   goto Cleanup;
  }

  //
  // 设置 ACE 具有所有访问权限
  //
  ZeroMemory( &ea, sizeof( EXPLICIT_ACCESS ) );
  BuildExplicitAccessWithName( &ea,
                     "Everyone",
                     TOKEN_ALL_ACCESS,
                     GRANT_ACCESS,
                     0 );

  if ( !GetKernelObjectSecurity( hToken,
                      DACL_SECURITY_INFORMATION,
                      pOrigSd,
                      0,
                      &dwSDLen ) )
  {
   //
   // 第一次调用给出的参数肯定返回这个错误,这样做的目的是
   // 为了得到原安全描述符 pOrigSd 的长度
   //
   if ( GetLastError() == ERROR_INSUFFICIENT_BUFFER )
   {
    pOrigSd = ( PSECURITY_DESCRIPTOR ) HeapAlloc( GetProcessHeap(),
                                   HEAP_ZERO_MEMORY,
                                   dwSDLen );
    if ( pOrigSd == NULL )
    {
      printf( "Allocate pSd memory to failed!\n" );

      bError = TRUE;
      goto Cleanup;
    }

    //
    // 再次调用才正确得到安全描述符 pOrigSd
    //
    if ( !GetKernelObjectSecurity( hToken,
                         DACL_SECURITY_INFORMATION,
                         pOrigSd,
                         dwSDLen,
                         &dwSDLen ) )
    {
      printf( "GetKernelObjectSecurity() = %d\n", GetLastError() );
      bError = TRUE;
      goto Cleanup;
    }
   }
   else
   {
    printf( "GetKernelObjectSecurity() = %d\n", GetLastError() );
    bError = TRUE;
    goto Cleanup;
   }
  }

  //
  // 得到原安全描述符的访问控制列表 ACL
  //
  if ( !GetSecurityDescriptorDacl( pOrigSd, &bDAcl, &pOldDAcl, &bDefDAcl ) )
  {
   printf( "GetSecurityDescriptorDacl() = %d\n", GetLastError() );

   bError = TRUE;
   goto Cleanup;
  }

  //
  // 生成新 ACE 权限的访问控制列表 ACL
  //
  dwRet = SetEntriesInAcl( 1, &ea, pOldDAcl, &pNewDAcl ); 
  if ( dwRet != ERROR_SUCCESS )
  {
   printf( "SetEntriesInAcl() = %d\n", GetLastError() ); 
   pNewDAcl = NULL;

   bError = TRUE;
   goto Cleanup;
  } 

  if ( !MakeAbsoluteSD( pOrigSd,
                pNewSd,
                &dwSDLen,
                pOldDAcl,
                &dwAclSize,
                pSacl,
                &dwSaclSize,
                pSidOwner,
                &dwSidOwnLen,
                pSidPrimary,
                &dwSidPrimLen ) )
  {
   //
   // 第一次调用给出的参数肯定返回这个错误,这样做的目的是
   // 为了创建新的安全描述符 pNewSd 而得到各项的长度
   //
   if ( GetLastError() == ERROR_INSUFFICIENT_BUFFER )
   {
    pOldDAcl = ( PACL ) HeapAlloc( GetProcessHeap(),
                         HEAP_ZERO_MEMORY,
                         dwAclSize );
    pSacl = ( PACL ) HeapAlloc( GetProcessHeap(),
                       HEAP_ZERO_MEMORY,
                       dwSaclSize );
    pSidOwner = ( PSID ) HeapAlloc( GetProcessHeap(),
                          HEAP_ZERO_MEMORY,
                          dwSidOwnLen );
    pSidPrimary = ( PSID ) HeapAlloc( GetProcessHeap(),
                           HEAP_ZERO_MEMORY,
                           dwSidPrimLen );
    pNewSd = ( PSECURITY_DESCRIPTOR ) HeapAlloc( GetProcessHeap(),
                                  HEAP_ZERO_MEMORY,
                                  dwSDLen );

    if ( pOldDAcl == NULL ||
        pSacl == NULL ||
        pSidOwner == NULL ||
        pSidPrimary == NULL ||
        pNewSd == NULL )
    {
      printf( "Allocate SID or ACL to failed!\n" );

      bError = TRUE;
      goto Cleanup;
    }

    //
    // 再次调用才可以成功创建新的安全描述符 pNewSd
    // 但新的安全描述符仍然是原访问控制列表 ACL
    //
    if ( !MakeAbsoluteSD( pOrigSd,
                   pNewSd,
                   &dwSDLen,
                   pOldDAcl,
                   &dwAclSize,
                   pSacl,
                   &dwSaclSize,
                   pSidOwner,
                   &dwSidOwnLen,
                   pSidPrimary,
                   &dwSidPrimLen ) )
    {
      printf( "MakeAbsoluteSD() = %d\n", GetLastError() );

      bError = TRUE;
      goto Cleanup;
    }
   }
   else
   {
    printf( "MakeAbsoluteSD() = %d\n", GetLastError() );

    bError = TRUE;
    goto Cleanup;
   }
  }

  //
  // 将具有所有访问权限的访问控制列表 pNewDAcl 加入到新的
  // 安全描述符 pNewSd 中
  //
  if ( !SetSecurityDescriptorDacl( pNewSd, bDAcl, pNewDAcl, bDefDAcl ) )
  {
   printf( "SetSecurityDescriptorDacl() = %d\n", GetLastError() );

   bError = TRUE;
   goto Cleanup;
  }

  //
  // 将新的安全描述符加到 TOKEN 中
  //
  if ( !SetKernelObjectSecurity( hToken, DACL_SECURITY_INFORMATION, pNewSd ) )
  {
   printf( "SetKernelObjectSecurity() = %d\n", GetLastError() );

   bError = TRUE;
   goto Cleanup;
  }

  //
  // 再次打开 WINLOGON 进程的 TOKEN,这时已经具有所有访问权限
  //
  if ( !OpenProcessToken( hProcess, TOKEN_ALL_ACCESS, &hToken ) )
  {
   printf( "OpenProcessToken() = %d\n", GetLastError() );  

   bError = TRUE;
   goto Cleanup;
  }

  //
  // 复制一份具有相同访问权限的 TOKEN
  //
  if ( !DuplicateTokenEx( hToken,
                  TOKEN_ALL_ACCESS,
                  NULL,
                  SecurityImpersonation,
                  TokenPrimary,
                  &hNewToken ) )
  {
   printf( "DuplicateTokenEx() = %d\n", GetLastError() );  

   bError = TRUE;
   goto Cleanup;
  }


  ZeroMemory( &si, sizeof( STARTUPINFO ) );
  si.cb = sizeof( STARTUPINFO );

  //
  // 不虚拟登陆用户的话,创建新进程会提示
  // 1314 客户没有所需的特权错误
  //
  ImpersonateLoggedOnUser( hNewToken );


  //
  // 我们仅仅是需要建立高权限进程,不用切换用户
  // 所以也无需设置相关 桌面 ,有了新 TOKEN 足够
  //


  //
  // 利用具有所有权限的 TOKEN,创建高权限进程
  //
  if ( !CreateProcessAsUser( hNewToken,
                    NULL,
                    szProcessName,
                    NULL,
                    NULL,
                    FALSE,
                    NULL, //NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE,
                    NULL,
                    NULL,
                    &si,
                    &pi ) )
  {
   printf( "CreateProcessAsUser() = %d\n", GetLastError() );  

   bError = TRUE;
   goto Cleanup;
  }

  bError = FALSE;

  Cleanup:
  if ( pOrigSd )
  {
   HeapFree( GetProcessHeap(), 0, pOrigSd );
  }
  if ( pNewSd )
  {
   HeapFree( GetProcessHeap(), 0, pNewSd );
  }
  if ( pSidPrimary )
  {
   HeapFree( GetProcessHeap(), 0, pSidPrimary );
  }
  if ( pSidOwner )
  {
   HeapFree( GetProcessHeap(), 0, pSidOwner );
  }
  if ( pSacl )
  {
   HeapFree( GetProcessHeap(), 0, pSacl );
  }
  if ( pOldDAcl )
  {
   HeapFree( GetProcessHeap(), 0, pOldDAcl );
  }

  CloseHandle( pi.hProcess );
  CloseHandle( pi.hThread );
  CloseHandle( hToken );
  CloseHandle( hNewToken );
  CloseHandle( hProcess );

  if ( bError )
  {
   return FALSE;
  }

  return TRUE;
}


void
main( int argc, char** argv )
{
  if ( argc < 2 )
  {
   printf( "Usage: wssrun \n" );
   return ;
  }

  if ( CreateSystemProcess( argv[1] ) == FALSE )
  {
   printf( "wssrun: CreateSystemProcess() to failed!\n" );
   return ;
  }
}
Windows createprocess以当前登录用户权限(uac降权)运行程序         近期的工作,总是会碰到一些比较奇特的需求,比如说:在一个以管理员权限运行的程序里面,启动/运行一个非管理员/当前用户权限的程序或者服务之类。        常规来说,管理员权限下运行的程序,即便创建新进程或者启动别的程序,被创建或者启动的也依然管理员权限。================================================================... 阅读详情

相关推荐

低权限IE和高权限进程通过管道通信时的权限问题

BOOL CreatePipeSecurity(PSECURITY_ATTRIBUTES *ppSa) { BOOL bSuccess = TRUE; DWORD dwError = ERROR_SUCCESS; PSECURITY_DESCRIPTOR pSd = NULL; PSECURITY_ATTRIBUTES pSa = NULL; PCWSTR szDDL = L

demoscene的专栏 768

在服务中用管理员权限创建一个可弹出UI的进程 (转载)

转载:http://blog.youkuaiyun.com/woshinia/article/details/7850295 转载:http://blog.youkuaiyun.com/hurryboylqs/article/details/53004970 转载:http://blog.youkuaiyun.com/fakine/article/details/8537763 HANDLE hToken = NU...

weixin_34388207的博客 320

ARIMA模型的R实现

1.模型简介 ARIMA模型,全称差分自回归移动平均模型。可以看作是差分运算和ARMA模型的结合。主要是针对具有线性趋势的非平稳的时间序列,来进行建模预测。 ARIMA模型的形式如下: Φ(B)∇

heirenmin的博客 1万+

windows系统服务 启动带有管理员权限的GUI进程

事情是这样的,公司的产品有个守护进程(windows Service)需要启动产品的主程序exe,让主程序它运行为管理员权限(因为主程序会加载一个插件,插件中有列出端口监听的功能,需要由端口查找到进程PID,由进程PID查找进程名或进程镜像路径,这些对于一些特殊进程例如svchost需要有管理员权限才能查到进程名和路径)。windows下的程序是不能在运行时获得管理员权限的,只能在创建进程的时候提升为管理员权限。如果是普通进程运行一个管理员权限程序,可以调用ShellExcute API。双击鼠标运行e..

technologyleader的专栏 2399

WRF-Chem新手避坑指南:从chem_opt到emiss_opt,那些手册里没明说的参数配置实战

本文为WRF-Chem新手提供从chem_opt到emiss_opt的参数配置实战指南,解析官方文档中未明确的常见陷阱与解决方案。通过华北重霾案例,详细讲解化学机制选择、排放源配置及特殊参数组合的注意事项,帮助用户避开常见错误,提升模拟效率。

weixin_30897079的博客 281

Fluent温度超限调试:从能量方程到网格优化的实战指南

本文深入解析Fluent中温度超限问题的诊断与解决方法,从能量方程机制到网格优化策略,提供实战指南。通过分析温度与焓的换算关系,探讨典型场景如能量方程发散、局部网格质量差等,并给出五步调试法及高级命令应用,帮助工程师有效解决温度计算异常问题。

weixin_29045585的博客 531

windows服务中以 管理员权限\普通权限 启动进程

windows 服务中以用户管理员权限或普通权限启动进程 // 管理员权限启动进程 #ifdef UNICODE MMSYSSHARED_EXPORT bool CreateProcessWithAdmin(const std::wstring& exe, const std::wstring& param, bool show) #else MMSYSSHARED_EXPORT bool CreateProcessWithAdmin(const std::string& exe,

4300

喷雾破碎模型解析:从理论到CFD应用实践

本文深入解析喷雾破碎模型的理论基础与CFD应用实践,重点介绍KHRT、TAB和ETAB等主流模型的核心原理与工程调参技巧。通过OpenFOAM实例演示和参数优化建议,帮助工程师精准预测液滴破碎行为,提升燃烧效率与排放控制性能,适用于汽车发动机、燃气轮机等工业场景。

weixin_29281915的博客 499

[转载]创建高权限进程

 [转载]创建高权限进程文章作者:sinister信息来源:白细胞Author:  sinisterEmail:  sinister@whitecell.orgHomepage:http://www.whitecell.org Date:   2006-02-12/*************************************************************

synjones的专栏 661

Windows 环境下 OpenClaw 的安装与千问大模型配置

为了不占用 C 盘空间,重装系统也不丢失配置,本文详细记录了如何将 OpenClaw 安装在非系统盘,比如D 盘,并对接阿里云 通义千问大模型的全过程。主要是利用 NVM 和 npm 进行安装,方便后续一键升级,配置具有免费额度的Qwen API,这个只需要在阿里云百炼注册一个账号就能获得免费额度。

博客 6538

Nginx国密HTTPS实战:SM2双证书部署与TongSuo编译指南

HTTPS作为保障网络通信安全的基石,其核心在于SSL/TLS协议与公钥基础设施(PKI)。它通过非对称加密实现身份认证与密钥交换,再结合对称加密确保数据传输的机密性与完整性。在金融、政务等对自主可控有严格要求的领域,采用符合国家密码管理局标准的国密算法(SM2/SM3/SM4)替代国际通用算法(如RSA/SHA-256/AES),已成为满足安全合规要求的关键技术路径。国密SSL不仅是一套算法替换,更涉及从底层密码库到上层应用服务的完整技术栈改造。其核心价值在于实现密码技术的自主可控,提升特定场景下的安全防

weixin_29323365的博客 499

创建高权限进程的方法

原文转自:http://www.3800hk.com/news/w45/123569.html写这个初衷是为了让 Windows 任务管理器可以结束掉一些服务和僵死进程,用 pslist/pskill 之类工具无法获得象任务管理器那样丰富的信息,还得来回切换,麻烦的很。最初想写个驱动监视任务管理器运行,使用 SYSTEM 进程 TOKEN 替换来达到目的。 后来觉得通用性不好,就改用了这种

weixu_2008的专栏 1205

思科模拟器CIsco Packet Tracer利用三层交换机实现VLAN间路由

版权声明:如果对大家有帮助,大家可以自行转载的。 1.技术原理: 三层交换机具备网络层的功能,实现 VLAN 相互访问的原理是:利用三层交换机的路由功能,通过识别数据包的 IP 地址,查找路由表进行选路转发,三层交换机利用直连路由可以实现不同 VLAN 之间的相互访问。三层交换机给接口配置 IP 地址。采用 SVI(交换虚拟接口)的方式实现 VLAN 间互连。SVI 是指为交换机中的VLAN 创建...

qq_37992321的博客 1万+

黑客技巧谈之创建高权限进程的方法

写这个初衷是为了让 Windows 任务管理器可以结束掉一些服务和僵死进程,用 pslist/pskill 之类工具无法获得象任务管理器那样丰富的信息,还得来回切换,麻烦的很。最初想写个驱动监视任务管理器运行,使用 SYSTEM 进程 TOKEN 替换来达到目的。 后来觉得通用性不好,就改用了这种方法。此方法还可使Regedit查看、编辑 SAM 等注册表键,何乐而不为。

求索 1041

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

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

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

绕过Win7 UAC 创建高权限进程

测试环境Win7 7600 1.遍历进程查找微软medium Intergrity 进程2.创建线程Ixxxxx Obj3.进行一些操作,并启动新进程 测试成功!

Orlando的积累知识库 1033

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

VB 创建SYSTEM用户进程

Option Explicitchenhui530 VB创建SYSTEM用户进程2007-5-29Private Const PROCESS_Create_THREAD = &H2Private Const PROCESS_QUERY_INFORMATION = &H400Private Const PROCESS_VM_WRITE = &H20Private Const PROCESS_V

lotuso的专栏 537

以SYSTEM权限运行程序

program SysTemRun;     uses     Windows,     tlhelp32,     AccCtrl,     AclAPI;         function UpperCase(const S: string): string;   var     Ch: Char;     L: Integer;     Source, Dest:

gj333的专栏 884

创建SYSTEM用户权限的进程

#include #include #include #include #include typedef NTSTATUS (WINAPI *pfRtlAdjustPrivilege)( ULONG Privilege, BOOLEAN Enable, BOOLEAN CurrentThread, PBOOLEAN Enabled); void AdjustPri

csafu的专栏 2648

"SYSTEM"用户创建进程

sysrun.ccl sysrun.cpp Shlwapi.lib advapi32.lib#include #include 

975

模拟高权限用户

我不知道这能不能算一个好点子,但我觉得这真的不错:模拟一个权力更大的用户进行某些无法完成的操作。 举个例子来说:你在Administrator用户下,打开文件1.exe的安全设置页面,添加并设置Guest用户的权限为file control拒否,如下图所示:   这样,按照正常的办法,Guest用户将访问不到1.exe文件了。但是一点其他的办法都没有吗?也不是的,我告诉你一个:模拟高

丸子头的专栏 1071
上一篇: 字符串查找算法
下一篇: KeyLogger
龍城狂霸拽爺
博客等级 码龄16年 10粉丝 101原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值