Re: Driver development using PureBasic
Posted: Mon Mar 04, 2013 6:21 pm
This is great - it should be added to the main program. 

http://www.purebasic.com
https://www.purebasic.fr/english/
+1DoubleDutch wrote:This is great - it should be added to the main program.
PB generates FASM, and uses FASM.EXE to build PE/EXE/DLL. This just uses custom macros and intercepts IDE. I guess nobody ever actually looked to see how PB worked.Nituvious wrote:Wow, very cool! I thought driver creation was assumed to be impossible with PureBasic?
Examples in the folder "Examples\Driver\".1. Install PureBasic 5.11 x86 to any folder.
2. Open directory where you installed PureBasic, and in the folder "Compilers" rename files Fasm.exe and Polink.exe in Fasm_.exe and Polink_.exe.
3. Open folder "PureLibraries\Windows\Libraries\" and delete all files.
4. Extract the archive in directory where you installed PureBasic 5.11 x86.
5. Run the program "IDE PB5.11 x86 Patch.exe", which will change the extension saved executable files with .exe on .sys.
To select the type of memory (Paged or NonPaged) intended a macro.System pool (to user pool have no relation) are two so-called memory pools, which, naturally, are located in the system address space: Pool nonpaged memory (Nonpaged Pool). So named because its pages are never reset the paging file, and therefore never spooled back. Ie the pool is always present in physical memory and is available at any IRQL. One reason for its existence is that the recourse to such memory can cause an error page (Page Fault). These errors lead to the collapse of the system, if there are at IRQL> = DISPATCH_LEVEL. Pool paged memory (Paged Pool). So named because its pages can be reset to the paging file, and therefore need to be pumped up back at the subsequent appeal to them. This memory can be used only when the IRQL is strictly less than DISPATCH_LEVEL. Both pools located in system address space, and hence accessible from any process context. To allocate memory in the system pools, there is a set of functions ExAllocatePoolXxx, and for the return of the allocated memory is only one - ExFreePool.
Code: Select all
SetPoolMode(Mode)
Code: Select all
GetPoolMode()
Code: Select all
Enumeration
#Pool_NonPaged ; Only use NonPaged memory. Valid at any level IRQL, but this memory is extremely deficient and it can not be wasted. This is the default.
#Pool_Paged ; Use only Memory is Paged. Valid at IRQL < #DISPATCH_LEVEL.
#Pool_Auto ; Automatic selection of the type of memory depending on the IRQL.
EndEnumeration
Code: Select all
!CALL _PB_EOP
Code: Select all
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)
SetPoolMode(#Pool_Auto) ; Автоматический выбор типа памяти в зависимости от IRQL.
s.s="1234 "
s+"5678 "+Random(1234)
DbgPrint(s)
*DriverObject\DriverUnload = @DriverUnload()
ProcedureReturn #STATUS_SUCCESS
EndProcedure
Code: Select all
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)
SetPoolMode(#Pool_Auto) ; Автоматический выбор типа памяти в зависимости от IRQL.
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
Code: Select all
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)
SetPoolMode(#Pool_Auto) ; Автоматический выбор типа памяти в зависимости от IRQL.
NewList x()
For i=1 To 100
If AddElement(x())
x()=i
EndIf
Next i
DbgPrint("Size list "+ListSize(x())+" items")
ForEach x()
DbgPrint(Str(x()))
Next
*DriverObject\DriverUnload = @DriverUnload()
ProcedureReturn #STATUS_SUCCESS
EndProcedure
Code: Select all
Declare DriverEntry(*DriverObject, *RegistryPath)
*Point=@DriverEntry()
!jmp [p_Point]
IncludePath #PB_Compiler_Home+"DDK\"
XIncludeFile "ntddk.pbi"
XIncludeFile "ntstatus.pbi"
XIncludeFile "ntfunct.pbi"
EnableExplicit
Procedure DriverUnload(*DriverObject.DRIVER_OBJECT)
DbgPrint("Unload Driver")
!CALL _PB_EOP ; Освобождение ресурсов.
EndProcedure
Procedure DriverEntry(*DriverObject.DRIVER_OBJECT, *RegistryPath.UNICODE_STRING)
Protected i, String.s="Installed on your computer OS "
DbgPrint("Load Driver")
Select OSVersion()
Case #PB_OS_Windows_2000
String+"Windows 2000"
Case #PB_OS_Windows_XP
String+"Windows XP"
Case #PB_OS_Windows_Server_2003
String+"Windows 2003"
Case #PB_OS_Windows_Vista
String+"Windows Vista"
Case #PB_OS_Windows_Server_2008
String+"Windows 2008"
Case #PB_OS_Windows_7
String+"Windows 7"
Case #PB_OS_Windows_Server_2008_R2
String+"Windows 2008"
Case #PB_OS_Windows_8
String+"Windows 8"
Default
String+"unknown"
EndSelect
DbgPrint(String)
*DriverObject\DriverUnload = @DriverUnload()
ProcedureReturn #STATUS_SUCCESS
EndProcedure
Code: Select all
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)
SetPoolMode(#Pool_Auto) ; Автоматический выбор типа памяти в зависимости от IRQL.
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
Code: Select all
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)
SetPoolMode(#Pool_Auto) ; Автоматический выбор типа памяти в зависимости от IRQL.
DbgPrint("Wait 1 sec.")
Time = ElapsedMilliseconds()
Delay(1000)
DbgPrint(Str(ElapsedMilliseconds()-Time))
*DriverObject\DriverUnload = @DriverUnload()
ProcedureReturn #STATUS_SUCCESS
EndProcedure
Code: Select all
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)
SetPoolMode(#Pool_Auto) ; Автоматический выбор типа памяти в зависимости от IRQL.
*Mem.Long = AllocateMemory(20)
If *Mem
DbgPrint("Memory size: "+Str(MemorySize(*Mem)))
*Mem\l = 1234
*Mem_2.Long = AllocateMemory(20)
If *Mem_2
DbgPrint("CopyMemory")
CopyMemory(*Mem, *Mem_2, MemorySize(*Mem_2))
DbgPrint("Value: "+Str(*Mem_2\l))
FreeMemory(*Mem_2)
*Mem_2=0
EndIf
DbgPrint("ReAllocateMemory")
*Mem=ReAllocateMemory(*Mem, 100)
If *Mem
DbgPrint("Value: "+Str(*Mem\l))
EndIf
If *Mem
FreeMemory(*Mem)
EndIf
EndIf
*DriverObject\DriverUnload = @DriverUnload()
ProcedureReturn #STATUS_SUCCESS
EndProcedure
Code: Select all
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)
SetPoolMode(#Pool_Auto) ; Автоматический выбор типа памяти в зависимости от IRQL.
; 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
Code: Select all
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)
; Этот выбор типа памяти работает только для функций PB. На функции ядра, типа ExAllocatePool(), он не распространяется.
SetPoolMode(#Pool_NonPaged) ; В дальнейшем память будет выделяться только из НЕподкачиваемого пула.
; Это необходимо только для уровня IRQL >= #DISPATCH_LEVEL.
x.s="This NonPagedPool memory" ; Память под массив выделена из НЕподкачиваемого пула.
DbgPrint(x)
SetPoolMode(#Pool_Paged) ; В дальнейшем память будет выделяться только из подкачиваемого пула.
; Будет работать если уровнь IRQL < #DISPATCH_LEVEL, на более высоком уровне может быть BSoD.
y.s="This PagedPool memory" ; Память под массив выделена из подкачиваемого пула.
DbgPrint(y)
SetPoolMode(#Pool_Auto) ; В дальнейшем , будет автоматический выбор типа памяти в зависимости от IRQL..
a.s="Auto mode type memory" ; В зависимости от уровня IRQL, память будет выделена из подкачиваемого или НЕподкачиваемого пула.
DbgPrint(a)
*DriverObject\DriverUnload = @DriverUnload()
ProcedureReturn #STATUS_SUCCESS
EndProcedure
Code: Select all
Declare DriverEntry(*DriverObject, *RegistryPath)
*Point=@DriverEntry()
!jmp [p_Point]
IncludePath #PB_Compiler_Home+"DDK\"
XIncludeFile "ntddk.pbi"
XIncludeFile "ntstatus.pbi"
XIncludeFile "ntfunct.pbi"
EnableExplicit
Global Mutex, ExitFlag
Procedure DriverUnload(*DriverObject.DRIVER_OBJECT)
ExitFlag=#True
Delay(400)
If Mutex
FreeMutex(Mutex)
EndIf
DbgPrint("Unload Driver")
!CALL _PB_EOP ; Освобождение ресурсов.
EndProcedure
Procedure WithoutMutex(x)
Protected a, b
For a = 1 To 5
LockMutex(Mutex)
DbgPrint("Thread "+Str(x)+": Trying to print 5x in a row:")
For b = 1 To 5
Delay(50)
If ExitFlag=#True
UnlockMutex(Mutex)
Break 2
EndIf
DbgPrint("Thread "+Str(x)+" Line "+Str(b))
Next b
UnlockMutex(Mutex)
Next a
LockMutex(Mutex)
DbgPrint("Exit Thread "+x)
UnlockMutex(Mutex)
PsTerminateSystemThread(#STATUS_SUCCESS)
EndProcedure
Procedure DriverEntry(*DriverObject.DRIVER_OBJECT, *RegistryPath.UNICODE_STRING)
Protected i
SetPoolMode(#Pool_Auto) ; Автоматический выбор типа памяти в зависимости от IRQL.
DbgPrint("Load Driver")
ExitFlag = #False
Mutex = CreateMutex()
If Mutex
LockMutex(Mutex)
DbgPrint("Run ThreadID "+Str(CreateThread(@WithoutMutex(), 1)))
Delay(25)
DbgPrint("Run ThreadID "+Str(CreateThread(@WithoutMutex(), 2)))
Delay(25)
DbgPrint("Run ThreadID "+Str(CreateThread(@WithoutMutex(), 3)))
UnlockMutex(Mutex)
Else
DbgPrint("Error CreateMutex()")
EndIf
*DriverObject\DriverUnload = @DriverUnload()
ProcedureReturn #STATUS_SUCCESS
EndProcedure
Test drivers must be in a virtual machine.
2.2 - Supports function OSVersion(), Mutex-functions, as well as function CreateThread() and WaitThread(), from library "Thread".
****
2.1 - The default is used nonpaged memory, that is needed to initialize the runtime PB.
****
2.0 - Supported library: "Array", "Cipher", "LinkedList", "Map", "Math", "Memory", "Misc", "RegularExpression", "Sort" and "String".
****
1.0 - The first version. Only supports library "Math" and "Memory".
1. Install PureBasic 5.31 x64 to any folder.
2. Open directory where you installed PureBasic, and in the folder "Compilers" rename files Fasm.exe and Polink.exe in Fasm_.exe and Polink_.exe.
3. Open folder "PureLibraries\Windows\Libraries\" and delete all files.
4. Extract the archive in directory where you installed PureBasic 5.31 x64.
5. Run the program "IDE PB5.31 x64 Patch.exe", which will change the extension saved executable files with .exe on .sys.
He is too busy adding proper x64 support, leave him be!AAT wrote:I do not know why the author did not answer you.