//token 权限令牌 import process; namespace process; class token{ ctor( processHandle,access ){ if(!processHandle[["token"]]){ if(!processHandle) processHandle = ::Kernel32.GetCurrentProcessP(); if(type.isString(processHandle)) { processHandle = ..process.find(processHandle); if(!processHandle) return; } this.processHandle = processHandle; var token = {ptr handle} if(::Advapi32.OpenProcessToken(processHandle,access : 8/*_TOKEN_QUERY*/,token)){ this.tokenHandle = token.handle } else { return null; } ..table.gc(this,"close"); } else{ this.tokenHandle = processHandle[["token"]] if(processHandle[["gc"]]) ..table.gc(this,"close"); } }; duplicate = function(level=2/*SecurityImpersonation*/){ var newToken = {ptr handle} if( ::Advapi32.DuplicateToken(this.tokenHandle,level,newToken) ) return newToken.handle; }; info = function(infClass,info){ if ( this.tokenHandle ) { var size ={INT v } var res = ::Advapi32.GetTokenInformation(this.tokenHandle,infClass,null,0,size); if(!res && !size.v ){ return false } var buf = ..raw.buffer(size.v); var ok = ::Advapi32.GetTokenInformation(this.tokenHandle,infClass,buf,#buf,size); if(ok){ ..raw.convert(buf,info); info["($safe-buffer)"] = buf; return info; } } }; user = function(){ var info,buf = this.info(1/*_TokenUser*/,{ ptr sid;INT attributes;}) //避免buf无引用时释放内存( info.sid实际上是指向buf去掉头部8个字节的内存 ) var size = ::Advapi32.GetLengthSid(info.sid); info.sid = ..raw.buffer(size,info.sid); return info; }; sid = function(){ return this.user()[["sid"]]; }; elevation = function(){ return _WINXP || !! this.info(20/*TokenElevation*/,{ INT TokenIsElevated })[["TokenIsElevated"]]; }; close = function(){ if(this.tokenHandle){ ..raw.closehandle(this.tokenHandle) this.tokenHandle = null; } }; @{_topointer = lambda() this.tokenHandle} } namespace token{ ::Advapi32 := ..raw.loadDll("Advapi32.dll"); sid = function(process){ var token = ..process.token(process); var sid = token.sid(); token.close(); return sid; } } /**intellisense() process.token(.(process,access) = 打开进程令牌,\n@process 参数指定 process 进程对象、句柄、或已执行文件名,省略时取当前进程句柄,\naccess指定访问权限,省略时默认值为 _TOKEN_QUERY\n返回对象在回收时默认自动调用close函数 process.token(.({token=tokenHandle}) = 绑定参数表中 tokenHandle 属性指定的进程令牌句柄,\n可选用 gc 属性指定是否允许对象回收时自动释放 token process.token() = !processToken. end intellisense**/ /**intellisense(process.token) sid(.(process) = 返回运行进程的用户 SID,返回值为 buffer 类型指针,\n@process 参数指定进程对象、句柄、或已执行文件名,省略时取当前进程句柄 end intellisense**/ /**intellisense(!processToken) user() = 获取进程令牌的用户信息,\n返回TokenUser结构体,返回值不需要手动释放 sid() = 返回进程的用户 SID,返回值为 buffer 类型指针,\n标准库 sys.acl 提供操作转换sid的函数,\n例如可用 sys.acl.sidToUserName 将 SID 转换为用户名 info(.(infClass,info) = 获取令牌信息\n@infClass参数使用枚举数值标明要获取的类型,\n@info参数为要获取的结构体,\n成功返回info参数 elevation() = 当前进程是否使用管理员权限启动 duplicate(.(level,tokenType,access,tokenAttributes) = 复制 token 并返回 token 句柄,\n打开进程时请指定 4/*_TOKEN_IMPERSONATE*/|2/*_TOKEN_DUPLICATE*/ 权限,\n所有参数可选,用法请参考源码 close() = 关闭对象 end intellisense**/ /**intellisense() _TOKEN_ADJUST_SESSIONID=@0x100/*_TOKEN_ADJUST_SESSIONID*/ _TOKEN_SOURCE_LENGTH=@8/*_TOKEN_SOURCE_LENGTH*/ _TOKEN_ADJUST_DEFAULT=@0x80/*_TOKEN_ADJUST_DEFAULT*/ _TOKEN_ADJUST_GROUPS=@0x40/*_TOKEN_ADJUST_GROUPS*/ _TOKEN_ADJUST_PRIVILEGES=@0x20/*_TOKEN_ADJUST_PRIVILEGES*/ _TOKEN_ALL_ACCESS=@0xF00FF/*_TOKEN_ALL_ACCESS*/ _TOKEN_ASSIGN_PRIMARY=@1/*_TOKEN_ASSIGN_PRIMARY*/ _TOKEN_DUPLICATE=@2/*_TOKEN_DUPLICATE*/ _TOKEN_EXECUTE=@0x20000/*_TOKEN_EXECUTE*/ _TOKEN_IMPERSONATE=@4/*_TOKEN_IMPERSONATE*/ _TOKEN_QUERY=@8/*_TOKEN_QUERY*/ _TOKEN_QUERY_SOURCE=@0x10/*_TOKEN_QUERY_SOURCE*/ _TOKEN_READ=@0x20008/*_TOKEN_READ*/ _TOKEN_WRITE=@0x200E0/*_TOKEN_WRITE*/ end intellisense**/