Rise的自留地

记录生活中的点滴,分享编程技术和游戏开发经验。

0%

下面的这些内容不包含在本文中:
官方的Lua包和文档 (参看 http://www.lua.org/),
涉及到Lua使用但不是被Lua使用者普遍使用的东西 (参看 http://www.lua.org/uses.html),
本wiki已经存在的内容(参看 LuaDirectory).

类库和与Lua绑定的资源

LibrariesAndBindings

开发环境

  • [LuaIDE] (5.0) - Windows平台Lua的整合开发环境(最新发布 2004-01-29).
  • [wxLua] (5.0) - Lua and wxWidgets的混合体.有自己的带有调试器的IDE。这个IDE使用wxlua开发的。
  • [LuaEclipse] (5.0) - Eclipse 平台的Lua IDE .
  • [Vortex LuaIDE] (5.0) - Brazilian Portuguese的一些免费的Lua IDE! (Outra IDE para Lua gratuita, mas em Português!).
  • [LuaX] (5.x) - 支持多种操作系统下开发Lua应用的开发平台(with GUI, serial port etc. modules)特别适合于工业自动化和嵌入式产品开发。
  • [VisualWx] (5.x) - Lua & wxLua的IDE (自由软件)
  • [QDE] (5.x) - Lua的Quotix 开发环境. 他支持工程管理,多文档接口等 (最新发布2005-03-06).
  • [B:Lua] - 开源项目: 具备各种特征的Lua IDE.

代码封装

  • [CPB] (5.0)(Win32) - C++ 和 Lua连接之桥,实现两种语言的相互通信.
  • [CaLua] (5.0) - 实现了绑定C函数和结构体到Lua,可以在Lua中使用C指针、数组、函数。(使用x86结构的计算机)
  • [CppLua] (5.0) - lua API的C++封装。
  • [lua2c] (5.0) - 将Lua代码转换成C代码的工具.
  • [luabind] (5.0) - 基于模板的,绑定Lua和C++类以及函数
  • [tolua] (5.0) - 自动绑定C/C++和Lua的工具.
  • LuaWrapper 基于模版的封装包,很容易绑定C++代码和Lua。纯头文件。
  • [tolua++] (5.0) - tolua的高级版本,带有c++面向对象的特征. ( CompilingToluappWithoutScons i.e., Compiling Tolua++ Without SCons )
  • [luapi] (5.0) - Lua api的C封装.
  • [PBLua] (5.0.2) - Lua 5.0.2基本库的封装.
  • [PowerBLua] (5.0) - PowerBASIC include & source for wrapping Lua (work in progress).
  • [wxScript] (5.0.2) - 一些抽象类,添加到脚本解释器可以使你的wxWidgets支持Lua语言。
  • [LunaticPython] (0.1) - Lua/Python 的双向桥。可以将Lua解释器嵌入到python中,反过来也可以。

Lua的使用

Lua的使用列表[1].

  • [Premake] -一个用Lua语言实现的 automake 替代品. 可以为MS VC++, GNU make, 等创建工程文件.
  • [Lumikki] (5.0) - 使用Lua宏创建web站点,可以使用导航菜单,风格等。

工具

  • ExpLua (5.0) - 代码文档工具(开发中。。。).
  • [Hamster (ex SCons/Lua)] (5.x) - Lua front-end to the SCons build engine (or others).
  • [Kepler Project] (5.0) - 使用 [CGILua 5.0]实现的Lua 5.0的web模板引擎 .
  • [Mod_Lua (5.0)] -  Apache 2的 module,使得web应用与PHP类似。
  • [ctrace] (5.0) - 跟踪Lua API调用的工具.
  • [lper] (5.0) - 创建持久Lua 状态的工具, 基于 [GNU mmalloc] (part of GDB).
  • PlutoLibrary (5.0.2) - 为Lua创建重量级的持久性.
  • [ChunkSpy] (5.0.2) - a binary chunk disassembler, with interactive mode, reading custom binary chunk formats, etc.
  • [lua bakefile] (5.0.2) - 创建 LUA 工程的makefile和工程文件。
  • [tolua bakefile] (5.0.2) - 创建 TOLUA 工程的makefile和工程文件。
  • [ChunkBake] (5.0.2) - a line-oriented assembler for Lua 5 virtual machine instructions
  • [LuaSrcDiet] (5.0.2) - 通过删除不必要的空白和注释缩减Lua文件的大小。
  • [LuaProfiler] (5.0) - 一个用来查找Lua应用瓶颈的工具time profiler 。

See also LuaEditorSupport.

文档

发布版

See LuaBinaries for links to precompiled vanilla Lua 5.0 executables for various platforms. Real binaries (without addons) should move from here to there.

  • [LuaCheia] (5.0) - Lua 5.0 for GNU/Linux, Mac/OS X, Windows, *BSD, Solaris, etc. Includes many add-on binary modules.
  • [LuaPlus] (5.0) - C++ enhancements and various extensions to core Lua functionality
  • [Linux RPMs] (5.0) - i386 binary, source and spec file for Lua 5.0.2
  • [RPMs for Lua] (5.0) - from Rpmfind.Net.
  • [RPMs with Lua modules]
  • [Lua 5 for EPOC] (5.0) - Lua 5.0.1 for Symbian OS v1-5.
  • [LuaCE] (5.0) - additional source files for compiling Lua for Windows CE.
  • [LuaPPC] (5.0) - Stand-alone Lua 5.0 interpreter for the Pocket PC. (Built using LuaCE above.)
  • [LuaPocket] (5.0) - Stand-alone Lua 5.0 interpreter for the Pocket PC with graphic support. (Built using LuaPPC above.)
  • [Lua for RISC OS] (5.0)
  • [Lua for Palm OS] (5.0) Port of Lua for Palm (in alpha).
  • [Lua89] (5.0) Experimental port of Lua to the TI89 graphing calculator.

其他的一些Lua实现方式

  • [Sol] - Lua 的派生物.
  • [Lua.NET] .net相关的Lua
  • [LuaLeo] -  根据[Leonardo VM] 实现的Lua 3.1
  • [Lua-ML] -  由面向对象的Caml实现的 Lua 2.5
  • [Yindo] - Lua 的实现,作为OpenGL 浏览器插件(很快过时了)
  • [Yueliang] (5.0.2) - 使用Lua实现Lua,包括词法解析、语法解析、代码生成和生成二进制chunks.

大家知道,Windows NT/2000为实现其可靠性,严格将系统划分为内核模式与用户模式,在i386系统中分别对应CPU的Ring0与Ring3级别。Ring0下,可以执行特权级指令,对任何I/O设备都有访问权等等。要实现从用户态进入核心态,即从Ring 3进入Ring 0必须借助CPU的某种门机制,如中断门、调用门等。而Windows NT/2000提供用户态执行系统服务(Ring 0例程)的此类机制即System Service的int 2eh中断服务等,严格的参数检查,只能严格的执行Windows NT/2000提供的服务,而如果想执行用户提供的Ring 0代码(指运行在Ring 0权限的代码),常规方法似乎只有编写设备驱动程序。本文将介绍一种在用户态不借助任何驱动程序执行Ring0代码的方法。

    Windows NT/2000将设备驱动程序调入内核区域(常见的位于地址0x80000000上),由DPL为0的GDT项8,即cs为8时实现Ring 0权限。本文通过在系统中构造一个指向我们的代码的调用门(CallGate),实现Ring0代码。基于这个思路,为实现这个目的主要是构造自己的CallGate。CallGate由系统中叫Global Descriptor Table(GDT)的全局表指定。GDT地址可由i386指令sgdt获得(sgdt不是特权级指令,普通Ring 3程序均可执行)。GDT地址在Windows NT/2000保存于KPCR(Processor Control Region)结构中(见《再谈Windows NT/2000环境切换》)。GDT中的CallGate是如下的格式:

    typedef struct
    {
        unsigned short  offset_0_15;
        unsigned short  selector;

        unsigned char    param_count : 4;
        unsigned char    some_bits   : 4;

        unsigned char    type        : 4;
        unsigned char    app_system  : 1;
        unsigned char    dpl         : 2;
        unsigned char    present     : 1;
    
        unsigned short  offset_16_31;
    } CALLGATE_DESCRIPTOR;

    GDT位于内核区域,一般用户态的程序是不可能对这段内存区域有直接的访问权。幸运的是Windows NT/2000提供了一个叫PhysicalMemory的Section内核对象位于\Device的路径下。顾名思义,通过这个Section对象可以对物理内存进行操作。用objdir.exe对这个对象分析如下:

    C:\NTDDK\bin>objdir /D \Device

    PhysicalMemory                   
        Section
        DACL - 
           Ace[ 0] - Grant - 0xf001f - NT AUTHORITY\SYSTEM
                             Inherit: 
                             Access: 0x001F  and  ( D RCtl WOwn WDacl )

           Ace[ 1] - Grant - 0x2000d - BUILTIN\Administrators
                             Inherit: 
                             Access: 0x000D  and  ( RCtl )

    从dump出的这个对象DACL的Ace可以看出默认情况下只有SYSTEM用户才有对这个对象的读写权限,即对物理内存有读写能力,而Administrator只有读权限,普通用户根本就没有权限。不过如果我们有Administrator权限就可以通过GetSecurityInfo、SetEntriesInAcl与SetSecurityInfo这些API来修改这个对象的ACE。这也是我提供的代码需要Administrator的原因。实现的代码如下:

    VOID SetPhyscialMemorySectionCanBeWrited(HANDLE hSection)
    {

       PACL pDacl=NULL;
       PACL pNewDacl=NULL;
       PSECURITY_DESCRIPTOR pSD=NULL;
       DWORD dwRes;
       EXPLICIT_ACCESS ea;

       if(dwRes=GetSecurityInfo(hSection,SE_KERNEL_OBJECT,DACL_SECURITY_INFORMATION,
                  NULL,NULL,&pDacl,NULL,&pSD)!=ERROR_SUCCESS)
          {
             printf( “GetSecurityInfo Error %u\n”, dwRes );
             goto CleanUp;
          }

       ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
       ea.grfAccessPermissions = SECTION_MAP_WRITE;
       ea.grfAccessMode = GRANT_ACCESS;
       ea.grfInheritance= NO_INHERITANCE;
       ea.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
       ea.Trustee.TrusteeType = TRUSTEE_IS_USER;
       ea.Trustee.ptstrName = “CURRENT_USER”;


       if(dwRes=SetEntriesInAcl(1,&ea,pDacl,&pNewDacl)!=ERROR_SUCCESS)
          {
             printf( “SetEntriesInAcl %u\n”, dwRes );
             goto CleanUp;
          }

       if(dwRes=SetSecurityInfo(hSection,SE_KERNEL_OBJECT,DACL_SECURITY_INFORMATION,NULL,NULL,pNewDacl,NULL)!=ERROR_SUCCESS)
          {
             printf(“SetSecurityInfo %u\n”,dwRes);
             goto CleanUp;
          }

    CleanUp:

       if(pSD)
          LocalFree(pSD);
       if(pNewDacl)
          LocalFree(pSD);
    }

    这段代码对给定HANDLE的对象增加了如下的ACE:

    PhysicalMemory                   
        Section
        DACL - 
           Ace[ 0] - Grant - 0x2 - WEBCRAZY\Administrator
                             Inherit: 
                             Access: 0x0002    //SECTION_MAP_WRITE

    这样我们在有Administrator权限的条件下就有了对物理内存的读写能力。但若要修改GDT表实现Ring 0代码。我们将面临着另一个难题,因为sgdt指令获得的GDT地址是虚拟地址(线性地址),我们只有知道GDT表的物理地址后才能通过\Device\PhysicalMemory对象修改GDT表,这就牵涉到了线性地址转化成物理地址的问题。我们先来看一看Windows NT/2000是如何实现这个的:

    kd> u nt!MmGetPhysicalAddress l 30
    ntoskrnl!MmGetPhysicalAddress:
    801374e0 56               push    esi
    801374e1 8b742408         mov     esi,[esp+0x8]
    801374e5 33d2             xor     edx,edx
    801374e7 81fe00000080     cmp     esi,0x80000000
    801374ed 722c             jb    ntoskrnl!MmGetPhysicalAddress+0x2b (8013751b)
    801374ef 81fe000000a0     cmp     esi,0xa0000000
    801374f5 7324             jnb   ntoskrnl!MmGetPhysicalAddress+0x2b (8013751b)
    801374f7 39153ce71780     cmp     [ntoskrnl!MmKseg2Frame (8017e73c)],edx
    801374fd 741c             jz    ntoskrnl!MmGetPhysicalAddress+0x2b (8013751b)
    801374ff 8bc6             mov     eax,esi
    80137501 c1e80c           shr     eax,0xc
    80137504 25ffff0100       and     eax,0x1ffff
    80137509 6a0c             push    0xc
    8013750b 59               pop     ecx
    8013750c e8d3a7fcff       call    ntoskrnl!_allshl (80101ce4)
    80137511 81e6ff0f0000     and     esi,0xfff
    80137517 03c6             add     eax,esi
    80137519 eb17             jmp   ntoskrnl!MmGetPhysicalAddress+0x57 (80137532)
    8013751b 8bc6             mov     eax,esi
    8013751d c1e80a           shr     eax,0xa
    80137520 25fcff3f00       and     eax,0x3ffffc
    80137525 2d00000040       sub     eax,0x40000000
    8013752a 8b00             mov     eax,[eax]
    8013752c a801             test    al,0x1
    8013752e 7506             jnz   ntoskrnl!MmGetPhysicalAddress+0x44 (80137536)
    80137530 33c0             xor     eax,eax
    80137532 5e               pop     esi
    80137533 c20400           ret     0x4

    从这段汇编代码可看出如果线性地址在0x80000000与0xa0000000范围内,只是简单的进行移位操作(位于801374ff-80137519指令间),并未查页表。我想Microsoft这样安排肯定是出于执行效率的考虑。这也为我们指明了一线曙光,因为GDT表在Windows NT/2000中一般情况下均位于这个区域(我不知道/3GB开关的Windows NT/2000是不是这种情况)。

    经过这样的分析,我们就可以只通过用户态程序修改GDT表了。而增加一个CallGate就不是我可以介绍的了,找本Intel手册自己看一看了。具体实现代码如下:

    typedef struct gdtr {
        short Limit;
        short BaseLow;
        short BaseHigh;
    } Gdtr_t, PGdtr_t;

    ULONG MiniMmGetPhysicalAddress(ULONG virtualaddress)
    {
        if(virtualaddress<0x80000000||virtualaddress>=0xA0000000)
           return 0;
        return virtualaddress&0x1FFFF000;
    }

    BOOL ExecRing0Proc(ULONG Entry,ULONG seglen)
    {
       Gdtr_t gdt;
       __asm sgdt gdt;
     
       ULONG mapAddr=MiniMmGetPhysicalAddress(gdt.BaseHigh<<16U|gdt.BaseLow);
       if(!mapAddr) return 0;

       HANDLE   hSection=NULL;
       NTSTATUS status;
       OBJECT_ATTRIBUTES        objectAttributes;
       UNICODE_STRING objName;
       CALLGATE_DESCRIPTOR cg;

       status = STATUS_SUCCESS;
   
       RtlInitUnicodeString(&objName,L"\Device\PhysicalMemory");

       InitializeObjectAttributes(&objectAttributes,
                                  &objName,
                                  OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                                  NULL,
                                 (PSECURITY_DESCRIPTOR) NULL);

       status = ZwOpenSection(&hSection,SECTION_MAP_READ|SECTION_MAP_WRITE,&objectAttributes);

       if(status == STATUS_ACCESS_DENIED){
          status = ZwOpenSection(&hSection,READ_CONTROL|WRITE_DAC,&objectAttributes);
          SetPhyscialMemorySectionCanBeWrited(hSection);
          ZwClose(hSection);
          status =ZwOpenSection(&hSection,SECTION_MAP_WRITE|SECTION_MAP_WRITE,&objectAttributes);
       }

       if(status != STATUS_SUCCESS)
         {
            printf(“Error Open PhysicalMemory Section Object,Status:%08X\n”,status);
            return 0;
         }
      
       PVOID BaseAddress;

       BaseAddress=MapViewOfFile(hSection,
                     FILE_MAP_READ|FILE_MAP_WRITE,
                     0,
                     mapAddr,    //low part
                     (gdt.Limit+1));

       if(!BaseAddress)
          {
             printf(“Error MapViewOfFile:”);
             PrintWin32Error(GetLastError());
             return 0;
          }

       BOOL setcg=FALSE;

       for(cg=(CALLGATE_DESCRIPTOR 
)((ULONG)BaseAddress+(gdt.Limit&0xFFF8));(ULONG)cg>(ULONG)BaseAddress;cg–)
           if(cg->type == 0){
             cg->offset_0_15 = LOWORD(Entry);
             cg->selector = 8;
             cg->param_count = 0;
             cg->some_bits = 0;
             cg->type = 0xC;          // 386 call gate
             cg->app_system = 0;      // A system descriptor
             cg->dpl = 3;             // Ring 3 code can call
             cg->present = 1;
             cg->offset_16_31 = HIWORD(Entry);
             setcg=TRUE;
             break;
          }

       if(!setcg){
            ZwClose(hSection);
            return 0;
       }

       short farcall[3];

       farcall[2]=((short)((ULONG)cg-(ULONG)BaseAddress))|3;  //Ring 3 callgate;

       if(!VirtualLock((PVOID)Entry,seglen))
          {
             printf(“Error VirtualLock:”);
             PrintWin32Error(GetLastError());
             return 0;
          }

       SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_TIME_CRITICAL);

       Sleep(0);

       _asm call fword ptr [farcall]

       SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_NORMAL);

       VirtualUnlock((PVOID)Entry,seglen);

       //Clear callgate
       
(ULONG )cg=0;
       
((ULONG *)cg+1)=0;

       ZwClose(hSection);
       return TRUE;

    }

    我在提供的代码中演示了对Control Register与I/O端口的操作。CIH病毒在Windows 9X中就是因为获得Ring 0权限才有了一定的危害,但Windows NT/2000毕竟不是Windows 9X,她已经有了比较多的安全审核机制,本文提供的代码也要求具有Administrator权限,但如果系统存在某种漏洞,如缓冲区溢出等等,还是有可能获得这种权限的,所以我不对本文提供的方法负有任何的责任,所有讨论只是一个技术热爱者在讨论技术而已。谢谢! 

    参考资料:
      1.Intel Corp<<Intel Architecture Software Developer’s Manual,Volume 3>>  


代码下载:http://www.cnblogs.com/Files/flying_bat/ntring0.zip

本篇是{% post_link alpha-color-blending-in-D3D-2 “D3D中的Alpha颜色混合(2)” %}的后续篇。

另一种实现实现背景透明显示的简便方法是直接应用渲染管道流水线的Alpha测试功能进行,{% post_link alpha-color-blending-in-D3D-2 “D3D中的Alpha颜色混合(2)” %}介绍的接口方法实际就是对Alpha测试的一个包装。Alpha测试是对需要写入绘图表面的像素颜色Alpha值进行测试,判断该Alpha值是否满足预先设定的条件,如果满足条件,则将该像素颜色值写入绘图表面,否则不写入。

渲染管道流水线通常需要将来自顶点的颜色,纹理像素的颜色,光照颜色以及物体表面材质反射光颜色进行混合,生成计算机屏幕的像素颜色。将多种颜色混合在一起,必须考虑各种颜色的成分比例,这个比例由Alpha因子决定。对于游戏开发来说,利用Alpha颜色混合可产生背景透明的渲染效果。

代码共享如下,在Win2K sp4/WinXP sp2上调试通过。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
BOOL CheckFileTrust( LPCWSTR lpFileName )
{
        BOOL bRet = FALSE;
    WINTRUST_DATA wd = { 0 };
    WINTRUST_FILE_INFO wfi = { 0 };
    WINTRUST_CATALOG_INFO wci = { 0 };
    CATALOG_INFO ci = { 0 };

    HCATADMIN hCatAdmin = NULL;
    <FONT color=blue>if</FONT> ( !CryptCATAdminAcquireContext( &amp;hCatAdmin, NULL, 0 ) )
    {
            <FONT color=blue>return</FONT> FALSE;
    }

    HANDLE hFile = CreateFileW( lpFileName, GENERIC_READ, FILE_SHARE_READ,
        NULL, OPEN_EXISTING, 0, NULL );
    <FONT color=blue>if</FONT> ( INVALID_HANDLE_VALUE == hFile )
    {
            CryptCATAdminReleaseContext( hCatAdmin, 0 );
        <FONT color=blue>return</FONT> FALSE;
    }

    DWORD dwCnt = 100;
    BYTE byHash[100];
    CryptCATAdminCalcHashFromFileHandle( hFile, &amp;dwCnt, byHash, 0 );
    CloseHandle( hFile );

    LPWSTR pszMemberTag = <FONT color=blue>new</FONT> WCHAR[dwCnt * 2 + 1];
    <FONT color=blue>for</FONT> ( DWORD dw = 0; dw &lt; dwCnt; ++dw )
    {
            wsprintfW( &amp;pszMemberTag[dw * 2], L"%02X", byHash[dw] );
    }

    HCATINFO hCatInfo = CryptCATAdminEnumCatalogFromHash( hCatAdmin,
        byHash, dwCnt, 0, NULL );
    <FONT color=blue>if</FONT> ( NULL == hCatInfo )
    {
            wfi.cbStruct       = <FONT color=blue>sizeof</FONT>( WINTRUST_FILE_INFO );
        wfi.pcwszFilePath  = lpFileName;
        wfi.hFile          = NULL;
        wfi.pgKnownSubject = NULL;

        wd.cbStruct            = <FONT color=blue>sizeof</FONT>( WINTRUST_DATA );
        wd.dwUnionChoice       = WTD_CHOICE_FILE;
        wd.pFile               = &amp;wfi;
        wd.dwUIChoice          = WTD_UI_NONE;
        wd.fdwRevocationChecks = WTD_REVOKE_NONE;
        wd.dwStateAction       = WTD_STATEACTION_IGNORE;
        wd.dwProvFlags         = WTD_SAFER_FLAG;
        wd.hWVTStateData       = NULL;
        wd.pwszURLReference    = NULL;
    }
    <FONT color=blue>else</FONT>
    {
            CryptCATCatalogInfoFromContext( hCatInfo, &amp;ci, 0 );
        wci.cbStruct             = <FONT color=blue>sizeof</FONT>( WINTRUST_CATALOG_INFO );
        wci.pcwszCatalogFilePath = ci.wszCatalogFile;
        wci.pcwszMemberFilePath  = lpFileName;
        wci.pcwszMemberTag       = pszMemberTag;

        wd.cbStruct            = <FONT color=blue>sizeof</FONT>( WINTRUST_DATA );
        wd.dwUnionChoice       = WTD_CHOICE_CATALOG;
        wd.pCatalog            = &amp;wci;
        wd.dwUIChoice          = WTD_UI_NONE;
        wd.fdwRevocationChecks = WTD_STATEACTION_VERIFY;
        wd.dwProvFlags         = 0;
        wd.hWVTStateData       = NULL;
        wd.pwszURLReference    = NULL;
    }
    GUID action = WINTRUST_ACTION_GENERIC_VERIFY_V2;
    HRESULT hr  = WinVerifyTrust( NULL, &amp;action, &amp;wd );
    bRet        = SUCCEEDED( hr );

    <FONT color=blue>if</FONT> ( NULL != hCatInfo )
    {
            CryptCATAdminReleaseCatalogContext( hCatAdmin, hCatInfo, 0 );
    }
    CryptCATAdminReleaseContext( hCatAdmin, 0 ); <FONT color=green>// 2007.4.10感谢童志明君指出一处内存泄漏</FONT>
    <FONT color=blue>delete</FONT>[] pszMemberTag;
    <FONT color=blue>return</FONT> bRet;
}

这段代码是在一个老外的论坛上不经意搜索到的,一个貌似德国人(因为他的注释不是英文写的,德国亦仅猜测尔,西班牙、葡萄牙、法兰西、俄罗斯亦都有可能)写的Delphi代码,其中使用了WinTrust.dll中的导出函数。使用VS2005的朋友们可以包含WinTrust.h、SoftPub.h和Mscat.h,并添加导入库WinTrust.lib;使用VC6的朋友们可以参考MSDN上的函数及结构体声明,并用函数指针进行调用。

我要做自己情绪的主人!

潮起潮落、冬去春来、月圆月缺、花飞花谢,自然界万物都在循环往复的变化之中,我也不例外,情绪会时好时坏。每天清晨醒来时,我可能不再有旧日的情怀。昨日的欢乐变成今日的哀愁,今日的悲伤又转为明日的喜悦。我的心像车轮般不停地旋转:由乐而悲,由悲而喜,由喜而忧。这就好比花儿的变化,今日绽放时的喜悦终将变成明天凋谢时的绝望。但是我要牢牢记住:正如今天枯败的花儿蕴藏着明天新生的种子,今天的悲伤也预示着明日的欢乐。

我要做自己情绪的主人!

我怎样才能控制自己的情绪,使我的每一天卓有成效?我只知道这样一个事实:无论我为他人带来的是风雨、忧郁、黑暗和悲观,还是欢乐、喜悦、光明和笑声,他们都会以同样而报之。花草树木,随着气候的变化而生长,而我要为自己创造天气,学会用自己的心灵弥补气候的不足。我必须得心平气和,否则迎来的又将是失败的一天。

我要做自己情绪的主人!

我怎样才能控制自己的情绪,让我的每一天充满幸福和欢乐?我要学会这个千古秘诀:弱者任思绪控制行为,强者让行为控制思绪。每天醒来当我被悲伤、自怜、失败的情绪包围时,我就这样与之对抗:沮丧时,我引亢高歌;悲伤时,我开怀大笑;病痛时,我加倍工作;恐惧时,我勇往直前;自卑时,我换上新装;不安时,我提高嗓音;穷困潦倒时,我想象未来的富有;力不从心时,我回想过去的成功;自轻自贱时,我想想自己的目标。

我要做自己情绪的主人!

从今往后,我必须不断对抗那些企图摧垮我的力量。失望与悲伤一眼就可识破,而那些不易觉察、面带微笑、招手而来的敌人,却随时可能将我摧毁。对它们,我永远不能放松警惕:自高自大时,我要追寻失败的记忆;洋洋得意时,我要想想竞争的对手;沾沾自喜时,不要忘了那忍辱的时刻;自以为是时,看看自己能否让风止步;骄傲自满时,要想到自己怯懦的时候;不可一世时,抬起头来,仰望天上群星。

我要做自己情绪的主人!

有了这项本领,我就能体察别人的情绪变化。我会宽容怒气冲冲的人,因为他尚未懂得控制自己的情绪;我能忍受他人的指责与辱骂,因为知道明天他会重新变得随和。我不再只凭一面之交来判断他人,也不再因一时的怨恨与人绝交。今天不肯花一分钱购买金蓬马车的人,明天也许会用全部家当换取树苗。知道了这个秘密,我对人可以宽容大度,对事能够冷静客观。

我要做自己情绪的主人!

我从此领悟了人类情绪变化的奥秘。对于自己千变万化的个性,我不再听之任之,我知道,只有积极主动地控制情绪,才能掌握自己的命运。我成为自己情绪的主人,我由此而变得伟大。

我要做自己情绪的主人!

年初的时候,几乎天天跟人吵架,因为什么呢?因为自己的狗脾气,那会甚至都不管自己到底对不对,反正就是吵。坦诚的说,后来都有点因此而沾沾自喜,觉得那是自己NB,自己是个有个性的人。事到如今,真是忍不住要笑一笑自己了,呵呵,用下面文章里的一句话来说就是:弱 者任情绪控制行为,强者让行为控制情绪。我是弱者,所以让情绪控制了自己的行为,还引以为荣。呵呵,你说可笑不?可笑。把这篇文章收藏在这里,供自己今后 再次翻阅。我想,只要在今后狗脾气再犯的时候,能来这里看看,确实能认真的读一下下面的文字,那我一定可以从弱者变成一个可以控制情绪的人的。

【肇法师曰】闻说诸心。谓有实心。故须破遣。明三世皆空。故论云。过去已灭。未来未起。现在虚妄。三世推求。了不可得。

      【疏钞云】未觉不知。随时流转。故有三世。若悟真一之心。即无过去现在未来。若有过去心可灭。即是自灭。若有未来心可生。即是自生。既有生有灭。即非常住真心。即为依他心。虚妄心。若一念有生灭心。即成六十二种邪见。九百种烦恼。

      【王日休曰】常住真心。即真性也。是以自无量无数劫来。常一定而不变动。岂有过去未来现在哉。若有过去未来现在。则为妄想。此三心是也。且若饱而未欲食。则饮食之心为未来。饥而正欲食。则欲食之心为现在。食毕而放匕箸。则欲食之心为过去。是此心因事而起。事过而灭。故为妄想也。不可得者。谓无也。言此三心本来无有。乃因事而有耳。圆觉经所以言六尘缘影。为自心相者。谓众生以六种尘缘之影。为自己之心相也。

      【僧若讷曰】本生心地观经云。如佛所说。唯将心法。为三界主。心法本源。不染尘秽。云何心法。染贪嗔痴。于三世法。唯说为心。过去心已灭。未来心未至。现在心不住。诸法之内性不可得。诸法之外相不可得。诸法中间都不可得。心法本来无有形相。心法本来无有住处。一切如来尚不可见心。何况余人。得见心法。

      【颜丙曰】谓思念前事者。为过去心。思念今事者。为现在心。思念后事者。为未来心。三念总放下者。谓之不可得。经云。前念后念及今念。念念不被邪见染。此为三心不可得。古云。一念不生全体现。亦谓三际俱断。三念俱妄。了不可得。

      【傅大士颂曰】依他一念起。俱为妄所行。便分六十二。九百乱纵横。(法华经二卷。世尊偈言。薄德少福人。众苦所逼迫。入邪见稠林。若有若无等。依止此诸见。具足六十二。毗婆沙论云。六十二见者。五蕴中各起四见。四五二十。三世各二十。通为六十。断常二见为根本。总为六十二见。且于色蕴中。即色是我。离色非我。我中有色。色中有我。五蕴中具有此四。疏钞解三心云。若一念有生灭心。即成六十二种邪见。九百种烦恼。)过此灭无灭。(一作不灭。)当来生不生。常能作此观。(去声)真妄坦然平。(晁文元公遇高士刘惟一。访以生灭之事。刘曰。人常不死。公骇之。刘曰。形死性不灭。是知此性历长存。)

      【川禅师曰】低声低声。真得鼻孔里出气。颂曰。三际求心心不见。两眼依然对两眼。不须遗剑刻舟寻。雪月风花常见面。

      【未曾有经云】妙吉祥菩萨。因见一人。言我造杀业。决堕地狱。如何救度。菩萨即化一人。亦曰。我造杀业。决堕地狱。前人闻已。言我亦然。化人告之。唯佛能救。相随共诣。化人白佛。我造杀业。怖堕地狱。愿佛救度。佛即告言。如汝所说造杀业者。汝从何心而起业相。为过去耶。未来耶。现在耶。若起过去心者。过去已灭。心不可得。若起未来心者。未来未来。心不可得。若起见在心者。见在不住。心不可得。三界俱不可得故。即无起作。无起作故。于其罪相何所见耶。善男子。心无所住。不在内外中间。心无色相。非青黄赤白。心无造作。无作者故。心非幻化。本真实故。心无边际。非限量故。心无取舍。非善恶故。心无转动。非生灭故。心等空虚。无障碍故。心非染净。离一切数故。善男子作是观者。即于一切法中。求心不可得。何以故。心之自性。即诸法性。诸法性空。即真实性。由是义故。汝今不应妄生怖畏。是时化人闻佛说法。即白佛言。我今得悟罪业性空。不生怖畏。尔时实造业者。亦白佛言。我今得悟罪业性空。而不复生怖畏之心。

      【李文会曰】谓三世心无性可得。故可从缘而生。

      【肇法师云】闻说诸心。谓有实心。故须破遣。明三世皆空。故云过去已灭。未来未起。现在虚妄。三世推求。了不可得。故云若悟无法无相无事平常真心。即法体空寂。不生不灭。湛然清净。岂有前念今念后念可得也。

      【马祖云】道不用修。但莫洿染。何谓洿染。但有生死造作趣向。皆是洿染。若欲直会其道。平常心即是道。何谓平常心。无造作。无是非。无取舍。无憎爱。无圣凡。是故经云。非凡夫行。非圣贤行。是菩萨行。

      【赵州问南泉云】如何是道。泉云。平常心是道。

      【圜悟禅师颂曰】欲识平常道。天真任自然。行船宜举棹。走马即加鞭。若遇饥来饭。还应困即眠。尽从缘所得。所得亦非缘。