Jump to content

  • Log In with Google      Sign In   
  • Create Account

Just Let It Trickle

Detailing the Hookers – Underneath the Sheets

Posted by , 18 July 2011 - - - - - - · 529 views

We all need ideas. Whether you've just finished something, or are getting a little bit bored with your current project you can't help but let your mind drift to the next cool thing you'll create. Sometimes the ideas come thick and fast, other times they're like gold dust. When I'm in the second camp, and reading the various boards I read, I will quite happily steal other peoples.

One such board is Sysinternals'. They do winternals, I do winternals, they have a suggestion section and I want ideas. It's a perfect fit. On a previous visit, one of the suggestions I found was for a program that could list active hooks. Given my previous excursions into user/win32k territory, it didn't seem like it'd be too hard. And apart from the digging around assembly listings for the structure offsets, it wasn't, and that was more time-intensive than difficult. At any rate, I am now the owner of 14 versions of win32k.sys' symbols. I don't even have 14 games on my computer!

Rather than just dumping a download link and saying what it does (like I semi-did last time), I thought I'd deconstruct the hows and why's of the kernel side of the query. Needless to say, much of what follows is discussion of undocumented things. I am aware this makes Raymond Chen cry. Sorry fella.

Continue reading on Just Let It Flow

Apologies to BenS1, I didn't notice the comment on the previous blog entry. Looks like I went and did what you were after anyway :)

Detailing the Hookers

Posted by , 01 July 2011 - - - - - - · 416 views

Sorry to crush your hopes but this isn't a post about my new job as a prostitute army drill sergeant. Nope, it's just another post of me shilling my wares.

In some distant part of the mists o'time, I wrote a little tool who purpose was to report pending messages and other misc info for a thread and the windows it owns. It's safe to say this was tangentially useful at best.

That was until I saw somebody, somewhere, ask if there was a tool that would or could list currently active Windows hooks and had an idea. After that idea sank (pineapple juice and tea do not go together even if you like them both), I went and stuck hook enumeration together with message and window enumeration to add to my previous work of desktop heap enumeration. Yep, if you need things enumerating, you can count on me.

So here we have it, MsgLister + hooks = MsgHookLister. The download zip contains the source for the app and the driver that pokes into undocumented Windows structures as well as x64 and x86 binaries.

A screenie of window mode
Posted Image

And of hook mode - how exciting
Posted Image

Hmm, what to enumerate now...

DLL - Demystifying Loader Lapses

Posted by , 07 May 2011 - - - - - - · 354 views

DLL hell isn’t just the name given to managing monstrous dependency chains. It’s also the name given to the phenomenon of pulling your hair out because LoadLibrary is returning NULL or because your dotNet app is throwing lots of System.DllNotFoundExceptions. The usual statement Windows gives as witness to these crimes is ‘Module not found’ as if it were some blind referee or umpire giving a call against the local sports team, while you swear blind at the injustice and can point at the exact file you wanted in an Explorer window.

On the surface of things it may seem like a hard luck story. Sure you can go hook this and that in effort to figure out why appending the filename to the dll search path resulted in failure, but like Bud Selig calling the 2002 All-Star game a tie, Windows levels the playing field by housing a certain tool you can leverage no matter which language you're coding in. All without having to write any more code in investigative anger nor download anything neither.

Continue reading on Just Let It Flow

U-A-Ceen Nothing Yet

Posted by , 29 April 2011 - - - - - - · 682 views

Detecting whether UAC is enabled or not is something I've never needed to do. I can't really see how it can affect anything you architect one way or another but nevertheless, some people think it's necessary and nice to know.

While investigating something else, I stumbled across a more accurate method of making the determination as opposed to reading the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\EnableLUA registry value. Looking around the Internet, it seems reading that key is often touted as the way to do it. There's nothing wrong with using this method, well, apart for one caveat: if the state of UAC has changed and the computer hasn't restarted yet, you'll get an erroneous result [1].

Being Windows, and its tens of thousands of undocumented functions, you'd expect there to be at least one function that returns whether an integral part of the OS is enabled or not. A quick search of exports with 'elevat' in the name in the big ol' database returned these matches for Vista:

Posted Image

Knowing that all the useful goodies are hidden in either kernel32 or ntdll, and having a name exactly along the lines of what I was looking for, CheckElevationEnabled seemed like a great place to start.

[source lang="asm"] public _CheckElevationEnabled@4 var_4 = dword ptr -4 pBool = dword ptr 8 mov edi, edi push ebp mov ebp, esp ; standard prolog push ecx ; make some stack space lea eax, [ebp+var_4] ; get a pointer to it push eax ; pass it on call ds:__imp__RtlQueryElevationFlags@4 ; RtlQueryElevationFlags(&x) test eax, eax jl short loc_77C200DF ; jump if !NT_SUCCESS mov eax, [ebp+var_4] ; put the filled in value in eax mov ecx, [ebp+pBool] ; move our pointer to ecx and eax, 1 ; mask off all but the lowest bit mov [ecx], eax ; here's how we know pBool is a pointer xor eax, eax ; set error to STATUS_SUCCESS loc_77C200DF: ; CODE XREF: CheckElevationEnabled(x)+12 push eax call ds:__imp__RtlNtStatusToDosErrorNoTeb@4 ; translate STATUS_* to ERROR_* leave retn 4[/source]
Or in C
[source lang="c"]DWORD WINAPI CheckElevationEnabled(BOOL* pResult){ DWORD x; NTSTATUS stat = RtlQueryElevationFlags(&x); if(NT_SUCCESS(stat)) { *pResult = (x & 1); } return RtlNtStatusToDosErrorNoTeb(stat);}[/source]

Unfortunately, it didn't really clear anything up. It's obviously checking whether a flag/bit is set, but there's no info on what the flag refers to or where it's coming from. It'd be easy to guess it is doing what we'd like it to but more spelunking is needed, next stop RtlQueryElevationFlags:

[source lang="asm"]_RtlQueryElevationFlags@4 proc near pFlags = dword ptr 8 mov edi, edi push ebp mov ebp, esp mov eax, [ebp+pFlags] and dword ptr [eax], 0 ; clear the slate test byte ptr ds:7FFE02F0h, 2 ; test the second bit of the address jz short loc_77CEEE74 ; go to next if not set mov dword ptr [eax], 1 ; set flags to one if it is loc_77CEEE74: ; CODE XREF: RtlQueryElevationFlags(x)+12 test byte ptr ds:7FFE02F0h, 4 ; test the third bit jz short loc_77CEEE80 ; skip to next test if not set or dword ptr [eax], 2 ; or on the relevant flag is it is loc_77CEEE80: ; CODE XREF: RtlQueryElevationFlags(x)+21 test byte ptr ds:7FFE02F0h, 8 ; test the fourth bit jz short loc_77CEEE8C ; skip to exit or dword ptr [eax], 4 ; or on the relevant flag if it is loc_77CEEE8C: ; CODE XREF: RtlQueryElevationFlags(x)+2D xor eax, eax ; return STATUS_SUCCESS pop ebp retn 4 _RtlQueryElevationFlags@4 endp[/source]

Rather strangely, the data it queries comes directly from a byte at a hardcoded address offset rather than via a kernel API call or a specific global pointer. From a strictly disassembly point of view, there's absolutely nothing new to go on to figure what the flags mean or represent. It did show that the error checking in CheckElevationEnabled is superfluous but other than that, nothing.

Of course, this is Windows and ntdll specifically, so it's unlikely that this requires a look at the source to figure out. Taking off the obvious 2f0 offset, googling or querying the address in WinDGB [2] shows that 0x7ffe0000 is the address where the KUSER_SHARED_DATA [3] (also called UserSharedData) structure lives. This structure is just a big bunch of parameters shared between user and kernel mode in memory that is mapped to the same address in every process. Forget PHP, this is a true superglobal.

Knowing the name makes the format easy to figure out. One option is to use a tool like Dia2Dump to list all the types and members from ntdll's symbols and grep the results. In a nice change of pace for this specific struct however, looking at the wdm.h or ntddk.h header files in the WDK, reveal it in C form, completely documented, and with some helpful comments to boot.

Back to the matter at hand, checking the struct for offset 0x2f0 reveals the queried structure bits to be:
[source lang="c"]union { ULONG SharedDataFlags; struct { // // The following bit fields are for the debugger only. Do not use. // Use the bit definitions instead. // ULONG DbgErrorPortPresent : 1; ULONG DbgElevationEnabled : 1; // second bit ULONG DbgVirtEnabled : 1; // third bit ULONG DbgInstallerDetectEnabled : 1; // fourth bit ULONG DbgSystemDllRelocated : 1; ULONG DbgDynProcessorEnabled : 1; ULONG DbgSEHValidationEnabled : 1; ULONG SpareBits : 25; } DUMMYSTRUCTNAME2;} DUMMYUNIONNAME2;[/source]

It's nice to put a name to data. Names which coincide with the settings found in the registry key are especially pleasing as it means this is undoubtedly the in-memory equivalent of those values. In order, the second bit denotes whether UAC is enabled, the third failed registry/file write virtualisation, and the fourth whether installers are detected and automatically elevated.

From the slight chance of wrong data from the registry, the train arrives into its station with an extra three methods of querying UAC. A direct read of a hardcoded address (not that that's recommend), a straight call to RtlQueryElevationFlags [4], or if you only care about UAC and not virtualisation or installer detection, CheckElevationEnabled.

If only this was useful in some way, oh well.

[1] Despite the minor stated limitation, this is the method employed by ?IEStubIsLuaEnabled@@YGHXZ, ordinal 30 in iertutil.dll on Vista and above

[2] WinDBG has the !ksuser extension to display the data contained in the KUSER_SHARED_DATA mapping

[3] KUSER_SHARED_DATA contents from Windows 7 SP1 32-bit layout via ntdll.dll's symbols.
To dump it yourself, get the PDB and run 'dia2dump -t "A:\Path\To\ntdll\symbols.pdb" > symboltypes.txt'
See ntddk.h or wdm.h in the DDK for the struct in C format.
[source lang="text"]UserDefinedType: _KUSER_SHARED_DATAData : this+0x0, Member, Type: unsigned long, TickCountLowDeprecatedData : this+0x4, Member, Type: unsigned long, TickCountMultiplierData : this+0x8, Member, Type: volatile struct _KSYSTEM_TIME, InterruptTimeUserDefinedType: _KSYSTEM_TIMEData : this+0x14, Member, Type: volatile struct _KSYSTEM_TIME, SystemTimeUserDefinedType: _KSYSTEM_TIMEData : this+0x20, Member, Type: volatile struct _KSYSTEM_TIME, TimeZoneBiasUserDefinedType: _KSYSTEM_TIMEData : this+0x2C, Member, Type: unsigned short, ImageNumberLowData : this+0x2E, Member, Type: unsigned short, ImageNumberHighData : this+0x30, Member, Type: wchar_t[0x104], NtSystemRootData : this+0x238, Member, Type: unsigned long, MaxStackTraceDepthData : this+0x23C, Member, Type: unsigned long, CryptoExponentData : this+0x240, Member, Type: unsigned long, TimeZoneIdData : this+0x244, Member, Type: unsigned long, LargePageMinimumData : this+0x248, Member, Type: unsigned long[0x7], Reserved2Data : this+0x264, Member, Type: enum _NT_PRODUCT_TYPE, NtProductTypeData : this+0x268, Member, Type: unsigned char, ProductTypeIsValidData : this+0x26C, Member, Type: unsigned long, NtMajorVersionData : this+0x270, Member, Type: unsigned long, NtMinorVersionData : this+0x274, Member, Type: unsigned char[0x40], ProcessorFeaturesData : this+0x2B4, Member, Type: unsigned long, Reserved1Data : this+0x2B8, Member, Type: unsigned long, Reserved3Data : this+0x2BC, Member, Type: volatile unsigned long, TimeSlipData : this+0x2C0, Member, Type: enum _ALTERNATIVE_ARCHITECTURE_TYPE, AlternativeArchitectureData : this+0x2C4, Member, Type: unsigned long[0x1], AltArchitecturePadData : this+0x2C8, Member, Type: union _LARGE_INTEGER, SystemExpirationDateUserDefinedType: _LARGE_INTEGERData : this+0x2D0, Member, Type: unsigned long, SuiteMaskData : this+0x2D4, Member, Type: unsigned char, KdDebuggerEnabledData : this+0x2D5, Member, Type: unsigned char, NXSupportPolicyData : this+0x2D8, Member, Type: volatile unsigned long, ActiveConsoleIdData : this+0x2DC, Member, Type: volatile unsigned long, DismountCountData : this+0x2E0, Member, Type: unsigned long, ComPlusPackageData : this+0x2E4, Member, Type: unsigned long, LastSystemRITEventTickCountData : this+0x2E8, Member, Type: unsigned long, NumberOfPhysicalPagesData : this+0x2EC, Member, Type: unsigned char, SafeBootModeData : this+0x2ED, Member, Type: unsigned char, TscQpcDataData : this(bf)+0x2ED:0x0 len(0x1), Member, Type: unsigned char, TscQpcEnabledData : this(bf)+0x2ED:0x1 len(0x1), Member, Type: unsigned char, TscQpcSpareFlagData : this(bf)+0x2ED:0x2 len(0x6), Member, Type: unsigned char, TscQpcShiftData : this+0x2EE, Member, Type: unsigned char[0x2], TscQpcPadData : this+0x2F0, Member, Type: unsigned long, SharedDataFlagsData : this(bf)+0x2F0:0x0 len(0x1), Member, Type: unsigned long, DbgErrorPortPresentData : this(bf)+0x2F0:0x1 len(0x1), Member, Type: unsigned long, DbgElevationEnabledData : this(bf)+0x2F0:0x2 len(0x1), Member, Type: unsigned long, DbgVirtEnabledData : this(bf)+0x2F0:0x3 len(0x1), Member, Type: unsigned long, DbgInstallerDetectEnabledData : this(bf)+0x2F0:0x4 len(0x1), Member, Type: unsigned long, DbgSystemDllRelocatedData : this(bf)+0x2F0:0x5 len(0x1), Member, Type: unsigned long, DbgDynProcessorEnabledData : this(bf)+0x2F0:0x6 len(0x1), Member, Type: unsigned long, DbgSEHValidationEnabledData : this(bf)+0x2F0:0x7 len(0x19), Member, Type: unsigned long, SpareBitsData : this+0x2F4, Member, Type: unsigned long[0x1], DataFlagsPadData : this+0x2F8, Member, Type: unsigned __int64, TestRetInstructionData : this+0x300, Member, Type: unsigned long, SystemCallData : this+0x304, Member, Type: unsigned long, SystemCallReturnData : this+0x308, Member, Type: unsigned __int64[0x3], SystemCallPadData : this+0x320, Member, Type: volatile struct _KSYSTEM_TIME, TickCountUserDefinedType: _KSYSTEM_TIMEData : this+0x320, Member, Type: volatile unsigned __int64, TickCountQuadData : this+0x320, Member, Type: unsigned long[0x3], ReservedTickCountOverlayData : this+0x32C, Member, Type: unsigned long[0x1], TickCountPadData : this+0x330, Member, Type: unsigned long, CookieData : this+0x334, Member, Type: unsigned long[0x1], CookiePadData : this+0x338, Member, Type: __int64, ConsoleSessionForegroundProcessIdData : this+0x340, Member, Type: unsigned long[0x10], Wow64SharedInformationData : this+0x380, Member, Type: unsigned short[0x10], UserModeGlobalLoggerData : this+0x3A0, Member, Type: unsigned long, ImageFileExecutionOptionsData : this+0x3A4, Member, Type: unsigned long, LangGenerationCountData : this+0x3A8, Member, Type: unsigned __int64, Reserved5Data : this+0x3B0, Member, Type: volatile unsigned __int64, InterruptTimeBiasData : this+0x3B8, Member, Type: volatile unsigned __int64, TscQpcBiasData : this+0x3C0, Member, Type: volatile unsigned long, ActiveProcessorCountData : this+0x3C4, Member, Type: volatile unsigned short, ActiveGroupCountData : this+0x3C6, Member, Type: unsigned short, Reserved4Data : this+0x3C8, Member, Type: volatile unsigned long, AitSamplingValueData : this+0x3CC, Member, Type: volatile unsigned long, AppCompatFlagData : this+0x3D0, Member, Type: unsigned __int64, SystemDllNativeRelocationData : this+0x3D8, Member, Type: unsigned long, SystemDllWowRelocationData : this+0x3DC, Member, Type: unsigned long[0x1], XStatePadData : this+0x3E0, Member, Type: struct _XSTATE_CONFIGURATION, XState[/source]

[4] Here's a simple wrapper for RtlQueryElevationFlags so you don't have to bother with the function typedefs and all that jazz.
[source lang="cpp"]enum ElevationFlags{ ELEVATION_UAC_ENABLED = 1, ELEVATION_VIRTUALIZATION_ENABLED = 2, ELEVATION_INSTALLER_DETECTION_ENABLED = 4};void GetElevationFlags(ElevationFlags* pFlags){ assert(pFlags); typedef NTSTATUS (NTAPI*pfnRtlQueryElevationFlags)(ElevationFlags*); HMODULE hNtdll = GetModuleHandle(L"ntdll.dll"); pfnRtlQueryElevationFlags rtlQueryElevationFlags = (pfnRtlQueryElevationFlags)GetProcAddress(hNtdll, "RtlQueryElevationFlags"); assert(rtlQueryElevationFlags); rtlQueryElevationFlags(pFlags);}[/source]

100% Apple Approved

Posted by , 01 April 2011 - - - - - - · 372 views

Yep, I'm now on iTunes and further reducing the Gamedev's journals' 'hit to miss ratio of useful-ity' at the same time. My place on iTunes isn't in any technical sections, heck no. I do have a hackintosh set up but after it took me 10 minutes to figure out where the off button was, the idea that I'm currently not in any position to be doing anything useful on that platform yet sprang to mind.

So what am I on about? A bit of background. First, the BBC were recently running a sitcom competition which I entered and didn't win. A production company then ran a competition for a stage based sitcom, which I entered and didn't win. Then I started sending stuff into BBC Radio 7's Newsjack, which I've also been unsuccessful with. They say 'if you can't beat them, join them' and as I've been unable to join them, I went the other way and have beaten them into submission** with my own one man news parodying sketch show which is what is on iTunes.

As with most shows, it ends with a song. The first of such being Gaddafi singing a song to give his side of the current situation.
Video link with lyrics

In other news, WindowWatcher (see previous post) is finished. I just have to bother to create a page on the website for it and then actually properly open it for public consumption.

Also, despite (or maybe because of) me not actually ever owning a NES, I've started watching episodes of Chrontendo. A chronological documentary (well, it's factual at any rate) of a guy going through the history of the machine giving 3-5 minute histories and other bits of info on every NES games released. There's also a sister series about the Master System, which is where I started watching from. This is probably the easiest way of finding episodes of each.


** It's totally not a coincedence that the series has finished its current run, leaving me nothing to write for

Watching the Windows Go By

Posted by , 24 February 2011 - - - - - - · 778 views

No, it's not an Andy Williams inspired poem, it's actual pictures of the thing I've been working on. Imagine that.

Enter WindowWatcher:
Posted Image

It's a single window, that displays another single window, keeping it on top. Great for watching stuff like TV or Youtube playlists in a small corner of your workspace while working in the rest of it. It's also great for tasks that would otherwise require flicking back and forth between windows, reading documentation and key tapping in the IDE for instance.

As you can see from above, you can zoom into specific areas, repeatedly if so desired. After that you can resize the window to blow up that specific portions way beyond normal size:
Posted Image

Of course, passive viewing by itself isn't brilliant. To address this WindowWatcher allows interaction too, anything you could do with the mouse and keyboard in the original window you can do via it. Posting to Twitter or Facebook, STFW-ing and faffing with WMP playlists being my current poisons:

Posted Image

Topping it off there's a simple plugin API for those stubborn windows which don't react normally to window messages.

Those windows better watch out, there's a new stalker in town.

Alternative Valentines Poem 2011 – The Slippery Slope

Posted by , 13 February 2011 - - - - - - · 474 views

It happens to be that time again, where all the loved up people get all mushy with their sentimental I love you’s. Just like Christmas though, there are no doubt some people who have a distaste for all that jazz.

So here's something I do every year, and that's write a poem that's not in the least bit mushy or about loving someone, but it is pretty UK centric:

Hey, how ya doing? Nice to have your support
You’re in on the ground floor I'm glad to import
A brand new prodigy, a rapping sensation
Spitting truth at a rate that outpaces inflation
With rhythmic oration I'm laying tracks in the booth
Should’ve used my hands though, shouting at nails is no use
Laying it out like Shayne Ward, yo this is gonna be handsome
Directing the youth from gangs and onto Esther Rantzen
Showing them hey, guys there's no need to boast
Truth is real beauty and you can spread that on your toast
The track's finally finished now I can record the words
Who’s got the piece of paper with my list of verbs?

Read the exciting conclusion on Just Let It Flow. it contains an actual verse from the song, the video shoot, Loose Women, Cricket, a brilliant pun or two, a non-surgical replacement for bum pumping and that old favourote Aesop's Fables.

You Don't Get This On MSDN

Posted by , 06 February 2011 - - - - - - · 302 views

What do you get when you combine C#, C++/CLI, Access 2003, VirtualBox, a few ISOs and too much free time?

You get a 345MB database of the complete API and dependency history of 32-bit Windows. Yep, every OS module from Win95 onwards has had its imports, exports, and selected PE header info extracted and committed to a handy-dandy Access 2000 format database. That’s a chronicle of 41 OS versions, 47,000+ modules, over 2,100,000 exports and over 5,125,000 imports. It also contains a bunch of premade SQL queries for statistical usage and some useful ones too such as "Which modules import a specific function?" and "What are the differences between dll version x and y?"

An idea of what data is available:

Posted Image

OS Export counts
Posted Image

Modules which import a specific function on a specific OS, here its SHUnicodeToAnsi on Vista SP0
Posted Image

You can download the 35MB 7-zip archive as well as lark around with other statisical data on the registry and resources from that cheekily embedded link. Happy querying.

WMI'm Going Speed Dating

Posted by , 28 January 2011 - - - - - - · 539 views

There's tonnes of example on how to use SWbemDateTime to convert from FILETIME's or CDates in VBScript, yet I couldn't find any for C++. So here's how...

All WMI queries that give or take datetime values, do so in a certain format called CIM_DATETIME. For scripting guys, this is only a minor inconvenience. The following listing is the entire code to display the OS install date in various formats:

' Create a new datetime object.
Set dateTime = CreateObject("WbemScripting.SWbemDateTime")

' Retrieve a WMI object that contains a datetime value.
for each os in GetObject( _
    "winmgmts:").InstancesOf ("Win32_OperatingSystem")

    ' The InstallDate property is a CIM_DATETIME. 
    MsgBox os.InstallDate
    dateTime.Value = os.InstallDate

    ' Display the year of installation.
    MsgBox "This OS was installed in the year " & dateTime.Year

    ' Display the installation date using the VT_DATE format.
    MsgBox "Full installation date (VT_DATE format) is " _
    & dateTime.GetVarDate

    ' Display the installation date using the FILETIME format.
    MsgBox "Full installation date (FILETIME format) is " _
    & dateTime.GetFileTime 
Set datetime = Nothing
For the native coders among us, the standard Win32 time functions neither produce nor consume this format meaning we have to perform some jiggery poker to get it to play nice.

Read the rest on Just Let It Flow

Undefined Behaviour - Star Trek Style!?

Posted by , 17 January 2011 - - - - - - · 321 views

We all know that stepping over array bounds is easily managed in C and C++. So much so that the C standard library has a function, gets, which may as well be named 'cause_buffer_overflow'. The consequences of overflowing a buffer are also understood, pretty much anything can happen. To demonstrate just how serious this can be, I’d like to relay something based on a true story:

"I'm a wizzy coder, do all my work in C
Function upon function of technical wizardry
I'm a scanf lord, the King Midas of gets
All I touch becomes gold and I don't have to fret"
That was the old me, coding with no fear of reprises
And no hard line respecter of stack buffer sizes
Until one fateful day when I was processing a file
Part of an assignment I'd grown to revile
It'd taken me a week, well I was just lazy
So like any respective student, I crammed like crazy
Line length was hardcoded, 80 chars in size
Thinking that was all was the start of my demise
Sample appointments piped into stdin
Consumed by gets, listed and linked in
I set off a test; you know to check my work
When I returned it was stuck looping on Captain Kirk
He was booked for back spasms; that much I remember
Thinking he ain't nothing but a Picard pretender
I attached a debugger to pacify the problem kitten
But everywhere I looked memory had been overwritten
Line by line and char by char
My buffer was filling up far too far
Off into the lands of the undefined realm
My program went careering with no-one at the helm
Surely it'd crash soon, there had to be an end
But the data kept coming like a royal stipend
First the window went white; Windows said it had to close
But it was running rampant just inches from my nose
The control-c combo, a press of escape
The keys mean nothing, hell I even pressed break
Explorer went down citing an access violation
But I know that's a euphemism for backdoor propagation
The assimilation had begun, the wallpaper turned green
I moved from the monitor to swerve the scanner beam
"We are the Borg, resistance is futile
Our boys are quite ugly but our dames are nubile
If you want to see them dance and be left with no saliva
Please accept the dialog to install our unsigned driver"
There was the crack, the weakness of the queen
User-mode was knackered but the kernel was still clean
I wondered how to extract these ring 3 dwellers
When my deflector dish contained nothing but half-eaten mozzarella
I changed my footwear, took off my red shirt
Whitened my face and brought in a little squirt
The dialog counted down, we couldn't wait any longer
Although the smelly-sock repeller couldn't get any stronger
I tried to hack it open, create some interface
When Wesley said "What about livekd from that sysinternals place?"
That was it; we were in, but with no symbols bestowed
.restart for a quick kill but the attempt was vetoed
Now I've seen the episode, I tried some root commands
"sudo rm /the_borg_and_their_plans"
'> sudo undefined', '> ...their_plans are locked'
Then "Shouldn't you have a nap?"; the USB lines aren't blocked?
The dialog timed out, the install progress blinked
And the toaster's trying to tell me that I need 40 winks?
"Can you believe this?" I scoffed at the distraction
"I believe the message intended a swift course of action"
Wesley piped up, the sweat glistening on his brow
"Powering down to S3, it's all we can do now"
From 80 up to 90, the install was relentless
And I'd missed borgesses in states of undressedness
The toaster powered down, the install had completed
"We are the Borg, we cannot be defeat..."
One syllable to go and that's where it stopped
As I unplugged the computer and the scan field dropped
Did they manage to spread? How far did it go?
And all this from a humble single byte overflow
I really didn't mean it, I promised to be good
I'll query buffer sizes and be a security stud
Or better yet change to std::getline
and make C++ a bedfellow of mine
No percent formats in sight, yeah, onto bigger better things
No char pointer reallocs only std::strings
I didn't switch completely, it has to be told
Because of the aftermath of that day which I'll now extol
After it all happened there was a knock at the door
"I believe you ordered some food, and wait there's more
It's totally free, yes nothing to pay"
Can you believe it? Undefined behaviour finally went my way
The day that started with coding and ended with tomatoed bread
Could've only been better if I'd got some Borg boobies instead
But as it stands now, I've learned how to go far
Respect buffer sizes but ignore Kirk's lower lumbar

If you got here that means you didn't baulk after the flimsy setup. You can find more of my well, technical poetry I'd guess you call it here, if you can stomach them that is. Oh and no, it wasn't based on a true story at all. I'd never use gets in a million years :-)

January 2017 »

1516171819 20 21