Forum | | | | | Halla alle zusammen...
Beim Durchstöbern von diesem [...] haben sich bei mir eine Menge an Fragen aufgehäuft - damit man sie besser abarbeiten kann, werde ich sie mal nummerieren :
1.) Es geht mir hier um das Memmory-Scanning im Kernelmode. Um in den Kernelmode zu gelangen, muß ich einen Service schreiben - genauer gesagt einen Service mit dem Flag SERVICE_KERNEL_DRIVER. Hat jemand Links zu Quelltexten für die Programmierung von Services (erst mal ohne diesen Flag) - egal in welcher Sprache? Es geht nicht um die Installierung, das kann ich, nur um den Service selbst.
2.) Da Profan von sich aus schon User-APIs aufruft (u.a. aus der User32) und diese APIs bei einem Kernelmode-Treiber nicht zur Verfügung stehen, ist die Programmierung eines Services mit dem Flag SERVICE_KERNEL_DRIVER in Profan nicht möglich - sehe ich das richtig?
3.) [quote:f7bf3be205]Unfortunately, some of the important APIs needed for memory scanning are not exported by name from NTOSKRNL.EXE for the use of a Kernel mode driver.[/quote:f7bf3be205] Demnach dürfte ich nur APIs aus NTOSKRNL.EXE, der WIN32K.SYS und der HAL.DLL verwenden, ist das richtig (Native APIs)?
4.) Für einen Service benötige ich die API RegisterServiceCtrlHandler. Die API kommt aus der ADVAPI32 und steht mir deshalb bei der Programmierung eines Kernelmode-Treibers nicht zur Verfügung, sehe ich das richtig? Welche Funktion verwende ich stattdessen?
5.) [quote:f7bf3be205]When a User mode application calls the KERNEL32.DLLÞVirtualQueryEx() API the call is redirected to the NTDLL.DLLÞNtQueryVirtualMemory() function. This API is not available from NTOSKRNL.EXE.[/quote:f7bf3be205] Ich glaube, das habe ich verstanden . [quote:f7bf3be205]A driver can solve this problem in two different ways. It can be linked against NTDLL.DLL. is the easiest way.[/quote:f7bf3be205] Einfach ist imer gut - doch wie verlinke ich gegen NTDLL? Steht mir NTDLL überhaupt zur Verfügung ? Wie verlinke ich gegen NTDLL ohne das mir LoadLibrary zur Verfügung steht?
6.) [quote:f7bf3be205]NtQueryVirtualMemory() queries the pages of a particular process. It is not documented but is only a translation of the VirtualQueryEx() API. ZwQueryVirtualMemory() is placed in NTOSKRNL.EXE and its name is shown by the Windows NT kernel debugger since the debug information contains the name of the function.[/quote:f7bf3be205] Die Funkton, die ich also zum bestimmen der zugewiesenen Seiten benötige, heißt also ZwQueryVirtualMemory(), richtig? |
| | | | |
| | | So, Frage Nummer 1 hat sich schon mal erledigt . Habe grad einen (ganz) kleinen Service geschrieben ... |
| | | | |
| | Frank Abbing | Hier ein Assemblercode, um einen Service zu proggen: KompilierenMarkierenSeparieren!; --------------------------------------------
; Framework for Windows NT/2000/XP service application
; Written by Franck hitchhikr Charlet 10-2002.
; --------------------------------------------
; This is a skeleton for an auto loading/shutting down NT service.
; That service will un/register itself too.
; --------------------------------------------
; buildblock RELEASE
; CAPT [BINDIR]ml.exe /c /coff "%1.asm"
; CAPT [BINDIR]Link.exe /SUBSYSTEM:WINDOWS "%1.obj"
; buildblockend
; buildblock DEBUG
; CAPT [BINDIR]ml.exe /Zd /Zi /c /coff "%1.asm"
; CAPT [BINDIR]Link.exe /DEBUG /DEBUGTYPE:CV /SUBSYSTEM:WINDOWS "%1.obj"
; buildblockend
.386
.model flat,stdcall
option casemap:none
; --------------- Includes
include masm32includewindows.inc
include masm32includekernel32.inc
include masm32includeuser32.inc
include masm32includeadvapi32.inc
includelib masm32libkernel32.lib
includelib masm32libuser32.lib
includelib masm32libadvapi32.lib
; Not defined in Windows.inc (as usual)
SERVICE_CONFIG_DESCRIPTION equ 1
SERVICE_DESCRIPTIONA STRUCT
lpDescription LPSTR 0
SERVICE_DESCRIPTIONA ENDS
SERVICE_DESCRIPTION TEXTEQU <SERVICE_DESCRIPTION>
; --------------- Service datas
.data
ServiceHandle dd 0
ServicesDatabase dd 0
ServiceCurrentStatus dd 0
ServiceEvent dd 0
hServiceThread dd 0
OsVer OSVERSIONINFO <>
ServiceDesc dd 0
ServiceStatus dd 0
; must be grouped
ServiceTable SERVICE_TABLE_ENTRY <0,0>
SERVICE_TABLE_ENTRY <0,0>
;
ServiceStatusTable SERVICE_STATUS <>
FileName db MAX_PATH + 1 dup (0)
ErrStartMsg db "Cant initialize control dispatcher.",0
ErrServiceDBMsg db "Cant open services database.",0
ErrCreateServiceMsg db "Cant create service.",0
ErrOpenServiceMsg db "Cant open service.",0
ErrRemoveServiceMsg db "Cant remove service.",0
ServiceInstalledMsg db "Service installed.",0
ServiceRemovedMsg db "Service removed.",0
; --------------- User datas
; Real name of the service
ServiceName db "MyService",0
; Description shown in windows 2000 and above
ServiceDescription db "Service description here",0
; The service should start as soon as it is installed or not
ServiceStartRightNow dd TRUE
; How and when the service should start
; SERVICE_BOOT_START
; SERVICE_SYSTEM_START
; SERVICE_AUTO_START
; SERVICE_DEMAND_START < Start it with the service manager of Windows.
ServiceStartFlag dd SERVICE_DEMAND_START
; Type of service
ServiceTypeFlag dd SERVICE_WIN32_OWN_PROCESS or SERVICE_INTERACTIVE_PROCESS
; --------------------------------------------
; User code
; --------------------------------------------
.code
; --------------- Perform tasks right before service effective creation
; Out: 0 = Stop install process
; 1 = Proceed with install
; ---------------
; ServicesDatabase variable is initialized
; ---------------
; (Tip: This routine can be used to display dialogs or whatever)
ServiceStart proc
xor eax,eax
inc eax
ret
ServiceStart endp
; --------------- Perform tasks right before service effective removal
; Out: 0 = Stop removal process
; 1 = Proceed with removal
; ---------------
; ServicesDatabase variable is initialized
; ServiceHandle variable is initialized
; ---------------
; (Tip: This routine can be used to display dialogs or whatever)
ServiceRemove proc
xor eax,eax
inc eax
ret
ServiceRemove endp
; --------------- Background Thread (infinite) of the service
ServiceThread proc param:dword
; Put your code here
ThreadLoop: invoke Sleep,1
jmp ThreadLoop
ServiceThread endp
; --------------------------------------------
; Background code
; --------------------------------------------
; --------------- Display an error and terminate process
RaiseError proc ErrorMsg:dword
invoke MessageBoxA,0,ErrorMsg,addr ServiceName,MB_OK or MB_ICONERROR
invoke ExitProcess,0
ret
RaiseError endp
; --------------- Display an informative message
RaiseInformation proc InfoMsg:dword
invoke MessageBoxA,0,InfoMsg,addr ServiceName,MB_OK or MB_ICONINFORMATION
ret
RaiseInformation endp
; --------------- Service entry point
; Must run 3 in ways with the same procedure:
; 1. Install
; 2. Start
; 3. Remove
start: invoke OpenSCManager,0,0,SC_MANAGER_CREATE_SERVICE
mov ServicesDatabase,eax
test eax,eax
jnz DatabaseObtained
invoke RaiseError,addr ErrServiceDBMsg
DatabaseObtained: ; Check if the service is in starting state
invoke OpenService,ServicesDatabase,addr ServiceName,SERVICE_ALL_ACCESS
mov ServiceHandle,eax
test eax,eax
jz InvalidService
invoke QueryServiceStatus,ServiceHandle,addr ServiceStatusTable
test eax,eax
jz NoServiceState
mov eax,ServiceStatusTable.dwCurrentState
; Feed service manager with our thread if starting state
cmp eax,SERVICE_START_PENDING
je ServiceStartup
NoServiceState: invoke CloseServiceHandle,ServiceHandle
jmp InstallProceed
InvalidService: ; Call user procedure
call ServiceStart
test eax,eax
jnz InstallProceed
invoke CloseServiceHandle,ServicesDatabase
invoke ExitProcess,0
InstallProceed: invoke GetModuleFileName,0,addr FileName,MAX_PATH
; Try to install
invoke CreateService,ServicesDatabase,addr ServiceName,addr ServiceName,SERVICE_ALL_ACCESS,ServiceTypeFlag,ServiceStartFlag,SERVICE_ERROR_NORMAL,addr FileName,0,0,0,0,0
mov ServiceHandle,eax
test eax,eax
jnz ServiceCreated
invoke GetLastError
cmp eax,ERROR_SERVICE_EXISTS
jne ServiceAlreadyExists
; Perform removal
invoke OpenService,ServicesDatabase,addr ServiceName,SERVICE_ALL_ACCESS or DELETE
mov ServiceHandle,eax
test eax,eax
jnz ServiceOpened
invoke CloseServiceHandle,ServicesDatabase
invoke RaiseError,addr ErrOpenServiceMsg
ServiceOpened: invoke QueryServiceStatus,ServiceHandle,addr ServiceStatusTable
mov eax,ServiceStatusTable.dwCurrentState
cmp eax,SERVICE_STOPPED
je ServiceAlreadyStopped
invoke ControlService,ServiceHandle,SERVICE_CONTROL_STOP,addr ServiceStatusTable
invoke Sleep,500
ServiceAlreadyStopped: ; Call user procedure
call ServiceRemove
test eax,eax
jnz RemoveProceed
invoke CloseServiceHandle,ServiceHandle
invoke CloseServiceHandle,ServicesDatabase
invoke ExitProcess,0
RemoveProceed: invoke DeleteService,ServiceHandle
test eax,eax
jnz ServiceRemoved
invoke CloseServiceHandle,ServiceHandle
invoke CloseServiceHandle,ServicesDatabase
invoke RaiseError,addr ErrRemoveServiceMsg
ServiceRemoved: invoke CloseServiceHandle,ServiceHandle
invoke CloseServiceHandle,ServicesDatabase
invoke RaiseInformation,addr ServiceRemovedMsg
invoke ExitProcess,0
ServiceAlreadyExists: invoke CloseServiceHandle,ServicesDatabase
invoke RaiseError,addr ErrCreateServiceMsg
ServiceCreated: mov [OsVer.dwOSVersionInfoSize],sizeof OsVer;
invoke GetVersionEx,addr OsVer
test eax,eax
jz CantObtainOSVersion
.if [OsVer.dwOSVersionInfoSize] >= 5
; Add a description if OS >= Win2k
.if [OsVer.dwPlatformId] == VER_PLATFORM_WIN32_NT
mov eax,offset ServiceDescription
mov [ServiceDesc], eax
invoke ChangeServiceConfig2, ServiceHandle, SERVICE_CONFIG_DESCRIPTION, addr ServiceDesc
.endif
.endif
CantObtainOSVersion: .if ServiceStartRightNow != FALSE
invoke StartService,ServiceHandle,0,0
.endif
invoke CloseServiceHandle,ServiceHandle
invoke CloseServiceHandle,ServicesDatabase
invoke RaiseInformation,addr ServiceInstalledMsg
invoke ExitProcess,0
ServiceStartup: invoke CloseServiceHandle,ServiceHandle
invoke CloseServiceHandle,ServicesDatabase
mov ServiceTable.lpServiceName,offset ServiceName
mov ServiceTable.lpServiceProc,offset ServiceMain
invoke StartServiceCtrlDispatcher,addr ServiceTable
test eax,eax
jnz ServiceDispatch
invoke RaiseError,addr ErrStartMsg
ServiceDispatch: invoke ExitProcess,eax
; --------------- Initialize service thread
InitServiceThread proc
local ThreadID:dword
invoke CreateThread,0,0,addr ServiceThread,0,0,addr ThreadID
mov hServiceThread,eax
test eax,eax
jz Err_InitThread
xor eax,eax
inc eax
or ServiceCurrentStatus,eax
Err_InitThread: ret
InitServiceThread endp
; --------------- Resume service
ResumeService: and ServiceCurrentStatus,0fffffffdh
invoke ResumeThread,hServiceThread
ret
; --------------- Pause service
PauseService: or ServiceCurrentStatus,2
invoke SuspendThread,hServiceThread
ret
; --------------- Stop service
StopService: and ServiceCurrentStatus,0fffffffeh
invoke SetEvent,ServiceEvent
ret
; --------------- Send message to system
SendStatus proc dwCurrentState:dword,dwWin32ExitCode:dword,dwServiceSpecificExitCode:dword,dwCheckPoint:dword,dwWaitHint:dword
mov ServiceStatusTable.dwServiceType,SERVICE_WIN32_OWN_PROCESS
push dwCurrentState
pop ServiceStatusTable.dwCurrentState
cmp dwCurrentState,SERVICE_START_PENDING
jne SStatusStartPending
mov ServiceStatusTable.dwControlsAccepted,0
jmp CheckSStatusPending
SStatusStartPending: mov ServiceStatusTable.dwControlsAccepted,SERVICE_ACCEPT_STOP or SERVICE_ACCEPT_PAUSE_CONTINUE or SERVICE_ACCEPT_SHUTDOWN
CheckSStatusPending: cmp dwServiceSpecificExitCode,0
jne SStatusSetExitCode
push dwWin32ExitCode
pop ServiceStatusTable.dwWin32ExitCode
jmp CheckSStatusExitCode
SStatusSetExitCode: mov ServiceStatusTable.dwWin32ExitCode,ERROR_SERVICE_SPECIFIC_ERROR
CheckSStatusExitCode: push dwServiceSpecificExitCode
pop ServiceStatusTable.dwServiceSpecificExitCode
push dwCheckPoint
pop ServiceStatusTable.dwCheckPoint
push dwWaitHint
pop ServiceStatusTable.dwWaitHint
invoke SetServiceStatus,ServiceStatus,addr ServiceStatusTable
xor eax,eax
inc eax
ret
SendStatus endp
; --------------- Terminate service
TerminateService proc ProvidedErr:dword
mov eax,ServiceEvent
test eax,eax
jz NoEventToTerminate
push eax
call CloseHandle
NoEventToTerminate: mov eax,ServiceStatus
test eax,eax
jz NoWorkingService
invoke SendStatus,SERVICE_STOPPED,ProvidedErr,0,0,0
NoWorkingService: mov eax,hServiceThread
test eax,eax
jz NoThreadToTerminate
push eax
call CloseHandle
NoThreadToTerminate: xor eax,eax
ret
TerminateService endp
; --------------- Answer to system messages
CtrlHandler proc CtrlCode:dword
local StatetoSend:dword
mov StatetoSend,0
cmp CtrlCode,SERVICE_CONTROL_STOP
jne HandleServStop
invoke SendStatus,SERVICE_STOP_PENDING,NO_ERROR,0,1,5000
call StopService
mov StatetoSend,SERVICE_STOPPED
jmp SCHandler
HandleServStop: cmp CtrlCode,SERVICE_CONTROL_PAUSE
jne HandleServPause
cmp ServiceCurrentStatus,1
jne HandleServPause
invoke SendStatus,SERVICE_PAUSE_PENDING,NO_ERROR,0,1,1000
call PauseService
mov StatetoSend,SERVICE_PAUSED
jmp SCHandler
HandleServPause: cmp CtrlCode,SERVICE_CONTROL_CONTINUE
jne HandleServResume
cmp ServiceCurrentStatus,3
jne HandleServResume
invoke SendStatus,SERVICE_CONTINUE_PENDING,NO_ERROR,0,1,1000
call ResumeService
mov StatetoSend,SERVICE_RUNNING
jmp SCHandler
HandleServResume: cmp CtrlCode,SERVICE_CONTROL_INTERROGATE
je SCHandler
cmp CtrlCode,SERVICE_CONTROL_SHUTDOWN
jne SCHandler
ret
SCHandler: invoke SendStatus,StatetoSend,NO_ERROR,0,0,0
ret
CtrlHandler endp
; --------------- Service main handler
ServiceMain proc ArgC:dword,ArgV:dword
invoke RegisterServiceCtrlHandler,addr ServiceName,addr CtrlHandler
mov ServiceStatus,eax
test eax,eax
jnz RegisteredCtrlHandler
invoke GetLastError
invoke TerminateService,eax
ret
RegisteredCtrlHandler: invoke SendStatus,SERVICE_START_PENDING,NO_ERROR,0,1,5000
invoke CreateEvent,0,TRUE,FALSE,0
mov ServiceEvent,eax
test eax,eax
jnz RegisteredEvent
invoke GetLastError
invoke TerminateService,eax
ret
RegisteredEvent: invoke SendStatus,SERVICE_START_PENDING,NO_ERROR,0,2,1000
invoke SendStatus,SERVICE_START_PENDING,NO_ERROR,0,3,5000
invoke InitServiceThread
test eax,eax
jnz RegisteredThread
invoke GetLastError
invoke TerminateService,eax
ret
RegisteredThread: invoke SendStatus,SERVICE_RUNNING,NO_ERROR,0,0,0
invoke WaitForSingleObject,ServiceEvent,INFINITE
invoke TerminateService,0
ret
ServiceMain endp
end start
|
| | | | |
| | | Besten Dank! Den werde ich noch gebrauchen können!
PS: Vor allen Dingen an der Proc, die auf die Statusmessages reagiert, habe ich im Gegensatz zu deinem ASM-Code extrem gespart . |
| | | | |
| | | Frage 4 und 5 haben sich erledigt. |
| | | | |
| | | [quote:3a9089c8fa][quote:3a9089c8fa]A driver can solve this problem in two different ways. It can be linked against NTDLL.DLL. is the easiest way.[/quote:3a9089c8fa] Einfach ist imer gut - doch wie verlinke ich gegen NTDLL? Steht mir NTDLL überhaupt zur Verfügung ? Wie verlinke ich gegen NTDLL ohne das mir LoadLibrary zur Verfügung steht? [/quote:3a9089c8fa] Der Autor des Artikels verschleiert hier aus Sicherheitsgründen scheinbar absichtlich etwas: Natürlich kann man nicht gegen NTDLL verlinken, wenn NTDLL gar nicht zur Verfügung steht - aber es gibt eine weitere Native-API, mit der man bestimmte Module in den Kernel nachladen kann (und die ist hier nicht erwähnt). Über diese API ist es auch möglich einen Treiber zu starten, ohne diesen als Service zu registrieren. Ich bin eigentlich davon ausgegangen, daß man zum Ausführen dieser speziellen API ein bestimmtes Privileg aktivieren muß und war dann erst sehr erschrocken, daß das gar nicht der Fall ist. Diese Privileg muß aber definitiv (und zum Glück) vorhanden sein.
Gruß
Andreas |
| | | | |
| | Sebastian König | Hallo Andreas,
ich habe vor ein paar Tagen [...] sehr interessanten Artikel gelesen. Natürlich weiß ich nicht, ob da etwas drinsteht, was Du noch nicht weißt...
MfG
Sebastian |
| | | | |
| | | Ich fang ja grade erst an - her damit! |
| | | | |
| | Sebastian König | [quote:0e34cddc70]Ich fang ja grade erst an - her damit![/quote:0e34cddc70] Folge einfach dem Link - auch die anderen Artikel auf der Seite (verschiedene Themen) finde ich sehr lesenswert. |
| | | | |
| | | Hab den Link übersehen - sieht gut aus, danke! |
| | | | |
| | | Ist sogar genau das, was ich noch brauchte. Danke! |
| | | | |
|
AntwortenThemenoptionen | 1.414 Betrachtungen |
ThemeninformationenDieses Thema hat 3 Teilnehmer: |
|