WINDOWS9x 的後台進程

來源:互聯網
上載者:User
WINDOWS9x 的後台進程加入時間:01-1-6 下午 04:47:20

 

上海仙霞路山特公司軟體中心黃飛

----1.後台進程

----在WINDOWSNT中有一個功能強大的SERVICE管理器,它管理著一部分實現重要功能的後台進程,例如FTP.HTTP.RAS.網路Message等等,這些後台進程被稱之為Service,他們可以在系統啟動時就載入,可以運行在較高的優先順序,可以說是非常靠近系統核心的裝置驅動程式中的一種.在WINDOWS95下,Microsoft沒有提供這樣一個高度集中化了的管理器,不過我們通過VC內建的PVIEW可以看到,在案頭背後同樣有秘密的後台進程存在,例如:SysTray,電源管理等.其實,這些就是WINDOWS95管理的後台進程,WINDOWS95沒有提供SERVICE管理器,取而代之的是一個簡單的登記介面,可以類似的稱之為WINDOWS95下的Service(不過嚴格的講,WINDOWS95下是沒有Service的),同樣的,通過這個登記介面,我們可以使自己的程式隨系統啟動而最先運行,隨系統關閉而最後停止,和作業系統結合在一起,實現許多獨特的功能.我在實際工作中,仔細的分析了這個Windows95的介面,並且測試後發現,在WINDOWS97和最新的WINDOWS98中它一樣有效.並通過這個機制,成功的實現了WINDOWS95.98下的無人職守監控.下面是關於這個介面的分析結果和一些準備知識.

----2.進程資料庫(PDB)介紹

----在Windows的核心資料結構中,有一個重要的進程管理結構叫進程資料庫,它位於Kernel32的公用記憶體堆中,可以通過GetCurrentProcessID(...)得到指向該結構的指標,以下是部分PDB的組成,與本文直接相關的是PDB位移21h處的Service標誌位元組,通過後面的偽碼分析,我們可以清楚的看到所謂登記為Windows95或Windows98下的Service進程,只不過是把它相應的PDB中該標誌位元組置為1而已.

位移量長度      說明
============================================
+00h  DWORD   Type // Kernel32對象的類型
+04h  DWORD   CReference //參考計數
+08h  DWORD   Un1 //未知
+0ch  DWORD   pSomeEvent //指向K32OBJ_EVENT指標
+10h  DWORD   TerminationStatus //活動標誌或傳回值
+14h  DWORD   Un2 //未知
...
+21h  BYTE    Flags1 // Service標記,
            // "1"是Service進程,
            // "0"普通進程
...
+24h  DWORD   pPSP // DOS PSP指標
...
============================================
---- 3. 實 現 接 口

---- (1) Windows95 中 提 供 的 簡 單 的Service 接 口 是 一 個32 位 的API: RegisterServiceProcess, 由 於 在VC++ 的Online help 中 得 不 到 關 於 這 個API 的 確 切 解 釋, 筆 者 不 得 不 針 對 此API 進 行 了 逆 向 分 析, 以 下 是 在Windows95 的Kernel32.dll 中 該API 的 偽 碼. 我 們 可 以 清 楚 的 看 到Window95 內 部 到 底 是 怎 樣 做 的, 其 實 處 理 的 非 常 簡 單.

BOOL RegisterServiceProcess
( DWORD dwProcessID, DWORD dwType )
{
HANDLE dwPID;
if( dwProcessID == NULL )
  dwPID = dwCurrentProcessID;
  // Get global kernel32 variable
else
  // Call some kernel functions
  if( ( dwPID = CheckPID( dwProcessID ) == NULL )
    return FALSE;
if( dwType == 1 )
{
  *(BYTE *)( dwPID + 0x21 ) | = 0x01;
  return TRUE;
}
if( dwType == 0 )
{
  *(BYTE *)( dwPID + 0x21 ) & = 0xFE;
  return TRUE;
}
return FALSE;
}
 以下為函數原形:
BOOL  RegisterServiceProcess( DWORD dwPID, DWORD dwType )
參數:  dwPID:進程ID, NULL代表當前進程
   dwType: RSP_SIMPLE_SERVICE為登記
       RSP_UNREGISTER_SERVICE為取消登錄
傳回值: TRUE: 調用成功
   FALSE: 調用失敗
---- (2) 另 外, 為 了 讓Service 進 程 有 機 會 在BOOT 後 就 啟 動,Windows95 的Registry 中 提 供 了 加 載 方 法: 在KEY " MyComputer /HKEY_LOCAL_MACHINE/SOFTWARE /Microsoft/Windows /CurrentVersion /RunServices " 加 入 自 己 的 應 用 程 序 命 令 行, 即 可 實 現 開 機 自 動 加 載. 當 然, 如 果 你 得 機 器 中 沒 有 這 個Key, 自 己 建 一 個 也 是 可 以 的.

---- 4. 例 程

---- 下 面 是 實 現 例 程, 所 有 代 碼 經 過 了WINDOWS95. WINDOWS98 BETA3 的 測 試, 可 以 方 便 的 加 入 到 自 己 的 項 目 文 件 中.

---- 頭 文 件:

// File:      service.h
// The head file of "service.cpp"
// Note: 1. You must use C++ compiler
//   2. The platform is WIN32 (WINNT & WIN95)

#ifndef _SERVICE_H
#define _SERVICE_H

/////////////////////////////////////
////////////// USED FOR WIN95 SERVICE
// Micros
#define RSP_SIMPLE_SERVICE      1
#define RSP_UNREGISTER_SERVICE    0

// Function types for GetProcAddress
#define RegisterServiceProcess_PROFILE
(DWORD (__stdcall *) (DWORD, DWORD))

// Service Fuctions in Win95
BOOL  W95ServiceRegister(DWORD dwType);
BOOL  W95StartService( DWORD dwType );

#endif

CPP 文 件:
// File:    service.cpp --- implement the service

#include "service.h"
/////////////////////////////////////
////////////// USED FOR WIN95 SERVICE
登 記 為Service 子 程 序:
/////////////////////////////////////////
////////////////////////////////////////
// Define:       BOOL
   W95ServiceRegister(DWORD dwType)
// Parameters: dwType --- Flag to
register or unregister the service
//      RSP_SIMPLE_SERVICE   means register
//      RSP_UNREGISTER_SERVICE means unregister
// Return: TRUE --- call success;
   FALSE --- call failer

BOOL  W95ServiceRegister( DWORD dwType )
{
   // Function address defination
   DWORD  (__stdcall * hookRegisterServiceProcess)
         ( DWORD dwProcessId, DWORD dwType );

   // Get address of function
   hookRegisterServiceProcess =
   RegisterServiceProcess_PROFILE
              GetProcAddress
             (GetModuleHandle("KERNEL32"),
              TEXT("RegisterServiceProcess"));

   // Register the WIN95 service
   if(hookRegisterServiceProcess(NULL,dwType)==0)
       return FALSE;
   return TRUE;
}
---- 加 入 注 冊 表 子 程 序:

#define SERVICE_NAME  TEXT("SERVICE")
// Define:   BOOL  W95StartService( DWORD dwType )
// Parameters: dwType --- Flag to
register or unregister the service
//      RSP_SIMPLE_SERVICE   means register
//      RSP_UNREGISTER_SERVICE means unregister
// Return: TRUE --- call success; FALSE --- call failer

BOOL W95StartService( DWORD dwType )
{
   // Local Variables
   TCHAR  lpszBuff[256];
   LPTSTR lpszStr = lpszBuff +128;
   LPTSTR lpszName    = lpszBuff;
   HANDLE hKey      = NULL;
   DWORD  dwStrCb     = 0;
   DWORD  dwValueType   = 0;

   // Get service name currently
   lpszName = GetCommandLine();
   for( int i = _tcslen(lpszName)-1; I >=0; i-- )
   {
    if( ( lpszName[i] != '"' )&&( lpszName[i]!=' ') )
           break;
       else if( lpszName[i] == '"' )
           lpszName[i] = '/0';
   }
   if( lpszName[0] == '"' )
       lpszName = lpszName +1;

   // Registe as start up service
   if( RegOpenKeyEx (HKEY_LOCAL_MACHINE,
   TEXT( "SOFTWARE//Microsoft//Windows//
    CurrentVersion//RunServices"),
          0,
          KEY_QUERY_VALUE | KEY_SET_VALUE,
          &hKey ) != ERROR_SUCCESS )
   {
       if( RegCreateKey( HKEY_LOCAL_MACHINE,
          TEXT( "SOFTWARE//Microsoft//
          Windows//CurrentVersion//RunServices"),
          &hKey ) != ERROR_SUCCESS )
       {
           //DebugOut( "RegCreateKey() error!");
           return FALSE;
       }
   }

   dwValueType   = REG_SZ;
   dwStrCb     = 128;

   // Take value
   if( RegQueryValueEx(hKey,
        SERVICE_NAME,
        0,
        &dwValueType,
        (LPBYTE)lpszStr,
        &dwStrCb ) == ERROR_SUCCESS )
   
   {
       // Find this key value
       if( _tcscmp( lpszStr, lpszName )==0 )
       {
           // Remove the service
           if( dwType == RSP_UNREGISTER_SERVICE )
           {
            if(RegDeleteValue( hKey, SERVICE_NAME )
             == ERROR_SUCCESS )
               {
                   RegCloseKey ( hKey );
                   return TRUE;
               }
               RegCloseKey( hKey );
               return FALSE;
           }
           // Already exist service
           if( dwType == RSP_SIMPLE_SERVICE )
           {
               //DebugOut("Already registed!");
               RegCloseKey( hKey );
               return TRUE;
           }
       }
       // Not find it
   } // No this value

   // Unregiste return
   if( dwType == RSP_UNREGISTER_SERVICE )
   {
       RegCloseKey( hKey );
       return TRUE;
   }

   // No this value then create it
   if( dwType == RSP_SIMPLE_SERVICE )
   {
       dwStrCb = 128;

       // Set value
       if( RegSetValueEx(hKey,
                   SERVICE_NAME,
                   0,
                   REG_SZ,
                   (CONST BYTE *)lpszName,
                   dwStrCb ) != ERROR_SUCCESS )
       {
           //DebugOut("RegSetValueEx() error!");
           RegCloseKey( hKey );

           return FALSE;
       }
       RegCloseKey( hKey );
       return TRUE;
   }

   // Unknow type
   RegCloseKey( hKey );
   return FALSE;
}
---- 主 程 序:

// WinMain function is the entry of the this program
int APIENTRY WinMain(HINSTANCE hInstance,
          HINSTANCE hPrevInstance,
          LPSTR   lpCmdLine,
          int    nCmdShow)
{
   if( W95ServiceRegister( RSP_SIMPLE_SERVICE ) )
   {
       W95StartService( RSP_SIMPLE_SERVICE );
   }

   MessageBox(NULL, "Sample service", "SERVICE", MB_OK );
   UNREFERENCED_PARAMETER( hInstance );
   UNREFERENCED_PARAMETER( lpCmdLine );
   UNREFERENCED_PARAMETER( nCmdShow );
   UNREFERENCED_PARAMETER( hPrevInstance );
   return 0;
}

----運行這個程式,等到MessageBox彈出後,從WINDOWS中退出到LOGON狀態,你會看見MessageBox一直保持開啟狀態直至受到響應或系統關機.所以要做WINDOWS95下系統級的後台進程,並不一定非要去編寫容易引起系統混亂的VXD程式,在硬體部分允許的情況下,我認為本文介紹的方法更加方便有效.

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.