志福's profile阿福台PhotosBlogLists Tools Help

Blog


    11/10/2009

    全民炒房是一种犯罪

    对《看高房价如何逼走自住客》的评论:

    忠告大家,钱多的没处花的人,房子价格再高你买就是了,而没钱的,建议你不要脑子一时发热去买超过自己消费能力的高价房来“投资”,等到你看到还会涨,基本也已经到顶了,你要去站岗吗?

    现在的炒房子是一种全民运动,有谁会愿意自己买的房子跌,都是“不卖房也天天问价”,恨不得一夜暴富,虽然自住的又不卖,但虚荣的心态和假富的资产,让他们乐此不彼(其实这是一种心理的疾病)。这样畸形的社会现象,可能只有到了极限才会有破灭的可能,大家才会警醒,既然理性的价格让大家觉得不够“刺激”不够爽,那就让房价涨得更快些吧...

    试问:

    全民炒房子,这是一种利用全民的犯罪行为,在你们贪婪去推高房子价格的同时,你们是否看到了物价的快速上涨,你们觉得你们变得“有钱”了吗?你们过得更加幸福了吗?你们是最后的赢家吗?你果真的不明白,那么建议先弄明白啥是钱,至少可以活的不那么“傻”,一辈子让社会愚弄。

    啥是钱,你真的懂了吗?

    钱只是一种符号,行使权,如果你过的并不幸福,你死的时候留下再多的钱对你自身来说是没有任何意义的。

    钱是用来让社会各种活动可以顺利进行,它的价值在于流通,如果没有流通,钱将变的一无所值。

    如果你觉得把钱拿去消费和销毁是一种浪费,那么你错了。你的钱消失了,只是一种流通的工具消失了而已,中国的国家财富并不会减少,钱不够用时央行可以再印。

    建议:

    适当合理地利用你手上的钱,让你自己过的幸福一点,会比一味地想着去房子来的更实在些。生命不过百年,但愿你不是天生就是来人间受苦的,我佛慈悲...

    10/16/2009

    河南安阳3.599亿大奖作假猜想

          是否有人想到过,这张3.599亿中奖的彩票,是否事实上并不存在呢?

          机选号码没有人会去记住它,只知44倍而已,只要在开奖后内部做假或入侵服务器,修改福彩中心数据,将该张44倍票的选号改成中奖号码即可。但是这个修改要在大奖公布前完成,而福彩中心的数据在开奖前应该已经封存了。只有内网才能连接,所以一定要有内部的人来配合完成这件事情。彩票根本没有双向防伪机制,只有单向的防伪码,可以在事后仿造出一张“真”的中奖彩票出来(只要在原来彩票的基础上将选号改成中奖号,其他完成一样即可)。假如真的如此,我们可以相信,即使是公开摇奖也于事无补,对这种做假也是防不胜防。

           合谋也好,入侵也好,相信福彩中心的数据系统也不安全,看来是需要有一套防作假系统来配合了,数据分开存储相互验证。

           假如真的是内部合谋,用保护个人信息隐私当挡箭版,这些信息永远不见天日,这些钱就可以无声无息地在人间"蒸发"了。像这种问无权问,查无人查,管无人管的事情,正是现在这个社会的管理漏洞。
     
           福彩中心的人,素质都那么高么?能有几个有骨气的?在这么大的金额面前,怎么分钱都够堵嘴巴了。
     
          实在不知道怎么去评论这类事情,有点像汶川大地震中那些泡沫工程一样,大事化小,小事化了,不闻不问,最后不了了之。诸如此类不公之事,无度频发,愈演愈烈,实非社会之福,有背和谐之本。
    4/20/2009

    Asp.net 常用的正则表达式汇集

    使用方法 

    using System.Text.RegularExpressions;
       string strCheck = TextBox1.Text.ToString();
            if (Regex.IsMatch(strCheck, "["u4e00-"u9fa5]{1,}$") == true)
            {
                Response.Write("是中文");
            }
            else
            {
                Response.Write("不是中文");
            }
     1.判断是否全部都是汉字:["u4e00-"u9fa5]{1,}$
     2.判断是否符合日期或日期加时间的格式。日期的年月日之间可以使-/或空格:
    ^(("d{2}(([02468][048])|([13579][26]))["-"/"s]?((((0?[13578])|(1[02]))["-"/"s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))["-"/"s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2["-"/"s]?((0?[1-9])|([1-2][0-9])))))|("d{2}(([02468][1235679])|([13579][01345789]))["-"/"s]?((((0?[13578])|(1[02]))["-"/"s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))["-"/"s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2["-"/"s]?((0?[1-9])|(1[0-9])|(2[0-8]))))))("s(((0?[0-9])|([1-2][0-3]))":([0-5]?[0-9])(("s)|(":([0-5]?[0-9])))))?$
     
     
     
    匹配Email地址的正则表达式:"w+([-+.]"w+)*@"w+([-.]"w+)*"."w+([-.]"w+)*
    评注:表单验证时很实用
     
    匹配网址URL的正则表达式:[a-zA-z]+://[^"s]*
    评注:网上流传的版本功能很有限,上面这个基本可以满足需求
     
    匹配帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):^[a-zA-Z][a-zA-Z0-9_]{4,15}$
    评注:表单验证时很实用
     
    匹配国内电话号码:"d{3}-"d{8}|"d{4}-"d{7}
    评注:匹配形式如 0511-4405222 或 021-87888822
     
    匹配腾讯QQ号:[1-9][0-9]{4,}
    评注:腾讯QQ号从10000开始
     
    匹配中国邮政编码:[1-9]"d{5}(?!"d)
    评注:中国邮政编码为6位数字
     
    匹配身份证:"d{15}|"d{18}
    评注:中国的身份证为15位或18位
     
    匹配ip地址:"d+"."d+"."d+"."d+
    评注:提取ip地址时有用
     
    匹配特定数字:
    整数或者小数:^[0-9]+".{0,1}[0-9]{0,2}$
    只能输入数字:"^[0-9]*$"。
    只能输入n位的数字:"^"d{n}$"。
    只能输入至少n位的数字:"^"d{n,}$"。
    只能输入m~n位的数字:。"^"d{m,n}$"
    只能输入零和非零开头的数字:"^(0|[1-9][0-9]*)$"。
    只能输入有两位小数的正实数:"^[0-9]+(.[0-9]{2})?$"。
    只能输入有1~3位小数的正实数:"^[0-9]+(.[0-9]{1,3})?$"。
    只能输入非零的正整数:"^"+?[1-9][0-9]*$"。
    只能输入非零的负整数:"^"-[1-9][]0-9"*$。
    只能输入非负整数(正整数+0):"^"d+$"      或者  ^[1-9]"d*|0$
    只能输入正整数:"^[0-9]*[1-9][0-9]*$"  或者  ^[1-9]"d*$
    只能输入非正整数(负整数+0):"^((-"d+)|(0+))$"  或者  ^-[1-9]"d*|0$
    只能输入负整数:"^-[0-9]*[1-9][0-9]*$"  或者 ^-[1-9]"d*$
    只能输入整数:"^-?"d+$"    或者 ^-?[1-9]"d*$
    只能输入非负浮点数(正浮点数+0):"^"d+("."d+)?$"   或者  ^[1-9]"d*"."d*|0"."d*[1-9]"d*|0?".0+|0$
    只能输入正浮点数:"^(([0-9]+".[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*".[0-9]+)|([0-9]*[1-9][0-9]*))$"   或者  ^[1-9]"d*"."d*|0"."d*[1-9]"d*$
    只能输入非正浮点数(负浮点数+0):"^((-"d+("."d+)?)|(0+(".0+)?))$"   或者  ^-([1-9]"d*"."d*|0"."d*[1-9]"d*)$
    只能输入负浮点数:"^(-(([0-9]+".[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*".[0-9]+)|([0-9]*[1-9][0-9]*)))$" 
                     或者 ^(-([1-9]"d*"."d*|0"."d*[1-9]"d*))|0?".0+|0$
    只能输入浮点数:"^(-?"d+)("."d+)?$"  或者  ^-?([1-9]"d*"."d*|0"."d*[1-9]"d*|0?".0+|0)$
     
    匹配特定字符串:
    只能输入长度为3的字符:"^.{3}$"。
    只能输入由26个英文字母组成的字符串:"^[A-Za-z]+$"。
    只能输入由26个大写英文字母组成的字符串:"^[A-Z]+$"。
    只能输入由26个小写英文字母组成的字符串:"^[a-z]+$"。
    只能输入由数字和26个英文字母组成的字符串:"^[A-Za-z0-9]+$"。
    只能输入由数字、26个英文字母或者下划线组成的字符串:"^"w+$"。

    验证用户密码:"^[a-zA-Z]"w{5,17}$"正确格式为:以字母开头,长度在6~18之间,只能包含字符、数字和下划线。

    验证是否含有^%&',;=?$"等字符:"[^%&',;=?$"x22]+"。

    验证Email地址:"^"w+([-+.]"w+)*@"w+([-.]"w+)*"."w+([-.]"w+)*$"。

    验证InternetURL:"^http://(["w-]+".)+["w-]+(/["w-./?%&=]*)?$"。

    验证电话号码:"^("("d{3,4}-)|"d{3.4}-)?"d{7,8}$"正确格式为:"XXX-XXXXXXX"、"XXXX-XXXXXXXX"、"XXX-XXXXXXX"、"XXX-XXXXXXXX"、"XXXXXXX"和"XXXXXXXX"。

    验证身份证号(15位或18位数字):"^"d{15}|"d{18}$"。

    验证一年的12个月:"^(0?[1-9]|1[0-2])$"正确格式为:"01"~"09"和"1"~"12"。

    验证一个月的31天:"^((0?[1-9])|((1|2)[0-9])|30|31)$"正确格式为;"01"~"09"和"1"~"31"。
     
    在asp.net中使用RegularExpressionValidator控件,可以将正则表达式和asp.net控件结合起来。
    例子:如何检查当TextBox设置为多行时是不是超长了?
    <asp:RegularExpressionValidator id="revTextBox1" runat="server" ForeColor="Red" Display="Dynamic" ControlToValidate="textBox1" ValidationExpression="("w|"W){1,100}">格式错误-只能输入不超过100个字符</asp:RegularExpressionValidator>
    3/27/2009

    [转]sql安装出错,安装程序配置服务器失败(解决了!)

    sql server 2000安装出错,无法找到动态链接库sqlunirl.dll
    安装文件肯定没有错,因为以前安装过,绝对可以用

    机子之前有装了sql server 2000,而且可以正常使用,只是今天突然无法连接到本地数据库,打算重装,我删了program files里的ms sql的目录,然后重装sql,结果在最后一步的时候提示,无法完成配置。后来又删除了一些注册表中的sql server信息(有备份注表),再安装时,就出现这样的提示了,更糟的是,备份的注册表却无法还原

    ============================
    现在问题解决了,总结了一些经验


    当安装时出现MDAC组件安装失败时,试着修复或重装microsoft office

    当你想重装sql server,而安装时又出现“您的机子上已经安装有一个实例”的提示时,可以删除program files\Microsoft SQL Server文件夹,再安装

    当出现某某动态链接文件找不到时,可以试着在sql server的安装文件中找到这个文件,复制到系统目录下的system和system32文件夹中(一般在出现这个错误消息时,都会提示哪几个文件夹下缺少这个文件)

    当出现安装程序配置服务器失败时,可以试着用一下方法解决
    此错误消息可以在系统目录下找到,例如我的系统是win2000,则该文件在C:\WINNT\sqlstp.log

    失败一:
    正在与服务?

    driver={sql server};server=ZHL;UID=sa;PWD=;database=master

    [Microsoft][ODBC 驱动程序 管理器] 驱动程序的 SQLAllocHandle on SQL_H

    driver={sql server};server=ZHL;UID=sa;PWD=;database=master

    [Microsoft][ODBC 驱动程序 管理器] 驱动程序的 SQLAllocHandle on SQL_H

    driver={sql server};server=ZHL;UID=sa;PWD=;database=master

    [Microsoft][ODBC 驱动程序 管理器] 驱动程序的 SQLAllocHandle on SQL_H

    SQL Server 配置?

    ###############################################################################

    13:40:06 Process Exit Code: (-1)
    13:40:09 安装程序配置服务器失败。参考服务器错误日志和 C:\WINNT\sqlstp.log 了解更多信息。
    13:40:09 Action CleanUpInstall:
    当出现这个错误时,试一下重装系统文件
    我的机子是win2000,在dos下重新运行win2000的安装,然后选择修复,而不是全新安装
    修复系统文件之后,再装sql server,则不会出现此错误消息



    失败二:
    正在与服务?

    driver={sql server};server=ZHL;UID=sa;PWD=;database=master

    [Microsoft][ODBC 驱动程序 管理器] 未发现数据源

    driver={sql server};server=ZHL;UID=sa;PWD=;database=master

    [Microsoft][ODBC 驱动程序 管理器] 未发现数据源

    driver={sql server};server=ZHL;UID=sa;PWD=;database=master

    [Microsoft][ODBC 驱动程序 管理器] 未发现数据源

    SQL Server 配置?

    ###############################################################################

    13:50:07 Process Exit Code: (-1)
    13:50:10 安装程序配置服务器失败。参考服务器错误日志和 C:\WINNT\sqlstp.log 了解更多信息。
    13:50:10 Action CleanUpInstall:
    当出现这个错误时,是因为在注册表删除了HKEY_LOCAL_MACHINE\SOFTWARE\ODBC中有关sql sever的

    内容
    这时可以选择修复注册表,或安装ODBC修复工具
    ODBC修复工具: http://211.101.4.50/download/canyin/tools/MDAC_TYP.EXE



    失败三:
    在与服务?

    driver={sql server};server=ZHL;UID=sa;PWD=;database=master

    [Microsoft][ODBC SQL Server Driver][Named Pipes]连接?

    [Microsoft][ODBC SQL Server Driver][Named Pipes]ConnectionRead (ReadFile()).

    driver={sql server};server=ZHL;UID=sa;PWD=;database=master

    [Microsoft][ODBC SQL Server Driver][Named Pipes]连接?

    [Microsoft][ODBC SQL Server Driver][Named Pipes]ConnectionRead (GetOverLappedResult()).

    driver={sql server};server=ZHL;UID=sa;PWD=;database=master

    [Microsoft][ODBC SQL Server Driver][Named Pipes]连接?

    [Microsoft][ODBC SQL Server Driver][Named Pipes]ConnectionRead (GetOverLappedResult()).

    SQL Server 配置?

    ###############################################################################

    17:17:41 Process Exit Code: (-1)
    17:17:45 安装程序配置服务器失败。参考服务器错误日志和
    当出现这个错误时,必须安装ODBC修复工具
    ODBC修复工具: http://211.101.4.50/download/canyin/tools/MDAC_TYP.EXE
    3/16/2009

    [转]SQL字符串函数

    SQL字符串函数

    字符串函数对二进制数据、字符串和表达式执行不同的运算。此类函数作用于CHAR、VARCHAR、 BINARY、 和VARBINARY 数据类型以及可以隐式转换为CHAR 或VARCHAR的数据类型。可以在SELECT 语句的SELECT 和WHERE 子句以及表达式中使用字符串函数。常用的字符串函数有:
    一、字符转换函数
    1、ASCII()
    返回字符表达式最左端字符的ASCII 码值。在ASCII()函数中,纯数字的字符串可不用‘’括起来,但含其它字符的字符串必须用‘’括起来使用,否则会出错。

     

    2、CHAR()
    将ASCII 码转换为字符。如果没有输入0 ~ 255 之间的ASCII 码值,CHAR() 返回NULL 。

     

    3、LOWER()和UPPER()
    LOWER()将字符串全部转为小写;UPPER()将字符串全部转为大写。

     

    4、STR()
    把数值型数据转换为字符型数据。
    STR ([,length[, ]])
    length 指定返回的字符串的长度,decimal 指定返回的小数位数。如果没有指定长度,缺省的length 值为10, decimal 缺省值为0。
    当length 或者decimal 为负值时,返回NULL;
    当length 小于小数点左边(包括符号位)的位数时,返回length 个*;
    先服从length ,再取decimal ;
    当返回的字符串位数小于length ,左边补足空格。

     

    二、去空格函数
    1、LTRIM() 把字符串头部的空格去掉。
    2、RTRIM() 把字符串尾部的空格去掉。
    三、取子串函数
    1、left()
    LEFT (, )
    返回character_expression 左起 integer_expression 个字符。
    2、RIGHT()
    RIGHT (, )
    返回character_expression 右起 integer_expression 个字符。
    3、SUBSTRING()
    SUBSTRING (, , length)
    返回从字符串左边第starting_ position 个字符起length个字符的部分。
    四、字符串比较函数
    1、CHARINDEX()
    返回字符串中某个指定的子串出现的开始位置。
    CHARINDEX (<’substring_expression’>, )
    其中substring _expression 是所要查找的字符表达式,expression 可为字符串也可为列名表达式。如果没有发现子串,则返回0 值。
    此函数不能用于TEXT 和IMAGE 数据类型。

     

    2、PATINDEX()
    返回字符串中某个指定的子串出现的开始位置。
    PATINDEX (<’%substring _expression%’>, )其中子串表达式前后必须有百分号“%”否则返回值为0。
    与CHARINDEX 函数不同的是,PATINDEX函数的子串中可以使用通配符,且此函数可用于CHAR、 VARCHAR 和TEXT 数据类型。
    五、字符串操作函数
    1、QUOTENAME()
    返回被特定字符括起来的字符串。
    QUOTENAME (<’character_expression’>[, quote_ character]) 其中quote_ character 标明括字符串所用的字符,缺省值为“[]”。

     

    2、REPLICATE()
    返回一个重复character_expression 指定次数的字符串。
    REPLICATE (character_expression integer_expression) 如果integer_expression 值为负值,则返回NULL 。
    3、REVERSE()
    将指定的字符串的字符排列顺序颠倒。
    REVERSE () 其中character_expression 可以是字符串、常数或一个列的值。
    4、REPLACE()
    返回被替换了指定子串的字符串。
    REPLACE (, , ) 用string_expression3 替换在string_expression1 中的子串string_expression2。
    4、SPACE()
    返回一个有指定长度的空白字符串。
    SPACE () 如果integer_expression 值为负值,则返回NULL 。
    5、STUFF()
    用另一子串替换字符串指定位置、长度的子串。
    STUFF (, , ,)
    如果起始位置为负或长度值为负,或者起始位置大于character_expression1 的长度,则返回NULL 值。
    如果length 长度大于character_expression1 中 start_ position 以右的长度,则character_expression1 只保留首字符。

     

    六、数据类型转换函数
    1、CAST()
    CAST ( AS [ length ])
    2、CONVERT()
    CONVERT ([ length ], [, style])
    1)data_type为SQL Server系统定义的数据类型,用户自定义的数据类型不能在此使用。
    2)length用于指定数据的长度,缺省值为30。
    3)把CHAR或VARCHAR类型转换为诸如INT或SAMLLINT这样的INTEGER类型、结果必须是带正号或负号的数值。
    4)TEXT类型到CHAR或VARCHAR类型转换最多为8000个字符,即CHAR或VARCHAR数据类型是最大长度。
    5)IMAGE类型存储的数据转换到BINARY或VARBINARY类型,最多为8000个字符。
    6)把整数值转换为MONEY或SMALLMONEY类型,按定义的国家的货币单位来处理,如人民币、美元、英镑等。
    7)BIT类型的转换把非零值转换为1,并仍以BIT类型存储。
    8)试图转换到不同长度的数据类型,会截短转换值并在转换值后显示“+”,以标识发生了这种截断。
    9)用CONVERT() 函数的style 选项能以不同的格式显示日期和时间。style 是将DATATIME 和SMALLDATETIME 数据转换为字符串时所选用的由SQL Server 系统提供的转换样式编号,不同的样式编号有不同的输出格式。

     

     

    七、日期函数
    1、day(date_expression)
    返回date_expression中的日期值
    2、month(date_expression)
    返回date_expression中的月份值
    3、year(date_expression)
    返回date_expression中的年份值
    4、DATEADD()
    DATEADD (, , )
    返回指定日期date 加上指定的额外日期间隔number 产生的新日期。参数“datepart” 取值如下:

     

    5、DATEDIFF()
    DATEDIFF (, , )
    返回两个指定日期在datepart 方面的不同之处,即date2 超过date1的差距值,其结果值是一个带有正负号的整数值。
    6、DATENAME()
    DATENAME (, )
    以字符串的形式返回日期的指定部分此部分。由datepart 来指定。
    7、DATEPART()
    DATEPART (, )
    以整数值的形式返回日期的指定部分。此部分由datepart 来指定。
    DATEPART (dd, date) 等同于DAY (date)
    DATEPART (mm, date) 等同于MONTH (date)
    DATEPART (yy, date) 等同于YEAR (date)
    8、GETDATE()
    以DATETIME 的缺省格式返回系统当前的日期和时间

    3/15/2009

    [转]关于"以前的某个程序安装已在安装计算机上创建挂起的文件操作"的解决办法

    以前装过sql server,后来删掉。现在重装,却出现“以前的某个程序安装已在安装计算机上创建挂起的文件操作。运行安装程序之前必须重新启动计算机”错误。无法进行下去。

    参考网上资料,总算搞定。步骤是:

    1)添加/删除程序中彻底删除sql server。

    2)将没有删除的sql server目录也删除掉。

    3)打开注册表编辑器,在HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager中找到PendingFileRenameOperations项目,并删除它。这样就可以清除安装暂挂项目。

    4)删除注册表中跟sql server相关的键。

    其实估计只要做第3步就可以搞定,这样就可以清除安装暂挂项目。自己是先走了1,2,4,最后做了3才搞定。所以估计3才是最关键的。

    3/13/2009

    [转]怎样在理想价位卖出股票

    买对股票只完成投资过程的一半或更少,接下来就是跟踪股票,并在股价大幅上涨之后卖掉股票,所以如何卖股票同样至关重要。俗话说:会买是银,会卖是金。如果买了好的股票,未能选择好的卖出时机,将会给股票投资带来诸多遗憾。

      "赌徒谬误"和"处置效应"卖股票是最难的事,从某种程度上讲,何时卖股票甚至比何时买股票、买何种股票更难,而且更重要。买者一旦买了一种股票,他就要决定是持有还是卖出。实战的结果很酷,投资者正确卖出股票的概率很低。究其根源,这种结果起因于心理学上的"赌徒谬误"和"处置效应"。

      如果你在一轮掷骰子中已掷出五次两点,你下次再掷出两点的机会就要小于1/6了。这种说法对不对呢?如果你对这个问题回答说"对",你就陷入了所谓"赌徒谬误"之中。在掷骰子时,每次掷出的点数和以前掷出的点数是完全无关的。

      "赌徒谬误"是说当一个赌徒看到连续抛出的10次正面硬币之后,他将倾向于相信下一次将抛出反面硬币。

      "赌徒谬误"

      发生的根本原因在于参与者的启发式思维:人们倾向于认为如果一件事总是连续出现一种结果,则很可能会出现不同的结果来将其"平均"一下。

      在股票市场上,"赌徒谬误"主要表现为投资者在股价上涨时,急于抛出股票,实现资本增值,股价下跌时,则不会及时止损,而是继续持有,避免实现资本亏损,并且期待着股价会反弹,而且连跌股票的持有时间要显著高于连涨股票,即"跌得越多,投资者越是持有"。

      "处置效应"

      即投资者对盈利和亏损的股票的不同处置行为。投资者往往将盈利的股票尽快兑现,将亏损的股票拖拉不卖。结果会形成这样的局面:公司业绩优良本来可以上升幅度更大的股票因为众多投资者的抛售,而压抑了其升幅,而一些业绩差行情无法回到历史高位的股票却因为散户投资者的集体拖拉不卖,而延长了缓慢下跌的过程。

      卖股方法那么怎样尽量减少投资中的"处置效应"与"赌徒谬误",在最理想的位置卖出股票呢?以下是几种在实战中被证明较为有效的方法:

      本利分离操作法所谓"本利分离",是指把最初投入股票的本金和后来赢取的利润区别对待。具体来说,就是把本金用作短线投资,去追逐那些强势股,而利润则用作长线投资,投放到绩优股上。这样做的好处是,本金可以及时出手获利,风险小;利润用作长线投资,心理负担轻,可以静待股价向有利位置发展。

      定点了结法股价波动常常出现各种让投资者大跌眼镜的情况,对此,一种使人少伤脑筋的卖法就是"定点了结",即股价升到某一点时便抛出所持股票。当然,这个点不是盲目确定而是根据自己所掌握的情况,进行盈利对比和发展势头等分析工作后确定的。比如,有位投资者在2007年4月20日在18元价位买入深万科,定点获利幅度为5~6元,一旦股价涨到了23~24元,那么不论有再多的利多消息,也就即行了结。那么他就应该在5月14日坚决卖出,由此成功地回避一次暴跌行情。

      止损了结法这种操作方法是将所持股票在股价回落到一定点时了结,以停止损失。比如投资者确定,不管股价将来如何上涨,只要在现在的价位基础上回跌2元就马上抛出。这种方法对中小股是很实用的,让出了小利,却解决了无法把握股市涨跌的问题。

      分批了结法简单地说,就是不一次卖掉手中所有股票,而是分批逐渐卖出。这种方法可以看作在投资者自己判断力较弱时,对定点了结法的补充。"分批了结法"主要分为"定量分批了结法"和"倒金字塔出货法"。如果持有某种股票1.2万股,成本是每股12元,预定初卖点是18元,一批卖3000股,以后每涨2元卖一批,这样就是20元卖3000股,22元卖3000股,直卖到24元。这是"定量分批了结法"。"倒金字塔出货法"则是每批出手的股票数量由小而大、呈倒金字塔形。显然,采用"倒金字塔出货法",获利可能较前者更大,但所承担的风险也相应更大。

      因时制宜法不同时期卖股票有不同的卖出方法。在跌市初期,如果个股股价下跌得不深、套牢尚不深的时候,应该立即斩仓卖出。这种时候考验投资者能否当机立断,是否具有果断的心理素质。只有及时果断地卖出,才能防止损失进一步扩大。在股价经历深幅快速下跌后,再恐慌地跌止损,所起的作用就有限了,这时股市极易出现反弹行情,可以把握好股价运行的节奏,趁大盘反弹时卖出。在大势持续疲软的市场上,见异常走势时坚决卖出。如果所持有的个股出现异常走势,意味着该股未来可能有较大的跌幅。例如在尾盘异常拉高的个股,要果断卖出。越是采用尾盘拉高的动作,越是说明主力资金已经到了无力护盘的地步。当股市下跌到某一阶段性底部时,可以采用补仓卖出法,因为这时股价离自己的买价相去甚远,如果强行卖出,损失往往会较大。可适当补仓以降低成本,等待行情回暖时再逢高卖出。这种卖出法适合于跌市已近尾声时。

      从心理角度说,卖股票永远是一件让人痛苦的事情。当股价已经大幅上升的时候,觉得还能赚得更多,如果卖了就没有获取更高利润的机会了。而当股票下跌甚至亏损比较严重的时候,卖出更是让人难受,卖出后就不再是数字的变化,而是实实在在的亏损。但是现在舍不得卖出,哪里还有资本再搏别的投资机会呢?现在的卖出正是为了去寻求更好的盈利,避免更大的亏损。当卖出时机来临的时候,就要坚决卖出。不求卖得多么高明,多么有艺术,只求卖得正确,卖得及时!
    3/12/2009

    [转]日立硬盘SATA1和SATA2跳线设置方法

    日立硬盘这点比较麻烦,没有跳线,0得用日立的FT软件改成SATA1模式就可以用了。
    上网下Feature Tool,找个能认出SATA2的机器,在那机器上用Feature Tool把硬盘模式改成SATA1就可以在你的主板上用了

    网络天使 2008-6-20 14:53

      我们知道,大多数品牌的SATA2硬盘上都设计了一个跳线,只要设置正确就可以启用SATA2或者SATA1工作模式。不过,日立硬盘必须使用相关的软件,才能开启SATA2模式与SATA1模式。具体解决过程如下:
      第一步:登录日立硬盘官方网站([url=http://www.hitachigst.com/hdd/support/download.htm]http://www.hitachigst.com/hdd/support/download.htm[/url]),下载一个名为Feature Tools的工具软件(最新版本为2.09)。
      注:升级过程必须在DOS下完成,因此必须准备一台刻录机和一张空白CD-R盘片,或者使用软盘和软驱。如果没有这些设备,则可以用vFloppy这款虚拟软盘程序来代替。
      第二步:启动Feature Tools后,在菜单“Selected Driver”中选择日立硬盘,然后按下“Alt+F”键,打开菜单栏上的“Features”菜单,选择“Change SATA Settings”,在弹出的对话框中将“Max Transfer Speed”(最大传输速度)设置为“Up to 3.0Gb/s”即可,想设置成SATA1模式就选择“Up to 1.5Gb/s”即可.
      第三步:完成设置后,软件会提示重新启动系统。但这时用“Ctrl+Alt+Del”组合键启动是无效的,应该按Power键关闭主机电源,再重新启动,这样才能使设置生效。
      经过上述操作后,日立硬盘才真正工作在自己所设置的模式下了。这里要注意的是,如果主板不支持SATA2模式,那么开启日立硬盘的SATA2模式与SATA1模式将不成功,很可能导致主板无法识别硬盘,切记!

    9/19/2008

    [转载]我所知道的奶业内幕!(不知真的假的)

    我不想再忍了,我所知道的奶业内幕!
    我所学的专业是乳品工艺,刚毕业曾在某国内老大级乳业集团工作。职位——收奶员。
      这几天的三鹿事件,沸沸扬扬。其实在我看来,没什么奇怪的,事情总是要被揭穿的,只不过是时间问题,以及是哪一家企业成为那个撞上枪口的倒霉蛋。三聚氰胺————冰山的一角。也许这个事件就要告下一个段落,也许仅仅是个序幕的开始……
    离职的员工到处去说原来公司的“坏话”,这个员工一定个没有道德的人。曾经我也是这么认为的,可最近我的想法变了,一个知道内情而不去告诉别人,眼看着别人吃亏上当的人,那才是个彻底道德败坏的人。
    离职后,我没喝过一滴奶!
    我先讲一下,收奶的过程。奶农的牛奶由当地附近村镇的奶站化验收集,按品质高低,分等级付给奶农钱。品质的指标不外乎PH值,蛋白质,干物质这几项。然后由奶站(当然了奶站是私人老板的)用罐装车混装后运到工厂,然后由工厂取样化验,测算指标同样按品质高低,分等级付给奶站钱。不知道大家看没看出来,想没想到这种操作模式会出现什么问题?有人说了,不是“天然牧场”“工业化收集吗”?有,的确有。但是我只能说:兄弟,你很傻,很天真!
    奶农想多赚钱怎么办呢?简单啊,掺水啊。那掺水指标降低就卖不上好价了怎么办?简单啊掺****啊。奶站想多赚钱怎么办呢?简单啊……。奶站的奶是从各个散户收来混装到罐车的,有一家的突然变质了,怎么办啊,全车都倒了吗?几十吨一罐的奶,蛋白质低了怎么办?干物质低了怎么办?PH值低了怎么办?有的牛病了打过抗生素怎么办?有的牛催奶打激素怎么办?
    话说回来了,奶农那点小计量能瞒奶站吗?奶站那点小九九能瞒工厂吗?如果我说,奶站不知情,工厂不知情。都是“不法奶农”干的坏事,全国人民要把矛头指向他们批判。那我可就真的,很傻,很天真。
      我们从来不拒收奶,因为我们知道,一件东西是要充分利用的,这样才能取得最大的价值,获得最大的利润。我们分罐储藏。最好的奶,供到车间做酸奶(发酵型酸奶或搅拌型酸奶),因为不是好奶做不出来。其次,做纯牛奶,高钙奶之类的。再差的奶做花色奶即花生奶,早餐奶等。还有那些发酸的奶怎么办呢,当然不能倒了,做酸性乳饮料,就是广告狂哄乱炸的,女人小孩都喝的***。这是本公司最大的利润所在,一盒奶的成本,还没有哪个包装盒值钱。还有那种臭的熏人的奶怎么办呢,简单,做冰激凌味道最好。还有那些又臭成粘稠状的怎么办呢,做奶粉。当然这叫工业粉,它有它的用途,不是装袋子就上市场的。
    我们有全球最大最先进的立体式仓库,媒体都赞扬过,可是你就没想想这快速消费品,生产出来就要卖的,搞那么大仓库什么用?酸性乳饮料越存放味道越好。那有人问了,生产日期怎么办?简单啊,提前打一个月,你也许不信吧,因为在你心中那是小黑工厂做的事。那又有人问了,市场上卖的岂不是过期奶? 我就这么告诉你吧,你手中那盒奶就是过期一周了,你喝也没问题。因为你所卖的奶是UHT超高温灭菌液态奶。
    关于UHT超高温灭乳到底有没有营养,我不想再说了,因为这个涉及到某人在某年为中国提出的一个口号,我们正向这个口号迈进,别管你喝的是什么奶,反正是牛奶。
    有个广告,中国某企业已经是这种超高温灭菌乳全球产销量第一,难道是那些乳业发达国家真的比不上我们了吗?其实是人家不生产这种乳品了。这笑话有点冷是吧。
    那有人说了,我们以后喝高端奶吧,广告都说想过有品位的生活就和那种奶。是啊,那奶是贵啊,贵的东西就好啊,那奶蛋白质高啊,高,实在是高,这一点澳大利亚人都服我们啊。
    我就不相信地球上的奶牛能挤出那么高蛋白质的奶……
    此言一出,某些专家就会来“辟谣”又得列出一套数据理论,来“引导”大家。
    是啊,我嘴没人家的大,钱更没人家拿的多……
    还有很多关键的还是不说为好,知道了对大家谁都不好。生活是美好的。
     
    真实案例看三鹿奶粉背后的恐怖的行业潜规则 
    目前闹得沸沸扬扬的三鹿奶粉事件,作为一个可能的知情者和懂点化学的人,我也来谈谈我的观点: 
    1、媒体也好,厂家也好,国*家质量监督也好,还是在忽悠大家,为什么我敢这么说,因为三聚氰氨根本不可能直接加入牛奶中,三聚氰氨的市场售价并不低,奶农不可能不计成本的提高浓度,其次,三聚氰氨水溶性较差,要想完全溶于牛奶比较麻烦;那为什么媒体,厂家,国*家质量监督要异口同声的说是不法之徒加入了三聚氰氨,其实就是为为了掩盖一个更可怕的问题,那就是加入的其他毒性更大的东西,说穿了就是尿素,尿素作为一种便宜的农家化肥,真是经济实惠的“好添加剂”。 
    2、为什么要加尿素,因为各乳品公司收购鲜奶,测试的标准主要是奶的蛋白质含量,说穿了就是氮的含量,尿素作为一种最普遍的氮肥,由于它独特的分子结构,记得好象是两个氮分子配个什么我忘了,氮的含量当然高了,混入奶中,提高氮浓度,价格自然也卖得高了; 
    3、尿素怎么转化为三聚氰氨的,很简单,奶粉的生产过程就是将鲜奶放在封闭的环境高温环境下,然后采取喷雾的方式直接转化成粉状就成了奶粉,而尿素在高温下会产生变化,生成三聚氰氨,OK,有毒的奶粉就这样生成了。 
    最后,我在谈谈我怎么知道这些内幕的,前几年,是01年还是02年,我记不太清楚了,在办理一件带黑社会性质的案件时,他们主要罪状之一就是把持我市某区的牛奶收购市场,长期以次冲好,我们在办案中就了解到,他们在牛奶中加入尿素、少量食用油,然后加大量水(良心好的加自来水,不好的就直接加池塘或者田里的水),最后用专用的搅拌机进行搅拌,一批蛋白质浓度高的鲜奶诞生了,但最后几个犯罪分子都翻供,说他们这种做法是普遍的,并不是他们发明的,后来我们专门去天友了解,确实如此,他们对牛奶收购中出现的这些问题根本没有比较有效的检测措施或者是因为收购站点太多,没有精力和金钱来负担这么大的检测开销,所以对广大奶农的行为基本采取的是默认的态度,而且据在天友的了解,这种现象在全国的乳制品行业是普遍的,只要存在向奶农收购牛奶,就普遍存在次类现象,所以三鹿事件的发生就是必然的,而且这次三鹿出了事,全国其他所有奶制品企业都保持沉默,没有一家跳出来指责,什么原因大家看了我的帖应该心里有数了吧,最后弱弱的问大家一句,这样的牛奶你们敢喝吗?
    9/12/2008

    社会保险的构成

    社会保险的构成
     养老保险
     失业保险
     工伤保险
     医疗保险
     生育保险
    一、养老保险
    1、基本养老保险
    基本养老保险是由国家通过立法强制实行,保证劳动者在年老丧失劳动能力时,给予基本生活保障的制度
    它适用于各类企业于职工,标准基本统一,费用实行国家、企业、个人三方面共同负担
    社会统筹于与个人账户相结合
    每个职工都有一个终身不变的养老保险账户,将个人缴费部分和用人单位缴纳退休统筹费的一部分,一并计入个人账户,不管职工到哪里工作,只要个人和单位缴了费,都计入个人账户,到退休时,按个人账户的累计储额计发放养老金
    个人账户包括:
    1、个人缴纳的全部基本养老保险费;
    2、企业缴纳基本养老保险费中按被保险人个人缴费工资基数的一定比例划入的部分;
    3、个人账户存储额的利息
    个人账户储存额的存储方式和使用范围?
    1、购买国家社会保险基金特种定向债券
    2、存入银行养老保险基金专户
    个人账户存储额只能用于养老,不得要求提前支取,用于购房、医疗或子女教育等。
    个人账户能否继承?
    职工在职死亡或离退休后死亡,其个人账户可以继承
     在职死亡:继承额为个人账户储存额中的个人缴费部分本息
     离退休后死亡:
    继承额=个人账户余额×个人缴费本息占个人账户全部储存额的比例
    什么是缴费工资
     缴费工资是指单位及个人按规定比例计算的缴纳养老保险费的基数,是个人计算养老水平的重要依据。
    基本养老保险费缴纳标准
    1、个人:以本人上一年月平均工资为缴费工资基数,缴费比例为8%;
    2、单位按全部被保险人缴费工资基数之和的19%缴纳基本养老保险费(自2003年起调整为20%)
    个人账户中企业划入比例如何确定?
    1998年7月《规定》要求:为被保险人按其缴费工资基数的11%建立基本养老保险个人账户
    企业缴费划入比例为3%
    哪些人可以按月领取基本养老金?
     在达到国家规定的退休年龄时,累计缴纳基本养老保险费满15年以上;
     1988年7月日《规定》实施前参加工作、实施后退休的人员,累计缴纳基本养老保险费满10年以上。
    基本养老保险待遇
     基本养老由基础养老金和个人账户养老金组成
    1、基础养老金月标准:上一年本市职工月平均工资的20%;
    2、个人账户养老金标准:本人账户储存额的1/120;
     个人缴费年限不满15年的,退休后不享受按月领取基本养老金待遇,其个人账户储存额一次支付给本人。
    二、失业保险
    什么是失业保险?
     失业保险是由国家通过立法强制实行,由社会集中建立基金,对因失业而暂时中断生活来源的劳动者提供物质帮助的制度。
    1、强制原则
    2、统一原则
    3、三方负担原则
    失业保险费缴纳标准?
     单位:按本单位上年职工月月平均工资总额的1.5%缴纳失业保险费;
     个人:个人按本人上年月平均工资的0.5%缴纳失业保险费。
    享受失业保险金的条件?
    1、已参加失业保险,并按规定缴费;
    2、非本人意愿中断就业;
    3、已办理失业登记,并有求职要求。
    失业人员的待遇?
    1、医疗补助金;
    2、一次性医疗补助金;
    3、计划生育补助金;
    4、丧葬补助金;
    5、抚恤金
    失业保险的发放期限?
     1-2年,领3个月;
     2-3年,领6个月;
     3-4年,领9个月;
     4-5年,领12个月;
     5年以上,每满1年增发1个月,最长不超过24个月。
    失业标准金的领取标准?
    1、缴费<5年,按最低工资的70%;
    2、5-10年,按最低工资的75%;
    3、……
    从第13个月起,按最低工资的70%
    三、工伤保险
    什么是工伤保险?
    工伤保险是由国家通过立法,对在保险范围之内的劳动者因工作意外事故和职业病遭受意外伤害,丧失劳动能力的,提供医疗救治,职业康复、经济补偿和基本生活保障;对因工伤死亡的,对其遗属提供抚恤等物质帮助的社会保险制度。
    享受工伤保险金的条件?
     因工伤身体呈疾病状态者
     因工伤丧失劳动能力并因此中断工资收入者
     永久或暂时丧失劳动能力而完全丧失或部分丧失工资收入者
     遗属由于供养者死亡而失去生活费来源者
    工伤保险的待遇?
    1、工伤医疗待遇
    2、工伤津贴待遇
    3、伤残待遇
    4、职业康复待遇
    5、因工死亡待遇
    无责任补偿
    劳动者在生产工作中发生工伤事故时,无论事故责任是否属于劳动者本人,受职业伤害者都应无条件得到必要的经济补偿
    工伤保险费全由企业负担,个人不缴费
    四、医疗保险
    1、基本医疗保险
    1、基本医疗保险是政府举办,用人单位和职工共同参加,按照财政,用人单位和职工个人的承受能力来确定参保人员医疗待遇水平。
    2、基本医疗保险实行个人账户与统筹基金相结合,保障广大参保人的基本医疗要求
    什么是大额医疗互助制度?
    为了解决住院大病和门诊慢性病职工个人负担过重问题,由政府举办的一种补充医疗保险,参加医疗保险的企业和不享受公务员以来补助的事业单位必须参加,是基本医疗保险的必要补充部分
    基本医疗保险缴费标准
    基本医疗保险费 大额医疗费用
    参保职工 2% 5元
    退休人员 / 3元
    用人单位 9% 1%
    职工以本人上一年月平均工资、企业以全部职工缴费工资和为基数
    基本医疗保险缴费标准说明
     职工本人上一年月平均工资低于本市月平均工资的60%的,以上年本市职工月平均工资的60%作为缴费工资基数
     月平均工资膏腴本市平均工资的300%以上标准部分不作为缴费基数
    个人账户
     个人账户是经办机构通过银行为参保人设立的一个特殊账户,用于纪录、储存个人缴纳的医疗保险费和单位缴费中划入的保费的使用情况。
     个人账户的资金属于个人所有,只能用于支付医疗费用,个人不能向账户存钱
    个人账户资金的来源
    1、个人缴费全部计入个人账户
    2、单位缴费按比例划入个人账户
     不满35周岁的按本人与缴费工资的0.8%划入;
     35-44周岁按1%划入;
     45周岁以上按2%划入;
     不满70周岁的退休人员按上年市平均工资的4.3%划入
     70周岁以上按4.8%划入
    个人账户支付范围
    1、门诊、急诊费用;
    2、定点药店够要费用;
    3、统筹基金起付钱以下的费用;
    4、起付线上按比例由个人负担的费用
    统筹基金不支付的医疗费用
    1、非定点医疗机构就诊的(急诊除外)
    2、非定点药店购药的(急诊除外)
    3、因交通事故、医疗事故或其它责任事故造成伤害的
    4、本人吸毒、打架斗殴或因其它违法行为造成伤害的
    5、因自杀、自残、酗酒等原因进行治疗的
    6、在国外或香港、澳门特区及台湾地区治疗的
    7、按照国家和本市规定应当由个人自付的
    基本医疗保险:起付标准(单位元)
    医院等级 起付标准
    在职职工 退休职工
    一级医院 500(759) 350(531)
    二级医院 1000(1138) 700(797)
    三级医院 2000(1897) 1400(1328)
    注:起付标准为2005年7月1日后的标准,括号是7月1日前的标准
    基本医疗保险:支付比例
    医院等级 在职职工 退休职工
    统筹基金支付 个人支付 统筹基金支付 个人支付
    一级医院 90% 10% 93% 7%
    二级医院 85% 15% 89.5% 10.5%
    三级医院 80% 20% 86% 14%
    基本医疗保险:封顶线
    封顶线(统筹基金最高支付限额):
    按年度累计机为上半年度本市职工平均工资的4倍计算
    例:上年度平均工资为:31020元
    封顶线为124080
    基本医疗保险:重疾补助
    重大疾病医疗补助支付费用 重大疾病医疗补助支付比例 个人支付比例
    0至10万元 90% 10%
    10万元以上15万元以下 95% 5%
    五、生育保险
    社会生育保险是国家针对女性生育行为、生育特点,通过国家强制手段征集生育基金,为怀孕和分娩的职业妇女及时提供经济帮助,保障参保母子的基本生活和健康,确保社会人口再生产和妇女、儿童权益的一项社会保障制度。
    哪些人适用生育保险?
     (一)国家机关、事业单位、国有企业、市属集体企业、社会团体、民办非企业单位、市属外商投资企业及其按规定参加我市养老保险的职工,中央、省和其他驻莞企业、机构及其参加综合基本医疗保险的职工,须同时参加生育保险。
     (二)镇区属集体企业、镇区外商投资企业私营企业及其职工,城镇个体经济组织及其从业人员,按我市养老保险的实施范围,在参加养老保险和住院基本医疗保险的同时,须以镇区为单位参加生育保险。
    缴交办法
     职工生育保险根据“以支定收、略有节余”的原则筹集基金。
     上述第二条第 (一)项中单位职工的生育保险费由单位按全部在职职工上年度月平均工资总额的0.5%逐月缴纳;
     第(二)项中单位职工的生育保险费由单位按本市(镇)上年度职工月平均工资的0.5%乘以在职职工人数逐月缴纳。职工个人不缴纳生育保险费。
    生育保险待遇
     参加生育保险的职工,在投保两个月后,符合省、市计划生育规定的生育或计划内怀孕流产的,根据其参加综合基本医疗保险或住院基本医疗保险,分别按以下标准,一次性享受定额的生育津贴和生育医疗费待遇:
     参保产妇生育出院后,若在产褥期(产后六周内)患生育引起的疾病时,其住院基本医疗费分别按以下办法支付(其他疾病按医疗保险规定处理):
     参加综合基本医疗保险及生育保险的女职工可由生育保险基金报销90%,个人负担10%;参加住院基本医疗保险及生育保险的女职工,由生育保险基金支付80%,个人负担20%。
    参保夫妻自愿终生只生一个孩子,符合《广东省计划生育条例》有关规定,并在计划生育部门领取有效的独生子女证明后,可一次性享受280元
    6/16/2008

    人生

    想法总是很多,现实总很无奈;只要尽你全力,人生定会精彩。
    6/6/2008

    Asprotect V2.X 的脱壳与修复的总结及练习

    作 者: blackeyes
    关于Asprotect V2.X 的脱壳与修复, loveboom的《ASPROTECT 2.x 脱壳系列》已经非常的全面与经典.
    本人在此只是依葫芦画瓢, 并将有些地方再详细的解释一下, 给菜鸟们脱Asprotect V2.X时进行参考, 高手就不要看了.
    先在理论上研讨一下, 由于编译器的不一样, C 与 Delphi 所编译的汇编结果有差别, Asprotect 加壳时处理的也不一样.
    先假设有一程序:
    OEP: 00401000
    IAT: 00407000 - 00407FFF
    在00401100 CALL DLL1.API1
    在00401180 CALL DLL1.API2
    Ospr 加壳后, 好多的API CALL 被改成 CALL 12000000
    然后开始研究.
    1. C/C++ Program
    1.1) 未被加壳的程序
    00401000 55 PUSH EBP ; 程序 OEP
    00401001 8BEC MOV EBP, ESP
    ...
    00401100 FF15 00704000 CALL DWORD PTR DS:[00407000] ; DLL1.API1
    00401106 ...
    00401180 FF15 04704000 CALL DWORD PTR DS:[00407004] ; DLL1.API2
    00401186 ...
    ********* IAT 可能是这样的 ************
    00407000 DD 7C571000 // DLL1.API1
    00407004 DD 7C572000 // DLL1.API2
    ...
    004070FC DD 00000000
    00407100 DD 7D00XXXX // DLL2.API1
    ...
    004071FC DD 00000000
    ...
    00407F00 DD 7F00XXXX // DLLn.API1
    ...
    00407FFC DD 00000000

    1.2) 被 Asprotect 加壳后的程序在OEP
    00401000 55 PUSH EBP ; 程序 OEP
    00401001 8BEC MOV EBP, ESP
    ...
    00401100 E8 FBEEBF11 CALL 12000000 ; 壳
    00401105 ??
    00401106 ...
    00401180 E8 7BEEBF11 CALL 12000000 ; 壳
    00401185 ??
    00401186 ...
    *************IAT************************
    00407000 DD ???????? // 被加密的 DLL1.API1 信息
    00407004 DD 7C572000 // 未加密的 DLL1.API2
    ASPR 将许多的API CALL 都改成了统一的 CALL 12000000
    即改 CALL DWORD PTR DS:[xxxxx] 成 CALL 12000000
    作 者: blackeyes
    关于Asprotect V2.X 的脱壳与修复, loveboom的《ASPROTECT 2.x 脱壳系列》已经非常的全面与经典.
    本人在此只是依葫芦画瓢, 并将有些地方再详细的解释一下, 给菜鸟们脱Asprotect V2.X时进行参考, 高手就不要看了.
    先在理论上研讨一下, 由于编译器的不一样, C 与 Delphi 所编译的汇编结果有差别, Asprotect 加壳时处理的也不一样.
    先假设有一程序:
    OEP: 00401000
    IAT: 00407000 - 00407FFF
    在00401100 CALL DLL1.API1
    在00401180 CALL DLL1.API2
    Ospr 加壳后, 好多的API CALL 被改成 CALL 12000000
    然后开始研究.
    1. C/C++ Program
    1.1) 未被加壳的程序
    00401000 55 PUSH EBP ; 程序 OEP
    00401001 8BEC MOV EBP, ESP
    ...
    00401100 FF15 00704000 CALL DWORD PTR DS:[00407000] ; DLL1.API1
    00401106 ...
    00401180 FF15 04704000 CALL DWORD PTR DS:[00407004] ; DLL1.API2
    00401186 ...
    ********* IAT 可能是这样的 ************
    00407000 DD 7C571000 // DLL1.API1
    00407004 DD 7C572000 // DLL1.API2
    ...
    004070FC DD 00000000
    00407100 DD 7D00XXXX // DLL2.API1
    ...
    004071FC DD 00000000
    ...
    00407F00 DD 7F00XXXX // DLLn.API1
    ...
    00407FFC DD 00000000

    1.2) 被 Asprotect 加壳后的程序在OEP
    00401000 55 PUSH EBP ; 程序 OEP
    00401001 8BEC MOV EBP, ESP
    ...
    00401100 E8 FBEEBF11 CALL 12000000 ; 壳
    00401105 ??
    00401106 ...
    00401180 E8 7BEEBF11 CALL 12000000 ; 壳
    00401185 ??
    00401186 ...
    *************IAT************************
    00407000 DD ???????? // 被加密的 DLL1.API1 信息
    00407004 DD 7C572000 // 未加密的 DLL1.API2
    ASPR 将许多的API CALL 都改成了统一的 CALL 12000000
    即改 CALL DWORD PTR DS:[xxxxx] 成 CALL 12000000

    [转]手动脱壳ASProtect V2.X Registered

    【PYG官方论坛】http://bbs.chinapyg.com
    大家有空去看看

    ================


    我是个菜鸟,想跟大家学习点技术。

    第一次做动画,有什么错误的地方望高手指正。

    今天和大家讨论一下

    手动脱壳之ASProtect V2.X Registered -> Alexey Solodovnikov *

    //////////////////////////
    设置Ollydbg忽略除了“内存访问异常”之外的所有其他异常选项。
    用插件去掉Ollydbg的调试器标志。

    ////////////////////////////////////////
    OD载入后停在这里:
    00401000 >  68 01B05600     PUSH csetup.0056B001  ===》壳的入口,F9运行
    00401005    E8 01000000     CALL csetup.0040100B
    0040100A    C3              RETN
    0040100B    C3              RETN
    0040100C    0D 6F2F026F     OR EAX,6F022F6F
    00401011    5B              POP EBX

    ===============
    Shift+F9按N次,注意右下角堆栈
    00AFFAFF    C601 9E         MOV BYTE PTR DS:[ECX],9E
    00AFFB02    BB 71FE8A67     MOV EBX,678AFE71
    00AFFB07    64:8F06         POP DWORD PTR FS:[ESI]
    00AFFB0A    0000            ADD BYTE PTR DS:[EAX],AL
    00AFFB0C    83C4 04         ADD ESP,4
    00AFFB0F    8D0C07          LEA ECX,DWORD PTR DS:[EDI+EAX]
    00AFFB12    59              POP ECX

    =====================

    0012FF50   0012FF5C  指向下一个 SEH 记录的指针
    0012FF54   00AFFA50  SE处理程序
    0012FF58   00000002
    0012FF5C   0012FF80  指向下一个 SEH 记录的指针
    0012FF60   00AFFFE8  SE处理程序
    0012FF64   0012FF78
    0012FF68   00A80000
    0012FF6C   00AFF62C
    0012FF70   00000000
    0012FF74   00B3D84C  ASCII "FECE69A1-E37D"  ====》硬盘特征指纹
    0012FF78   0012FF98
    0012FF7C   00ADE2D0
    0012FF80   0012FFE0  指向下一个 SEH 记录的指针
    0012FF84   00AFF854  SE处理程序
    0012FF88   0012FF98

    Shift+F9经过=23次异常后,堆栈出现硬盘特征指纹
    =================
    Shift+F9按5次,堆栈硬盘特征指纹消失,再按1次Shift+F9
    00AFE8F9    C601 9E         MOV BYTE PTR DS:[ECX],9E
    00AFE8FC    BB 71FE8A67     MOV EBX,678AFE71
    00AFE901    64:8F06         POP DWORD PTR FS:[ESI]
    00AFE904    0000            ADD BYTE PTR DS:[EAX],AL
    00AFE906    83C4 04         ADD ESP,4
    00AFE909    8D0C07          LEA ECX,DWORD PTR DS:[EDI+EAX]
    00AFE90C    59              POP ECX
    00AFE90D    A1 4848B000     MOV EAX,DWORD PTR DS:[B04848]
    ==================
    向上找到这里:
    00AFE8E3    C3              RETN
    00AFE8E4    EB 01           JMP SHORT 00AFE8E7
    00AFE8E6    9A C1D19D36 EB0>CALL FAR 01EB:369DD1C1                   ; 远调用
    00AFE8ED    9A 83F1102B C96>CALL FAR 64C9:2B10F183                   ; 远调用
    00AFE8F4    FF31            PUSH DWORD PTR DS:[ECX]
    00AFE8F6    64:8921         MOV DWORD PTR FS:[ECX],ESP
    00AFE8F9    C601 9E         MOV BYTE PTR DS:[ECX],9E

    在00AFE8E3    C3              RETN按F2下断,Shift+F9断下,取消断点,F8单步

    7C9237BF    64:8B25 0000000>MOV ESP,DWORD PTR FS:[0]
    7C9237C6    64:8F05 0000000>POP DWORD PTR FS:[0]
    7C9237CD    8BE5            MOV ESP,EBP
    7C9237CF    5D              POP EBP
    7C9237D0    C2 1400         RETN 14

    Alt+M查看内存在00401000按F2下断,F9运行
    004B02B8    55              PUSH EBP
    004B02B9    8BEC            MOV EBP,ESP
    004B02BB    83C4 E4         ADD ESP,-1C
    004B02BE    53              PUSH EBX
    004B02BF    56              PUSH ESI
    004B02C0    33C0            XOR EAX,EAX
    004B02C2    8945 E4         MOV DWORD PTR SS:[EBP-1C],EAX

    004B02B8程序OEP脱壳之。是Borland Delphi 6.0 - 7.0
    ==================

    脱壳之后如何修复请高手指教。

    动画下载
    http://free.ys168.com/?a3chenming

    破解常用断点大全


    断点大全

    断点大全
    密码常用中断
    Hmemcpy (win9x专用)
    GetDlgItemTextA
    GetDlgItemInt
    vb:
    getvolumeinformationa  

    vbastrcomp (trw)
    Bpx __vbaStrComp (记得是两个 '_')
    MSVBVM60!_vbastrcomp|sofice
    MSVBVM50!           | 

    VBAI4STR 

    Ctrl+D
    bpx msvbvm60!__vbastrcomp do "d *(esp+0c)"(softice)
    按几次F5出册码出来了。
    bpx regqueryvalueexa do “d esp->8”(trw) 

    vbaVarTstEq 判断是否注册的函数
    (0042932F 66898580FEFFFF          mov word ptr [ebp+FFFFFE80], ax
    改为0042932F 66898580FEFFFF       mov word ptr [ebp+FFFFFE80], bx)

    时间常用中断
    GetSystemTime
    GetLocalTime
    GetTickCount
    vb:
    rtcGetPresentDate          //取得当前日期 

    杀窗常用中断
    Lockmytask (win9x专用)
    DestroyWindow
    mouse_event (鼠标中断)
    postquitmessage (Cracking足彩xp,很有用^_^)
    vb:
    _rtcMsgBox 

    ini文件内容常用中断
    GetPrivateProfileStringA
    GetPrivateProfileProfileInt 

    key文件:
    getprivateprofileint
    ReadFile
    CreateFileA 

    注册表常用中断
    RegQueryvalueA
    RegQueryvalueExA 

    狗加密中断
    BPIO -h 278 R
    BPIO -h 378 R  

    其它常用函数断点
    CreateFileA (读狗驱动程序),
    DeviceIOControl,
    FreeEnvironmentStringsA (对付HASP非常有效).
    Prestochangoselector (16-bit HASP's), '7242' 查找字符串 (对付圣天诺).具体含义参考下面的范例。 

    光盘破解中断
    16:
    getvolumeinformation
    getdrivetype
    int 2fh (dos)
    32:
    GetDriveTypeA  
    GetFullPathNameA
    GetWindowsDirectoryA 

    读磁盘中断
    GETLASTERROR 返回扩充出错代码  

    限制中断
    EnableMenuItem 允许、禁止或变灰指定的菜单条目
    EnableWindow 允许或禁止鼠标和键盘控制指定窗口和条目(禁止时菜单变灰)  

    不知道软盘中断是什么了?还有其它特殊中断,不知道其他朋友可否说一下了?
    如:Lockmytask and mouse_event,这些就不是api32函数?
    win9x 与 win2k进行破解,以上中断有部分已经不能用了?
    不知道在win2k上,以上常用中断函数是什么了?
    也就是问密码、时间、窗口、ini、key、注册表、加密狗、光盘、软盘、限制等!
    了解常用的中断,对破解分析可以做到事半功倍!
    请大家说一下!还有如何破解了某个软件时,一重启就打回原形?
    不知道下什么中断了?可以分为三种情况:
    1.比较可能在注册表中
    2.比较在特殊文件(*.key *.ini *.dat等)
    3.比较在程序中,没有任何错误提示或者反译也找不到明显字符(这个就是我想问的) 

    还有一个是最难的,就是去掉水印!
    也可以三种情况:
    A.水印是位图文件(bitblt,creatBITMAP等位图函数)
    B.水印是明显字符(反译分析)
    C.水印不是明显字符(如:This a demo!它只是显示在另一个制作文件上,可是*.htm *.exe等)
    C.才是最难搞,也是很多人想知道的!包括我在内。不知道高手们有何提示了? 

    广告条:
    可以分两种情况:
    A.从创建窗口进手,可以用到movewindow或者其它窗口函数!
    B.从位图进手,也可以用到bitblt或者其它位图函数!
    最后可以借助一些现有工具(如:api27,vwindset,freespy之类的工具) 

    葡萄虽无树,藤生棚中秧。
    人处凡尘中,岂不惹尘埃? 

    小球[CCG]
    那要看是在哪作的标记,通常是在注册表中留下信息!
    在softice中就要用bpx regqueryvalueexa do "d esp->8"来中断看看,
    在trw中要用bpx regqueryvalueexa do "d*(esp+8)"来中断看看。
    还有的是在本目录下留下注册信息,常见的有.dat .ini .dll等等,
    我是用bpx readfile来中断的,还有的是在windows目录下留下注册信息。
    你可以借助专用的工具帮助你查看,入filemon等!  

    vb: 

    1、__vbaVarTstNe              //比较两个变量是否不相等
    2、rtcR8ValFromBstr            //把字符串转换成浮点数
    3、rtcMsgBox  显示一信息对话框  
    4、rtcBeep                    //让扬声器叫唤
    5、rtcGetPresentDate          //取得当前日期  

    针对字串:
    __vbaStrComp
    __vbaStrCmp
    __vbaStrCompVar
    __vbaStrLike
    __vbaStrTextComp
    __vbaStrTextLike
    针对变量:
    __vbaVarCompEq
    __vbaVarCompLe
    __vbaVarCompLt
    __vbaVarCompGe
    __vbaVarCompGt
    __vbaVarCompNe  

    VB的指针:
    THROW  

    VB DLL还调用了oleauto32.dll中的部分函数。oleauto32.dll是个通用的proxy/stub DLL,其每个函数的原型在<oleauto.h>中定义,并在MSDN中有详细描述。这也有助于理解VB DLL中的函数的作用。  

    举例:  

    LEA EAX, [EBP-58]
    PUSH EAX
    CALL [MSVBVM60!__vbaI4Var]  

    执行call之前敲dd eax+8,得到的值为3;
    执行完call之后,eax = 3
    从而可知__vbaI4Var的作用是将一个VARIANT转换为I4(即一个长整数)。 

    __vbaVarTstNe似乎是用来进行自校验的,正常情况下返回值为0。
    已知适用的软件有:网络三国智能机器人、音乐贺卡厂。当这两个软件被脱壳后都回出错,网络三国智能机器人会产生非法*作,而音乐贺卡厂会告诉你是非法拷贝,通过修改__vbaVarTstNe的返回值都可让它们正常运行。
    所以当您遇到一个VB软件,脱壳后无法正常运行,而又找不出其它问题时,可试试拦截这个函数,说不定会有用哦。8-) 

    API不太知道,也许可以通过BIOS在98平台上读写扇区,不过在2000/NT下可以通过内黑ATAPI,HAL写扇区
    machoman[CCG]
    bpx WRITE_PORT_BUFFER_USHORT
    NT/2000下这个断点,当edx=1f0h,时,可以看见EDI地址内数据为扇区位置数据,必须先 在winice.dat 中装入hal.sys 详细内容看ATAPI手册  

    补充篇:
    关于对VB程序和时间限制程序的断点
    CrackerABC
    先给出修改能正确反编译VB程序的W32DASM的地址:
    ======================
    offsets 0x16B6C-0x16B6D  

    修改机器码为: 98 F4
    ======================  

    VB程序的跟踪断点:  

    ============
    MultiByteToWideChar,
    rtcR8ValFromBstr,
    WideCharToMultiByte,
    __vbaStrCmp
    __vbaStrComp
    __vbaStrCopy
    __vbaStrMove
    __vbaVarTstNe
    rtcBeep
    rtcGetPresentDate (时间API)
    rtcMsgBox
    =========  

    时间限制断点:  

    ================
    CompareFileTime
    GetLocalTime
    GetSystemTime
    GetTimeZoneInformation
    msvcrt.diffTime()
    msvcrt.Time()
    ================  

    一般处理

    bpx hmemcpy
    bpx MessageBox
    bpx MessageBoxExA
    bpx MessageBeep
    bpx SendMessage 

    bpx GetDlgItemText
    bpx GetDlgItemInt
    bpx GetWindowText
    bpx GetWindowWord
    bpx GetWindowInt
    bpx DialogBoxParamA
    bpx CreateWindow
    bpx CreateWindowEx
    bpx ShowWindow
    bpx UpdateWindow 

    bmsg xxxx wm_move
    bmsg xxxx wm_gettext
    bmsg xxxx wm_command
    bmsg xxxx wm_activate   

    时间相关
    bpint 21 if ah==2A (DOS)
    bpx GetLocalTime
    bpx GetFileTime
    bpx GetSystemtime   

    CD-ROM 或 磁盘相关
    bpint 13 if ah==2 (DOS)
    bpint 13 if ah==3 (DOS)
    bpint 13 if ah==4 (DOS)
    bpx GetFileAttributesA
    bpx GetFileSize
    bpx GetDriveType
    bpx GetLastError
    bpx ReadFile
    bpio -h (Your CD-ROM Port Address) R   

    软件狗相关
    bpio -h 278 R
    bpio -h 378 R   

    键盘输入相关
    bpint 16 if ah==0 (DOS)
    bpint 21 if ah==0xA (DOS)   

    文件访问相关
    bpint 21 if ah==3dh (DOS)
    bpint 31 if ah==3fh (DOS)
    bpint 21 if ah==3dh (DOS)
    bpx ReadFile
    bpx WriteFile
    bpx CreateFile
    bpx SetFilePointer
    bpx GetSystemDirectory  

    INI 初始化文件相关
    bpx GetPrivateProfileString
    bpx GetPrivateProfileInt
    bpx WritePrivateProfileString
    bpx WritePrivateProfileInt  

    注册表相关
    bpx RegCreateKey
    bpx RegDeleteKey
    bpx RegQueryvalue
    bpx RegCloseKey
    bpx RegOpenKey  

    注册标志相关
    bpx cs:eip if EAX==0  

    内存标准相关
    bpmb cs:eip rw if 0x30:0x45AA==0  

    显示相关
    bpx 0x30:0x45AA do "d 0x30:0x44BB"
    bpx CS:0x66CC do "? EAX"

    [转]ASProtect V2.X脱壳+处理附加数据+去自校验~ASProtect V2.X脱壳+处理附加数据+去自校验~

    ------------------------------------------------------------------
    ASProtect V2.X脱壳+处理附加数据+去自校验
    作者:Hmily
    博客:Http://Blog.52Hmily.Cn
    QQ群:39940458
    -------------------------------------------------------------------
    大家好,我是Hmily,今天给大家带来 Q宠保姆VC版 2.23 SP8版2007.09.13脱壳教程,需要的工具有:
    PEiD,OD,Volx大侠ASProtect脚本(http://www.unpack.cn/viewthread.php?tid=9487),ImportREC,Overlay 最终版,Resource Binder......(这些网上都能下到,就不提供了)
    这个是我上次脱Q宠保姆VC版 2.23 SP7版 2007.09.06的记录:http://hi.baidu.com/52hmily/blog ... 7a120b28388a04.html
    好,开始,先查下壳
    普通扫描:ASProtect V2.X Registered -> Alexey Solodovnikov          * Sign.By.fly [Overlay] *注意是有附加数据的
    用插件VerA 0.15扫描:Version: ASProtect 2.3 SKE build 06.26 Beta [Extract]

    第一步:脱壳
    先OD载入吧,运行脚本,就会自动脱壳了,脱完先修复,先查看OD运行记录,再打开ImportREC,然后对照着填OEP地址,点获取输入表,再点修复转存文件。

    第二步:处理附加数据
    好了,现在来处理附加数据,打开Overlay,点复制Overlay,这样就处理了附加数据

    第三步:去自校验
    现在还是运行不了,看来是有自校验,我们把脱好的程序再次载入OD,在命令出输入:bp CreateFileA,回车,按F9运行,到这就可以了,下面看清楚,点反汇编窗口中跟随,F2下端,F9运行到这里,取消断点,这里都是系统的领空,我们要到程序的领空去,按F8先跟到程序领空,好,这里已经到系统领空了,下面还是用F8跟,后面慢慢来,大家看好,
    004638D8      .    A3 04DB4D00      mov        dword ptr [4DDB04], eax
    004638DD      .    E8 61F5FFFF      call      00462E43
    004638E2      .    E8 272BFFFF      call      0045640E
    004638E7      .    85C0            test      eax, eax
    004638E9      .    0F85 15010000 jnz        00463A04    ————跳转没实现
    004638EF      .    52              push      edx
    004638F0      .    57              push      edi
    004638F1      .    C1D2 E7          rcl        edx, 0E7
    004638F4      .    83EA 03          sub        edx, 3
    004638F7      .    68 28214200      push      00422128
    004638FC      .    81D2 EC7E7BD3 adc        edx, D37B7EEC
    00463902      .    5A              pop        edx
    00463903      .    FF32            push      dword ptr [edx]
    00463905      .    335424 08        xor        edx, dword ptr [esp+8]
    00463909      .    335424 28        xor        edx, dword ptr [esp+28]
    如果这样下去你会发现程序就结束了,说明这里是关键的跳转,我们先看看,继续跟,出错了,好了,现在我们重新载入程序,直接跳到刚才那个地方004638E9,
    004638E9      . /0F85 15010000 jnz        00463A04
    没实现跳转,我们来让他实现,可以直接把JNZ改成JMP就可以了,保存
    好,我们现在再看看能不能运行,晕,刚才突然点错了,我们继续,OK,可以啦,查下壳 VC8 -> Microsoft Corporation [Overlay] *,我们再用Resource Binder给它优化下,重建资源,
    程序也会小点,好了,这样教程就结束了。

    欢迎大家和我交流技术!

    88


    教程地址:http://exs.mail.qq.com/cgi-bin/d ... 5281125d325ea32d7ce

    提取码:edac828d

    Q宠保姆VC版 2.23 SP8版2007.09.13UNPack:http://exs.mail.qq.com/cgi-bin/d ... 4d0ac7ddece7271e0dc

    提取码:ae5027bb
    5/31/2008

    折翼的天使[转]

                我是一个折翼的天使
                一次偶然的事故
                使我不再会飞翔

                天空中有无数个天使在飞翔
                望着其中最美丽的那个
                我心无比向往
                
                挥动双翅想飞到你的身旁
                却重重地跌落到地上
                以致我遍体鳞伤
                这才明白
                原来我已不会飞翔

                你来到我的身旁
                在我头顶一圈一圈飞翔
                来表达你对我的同情
                却不能了解我心中的忧伤  
      
                望着你远去的背影
                我心彷徨
                可心已随你一起飞翔

                若上帝醒来
                他不会让我再这样
                他会让我和你一起在天空中自由地翱翔

                
                上帝依旧在沉睡
                但时间不会太长
                也许是十天
                也许是整个世纪
                但真的不会太长
                到时我就可以和你一起飞翔
                我心真的希望
    4/18/2008

    [转]突破NP屏蔽,实现按键模拟

    突破NP屏蔽,实现按键模拟!

    nProtect GameGuard、XTRAP是两款比较著名的防作弊软件,在玩家使用外挂(无论任何游戏的外挂,就算不是当前游戏的外挂也不可以)的时候

    会提示"检测到游戏被破解修改"并强行关闭游戏。

    什么是nProtect?

    nProtect是设计用于保护个人电脑终端不被病毒和黑客程序感染的新概念的基于网络的反黑客和反病毒的工具。他帮助确保所有输入个人电脑

    终端的信息在网络上不落入黑客手中。在最终用户在执行电子贸易时,可以通过将nProtect配置在那些提供电子商务、进口贸易,电子贸易的

    金融机构的网站上,来提高安全等级。

    nProtect怎样工作?

    nProtect是一种基于服务器端的解决方案并且当那些需要保护的任何网络应用被运行时而自动启动。nProtect被载入内存,所以最终用户不需

    要安装任何应用程序,只要nProtect启动,就开始拒绝黑客工具和病毒的入侵!

    nProtect如何工作?

    用户登陆时nProtect自动启动。
    浏览器确认和自动安装安全模块到用户的个人电脑。
    扫描黑客工具和病毒
    通知用户目前的安全状态
    如果有黑客工具和病毒尝试删除 
    在被入侵时端驻留内存来锁定黑客工具直到电脑或者nProtect关闭。

    nProtect 的主要功能介绍:

    实时侦测并封锁修改游戏之黑客程序。
    实时侦测并封锁各类型系统病毒。
    实时侦测并封锁加速程序。
    实时侦测并封锁自动鼠标(连点)程序。
    封锁不当外挂程序。
    封锁各种意图远程控制玩家个人计算机的动作。
    限制意图侧录键盘鼠标动作的恶性程序。
    限制可疑间谍程序,加强安全性。

    使用此软件的网络游戏有很多,比如:冒险岛、蒸汽幻想、惊天动地、神话等等。

    这篇文章只讲如何突破NP对按键类的封锁。

    NP对按键的封锁方式主要有3种:

    1、封系统API函数,按键模拟类的API函数有KeyBoard_Event(键盘模拟)、Mouse_Event(鼠标模拟)、SetCursor(模拟鼠标移动)、SendInput()

    、SendMessage(发送消息)PutMessage(发送消息)。这种封API函数的方法在NP早期被应用,主要手段是通过钩子函数修改API的CALL地址。但这

    种手段很快被人破解,破解方法有2种,1种方法是移植这些API函数的代码(具体移植方法请见相关的专业资料)我曾用这方法,把整个

    kernel32.dll系统库文件更名复制,然后调用该库的API,从而绕过NP;第2种方法是使用WINIO.SYS驱动,硬件模拟按键动作(此驱动只支持

    8042端口,即只能模拟PS2键盘鼠标动作)。
    2、鉴于上面原因,NP不再封系统API,而是封按键模拟相关的内核API。移植系统API来模拟按键就不能实现了,因为移植的系统API最终要调用

    内核API。这样留给我们的工作只能是通过驱动硬件来模拟按键动作了。
    3、网上流行的硬件模拟是通过对8042端口驱动来实现的,这种操作端口来实现硬件模拟的方法必须要在系统RING0层才能进行。所以,这类操

    作都必须通过驱动或中断程序来实现。目前网络上流行的端口操作驱动程序有2种:WINIO.SYS及PortTalk.SYS,WINIO.SYS操作端口效率较高。

    它们的主要缺陷是只能模拟PS2的键盘、鼠标,当键盘或鼠标是USB的,或者频繁模拟鼠标时就会出现卡死现象。但这类操作端口的模拟也没长

    久,NP也把这类模拟给封了。封的办法很简单,这2个驱动特征太明显了:WINIO把端口操作从RING0层暴露给RING3层,这样的暴露给系统安全

    带来隐患,所以有的杀毒软件会对WINIO进行查杀!NP封这种具有典型特征驱动程序易如反掌;PortTalk是用户级驱动程序,可以通过调用

    DeviceIoControl函数来操作端口,但正因是用户级驱动,其发出IRP在下传时容易被NP截获屏蔽。这样NP给我们剩下的操作空间就不多了:1、

    改写或移植内核API,这种方法因系统及版本不同实现起来相当困难,极容易造成机器死机。2、虚拟一个设备,通过该设备驱动程序来操作端

    口,最好是将其设备虚拟成键盘和鼠标设备。这种方法可行,因为NP难以实现封设备驱动(封错了机器就死机了)。但这方法也有缺陷,驱动

    程序需要安装,安装弹出微软的认证签名窗口(未经签名存在安全问题),这对许多用户来说是难以接受的。
        以上几种反NP屏蔽按键的方法我在写“按键游侠”(下载地址Http://www.net321.net.cn,论坛地址:Http://www.fyhand.com/bbs)各版

    本时都用过。随着NP的升级,按键游侠反NP的措施也在升级,从最初的API拦截,到现在的虚拟设备驱动、移植内核API。按键游侠始终能突破

    NP屏蔽,模拟按键动作。在对NP的较量中,我从本站中找到许多有关NP的资料,在此一并感谢哪些无私的提供最前端资料的高手。同时也感谢

    哪些提供USB技术朋友,让按键游侠能够硬件模拟USB键盘、鼠标!



    相关资料:按键游侠 WINIO.SYS PortTalk.SYS NP KeyBoard_Event Mouse_Event SetCursor SendInput SendMessage PutMessage USB 驱动签

    名 DeviceIoControl  钩子函数 需要了解这些知识的朋友可以按这些资料在百度湖GOOGLE上查找。

    【转】如何在NP下读写游戏内存及如何进入NP进程

    标 题: 【原创】如何在NP下读写游戏内存及如何进入NP进程
    作 者: 堕落天才
    时 间: 2007-01-04,13:28
    链 接: http://bbs.pediy.com/showthread.php?t=37417

    ******************************************************
    *标题:【原创】如何在NP下读写游戏内存及如何进入NP进程 *
    *作者:堕落天才                                       *
    *日期:2007年1月4号                                   *
    *版权声明:请保持文章的完整,转载请注明出处           *
    ******************************************************

       在上一篇文章《反NP监视原理》中说到要去掉NP的注入是很容易的事,但是去掉npggNT.des并不是说我们想对游戏怎么样都可以了,NP还挂钩了很多内核函数,所以很多关键系

    统函数就算我们在用户层能用也对游戏没有什么效果。
       如果我们想在不破解NP前提下读写游戏内存该怎么办呢,我想办法至少有两个
    一、用驱动
        在驱动下读写游戏内存是没问题,但是由于我不懂驱动,所以也没什么可说。
    二、进入游戏进程
        在用户层,如果我们想在不破解NP的前提下读写游戏内存的话,大概就只能进入游戏进程了。因为很简单,我们的程序无法对游戏使用OpenProcess、ReadProcessMemoery及

    WriteProcessMemory这些函数(就算是去掉了NP监视模块npggNT.des),而NP又不可能限制游戏自身使用这些函数,所以只要我们能够进入游戏进程就能够读写游戏的内存。怎么

    进入游戏呢?下面介绍两种方法:

        1,最简单的办法 ―全局消息钩子(WH_GETMESSAGE)
          看似很复杂的东西原来很简单就可以实现,大道至易啊。使用消息钩子进入游戏进程无疑是最简单的一种方法,具体编程大概象这样:一个消息钩子的DLL,里面包含一个消

    息回调函数(什么都不用做),读写内存过程,跟主程序通讯过程或操作界面过程,当然在DLL_PROCESS_ATTACH要判断当前的进程是不是游戏的,是的话就做相应的处理;一个安

    装全局消息钩子的主程序。大概这样就可以了。使用全局消息钩子的好处是简单易用,但是不足之处是要在游戏完全启动(NP当然也启动啦)后才能进入,如果想在NP启动前做一

    些什么事的话是不可能的。
         另外也简单介绍一下防全局钩子的办法,Windows是通过调用LoadLibraryExW来向目标进程注入钩子DLL的,所以只要我们在钩子安装前挂钩了这个函数,全局钩子就干扰不了

    了。

         2,更麻烦的办法 ― 远程注入
           知道远程注入方法和原理的人可能会说“有没有搞错,OpenProcess、WriteProcessMemory这些必备函数都不能用,怎么注入?”,当然啦,NP启动后是不能干这些事情,所

    以我们要在NP启动前完成。这样一来,时机就很重要了。
           游戏启动的流程大概是这样:游戏Main->GameGuard.des->GameMon.des(NP进程)。这里的做法是这样:游戏Main->GameGuard.des(暂停)->注入DLL->GameGuard.des(继

    续)->GameMon.des。关键点就是让GameGuard.des暂停,有什么办法?我想到一个是全局消息钩子(还是少不了它啊)。要实现大概需要做下面的工作:一个全局消息钩子DLL,里面只

    要一个消息回调函数(什么都不用做),DLL_PROCESS_ATTACH下进行当前进程判断找GameGuard.des,找到的话就向主程序SendMessage;主程序,负责安装钩子,接收钩子DLL发来的

    消息,接收到消息就开始查找游戏进程,向游戏进程注入内存操作DLL,返回给SendMessage让GameGuard.des继续,卸载钩子(免得它继续钩来钩去);内存操作DLL,负责对游戏

    内存进行操作。
            具体编写如下(有省略):
    ////////////////////////////////////////////////GameHook.cpp//////////////////////////////////////////////////////////////////
    BOOL IsGameGuard();
    //////////////////////////////////
    LRESULT CALLBACK GetMsgProc(int nCode,WPARAM wParam,LPARAM lParam)
    {
      return (CallNextHookEx(m_hHook,nCode,wParam,lParam));//什么都不需要做
    }
    ///////////////////////////////////////
    BOOL WINAPI DllMain(HINSTANCE hInst,DWORD dwReason,LPVOID lp)
    {
      switch(dwReason){
      case DLL_PROCESS_ATTACH:    
        if(IsGameGuard())//判断当前进程是不是GameGuard.des
           SendMessage(m_hwndRecv,WM_HOOK_IN_GAMEGUARD,NULL,NULL);//向主窗体发送消息,SendMessage是等待接受窗体处理完毕才返回的,
        break;                               //所以进程就暂停在这里,我们有足够的时间去做事情
      case DLL_PROCESS_DETACH:
        break;
      }
      return TRUE;
    }
    ///////////////////////////////////
    GAMEHOOKAPI BOOL SetGameHook(BOOL fInstall,HWND hwnd)
    {
      ...
    }
    ////////////////////////////////////////
    BOOL IsGameGuard()
    {
           TCHAR  szFileName[256];
           GetModuleFileName(NULL,szFileName,256);
           if(strstr(szFileName,"GameGuard.des")!=NULL){//这样的判断严格来说是有问题的,但实际操作也够用了。当然也可以进行更严格的判断,不过麻烦点
              return TRUE;
           }
      return FALSE;
    }
    //////////////////////////////////////////////////////Main////////////////////////////////////////////////////////////////////////
    void OnGameGuard(WPARAM wParam,LPARAM lParam)//处理消息钩子DLL发来的消息就是上面SendMessage的那个
    {  
      DWORD dwProcessId=FindGameProcess(m_strGameName);//开始查找游戏进程
      if(dwProcessId==0){
        MessageBox(m_hWnd,"没有找到游戏进程","查找游戏进程",MB_OK);
        return;
      }  

        if(!InjectDll(dwProcessId)){//查找到就开始注入
        MessageBox(m_hWnd,"向游戏进程注入失败",注入",MB_OK);
        return;
         }
    }
    /////////////////////////////////////////////////
    DWORD FindGameProcess(LPCSTR szGameName)//负责查找游戏进程
    {
      HANDLE hSnapshot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
      if(hSnapshot==INVALID_HANDLE_VALUE)
        return 0;
      PROCESSENTRY32 pe={sizeof(pe)};
      DWORD dwProcessID=0;
      for(BOOL fOK=Process32First(hSnapshot,&pe);fOK;fOK=Process32Next(hSnapshot,&pe)){
        if(lstrcmpi(szGameName,pe.szExeFile)==0){
          dwProcessID=pe.th32ProcessID;
          break;
        }
      }
      CloseHandle(hSnapshot);
      return dwProcessID;
    }
    /////////////////////////////////////////////////
    BOOL InjectDll(DWORD dwProcessId)//负责注入,参考自Jeffrey Richter《windows核心编程》
    {
      CString strText;
      char* szLibFileRemote=NULL;

      HANDLE hProcess=OpenProcess(PROCESS_CREATE_THREAD|PROCESS_VM_OPERATION|PROCESS_VM_WRITE,FALSE,dwProcessId);
      if(hProcess==NULL){
      //  SetRecord("Open game process failed!");               
        return FALSE;
      }
      int cch=lstrlen(szDll)+1;
      int cb=cch*sizeof(char);
      szLibFileRemote=(char*)VirtualAllocEx(hProcess,NULL,cb,MEM_COMMIT,PAGE_READWRITE);
      if(szLibFileRemote==NULL){
      //  SetRecord("Alloc memory to game process failed!");
        CloseHandle(hProcess);
        return FALSE;
      }

      if(!WriteProcessMemory(hProcess,(LPVOID)szLibFileRemote,(LPVOID)szDll,cb,NULL)){
      //  SetRecord("Write game process memory failed!");
        CloseHandle(hProcess);
        return FALSE;
      }

      PTHREAD_START_ROUTINE pfnThreadRtn=(PTHREAD_START_ROUTINE)
         GetProcAddress(GetModuleHandle(TEXT("kernel32")),"LoadLibraryA");
      if(pfnThreadRtn==NULL){
      //  SetRecord("Alloc memory to game process failed!");
        CloseHandle(hProcess);
        return FALSE;
      }

      HANDLE hThread=CreateRemoteThread(hProcess,NULL,0,pfnThreadRtn, szLibFileRemote,0,NULL);
       if(!hThread)
       {
        //    SetRecord("Create remote thread failed!");
        CloseHandle(hProcess);
       return FALSE;
       }      
       if(hThread!=NULL)
         CloseHandle(hThread);  
       CloseHandle(hProcess);
        return TRUE;

    }     
    ///////////////////////////操作游戏内存的DLL就不贴了,大家根据不同的需要各显神通吧///////////////////////////////////////////////////      
          
           这种方法比一个全局消息钩子麻烦一点,但是优点是显然易见的:可以在NP启动前做事情,比如HOOK游戏函数或做游戏内存补丁。下面进入NP进程还要用到这种方法。

    三、进入NP进程
        如果我们对NP有足够的了解,想对它内存补丁一下,来做一些事情,哪又怎样才可以进入NP的进程呢?嗯,我们知道游戏启动流程是这样的游戏Main->GameGuard.des-

    >GameMon.des(NP进程),其中GameGuard.des跟GameMon.des进程是游戏Main通过调用函数CreateProcessA来创建的,上面我们说到有办法在NP进程(GameMon.des)启动前将我们的

    DLL注入到游戏进程里,因此我们可以在GameMon.des启动前挂钩(HOOK)CreateProcessA,游戏创建NP进程时让NP暂停,但是游戏本来创建NP进程时就是让它先暂停的,这步我们

    可以省了。下面是游戏启动NP(版本900)时传递的参数

          ApplicationName:C:\惊天动地Cabal Online\GameGuard\GameMon.des
          CommandLine:\x01\x58\x6d\xae\x99\x55\x57\x5d\x49\xbe\xe4\xe1\x9b\x14\xe6\x88\x57\x68\x6d\x11\xb9\x36\x73\x38\x71\x1e\x88\x46\xa9\x97\xd4\x3a\x20\x90

    \x62\xae\x15\xcd\x4b\xcd\x72\x82\xbd\x75\x0a\x54\xf0\xcc\x01\xad
          CreationFlags:4
          Directory:
          其中的CommandLine好长啊,它要传递的参数是:一个被保护进程的pid,两个Event的Handle,以及当前timeGetTime的毫秒数 (感谢JTR分享)。
          CreationFlags:4 查查winbase.h头文件,发现#define CREATE_SUSPENDED  0x00000004,所以NP进程创建时就是暂停的
        
          在我们替换的CreateProcessA中,先让游戏创建NP进程(由于游戏创建时NP进程本来就是暂停的,所以不用担心NP的问题),让游戏进程暂停(SendMessage就可以了),然后再

    向NP进程注入DLL,最后让游戏进程继续。这样我们的DLL就进入NP进程了。实现起来大概是这样子
    BOOL
    WINAPI
    MyCreateProcessA(//替换原来的CreateProcessA
        LPCSTR lpApplicationName,
        LPSTR lpCommandLine,
        LPSECURITY_ATTRIBUTES lpProcessAttributes,
        LPSECURITY_ATTRIBUTES lpThreadAttributes,
        BOOL bInheritHandles,
        DWORD dwCreationFlags,
        LPVOID lpEnvironment,
        LPCSTR lpCurrentDirectory,
        LPSTARTUPINFOA lpStartupInfo,
        LPPROCESS_INFORMATION lpProcessInformation
        )
    {
      UnhookCreateProcessA();
      BOOL fRet=CreateProcessA(lpApplicationName,lpCommandLine,lpProcessAttributes,lpThreadAttributes,bInheritHandles,dwCreationFlags,
         lpEnvironment,lpCurrentDirectory,lpStartupInfo,lpProcessInformation);  
      RehookCreateProcessA();
            SendMessage(hwndRecv,//负责注入的窗体句柄
                       WM_HOOK_NP_CREATE,//自定义消息
                       (WPARAM)lpProcessInformation->dwProcessId,//把NP进程ID传给负责注入的主窗体
                       NULL);
      return fRet;
    }

    四、注意问题
        由于我们是在不破解NP的前提下对游戏内存进行操作,所以一不小心的话,很容易就死游戏。NP保护了游戏进程的代码段,所以在NP启动后就不要再对其代码段进行修改,要

    补丁或HOOK系统函数这些都要在NP启动前完成。当然读写游戏的数据段是没问题的,因为游戏本身也不断进行这样的操作。

    【转】驱动中实现模拟键盘按键

    标 题: 【原创】驱动中实现模拟键盘按键
    作 者: luocong
    时 间: 2007-04-19,11:35
    链 接: http://bbs.pediy.com/showthread.php?t=42980

    在ring3中实现模拟键盘按键有N^N种方式,比如SendInput()、keybd_event()……但在驱动中要怎么模拟呢?

    1、写端口大法
    #define defI8042_DATA_PORT ((PUCHAR)0x60)
    #define defI8042_CTRL_PORT ((PUCHAR)0x64)
    #define defOBUFFER_FULL 0x01

    BOOLEAN
    WaitForKeyboardWrite(VOID)
    {
        INT i;
        UCHAR c;

        for (i = 0; i < 1000; ++i)
        {
            KeStallExecutionProcessor(50);
            c = READ_PORT_UCHAR(defI8042_CTRL_PORT);
            if ((c & defOBUFFER_FULL) == defOBUFFER_FULL)
                break;
        }

        return i ? TRUE : FALSE;
    }

    VOID PressKeyByScanCode(
        IN CONST BYTE ScanCode
    )
    {
        WRITE_PORT_UCHAR(defI8042_CTRL_PORT, 0xd2);

        WaitForKeyboardWrite();

        WRITE_PORT_UCHAR(defI8042_DATA_PORT, ScanCode);
    }

    搞定,简单易行!缺点是只对PS/2键盘有效,USB的就一边凉快去吧。

    2、构造IRP大法
    这个比较麻烦,而且由于某些原因,略……

    3、调用KeyboardClassServiceCallback()大法
    kbdclass驱动是在I8042prt和kbdhid这两个驱动之上的,所以直接调用它的KeyboardClassServiceCallback()是能对PS/2和USB同时生效的,由于某些原因偶也不想给出具体的代码来。大致指点一下方向:

    KeyboaredClassServiceCallback函数的原型如下:

    typedef VOID (* PFN_KeyboardClassServiceCallback)(
        IN PDEVICE_OBJECT DeviceObject,
        IN PKEYBOARD_INPUT_DATA InputDataStart,
        IN PKEYBOARD_INPUT_DATA InputDataEnd,
        IN OUT PULONG InputDataConsumed
        );

    第一个参数DeviceObject是kbdclass的DeviceObject,怎么得到它呢?思路:先找到kbdclass的DriverObject,然后从DriverObject得到DeviceObject。
    第二和第三个参数是KEYBOARD_INPUT_DATA,自己填充,想模拟什么按键就写什么MakeCode和Flags吧。注意第三个参数应该为第二个参数的指针地址值+1。
    第四个参数,随便弄个ULONG型的变量给它就行了,反正是可以丢弃的。(I8042prt里面用到了它,但我们自己的模拟按键不用也行)

    缺点:每个系统的kbdclass.sys中的KeyboardClassServiceCallback的RVA都不相同,要自己hardcode一下,不过写驱动本来就是那么麻烦,习惯了就好。

    网友:cngage评论
    关于写端口部分,不知道楼住从哪里找的代码,写错了吧。
    BOOLEAN
    WaitForKeyboardWrite(VOID)
    {
        INT i;
        UCHAR c;

        for (i = 0; i < 1000; ++i)
        {
            KeStallExecutionProcessor(50);
            c = READ_PORT_UCHAR(defI8042_CTRL_PORT);
            if ((c & defOBUFFER_FULL) == defOBUFFER_FULL)
                break;
        }

        return i ? TRUE : FALSE;
    }

    判断状态寄存器是否为空,判断条件应该是
    if ((c & 0x02)==0)
    下面这句判断出的结果是输出buffer为满的情况
    if ((c & defOBUFFER_FULL) == defOBUFFER_FULL)

    4/17/2008

    【转载】反NP监视原理(+Bypass NP in ring0)

    NP=nProtect GameGuard(如果你不知道这是什么,请不要往下看)
    *******************************************
    *标题:【原创】反NP监视原理                *
    *作者:堕落天才                            *
    *日期:2007年1月3号                        *
    *版权声明:请保存文章的完整,转载请注明出处*
    *******************************************
    一、NP用户层监视原理
        NP启动后通过WriteProcessMemory跟CreateRemoteThread向所有进程注入代码(除了系统进程smss.exe),代码通过np自己的LoadLibrary向目标进程加载npggNT.des。npggNT.des一旦加载就马上开始干“坏事”,挂钩(HOOK)系统关键函数如OpenProcess,ReadProcessMemory,WriteProcessMemory,PostMessage等等。挂钩方法是通过改写系统函数头,在函数开始JMP到npggNT.des中的替换函数。用户调用相应的系统函数时,会首先进入到npggNT.des模块等待NP的检查,如果发现是想对其保护的游戏进行不轨操作的话,就进行拦截,否则就调用原来的系统函数,让用户继续。
        下面是NP启动前user32.dll中的PostMessageA的源代码(NP版本900,XP sp2)
        8BFF            MOV EDI,EDI
        55              PUSH EBP
        8BEC            MOV EBP,ESP
        56              PUSH ESI
        57              PUSH EDI
        8B7D 0C         MOV EDI,DWORD PTR SS:[EBP+C]
        8BC7            MOV EAX,EDI
        2D 45010000     SUB EAX,145
        74 42           JE SHORT USER32.77D1CBDA
        83E8 48         SUB EAX,48
        74 3D           JE SHORT USER32.77D1CBDA
        2D A6000000     SUB EAX,0A6
        0F84 D4530200   JE USER32.77D41F7C
        8B45 10         MOV EAX,DWORD PTR SS:[EBP+10]
        8B0D 8000D777   MOV ECX,DWORD PTR DS:[77D70080]
        F641 02 04      TEST BYTE PTR DS:[ECX+2],4
        0F85 03540200   JNZ USER32.77D41FBE
        8D45 10         LEA EAX,DWORD PTR SS:[EBP+10]
        50              PUSH EAX
        57              PUSH EDI
        E8 FBFEFFFF     CALL USER32.77D1CAC0
        FF75 14         PUSH DWORD PTR SS:[EBP+14]
        FF75 10         PUSH DWORD PTR SS:[EBP+10]
        57              PUSH EDI
        FF75 08         PUSH DWORD PTR SS:[EBP+8]
        E8 ACBFFFFF     CALL USER32.77D18B80
        5F              POP EDI
        5E              POP ESI
        5D              POP EBP
        C2 1000         RETN 10

        而下面是NP启动后user32.dll中的PostMessageA的源代码(NP版本900,XP sp2)
        E9 A69AB8CD     JMP npggNT.458A6630
        56              PUSH ESI
        57              PUSH EDI
        8B7D 0C         MOV EDI,DWORD PTR SS:[EBP+C]
        8BC7            MOV EAX,EDI
        2D 45010000     SUB EAX,145
        74 42           JE SHORT USER32.77D1CBDA
        83E8 48         SUB EAX,48
        74 3D           JE SHORT USER32.77D1CBDA
        2D A6000000     SUB EAX,0A6
        0F84 D4530200   JE USER32.77D41F7C
        8B45 10         MOV EAX,DWORD PTR SS:[EBP+10]
        8B0D 8000D777   MOV ECX,DWORD PTR DS:[77D70080]
        F641 02 04      TEST BYTE PTR DS:[ECX+2],4
        0F85 03540200   JNZ USER32.77D41FBE
        8D45 10         LEA EAX,DWORD PTR SS:[EBP+10]
        50              PUSH EAX
        57              PUSH EDI
        E8 FBFEFFFF     CALL USER32.77D1CAC0
        FF75 14         PUSH DWORD PTR SS:[EBP+14]
        FF75 10         PUSH DWORD PTR SS:[EBP+10]
        57              PUSH EDI
        FF75 08         PUSH DWORD PTR SS:[EBP+8]
        E8 ACBFFFFF     CALL USER32.77D18B80
        5F              POP EDI
        5E              POP ESI
        5D              POP EBP
        C2 1000         RETN 10
       
        通过对比我们可以发现,NP把PostMessageA函数头原来的8BFF558BEC五个字节改为了E9A69AB8CD,即将MOV EDI,EDI  PUSH EBP
    MOV EBP,ESP 三条指令改为了JMP npggNT.458A6630。所以用户一旦调用PostMessageA的话,就会跳转到npggNT.des中的458A6630中去。
    二、用户层反NP监视方法
        1,把被NP修改了的函数头改回去
           上面知道NP是通过在关键系统函数头写了一个JMP来进行挂钩的,因此,在理论上我们可以通过把函数头写回去来进行调用。在实际操作的时候,这种方法并不理想。因为npggNT.des也挂钩了把函数头改写回去的所有函数,还有它的监视线程也会进行检校判断它挂钩了的函数是不是被修改回去。因此实现起来很困难,随时都会死程序。
        2,构建自己的系统函数(感谢JTR提供)
           这种方法适用于代码比较简单的系统函数。下面我们看看keybd_event的函数源码
        8BFF            MOV EDI,EDI                              ; USER32.keybd_event
        55              PUSH EBP
        8BEC            MOV EBP,ESP
        83EC 1C         SUB ESP,1C
        8B4D 10         MOV ECX,DWORD PTR SS:[EBP+10]
        8365 F0 00      AND DWORD PTR SS:[EBP-10],0
        894D EC         MOV DWORD PTR SS:[EBP-14],ECX
        66:0FB64D 08    MOVZX CX,BYTE PTR SS:[EBP+8]
        66:894D E8      MOV WORD PTR SS:[EBP-18],CX
        66:0FB64D 0C    MOVZX CX,BYTE PTR SS:[EBP+C]
        66:894D EA      MOV WORD PTR SS:[EBP-16],CX
        8B4D 14         MOV ECX,DWORD PTR SS:[EBP+14]
        894D F4         MOV DWORD PTR SS:[EBP-C],ECX
        6A 1C           PUSH 1C
        33C0            XOR EAX,EAX
        8D4D E4         LEA ECX,DWORD PTR SS:[EBP-1C]
        40              INC EAX
        51              PUSH ECX
        50              PUSH EAX
        8945 E4         MOV DWORD PTR SS:[EBP-1C],EAX
        E8 9B8DFCFF     CALL USER32.SendInput
        C9              LEAVE
        C2 1000         RETN 10

        由上面我们看到keybd_event进行了一些参数的处理最后还是调用了user32.dll中的SendInput函数。而下面是SendInput的源代码
        B8 F6110000     MOV EAX,11F6
        BA 0003FE7F     MOV EDX,7FFE0300
        FF12            CALL DWORD PTR DS:[EDX]          ; ntdll.KiFastSystemCall
        C2 0C00         RETN 0C

        SendInput代码比较简单吧?我们发现SendInput最终是调用了ntdll.dll中的KiFastSystemCall函数,我们再跟下去,KiFastSystemCall就是这个样子了
        8BD4            MOV EDX,ESP
        0F34            SYSENTER
        最终就是进入了SYSENTER。
        
        通过上面的代码我们发现一个keybd_event函数构建并不复杂因此我们完全可以把上面的代码COPY到自己的程序,用来替代原来的keybd_event。NP启动后依然会拦截原来的那个,但已经没关系啦,因为我们不需要用原来那个keybd_event了。
        这种方法适用于源代码比较简单的系统函数,复杂的话实现起来就比较麻烦了。我是没有信心去重新构建一个PostMessageA,因为其中涉及到N个jmp和Call,看起来头都大。 还有在VC6里嵌入汇编经常死VC(这种事太烦人了),我想不会是我用了盗版的原因吧?
      
        3,进入ring0(感谢风景的驱动鼠标键盘模拟工具)
         由上面可以看到,NP用户层的监视不过是修改了一下系统的函数头,进行挂钩监视。因此,要反NP用户层监视的话,进入ring0的话很多问题就可以解决了。比如WinIO在驱动层进行键盘模拟,npggNT.des是拦截不到的。但是由于NP用了特征码技术,再加上WinIO名气太大了,所以WinIO在NP版本8××以后都不能用了。但是如果熟悉驱动开发的话,自己写一个也不是很困难的事。
     
         说了那么多看起来很“高深”的东西,现在说一些象我这样的菜鸟都能明白的东西,呵呵,因为这是菜鸟想出来的菜办法。
        4,断线程
           我们知道NP是通过CreateRemoteThread在目标进程创建远程线程的,还有一点,很重要的一点就是:NP向目标进程调用了CreateRemoteThread后就什么都不管了,也就是说,凭本事可以对除游戏外的所有进程npggNT.des模块进行任何“处置”。这样我们可以用一个很简单的方法就是检查自己的线程,发现多余的话(没特别的事情就是NP远程创建的)就马上结束了它,这样NP就无法注入了。但是由于windows系统是多任务系统,而CreateRemoteThread的执行时间又极短,要在这么短的时间内发现并结束它的话是一件很困难的事。一旦CreateRemoteThread执行完毕而我们的监视线程还没有起作用的话,后果就惨重了,npggNT.des马上把程序“搞死”。因为我们一直试图关闭它的线程,而npggNT.des又拦截了TerminateThread,所以我们就只能不断地“重复重复再重复”去试图关闭npggNT.des的监视线程。如果我们很幸运地在其执行注入代码时就能断了它地线程地话,npggNT.des就无法注入了。这种方法在NP早期版本大概有百分之五十的成功率,现在能有百分之一的成功率都不错了。

         5,断线程之线程陷阱
          我知道“线程陷阱”这个词肯定不是我首创,但用“陷阱”这种方法来对付NP之前在网上是找不到的。为什么要叫“线程陷阱”?因为这确确实实是一个陷阱,在npggNT.des肯定要经过的地方设置一个“陷阱”,等它来到之后,掉进去自动就死掉了。而搭建陷阱的方法简单得令你难以相信。
           上面我们从npggNT.des的监视原理可以看到,npggNT.des要来挂钩(HOOK)我们的系统函数,这种的方法我们也会,是不是?哪想想,这种挂钩方法需要用到哪些系统函数呢? 打开进程OpenProcess或GetCurrentProcess(因为npggNT.des已经进入了目标进程,所以没有必要再调用OpenProcess,肯定是用后者)、找模块地址GetModelHandle、找函数地址GetProcAddress、改写函数头的内存属性VirtualQuery&VirtualProtect、写内存WriteProcessMemory。嘿嘿,在这些地方设置陷阱就八九不离十了,肯定是npggNT.des干那坏勾当要经过的地方。
          怎么设陷阱呢?选一个上面说的函数(我没有一一尝试),先自己挂钩(嘿嘿,NP会我们也会)。等到有人调用的时候,先判断当前的的线程是不是我们程序的,不是的话,那就断了它吧(一个ExitThread就可以了)。大概就像下面这个样子
    HANDLE WINAPI MyGetCurrentProcess(VOID)//替换掉原来的GetCurrentProcess
    {
       DWORD dwThreadId=GetCurrentThreadId();//得到当前线程ID
       if(!IsMyThread(dwThreadId)){//不是我们要保护的线程
          ExitThread(0);//断了它吧         
       }
       UnhookGetCurrentProcess(); //是我们要保护的线程调用就恢复函数头
       HANDLE hProcess=GetCurrentProcess();//让它调用
       RehookGetCurrentProcess();//重新挂钩
       return hProcess;   //返回调用结果
    }
          这种方法去掉npggNT.des的监视是完全能够实现的,但是这个函数IsMyThread(dwThreadId)非常关键,要考虑周全,不然断错线程的话,就“自杀”了。

          6,更简单的陷阱
             原理跟上面一样,但是我们将替换函数写成这个样子
    HANDLE WINAPI MyGetCurrentProcess(VOID)//替换掉原来的GetCurrentProcess

       HMODLE hMod=GetModelHandle("npggNT.des");
       if(hMod!=NULL){
          FreeLibrary(hMod);      //直接Free掉它
       }
       UnhookGetCurrentProcess(); //是我们要保护的线程调用就恢复函数头
       HANDLE hProcess=GetCurrentProcess();//让它调用
       RehookGetCurrentProcess();//重新挂钩
       return hProcess;   //返回调用结果
    }
         这种方法就万无一失了,不用担心会“自杀”。

    三、总结
        由上面可以看到在用户层上反NP监视是不是很简单的事?最简单有效的就是第六种方法,短短的几行代码就可以搞定了。但是不要指望去掉了npggNT.des就可以为所欲为了,还有NP还在驱动层做了很多手脚,比如WriteProcessMemory在用户层用没问题,但是过不了NP的驱动检查,对游戏完全没效果。要在NP下读写游戏内存,说起来又另一篇文章了《如何在NP下读写游戏内存》,请继续关注。

    **********************************************************************
    Bypass NP in ring0 (2007年3月16日):
    1,Add MyService
    2,hook sysenter
    3,SystemServiceID->MyServiceID
    4,MyService JMP ->SystemService Function + N bytes(参考【原创】SSDT Hook的妙用-对抗ring0 inline hook  )

    1、2、3 ->绕过NP SSDT检测
    4       ->绕过NP 内核函数头检测

    NP968下通过