电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術(shù)文章
文章詳情頁

《Undocumented Windows 2000 Secrets》翻譯 --- 第三章(3)

瀏覽:91日期:2023-08-27 11:16:20

第三章 編寫內(nèi)核模式驅(qū)動程序

翻譯: Kendiv

更新: Thursday, February 10, 2005

設(shè)備 I/O 控制

就像在本章開頭的簡介中提到的,在本書中,我們不會構(gòu)建某一具體硬件的驅(qū)動程序。替代的是,我們將利用功能強大的內(nèi)核驅(qū)動程序來研究 Windows 2000 的秘密。從實際結(jié)果來看,驅(qū)動程序的強大之處在于它們能在 CPU 的最高特權(quán)級別上運行。這意味著內(nèi)核驅(qū)動可以訪問所有的系統(tǒng)資源,可以讀取所有的內(nèi)存空間,而且也被允許執(zhí)行 CPU 的特權(quán)指令,如,讀取 CPU 控制寄存器的當(dāng)前值等。而處于用戶模式下的程序如果試圖從內(nèi)核空間中讀取一個字節(jié)或者試圖執(zhí)行像 MOV EAX,CR3 這樣的匯編指令都會被立即終止掉。不過,這種強大的底線是驅(qū)動程序的一個很小的錯誤就會讓整個系統(tǒng)崩潰。即使是非常小的錯誤發(fā)生,也會讓系統(tǒng)藍屏,因此開發(fā)內(nèi)核程序的人員必須比 Win32 應(yīng)用程序或 DLL 的開發(fā)人員更加仔細的處理錯誤。還記得我們在第一章里使用的導(dǎo)致系統(tǒng)藍屏的 Windows 2000 Killer device driver 嗎?它所作的一切只是觸及了虛擬內(nèi)存地址 0x00000000 ,然后就 ---Boom !!!你應(yīng)該意識到在開發(fā)內(nèi)核驅(qū)動時,你會比以往更頻繁的重啟你的機器。

在隨后章節(jié)中,我給出的驅(qū)動程序代碼將采用稱為設(shè)備 I/O 控制( IOCTL )的技術(shù),以允許用戶模式下的代碼實現(xiàn)一定程序的“遠程控制”。如果應(yīng)用程序需要訪問在用戶模式下無法觸及的系統(tǒng)資源,那內(nèi)核驅(qū)動程序?qū)⒖珊芎玫耐瓿纱隧椆ぷ鳎?IOCTL 則是聯(lián)系二者的橋梁。事實上, IOCTL 并不是 Windows 2000 采用的新技術(shù)。即使舊的操作系統(tǒng) ---Dos 2.11 也具有這種能力, 0x44 函數(shù)及其子函數(shù)構(gòu)成了 DOS 的 IOCTL 。基本上, IOCTL 是通過控制通路和設(shè)備通訊的一中手段,控制通路在邏輯上獨立于數(shù)據(jù)通路。想象一個硬盤設(shè)備通過其主數(shù)據(jù)通路傳遞磁盤扇區(qū)中的內(nèi)容。如果客戶想獲取當(dāng)前設(shè)備使用的媒體信息,它就必須使用另一個不同的通路。例如, DOS 函數(shù) 0x44 ,其子函數(shù) 0x0d 、 0x66 構(gòu)成了 DOS 的 IOCTL ,調(diào)用這些函數(shù)就可讀取磁盤的 32 位連續(xù)數(shù)據(jù)(參考 Brown and Kyle 1991 , 1993 )。

設(shè)備 I/O 控制根據(jù)要控制的設(shè)備,可以有多種實現(xiàn)方式。就其一般形式來說, IOCTL 有如下幾類:

l 客戶端通過一個特殊的進入點來控制設(shè)備。在 DOS 中,這個進入點為 INT 21h 、函數(shù)號 0x44 。在 Windows 2000 中,則通過 Kernel32.dll 導(dǎo)出的 Win32 函數(shù) DeviceIoControl() 。

l 客戶端通過提供設(shè)備的唯一標(biāo)識符、控制代碼以及一個存放輸入數(shù)據(jù)的緩沖區(qū)、一個存放輸出數(shù)據(jù)的緩沖區(qū)來調(diào)用 IOCTL 的進入點。對于 Windows 2000 ,設(shè)備標(biāo)識符是成功打開的設(shè)備的句柄( HANDLE )。

l 控制代碼用于告訴目標(biāo)設(shè)備的 IOCTL 分派器( dispatcher ),客戶端請求的是哪一個控制函數(shù)。

l 輸入緩沖區(qū)中可包含任意地附加數(shù)據(jù),設(shè)備可能需要這些數(shù)據(jù)來完成客戶所請求的操作。

l 客戶所請求的操作產(chǎn)生的任何數(shù)據(jù),都會保存在客戶端提供的輸出緩沖區(qū)中。

l IOCTL 操作的整體結(jié)果通過返回給客戶端的狀態(tài)代碼來表示

很 顯然這是一種強大的通用機制,這種機制可以適用于很大范圍的控制請求。例如,應(yīng)用程序在訪問系統(tǒng)內(nèi)核所占用的內(nèi)存空間時會被禁止,這是因為當(dāng)程序觸及該內(nèi) 存空間時會立即拋出一個異常,不過程序可以通過加載一個內(nèi)核驅(qū)動程序來完成此項工作,這樣就可避免出現(xiàn)異常。交互的兩個模塊都需遵循 IOCTL 協(xié)議來管理數(shù)據(jù)的傳輸。例如,程序可能通過給驅(qū)動程序發(fā)送控制代碼 0x80002000 來讀取內(nèi)存或發(fā)送 0x80002001 來向內(nèi)存中寫入數(shù)據(jù)。對于讀取請求, IOCTL 輸 入緩沖區(qū)或許要提供基地址和要讀取的字節(jié)數(shù)。內(nèi)核驅(qū)動程序能獲取這些請求并通過控制代碼來判斷是讀取操作還是寫入操作。對于讀取請求,內(nèi)核驅(qū)動程序會將請 求的內(nèi)存范圍內(nèi)的數(shù)據(jù)復(fù)制到調(diào)用者提供的輸出緩沖區(qū)中,如果輸出緩沖區(qū)足夠容納這些數(shù)據(jù),則返回成功代碼。對于寫入請求,驅(qū)動程序會將輸入緩沖區(qū)中的數(shù)據(jù) 復(fù)制到指定的內(nèi)存中(該內(nèi)存的起始位置也由輸入緩沖區(qū)指定)。在第四章,我將提供一個 Memory Spy 的示列代碼。

現(xiàn)在,可以看出 IOCTL 是 Win32 應(yīng)用程序的一種后門,通過 IOCTL ,程序可以執(zhí)行幾乎所有的操作,而在此之前,這些操作僅允許特權(quán)模塊執(zhí)行。當(dāng)然,這需要首先編寫一個特權(quán)級的模塊,但是,一旦你擁有一個運行于系統(tǒng)中的 Spy 模塊,一切就變得很簡單了。本書的兩個目標(biāo)是:詳細展示如何編寫內(nèi)核模式的驅(qū)動程序以及一個可以完成很多讓人驚異的事的驅(qū)動程序的示例代碼。

Windows 2000 的 Killer Device

在開始更高級的驅(qū)動程序工程之前,讓我們先看看一個非常簡單的驅(qū)動程序。在第一章中,我介紹了 Windows 2000 的 Killer Device----w2k_kill.sys ,它被設(shè)計為引發(fā)一個良性的系統(tǒng)崩潰。這個驅(qū)動程序并不需要 示例 3-3 中的大多數(shù)代碼,因為它在有機會收到第一個 I/O 請求包之前就會使系統(tǒng)崩潰。 示例 3-7 給出了它的實現(xiàn)代碼。這里沒有給出 w2k_kill.h 文件,因為它不不包含任何我們感興趣的代碼。

示列 3-7 中的代碼沒有在 DriverEntry() 中執(zhí)行初始化操作,因為系統(tǒng)會在 DriverEntry() 返回前就崩潰,所以沒有必要進行這些額外的工作。

#define _W2K_KILL_SYS_

#include <ddkntddk.h>

#include 'w2k_kill.h'

// =================================================================

// DISCARDABLE FUNCTIONS

// =================================================================

NTSTATUS DriverEntry (PDRIVER_OBJECT pDriverObject,

PUNICODE_STRING pusRegistryPath);

#ifdef ALLOC_PRAGMA

#pragma alloc_text (INIT, DriverEntry)

#endif

// =================================================================

// DRIVER INITIALIZATION

// =================================================================

NTSTATUS DriverEntry (PDRIVER_OBJECT pDriverObject,

PUNICODE_STRING pusRegistryPath)

{

return *((NTSTATUS *) 0);

}

// =================================================================

// END OF PROGRAM

// =================================================================

示列 3-7. 一個小巧的系統(tǒng)崩潰者

加載 / 卸載驅(qū)動程序

在完成一個內(nèi)核驅(qū)動程序之后,你可能會想立即執(zhí)行它。怎么做呢?典型的做法是,在系統(tǒng)啟動時加載驅(qū)動程序并執(zhí)行之。但這是不是就意味著我們每次更新驅(qū)動程序后,都必須重新啟動系統(tǒng)呢?很幸運,這并不是必須的。 Windows 2000 的一個特色就是提供了一個 Win32 接口以允許在運行時加載或卸載驅(qū)動程序。這是由服務(wù)控制管理器( Service Control Manager , SCM )完成的,下面的將詳細介紹它的用法。

服務(wù)控制管理器

“服務(wù)控制管理器”這個名字容易讓人誤解,因為它暗示該組件僅用于服務(wù)的管理。服務(wù)( Service )是 Windows 2000 的一類非常強大的模塊,它們在后臺運行配套的程序,并且不需要用戶交互(也就是說沒有常見的用戶界面或者控制臺)。換句話說,一個服務(wù)就是一個始終運行于系統(tǒng)中的 Win32 進程,即使沒有用戶登陸進來也如此。盡管開發(fā)服務(wù)是一個令人興奮的話題,但它并不屬于本書的范疇。想進一步了解服務(wù)的開發(fā),請閱讀 Windows Developer's Journal ( WDJ )( Tomlinson 1996a )中 Paula Tomlinson 提供的非常不錯的教程,以及隨后在她的 WDJ 專欄 ----Understanding NT 中發(fā)表的有關(guān)服務(wù)的論文。

SC 管理器(即服務(wù)控制管理器)可以控制服務(wù)和驅(qū)動程序。為了簡單起見,我在這里使用“服務(wù)”一詞來代表 SC 管理器控制的所有對象,這包括嚴(yán)格意義上的服務(wù)和內(nèi)核驅(qū)動程。 SC 的接口對于 Win32 程序是可用的,它由 Win32 子系統(tǒng)組件 ----advapi32.dll 提供,這個 DLL 還提供了很多有趣的 API 函數(shù)。 3-3 給出了用于加載、控制和卸載服務(wù)的 API 函數(shù)的名稱,同時還給出了簡單的描述。在你可以加載或訪問任何服務(wù)之前,你必須獲取 SC 管理器的句柄(通過調(diào)用 OpenSCManager() ),在隨后的討論中,該句柄將被稱為:管理器句柄。 CreateService() 和 OpenService() 都需要此句柄,而這些函數(shù)返回的句柄將被稱為:服務(wù)句柄。這種類型的句柄可以傳遞給需要引用一個服務(wù)的函數(shù),如 ControlService() 、 DeleteService() 和 StartService() 。這兩種類型的 SC 句柄都通過 CloseServiceHandle() 函數(shù)來釋放。

CloseServiceHandle

關(guān)閉來自 OpenSCManager() 、 CreateService() 或 OpenService() 的句柄

ControlService

停止、暫停、繼續(xù)、查詢或通知已加載的服務(wù) / 驅(qū)動程序

CreateService

加載一個服務(wù) / 驅(qū)動程序

DeleteService

卸載一個服務(wù) / 驅(qū)動程序

OpenSCManager

獲取 SC 管理器的句柄

OpenService

獲取一個已加載的服務(wù) / 驅(qū)動程序的句柄

QueryServiceStatus

查詢一個服務(wù) / 驅(qū)動程序的屬性和當(dāng)前狀態(tài)

StartService

啟動一個已加載的服務(wù) / 驅(qū)動程序

表 3-3. 基本的服務(wù)控制函數(shù)

加載和運行一個服務(wù)需要執(zhí)行的典型操作步驟:

1. 調(diào)用 OpenSCManager() 以獲取一個管理器句柄

2. 調(diào)用 CreateService() 來向系統(tǒng)中添加一個服務(wù)

3. 調(diào)用 StartService() 來運行一個服務(wù)

4. 調(diào)用 CloseServiceHandle() 來釋放管理器或服務(wù)句柄

要確保當(dāng)一個錯誤發(fā)生時,要回滾到最后一個成功的調(diào)用,然后再開始。例如,你在調(diào)用 StartService() 時 SC 管理器報告了一個錯誤,你就需要調(diào)用 DeleteService() 。否則,服務(wù)將保持在一個非預(yù)期的狀態(tài)。另一個使用 SC 管理器 API 易犯的錯誤是,必須為 CreateService() 函數(shù)提供可執(zhí)行文件的全路徑名,否則,如果該函數(shù)在當(dāng)前目錄中沒有找到可執(zhí)行文件的話,就會失敗。因此,你應(yīng)該使用 Win32 函數(shù) ---GetFullPathName() 來規(guī)格化傳遞給 CreateService() 的所有文件名,除非可以保證它們已經(jīng)是全路徑的。

高層的驅(qū)動程序管理函數(shù)

為了更容易的和 SC 管理器進行交互,本書附帶的 CD 提供了多個更高級的外包函數(shù),這些函數(shù)屏蔽了原有的一些不方便的特殊要求。這些函數(shù)是本書提供的龐大的 Windows 2000 工具庫(位于隨書 CD 中的 srcw2k_lib )中的一部分。 w2k_lib.dll 導(dǎo)出的所有函數(shù)都有一個全局的名字前綴 w2k ,服務(wù)和驅(qū)動程序管理函數(shù)都使用 w2kService 前綴。 列表 3-8 給出了本書提供的工具庫中實現(xiàn)的加載、控制和卸載服務(wù) / 驅(qū)動程序的函數(shù)的細節(jié)。

// =================================================================

// SERVICE/DRIVER MANAGEMENT

// =================================================================

SC_HANDLE WINAPI w2kServiceConnect (void)

{

return OpenSCManager (NULL, NULL, SC_MANAGER_ALL_ACCESS);

}

// -----------------------------------------------------------------

SC_HANDLE WINAPI w2kServiceDisconnect (SC_HANDLE hManager)

{

if (hManager != NULL) CloseServiceHandle (hManager);

return NULL;

}

// -----------------------------------------------------------------

SC_HANDLE WINAPI w2kServiceManager (SC_HANDLE hManager,

PSC_HANDLE phManager,

BOOL fOpen)

{

SC_HANDLE hManager1 = NULL;

if (phManager != NULL)

{

if (fOpen)

{

if (hManager == NULL)

{

*phManager = w2kServiceConnect ();

}

else

{

*phManager = hManager;

}

}

else

{

if (hManager == NULL)

{

*phManager = w2kServiceDisconnect (*phManager);

}

}

hManager1 = *phManager;

}

return hManager1;

}

// -----------------------------------------------------------------

SC_HANDLE WINAPI w2kServiceOpen (SC_HANDLE hManager,

PWord pwName)

{

SC_HANDLE hManager1;

SC_HANDLE hService = NULL;

w2kServiceManager (hManager, &hManager1, TRUE);

if ((hManager1 != NULL) && (pwName != NULL))

{

hService = OpenService (hManager1, pwName,

SERVICE_ALL_ACCESS);

}

w2kServiceManager (hManager, &hManager1, FALSE);

return hService;

}

// -----------------------------------------------------------------

BOOL WINAPI w2kServiceClose (SC_HANDLE hService)

{

return (hService != NULL) && CloseServiceHandle (hService);

}

// -----------------------------------------------------------------

BOOL WINAPI w2kServiceAdd (SC_HANDLE hManager,

PWORD pwName,

PWORD pwInfo,

PWORD pwPath)

{

SC_HANDLE hManager1, hService;

PWORD pwFile;

WORD awPath [MAX_PATH];

DWORD n;

BOOL fOk = FALSE;

w2kServiceManager (hManager, &hManager1, TRUE);

if ((hManager1 != NULL) && (pwName != NULL) &&

(pwInfo != NULL) && (pwPath != NULL) &&

(n = GetFullPathName (pwPath, MAX_PATH, awPath, &pwFile)) &&

(n < MAX_PATH))

{

if ((hService = CreateService (hManager1, pwName, pwInfo,

SERVICE_ALL_ACCESS,

SERVICE_KERNEL_DRIVER,

SERVICE_DEMAND_START,

SERVICE_ERROR_NORMAL,

awPath, NULL, NULL,

NULL, NULL, NULL))

!= NULL)

{

w2kServiceClose (hService);

fOk = TRUE;

}

else

{

fOk = (GetLastError () ==

ERROR_SERVICE_EXISTS);

}

}

w2kServiceManager (hManager, &hManager1, FALSE);

return fOk;

}

// -----------------------------------------------------------------

BOOL WINAPI w2kServiceRemove (SC_HANDLE hManager,

PWORD pwName)

{

SC_HANDLE hService;

BOOL fOk = FALSE;

if ((hService = w2kServiceOpen (hManager, pwName)) != NULL)

{

if (DeleteService (hService))

{

fOk = TRUE;

}

else

{

fOk = (GetLastError () ==

ERROR_SERVICE_MARKED_FOR_DELETE);

}

w2kServiceClose (hService);

}

return fOk;

}

// -----------------------------------------------------------------

BOOL WINAPI w2kServiceStart (SC_HANDLE hManager,

PWORD pwName)

{

SC_HANDLE hService;

BOOL fOk = FALSE;

if ((hService = w2kServiceOpen (hManager, pwName)) != NULL)

{

if (StartService (hService, 1, &pwName))

{

fOk = TRUE;

}

else

{

fOk = (GetLastError () ==

ERROR_SERVICE_ALREADY_RUNNING);

}

w2kServiceClose (hService);

}

return fOk;

}

// -----------------------------------------------------------------

BOOL WINAPI w2kServiceControl (SC_HANDLE hManager,

PWORD pwName,

DWORD dControl)

{

SC_HANDLE hService;

SERVICE_STATUS ServiceStatus;

BOOL fOk = FALSE;

if ((hService = w2kServiceOpen (hManager, pwName)) != NULL)

{

if (QueryServiceStatus (hService, &ServiceStatus))

{

switch (ServiceStatus.dwCurrentState)

{

case SERVICE_STOP_PENDING:

case SERVICE_STOPPED:

{

fOk = (dControl == SERVICE_CONTROL_STOP);

break;

}

case SERVICE_PAUSE_PENDING:

case SERVICE_PAUSED:

{

fOk = (dControl == SERVICE_CONTROL_PAUSE);

break;

}

case SERVICE_START_PENDING:

case SERVICE_CONTINUE_PENDING:

case SERVICE_RUNNING:

{

fOk = (dControl == SERVICE_CONTROL_CONTINUE);

break;

}

}

}

fOk = fOk ||

ControlService (hService, dControl, &ServiceStatus);

w2kServiceClose (hService);

}

return fOk;

}

// -----------------------------------------------------------------

BOOL WINAPI w2kServiceStop (SC_HANDLE hManager,

PWORD pwName)

{

return w2kServiceControl (hManager, pwName,

SERVICE_CONTROL_STOP);

}

// -----------------------------------------------------------------

BOOL WINAPI w2kServicePause (SC_HANDLE hManager,

PWORD pwName)

{

return w2kServiceControl (hManager, pwName,

SERVICE_CONTROL_PAUSE);

}

// -----------------------------------------------------------------

BOOL WINAPI w2kServiceContinue (SC_HANDLE hManager,

PWORD pwName)

{

return w2kServiceControl (hManager, pwName,

SERVICE_CONTROL_CONTINUE);

}

// -----------------------------------------------------------------

SC_HANDLE WINAPI w2kServiceLoad (PWORD pwName,

PWORD pwInfo,

PWORD pwPath,

BOOL fStart)

{

BOOL fOk;

SC_HANDLE hManager = NULL;

if ((hManager = w2kServiceConnect ()) != NULL)

{

fOk = w2kServiceAdd (hManager, pwName, pwInfo, pwPath);

if (fOk && fStart)

{

if (!(fOk = w2kServiceStart (hManager, pwName)))

{

w2kServiceRemove (hManager, pwName);

}

}

if (!fOk)

{

hManager = w2kServiceDisconnect (hManager);

}

}

return hManager;

}

// -----------------------------------------------------------------

SC_HANDLE WINAPI w2kServiceLoadEx (PWORD pwPath,

BOOL fStart)

{

PVS_VERSIONDATA pvvd;

PWORD pwPath1, pwInfo;

WORD awName [MAX_PATH];

DWORD dName, dExtension;

SC_HANDLE hManager = NULL;

if (pwPath != NULL)

{

dName = w2kPathName (pwPath, &dExtension);

lstrcpyn (awName, pwPath + dName,

min (MAX_PATH, dExtension - dName + 1));

pwPath1 = w2kPathEvaluate (pwPath, NULL);

pvvd = w2kVersionData (pwPath1, -1);

pwInfo = ((pvvd != NULL) && pvvd->awFileDescription [0]

? pvvd->awFileDescription

: awName);

hManager = w2kServiceLoad (awName, pwInfo, pwPath1, fStart);

w2kMemoryDestroy (pvvd);

w2kMemoryDestroy (pwPath1);

}

return hManager;

}

// -----------------------------------------------------------------

BOOL WINAPI w2kServiceUnload (PWORD pwName,

SC_HANDLE hManager)

{

SC_HANDLE hManager1 = hManager;

BOOL fOk = FALSE;

if (pwName != NULL)

{

if (hManager1 == NULL)

{

hManager1 = w2kServiceConnect ();

}

if (hManager1 != NULL)

{

w2kServiceStop (hManager1, pwName);

fOk = w2kServiceRemove (hManager1, pwName);

}

}

w2kServiceDisconnect (hManager1);

return fOk;

}

// -----------------------------------------------------------------

BOOL WINAPI w2kServiceUnloadEx (PWORD pwPath,

SC_HANDLE hManager)

{

DWORD dName, dExtension;

WORD awName [MAX_PATH];

PWORD pwName = NULL;

if (pwPath != NULL)

{

dName = w2kPathName (pwPath, &dExtension);

lstrcpyn (pwName = awName, pwPath + dName,

min (MAX_PATH, dExtension - dName + 1));

}

return w2kServiceUnload (pwName, hManager);

}

// -----------------------------------------------------------------

列表 3-8. 服務(wù)和驅(qū)動管理庫函數(shù)

標(biāo)簽: Windows系統(tǒng)
主站蜘蛛池模板: 螺旋绞龙叶片,螺旋输送机厂家,山东螺旋输送机-淄博长江机械制造有限公司 | 【官网】博莱特空压机,永磁变频空压机,螺杆空压机-欧能优 | 洗石机-移动滚筒式,振动,螺旋,洗矿机-青州冠诚重工机械有限公司 | 建筑资质代办-建筑企业资质代办机构-建筑资质代办公司 | 别墅图纸超市|别墅设计图纸|农村房屋设计图|农村自建房|别墅设计图纸及效果图大全 | 不锈钢发酵罐_水果酒发酵罐_谷物发酵罐_山东誉诚不锈钢制品有限公司 | 耐火砖厂家,异形耐火砖-山东瑞耐耐火材料厂| 铝合金线槽_铝型材加工_空调挡水板厂家-江阴炜福金属制品有限公司 | 长沙印刷厂-包装印刷-画册印刷厂家-湖南省日大彩色印务有限公司 青州搬家公司电话_青州搬家公司哪家好「鸿喜」青州搬家 | 超细|超微气流粉碎机|气流磨|气流分级机|粉体改性机|磨粉机|粉碎设备-山东埃尔派粉体科技 | 塑料造粒机「厂家直销」-莱州鑫瑞迪机械有限公司 | 杭州货架订做_组合货架公司_货位式货架_贯通式_重型仓储_工厂货架_货架销售厂家_杭州永诚货架有限公司 | 对照品_中药对照品_标准品_对照药材_「格利普」高纯中药标准品厂家-成都格利普生物科技有限公司 澳门精准正版免费大全,2025新澳门全年免费,新澳天天开奖免费资料大全最新,新澳2025今晚开奖资料,新澳马今天最快最新图库 | 粉丝机械,粉丝烘干机,粉丝生产线-招远市远东粉丝机械有限公司 | 碳化硅,氮化硅,冰晶石,绢云母,氟化铝,白刚玉,棕刚玉,石墨,铝粉,铁粉,金属硅粉,金属铝粉,氧化铝粉,硅微粉,蓝晶石,红柱石,莫来石,粉煤灰,三聚磷酸钠,六偏磷酸钠,硫酸镁-皓泉新材料 | 钢制暖气片散热器_天津钢制暖气片_卡麦罗散热器厂家 | 气动隔膜阀_气动隔膜阀厂家_卫生级隔膜阀价格_浙江浙控阀门有限公司 | 冷水机-冰水机-冷冻机-冷风机-本森智能装备(深圳)有限公司 | 仿真茅草_人造茅草瓦价格_仿真茅草厂家_仿真茅草供应-深圳市科佰工贸有限公司 | 气弹簧定制-气动杆-可控气弹簧-不锈钢阻尼器-工业气弹簧-可调节气弹簧厂家-常州巨腾气弹簧供应商 | PO膜_灌浆膜及地膜供应厂家 - 青州市鲁谊塑料厂 | 升降机-高空作业车租赁-蜘蛛车-曲臂式伸缩臂剪叉式液压升降平台-脚手架-【普雷斯特公司厂家】 | NM-02立式吸污机_ZHCS-02软轴刷_二合一吸刷软轴刷-厦门地坤科技有限公司 | 广东健伦体育发展有限公司-体育工程配套及销售运动器材的体育用品服务商 | 轻型地埋电缆故障测试仪,频响法绕组变形测试仪,静荷式卧式拉力试验机-扬州苏电 | 电缆隧道在线监测-智慧配电站房-升压站在线监测-江苏久创电气科技有限公司 | 刮板输送机,粉尘加湿搅拌机,螺旋输送机,布袋除尘器 | 柴油机_柴油发电机_厂家_品牌-江苏卡得城仕发动机有限公司 | 臭氧老化试验箱,高低温试验箱,恒温恒湿试验箱,防水试验设备-苏州亚诺天下仪器有限公司 | 蓝莓施肥机,智能施肥机,自动施肥机,水肥一体化项目,水肥一体机厂家,小型施肥机,圣大节水,滴灌施工方案,山东圣大节水科技有限公司官网17864474793 | 防水套管厂家_刚性防水套管_柔性防水套管_不锈钢防水套管-郑州中泰管道 | 低气压试验箱_高低温低气压试验箱_低气压实验箱 |林频试验设备品牌 | 耐腐蚀泵,耐腐蚀真空泵,玻璃钢真空泵-淄博华舜耐腐蚀真空泵有限公司 | 污水/卧式/潜水/钻井/矿用/大型/小型/泥浆泵,价格,参数,型号,厂家 - 安平县鼎千泵业制造厂 | 混合反应量热仪-高温高压量热仪-微机差热分析仪DTA|凯璞百科 | 东莞韩创-专业绝缘骨架|马达塑胶零件|塑胶电机配件|塑封电机骨架厂家 | 馋嘴餐饮网_餐饮加盟店火爆好项目_餐饮连锁品牌加盟指南创业平台 | 仓储笼_仓储货架_南京货架_仓储货架厂家_南京货架价格低-南京一品仓储设备制造公司 | 磨煤机配件-高铬辊套-高铬衬板-立磨辊套-盐山县宏润电力设备有限公司 | 广州企亚 - 数码直喷、白墨印花、源头厂家、透气无手感方案服务商! | 液压中心架,数控中心架,自定心中心架-烟台恒阳机电设计有限公司 行星搅拌机,双行星搅拌机,动力混合机,无锡米克斯行星搅拌机生产厂家 |