DebugPort 调用过程

DebugPort 调用过程
DebugPort 调用过程

DebugPort调用过程

学习各种外挂制作技术,马上去百度搜索"魔鬼作坊"点击第一个站进入、快速成为做挂达人。

1一个程序被ring3调试器调试时,有很多的调试特征可以检测,本论坛也有专门的帖子详细论述,但有个非常根本的标志ring3也是可以检测的比较少人提及,那就是_EPROCESS.DebugPort。DebugPort对于ring3调试器来说非常重要,没有它正常的ring3调试是无法进行的。当然要检测这个标志的前提是程序能够读取ring0内存,在XP 以上的系统有个非常简单的方法就是使用ZwSystemDebugControl的SysDbgReadVirtualMemory方法,我们也可以mapphysicalmemory来操作。检测DebugPort之前首先要得到进程的eprocess地址,这可以通过ZwQuerySystemInformation的SystemHandleInformation方法得到,也可以直接搜索ring0内存的eprocess结构。

对于ring3直接检测DebugPort,我们可以通过禁止该进程访问ring0内存来对付,但是目标一旦使用驱动来检测,那么就非常麻烦了。下面介绍一种隐藏_EPROCESS.DebugPort的方法,这种方法的基本思路是,将一个正常被调试进程的DebugPort置零后,修正所有受影响的函数,使我们的调试器能够正常进行。这些函数如下:

PspCreateProcess、MmCreatePeb进程创建,设置DebugPort

DbgkCreateThread发送线程或者进程创建的调试信息

KiDispatchException、DbgkForwardException和DbgkpQueueMessage发送异常调试信息

PspExitThread、DbgkExitThread和DbgkExitProcess发送线程退出、进程退出的调试信息

DbgkMapViewOfSection和DbgkUnMapViewOfSection发送映像装载卸载调试信息

DbgkpSetProcessDebugObject和DbgkpMarkProcessPeb当调试器附加进程时设置DebugPort

这类函数非常多的,如果都HOOK处理的话,那太恐怖了,这里使用一个非常简单的办法:偷龙转凤。我们看系统访问DebugPort的代码都是这样的(XP)

8b89bc000000mov ecx,dword ptr[ecx+0BCh]//0BCh就是DebugPort的偏移

我们可以把DebugPort转移到_EPROCESS的另外一个地方,比如我使用+0x070CreateTime,它是纪录进程创建时间的,进程创建之后,在进程退出前系统不会对它进行任何修改,而且我们修改后对系统或进程没有任何影响。这样我们可以把上面的代码改成这样

8b8970000000mov ecx,dword ptr[ecx+070h]//指向CreateTime,实际的DebugPort已经被移到这里

只需要修改一个字节,非常简单。

当然这种方法最麻烦的地方就是定位引用到DebugPort的函数(本人仅仅针对不同的XP系统制作特征码都累到吐血),这些函数都是不导出的,如果是特定系统,最简单的方法就是WinDbg->uf***直接找地址硬编码,只需要几分钟时间。

BOOLEAN InitHackAddress()

2{

3_SEH_TRY

4{

5g_KernelBase=GetKernelBaseAndSize(&g_KernelSize);

6g_HackPspCreateProcess= SearchHackPspCreateProcess(&g_NopPspCreateProcess.Address);

7g_HackKiDispatchException

=SearchKiDispatchException(g_KernelBase,g_KernelSize);

8g_HackDbgkpQueueMessage= SearchDbgkpQueueMessage(g_KernelBase,g_KernelSize);

9g_HackDbgkCreateThread= SearchDbgkCreateThread(g_KernelBase,g_KernelSize);

10SearchDbgkNotifyRoutine(g_KernelBase,g_KernelSize);

11g_HackPspExitThread=SearchPspExitThread();

12g_HackMmCreatePeb=SearchMmCreatePeb(g_HackPspCreateProcess); 13SearchDbgkpSetProcessDebugObject(g_KernelBase,g_KernelSize);

14if(g_HackDbgkpSetProcessDebugObject[3])

15g_HackDbgkpMarkProcessPeb= SearchDbgkpMarkProcessPeb(g_HackDbgkpSetProcessDebugObject[3]);

16

17if(g_NopPspCreateProcess.Address!=0){

18

RtlFillMemory(g_NopPspCreateProcess.NopCode,sizeof(g_NopPspCreateProcess. NopCode),0x90);

19g_NopPspCreateProcess.Size=9;

20

RtlCopyMemory(g_NopPspCreateProcess.OrigCode,(PVOID)g_NopPspCreateProce ss.Address,g_NopPspCreateProcess.Size);

21}

22if(g_NopDbgkForwardException.Address!=0){

23

RtlFillMemory(g_NopDbgkForwardException.NopCode,sizeof(g_NopDbgkForwardE xception.NopCode),0x90);

24

RtlCopyMemory(g_NopDbgkForwardException.OrigCode,(PVOID)g_NopDbgkForwa rdException.Address,g_NopDbgkForwardException.Size);

25}

26if(g_NopDbgkExitThread.Address!=0){

27

RtlFillMemory(g_NopDbgkExitThread.NopCode,sizeof(g_NopDbgkExitThread.NopC ode),0x90);

28

RtlCopyMemory(g_NopDbgkExitThread.OrigCode,(PVOID)g_NopDbgkExitThread.A ddress,g_NopDbgkExitThread.Size);

29}

30if(g_NopDbgkExitProcess.Address!=0){

31

RtlFillMemory(g_NopDbgkExitProcess.NopCode,sizeof(g_NopDbgkExitProcess.Nop Code),0x90);

32

RtlCopyMemory(g_NopDbgkExitProcess.OrigCode,(PVOID)g_NopDbgkExitProcess. Address,g_NopDbgkExitProcess.Size);

33}

34if(g_NopDbgkMapViewOfSection.Address!=0){

35

RtlFillMemory(g_NopDbgkMapViewOfSection.NopCode,sizeof(g_NopDbgkMapView OfSection.NopCode),0x90);

36

RtlCopyMemory(g_NopDbgkMapViewOfSection.OrigCode,(PVOID)g_NopDbgkMapV iewOfSection.Address,g_NopDbgkMapViewOfSection.Size);

37}

38if(g_NopDbgkUnMapViewOfSection.Address!=0){

39

RtlFillMemory(g_NopDbgkUnMapViewOfSection.NopCode,sizeof(g_NopDbgkUnMa pViewOfSection.NopCode),0x90);

40

RtlCopyMemory(g_NopDbgkUnMapViewOfSection.OrigCode,(PVOID)g_NopDbgkUn MapViewOfSection.Address,g_NopDbgkUnMapViewOfSection.Size);

41}

42

43

44}

45_SEH_HANDLER

46{

47DbgPrint("InitHackAddress Exception!\n");

48}

49return(g_HackPspCreateProcess!=0&&

50g_HackKiDispatchException!=0&&

51g_HackDbgkForwardException!=0&&

52g_HackDbgkpQueueMessage!=0&&

53g_NopPspCreateProcess.Address!=0&&

54g_NopDbgkForwardException.Address!=0&&

55g_HackDbgkCreateThread!=0&&

56g_HackDbgkExitThread!=0&&

57g_NopDbgkExitThread.Address!=0&&

58g_HackDbgkExitProcess!=0&&

59g_NopDbgkExitProcess.Address!=0&&

60g_HackDbgkMapViewOfSection!=0&&

61g_NopDbgkMapViewOfSection.Address!=0&&

62g_HackDbgkUnMapViewOfSection!=0&&

63g_NopDbgkUnMapViewOfSection.Address!=0&&

64g_HackPspExitThread!=0&&

65g_HackMmCreatePeb!=0&&

66g_HackDbgkpSetProcessDebugObject[0]!=0&&

67g_HackDbgkpSetProcessDebugObject[1]!=0&&

68g_HackDbgkpSetProcessDebugObject[2]!=0&&

69g_HackDbgkpSetProcessDebugObject[3]!=0&&

70g_HackDbgkpMarkProcessPeb!=0);

71}//修改已经运行进程的DebugPort位置

72BOOLEAN ChangeProcessDebugPort(BOOLEAN Hide)

73{

74ULONG eProcess=(ULONG)PsInitialSystemProcess;

75PLIST_ENTRY pListHead,pListWalk;

76ULONG DebugObject;

77if(!g_bIsAddressStartup){

78return FALSE;

79}

80pListHead=(PLIST_ENTRY)(eProcess+ACTIVE_LINKS_OFFSET);

81pListWalk=pListHead;

82_SEH_TRY

83{

84do{

85if(pListWalk==NULL||eProcess==0)

86break;

87eProcess=((ULONG)pListWalk-ACTIVE_LINKS_OFFSET);

88if(Hide){

89DebugObject=*(ULONG*)(eProcess+DEBUG_PORT_OFFSET); 90*(ULONG*)(eProcess+CREATE_TIME_OFFSET)=DebugObject; 91*(ULONG*)(eProcess+DEBUG_PORT_OFFSET)=0;

92}else{

93DebugObject=*(ULONG*)(eProcess+CREATE_TIME_OFFSET); 94*(ULONG*)(eProcess+DEBUG_PORT_OFFSET)=DebugObject; 95}

96pListWalk=pListWalk->Flink;

97}while(pListWalk!=pListHead);

98}

99_SEH_HANDLER

100{

101DbgPrint("ChangeProcessDebugPortexception!\n");

102}

103

104return TRUE;

105}

106代码:

107BOOLEANModifyDebugFunction()

108{

109if(!g_bIsAddressStartup){

110returnFALSE;

111}

112__asm{

113cli

114mov eax,cr0

115and eax,not10000h

116mov cr0,eax

117}

118*(ULONG*)g_HackPspCreateProcess=CREATE_TIME_OFFSET;

119*(ULONG*)g_HackKiDispatchException=CREATE_TIME_OFFSET;

120*(ULONG*)g_HackDbgkForwardException=CREATE_TIME_OFFSET;

121*(ULONG*)g_HackDbgkpQueueMessage=CREATE_TIME_OFFSET;

122*(ULONG*)g_HackDbgkCreateThread=CREATE_TIME_OFFSET;

123*(ULONG*)g_HackDbgkExitThread=CREATE_TIME_OFFSET;

124*(ULONG*)g_HackDbgkExitProcess=CREATE_TIME_OFFSET;

125*(ULONG*)g_HackDbgkMapViewOfSection=CREATE_TIME_OFFSET;

126*(ULONG*)g_HackDbgkUnMapViewOfSection=CREATE_TIME_OFFSET;

127*(ULONG*)g_HackPspExitThread=CREATE_TIME_OFFSET;

128*(ULONG*)g_HackDbgkpMarkProcessPeb=CREATE_TIME_OFFSET;

129*(ULONG*)g_HackMmCreatePeb=CREATE_TIME_OFFSET;

130*(ULONG*)g_HackDbgkpSetProcessDebugObject[0]= CREATE_TIME_OFFSET;

131*(ULONG*)g_HackDbgkpSetProcessDebugObject[1]= CREATE_TIME_OFFSET;

132*(ULONG*)g_HackDbgkpSetProcessDebugObject[2]= CREATE_TIME_OFFSET;

133*(ULONG*)g_HackDbgkpSetProcessDebugObject[3]= CREATE_TIME_OFFSET;

134

135

RtlCopyMemory((PVOID)g_NopPspCreateProcess.Address,g_NopPspCreateProces s.NopCode,g_NopPspCreateProcess.Size);

136

RtlCopyMemory((PVOID)g_NopDbgkForwardException.Address,g_NopDbgkForward Exception.NopCode,g_NopDbgkForwardException.Size);

137

RtlCopyMemory((PVOID)g_NopDbgkExitThread.Address,g_NopDbgkExitThread.No pCode,g_NopDbgkExitThread.Size);

138

RtlCopyMemory((PVOID)g_NopDbgkExitProcess.Address,g_NopDbgkExitProcess.N opCode,g_NopDbgkExitProcess.Size);

139

RtlCopyMemory((PVOID)g_NopDbgkMapViewOfSection.Address,g_NopDbgkMapVi ewOfSection.NopCode,g_NopDbgkMapViewOfSection.Size);

140

RtlCopyMemory((PVOID)g_NopDbgkUnMapViewOfSection.Address,g_NopDbgkUn MapViewOfSection.NopCode,g_NopDbgkUnMapViewOfSection.Size);

141__asm{

142mov eax,cr0

143or eax,10000h

144mov cr0,eax

145sti

146}

147return TRUE;

148}

149BOOLEAN WriteBackDebugFunction()

150{

151if(!g_bIsAddressStartup){

152return FALSE;

153}

154__asm{

155cli

156mov eax,cr0

157and eax,not10000h

158mov cr0,eax

159}

160*(ULONG*)g_HackPspCreateProcess=DEBUG_PORT_OFFSET;

161*(ULONG*)g_HackKiDispatchException=DEBUG_PORT_OFFSET;

162*(ULONG*)g_HackDbgkForwardException=DEBUG_PORT_OFFSET;

163*(ULONG*)g_HackDbgkpQueueMessage=DEBUG_PORT_OFFSET;

164*(ULONG*)g_HackDbgkCreateThread=DEBUG_PORT_OFFSET;

165*(ULONG*)g_HackDbgkExitThread=DEBUG_PORT_OFFSET;

166*(ULONG*)g_HackDbgkExitProcess=DEBUG_PORT_OFFSET;

167*(ULONG*)g_HackDbgkMapViewOfSection=DEBUG_PORT_OFFSET;

168*(ULONG*)g_HackDbgkUnMapViewOfSection=DEBUG_PORT_OFFSET;

169*(ULONG*)g_HackPspExitThread=DEBUG_PORT_OFFSET;

170*(ULONG*)g_HackDbgkpMarkProcessPeb=DEBUG_PORT_OFFSET;

171*(ULONG*)g_HackMmCreatePeb=DEBUG_PORT_OFFSET;

172*(ULONG*)g_HackDbgkpSetProcessDebugObject[0]= DEBUG_PORT_OFFSET;

173*(ULONG*)g_HackDbgkpSetProcessDebugObject[1]= DEBUG_PORT_OFFSET;

174*(ULONG*)g_HackDbgkpSetProcessDebugObject[2]= DEBUG_PORT_OFFSET;

175*(ULONG*)g_HackDbgkpSetProcessDebugObject[3]= DEBUG_PORT_OFFSET;

176

RtlCopyMemory((PVOID)g_NopPspCreateProcess.Address,g_NopPspCreateProces s.OrigCode,g_NopPspCreateProcess.Size);

177

RtlCopyMemory((PVOID)g_NopDbgkForwardException.Address,g_NopDbgkForward Exception.OrigCode,g_NopDbgkForwardException.Size);

178

RtlCopyMemory((PVOID)g_NopDbgkExitThread.Address,g_NopDbgkExitThread.Ori gCode,g_NopDbgkExitThread.Size);

179

RtlCopyMemory((PVOID)g_NopDbgkExitProcess.Address,g_NopDbgkExitProcess.O rigCode,g_NopDbgkExitProcess.Size);

180

RtlCopyMemory((PVOID)g_NopDbgkMapViewOfSection.Address,g_NopDbgkMapVi ewOfSection.OrigCode,g_NopDbgkMapViewOfSection.Size);

181

RtlCopyMemory((PVOID)g_NopDbgkUnMapViewOfSection.Address,g_NopDbgkUn MapViewOfSection.OrigCode,g_NopDbgkUnMapViewOfSection.Size);

182__asm{

183mov eax,cr0

184or eax,10000h

185mov cr0,eax

186sti

187}

188return TRUE;

189}

我想再嗦一下,上面代码大家看到很多函数有个NOPCode,这个实际上是对付线程PS_C ROSS_THREAD_FLAGS_HIDEFROMDBG的,NOP掉相关地方后,就算线程被设置为T hreadHideFromDebugger也无法阻挡调试器接收调试信息。

read系统调用流程

Read 系统调用在用户空间中的处理过程 Linux 系统调用(SCI,system call interface)的实现机制实际上是一个多路汇聚以及分解的过程,该汇聚点就是 0x80 中断这个入口点(X86 系统结构)。也就是说,所有系统调用都从用户空间中汇聚到 0x80 中断点,同时保存具体的系统调用号。当 0x80 中断处理程序运行时,将根据系统调用号对不同的系统调用分别处理(调用不同的内核函数处理)。系统调用的更多内容,请参见参考资料。 Read 系统调用也不例外,当调用发生时,库函数在保存 read 系统调用号以及参数后,陷入 0x80 中断。这时库函数工作结束。Read 系统调用在用户空间中的处理也就完成了。 回页首 Read 系统调用在核心空间中的处理过程 0x80 中断处理程序接管执行后,先检察其系统调用号,然后根据系统调用号查找系统调用表,并从系统调用表中得到处理 read 系统调用的内核函数 sys_read ,最后传递参数并运行 sys_read 函数。至此,内核真正开始处理 read 系统调用(sys_read 是 read 系统调用的内核入口)。 在讲解 read 系统调用在核心空间中的处理部分中,首先介绍了内核处理磁盘请求的层次模型,然后再按该层次模型从上到下的顺序依次介绍磁盘读请求在各层的处理过程。 Read 系统调用在核心空间中处理的层次模型 图1显示了 read 系统调用在核心空间中所要经历的层次模型。从图中看出:对于磁盘的一次读请求,首先经过虚拟文件系统层(vfs layer),其次是具体的文件系统层(例如 ext2),接下来是 cache 层(page cache 层)、通用块层(generic block layer)、IO 调度层(I/O scheduler layer)、块设备驱动层(block device driver layer),最后是物理块设备层(block device layer)

第六章 远程服务调用和Service Locator

第六章远程服务调用和Service Locator 1.什么是Websharp Service Locator 当今大部分的企业应用都是分布式的,单机版的软件虽然仍旧有很多,但是,在考虑一个完整的应用软件系统框架的时候,总是需要考虑完整的情况。多层分布式应用软件的开发原则和技术通常也是适用于单机版软件的。 对于多层的应用系统来说,我们通常把它们划分成客户端、应用服务层和数据库。在应用服务层,我们需要考虑至少两个方面的问题: ?如何实现业务逻辑 ?如何向客户端提供服务。 我们可能使用多种技术来实现服务的提供:Webservice、.Net Remoting、甚至EJB等。如此多的实现技术,带来的很大的灵活性,但同时也带来了文题,其中一个就是,有多少种服务端技术,就得有多少种相应的客户端访问技术。甚至,在某些分布式应用系统中,应用逻辑使用不同的技术开发,存在于不同的机器上,有的存在于客户机本机,有的使用.Net Remoting开发,存在于局域网内,有的使用因特网上的Web Service,有的时候,我们希望相同的业务逻辑能够支持不同的客户端。 在这种情况下,我们需要一个一致的服务访问编程模型,以统合不同的服务访问模式,简化系统的开发和部署。Websharp Service Locator(以下简称WSL)提供了这样一种能力,开发人员只需要定义服务访问接口,就可以使用一致的方式透明的访问这些服务,而不用理会这些服务之间的不同点。框架会自动生成访问远程服务需要的代理。 下面简单介绍一下.Net环境下的两种主要分布式访问技术: 2.Web Service Web Service便是基于网络的、分布式的模块化组件,它执行特定的任务,遵守具体的技术规范,这些规范使得Web Service能与其他兼容的组件进行互操作。它可以使用标准的互联网协议,像超文本传输协议HTTP和XML,将功能体现在互联网和企业内部网上。Web Service平台是一套标准,它定义了应用程序如何在Web上实现互操作性。可以使用任何语言,在任何平台上写Web Service。 Web Service平台需要一套协议来实现分布式应用程序的创建。任何平台都有它的数据表示方法和类型系统。要实现互操作性,Web Service平台必须提供一套标准的类型系统,用于沟通不同平台、编程语言和组件模型中的不同类型系统。目前这些协议有: 1.XML和XSD 可扩展的标记语言XML是Web Service平台中表示数据的基本格式。除了易于建立和易于分析外,XML主要的优点在于它既与平台无关,又与厂商无关。XML是由万维网协会(W3C)创建,W3C制定的XML SchemaXSD定义了一套标准的数据类型,并给出了一种语言来扩展这套数据类型。 Web Service平台是用XSD来作为数据类型系统的。当你用某种语言如https://www.360docs.net/doc/7310645256.html,或C#来构造一个Web Service时,为了符合Web Service标准,所有你使用的数据类型都必须被转换为XSD类型。如想让它使用在不同平台和不同软件的不同组织间传递,还需要用某种东西将它包装起来。这种东西就是一种协

操作系统实验一 系统调用

huixing操作系统实验一 姓名:廖桉冬学号:09012431 日期:15/3/27 实验内容: 使用系统调用,用C或C++写一个程序,实现如下功能:从一个文件中读出数据,写入另一个文件中。 实验要求: 具有良好的交互性 使用者可输入源文件和目的文件的路径和文件名。 具有完善的错误处理机制 针对可能出现的各种错误,要有相应的错误提示输出,并作相应处理。 在Windows和Linux操作系统上调试并运行 实验目的: 通过实验,加深对系统调用概念的理解,了解其实现机制以及使用方式。 通过在Linux操作系统上编写和调试简单程序,进一步熟悉Linux操作系统的使用,初步掌握linux环境下的C或C++编译和调试工具,为进一步理解和学习Linux操作系统的内核结构和核心机制作准备。 设计思路和流程图 读入源文件/目标文件名-->打开文件流-(打开是否正常)->将源文件字符流读出暂存-->将字符流输出到目标文件; 主要数据结构及其说明 string:暂存文件名 ifstream/ofstream:文件流输入输出 a:字符暂存 源程序并附上注释 #include #include #include using namespace std; int main() { //读取文件名 string infile; string outfile; cout<<"输入你想要读取的文件名/(路径) :"<

cin>>infile; cout<<"输入你想要写入的文件名/(路径) :"<>outfile; //打开文件流 ifstream f_in(infile.c_str()); ofstream f_out(outfile.c_str(),ios::app); if(!f_in) { cout<<"源文件不存在."<>a; f_out<

系统调用方式文件编程题库

Linux文件编程函数 一简述几个基本知识—— 1 Linux应用程序编程所用到的函数,主要有两种方式提供: 系统调用方式函数库方式 2 如何学习这些函数? 三步学习法: 第一步:借助工具书,查找函数名;《Unix环境高级编程》第二步:在Linux系统中,利用man命令查看函数信息,并填写函数学习手册。 第三步:实践,编写代码。 3 VI概念——文件描述符 性质:一个数字 特别含义:其功能类似于身份证号码,通过身份证号码,可以将对应的公民;在Linux系统中,每一个打开的文件,都对应一个数字,通过这个唯一的数字,可以找到这个打开的文件,并对其进行操作,比如读、写等。 二首先学习系统调用方式提供的函数—— 4 学习以下7个函数—— 打开文件创建文件关闭文件读文件写文件文件定位 复制文件描述符 5 打开文件——open 范例1:打开已经存的文件 open.c

#include #include #include void main() { int fd;/*文件描述符*/ fd = open("/home/test.c",O_RDWR); if(fd<0) printf("Open file fali!\n"); else printf("Open file sucessfully!\n"); } 范例2:利用open函数创建新文件 open_creat.c #include #include #include void main() {

linux添加系统调用实验步骤

首先,进入到内核源码目录/usr/src/linux-2.6.34中,添加自己的系统调用号。 lyh@lyh:~$ cd /usr/src/linux-2.6.34/ 系统调用号在unistd_32.h文件中定义。内核中每个系统调用号都是 以“__NR_"开头的,在该文件中添加自己的系统调用号 lyh@lyh:/usr/src/linux-2.6.34$ sudo vim arch/x86/include/asm/unistd_32.h #define __NR_pwritev 334 #define __NR_rt_tgsigqueueinfo 335 #define __NR_perf_event_open 336 #define __NR_recvmmsg 337 #define __NR_mycall 338 #ifdef __KERNEL__ #define NR_syscalls 339 在内核源文件中该行为#define NR_syscalls 338,在系统调用执行的过程中,system_call()函数会根据该值来对用户态进程的有效性进行检查。如果这个号大于或等于NR_syscalls,系统调用处理程序终止。所以应该将原来的#define NR_syscalls 338修改为#define NR_syscalls 339 其次,在系统调用表中添加相应的表项 (1)lyh@lyh:/usr/src/linux-2.6.34$ sudo vim arch/x86/kernel/syscall_table_32.S ENTRY(sys_call_table) .long sys_restart_syscall .long sys_exit ………………(这里省略了部分) .long sys_rt_tgsigqueueinfo .long sys_perf_event_open .long sys_recvmmsg .long sys_mycall (2)lyh@lyh:/usr/src/linux-2.6.34$ sudo vim arch/h8300/kernel/syscalls.S #include #include

添加系统调用实验报告

一、构建基本的实验环境 1.1基本实验环境与前提条件 Windows7 、Word 2010、Vmware WorkStation 8.5、AdobeReader ReadHatLinux 9.0,gcc,vi Linux内核[V2.4.18] 1.2虚拟机的安装及使用 1.3将Linux 内核源代码及配置文件传送给虚拟机上的Red Hat Linux V9.0 系统 配置网络时遇到这个问题, Determining IP information for eth0... failed; no link present. Check cable? 通过查找资料发现是系统的Bug, 解决方法如下: 到/etc/sysconfig/network-scripts/ifcfg-eth0 在文件最后一行中加入 check_link_down () { return 1; } 另外如果存在/etc/sysconfig/networking/profiles/default/ifcfg-eth0 文件,则同样在其中加入这一段东西即可,然后重启系统。 设置网络为DHCP,重新启动就可以,啦,直接上图

最后将内核代码下载到/root目录下 二、Linux 内核编译、配置与调试 2.1 内核配置与编译 2.1.1、解压内核源代码文件 tar -zxf linux-2.4.18.tar.gz 2.1.2、解压后如下

2.1.3、拷贝linux,命名为linux-2.4.18 cp -r linux linux-2.4.18 2.1.4、移动config-2.4.18forMP.txt到linux-2.4.18根目录,替换掉.config 2.1.5、进入linux-2.4.18目录,配置和编译内核模块 make oldconfig make dep

远程调用的几种方式

远程调用的几种方式 在分布式服务框架中,一个最基础的问题就是远程服务是怎么通讯的,在Java领域中有很多可实现远程通讯的技术,例如:RMI、MINA、ESB、Burlap、Hessian、SOAP、EJB 和JMS 等,这些名词之间到底是些什么关系呢,它们背后到底是基于什么原理实现的呢,了解这些是实现分布式服务框架的基础知识,而如果在性能上有高的要求的话,那深入了解这些技术背后的机制就是必须的了,在这篇blog中我们将来一探究竟,抛砖引玉,欢迎大家提供更多的实现远程通讯的技术和原理的介绍。 基本原理 要实现网络机器间的通讯,首先得来看看计算机系统网络通信的基本原理,在底层层面去看,网络通信需要做的就是将流从一台计算机传输到另外一台计算机,基于传输协议和网络IO 来实现,其中传输协议有tcp、udp等等,tcp、udp都是在基于Socket概念上为某类应用场景而扩展出的传输协议,网络IO,主要有bio、nio、aio三种方式,所有的分布式应用通讯都基于这个原理而实现,只是为了应用的易用,各种语言通常都会提供一些更为贴近应用易用的应用层协议。 应用级协议 远程服务通讯,需要达到的目标是在一台计算机发起请求,另外一台机器在接收到请求后进行相应的处理并将结果返回给请求端,这其中又会有诸如one way request、同步请求、异步请求等等请求方式,按照网络通信原理,需要实现这个需要做的就是将请求转换成流,通过传输协议传输至远端,远端计算机在接收到请求的流后进行处理,处理完毕后将结果转化为流,并通过传输协议返回给调用端。 原理是这样的,但为了应用的方便,业界推出了很多基于此原理之上的应用级的协议,使得大家可以不用去直接操作这么底层的东西,通常应用级的远程通信协议会提供: 1. 为了避免直接做流操作这么麻烦,提供一种更加易用或贴合语言的标准传输格式; 2. 网络通信机制的实现,就是替你完成了将传输格式转化为流,通过某种传输协议传输至远端计算机,远端计算机在接收到流后转化为传输格式,并进行存储或以某种方式通知远端计算机。 所以在学习应用级的远程通信协议时,我们可以带着这几个问题进行学习: 1. 传输的标准格式是什么? 2. 怎么样将请求转化为传输的流? 3. 怎么接收和处理流? 4. 传输协议是? 不过应用级的远程通信协议并不会在传输协议上做什么多大的改进,主要是在流操作方面,让应用层生成流和处理流的这个过程更加的贴合所使用的语言或标准,至于传输协议则通常都是可选的,在java领域中知名的有:RMI、XML-RPC、Binary-RPC、SOAP、CORBA、JMS,来具体的看看这些远程通信的应用级协议:

操作系统教程第版课后答案

操作系统教程第5版课后答案 费祥林、骆斌编着 第一章操作系统概论 习题一 一、思考题 1.简述现代计算机系统的组成及层次结构。 答:现代计算机系统由硬件和软件两个部分组成。是硬件和软件相互交织形成的集合体,构成一个解决计算问题的工具。硬件层提供基本可计算的资源,包括处理器、寄存器、内存、外存及I/O设备。软件层由包括系统软件、支撑软件和应用软件。其中系统软件是最靠近硬件的。 2、计算机系统的资源可分成哪几类?试举例说明。 答:包括两大类,硬件资源和信息资源。硬件资源分为处理器、I/O设备、存储器等;信息资源分为程序和数据等。 3.什么是操作系统?操作系统在计算机系统中的主要作用是什么? 答:操作系统是一组控制和管理计算机硬件和软件资源,合理地对各类作业进行调度,以及方便用户使用的程序的集合。 操作系统在计算机系统中主要起4个方面的作用。 (1)服务用户观点——操作系统提供用户接口和公共服务程序 (2)进程交互观点——操作系统是进程执行的控制者和协调者 (3)系统实现观点——操作系统作为扩展机或虚拟机 (4)资源管理观点——操作系统作为资源的管理者和控制者 4.操作系统如何实现计算与操作过程的自动化? 答:大致可以把操作系统分为以下几类:批处理操作系统、分时操作系统、实时操作系统、网络操作系统和分布式操作系统。其中批处理操作系统能按照用户预先规定好的步骤控制作业的执行,实现计算机操作的自动化。又可分为批处理单道系统和批处理多道系统。单道系统每次只有一个作业装入计算机系统的主存储器运行,多个作业可自动、顺序地被装入运行。批处理多道系统则允许多个作业同时装入主存储器,中央处理器轮流地执行各个作业,各个作业可以同时使用各自所需的外围设备,这样可以充分利用计算机系统的资源,缩短作业时间,提高系统的吞吐率 5.操作系统要为用户提供哪些基本的和共性的服务? 答:(1)创建程序和执行程序;(2)数据I/O和信息存取;(3)通信服务;(4)差错检测和处理。为了保证高效率、高质量的工作,使得多个应用程序能够有效的共享系统资源,提高系统效率,操作系统还具备一些其他的功能:资源分配,统计,保护等。 6.试述操作系统所提供的各种用户接口。 答:操作系统通过程序接口和操作接口将其服务和功能提供给用户。程序接口由一组系统调用组成,在应用程序中使用“系统调用”可获得操作系统的低层服务,访问或使用系统管理的各种软硬件资源,是操作系统对外提供服务和功能

SQL Server服务远程过程调用失败解决

Sql Server服务远程过程调用失败解决 Sql Server服务远程过程调用失败解决 问题: 今天SQL数据库登录不上,提示以下错误: 启动SQL Server配置管理器,发现如下问题(配置环境:win7旗舰版x64,SqlServer2008R2,同时安装VS2012):

以前出现过这个问题,那时候是因为把实例安装在了D盘,后来D盘被格式化了。然后,这些就没了。今天早上打开电脑,竟然又出现这个问题,可是Server2008R2全部装在C盘了呢。 解决方法: 最后查找解决方法,发现故障原因为:安装Visual Studio 2012的时候,自动安装“Microsoft SQL Server 2012 Express LocalDB”服务,导致原本的SQL2008无法正常工作。那么解决方法如下: ①方法一: 打开控制面板,找到程序->卸载程序,把”Microsoft SQL Server 2012 Express LocalDB”卸载掉,然后打开SQL Server 配置管理器,显示一切正常就OK了。 但我的VS2012已经安装半个多月了,怎么今天才出现这个问题? ②方法二: 升级SqlServer2008R2为SP1或者SP2。 但是现在急用,我的实例还在,只是没有启动而已,就尝试如下方法: 右击“计算机”→“管理”→“服务”,找到SQL Server(MSSQLSERVER),右击,选择“启动”。 再登录数据库,没有问题了。但是重新启动系统后,问题会依旧的。 总结:

想要永久解决该问题还得用上面的方法。为防万一,最好进去把自己的数据库备份出来,或者创建一个系统还原点,然后再去尝试。总的来说,上面的两种方法原因都是因为微软的兼容性问题,或者卸载新的回去旧版本,或者升级成为新版本。所以,本人已经通过第二种方法,完美实现正常。

Java远程方法调用

font size="3">概述 Java Remote Method Invocation ( RMI -- Java远程方法调用)允许您使用Java编写分布式对象。本文将介绍RMI的优点以及如何将其连接到现有的和原有的系统中,以及与用Java 编写的组件的连接。 RMI为采用Java对象的分布式计算提供了简单而直接的途径。这些对象可以是新的Java对象,也可以是围绕现有API的简单的Java 包装程序。Java体现了“编写一次就能在任何地方运行的模式。而RMI 可将Java模式进行扩展,使之可在任何地方运行”。 因为RMI是以Java为核心的,所以,它将Java的安全性和可移植性等强大功能带给了分布式计算。您可将代理和梢?务逻辑等属性移动到网络中最合适的地方。如果您要扩展Java在系统中的使用,RMI将使您充分利用其强大功能。 RMI可利用标准Java本机方法接口JNI与现有的和原有的系统相连接。RMI还可利用标准JDBC包与现有的关系数据库连接。RMI/JNI 和RMI/JDBC相结合,可帮助您利用RMI与目前使用非Java语言的现有服务器进行通信,而且在您需要时可扩展Java在这些服务器上的使用。RMI可帮助您在扩展使用时充分利用Java的强大功能。

优点 从最基本的角度看,RMI是Java的远程过程调用(RPC)机制。与传统的RPC系统相比,RMI具有若干优点,因为它是Java面向对象方法的一部分。传统的RPC系统采用中性语言,所以是最普通的系统--它们不能提供所有可能的目标平台所具有的功能。 RMI以Java为核心,可与采用本机方法与现有系统相连接。这就是说,RMI可采用自然、直接和功能全面的方式为您提供分布式计算技术,而这种技术可帮助您以不断递增和无缝的方式为整个系统添加Java功能。 RMI的主要优点如下: 面向对象:RMI可将完整的对象作为参数和返回值进行传递,而不仅仅是预定义的数据类型。也就是说,您可以将类似Java哈希表这样的复杂类型作为一个参数进行传递。而在目前的RPC系统中,您只能依靠客户机将此类对象分解成基本数据类型,然后传递这些数据类型,最后在服务器端重新创建哈希表。RMI则不需额外的客户程序代码(将对象分解成基本数据类型),直接跨网传递对象。 可移动属性:RMI可将属性(类实现程序)从客户机移动到服务器,或者从服务器移到客户机。例如,您可以定义一个检查雇员开支报告

Linux 系统调用实现机制实验报告-内核安装详解

Linux系统调用实现机制实验报告 实验目的: 熟悉Linux系统调用过程,掌握系统调用的基本原理并在实验中实现系统调用的添加。 实验所需软件: 实验平台:VMware WorkStation; 系统环境:Red Hat Linux9.0; 传输工具:Ftp server(Serv USetup); 实验过程: 一、实验环境的搭建 (一)在Window下安装虚拟机VMware WorkStation; (二)在虚拟机上安装Red Hat 9.0系统; (三)在Window下安装Ftp Server,实现Linux与windows文件共享。 1. Ftp服务器的配置 打开Ftp Server,在[管理控制台]中选择[新建域],系统会弹出配置域向导的对话框,这里按要求填入相应信息,即可配置成功一个ftp服务器。步骤1要求用户填入域的[名称]和[说明],[名称]必须填写,[说明]可以不填。例如:在名称中输入[Linux实验],选择[下一步],便进入到域向导的步骤2。 步骤2是服务器访问协议和端口的配置,默认即可,点击[下一步]进入步骤3。步骤3是IP地址的配置,输入Windows主机的IP地址(202.112.147.176)。 确认无误后,点击[完成]。接下来要做的就是为域添加用户,根据添加用户向导,逐个填写[用户名],[密码],[根目录(即共享的文件目录)]以及[访问权限]。本次实验的配置为:tml(用户名),密码为空,E:\安全操作系统\实验材料(存放config-2.4.18forMP.txt和linux-2.4.18.tar.gz的目录),完全访问(访问权限)。到此,服务器的配置已经完成。 2. 在Linux下访问服务器,并下载文件

linux0.11系统调用原理及实验总结

Linux0.11系统调用原理及实验总结 1系统调用的原理 1.1概述 系统调用是一个软中断,中断号是0x80,它是上层应用程序与Linux系统内核进行交互通信的唯一接口。通过int 0x80,就可使用内核资源。不过,通常应用程序都是使用具有标准接口定义的C函数库间接的使用内核的系统调用,即应用程序调用C函数库中的函数,C函数库中再通过int 0x80进行系统调用。 所以,系统调用过程是这样的: 应用程序调用libc中的函数->libc中的函数引用系统调用宏->系统调用宏中使用int 0x80完成系统调用并返回。 另外一种访问内核的方式是直接添加一个系统调用,供自己的应用程序使用,这样就不再使用库函数了,变得更为直接,效率也会更高。 1.2相关的数据结构 在说具体的调用过程之前,这里先要说几个数据结构。 1.2.1 系统调用函数表 系统调用函数表sys_call_table是在sys.h中定义的,它是一个函数指针数组,每个元素是一个函数指针,它的值是各个系统提供的供上层调用的系统函数的入口地址。也就是说通过查询这个表就可以调用软中断0x80所有的系统函数处理函数。 1.2.2 函数指针偏移宏 这是一系列宏,它们的定义在unistd.h中,基本形式为#define _NR_name value,name为系统函数名字,value是一个整数值,是name所对应的系统函数指针在sys_call_table中的偏移量。 1.2.3 系统调用宏 系统调用宏_syscalln(type,name)在内核的unistd.h文件中定义的,对它展开就是: type name(参数列表) { 调用过程; }; 其中,n为参数个数,type为函数返回值类型,name为所要调用的系统函数的名字。在unistd.h 中共定义了4个这样的宏(n从0到3),也就是说,0.11核中系统调用最多可带3个参数。

linux系统调用

2002 年 3 月 01 日 本文列出了大部分常见的Linux系统调用,并附有简要中文说明。 以下是Linux系统调用的一个列表,包含了大部分常用系统调用和由系统调用派生出的的函数。这可能是你在互联网上所能看到的唯一一篇中文注释的Linux系统调用列表,即使是简单的字母序英文列表,能做到这么完全也是很罕见的。 按照惯例,这个列表以man pages第2节,即系统调用节为蓝本。按照笔者的理解,对其作了大致的分类,同时也作了一些小小的修改,删去了几个仅供内核使用,不允许用户调用的系统调用,对个别本人稍觉不妥的地方作了一些小的修改,并对所有列出的系统调用附上简要注释。 其中有一些函数的作用完全相同,只是参数不同。(可能很多熟悉C++朋友马上就能联想起函数重载,但是别忘了Linux核心是用C语言写的,所以只能取成不同的函数名)。还有一些函数已经过时,被新的更好的函数所代替了(gcc在链接这些函数时会发出警告),但因为兼容的原因还保留着,这些函数我会在前面标上“*”号以示区别。 一、进程控制: fork 创建一个新进程 clone 按指定条件创建子进程 execve 运行可执行文件 exit 中止进程 _exit 立即中止当前进程 getdtablesize 进程所能打开的最大文件数 getpgid 获取指定进程组标识号 setpgid 设置指定进程组标志号 getpgrp 获取当前进程组标识号 setpgrp 设置当前进程组标志号 getpid 获取进程标识号 getppid 获取父进程标识号 getpriority 获取调度优先级 setpriority 设置调度优先级 modify_ldt 读写进程的本地描述表 nanosleep 使进程睡眠指定的时间 nice 改变分时进程的优先级 pause 挂起进程,等待信号 personality 设置进程运行域 prctl 对进程进行特定操作 ptrace 进程跟踪 sched_get_priority 取得静态优先级的上限 _max sched_get_priority 取得静态优先级的下限 _min sched_getparam 取得进程的调度参数 sched_getscheduler 取得指定进程的调度策略 sched_rr_get_inter 取得按RR算法调度的实时进程的时间片长度 val sched_setparam 设置进程的调度参数 sched_setscheduler 设置指定进程的调度策略和参数

实习一远程过程调用中间件及数据访问中间件

实验一远程过程调用中间件及数据访问中间件 一、实习目的 通过实例掌握RMI,RPC,JDBC等中间件的使用。 二、实习要求 1)RPC实现远程计算服务。服务器端提供计算服务;客户端调用计算服务。 2)RMI+JDBC远端数据库的访问。实现简单的成绩查询系统(创建表,录入成绩,查询成绩等)。在服务器端,通过JDBC访问数据库。客户端调用服务端提供的各种数据库操作。 3)服务器和客户端不在同的机器上进行测试。 4)打包成易于执行的文件,如exe, bat文件。 三、实习过程 1 利用RPC实现远程计算服务。 (1)使用IDL定义服务接口mathservice.idl, 定义计算服务操作,方法如下: 加:void Cal_Add([in] double a, [in] double b, [out] double * result); 减:void Cal_Sub([in] double a, [in] double b, [out] double * result); 乘:void Cal_Mul([in] double a, [in] double b, [out] double * result); 除:void Cal_Div([in] double a, [in] double b, [out] double * result); (2)编写配置文件mathservice.acf, 定义绑定句柄 (3) 编译mathservice.idl文件,产生文件mathservice.h, mathservice_s.c, mathservice_c.c (4) 编写服务端程序, 编译连接工程,生成mathservice.exe (5) 编写客户端程序 (6) 测试: 测试结果截图如下: 加法运算:

用Java实现SOAP的XML文档网络传输及远程过程调用RPC

用Java实现基于SOAP的XML文档网络传输及远程过程调用(RPC) SOAP(Simple Object Access Protocol,简单对象访问协议) 是一种基于XML的,用于计算机之间交换信息的协议。SOAP能应用于各种消息接发系统,并能通过各种传输协议进行消息传递,但最初的侧重点是通过HTTP传输的远程过程调用。SOAP是Web service的一个重要组成部份,如果把Web service比喻成Internet,那么SOAP就可以比喻成TCP/IP。SOAP是一种协议而非具体产品,微软也有自己的SOAP实现产品,而Java下比较流行的SOAP实现产品就是Apache SOAP,不过它的下一个版本已经改名成AXIS了。 SOAP是用XML文件来做为数据转输的载体的,走HTTP的线路。一般企业的防火墙都开放HTTP的80端口,所以SOAP不会被防火墙阻断,这算是SOAP的一个优点。信息转输的双方都要求支持SOAP服务,因为XML文件发过去,则对方需要有SOAP服务来接收,然后对方会有反馈也是XML文件,这时你也需要安装SOAP服务来接收。 1. 环境配置 为了运行程序,我们首先必须配置好环境: 共要下载四个软件包,它们都是开源免费的。其中,前两个是Apache的,后两个是SUN 网站的,如下所示: ?SOAP:2.3.1/ ?Xerces: ?JavaMail: ?JAF: 下载后将它们分别解压缩。分别在这四个包的解压目录中找到:xerces.jar、soap.jar、mail.jar、activation.jar(JAF的),则是四个jar文件是我们所需要的。 本机安装环境:WindowsXP(SP2) + JDK1.4.2_06 + Tomcat5.0.28 + SOAP2.3.1 配置步骤: 1、安装JDK和Tomcat。过程比较简单,这里不再详述。 2、将刚才所找到的四个jar文件复制到Tomcat的“Tomcat 5.0\common\lib”目录下, 这个目录是Tomcat的默认包目录,在这个目录中的所有包在Tomcat启动时都会 被自动加载。 3、将\ JDK1.4.2\lib\路径下的tools.jar也复制到Tomcat的“Tomcat 5.0\common\lib”目录下。

(1)-系统调用篇

Windows的地址空间分用户模式与内核模式,低2GB的部分叫用户模式,高2G的部分叫内核模式,位于用户空间的代码不能访问内核空间,位于内核空间的代码却可以访问用户空间 一个线程的运行状态分内核态与用户态,当指令位于用户空间时,就表示当前处于内核态,当指令位于内核空间时,就处于内核态. 一个线程由用户态进入内核态的途径有3种典型的方式: 1、主动通过int 2e(软中断自陷方式)或sysenter指令(快速系统调用方式)调用系统服务函数,主 动进入内核 2、发生异常,被迫进入内核 3、发生硬件中断,被迫进入内核 现在讨论第一种进入内核的方式:(又分为两种方式) 1、通过老式的int 2e指令方式调用系统服务(因为老式cpu没提供sysenter指令) 如ReadFile函数调用系统服务函数NtReadFile Kernel32.ReadFile() //点号前面表示该函数的所在模块 { //所有Win32 API通过NTDLL中的系统服务存根函数调用系统服务进入内核 NTDLL.NtReadFile(); } NTDLL.NtReadFile() { Mov eax,152 //我们要调用的系统服务函数号,也即SSDT表中的索引,记录在eax中 If(cpu不支持sysenter指令) { Lea edx,[esp+4] //用户空间中的参数区基地址,记录在edx中 Int 2e //通过该自陷指令方式进入KiSystemService,‘调用’对应的系统服务 } Else { Lea edx,[esp +4] //用户空间中的参数区基地址,记录在edx中 Sysenter //通过sysenter方式进入KiFastCallEntry,‘调用’对应的系统服务 } Ret 36 //不管是从int 2e方式还是sysenter方式,系统调用都会返回到此条指令处 } Int 2e的内部实现原理: 该指令是一条自陷指令,执行该条指令后,cpu会自动将当前线程的当前栈切换为本线程的内核栈(栈分用户栈、内核栈),保存中断现场,也即那5个寄存器。然后从该cpu的中断描述符表(简称IDT)中找到这个2e中断号对应的函数(也即中断服务例程,简称ISR),jmp 到对应的isr处继续执行,此时这个ISR 本身就处于内核空间了,当前线程就进入内核空间了 Int 2e指令可以把它理解为intel提供的一个内部函数,它内部所做的工作如下 Int 2e { Cli //cpu一中断,立马自动关中断 Mov esp, TSS.内核栈地址 //切换为内核栈,TSS中记录了当前线程的内核栈地址 Push SS

二.掌握系统调用的实现过程,通过编译内核方法,增加一个新

二.掌握系统调用的实现过程,通过编译内核方法,增加一个新的系统调用。另编写一个应用程序,调用新增加的系统调用。 (1) 实现的功能是:文件拷贝; 操作步骤: 1。先在/usr/src/linux-2.4.18-3/kernel/sys.c文件末尾添加mycopy_s.c里的代码。 2。修改文件 /usr/src/linux-2.4.18-3/include/asm-i386/unistd.h文件在文件中相应位置加上: #define __NR_mycopy 239 3.修改文件 /usr/src/linux-2. 4.18-3/arch/i386/kernel/entry.S文件 在文件中相应位置加上: .long SYMBOL_NAME(sys_mycopy) 编译内核:(过程中要先后使用的命令如下,其中后两步操作为非必要,若不执行,则新内核下某些系统功能将无法实现) make mrproper make oldconfig make dep make clean make bzImage make modules make modules_install maek install 这几步均成功完成后,新内核已经生成,执行如下步骤: cp /usr/src/linux-2.4.18-3/arch/i386/boot/bzImage /boot/bzImage-new cp /usr/src/linux-2.4.18-3/System.map /boot/System.map-new ln –sf /boot/System.map-new /boot/System.map 然后进入 /etc/lilo.conf(本机采用Lilo配置),添加如下代码: image=/boot/bzImage-new label=linux-new root=/dev/hda1 /* hda1为安装linux的分区 */ 然后进入 /sbin,运行lilo,完成配置。 重启系统后选择标签为linux-new的新内核进入。 在新内核下测试系统调用,其运行结果如下: [YAKUZA$root] ls copy.c test.c [YAKUZA$root] gcc mycopy_test.c –o mycopy_test [YAKUZA$root] ls mycopy_test mycopy_test.c test.c [YAKUZA$root] cat test.c #include main()

windows系统调用

Windows系统调用浅析 默认分类2009-11-05 17:39:15 阅读390 评论0 字号:大中小订阅 网上关于Linux系统调用的资料很多了,介绍都很详细。而最近需要了解下Windows系统调用,发现Windows的系统调用机制比Linux的复杂很多,可能是初次接触比较陌生的缘故。我在此只是进行简单的分析,基本上都是查看别人的资料,再加上自己的理解。(说明:毛得操老师写的关于《Windows内核源码情景分析》是本很好的参考资料,建议大家有兴趣的看看)X86体系结构提供了4个特权级(r ing 0, 1, 2, 3),W indows只使用了其中的2个特权级,分别是r ing 0(内核空间),ring 3(用户空间)。在默认情况下,Windows将低2GB的地址空间。 与进程相关的结构主要包括进程块(EPROCESS)、进程环境块(PEB)、线程块(ETHREAD)、线程环境块(TEB),它们之间的关系如下图: (1)进程块(EPROCESS):每个W indows进程通过进程块来描述,其中包含于进程相关的属性,同时还指向其他的数据结构。 (2)进程环境块(PEB):存放进程信息,每个进程都有自己的PEB信息。位于用户地址空间。在Win 2000下,进程环境块的地址对于每个进程来说是固定的,在0x7FFDF000处,这是用户地址空间,所以程序能够直接访问。准确的PEB

在进行系统调用之前,EAX中保存系统调用服务ID,而EDX中保存了调用参数的堆栈指针,然后引发IN T 2Eh中断。 (1)Windows 2000中的系统调用执行过程: ServiceId:请求的中断服务ID ParameterTable:中断服务对应的参数 ParamTableBytes:参数个数信息 添加Hook的过程:先在系统中找到ID T,然后确定2Eh在ID T中的地址,最后将用户定义的函数地址去取代它。当用户态进程一旦调用系统服务就会触发Hook函数。

read系统调用流程

Read 系统调用在用户空间中得处理过程 Linux 系统调用(SCI,system call interface)得实现机制实际上就是一个多路汇聚以及分解得过程,该汇聚点就就是 0x80 中断这个入口点(X86 系统结构)。也就就是说,所有系统调用都从用户空间中汇聚到 0x80 中断点,同时保存具体得系统调用号。当 0x80 中断处理程序运行时,将根据系统调用号对不同得系统调用分别处理(调用不同得内核函数处理)。系统调用得更多内容,请参见参考资料。 Read 系统调用也不例外,当调用发生时,库函数在保存 read 系统调用号以及参数后,陷入 0x80 中断。这时库函数工作结束。Read 系统调用在用户空间中得处理也就完成了。 回页首 Read 系统调用在核心空间中得处理过程 0x80 中断处理程序接管执行后,先检察其系统调用号,然后根据系统调用号查找系统调用表,并从系统调用表中得到处理 read 系统调用得内核函数 sys_read ,最后传递参数并运行 sys_read 函数。至此,内核真正开始处理 read 系统调用(sys_read 就是 read 系统调用得内核入口)。 在讲解 read 系统调用在核心空间中得处理部分中,首先介绍了内核处理磁盘请求得层次模型,然后再按该层次模型从上到下得顺序依次介绍磁盘读请求在各层得处理过程。 Read 系统调用在核心空间中处理得层次模型 图1显示了 read 系统调用在核心空间中所要经历得层次模型。从图中瞧出:对于磁盘得一次读请求,首先经过虚拟文件系统层(vfs layer),其次就是具体得文件系统层(例如 ext2),接下来就是 cache 层(page cache 层)、通用块层(generic block layer)、IO 调度层(I/O scheduler layer)、块设备驱动层(block device driver layer),最后就是物理块设备层(block device layer)

RMI远程方法调用

Java RMI 技术原理(远程方法调用)Java RMI指的是远程方法调用。它是一种机制,能够让在某个Java虚拟机上的对象调用另一个Java虚拟机中的对象上的方法。可以用此方法调用的任何对象必须实现该远程接口。 Java RMI不是什么新技术(JDK1.1就有了),但却是是非常重要的底层技术。大名鼎鼎的EJB都是建立在RMI基础之上的,现在还有一些开源的远程调用组件,其底层技术也是RMI。 在这个大力吹捧Web Service、SOA的年代,不是每个应用都应该选用笨拙的Web Service组件来实现,有人通过对比测试后,认为RMI是最简单的,在一些小的应用中是最合适的。在Java中,只要一个类extends了 java.rmi.Remote接口,即可成为存在于服务器端的远程对象,供客户端访问并提供一定的服务。 注意:extends了Remote接口的类或者其他接口中的方法若是声明抛出了RemoteException异常,则表明该方法可被客户端远程访问调用。 同时,远程对象必须实现java.rmi.server.UniCastRemoteObject类,这样才能保证客户端访问获得远程对象时,该远程对象将会把自身的一个拷贝以Socket的形式传输给客户端,此时客户端所获得的这个拷贝称为“存根stub”,而服务器端本身已存在的远程对象则称之为“骨架skeleton”。其实此时的Stub 是客户端的一个代理,用于与服务器端的通信,而Skeleton也可认为是服务器端的一个代理,用于接收客户端的请求之后调用远程方法来响应客户端的请求。 从客户对象经存根(Stub)、远程引用层(Remote Reference Layer)和传输层(Transport Layer)向下,传递给主机,然后再次经传输层,向上穿过远程

相关文档
最新文档