GCCを使用してWindows NTのカーネルDLLを作成
8906 ワード
原文リンク:GCCを使用してWindows NTのカーネルDLLを作成
階層型ドライバの章では、I/Oマネージャの直列接続に依存せず、カーネルルーチンを直接呼び出すことで、ドライバの実行効率を大幅に向上させることができます.
このような機能を実現するためには、ユーザモードでのDLLと同様のメカニズムを提供する必要があるが、この「DLL」はカーネルにロードされる.実はWindows NTカーネル自体はとっくにこのようなメカニズムを利用しています.例えばHal.dll、ntoskrnl.Exceや、サードパーティ製ドライバに対してHAL層、カーネル層、実行体層の機能関数をそれぞれ導出したドライバなどがあります.
Tim Robertsの「カーネルモードのDLL」では、カーネルDLLの主な特徴が示されています.
カーネルDLLは、ユーザー・モードDLLと同じです.リンクは、DLLの構築時にインポート・ライブラリを生成し、このDLLを使用するドライバのターゲット・ライブラリのリストに含めます.レジストリテクニックもDLLを停止する特別な動作も必要ありません.カーネルDLLは、参照された他のドライバとともに自動的にロードされ、最後に参照されたドライバとともに自動的にアンインストールされます(注1).
このようなDLLを実現するために、RobertsはDDKを使用してTARGETYPEをEXPORT_として生成する方法を示した.DRIVERのプロジェクト.私は試して、望み通りに、確かにxxxを創立しました.Sysファイル、私はまたこのsysのPEタイプを観察して、それが標準のカーネルsysと変わらないことを発見して、それではgccで1つのカーネルモードのDLLを生成することができますか?答えは肯定的だ!Windows NTの下にあるCore Dllをgcc(MinGW)で書いている場合は、DDKのEXPORT_DRIVERタイプのモジュールを書くこともできますが、具体的なやり方は省略します...
はい、上は冗談です.ほほほ.MinGWでCoreDllを書く方法について詳しく説明します.まずあなたのシステムにMinGWをインストールするべきで、私は今使っています(MinGW 5.1.4). あなたのシステムにはMasm 32 V 9があります.0+の環境(これは必須ではなく、Gccも自分でドライバファイルを生成する能力があり、私はMasm方式を採用しています)では、WINDDKをインストールし、その環境で最終的なドライバファイルを生成することもできます. 用gccNTDrvFrame(注2)CoreDllの動的ロードとアンインストール機能を実現するにはsys.cで次の2つのインスタンスを提供する必要があります.構築と分析に関する内容をそれらの中に入れることができます.同様にDriverには標準的なDriverEntryエントリポイントが含まれている必要がありますが、実際にはシステムは呼び出されません.この要件はシステムを作成することです.カーネルドライバごとに/ENTRY:DriverEntryをリンクオプションに追加するため、人為的に制限されます.従って,導出したDLLのみに対しても擬似入口点を提供しなければならない.
4.エクスポートする必要がある関数を作成します.ここでは例を示しただけなので、簡単なエクスポート関数を書きました.
5. コネクタのdefファイルを作成します.内容は次のとおりです.
6. gccNTDrvFrameのbuilderを実行し、CoreDllのコンパイルと接続を完了し、エラーがなければいくつかのファイルが生成され、そのうち2つしか使用されません.1つはxxxです.Sys、これは言うまでもなく他の駆動呼び出しのCoreDllであり、もう一つはxxxである.lib、xxxを呼び出す必要があるすべてのものです.Sysの他のドライバの作成に必要なファイル、hal.lib、ntoskrnl.libはまったく同じです.
7. 別のDriverプロジェクトを新規作成し、b.batのlink接続オプションにxxxを追加します.lib.外部関数を宣言して呼び出す方法は次のとおりです.
もちろんDriverEntryで呼び出す必要はありません.xxxですから.Sysはシステムによってsysを呼び出す前に自動的に動的にロードされる.
8. このsysをbuilderで確立し、プロセス全体が終了します.
终わりの言叶:ここはただ1つの最も简単な例で、もしこのような“小さい”事だけをしてCoreDllを使うならば、鶏を杀して牛刀を使う意味を免れません.CoreDllの用途は大きく広がることができて、どのようにあなたの情熱と才能を発揮するかについては、私の力の及ぶ限りではありません.(^o^)
注1:ただし、Windows 98の第2版またはWindows MeではカーネルDLLはアンインストールされません.
注2:gccNTDrvFrameは私が書いたgccがwindows NT駆動を確立するフレームワークパッケージで、後で新しい文章で紹介します.
(PS:記事参照http://sluttery.spaces.live.com/blog/cns!3569FEA80C717FD4!519.entry)
このような機能を実現するためには、ユーザモードでのDLLと同様のメカニズムを提供する必要があるが、この「DLL」はカーネルにロードされる.実はWindows NTカーネル自体はとっくにこのようなメカニズムを利用しています.例えばHal.dll、ntoskrnl.Exceや、サードパーティ製ドライバに対してHAL層、カーネル層、実行体層の機能関数をそれぞれ導出したドライバなどがあります.
Tim Robertsの「カーネルモードのDLL」では、カーネルDLLの主な特徴が示されています.
カーネルDLLは、ユーザー・モードDLLと同じです.リンクは、DLLの構築時にインポート・ライブラリを生成し、このDLLを使用するドライバのターゲット・ライブラリのリストに含めます.レジストリテクニックもDLLを停止する特別な動作も必要ありません.カーネルDLLは、参照された他のドライバとともに自動的にロードされ、最後に参照されたドライバとともに自動的にアンインストールされます(注1).
このようなDLLを実現するために、RobertsはDDKを使用してTARGETYPEをEXPORT_として生成する方法を示した.DRIVERのプロジェクト.私は試して、望み通りに、確かにxxxを創立しました.Sysファイル、私はまたこのsysのPEタイプを観察して、それが標準のカーネルsysと変わらないことを発見して、それではgccで1つのカーネルモードのDLLを生成することができますか?答えは肯定的だ!Windows NTの下にあるCore Dllをgcc(MinGW)で書いている場合は、DDKのEXPORT_DRIVERタイプのモジュールを書くこともできますが、具体的なやり方は省略します...
はい、上は冗談です.ほほほ.MinGWでCoreDllを書く方法について詳しく説明します.
1 __declspec(dllexport) DDKAPI NTSTATUS DllInitialize(/
2 IN PUNICODE_STRING RegistryPath); 3 __declspec(dllexport) DDKAPI NTSTATUS DllUnload(void);
4.エクスポートする必要がある関数を作成します.ここでは例を示しただけなので、簡単なエクスポート関数を書きました.
1 __declspec(dllexport) DDKAPI NTSTATUS GetMagicNum(IN int *pVal) 2 { 3 if(!pVal) 4 { 5 DbgPrint("err : pVal == NULL!/n"); 6 return STATUS_DEVICE_CONFIGURATION_ERROR; 7 } 8 DbgPrint("*pVal is %d/n",*pVal); 9 *pVal *= 11 * 11; 10 DbgPrint("After OP --- *pVal is %d/n",*pVal); 11 return STATUS_SUCCESS
5. コネクタのdefファイルを作成します.内容は次のとおりです.
NAME CoreDll.sys
EXPORTS
DllInitialize PRIVATE
DllUnload PRIVATE
GetMagicNum
6. gccNTDrvFrameのbuilderを実行し、CoreDllのコンパイルと接続を完了し、エラーがなければいくつかのファイルが生成され、そのうち2つしか使用されません.1つはxxxです.Sys、これは言うまでもなく他の駆動呼び出しのCoreDllであり、もう一つはxxxである.lib、xxxを呼び出す必要があるすべてのものです.Sysの他のドライバの作成に必要なファイル、hal.lib、ntoskrnl.libはまったく同じです.
7. 別のDriverプロジェクトを新規作成し、b.batのlink接続オプションにxxxを追加します.lib.外部関数を宣言して呼び出す方法は次のとおりです.
__declspec(dllimport) DDKAPI NTSTATUS GetMagicNum(IN int *pVal); DDKAPI NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject,/ PUNICODE_STRING pRegistryPath) { PDEVICE_OBJECT pDevObj; NTSTATUS status = STATUS_DEVICE_CONFIGURATION_ERROR; PRINT("[%s]enter DriverEntry.../n",__func__); RtlInitUnicodeString(&DevName,DEVNAMEW); RtlInitUnicodeString(&SymlnkName,SYMLNKNAMEW); if(IoCreateDevice(pDriverObject,0,&DevName,FILE_DEVICE_UNKNOWN,/
0,false,&pDevObj) != STATUS_SUCCESS) { PRINT("[%s]IoCreateDevice Failed!/n",__func__); goto QUIT; } if(IoCreateSymbolicLink(&SymlnkName,&DevName) != STATUS_SUCCESS) { IoDeleteDevice(pDevObj); PRINT("[%s]IoCreateSymbolicLink Failed!/n",/ __func__); goto QUIT; } pDevObj->Flags |= DO_BUFFERED_IO; pDriverObject->DriverUnload = DriverUnload; pDriverObject->MajorFunction[IRP_MJ_CREATE] = / DrvDispatchCreateClose; pDriverObject->MajorFunction[IRP_MJ_CLOSE] = / DrvDispatchCreateClose; pDriverObject->MajorFunction[IRP_MJ_READ] = / DispatchRead; pDriverObject->MajorFunction[IRP_MJ_WRITE] = / DispatchWrite; pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = / DrvDispatchControl; pDriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = / DrvShutdown; if(!NT_SUCCESS(IoRegisterShutdownNotification(/ pDriverObject->DeviceObject))) { PRINT("[%s]err : Register Shutdown Failed!/n",/ __func__); } int i = 11; GetMagicNum(&i); PRINT("[%s]Addr of KeServiceDescriptorTable : %p/n",/ __func__,KeServiceDescriptorTable); PRINT("[%s]leave DriverEntry.../n",__func__); status = STATUS_SUCCESS; QUIT: return status; }
もちろんDriverEntryで呼び出す必要はありません.xxxですから.Sysはシステムによってsysを呼び出す前に自動的に動的にロードされる.
8. このsysをbuilderで確立し、プロセス全体が終了します.
终わりの言叶:ここはただ1つの最も简単な例で、もしこのような“小さい”事だけをしてCoreDllを使うならば、鶏を杀して牛刀を使う意味を免れません.CoreDllの用途は大きく広がることができて、どのようにあなたの情熱と才能を発揮するかについては、私の力の及ぶ限りではありません.(^o^)
注1:ただし、Windows 98の第2版またはWindows MeではカーネルDLLはアンインストールされません.
注2:gccNTDrvFrameは私が書いたgccがwindows NT駆動を確立するフレームワークパッケージで、後で新しい文章で紹介します.
(PS:記事参照http://sluttery.spaces.live.com/blog/cns!3569FEA80C717FD4!519.entry)