亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關(guān)于我們
? 蟲蟲下載站

?? 漫談兼容內(nèi)核之十八:windows的lpc機制.txt

?? 漫談系統(tǒng)內(nèi)核內(nèi)幕 收集得很辛苦 呵呵 大家快下在吧
?? TXT
?? 第 1 頁 / 共 4 頁
字號:
漫談兼容內(nèi)核之十八:Windows的LPC機制

毛德操

    LPC是“本地過程調(diào)用(Local Procedure Call)”的縮寫。所謂“本地過程調(diào)用”是與“遠程過程調(diào)用”即RPC相對而言的。其實RPC是廣義的,RPC可以發(fā)生在不同的主機之間,也可以發(fā)生在同一臺主機上,發(fā)生在同一臺主機上就是LPC。所以在Unix語境下就沒有LPC這一說,即使發(fā)生在同一臺主機上也稱為RPC。在歷史上,RPC是“開放軟件基金會(OSF)”設(shè)計和提出的一種用以實現(xiàn)“Unix分布計算環(huán)境(Unix DCE)”的標(biāo)準(zhǔn)。實際上,微軟的DCOM技術(shù),就是建立在RPC基礎(chǔ)上的。Win2000的RPC可以采用TCP/IP、SPX、NetBIOS、命名管道、以及“本地”作為底層的通信手段,這“本地”就是LPC。另一方面,Windows是一個帶有許多微內(nèi)核系統(tǒng)特征的操作系統(tǒng)(盡管它的內(nèi)核不是微內(nèi)核),系統(tǒng)中有不少“系統(tǒng)級”的服務(wù)進程,例如大家已經(jīng)熟知的csrss、管理用戶登錄的“本地安全認(rèn)證服務(wù)”進程LSASS等等,用戶進程以及微軟提供的系統(tǒng)工具軟件經(jīng)常需要調(diào)用由這些服務(wù)進程提供的服務(wù),這里L(fēng)PC就起著重要的作用。
    LPC的基礎(chǔ)是一種稱為“端口(Port)”的進程間通信機制,類似于本地的(Unix域的)Socket。這種Port機制提供了面向報文傳遞(message passing)的進程間通信,而LPC則是建立在這個基礎(chǔ)上的高層機制,目的是提供跨進程的過程調(diào)用。注意這里所謂“跨進程的過程調(diào)用”不同于以前所說的“跨進程操作”。前者是雙方有約定、遵循一定規(guī)程的、有控制的服務(wù)提供,被調(diào)用者在向外提供一些什么服務(wù)、即提供哪些函數(shù)調(diào)用方面是自主的,而后者則可以是在不知不覺之間的被利用、被操縱。前者是良性的,而后者可以是惡性的。
    “Microsoft Windows Internals”書中說LPC是“用于快速報文傳遞的進程間通信機制”。其實這是誤導(dǎo)的,應(yīng)該說Port才是這樣的進程間通信機制,而LPC是建立在這上面的應(yīng)用。然而這種說法已經(jīng)被廣泛接受和采納,都把LPC和Port混淆起來了,所以本文也只好跟著說“Windows的LPC機制”,而實際上要說的則主要是Windows的Port機制。在下面的敘述中,凡說到LPC的地方往往實際上是在說Port,讀者要注意區(qū)分。

    端口是一種面向連接的通信機制,通信的雙方需要先建立起“連接”。這種連接一般建立在用戶進程之間。在建立了連接的雙方之間有幾種交換報文的方法:
? l 不帶數(shù)據(jù)的純報文。
? l 不大于256字節(jié)的短報文。
? l 如果是大于256字節(jié)的長報文,就要在雙方之間建立兩個共享內(nèi)存區(qū)(Section)。雙方通過共享內(nèi)存區(qū)交換數(shù)據(jù),但通過報文進行協(xié)調(diào)和同步。
    大塊數(shù)據(jù)之所以要通過共享內(nèi)存區(qū)交換,一來是因為這樣就為用于Port機制的緩沖區(qū)設(shè)置了一個上限,便于內(nèi)存管理。而更重要的是提高了效率,因為否則便要在發(fā)送端把大塊數(shù)據(jù)搬入內(nèi)核空間,又在接收端把大塊數(shù)據(jù)搬到用戶空間。
    Windows內(nèi)核為基于端口的進程間通信機制提供了不少系統(tǒng)調(diào)用,包括(但并不限于):
[code]? l NtCreatePort()
? l NtCreateWaitablePort()
? l NtListenPort()
? l NtConnectPort()
? l NtAcceptConnectPort()
? l NtCompleteConnectPort()
? l NtRequestPort()
? l NtRequestWaiReplyPort()
? l NtReplyPort()
? l NtReplyWaitReceivePort()
? l NtReplyWaitReceivePortEx()。同上,但是帶有超時控制
? l NtReadRequestData()
? l NtWriteRequestData()
? l NtQueryInformationPort()[/code]

    這么多的系統(tǒng)調(diào)用(由此也可見LPC在Windows操作系統(tǒng)中的份量),當(dāng)然不可能在這里一一加以介紹。本文只是從中揀幾個關(guān)鍵而典型的作些介紹。另一方面,由于Port與Socket的相似性,對于兼容內(nèi)核的開發(fā)而言應(yīng)該比較容易把它嫁接到Socket機制上去。
    值得一提的是,Port在Win32 API界面上是不可見的(實際上甚至LPC也不是直接可見的),而Windows的系統(tǒng)調(diào)用界面又不公開。這說明Port只是供微軟“內(nèi)部使用”的。讀者后面就會看到,Port是一種既包括進程間的數(shù)據(jù)傳輸,又包括進程間的同步、數(shù)據(jù)量又可大可小的綜合性的進程間通信機制。這樣,由微軟自己開發(fā)的軟件、特別是一些系統(tǒng)工具,當(dāng)然可以使用這些系統(tǒng)調(diào)用、也即利用Port這種功能比較強的進程間通信機制,而第三方開發(fā)的軟件可就用不上了。

    端口分“連接端口(connection port)”和“通信端口(communication port)”兩種,各自扮演著不同的角色。連接端口用于連接的建立,通信端口才真正用于雙方的通信。只有服務(wù)進程才需要有連接端口,但是通信雙方都需要有通信端口。
    雖然LPC一般發(fā)生在進程之間,但是實際參與通信的總是具體的線程,所以在下面的敘述中都以線程作為通信的兩端。
    典型的建立連接和通信的過程如下:
? l 需要建立LPC通信時,其中提供服務(wù)的一方、即服務(wù)線程首先要通過NtCreatePort()創(chuàng)建一個命名的連接端口、即Port對象。這個對象名應(yīng)為請求服務(wù)的一方、即客戶線程所知。
? l 建立了上述連接端口以后,服務(wù)線程應(yīng)通過NtListenPort()等待接收來自客戶線程的連接請求(服務(wù)線程被阻塞)。
? l 客戶線程通過NtConnectPort()創(chuàng)建一個客戶方的無名通信端口,并向上述命名的連接端口發(fā)出連接請求(客戶線程被阻塞)。
? l 服務(wù)線程收到連接請求(因而被喚醒)以后,如果同意建立連接就通過NtAcceptConnectPort()創(chuàng)建一個服務(wù)方的無名通信端口、接受連接、并返回該無名通信端口的Handle。然后再通過NtCompleteConnectPort()喚醒客戶線程。
? l 客戶線程被喚醒,并返回所創(chuàng)建的無名通信端口的Handle。
? l 服務(wù)線程另創(chuàng)建一個新的線程,負(fù)責(zé)為客戶線程提供LPC服務(wù)。該線程因企圖從上述通信端口接收報文、等待來自客戶端的服務(wù)請求而被阻塞。所以,新創(chuàng)建的線程時LPC服務(wù)線程,而原來的服務(wù)線程是端口服務(wù)進程。
? l 端口服務(wù)線程再次調(diào)用NtListenPort(),等待來自其它客戶的連接請求。
? l 客戶線程通過NtRequestWaiReplyPort()向?qū)Ψ桨l(fā)送報文,請求得到LPC服務(wù),并因等待回答而被阻塞。
? l 服務(wù)端的相應(yīng)線程、即LPC服務(wù)線程因接收到報文而被喚醒,并根據(jù)報文內(nèi)容提供相應(yīng)的LPC服務(wù)。
? l LPC服務(wù)線程通過NtReplyPort()向客戶方發(fā)送回答報文(一般是計算結(jié)果)。客戶線程解除阻塞。
    如果回顧一下Wine進程與服務(wù)進程wineserver之間的通信,就可以明白Wine是用命名管道和Socket在模仿Windows的LPC通信,只不過那是在用戶空間的模仿。另一方面,熟悉Socket通信的讀者可以看到,Port與Socket是很相像的。

    先看Port的創(chuàng)建。我們看系統(tǒng)調(diào)用NtCreatePort()的代碼:

[code]NTSTATUS STDCALL
NtCreatePort (OUT  PHANDLE            PortHandle,
          IN  POBJECT_ATTRIBUTES    ObjectAttributes,
          IN  ULONG                   MaxConnectInfoLength,
          IN  ULONG                   MaxDataLength,
          IN  ULONG                   MaxPoolUsage)
{
  PEPORT  Port;
  NTSTATUS Status;

  DPRINT("NtCreatePort() Name %x\n", ObjectAttributes->ObjectName->Buffer);

  /* Verify parameters */
  Status = LpcpVerifyCreateParameters (PortHandle, ObjectAttributes,
                     MaxConnectInfoLength, MaxDataLength, MaxPoolUsage);
  . . . . . .

  /* Ask Ob to create the object */
  Status = ObCreateObject (ExGetPreviousMode(), LpcPortObjectType,
               ObjectAttributes, ExGetPreviousMode(),
               NULL, sizeof(EPORT), 0, 0, (PVOID*)&Port);
  . . . . . .

  Status = ObInsertObject ((PVOID)Port, NULL, PORT_ALL_ACCESS,
                                            0, NULL, PortHandle);
  . . . . . .

  Status = LpcpInitializePort (Port, EPORT_TYPE_SERVER_RQST_PORT, NULL);
  Port->MaxConnectInfoLength = PORT_MAX_DATA_LENGTH;
  Port->MaxDataLength = PORT_MAX_MESSAGE_LENGTH;
  Port->MaxPoolUsage = MaxPoolUsage;

  ObDereferenceObject (Port);

  return (Status);
}[/code]

    參數(shù)ObjectAttributes、即OBJECT_ATTRIBUTES結(jié)構(gòu)中有個Unicode字符串,那就是對象名,需要在調(diào)用NtCreatePort()之前加以設(shè)置,這跟創(chuàng)建/打開文件時的文件名設(shè)置是一樣的。當(dāng)然,除對象名以外,ObjectAttributes中還有別的信息,那就不是我們此刻所關(guān)心的了。其余參數(shù)的作用則不言自明。代碼中的LpcpVerifyCreateParameters()對參數(shù)進行合理性檢查,ObCreateObject()和ObInsertObject()就無需多說了,而LpcpInitializePort()主要是對代表著端口的EPORT數(shù)據(jù)結(jié)構(gòu)進行初始化。EPORT數(shù)據(jù)結(jié)構(gòu)的定義如下:

[code]typedef struct _EPORT
{
  KSPIN_LOCK     Lock;
  KSEMAPHORE    Semaphore;
  USHORT          Type;
  USHORT          State;
  struct _EPORT      *RequestPort;
  struct _EPORT      *OtherPort;
  ULONG           QueueLength;
  LIST_ENTRY      QueueListHead;
  ULONG           ConnectQueueLength;
  LIST_ENTRY      ConnectQueueListHead;
  ULONG           MaxDataLength;
  ULONG           MaxConnectInfoLength;
  ULONG           MaxPoolUsage;        /* size of NP zone */
} EPORT, * PEPORT;[/code]

    結(jié)構(gòu)中的QueueListHead就是用來接收報文的隊列。ConnectQueueListHead則是用來緩存連接請求的隊列,這是因為一個Port可能會一下子接收到好幾個連接請求。字段Type用來紀(jì)錄端口的類型,一共有三種類型:

[code]#define EPORT_TYPE_SERVER_RQST_PORT    (0)
#define EPORT_TYPE_SERVER_COMM_PORT   (1)
#define EPORT_TYPE_CLIENT_COMM_PORT   (2)[/code]

    從上面的代碼中可以看出,NtCreatePort()所創(chuàng)建的是“請求端口”,即類型為EPORT_TYPE_SERVER_RQST_PORT的端口,也就是“連接端口”。
    字段state說明端口的狀態(tài)和性質(zhì),例如EPORT_WAIT_FOR_CONNECT、EPORT_CONNECTED_CLIENT等等。
    注意每個EPORT結(jié)構(gòu)中都嵌有一個“信號量”結(jié)構(gòu)Semaphore,這就是通信雙方用來實現(xiàn)同步的手段。所以說,Port是集成了數(shù)據(jù)交換和行為同步的綜合性的進程間通信機制。
    還有個字段OtherPort也值得一說,這是個指針,互相指向已經(jīng)建立了連接的對方端口。
    LpcpInitializePort()的代碼就不看了。只是要說明一下,端口對象的初始化也包括了對其“信號量”數(shù)據(jù)結(jié)構(gòu)的初始化,并且信號量的初值是0,而最大值則為最大整數(shù)LONG_MAX,所以實際上沒有限制。

    創(chuàng)建了連接端口以后,服務(wù)進程就通過NtListenPort()等待連接請求,并因此而被阻塞進入睡眠。

[code]NTSTATUS STDCALL
NtListenPort (IN HANDLE  PortHandle,  IN PLPC_MESSAGE  ConnectMsg)
{
  NTSTATUS Status;

  /* Wait forever for a connection request. */
  for (;;)
  {
     Status = NtReplyWaitReceivePort(PortHandle, NULL, NULL, ConnectMsg);
     /* Accept only LPC_CONNECTION_REQUEST requests. Drop any other message. */
     if (!NT_SUCCESS(Status) ||
              LPC_CONNECTION_REQUEST == ConnectMsg->MessageType)
     {
        DPRINT("Got message (type %x)\n", LPC_CONNECTION_REQUEST);
        break;
     }
     DPRINT("Got message (type %x)\n", ConnectMsg->MessageType);
  }

  return (Status);
}[/code]

    所謂“收聽(Listen)”,就是在一個for循環(huán)中反復(fù)調(diào)用NtReplyWaitReceivePort(),等待接收來自客戶方的報文,直至接收到報文、并且所收到報文的類型為“連接請求”、即LPC_CONNECTION_REQUEST時為止。如果接收到的報文不是連接請求就回過去再等,所以才把它放在無限for循環(huán)中。
    NtReplyWaitReceivePort()本來的作用是“發(fā)送一個應(yīng)答報文并等待接收”,但是這里的應(yīng)答報文指針為NULL,也就是無應(yīng)答報文可發(fā),這樣就成為只是等待來自客戶方的請求了。另一方面,這個函數(shù)是不帶超時(Timeout)的,只要沒有收到客戶方的請求就一直等待下去。

[code][NtListenPort() > NtReplyWaitReceivePort()]

NTSTATUS STDCALL
NtReplyWaitReceivePort (IN HANDLE PortHandle, OUT PULONG PortId,
       IN PLPC_MESSAGE LpcReply, OUT PLPC_MESSAGE LpcMessage)
{
  return(NtReplyWaitReceivePortEx (PortHandle, PortId, LpcReply, LpcMessage, NULL));
}[/code]

    NtReplyWaitReceivePort()是不帶超時的,另一個系統(tǒng)調(diào)用NtReplyWaitReceivePortEx()則有超時功能,所以前者是通過后者實現(xiàn)的,只是把(最后那個)參數(shù)Timeout設(shè)成NULL。

[code][NtListenPort() > NtReplyWaitReceivePort() > NtReplyWaitReceivePortEx()]

NTSTATUS STDCALL
NtReplyWaitReceivePortEx(IN HANDLE PortHandle, OUT PULONG PortId,
        IN PLPC_MESSAGE LpcReply, OUT PLPC_MESSAGE LpcMessage,
        IN PLARGE_INTEGER Timeout)
{
   . . . . . .
  
   if( Port->State == EPORT_DISCONNECTED )
     {
       /* If the port is disconnected, force the timeout to be 0
         so we don't wait for new messages, because there won't be
         any, only try to remove any existing messages */
       Disconnected = TRUE;
       to.QuadPart = 0;
       Timeout = &to;
     }
   else Disconnected = FALSE;

   Status = ObReferenceObjectByHandle(PortHandle, PORT_ALL_ACCESS,
                        LpcPortObjectType, UserMode, (PVOID*)&Port, NULL);
   . . . . . .
   /* Send the reply, only if port is connected */
   if (LpcReply != NULL && !Disconnected)
   {
      Status = EiReplyOrRequestPort(Port->OtherPort, LpcReply, LPC_REPLY, Port);
      KeReleaseSemaphore(&Port->OtherPort->Semaphore,
                          IO_NO_INCREMENT, 1, FALSE);
      . . . . . .
   }
  
   /* Want for a message to be received */
   Status = KeWaitForSingleObject(&Port->Semaphore, UserRequest,
                                      UserMode, FALSE, Timeout);
   if( Status == STATUS_TIMEOUT )
   {
       . . . . . .
   }
   . . . . . .
   /* Dequeue the message */
   KeAcquireSpinLock(&Port->Lock, &oldIrql);
   Request = EiDequeueMessagePort(Port);
   KeReleaseSpinLock(&Port->Lock, oldIrql);

   if (Request->Message.MessageType == LPC_CONNECTION_REQUEST)
   {
       LPC_MESSAGE Header;
       PEPORT_CONNECT_REQUEST_MESSAGE CRequest;

?? 快捷鍵說明

復(fù)制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
国产精品传媒视频| 国产精品美女久久久久久| aaa国产一区| 国产中文字幕一区| 国产成人av福利| 国产99久久久久| 岛国精品在线播放| 在线观看日韩电影| 91福利资源站| 欧美日韩中文另类| 日韩欧美国产一区二区三区| 日韩免费一区二区| 国产日产欧美一区二区三区| 久久久久免费观看| 日韩一区在线免费观看| 一区二区三区91| 日本欧美加勒比视频| 精久久久久久久久久久| 国产精品一区免费在线观看| 成人黄色免费短视频| 99精品久久只有精品| 欧美日韩国产一级片| 日韩精品一区二区三区老鸭窝| 精品女同一区二区| 国产精品国产三级国产aⅴ无密码| 亚洲欧洲av在线| 天涯成人国产亚洲精品一区av| 麻豆高清免费国产一区| 成人av资源在线观看| 欧美日韩在线三级| 久久蜜臀精品av| 一区二区三区四区蜜桃| 美女视频黄 久久| 91麻豆国产精品久久| 欧美一区二区三区在线观看| 久久久精品tv| 国产在线一区二区| 欧美午夜精品久久久久久超碰 | 免费在线看成人av| 国产制服丝袜一区| 欧美日韩国产a| 欧美国产在线观看| 午夜影院久久久| 不卡一区二区中文字幕| 91精品国产91久久综合桃花| 国产精品久久久久影视| 蜜芽一区二区三区| 色爱区综合激月婷婷| 久久亚洲影视婷婷| 日韩av一区二区在线影视| 99riav一区二区三区| 亚洲精品一区二区三区影院| 亚洲va中文字幕| 成人av高清在线| 国产亚洲美州欧州综合国| 日日欢夜夜爽一区| 在线免费一区三区| 中文字幕永久在线不卡| 激情久久久久久久久久久久久久久久| 色偷偷久久人人79超碰人人澡| 国产清纯在线一区二区www| 日韩成人精品视频| 欧美日韩国产不卡| 亚洲欧洲综合另类在线| 国产成人自拍网| 精品久久一区二区三区| 午夜精品国产更新| 欧美性受xxxx| 亚洲成人久久影院| 欧美图区在线视频| 亚洲va天堂va国产va久| 欧美色综合久久| 亚洲国产成人av| 制服丝袜一区二区三区| 天天综合日日夜夜精品| 欧美疯狂性受xxxxx喷水图片| 亚洲欧美日韩人成在线播放| 欧美日韩国产成人在线免费| 一区二区三区四区在线播放| 色香色香欲天天天影视综合网| 中文字幕佐山爱一区二区免费| 成人av资源网站| 亚洲色图色小说| 欧美性感一区二区三区| 婷婷六月综合网| 精品成人一区二区三区| 国产传媒一区在线| 亚洲欧洲色图综合| 欧美在线小视频| 日本强好片久久久久久aaa| 精品国产青草久久久久福利| 麻豆成人在线观看| 欧美国产精品久久| 97国产一区二区| 一区二区免费在线| 91精品国产综合久久久蜜臀图片| 美国毛片一区二区| 久久久激情视频| 在线精品视频免费观看| 免费成人美女在线观看.| 久久久三级国产网站| 一本久道久久综合中文字幕| 亚洲午夜国产一区99re久久| 欧美成人三级在线| av激情综合网| 午夜视频在线观看一区二区 | 床上的激情91.| 一区二区三区四区在线播放 | 樱花影视一区二区| 日韩一区二区三区在线视频| 国产激情视频一区二区三区欧美 | 欧美色图一区二区三区| 看电影不卡的网站| 亚洲视频免费观看| 日韩欧美亚洲国产另类| 成人久久18免费网站麻豆| 亚洲福利视频一区二区| 国产欧美一区二区三区网站| 欧美色图一区二区三区| 成人国产精品视频| 免费高清不卡av| 亚洲自拍欧美精品| 亚洲国产成人午夜在线一区| 91精品国产一区二区| 97se亚洲国产综合自在线| 麻豆精品视频在线| 亚洲午夜激情网页| 亚洲你懂的在线视频| 久久久不卡网国产精品一区| 欧美丰满少妇xxxbbb| 色婷婷亚洲一区二区三区| 国产精品77777| 激情欧美一区二区三区在线观看| 亚洲va欧美va人人爽午夜| 亚洲 欧美综合在线网络| 亚洲欧美偷拍三级| 国产精品欧美极品| 久久九九99视频| 欧美精品一区二区三区久久久| 欧美亚日韩国产aⅴ精品中极品| a在线播放不卡| 成人精品gif动图一区| 国产福利一区在线观看| 麻豆成人免费电影| 看片网站欧美日韩| 久久成人av少妇免费| 三级欧美在线一区| 丝袜美腿亚洲一区| 亚洲一区二区三区视频在线播放| 亚洲男同性恋视频| 亚洲一区二区三区三| 一区二区三区免费观看| 亚洲美女免费在线| 亚洲男人天堂一区| 一区二区三区日本| 午夜国产精品影院在线观看| 亚洲图片欧美色图| 石原莉奈在线亚洲二区| 久久精品久久久精品美女| 日本欧洲一区二区| 精品一区二区三区在线播放| 久久精品国产免费看久久精品| 麻豆精品国产91久久久久久| 欧美aa在线视频| 久久99精品国产麻豆不卡| 国产一区不卡在线| av电影在线观看一区| 日本精品裸体写真集在线观看 | 日韩欧美国产午夜精品| 国产精品第13页| 一区二区三区四区不卡在线 | 欧美日韩一卡二卡| 91麻豆精品国产自产在线| 日韩欧美成人一区| 亚洲国产精品精华液2区45| 亚洲男帅同性gay1069| 日韩高清不卡一区二区三区| 久久激情综合网| a美女胸又www黄视频久久| 欧美日韩亚洲综合在线| 久久在线免费观看| 亚洲综合精品久久| 国产一区二区免费在线| 色综合天天综合网天天狠天天| 在线播放91灌醉迷j高跟美女| 在线播放/欧美激情| 日本一区二区成人| 日韩精品五月天| 三级不卡在线观看| 国产不卡视频在线播放| 欧美日韩卡一卡二| 国产日韩欧美不卡| 天堂久久一区二区三区| 99久久精品情趣| 日韩手机在线导航| 一区二区三区小说| 粉嫩aⅴ一区二区三区四区五区| 色欧美88888久久久久久影院| 欧美成人精品1314www| 亚洲欧美日韩人成在线播放|