打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
创建高权限进程

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

/*****************************************************************
文件名 : wssrun.c
描述 : 创建高权限进程
作者 : sinister
最后修改日期 : 2006.2.09

*****************************************************************/

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

C++代码
  1. #include
  2. #include
  3. #include
  4. #include
  5. #include
  6. #include
  7. #include

  8. #pragma comment(lib,”Shlwapi.lib”)


  9. /////////////////////////////////////////////////////////////////
  10. // 函数类型 :自定义工具函数
  11. // 函数模块 :
  12. ////////////////////////////////////////////////////////////////
  13. // 功能 :提升当前进程权限
  14. // 注意 :
  15. /////////////////////////////////////////////////////////////////
  16. // 作者 : sinister
  17. // 发布版本 : 1.00.00
  18. // 发布日期 : 2006.2.09
  19. /////////////////////////////////////////////////////////////////
  20. // 重 大 修 改 历 史
  21. ////////////////////////////////////////////////////////////////
  22. // 修改者 :
  23. // 修改日期 :
  24. // 修改内容 :
  25. /////////////////////////////////////////////////////////////////

  26. BOOL
  27. EnableDebugPriv( LPCTSTR szPrivilege )
  28. {
  29. HANDLE hToken;
  30. LUID sedebugnameValue;
  31. TOKEN_PRIVILEGES tkp;

  32. if ( !OpenProcessToken( GetCurrentProcess(),
  33. TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
  34. &hToken ) )
  35. {
  36. return FALSE;
  37. }
  38. if ( !LookupPrivilegeValue( NULL, szPrivilege, &sedebugnameValue ) )
  39. {
  40. CloseHandle( hToken );
  41. return FALSE;
  42. }

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

  46. if ( !AdjustTokenPrivileges( hToken, FALSE, &tkp, sizeof tkp, NULL, NULL ) )
  47. {
  48. CloseHandle( hToken );
  49. return FALSE;
  50. }

  51. return TRUE;
  52. }

  53. /////////////////////////////////////////////////////////////////
  54. // 函数类型 :自定义工具函数
  55. // 函数模块 :
  56. ////////////////////////////////////////////////////////////////
  57. // 功能 :通过指定进程名得到其进程 ID
  58. // 注意 :
  59. /////////////////////////////////////////////////////////////////
  60. // 作者 : sinister
  61. // 发布版本 : 1.00.00
  62. // 发布日期 : 2006.2.09
  63. /////////////////////////////////////////////////////////////////
  64. // 重 大 修 改 历 史
  65. ////////////////////////////////////////////////////////////////
  66. // 修改者 :
  67. // 修改日期 :
  68. // 修改内容 :
  69. /////////////////////////////////////////////////////////////////

  70. DWORD
  71. GetProcessId( LPCTSTR szProcName )
  72. {
  73. PROCESSENTRY32 pe;
  74. DWORD dwPid;
  75. DWORD dwRet;
  76. BOOL bFound = FALSE;

  77. //
  78. // 通过 TOOHLP32 函数枚举进程
  79. //

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

  84. for ( dwRet = Process32First( hSP, &pe );
  85. dwRet;
  86. dwRet = Process32Next( hSP, &pe ) )
  87. {
  88. //
  89. // 使用 StrCmpNI 比较字符传,可忽略大小写
  90. //
  91. if ( StrCmpNI( szProcName, pe.szExeFile, strlen( szProcName ) ) == 0 )
  92. {
  93. dwPid = pe.th32ProcessID;
  94. bFound = TRUE;
  95. break;
  96. }
  97. }

  98. CloseHandle( hSP );

  99. if ( bFound == TRUE )
  100. {
  101. return dwPid;
  102. }
  103. }

  104. return NULL;
  105. }

  106. /////////////////////////////////////////////////////////////////
  107. // 函数类型 :自定义工具函数
  108. // 函数模块 :
  109. ////////////////////////////////////////////////////////////////
  110. // 功能 : 创建具有高权限的进程
  111. // 注意 :
  112. /////////////////////////////////////////////////////////////////
  113. // 作者 : sinister
  114. // 发布版本 : 1.00.00
  115. // 发布日期 : 2006.2.09
  116. /////////////////////////////////////////////////////////////////
  117. // 重 大 修 改 历 史
  118. ////////////////////////////////////////////////////////////////
  119. // 修改者 :
  120. // 修改日期 :
  121. // 修改内容 :
  122. /////////////////////////////////////////////////////////////////

  123. BOOL
  124. CreateSystemProcess( LPTSTR szProcessName )
  125. {
  126. HANDLE hProcess;
  127. HANDLE hToken, hNewToken;
  128. DWORD dwPid;

  129. PACL pOldDAcl = NULL;
  130. PACL pNewDAcl = NULL;
  131. BOOL bDAcl;
  132. BOOL bDefDAcl;
  133. DWORD dwRet;

  134. PACL pSacl = NULL;
  135. PSID pSidOwner = NULL;
  136. PSID pSidPrimary = NULL;
  137. DWORD dwAclSize = 0;
  138. DWORD dwSaclSize = 0;
  139. DWORD dwSidOwnLen = 0;
  140. DWORD dwSidPrimLen = 0;

  141. DWORD dwSDLen;
  142. EXPLICIT_ACCESS ea;
  143. PSECURITY_DESCRIPTOR pOrigSd = NULL;
  144. PSECURITY_DESCRIPTOR pNewSd = NULL;

  145. STARTUPINFO si;
  146. PROCESS_INFORMATION pi;

  147. BOOL bError;

  148. if ( !EnableDebugPriv( “SeDebugPrivilege” ) )
  149. {
  150. printf( “EnableDebugPriv() to failed!\n” );

  151. bError = TRUE;
  152. goto Cleanup;
  153. }

  154. //
  155. // 选择 WINLOGON 进程
  156. //
  157. if ( ( dwPid = GetProcessId( “WINLOGON.EXE” ) ) == NULL )
  158. {
  159. printf( “GetProcessId() to failed!\n” );

  160. bError = TRUE;
  161. goto Cleanup;
  162. }

  163. hProcess = OpenProcess( PROCESS_QUERY_INFORMATION, FALSE, dwPid );
  164. if ( hProcess == NULL )
  165. {
  166. printf( “OpenProcess() = %d\n”, GetLastError() );

  167. bError = TRUE;
  168. goto Cleanup;
  169. }

  170. if ( !OpenProcessToken( hProcess, READ_CONTROL | WRITE_DAC, &hToken ) )
  171. {
  172. printf( “OpenProcessToken() = %d\n”, GetLastError() );

  173. bError = TRUE;
  174. goto Cleanup;
  175. }

  176. //
  177. // 设置 ACE 具有所有访问权限
  178. //
  179. ZeroMemory( &ea, sizeof( EXPLICIT_ACCESS ) );
  180. BuildExplicitAccessWithName( &ea,
  181. “Everyone”,
  182. TOKEN_ALL_ACCESS,
  183. GRANT_ACCESS,
  184. 0 );

  185. if ( !GetKernelObjectSecurity( hToken,
  186. DACL_SECURITY_INFORMATION,
  187. pOrigSd,
  188. 0,
  189. &dwSDLen ) )
  190. {
  191. //
  192. // 第一次调用给出的参数肯定返回这个错误,这样做的目的是
  193. // 为了得到原安全描述符 pOrigSd 的长度
  194. //
  195. if ( GetLastError() == ERROR_INSUFFICIENT_BUFFER )
  196. {
  197. pOrigSd = ( PSECURITY_DESCRIPTOR ) HeapAlloc( GetProcessHeap(),
  198. HEAP_ZERO_MEMORY,
  199. dwSDLen );
  200. if ( pOrigSd == NULL )
  201. {
  202. printf( “Allocate pSd memory to failed!\n” );

  203. bError = TRUE;
  204. goto Cleanup;
  205. }

  206. //
  207. // 再次调用才正确得到安全描述符 pOrigSd
  208. //
  209. if ( !GetKernelObjectSecurity( hToken,
  210. DACL_SECURITY_INFORMATION,
  211. pOrigSd,
  212. dwSDLen,
  213. &dwSDLen ) )
  214. {
  215. printf( “GetKernelObjectSecurity() = %d\n”, GetLastError() );
  216. bError = TRUE;
  217. goto Cleanup;
  218. }
  219. }
  220. else
  221. {
  222. printf( “GetKernelObjectSecurity() = %d\n”, GetLastError() );
  223. bError = TRUE;
  224. goto Cleanup;
  225. }
  226. }

  227. //
  228. // 得到原安全描述符的访问控制列表 ACL
  229. //
  230. if ( !GetSecurityDescriptorDacl( pOrigSd, &bDAcl, &pOldDAcl, &bDefDAcl ) )
  231. {
  232. printf( “GetSecurityDescriptorDacl() = %d\n”, GetLastError() );

  233. bError = TRUE;
  234. goto Cleanup;
  235. }

  236. //
  237. // 生成新 ACE 权限的访问控制列表 ACL
  238. //
  239. dwRet = SetEntriesInAcl( 1, &ea, pOldDAcl, &pNewDAcl );
  240. if ( dwRet != ERROR_SUCCESS )
  241. {
  242. printf( “SetEntriesInAcl() = %d\n”, GetLastError() );
  243. pNewDAcl = NULL;

  244. bError = TRUE;
  245. goto Cleanup;
  246. }

  247. if ( !MakeAbsoluteSD( pOrigSd,
  248. pNewSd,
  249. &dwSDLen,
  250. pOldDAcl,
  251. &dwAclSize,
  252. pSacl,
  253. &dwSaclSize,
  254. pSidOwner,
  255. &dwSidOwnLen,
  256. pSidPrimary,
  257. &dwSidPrimLen ) )
  258. {
  259. //
  260. // 第一次调用给出的参数肯定返回这个错误,这样做的目的是
  261. // 为了创建新的安全描述符 pNewSd 而得到各项的长度
  262. //
  263. if ( GetLastError() == ERROR_INSUFFICIENT_BUFFER )
  264. {
  265. pOldDAcl = ( PACL ) HeapAlloc( GetProcessHeap(),
  266. HEAP_ZERO_MEMORY,
  267. dwAclSize );
  268. pSacl = ( PACL ) HeapAlloc( GetProcessHeap(),
  269. HEAP_ZERO_MEMORY,
  270. dwSaclSize );
  271. pSidOwner = ( PSID ) HeapAlloc( GetProcessHeap(),
  272. HEAP_ZERO_MEMORY,
  273. dwSidOwnLen );
  274. pSidPrimary = ( PSID ) HeapAlloc( GetProcessHeap(),
  275. HEAP_ZERO_MEMORY,
  276. dwSidPrimLen );
  277. pNewSd = ( PSECURITY_DESCRIPTOR ) HeapAlloc( GetProcessHeap(),
  278. HEAP_ZERO_MEMORY,
  279. dwSDLen );

  280. if ( pOldDAcl == NULL ||
  281. pSacl == NULL ||
  282. pSidOwner == NULL ||
  283. pSidPrimary == NULL ||
  284. pNewSd == NULL )
  285. {
  286. printf( “Allocate SID or ACL to failed!\n” );

  287. bError = TRUE;
  288. goto Cleanup;
  289. }

  290. //
  291. // 再次调用才可以成功创建新的安全描述符 pNewSd
  292. // 但新的安全描述符仍然是原访问控制列表 ACL
  293. //
  294. if ( !MakeAbsoluteSD( pOrigSd,
  295. pNewSd,
  296. &dwSDLen,
  297. pOldDAcl,
  298. &dwAclSize,
  299. pSacl,
  300. &dwSaclSize,
  301. pSidOwner,
  302. &dwSidOwnLen,
  303. pSidPrimary,
  304. &dwSidPrimLen ) )
  305. {
  306. printf( “MakeAbsoluteSD() = %d\n”, GetLastError() );

  307. bError = TRUE;
  308. goto Cleanup;
  309. }
  310. }
  311. else
  312. {
  313. printf( “MakeAbsoluteSD() = %d\n”, GetLastError() );

  314. bError = TRUE;
  315. goto Cleanup;
  316. }
  317. }

  318. //
  319. // 将具有所有访问权限的访问控制列表 pNewDAcl 加入到新的
  320. // 安全描述符 pNewSd 中
  321. //
  322. if ( !SetSecurityDescriptorDacl( pNewSd, bDAcl, pNewDAcl, bDefDAcl ) )
  323. {
  324. printf( “SetSecurityDescriptorDacl() = %d\n”, GetLastError() );

  325. bError = TRUE;
  326. goto Cleanup;
  327. }

  328. //
  329. // 将新的安全描述符加到 TOKEN 中
  330. //
  331. if ( !SetKernelObjectSecurity( hToken, DACL_SECURITY_INFORMATION, pNewSd ) )
  332. {
  333. printf( “SetKernelObjectSecurity() = %d\n”, GetLastError() );

  334. bError = TRUE;
  335. goto Cleanup;
  336. }

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

  343. bError = TRUE;
  344. goto Cleanup;
  345. }

  346. //
  347. // 复制一份具有相同访问权限的 TOKEN
  348. //
  349. if ( !DuplicateTokenEx( hToken,
  350. TOKEN_ALL_ACCESS,
  351. NULL,
  352. SecurityImpersonation,
  353. TokenPrimary,
  354. &hNewToken ) )
  355. {
  356. printf( “DuplicateTokenEx() = %d\n”, GetLastError() );

  357. bError = TRUE;
  358. goto Cleanup;
  359. }


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

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


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


  371. //
  372. // 利用具有所有权限的 TOKEN,创建高权限进程
  373. //
  374. if ( !CreateProcessAsUser( hNewToken,
  375. NULL,
  376. szProcessName,
  377. NULL,
  378. NULL,
  379. FALSE,
  380. NULL, //NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE,
  381. NULL,
  382. NULL,
  383. &si,
  384. π ) )
  385. {
  386. printf( “CreateProcessAsUser() = %d\n”, GetLastError() );

  387. bError = TRUE;
  388. goto Cleanup;
  389. }

  390. bError = FALSE;

  391. Cleanup:
  392. if ( pOrigSd )
  393. {
  394. HeapFree( GetProcessHeap(), 0, pOrigSd );
  395. }
  396. if ( pNewSd )
  397. {
  398. HeapFree( GetProcessHeap(), 0, pNewSd );
  399. }
  400. if ( pSidPrimary )
  401. {
  402. HeapFree( GetProcessHeap(), 0, pSidPrimary );
  403. }
  404. if ( pSidOwner )
  405. {
  406. HeapFree( GetProcessHeap(), 0, pSidOwner );
  407. }
  408. if ( pSacl )
  409. {
  410. HeapFree( GetProcessHeap(), 0, pSacl );
  411. }
  412. if ( pOldDAcl )
  413. {
  414. HeapFree( GetProcessHeap(), 0, pOldDAcl );
  415. }

  416. CloseHandle( pi.hProcess );
  417. CloseHandle( pi.hThread );
  418. CloseHandle( hToken );
  419. CloseHandle( hNewToken );
  420. CloseHandle( hProcess );

  421. if ( bError )
  422. {
  423. return FALSE;
  424. }

  425. return TRUE;
  426. }


  427. void
  428. main( int argc, char** argv )
  429. {
  430. if ( argc < 2 )
  431. {
  432. printf( “Usage: wssrun \n” );
  433. return ;
  434. }

  435. if ( CreateSystemProcess( argv[1] ) == FALSE )
  436. {
  437. printf( “wssrun: CreateSystemProcess() to failed!\n” );
  438. return ;
  439. }
  440. }
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
关机有关的函数
三个给进程提权的方法 (c/cpp)
文件占坑法过360查杀
WINDOWS系统下木马程序的设计与实现
获取进程模块的信息
C++ 让电脑关机,重启,注销
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服