В отличие от
предыдущей версии, эта версия поддерживает работу со строками, а так же динамические и ассоциативные массивы, связные списки и конечно же динамическое содержимое в структурах (строки, массивы, списки и т. д.). Архив во вложении.
Цитата:
Установка.
1. Установить PureBasic 5.11 x86 в любую папку.
2. Открыть папку с установленным PureBasic и в папке "Compilers" переименовать файлы Fasm.exe и Polink.exe в Fasm_.exe и Polink_.exe.
3. Открыть папку "PureLibraries\Windows\Libraries\" и удалить все файлы.
4. Извлечь архив в папку с установленным PureBasic 5.11 x86.
5. Запустить программу "IDE PB5.11 x86 Patch.exe", которая изменит расширение сохраняемых исполняемых файлов с .exe на .sys.
Кроме того, работают функции Random() и Delay(), а так же функции работы с памятью. Примеры в папке
Examples\Driver\.Только учтите, что для всего этого используется память ядра и ее нужно экономить. Есть еще одна особенность работы с памятью (цитата с wasm.ru).
Цитата:
Системные кучи (к пользовательским кучам не имеют никакого отношения) представлены двумя так называемыми пулами памяти, которые, естественно, располагаются в системном адресном пространстве:
Пул неподкачиваемой памяти (Nonpaged Pool). Назван так потому, что его страницы никогда не сбрасываются в файл подкачки, а значит, никогда и не подкачиваются назад. Т.е. этот пул всегда присутствует в физической памяти и доступен при любом IRQL. Одна из причин его существования в том, что обращение к такой памяти не может вызвать ошибку страницы (Page Fault). Такие ошибки приводят к краху системы, если происходят при IRQL >= DISPATCH_LEVEL.
Пул подкачиваемой памяти (Paged Pool). Назван так потому, что его страницы могут быть сброшены в файл подкачки, а значит должны быть подкачаны назад при последующем к ним обращении. Эту память можно использовать только при IRQL строго меньше DISPATCH_LEVEL.
Оба пула находятся в системном адресном пространстве, а значит, доступны из контекста любого процесса. Для выделения памяти в системных пулах существует набор функций ExAllocatePoolXxx, а для возвращения выделенной памяти всего одна - ExFreePool.
Для того чтобы была возможность выбрать тип памяти (подкачиваемая или нет), был добавлен макрос
Код:
Возможные значения.
Код:
1 2 3 4 5
| Enumeration #Pool_NonPaged ; Использовать только неподкачиваемую память. Допустимо на любом уровне IRQL, но эта память крайне дефицитна и растрачивать впустую ее нельзя. Это по умолчанию. #Pool_Paged ; Использовать только подкачиваемую память. Допустимо на уровне IRQL меньше #DISPATCH_LEVEL. #Pool_Auto ; Автоматический выбор типа памяти в зависимости от IRQL. EndEnumeration |
Смена типа памяти действует только на последующие выделения памяти, а тип уже выделенной памяти не меняется. И кроме того, это действует только на функции PB. На вызов функции ядра ExAllocatePool() и ей подобных, не распространяется. Пример использования в "Examples\Driver\Simple\SelectMemoryType.pb".
Так же нужно следить за освобождением памяти. Даже если драйвер был выгружен из памяти, это не освободит ресурсы и память будет занята до перезагрузки системы. Если память неподкачиваемая, это равносильно уменьшению размера физической памяти!
В конце процедуры DriverUnload() нужно добавить строку.
Код:
Это освободит память используемую рантаймом PB.
Минус этой версии в том, что рантайм не вырезается (в предыдущей версии он резался на корню потому что он использует WinAPI) и из-за этого размер драйвера довольно ощутимый. Но без рантайма и инициализации объектов, нельзя использовать строки, динамические массивы, связанные списки и т. д.
Пара примеров работы со строками, массивами и т. д.
Соединение строк и использование Random().
Код:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| Declare DriverEntry(*DriverObject, *RegistryPath) *Point=@DriverEntry() !jmp [p_Point] IncludePath #PB_Compiler_Home+"DDK\" XIncludeFile "ntddk.pbi" XIncludeFile "ntstatus.pbi" XIncludeFile "ntfunct.pbi" Procedure DriverUnload(*DriverObject.DRIVER_OBJECT) !CALL _PB_EOP ; Освобождение ресурсов. EndProcedure Procedure DriverEntry(*DriverObject.DRIVER_OBJECT, *RegistryPath.UNICODE_STRING) s.s="1234 " s+"5678 "+Random(1234) DbgPrint(s) *DriverObject\DriverUnload = @DriverUnload() ProcedureReturn #STATUS_SUCCESS EndProcedure |
Работа с массивом.
Код:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| Declare DriverEntry(*DriverObject, *RegistryPath) *Point=@DriverEntry() !jmp [p_Point] IncludePath #PB_Compiler_Home+"DDK\" XIncludeFile "ntddk.pbi" XIncludeFile "ntstatus.pbi" XIncludeFile "ntfunct.pbi" Procedure DriverUnload(*DriverObject.DRIVER_OBJECT) !CALL _PB_EOP ; Освобождение ресурсов. EndProcedure Procedure DriverEntry(*DriverObject.DRIVER_OBJECT, *RegistryPath.UNICODE_STRING) Dim x.a(10) x(10)=2 ReDim x(200) x(200)=4 s.s=Str(x(10))+" "+x(200) DbgPrint(s) DbgPrint(Str(ArraySize(x()))) *DriverObject\DriverUnload = @DriverUnload() ProcedureReturn #STATUS_SUCCESS EndProcedure |
Работа со списком.
Код:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| Declare DriverEntry(*DriverObject, *RegistryPath) *Point=@DriverEntry() !jmp [p_Point] IncludePath #PB_Compiler_Home+"DDK\" XIncludeFile "ntddk.pbi" XIncludeFile "ntstatus.pbi" XIncludeFile "ntfunct.pbi" Procedure DriverUnload(*DriverObject.DRIVER_OBJECT) !CALL _PB_EOP ; Освобождение ресурсов. EndProcedure Procedure DriverEntry(*DriverObject.DRIVER_OBJECT, *RegistryPath.UNICODE_STRING) NewList x() For i=1 To 100 If AddElement(x()) x()=i EndIf Next i DbgPrint(Str(ListSize(x()))) ForEach x() DbgPrint(Str(x())) Next *DriverObject\DriverUnload = @DriverUnload() ProcedureReturn #STATUS_SUCCESS EndProcedure |
Структура с массивом и списком.
Код:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| Declare DriverEntry(*DriverObject, *RegistryPath) *Point=@DriverEntry() !jmp [p_Point] IncludePath #PB_Compiler_Home+"DDK\" XIncludeFile "ntddk.pbi" XIncludeFile "ntstatus.pbi" XIncludeFile "ntfunct.pbi" Structure TestStruct x.a List l.l() k.q Array a.s(10) Map m.l() EndStructure Procedure DriverUnload(*DriverObject.DRIVER_OBJECT) !CALL _PB_EOP ; Освобождение ресурсов. EndProcedure Procedure DriverEntry(*DriverObject.DRIVER_OBJECT, *RegistryPath.UNICODE_STRING) x.TestStruct If AddElement(x\l()) x\l()=2 EndIf x\a(2)="Driver" x\m("dr")=1234 DbgPrint("List: "+x\l()) DbgPrint("Array: "+x\a(2)) DbgPrint("Map: "+x\m("dr")) *DriverObject\DriverUnload = @DriverUnload() ProcedureReturn #STATUS_SUCCESS EndProcedure |
Функция Delay().
Код:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| Declare DriverEntry(*DriverObject, *RegistryPath) *Point=@DriverEntry() !jmp [p_Point] IncludePath #PB_Compiler_Home+"DDK\" XIncludeFile "ntddk.pbi" XIncludeFile "ntstatus.pbi" XIncludeFile "ntfunct.pbi" Procedure DriverUnload(*DriverObject.DRIVER_OBJECT) !CALL _PB_EOP ; Освобождение ресурсов. EndProcedure Procedure DriverEntry(*DriverObject.DRIVER_OBJECT, *RegistryPath.UNICODE_STRING) DbgPrint("Delay 4 sec.") Delay(4000) DbgPrint("End Delay") *DriverObject\DriverUnload = @DriverUnload() ProcedureReturn #STATUS_SUCCESS EndProcedure |
Использование функций AES.
Код:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| Declare DriverEntry(*DriverObject, *RegistryPath) *Point=@DriverEntry() !jmp [p_Point] IncludePath #PB_Compiler_Home+"DDK\" XIncludeFile "ntddk.pbi" XIncludeFile "ntstatus.pbi" XIncludeFile "ntfunct.pbi" Procedure DriverUnload(*DriverObject.DRIVER_OBJECT) !CALL _PB_EOP ; Освобождение ресурсов. EndProcedure Procedure DriverEntry(*DriverObject.DRIVER_OBJECT, *RegistryPath.UNICODE_STRING) ; Should be compiled in ascii mode ; String$ = "Hello this is a test for AES" *CipheredString = AllocateMemory(Len(String$)+1) ; Space for the string and its *DecipheredString = AllocateMemory(Len(String$)+1) ; null terminating character (ASCII mode) If AESEncoder(@String$, *CipheredString, Len(String$), ?Key, 128, ?InitializationVector) DbgPrint("Ciphered: "+PeekS(*CipheredString)) AESDecoder(*CipheredString, *DecipheredString, Len(String$), ?Key, 128, ?InitializationVector) DbgPrint("Deciphered: "+PeekS(*DecipheredString)) EndIf DataSection Key: Data.b $06, $a9, $21, $40, $36, $b8, $a1, $5b, $51, $2e, $03, $d5, $34, $12, $00, $06 InitializationVector: Data.b $3d, $af, $ba, $42, $9d, $9e, $b4, $30, $b4, $22, $da, $80, $2c, $9f, $ac, $41 EndDataSection *DriverObject\DriverUnload = @DriverUnload() ProcedureReturn #STATUS_SUCCESS EndProcedure |
Сортировка массива.
Код:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| Declare DriverEntry(*DriverObject, *RegistryPath) *Point=@DriverEntry() !jmp [p_Point] IncludePath #PB_Compiler_Home+"DDK\" XIncludeFile "ntddk.pbi" XIncludeFile "ntstatus.pbi" XIncludeFile "ntfunct.pbi" Procedure DriverUnload(*DriverObject.DRIVER_OBJECT) !CALL _PB_EOP ; Освобождение ресурсов. EndProcedure Procedure DriverEntry(*DriverObject.DRIVER_OBJECT, *RegistryPath.UNICODE_STRING) Dim a.s(4) a(0)="1234" a(1)="asd" a(2)="myt" a(3)="zer" a(4)="89" RandomizeArray(a()) ; Рассортировка. For i=0 To 4 DbgPrint(a(i)) Next DbgPrint("-------------") SortArray(a(), #PB_Sort_Ascending) ; Сортировка. For i=0 To 4 DbgPrint(a(i)) Next *DriverObject\DriverUnload = @DriverUnload() ProcedureReturn #STATUS_SUCCESS EndProcedure |
Регулярные выражения. Правда, размер драйвера больше 150 КБ, что много!
Код:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| Declare DriverEntry(*DriverObject, *RegistryPath) *Point=@DriverEntry() !jmp [p_Point] IncludePath #PB_Compiler_Home+"DDK\" XIncludeFile "ntddk.pbi" XIncludeFile "ntstatus.pbi" XIncludeFile "ntfunct.pbi" Procedure DriverUnload(*DriverObject.DRIVER_OBJECT) !CALL _PB_EOP ; Освобождение ресурсов. EndProcedure Procedure DriverEntry(*DriverObject.DRIVER_OBJECT, *RegistryPath.UNICODE_STRING) If CreateRegularExpression(0, "[a-z]b[A-Z]") DbgPrint(Str(MatchRegularExpression(0, "abC"))) ; Will print 1 DbgPrint(Str(MatchRegularExpression(0, "abc"))) ; Will print 0 FreeRegularExpression(0) Else DbgPrint(RegularExpressionError()) EndIf *DriverObject\DriverUnload = @DriverUnload() ProcedureReturn #STATUS_SUCCESS EndProcedure |
Как проверить работу примеров?
Для начала их нужно скомпилировать, т. е. получить *.sys файл.
Теперь драйвер скомпилирован и его можно запустить чтобы посмотреть как он работает.
С помощью меню "Инструменты" среды PureBasic, запускаем два инструмента, имеющие имена
Dbgview и
KmdManager. В
KmdManager указываем путь к драйверу. Далее последовательно нажимаем следующие кнопки в окне: "Register", "Run", "Stop" и "Unregister".
Если повезет и не появится BSoD В окне программы
Dbgview увидим то, что драйвер передал ей используя функцию DbgPrint(). Если там будет пусто, проверьте есть ли галочка в пункте "Capture Kernel" меню "Capture" программы
Dbgview. Если нет, поставьте и перезапустите ее.
Вот что покажет
Dbgview при выполнении кода "Использование функций AES".

История версий.
Цитата:
2.2 - Поддерживается функция OSVersion(), Mutex-функции, а также функции CreateThread() и WaitThread() из библиотеки Thread.
****
2.1 - По умолчанию используется неподкачиваемая память, что необходимо для инициализации рантайма PB.
****
2.0 - Поддерживаются библиотеки: "Array", "Cipher", "LinkedList", "Map", "Math", "Memory", "Misc", "RegularExpression", "Sort" и "String".
****
1.0 - Первая версия. Поддерживались только библиотеки "Math" и "Memory".
Тестируйте драйверы на виртуальной машине.
_________________
Компьютер позволяет решать все те проблемы, которые до его изобретения не существовали.
