Re: CTL_CODE Funktion in Delphi
Zitat:
Zitat:
- Native API (UM) - Native API (KM) + Rest vom KM UM == User-Mode KM == Kernel-Mode Ich stehe dir gern per PM zur Verfügung, soweit es meine Zeit zuläßt. Vielleicht könnten wir gemeinsam einen Artikel zu diesem Thema verfassen - für das "de-delphi"-Projekt auf SF.net! |
Re: CTL_CODE Funktion in Delphi
Zu dem BOOLEAN
wenn das wirklich ByteBoll ist, dann sollte das wohl auch besser als ByteBoll definiert werden und nicht mal einfach so als Boolaen(Delphi) ich glaub das war so:
Delphi-Quellcode:
ByteBool(True) = $FF
Boolean(True) = $01 ByteBool(False) = $00 Boolean(False) = $00 ach ja, die C-Header im PSDK sind wohl an 8 Byte-Grenzen gepackt ... warum MS das im DDK anscheinend anders gemacht hat ... keine Ahnung ._. |
Re: CTL_CODE Funktion in Delphi
Zitat:
Reicht das? :zwinker: :mrgreen: Nachtrag: natürlich wissen wir ja alle, daß wir lieber Puffer mit Pointern benutzen sollten (über ExAllocatePoolWithTag), aber wenn man eben doch mal eine Struktur direkt auf dem Stack zu liegen hat, kann das kleinste Byte über Wohl oder Wehe des Threads entscheiden. |
Re: CTL_CODE Funktion in Delphi
Zitat:
|
Re: CTL_CODE Funktion in Delphi
Hallo,
anbei der Code zum Thema. Ich habe ihn überarbeitet und festgestellt, dass es auch ohne packed-Deklaration funktioniert.
Delphi-Quellcode:
{
Based on an article and code by Ivo Ivanov at The Code Project: Detecting Windows NT/2K process execution url: [url]http://www.codeproject.com/threads/procmon.asp[/url] PLEASE NOTE: Download driver 'NTProcDrv.sys' at the url noted above!!! } program NTDriverController; {$APPTYPE CONSOLE} uses SysUtils, Windows, psapi, WinSvc; type TCallbackInfo = record ParentId : THANDLE; ProcessId: THANDLE; bCreate : ByteBool; end; PCallbackInfo = ^TCallbackInfo; const IOCTL_PROCVIEW_GET_PROCINFO = $0022E000; //CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0800, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) var m_hSCM : SC_HANDLE; m_hDriver : SC_HANDLE; nServiceStatus : SERVICE_STATUS; strServiceName : String = 'NTProcDrv'; strDisplayName : String = 'Process creation/termination detector for Windows XP'; strFileName : String = ''; lpServiceArgVectors: PAnsiChar = nil; m_hShutDownEvent : THandle; //////////////////////////////////////////////////////////////////////////////// function GetExeNameByPID(dwPID: DWord): String; var h: THandle; begin Result := ''; h := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, dwPID); if (h <> 0) then try SetLength(Result, MAX_PATH); ZeroMemory(@Result[1], MAX_PATH); SetLength(Result, GetModuleFileNameEx(h, 0, @Result[1], MAX_PATH)); finally CloseHandle(h); end; Result := LowerCase(Result); end; //////////////////////////////////////////////////////////////////////////////// function KeyboardThread(dwArg: DWORD): DWORD; var nEvents : Cardinal; dwNumRead: DWORD; InputRec : TInputRecord; begin Result := 0; while (true) do begin GetNumberOfConsoleInputEvents(GetStdHandle(STD_INPUT_HANDLE), nEvents); if (nEvents > 0) then begin ReadConsoleInput(GetStdHandle(STD_INPUT_HANDLE), InputRec, 1, dwNumRead); if (InputRec.Event.KeyEvent.AsciiChar = 'q') then break; end; Sleep(800); end; writeln('# shutting down, please wait...'); SetEvent(m_hShutDownEvent); ExitThread(0); end; //////////////////////////////////////////////////////////////////////////////// function WaitForState(dwDesiredState: DWORD; pss: SERVICE_STATUS): Boolean; var dwWaitHint: DWORD; begin Result := False; if (m_hDriver <> 0) then while (True) do begin // Get current state of driver Result := QueryServiceStatus(m_hDriver, pss); // If we can't query the driver, we're done if not(Result) then break; // If the driver reaches the desired state if (pss.dwCurrentState = dwDesiredState) then break; // We're not done, wait the specified period of time dwWaitHint := pss.dwWaitHint div 10; // Poll 1/10 of the wait hint if (dwWaitHint < 1000) then dwWaitHint := 1000; // At most once a second if (dwWaitHint > 10000) then dwWaitHint := 10000; // At least every 10 seconds Windows.Sleep(dwWaitHint); end; end; //////////////////////////////////////////////////////////////////////////////// procedure RetrieveProcessInfo(hDriver: THandle; CallbackInfo, CallbackTemp: PCallbackInfo); var dwBytesReturned: DWORD; ov : OVERLAPPED; begin ZeroMemory(@ov, SizeOf(OVERLAPPED)); dwBytesReturned := 0; ov.hEvent := CreateEvent(nil, True, False, nil); if DeviceIoControl(hDriver, IOCTL_PROCVIEW_GET_PROCINFO, nil, 0, @CallbackInfo^, SizeOf(TCallbackInfo), dwBytesReturned, @ov) then GetOverlappedResult(m_hDriver, ov, dwBytesReturned, True) else writeln('! Error while DeviceIoControl, code: ' + IntToStr(GetLastError)); if ((callbackTemp^.ParentId <> callbackInfo^.ParentId) or (callbackTemp^.ProcessId <> callbackInfo^.ProcessId) or (callbackTemp^.bCreate <> callbackInfo^.bCreate)) then begin if(callbackInfo^.bCreate) then begin Sleep(300); // sleep some ms or image name could not be determinated :-( writeln('# process created, PID : ' + IntToStr(callbackInfo^.ProcessId) + ' ' + GetExeNameByPID(callbackInfo.ProcessId)) end else writeln('# process terminated, PID: ' + IntToStr(callbackInfo^.ProcessId)); end; CloseHandle(ov.hEvent); // Store the data for next time to prevent doubled events callbackTemp^ := callbackInfo^; end; //////////////////////////////////////////////////////////////////////////////// procedure ProcessMonitor; var szDriverName : String; hDriver : THandle; m_hProcessEvent: THandle; CallbackInfo : TCallbackInfo; CallbackTemp : TCallbackInfo; lpHandles : TWOHandleArray; dwResult : DWORD; dwThreadID : DWORD; begin szDriverName := '\\.\Global\NTProcDrv'#0; // Change to '\\.\NTProcDrv'#0 if CreateFile failes... hDriver := CreateFile(@szDriverName[1], GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0); if (hDriver <> INVALID_HANDLE_VALUE) then begin m_hShutdownEvent := CreateEvent(nil, False, False, nil); m_hProcessEvent := OpenEvent(SYNCHRONIZE, False, 'NTProcDrvProcessEvent'); ZeroMemory(@lpHandles, SizeOf(lpHandles)); lpHandles[0] := m_hShutdownEvent; lpHandles[1] := m_hProcessEvent; CreateThread(nil, 0, @KeyboardThread, nil, 0, dwThreadID); ZeroMemory(@CallbackInfo, SizeOf(TCallbackInfo)); ZeroMemory(@CallbackTemp, SizeOf(TCallbackInfo)); while (True) do begin dwResult := WaitForMultipleObjects(2, @lpHandles, False, INFINITE); if (dwResult = 0) then break; // user pressed 'q' RetrieveProcessInfo(hDriver, @CallbackInfo, @CallbackTemp); end; Sleep(1000); // ExitThread(0) and cleaning stack might take some ms CloseHandle(m_hProcessEvent); CloseHandle(m_hShutdownEvent); CloseHandle(hDriver); end; end; //////////////////////////////////////////////////////////////////////////////// begin writeln('# opening Servive Control Manager (SCM)...'); m_hSCM := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS); if (m_hSCM <> 0) then begin writeln('# opened SCM'); strFileName := ExtractFilePath(ParamStr(0)) + strServiceName + '.sys'; m_hDriver := OpenService(m_hSCM, PChar(strServiceName), SERVICE_ALL_ACCESS); if (m_hDriver <> 0) then begin if ControlService(m_hDriver, SERVICE_CONTROL_STOP, nServiceStatus) then WaitForState(SERVICE_STOPPED, nServiceStatus); DeleteService(m_hDriver); CloseServiceHandle(m_hDriver); writeln('! driver was not deleted last time.'); CloseServiceHandle(m_hDriver); Sleep(1000); end; m_hDriver := CreateService(m_hSCM, PChar(strServiceName), PChar(strDisplayName), SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, PChar(strFilename), nil, nil, nil, nil, nil); if (m_hDriver <> 0) then begin writeln('# service created, starting kernel driver...'); if (StartService(m_hDriver, 0, lpServiceArgVectors)) then WaitForState(SERVICE_RUNNING, nServiceStatus) else begin DeleteService(m_hDriver); CloseServiceHandle(m_hDriver); CloseServiceHandle(m_hSCM); writeln('! error while starting driver'); exit; end; writeln('# kernel driver started'); // interact with driver now... ProcessMonitor; writeln('# stopping kernel driver...'); if ControlService(m_hDriver, SERVICE_CONTROL_STOP, nServiceStatus) then WaitForState(SERVICE_STOPPED, nServiceStatus) else writeln('! could not stop kernel driver'); // Mark the service for deletion. if DeleteService(m_hDriver) then writeln('# service deleted') else writeln('! could not delete service'); CloseServiceHandle(m_hDriver); end; CloseServiceHandle(m_hSCM); end; Sleep(1000); end. |
Re: CTL_CODE Funktion in Delphi
Zitat:
Delphi-Quellcode:
sizeof(TCallbackInfo2) == 12
TCallbackInfo1 = packed record
ParentId : THANDLE; bCreate : ByteBool; ProcessId: THANDLE; end; TCallbackInfo2 = record ParentId : THANDLE; bCreate : ByteBool; ProcessId: THANDLE; end; sizeof(TCallbackInfo1) == 9 Übrigens, wenn du deinen Code noch etwas würzen willst, könntest du PutBinResTo benutzen und den Treiber in dein Programm einbetten. |
Re: CTL_CODE Funktion in Delphi
Zitat:
|
Re: CTL_CODE Funktion in Delphi
Ist nicht nur Kosmetik. Ich hatte vergessen, daß die etwas ausgereiftere Variante ExtractResTo heißt.
|
Re: CTL_CODE Funktion in Delphi
Zitat:
Gruß peanut. |
Re: CTL_CODE Funktion in Delphi
Zitat:
Macht sich besonders bei Treibern sehr sehr schön. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:34 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz