The RedBox DVD Kiosk

by Mister Bojangles  (cougar.slayer@gmail.com)

I never had a real job before 9/11, so I was caught off guard by how paranoid people in corporate America have become about security.

What has always irked me about this security is that you know its presence, but never are the details disclosed to you.  Aside from the empty threat from HR that I am personally responsible for any outside software I install, they assume that the impotent security guards and worthless electronic badge system have put the fear of God into me.  Hardly.

A while ago I received a text message reminding me that I am required to log out of my machine.  They knew I had not logged out because my status in Windows Messenger was "Away" and not "Offline".

In fairness, my company is reasonably cool and has better things to do than babysit its employees.  But I learned that they me Windows Messenger as a way of snooping.  It's relatively benign this time, but what about in the future?

What else is being snooped that they aren't telling me?

In light of this occurrence I decided to develop something I could use to manipulate the people watching me, whoever they are.  As usual, I'm not responsible for bad performance reviews, getting your ass fired, or any legal action as a result of this program.

The code is VB.NET, but could easily be ported to another language that supports COM objects and can build a Windows Forms app if you don't have Visual Studio or for some reason you can't install the .NET framework (which includes free command line compilers for VB, C#, Visual J#, and JavaScript).

First, let's look at the Windows Form (Figure 1) associated with this app.


Figure 1

Only one value is accepted, which is a number that becomes a number of minutes.  The "Go" button starts everything.

Notice the properties of this form (Figure 2).  The maximize box is not enabled.  This prevents a clumsy user from accidentally filling the screen with this window just as the boss walks by.


Figure 2

By setting ShowInTaskbar to False, this program very easily becomes invisible.  Minimize the program using the appropriate window control and the app will still run but disappear (nearly) completely.

Alternatively, the small window could easily be hidden by a larger one.

Now let's get into the code, starting from the top.

System.Math is necessary for random numbers.  The first Private statement is a declaration of the ExitWindowsEx function from the USER32 library (a system library) which is what forces Windows to logoff (more on this later).

Next is the declaration of the Sleep subroutine from the KERNEL32 library, another system library.  This is used to tell the program to wait for a specified number of milliseconds.

The Sleep subroutine is useful because it avoids the Timer control available in form design, which is only good for about a minute anyway.

Next is the instantiation of the Windows Messenger API.  Before this will work, you must add a reference to Windows Messenger, which is easy in Visual Studio.

Go to the "Project" menu then "Add Reference".  Next, click "Browse" and navigate to MSMSGS.EXE (should be C:\Program Files\Messenger) and the necessary reference is now included in your project!

This can be done for any DLL, TLB, OLB, OCX, or EXE file, so if you need to customize this for your own app try adding it as a reference to a Visual Studio project and use the Object Browser to see what methods are available!

Next, the Enum which handles the four different types of exiting Windows.  Logoff does just a however other programs are allowed to interrupt the process.  If you've ever seen the annoying "Program X is not responding... End Now or Cancel" box, this is a program interruption.

Shutdown and Restart... what do you think they do?  The one we'll be using is ForceLogoff.  This logs the user out regardless of what other programs need done.  So make sure you saved everything.

Clicking "Go" sets everything in motion.

After the declarations, the first thing we need to do is get an instance of the Windows Messenger API, which is done with the New statement.  Cursor position is initialized and IsNumeric is used for error checking.  If the value is numeric, it returns true.

Next, the time at which to logoff (goTime) is set after passing the error checking.

The loop is the guts of the code.

Based on the seconds in the current time, the cursor moves around a range of 640x480, set as such for even the lowest resolution so an out of bounds will never occur.  Note that a range can be specified from the .Next method of the random number variable.

Then the program will sleep for two seconds.  The cursor movement is just in case they track user activity.  The sleep is less trivial because it varies processor activity.  This is useful for giving the appearance of a batch job running, just in case they would check processor activity.

Next, the status of Windows Messenger is manipulated based on the minute of the system time.  This serves to give the appearance of normal modulation of status.  True, this is formulaic, but there's much more that could be done here.

Random numbers provide a wealth of possibilities throughout the program, so get creative!  I experimented with comparing two random numbers and changing the status when a match occurred.  On a 1.5 GHz machine a range of one billion random numbers gave a suitable duration.

Experiment on your own machine, but be mindful that too small a range and the status will change a hundred times a second, too large a range and the status will never change.

Finally, if the goTime is equal to or greater than sysTime, Windows is forced to logoff.

No one is the wiser, and to the remote observer it appears as though you've been working hard!

Useful when you want the afternoon off or when you want the boss to think you're working hard for that big promotion!

Shoutz: Dogpatch, Daniel Cooper, f@t@$$, Mother Puelo, 200lx.

punking-the-watchers.vb:

Option Explicit On
Imports System.Math

Public Class Form1
    Inherits System.Windows.Forms.Form

    Private Declare Function ExitWindowsEx Lib "user32" (ByVal uFlags As Long, ByVal dwReserved As Long) As Long
    Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
    Private WithEvents WinMsg As MessengerAPI.Messenger

    Private Enum WindowsExitFlags
         Logoff = 0
         Shutdown = 1
         Reboot = 2
         ForceLogoff = 4
    End Enum

    Private Sub btnGo_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnGo.Click
         Dim time As Integer
         Dim checkTime As Boolean
         Dim sysTime As Date = DateTime.Now
         Dim goTime As Date = DateTime.Now
         Dim position As Point
         Dim rand As New Random(CInt(Now.Ticks And Integer.Maxvalue))
         Dim randPos As Integer

         WinMsg = New MessengerAPI.Messenger
         position = Cursor.Position()
         checkTime = IsNumeric(txtVal.Text)

         If (checkTime = True) Then
              If (txtVal.Text > 0) Then
                   time = txtVal.Text
                   goTime = Now.AddMinutes(time)
              Else
                   MessageBox.Show("Value must be > 0. Try again.")
                   txtVal.Clear()
                   Exit Sub
              End If
         Else
              MessageBox.Show("Value must be numeric. Try again.")
              txtval.Clear()
              Exit Sub
         End If

         Do Until goTime = sysTime
              sysTime = DateTime.Now

              Select Case sysTime.Second
                   Case 15, 59
                        randPos = rand.Next(0, 640)
                        position.X = randPos
                        Cursor.position = position
                        Sleep(2000)
                   Case 30, 45
                        randPos = rand.Next(0, 480)
                        position.Y = randPos
                        Cursor.Position = position
                        Sleep(2000)
                   End Select

                   Select Case sysTime.Minute
                        Case 8, 26, 39, 46
                             WinMsg.MyStatus = MessengerAPI.MISTATUS.MISTATUS_ONLINE
                        Case 6, 23, 36, 44
                             WinMsg.MyStatus = MessengerAPI.MISTATUS.MISTATUS_AWAY
				   End Select

                   If goTime <= sysTime Then
                        Exit WindowsEx(WindowsExitFlags.ForceLogoff, 0&)
                   End If
         Loop
    End Sub

#Region " Windows Form Designer generated code "

    Public Sub New()
         MyBase.New()

         'This call is required by the Windows Form Designer.
         InitializeComponent()

		 'Add any initialization after the InitializeComponent() call
	End Sub

    'Form overrides dispose to clean up the component list.
    Protected Overloads Overrides Sub Dispose (ByVal disposing As Boolean)
         If disposing Then
              If Not (components Is Nothing) Then
                   components.Dispose()
              End If
         End If
         MyBase.Dispose(disposing)
    End Sub

    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.
    'Do not modify it using the code editor.
    Friend WithEvents btnGo As System.Windows.Forms.Button
    Friend WithEvents txtVal As System.Windows.Forms.TextBox
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
         Dim resources As System.Resources.ResourceManager = New System.Resources.ResourceManager(GetType(Form1))
         Me.btnGo = New System.Windows.Forms.Button
         Me.txtVal = New System.Windows.Forms.TextBox
         Me.SuspendLayout()
	     '
		 'btnGo
		 '
         Me.btnGo.Location = New System.Drawing.Point(88, 5)
         Me.btnGo.Name = "btnGo"
         Me.btnGo.Size = New System.Drawing.Size(75, 24)
         Me.btnGo.TabIndex = 0
         Me.btnGo.Text = "Go"
         '
		 'txtVal
		 '
         Me.txtVal.Location = New System.Drawing.Point(8, 8)
         Me.txtVal.Name = "txtVal"
         Me.txtVal.Size = New System.Drawing.Size(70, 20)
         Me.txtVal.TabIndex = 1
         Me.txtVal.Text = ""
		 '
		 'Form1
		 '
         Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
         Me.ClientSize = New System.Drawing.Size(177, 37)
         Me.Controls.Add(Me.txtVal)
         Me.Controls.Add(Me.btnGo)
         Me.Icon = CType(resources.GetObject("$this.Icon"), System.Drawing.Icon)
         Me.Location = New System.Drawing.Point(150, 150)
         Me.MaximizeBox = False
         Me.Name = "Form1"
         Me.ShowInnTaskbar = False
         Me.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen
         Me.ResumeLayout(False)

    End Sub

#End Region

End Class

Code: punking-the-watchers.vb

Return to $2600 Index