- 浏览: 82411 次
- 性别:
- 来自: 杭州
最新评论
-
tian012:
thx a lot
淘宝Java中间件之路 -
yj10864:
很棒!
淘宝技术嘉年华 Java@Taobao PPT -
invincibleLiu:
这个文件如果包含了第三方依赖的话在vista下就不宜生成了,空 ...
VISTA下的Manifest文件,提升权限 -
vanadies10:
aixiangct 写道华黎?!您在微博还欠我一条回复呢,O( ...
北京之行,收获很多 -
vanadies10:
forchenyun 写道“淘宝会在今年的7月份在杭州举办淘宝 ...
北京之行,收获很多
看到一篇不错的文章。转载过来也算是给自己的一个积累吧。
You may have heard that built-in services in Windows Vista were specifically hardened by Microsoft engineers during its development process. You might be wondering what that really means, how it works and, if you are a developer, how to harden your own services the Vista way. Jean-Yves Poublan, a Principal Security Consultant at Microsoft, and I are publishing a series of posts on how to leverage Windows Vista new architecture to make your services more secure.
Today, we start with a significant change with Windows Vista and Longhorn Server: Win32 services are now isolated in Session 0. So, what does this mean for developers?
‘windows’ on ‘desktops’ in ‘window stations’ in ‘Terminal Services sessions’
Windows NT was designed to be a multi-user system through the use of sessions. The SDK refers to these as Terminal Services sessions which are not to be confused with logon sessions, as they are not the same thing. Terminal Services sessions are created and managed by the session manager (smss.exe) which is one of the first processes created when the system starts. Logon sessions and processes somehow live within a Terminal Services session.
Note : The Terminal Services session ID for a given logon session may be obtained by calling the LsaGetLogonSessionData API after having enumerated the logon sessions (LsaEnumerateLogonSessions). One may also get the Terminal Services session ID for a process with the GetTokenInformation(TokenSessionId) API after having obtained the primary token for the process (OpenProcessToken).
Previous to Windows Vista and Longhorn Server, Win32 services and user applications for the console user (as well as winlogon.exe and the Win32 subsystem – csrss.exe) were all started within Terminal Services Session 0. A second Terminal Services session (Session 1) was created when a second user logged on (such as a user connecting through Terminal Services on Windows Server 2003, or a second user logging on Windows XP through Fast User Switching), and so on.
So user applications for the console user always shared Session 0 with system services. This is no longer the case with Windows Vista and Longhorn server.
What is wrong with having system services and user applications live in the same session? Well, it mostly has to do with interactive services.
First let’s recall what desktops and window stations are. Both are securable kernel objects in the sense that they are protected by ACLs. You can think of Terminal Services sessions having window stations that in turn contain desktops. There is a special window station called Winsta0 which is the windows station that is connected to the display and input devices. Processes are attached to a window station which they are going to use (supposedly) to interact with the user. Threads within a process are themselves attached to a desktop (within the window station) on which they display windows and they get input from the user. Windows messages are confined within a desktop, and Winsta0 will typically have three desktops: the winlogon desktop, the interactive desktop, and the screen saver desktop. Winsta0 grants rights to SYSTEM and the logon SID, so only the system and the currently logged on user can access the console. When a user logs off, the logon SID is removed from Winsta0, and when a new user logs on, the new logon SID is added to Winsta0’s ACL.
Windows, on the other hand, are user objects that are not securable by ACLs. So threads that have gained access to a desktop can send messages to any window on that desktop. In the past, applications that ran with higher privileges on the desktop have been vulnerable to the infamous shatter attacks from other malicious applications.
Normally, Win32 services are not attached to Winsta0 (they don’t have the rights on Winsta0), but instead they get their own window stations. Those window stations are not connected to any hardware so if a service displays a window and waits for user input, it may well wait forever…
Interactive services – to be avoided if at all possible
Interactive services are services that are configured as such (flag SERVICE_INTERACTIVE_PROCESS for CreateService or ChangeServiceConfig APIs). When the SCM starts a process for an interactive service, it attaches the service to Winsta0 instead of the service window station. In order to do so, the service process must run as SYSTEM (since only SYSTEM - and currently logged on user - have rights on Winsta0). Service threads can then attach to the interactive desktop and interact with the user.
One can see two compounded problems here: interactive services are vulnerable to Windows messages attacks from malicious user applications, and those attacks can result in privilege elevation since interactive services run as SYSTEM with TCB privilege. So deploying an interactive service that is vulnerable could compromise the whole system.
There are other things wrong with interactive services. On Windows Server 2003 with Terminal Services, the user that is currently logged on at the console in Session 0 may not be the user that the service should interact with. On Windows XP with Fast User Switching, it is even worse. The currently active console user may not be Session 0, but Session 1 (or Session n). In that case, if the interactive service waits for user input, it may wait forever from Session 0 which is not active. It is said that interactive services with Fast User Switching just don’t work. Because of that, developing and deploying interactive services has been strongly discouraged. As a matter of fact, interactive services can be banned from the system by setting the NoInteractiveServices registry value to 1 in HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Windows. In that case, interactive services will still be started by the SCM (Services Control Manager), but they won’t be attached to Winsta0 (the SCM does log a warning in the event log). This is valid for Windows Vista and Longhorn as well.
Isolation of services in Session 0 with Windows Vista and Longhorn Server
With Windows Vista and Longhorn Server, user applications for the first logged on console user are now started in Terminal Services Session 1, and services in Session 0 are isolated from user applications. The second logged on user gets Session 2 and so on. Services isolation in Session 0 helps protecting the system from malicious user applications. Imagine one has installed an interactive service that is vulnerable, that interactive service will not share the desktop with (potentially) malicious user applications anymore and as such will be less likely to be compromised and used as a vehicle to attack the system.
Services isolation in Session 0 affects all services that assume they are running in the same session as user applications, and not only services that configured as interactive services. For instance, a service that communicates with user applications by way of Windows messages will no longer work. Also, a service that synchronizes with user applications through synchronization objects (semaphores, mutexes, etc…) created in the session private name space will no longer work as well. The global name space should be used instead (object names prefixed with Global\).
Under Windows Vista and Longhorn, a service can still be configured to be an interactive service, but such configuration does not make a whole lot of sense, since the interactive service will be attached to the Winsta0 in Session 0, which does not have a physical console and user to interact with.
If you have a service that is designed to be an interactive service and as such interacts with the desktop, or a service that assumes it is running in the same session as user applications, it is time to change it. Windows SDK does give some ideas of how a service could interact with users, without having to be an interactive service. This includes communicating with a user process through some form of IPC (preferably secure) channel, or using Terminal Services APIs such WTSSendMessage. Determining which user (in which target session) your service should interact with is up to you but should not be overlooked.
For legacy interactive services that cannot be changed in the short term, Windows Vista provides a compatibility mechanism called Interactive Service Detection service (ui0detect.exe). UI0Detect monitors interactive services in Wintsta0 of Session 0 and when such service displays a modal dialog it notifies the user in the currently active console session. The user can choose to switch to Winsta0/interactive desktop of Session 0 to respond to the dialog, and then switch back to the user session. UI0Detect is a temporary measure designed to limit the effect of Session 0 service isolation for existing interactive services that cannot be changed. As a service developer you should not count on that mechanism.
What about MessageBox() and MessageBox(MB_SERVICE_NOTIFICATION)?
When calling the MessageBox() API - *without* the MS_SERVICE_NOTIFICATION flag - from a service that is not an interactive service, the thread waits forever. It is worth noting that if a non interactive service is programmed in managed code on the .Net Runtime, calling the System.Windows.Forms.MessageBox.Show() method will raise an exception (“System.InvalidOperationException: Showing a modal dialog box or form when the application is not running in UserInteractive mode is not a valid operation. Specify the ServiceNotification or DefaultDesktopOnly style to display a notification from a service application”) instead of hanging there waiting for user input. Also if the service is an interactive service, under Windows Vista, UI0Detect will handle the interaction for MessageBox() – without MB_SERVICE_NOTIFICATION.
The MB_SERVICE_NOTIFICATION flag causes the system to redirect the message box to the interactive desktop (or winlogon desktop if there is no user logged on) on WinSta0 where it is handled by csrss.exe (the Win32 subsystem).It was designed to allow services that technically are not interactive services (i.e. they are not configured as interactive services and thus are not attached to Winsta0) to display a modal dialog message box on the interactive desktop and get user input.
Under Windows Vista RTM, this does not work however, in the sense that instead of the message box being redirected to the interactive desktop of a session with a user on it, or taken care of by UI0Detect as one could hope, the functions returns IDOK immediately with no user interaction whatsoever. It behaves that way even for services that are configured as interactive services and whose interactions are normally handled by UI0Detect. If your service uses MessageBox(MB_SERVICE_NOTIFICATION) to ask for user approval for some operation, it may need to be modified.
The following two tables summarize MessageBox behaviors under Windows XP SP2 and Windows Vista RTM.
NoInteractiveServices = 0 NoInteractiveServices = 1
SERVICE_INTERACTIVE_PROCESS
(CreateService, ChangeServiceConfig)
Window station (service is running as SYSTEM) 0x00000000
"Allow service to interact with desktop"= unchecked
Service-0x0-3e7$ 0x00000100
"Allow service to interact with desktop"= checked
WinSta0 0x00000000
"Allow service to interact with desktop"= unchecked
Service-0x0-3e7$ 0x00000100
"Allow service to interact with desktop"= checked
Service-0x0-3e7$
MessageBox() No display – waiting forever (1) Display OK (directly by service process)
No display – waiting forever (1) SCM warning in event log when starting the service
No display – waiting forever (1)
MessageBox(MB_SERVICE_NOTIFICATION) Display OK (through csrss.exe) Display OK (through csrss.exe) Display OK (through csrss.exe) SCM warning in event log when starting the service
Display OK (through csrss.exe)
MessageBox behavior on Windows XP SP2
(1) Managed code: runtime will raise an exception
NoInteractiveServices = 0 NoInteractiveServices = 1
SERVICE_INTERACTIVE_PROCESS
(CreateService, ChangeServiceConfig)
Window station (service is running as SYSTEM) 0x00000000
"Allow service to interact with desktop"= unchecked
Service-0x0-3e7$ 0x00000100
"Allow service to interact with desktop"= checked
WinSta0 0x00000000
"Allow service to interact with desktop"= unchecked
Service-0x0-3e7$ 0x00000100
"Allow service to interact with desktop"= checked
Service-0x0-3e7$
MessageBox() No display – waiting forever (1) Interactive Service Detection – user can switch to Session 0 to respond service No display – waiting forever (1) SCM warning in event log when starting the service
No display – waiting forever (1)
MessageBox(MB_SERVICE_NOTIFICATION) No display – returns 1 (IDOK)(2) immediately No display – returns 1 (IDOK)(2) immediately No display – returns 1 (IDOK)(2) immediately SCM warning in event log when starting the service
No display – returns 1 (IDOK)(2) immediately
MessageBox behavior on Windows Vista RTM
(1) Managed code: runtime will raise an exception
(2) Even if message box has no such button
You may have heard that built-in services in Windows Vista were specifically hardened by Microsoft engineers during its development process. You might be wondering what that really means, how it works and, if you are a developer, how to harden your own services the Vista way. Jean-Yves Poublan, a Principal Security Consultant at Microsoft, and I are publishing a series of posts on how to leverage Windows Vista new architecture to make your services more secure.
Today, we start with a significant change with Windows Vista and Longhorn Server: Win32 services are now isolated in Session 0. So, what does this mean for developers?
‘windows’ on ‘desktops’ in ‘window stations’ in ‘Terminal Services sessions’
Windows NT was designed to be a multi-user system through the use of sessions. The SDK refers to these as Terminal Services sessions which are not to be confused with logon sessions, as they are not the same thing. Terminal Services sessions are created and managed by the session manager (smss.exe) which is one of the first processes created when the system starts. Logon sessions and processes somehow live within a Terminal Services session.
Note : The Terminal Services session ID for a given logon session may be obtained by calling the LsaGetLogonSessionData API after having enumerated the logon sessions (LsaEnumerateLogonSessions). One may also get the Terminal Services session ID for a process with the GetTokenInformation(TokenSessionId) API after having obtained the primary token for the process (OpenProcessToken).
Previous to Windows Vista and Longhorn Server, Win32 services and user applications for the console user (as well as winlogon.exe and the Win32 subsystem – csrss.exe) were all started within Terminal Services Session 0. A second Terminal Services session (Session 1) was created when a second user logged on (such as a user connecting through Terminal Services on Windows Server 2003, or a second user logging on Windows XP through Fast User Switching), and so on.
So user applications for the console user always shared Session 0 with system services. This is no longer the case with Windows Vista and Longhorn server.
What is wrong with having system services and user applications live in the same session? Well, it mostly has to do with interactive services.
First let’s recall what desktops and window stations are. Both are securable kernel objects in the sense that they are protected by ACLs. You can think of Terminal Services sessions having window stations that in turn contain desktops. There is a special window station called Winsta0 which is the windows station that is connected to the display and input devices. Processes are attached to a window station which they are going to use (supposedly) to interact with the user. Threads within a process are themselves attached to a desktop (within the window station) on which they display windows and they get input from the user. Windows messages are confined within a desktop, and Winsta0 will typically have three desktops: the winlogon desktop, the interactive desktop, and the screen saver desktop. Winsta0 grants rights to SYSTEM and the logon SID, so only the system and the currently logged on user can access the console. When a user logs off, the logon SID is removed from Winsta0, and when a new user logs on, the new logon SID is added to Winsta0’s ACL.
Windows, on the other hand, are user objects that are not securable by ACLs. So threads that have gained access to a desktop can send messages to any window on that desktop. In the past, applications that ran with higher privileges on the desktop have been vulnerable to the infamous shatter attacks from other malicious applications.
Normally, Win32 services are not attached to Winsta0 (they don’t have the rights on Winsta0), but instead they get their own window stations. Those window stations are not connected to any hardware so if a service displays a window and waits for user input, it may well wait forever…
Interactive services – to be avoided if at all possible
Interactive services are services that are configured as such (flag SERVICE_INTERACTIVE_PROCESS for CreateService or ChangeServiceConfig APIs). When the SCM starts a process for an interactive service, it attaches the service to Winsta0 instead of the service window station. In order to do so, the service process must run as SYSTEM (since only SYSTEM - and currently logged on user - have rights on Winsta0). Service threads can then attach to the interactive desktop and interact with the user.
One can see two compounded problems here: interactive services are vulnerable to Windows messages attacks from malicious user applications, and those attacks can result in privilege elevation since interactive services run as SYSTEM with TCB privilege. So deploying an interactive service that is vulnerable could compromise the whole system.
There are other things wrong with interactive services. On Windows Server 2003 with Terminal Services, the user that is currently logged on at the console in Session 0 may not be the user that the service should interact with. On Windows XP with Fast User Switching, it is even worse. The currently active console user may not be Session 0, but Session 1 (or Session n). In that case, if the interactive service waits for user input, it may wait forever from Session 0 which is not active. It is said that interactive services with Fast User Switching just don’t work. Because of that, developing and deploying interactive services has been strongly discouraged. As a matter of fact, interactive services can be banned from the system by setting the NoInteractiveServices registry value to 1 in HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Windows. In that case, interactive services will still be started by the SCM (Services Control Manager), but they won’t be attached to Winsta0 (the SCM does log a warning in the event log). This is valid for Windows Vista and Longhorn as well.
Isolation of services in Session 0 with Windows Vista and Longhorn Server
With Windows Vista and Longhorn Server, user applications for the first logged on console user are now started in Terminal Services Session 1, and services in Session 0 are isolated from user applications. The second logged on user gets Session 2 and so on. Services isolation in Session 0 helps protecting the system from malicious user applications. Imagine one has installed an interactive service that is vulnerable, that interactive service will not share the desktop with (potentially) malicious user applications anymore and as such will be less likely to be compromised and used as a vehicle to attack the system.
Services isolation in Session 0 affects all services that assume they are running in the same session as user applications, and not only services that configured as interactive services. For instance, a service that communicates with user applications by way of Windows messages will no longer work. Also, a service that synchronizes with user applications through synchronization objects (semaphores, mutexes, etc…) created in the session private name space will no longer work as well. The global name space should be used instead (object names prefixed with Global\).
Under Windows Vista and Longhorn, a service can still be configured to be an interactive service, but such configuration does not make a whole lot of sense, since the interactive service will be attached to the Winsta0 in Session 0, which does not have a physical console and user to interact with.
If you have a service that is designed to be an interactive service and as such interacts with the desktop, or a service that assumes it is running in the same session as user applications, it is time to change it. Windows SDK does give some ideas of how a service could interact with users, without having to be an interactive service. This includes communicating with a user process through some form of IPC (preferably secure) channel, or using Terminal Services APIs such WTSSendMessage. Determining which user (in which target session) your service should interact with is up to you but should not be overlooked.
For legacy interactive services that cannot be changed in the short term, Windows Vista provides a compatibility mechanism called Interactive Service Detection service (ui0detect.exe). UI0Detect monitors interactive services in Wintsta0 of Session 0 and when such service displays a modal dialog it notifies the user in the currently active console session. The user can choose to switch to Winsta0/interactive desktop of Session 0 to respond to the dialog, and then switch back to the user session. UI0Detect is a temporary measure designed to limit the effect of Session 0 service isolation for existing interactive services that cannot be changed. As a service developer you should not count on that mechanism.
What about MessageBox() and MessageBox(MB_SERVICE_NOTIFICATION)?
When calling the MessageBox() API - *without* the MS_SERVICE_NOTIFICATION flag - from a service that is not an interactive service, the thread waits forever. It is worth noting that if a non interactive service is programmed in managed code on the .Net Runtime, calling the System.Windows.Forms.MessageBox.Show() method will raise an exception (“System.InvalidOperationException: Showing a modal dialog box or form when the application is not running in UserInteractive mode is not a valid operation. Specify the ServiceNotification or DefaultDesktopOnly style to display a notification from a service application”) instead of hanging there waiting for user input. Also if the service is an interactive service, under Windows Vista, UI0Detect will handle the interaction for MessageBox() – without MB_SERVICE_NOTIFICATION.
The MB_SERVICE_NOTIFICATION flag causes the system to redirect the message box to the interactive desktop (or winlogon desktop if there is no user logged on) on WinSta0 where it is handled by csrss.exe (the Win32 subsystem).It was designed to allow services that technically are not interactive services (i.e. they are not configured as interactive services and thus are not attached to Winsta0) to display a modal dialog message box on the interactive desktop and get user input.
Under Windows Vista RTM, this does not work however, in the sense that instead of the message box being redirected to the interactive desktop of a session with a user on it, or taken care of by UI0Detect as one could hope, the functions returns IDOK immediately with no user interaction whatsoever. It behaves that way even for services that are configured as interactive services and whose interactions are normally handled by UI0Detect. If your service uses MessageBox(MB_SERVICE_NOTIFICATION) to ask for user approval for some operation, it may need to be modified.
The following two tables summarize MessageBox behaviors under Windows XP SP2 and Windows Vista RTM.
NoInteractiveServices = 0 NoInteractiveServices = 1
SERVICE_INTERACTIVE_PROCESS
(CreateService, ChangeServiceConfig)
Window station (service is running as SYSTEM) 0x00000000
"Allow service to interact with desktop"= unchecked
Service-0x0-3e7$ 0x00000100
"Allow service to interact with desktop"= checked
WinSta0 0x00000000
"Allow service to interact with desktop"= unchecked
Service-0x0-3e7$ 0x00000100
"Allow service to interact with desktop"= checked
Service-0x0-3e7$
MessageBox() No display – waiting forever (1) Display OK (directly by service process)
No display – waiting forever (1) SCM warning in event log when starting the service
No display – waiting forever (1)
MessageBox(MB_SERVICE_NOTIFICATION) Display OK (through csrss.exe) Display OK (through csrss.exe) Display OK (through csrss.exe) SCM warning in event log when starting the service
Display OK (through csrss.exe)
MessageBox behavior on Windows XP SP2
(1) Managed code: runtime will raise an exception
NoInteractiveServices = 0 NoInteractiveServices = 1
SERVICE_INTERACTIVE_PROCESS
(CreateService, ChangeServiceConfig)
Window station (service is running as SYSTEM) 0x00000000
"Allow service to interact with desktop"= unchecked
Service-0x0-3e7$ 0x00000100
"Allow service to interact with desktop"= checked
WinSta0 0x00000000
"Allow service to interact with desktop"= unchecked
Service-0x0-3e7$ 0x00000100
"Allow service to interact with desktop"= checked
Service-0x0-3e7$
MessageBox() No display – waiting forever (1) Interactive Service Detection – user can switch to Session 0 to respond service No display – waiting forever (1) SCM warning in event log when starting the service
No display – waiting forever (1)
MessageBox(MB_SERVICE_NOTIFICATION) No display – returns 1 (IDOK)(2) immediately No display – returns 1 (IDOK)(2) immediately No display – returns 1 (IDOK)(2) immediately SCM warning in event log when starting the service
No display – returns 1 (IDOK)(2) immediately
MessageBox behavior on Windows Vista RTM
(1) Managed code: runtime will raise an exception
(2) Even if message box has no such button
相关推荐
Isolation and characterization of a novel mesonivirus from Culex mosquitoes in China
在介绍和分析数据库事务隔离级别的经典文献《A Critique of ANSI SQL Isolation Levels》中,作者Hal Berenson、Phil Bernstein、Jim Gray、Jim Melton、Elizabeth O’Neil和Patrick O'Neil深入探讨了ANSI SQL-92...
对比了世界各地不同工作组的方法,并详细介绍了牛心线粒体的提取、亚线粒体颗粒、F1-ATP酶、F0-ATP酶及其亚基(包括F1-ATP酶的α、β、γ、δ、ε亚基和F0-ATP酶的b、c、d、e、f、g、h、F6、A6L亚基)以及与ATP酶...
此外,Vista在WinLogOn阶段引入了“Session 0 Isolation”策略,将系统服务与用户会话分开运行,降低了由于服务错误导致的桌面崩溃风险。这个改动提高了系统的稳定性,但同时也对开发服务型应用程序提出了新的挑战。...
本文将重点分析Windows Vista中引入的两大关键安全特性:用户账户保护(User Account Protection,UAP)和用户界面权限隔离(User Interface Privilege Isolation,UIPI)。此外,还将探讨这些特性的一些不足之处,...
标题 "A network virtualization approach for performance isolation in controller area network (CAN)" 涉及的核心知识点是网络虚拟化在控制器区域网络(CAN)中的应用,旨在实现性能隔离。在这个主题下,我们将...
DB - A Critique of ANSI SQL Isolation Levels.pdf ANSI SQL-92 [MS, ANSI] defines Isolation Levels in terms of phenomena: Dirty Reads, Non-Re-peatable Reads, and Phantoms. This document shows that ...
Isolation and Preliminary Identification of Aluminium-resistant Microorganisms from the Rhizophric Soil of Tea Plant,吴颖,梁月荣,Microorganism isolated from rhizospheric soil of tea plant was ...
UIPI(User Interface Privilege Isolation,用户界面特权隔离)是微软在Windows Vista操作系统中引入的一项重要安全特性。这一特性主要目的是为了防止恶意软件利用窗口消息传递机制进行攻击或执行未授权的操作。在...
在Windows Vista系统中,服务优化是一项重要的维护任务,旨在提高系统性能和稳定性。Vista引入了许多新服务,其中一些是针对 Ultimate版本特有的。以下是一些关键服务的详细说明,以及优化建议: 1. **Application ...
在Windows Vista操作系统中,服务是系统的核心组成部分,它们在后台执行特定的任务,为用户和应用程序提供支持。然而,这些服务的默认配置可能并不适合每个用户的实际需求,有时会导致系统资源的浪费,甚至影响系统...
该研究由赵鑫、田丰伟等人完成,涉及人体肠道细菌对氯霉素作为唯一碳源和能量来源的利用能力。研究团队从健康志愿者粪便样本中分离出五株能够利用氯霉素的需氧肠道细菌,并通过菌株形态、生理生化特征以及16SrDNA...
随着技术的进步和社会对安全可靠性的需求日益增长,故障检测与隔离(Fault Detection and Isolation, FDI)成为了设计安全可靠系统的关键环节之一。传统的FDI方法通常依赖于系统的线性特性以及噪声和干扰的高斯分布...
from its role in energy production, mitochondrial respiration also plays a crucial part in plant stress response, detoxification, and signaling. The measurement of mitochondrial respiration in ...
see problems that they experienced daily solved in a matter of moments. Those peo- ple reacted with an excitement similar to mine. In the summer of 2014, an associate publisher with Manning called me ...
羊草LcSAP基因的克隆及提高转基因酵母耐盐性的分析,刘晶莹,杨睎喆,本文通过RACE技术从羊草中克隆LcSAP基因,该基因编码161氨基酸残基,蛋白分子量17.6 kDa。RT-PCR分析表明LcSAP基因在叶中比根中表达量高,�