2008-11-17

Despite it All, I'm Getting a 10.00 for Reliability in Windows Vista

Note: this content originally from http://mygreenpaste.blogspot.com. If you are reading it from some other site, please take the time to visit My Green Paste, Inc. Thank you.

I guess I've got nothing to complain about. I'll let the screenshot speak for itself...


2008-11-03

Error 0x8007052e from Windows Media Services

Note: this content originally from http://mygreenpaste.blogspot.com. If you are reading it from some other site, please take the time to visit My Green Paste, Inc. Thank you.

I was recently working on getting Windows Media Services configured on a system. Going through the properties, I noticed that the "WMS Anonymous User Authentication" plugin was in an error state. On inspection, I was presented with the following dialog.

---------------------------
Windows Media Services
---------------------------
The plug-in cannot be enabled because the user name or password does not match the settings for the Windows user account used for anonymous guests.
---------------------------
OK
---------------------------

Also, the event viewer was showing the following:

Event Type: Error
Event Source: WMServer
Event Category: Plugin
Event ID: 323
Date: [Date]
Time: [Time]
User: N/A
Computer: [CompName]
Description:
Plug-in 'WMS Anonymous User Authentication' on the server failed with the following information: Error code = 0x8007052e, Error text = 'Logon failure: unknown user name or bad password. '.
For more information, see Help and Support Center at
http://go.microsoft.com/fwlink/events.asp.
Data:
0000: 8007052e

Checking "Local Users and Groups", I could see that the specified user (WMUS_COMPNAME) certainly existed. I changed the password for the user and then set the password in the properties for "WMS Anonymous User Authentication". I was rewarded with the same message. The user name and password were correct, so I focused my attention elsewhere. I first tried changing the settings to provoke the message while running Sysinternals' Filemon and Regmon, but was unable to pull anything from the captured data that seemed like it was germane to the problem.

The next thing I tried was creating a new account and specifying that account in the properties for "WMS Anonymous User Authentication". This worked; the status of "WMS Anonymous User Authentication" became "Enabled". I found this odd, as I was working with a fresh installation of Windows Media Services. In comparing the accounts (WMUS_COMPNAME and the test account I created), I noticed the WMUS_COMPNAME account was just a member of the Guests group, while the test account was just a member of the Users group. So, I added the test account to Guests and removed it from Users, and then checked / OK'd the "WMS Anonymous User Authentication" properties. I got the aforementioned message. I changed the test account back to the original group memberships, and "WMS Anonymous User Authentication" did not complain.

At this point, I knew that the problem was related to some restriction placed on the Guests group. I ran secpol.msc to check the Local Security Policy Settings, and I noticed that Guests had been added to the Security Setting for the "Deny access to this computer from the network" policy. According to TechNet, the default for this policy is "None". Removing Guests from the setting allowed the WMUS_COMPNAME account to function as the anonymous account used by Windows Media Services.

2008-10-21

Handle Leak in Apple's mDNSResponder.exe

A while ago, I noticed a handle leak in Apple's "Bonjour Service" (yeah, that sounds like something I want running on my system...) - mDNSResponder.exe. I knew right away that that was the executable for the "Bonjour Service" because the name is so helpful. (Joking. Even if it was named after the service, how the heck would I even guess what the "Bonjour Service" did. But I digress...)

The service description is:

Bonjour allows applications like iTunes and Safari to advertise and discover services on the local network. Having Bonjour running enables you to connect to hardware devices like Apple TV and software services like iTunes sharing and AirTunes. If you disable Bonjour, any network service that explicitly depends on it will fail to start.

I put up with the leak for a while, from time to time stopping the service when I thought of it after booting. Most of the time I didn't think of it and the leak did not appear to be having any kind of performance impact on my system (I never saw it get above 80,000 handles). An update (or two?) later, I thought it would be fixed. So I was surprised to find mDNSResponder.exe had more than 55,000 handles when I checked recently with Sysinternals' Process Explorer.


I tried to use Process Explorer's handle pane to see the handles in mDNSResponder.exe, but with that many handles to display, and with Process Explorer running with its default High priority and refreshing every second, the system became rather sluggish. I dropped the priority of Process Explorer with Task Manager, hid the lower-pane view, and gave Handle.exe a shot with handle.exe -a -p mdnsresponder.exe.

I found that the handles being leaked are handles to registry keys - specifically, HKLM\SYSTEM\ControlSet001\Services\Tcpip\Parameters. (ControlSet001 is the current control set on my system.)

Since there's not much I can do about the handle leak, I'll disable the service, and hope the next update fixes the problem as surely the next update will set the service to Automatic start. Wonder why the installer doesn't at least set a service such as this as "Delayed Start" in Vista...

2008-09-17

Advanced Windows Debugging on Channel 9

Note: this content originally from http://mygreenpaste.blogspot.com. If you are reading it from some other site, please take the time to visit My Green Paste, Inc. Thank you.

Just a quick note - the authors of Advanced Windows Debugging have been interviewed on MSDN's Channel 9. It's about 43 minutes long, and it's interesting to hear the authors talk about their experiences, the motivation behind the book, the effect of additional layers of abstraction, etc., and go through a handle leak debugging session. Check it out!

2008-07-09

In Vista, How Does the FLAGS Switch of REG.EXE Work? Part 2

Note: this content originally from http://mygreenpaste.blogspot.com. If you are reading it from some other site, please take the time to visit My Green Paste, Inc. Thank you.

Previously, I wrote about the FLAGS switch for REG.EXE in Vista and covered a technique that would set the virtualization-related flags of a registry key programmatically. This post intends to cover the other side - querying for the virtualization-related flags of a registry key. Again, we're dealing with an "undocumented" function in NTDLL.DLL - NtQueryKey:

NTSTATUS NtQueryKey(
IN HANDLE KeyHandle,
IN KEY_INFORMATION_CLASS KeyInformationClass,
OUT PVOID KeyInformation,
IN ULONG Length
OUT PULONG ResultLength );


To retrieve the flags for a key, call NtQueryKey with KeyInformationClass set to 5, which WDM.h tells us is KeyFlagsInformation.
typedef enum _KEY_INFORMATION_CLASS {
KeyBasicInformation,
KeyNodeInformation,
KeyFullInformation,
KeyNameInformation,
KeyCachedInformation,
KeyFlagsInformation,
KeyVirtualizationInformation,
MaxKeyInfoClass // MaxKeyInfoClass should always be the last enum
} KEY_INFORMATION_CLASS


REG.EXE supplies 12 for the value of the Length param, and the last 4 bytes of the buffer (KeyInformation) are modified when NtQueryKey returns. This would seem to suggest that the struct to receive the information containing the virtualization flags looks something like:
typedef struct _KEY_FLAGS_INFO {
ULONG unknown1;
ULONG unknown2;
ULONG ControlFlags;
} KEY_FLAGS_INFO, *PKEY_FLAGS_INFO;


Putting it all together, then, we have something like:
typedef NTSYSAPI NTSTATUS (NTAPI* FuncNtQueryKey)( HANDLE KeyHandle, KEY_INFORMATION_CLASS KeyInformationClass, PVOID KeyInformation, ULONG Length, PULONG ResultLength );
// ...
FuncNtQueryKey ntqk = (FuncNtQueryKey)GetProcAddress( GetModuleHandle( _T("ntdll.dll") ), "NtQueryKey" );
KEY_FLAGS_INFO kfi = {0};
HKEY hTheKey = NULL;
RegOpenKeyEx( HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Whatever"), 0, KEY_ALL_ACCESS, &hTheKey );
DWORD dwResultLen = 0;
DWORD dwNtqkResult = ntqk( hTheKey , KeyFlagsInformation, &kfi, sizeof( KEY_FLAGS_INFO ), &dwResultLen );
RegCloseKey( hTheKey );
hTheKey = NULL;


The flags (_CONTROL_FLAGS, from Part 1) are stored as a bitmask in kfi.ControlFlags.
typedef enum _CONTROL_FLAGS {
RegKeyClearFlags = 0,
RegKeyDontVirtualize = 2,
RegKeyDontSilentFail = 4,
RegKeyRecurseFlag = 8
} CONTROL_FLAGS;


The code above provides the same information as invoking REG.EXE FLAGS HKLM\Software\Whatever QUERY.

Again - note that this exploration was done on Windows Vista SP1. I would expect the content here to also apply to Windows Vista (no SP) as well as Windows Server 2008, but...

2008-06-30

A Little Fun with Rundll32.exe

Note: this content originally from http://mygreenpaste.blogspot.com. If you are reading it from some other site, please take the time to visit My Green Paste, Inc. Thank you.


Was having a little fun with rundll32.exe (command-lines will probably be a little messed up due to the length - they should be entered as one complete command). I first tried the commands on XP, but they produce similar results on Vista.


C:\WINDOWS\system32\rundll32.exe C:\WINDOWS\system32\sysdm.cpl,NoExecuteProcessException C:\windows\system32\ntoskrnl.exe



C:\WINDOWS\system32\rundll32.exe C:\WINDOWS\system32\sysdm.cpl,NoExecuteProcessException C:\windows\system32\hal.dll



C:\WINDOWS\system32\rundll32.exe C:\WINDOWS\system32\sysdm.cpl,NoExecuteProcessException C:\windows\system32\chkdsk.exe



C:\WINDOWS\system32\rundll32.exe C:\WINDOWS\system32\sysdm.cpl,NoExecuteProcessException C:\windows\system32\autochk.exe



C:\WINDOWS\system32\rundll32.exe C:\WINDOWS\system32\sysdm.cpl,NoExecuteProcessException C:\windows\system32\smss.exe



C:\WINDOWS\system32\rundll32.exe C:\WINDOWS\system32\sysdm.cpl,NoExecuteProcessException C:\windows\system32\winlogon.exe



C:\WINDOWS\system32\rundll32.exe C:\WINDOWS\system32\sysdm.cpl,NoExecuteProcessException c:\windows\Soap Bubbles.bmp


2008-06-22

New Tool for Detecting Rootkits

Note: this content originally from http://mygreenpaste.blogspot.com. If you are reading it from some other site, please take the time to visit My Green Paste, Inc. Thank you.

Congratulations to AD for the public release of the beta of RootRepeal, a new rootkit detector!

See the tool's site on GooglePages for more info or to download:

http://rootrepeal.googlepages.com

2008-05-27

Garbled Content Ratings Dialog in IIS 6

Note: this content originally from http://mygreenpaste.blogspot.com. If you are reading it from some other site, please take the time to visit My Green Paste, Inc. Thank you.

Ran into the following while configuring IIS 6 on a new system. Not sure if I need to be concerned...

Garbled Content Ratings Dialog

2008-05-25

Creating Programs for Windows 9x and NT with Visual C++ 2008

Note: this content originally from http://mygreenpaste.blogspot.com. If you are reading it from some other site, please take the time to visit My Green Paste, Inc. Thank you.

A recent topic in the Development forum at Sysinternals Forums contains some information about how to use Visual C++ 2008 to create binaries that run on Windows 9x and NT. For NT, it seems to just be a matter of changing the Subsystem Version to 4.0. One might think to use the /SUBSYSTEM linker switch for this. However, when one attempts to do so, the shipping link.exe reports:


LINK : warning LNK4010: invalid subsystem version number x.y; default subsystem version assumed


In this case, the default subsystem version is 5.0, and NT needs 4.0. One can use an older copy of EditBin.exe to change this (I found the version that shipped with Visual Studio .NET 2003 to work):


editbin /SUBSYSTEM:CONSOLE,4.0 c:\path\to\your.exe


The same requirement also exists to get the executable to run on Windows 9x, but one needs to do a bit more work.


Louis Solomon has taken the time and put forth the effort to find what is needed for this, and has documented it at C/C++ EXEs and DLLs created by Visual Studio 2008 don't run on Windows 4.0 (ie, NT4 and Win9x).

2008-04-27

In Vista, How Does the FLAGS Switch of REG.EXE Work?

Note: this content originally from http://mygreenpaste.blogspot.com. If you are reading it from some other site, please take the time to visit My Green Paste, Inc. Thank you.


A while back, there was a topic (Virtual Registry vs. "Real registry") in the Sysinternals Forums that brought up the question of how to set the virtualization-related flags of a registry key programmatically in Vista, rather than through the use of the REG.EXE tool's FLAGS switch. (For more information on the flags, see Mark Russinovich's article in TechNet Magazine, "Inside Windows Vista User Account Control"). Even before that topic in the forum, I had wondered how it was done but had not had a chance to explore. It didn't seem that many others were curious about it. That topic had resurrected the idea, but it quickly fell to the bottom of the list. I've finally gotten around to experimenting, and that leads to this write-up. I still don't see much in the way of this discussed anywhere, by searching for terms involved (data types, function param names, etc.), so hopefully this will help someone. (Keep in mind that there very well may be a reason Microsoft hasn't made this available through another, more direct API.)


In the referenced topic, I had gotten so far as determining that REG.EXE was doing its work through the use of NtSetInformationKey, an "undocumented" API in NTDLL.DLL.


NTSYSAPI 

NTSTATUS

NTAPI

NtSetInformationKey(

IN HANDLE KeyHandle,

IN KEY_SET_INFORMATION_CLASS InformationClass,

IN PVOID KeyInformationData,

IN ULONG DataLength );


After a bit of plonking around in WinDbg, I've come up with the following following details. REG.EXE calls NtSetInformationKey, specifying a value of 2 for the InformationClass parameter. This parameter is of type KEY_SET_INFORMATION_CLASS, which wdm.h tells us is an enum:


typedef enum _KEY_SET_INFORMATION_CLASS {

KeyWriteTimeInformation,

KeyWow64FlagsInformation,

KeyControlFlagsInformation,

KeySetVirtualizationInformation,

KeySetDebugInformation,

MaxKeySetInfoClass // MaxKeySetInfoClass should always be the last enum

} KEY_SET_INFORMATION_CLASS;


So the 2 for the InformationClass parameter would correspond to KeyControlFlagsInformation. WDM.H also suggests that this class has a type that one passes for the KeyInformationData parameter - KEY_CONTROL_FLAGS_INFORMATION:


typedef struct _KEY_CONTROL_FLAGS_INFORMATION {

ULONG ControlFlags;

} KEY_CONTROL_FLAGS_INFORMATION, *PKEY_CONTROL_FLAGS_INFORMATION;


We have a basic idea of how to call NtSetInformationKey now. But what are the values that the ControlFlags member of KEY_CONTROL_FLAGS_INFORMATION can be set to? It would appear that the following (self-made) enum covers the pertinent flags - at least the ones REG.EXE FLAGS can handle (there may be more):


typedef enum _CONTROL_FLAGS {

RegKeyClearFlags = 0,

RegKeyDontVirtualize = 2,

RegKeyDontSilentFail = 4,

RegKeyRecurseFlag = 8

} CONTROL_FLAGS;


The control flags are a bitmask, so you can OR them to set more than one.


Now that we have this information, what's left? We need to put it all together in a call to NtSetInformationKey. So, we need to get a pointer to the function in NTDLL.DLL. Then, we can declare a struct of type KEY_CONTROL_FLAGS_INFORMATION, set the ControlFlags member to be what we wish, and open a key to the desired location in the registry, that can be passed to NtSetInformationKey. In the end, we wind up with something like the following (error handling has been omitted):


typedef NTSYSAPI NTSTATUS (NTAPI* FuncNtSetInformationKey) (

HANDLE KeyHandle,

KEY_SET_INFORMATION_CLASS InformationClass,

PVOID KeyInformationData,

ULONG DataLength );

//...

FuncNtSetInformationKey ntsik = (FuncNtSetInformationKey)GetProcAddress(

GetModuleHandle( _T("ntdll.dll") ), "NtSetInformationKey" );

KEY_CONTROL_FLAGS_INFORMATION kcfi = {0};

kcfi.ControlFlags = RegKeyDontVirtualize | RegKeyRecurseFlag;

HKEY hTheKey = NULL;

RegOpenKeyEx( HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Whatever"), 0, KEY_ALL_ACCESS, &hTheKey );

ntsik( hTheKey, KeyControlFlagsInformation, &kcfi, sizeof( KEY_CONTROL_FLAGS_INFORMATION ) );

RegCloseKey( hTheKey );

hTheKey = NULL;



The code above is the equivalent of invoking REG.EXE FLAGS HKLM\Software\Whatever SET DONT_VIRTUALIZE RECURSE_FLAGS. To clear the flags, just set kcfi.ControlFlags to RegKeyClearFlags (same as REG.EXE FLAGS HKLM\Software\Whatever SET).

Hopefully, this will prove useful to those that have wished to set these flags programmatically. In a future post, I hope to explore querying for these flags, ala REG.EXE FLAGS HKLM\Software\Whatever QUERY.


Note that this exploration was done on Windows Vista SP1. I would expect the content here to also apply to Windows Vista (no SP) as well as Windows Server 2008, but...

2008-04-25

My Answer to "Microsoft Advanced Windows Debugging and Troubleshooting" Puzzler 3

Note: this content originally from http://mygreenpaste.blogspot.com. If you are reading it from some other site, please take the time to visit My Green Paste, Inc. Thank you.

Previously, I had written about the puzzlers on the NTDebugging / Microsoft Advanced Windows Debugging and Troubleshooting blog - specifically, the most recent puzzler which involved reverse engineering some assembler. The answer was posted today - there were a lot of responses, and a lot of correct responses.

I had posted the hashes for my answer (which was correct), that I am now able to disclose...

void myfun( char* param1 )
{
size_t local1 = strlen( param1 );
for( int local2 = local1; local2 > 0; local2-- )
{
for( int local3 = 0; local3 < local2 - 1; local3++ )
{
if( *(param1+local3) > *(param1+local3+1) )
{
char local4 = *(param1+local3);
*(param1+local3) = *(param1+local3+1);
*(param1+local3+1) = local4;
}
}
}
}

2008-04-24

Microsoft Advanced Windows Debugging and Troubleshooting Puzzlers

Note: this content originally from http://mygreenpaste.blogspot.com. If you are reading it from some other site, please take the time to visit My Green Paste, Inc. Thank you.

Over on the Microsoft Advanced Windows Debugging and Troubleshooting blog, they've been posting a "Puzzler" every Monday and providing the answers the following Friday.

The puzzlers are fun to participate in and it is interesting to read people's responses - everyone has their own ideas and own experiences to draw off of.

With the third puzzler, the blog authors have decided to make the challenge a bit more difficult - the latest puzzler requires one to reverse engineer some assembler.

I've not got much experience with reverse engineering assembler - I can read some assembler and can usually get a very basic idea of what a targeted chunk of code is doing. So it was an interesting challenge for me to attempt to C-ify the assembler they provided. It doesn't appear that the authors are posting the responses until they reveal the answer (makes sense to me!). But I thought I'd post hashes of my response, which I'll also post once the NT Debugging blog authors post the answer and submitted comments / responses.

From Sigcheck:


Z:\NTDebuggingPuzzler3>sigcheck -h TheFunc.txt

Sigcheck v1.52
Copyright (C) 2004-2008 Mark Russinovich
Sysinternals - www.sysinternals.com

Z:\NTDebuggingPuzzler3\TheFunc.txt:
Verified: Unsigned
File date: 12:52 PM 4/22/2008
Publisher: n/a
Description: n/a
Product: n/a
Version: n/a
File version: n/a
MD5: 755394f9711b80968f17c8ffcb8f2394
SHA1: e8443f09eef43f2575aa08ba25f68267dba7243e
SHA256: 0e044419ef78f2fa7a8e258098f4f658426a8dc3e8a5b9a121a352c2dbbbfafc


EDIT 2008-04-24: The hashes are for the code that was submitted in my second response (not the entire response - just the code). In my first response, I inadvertently left some garbage in the code (an unnecessary / unused local I had been playing with) and I neglected to remove it before submitting. Not sure how it will all pan out when the comments / responses get posted tomorrow...

2008-03-25

Clipboard Chaos!

Note: this content originally from http://mygreenpaste.blogspot.com. If you are reading it from some other site, please take the time to visit My Green Paste, Inc. Thank you.

OK, so perhaps chaos is a bit of a harsh word here. But the clipboard was recently driving me nuts! All I was trying to do was copy some text to it, and the operation was failing. Of course, as it was an ad hoc app, I didn't have any kind of error handling. The app worked just fine on one system, but running the app on another system (a virtual machine) consistently resulted in failure to copy the text to the clipboard.

Ultimately, I was able to determine what process was preventing my app from putting data in the clipboard, but I haven't yet found a decent workaround for when the problem happens. It's not critical for me, as the act of copying the text to the clipboard is more of a nicety than a requirement.

Anyway, using P/Invoke and System.Diagnostics, I found that vmusrvc.exe - the Virtual PC "Virtual Machine User Services" - had the clipboard open. Using the timestamps from Process Monitor's Profiling Events (generated at 100 ms intervals), and the timestamp of the failed operation from my app, I was able to determine the stack of vmusrvc.exe:

ntdll.dllKiFastSystemCallRet
vmusrvc.exevmusrvc.exe + 0x9a17
vmusrvc.exevmusrvc.exe + 0x9c24
vmusrvc.exevmusrvc.exe + 0x91f8
vmusrvc.exevmusrvc.exe + 0x907f
USER32.dllInternalCallWinProc + 0x28
USER32.dllUserCallWinProcCheckWow + 0x150
USER32.dllDispatchClientMessage + 0xa3
USER32.dll__fnDWORD + 0x24
ntdll.dllKiUserCallbackDispatcher + 0x13
vmusrvc.exevmusrvc.exe + 0x2d29
vmusrvc.exevmusrvc.exe + 0xdba6
kernel32.dllBaseProcessStart + 0x23

No parameters, of course, and symbol information for vmusrvc.exe does not appear to be available, but obviously user32.dll is processing some message. I may look into this more at a later point.

To find the process that was interfering with my clipboard work, I used P/Invoke to call GetOpenClipboardWindow() and then GetWindowThreadProcessId(), passing in the handle returned by GetOpenClipboardWindow(). Then, finding the process' executable name was just a matter of using the Modules collection of the Process instance returned by passing in the process id retrieved by GetWindowThreadProcessId() to System.Diagnostics.Process.GetProcessById().

The following code:

using System.Runtime.InteropServices;
using System.Diagnostics;
...
string data = "aasdlkjasdlk alkjsdl kajsdlkj al";
try
{
Clipboard.SetData( System.Windows.Forms.DataFormats.Text, data );
}
catch( ExternalException ee )
{
LogIt( ee.ToString() );
IntPtr hWnd = GetOpenClipboardWindow();
if( IntPtr.Zero != hWnd )
{
uint pid = 0;
uint tid = GetWindowThreadProcessId( hWnd, out pid );
LogIt( "Process with hWnd {0}, PID {1} ({1:x}), TID {2} ({2:x}), " +
"name {3} has the clipboard", hWnd, pid, tid,
Process.GetProcessById( (int)pid ).Modules[0].FileName );
}
}

Resulted in the following output:


2008-03-25 00:54:45.4938864--> System.Runtime.InteropServices.ExternalException: Requested Clipboard operation did not succeed.
at System.Windows.Forms.Clipboard.ThrowIfFailed(Int32 hr)
at System.Windows.Forms.Clipboard.SetDataObject(Object data, Boolean copy, Int32 retryTimes, Int32 retryDelay)
at System.Windows.Forms.Clipboard.SetData(String format, Object data)
at Clippy.Form1.button1_Click(Object sender, EventArgs e)
2008-03-25 00:54:45.5339440--> Process with hWnd 65716 (65716), PID 1492 (5d4), TID 1496 (5d8), name C:\Program Files\Virtual Machine Additions\vmusrvc.exe has the clipboard

Interestingly, trying an alternative method of the Clipboard to set the content also failed. The Clipboard.SetDataObject() overload that takes a retryTimes and retryDelay parameter failed in the same fashion after roughly ten seconds when invoked as follows:


Clipboard.SetDataObject( data, false, 100, 100 );

I tried variations on retryTimes and retryDelay, to no avail.

Not sure what vmusrvc.exe is doing with the clipboard (probably has to do with monitoring it for host / guest VM interaction), but the act of setting the contents of the clipboard didn't fail 100% of the time in the VM. Often enough to make it extremely unreliable, though. During "normal" system usage, I was not able to cause a failure when running the app on a non-virtual (actual?) system.

2008-02-21

w29n51.sys BSODs on XP

Note: this content originally from http://mygreenpaste.blogspot.com. If you are reading it from some other site, please take the time to visit My Green Paste, Inc. Thank you.

Twice now in as many months I have been the proud recipient of a BSOD on XP. The crashes were identical to each other with only various addresses being different (modules loaded into a different location and the like). They appear to have been caused by a bug in w29n51.sys; the crashes are of the IRQL_NOT_LESS_OR_EQUAL (a) variety. w29n51.sys is the "Intel® Wireless LAN Driver". Admittedly, I'm running a version that is likely not the latest. But it is interesting that googling the relevant stack entries (w29n51+0x1291, w29n51+0xa6af) turns up no hits. Also of interest is that the driver file is larger than 3 MB - more than 3 times the size of the next largest driver file in %systemroot%\system32\drivers... Strings does show a large number of verbose log-type messages that one can presumably cause to be logged via some configuration setting, as well as "tabular" data.

Of course, it is also disturbing that at the time of these crashes, the wireless hardware was disabled on this laptop... Confused

2008-02-19

Plagiarism, Revisited

Note: this content originally from http://mygreenpaste.blogspot.com. If you are reading it from some other site, please take the time to visit My Green Paste, Inc. Thank you.

Raymond Chen posted about a topic yesterday that seems to hit the nail on the head with regard to some of the recent posts I've made here. In What's with all those spam ping-bots?, he describes the methodology used by blog and comment spammers / content thieves, and the motivation ($$) for doing what they do.

Of interest:

(You may notice that many of these sites mis-attribute the authorship; some of them even claim to have written the article themselves!)

Raymond also offers some advice about what one can try to do to "hit them in the pocketbook".

Sadly (ironically?), as I write this, 50% of the comments to that very blog entry are of the type that Raymond was writing about.

So it appears that there is not much that one is going to do to curb this. Also, considering that much of the content here (not just the newer stuff) has already been picked up and assimilated into other sites that slap a label on it as their own, and have even translated it (?????) into foreign languages, and then stamped ads all over it, I'm not inclined to waste much effort on the matter. I'll simply preface each entry with what you have seen the last few articles start with, and hope that that part of it makes its way along with the article to wherever it winds up. I may intersperse one or two similar statements in the longer articles as well. I hope it's not too distracting...

2008-02-07

Use C# to Find What Services are Running in a Process

Note: this content originally from http://mygreenpaste.blogspot.com. If you are reading it from some other site, please take the time to visit My Green Paste, Inc. Thank you.

Recently, an individual going by the moniker 'hi' posted a comment to Setting the Priority of a Service Process via Script:

How would I, if I want to, find which services are part of a particular svchost.exe? Can in be done in C#?

Thanks!

I replied via comment, but one has even less control over formatting in comments than one does in the actual blog posting, so I figured I would post the response here as well.

=================

Tasklist.exe with the /svc param can tell you, as can Process Explorer. You can also inspect the registry to determine what services would load with what SVCHOST group (see "Troubleshooting Performance Issues with Automatic Updates" for more details).

As far as C# code, the following requires a reference to System.Management. Invoke the program, passing it the process id of the process you're curious about, and it will output the services running in that process.

using System;
using System.Management;

namespace MyGreenPaste
{
class Program
{
static void Main( string[] args )
{
if( args.GetLength( 0 ) <= 0 )
{
Console.WriteLine( "Usage: {0} pid",
System.IO.Path.GetFileName(
System.Diagnostics.Process.GetCurrentProcess().
MainModule.FileName ) );
Console.WriteLine( " where pid is the process id " +
"of a process hosting at least one service" );
return;
}

try
{
ManagementObjectSearcher mos =
new ManagementObjectSearcher( "root\\CIMV2",
string.Format( "SELECT * FROM Win32_Service " +
"where ProcessId={0}", args[0] ) );
foreach( ManagementObject result in mos.Get() )
{
Console.WriteLine( "{0} -> {1}", result["Name"],
result["DisplayName"] );
}
}
catch( ManagementException mex )
{
Console.WriteLine( "** Error querying WMI:{0}{1}",
System.Environment.NewLine, mex.Message );
}
}
}
}

2008-02-02

Small Update Regarding Previous Post Pertaining to Plagiarism

Ahhhh, alliteration. Anyway, just noticed that one of the other sites has posted the cheesy comment I referenced in my previous entry, Set the Priority of a Process By Name Automatically, in Vista - Part 2. So, both saw fit to post the comments (took a while for the one site, though) - the first stamped 2008-01-31 2:37 GMT, and the second stamped 2008-01-30 13:40 GMT. No sign of Part 2 on either of these sites, though... Hmmm...

2008-01-31

Set the Priority of a Process By Name Automatically, in Vista - Part 2

This isn't what I want to be writing about. But a recent discovery compels me to do so. So, I've decided to make this an experiment, and beg your apologies that this will not have much technical merit despite the title.

After the last post, Set the Priority of a Process By Name Automatically, in Vista (which probably could have been named a lot better), I discovered that the post had made its way to some other sites. These sites appear to pull content from all over the web, package it up as their own, and toss ads all over it. One is lucky if the site even references the original author or links back to the original location of the post. It's frustrating, to say the least. I'm all for distribution of knowledge and the like, but that's taking it too far. Maybe I shouldn't feel this way, but I (like others) put brain sweat and time into the work I do, and it would be nice if the source of the information would at least be cited if they're going to republish it without the author's consent.

So I visited two of these sites (which I have not yet decided if I will mention or not, for what I hope are obvious reasons) and attempted to leave comments. Of course the comments are moderated - don't want any upset victims coming in and raising he. The comments were along the line of:

As the author of the original article referenced here, I kindly request that those interested in it please read it at MY blog, <a href="http://mygreenpaste.blogspot.com">My Green Paste, Inc.</a>

My site does not currently have ads, and I am NOT even considering ads at this time.

–«/\/\Øö±ò\/»®© (molotov)


Can you guess what happened? Yep - the comments were not approved, and were never published on the sites in question. I then attempted to leave another comment at each copy of my posting. This time, one site saw fit to allow the comment, and the other one did not. I suspected NO comments would have been allowed through either site, so I was a bit surprised. The comment was a bit ridiculous given the content of the posting, and rather generic; perhaps that's why it was allowed. The comment was simply:

does this work for other os like XP or server 2003?

Amazing. It was posted at 2008-01-31 2:37 GMT. The comment, like this post, is a part of the experiment. See, if I mention things that I mentioned in the previous post, like CpuPriorityClass, image file execution options, IoPriority, PagePriority, PerfOptions, powershell, priority, Process Monitor, setpriorityclass, Sysinternals, Vista, WorkingSetLimitInKB, Vista, Windows Vista, Windows Vista Ultimate, etc. (sorry to get carried away there), will this post make it to these sites as well? If so, wouldn't that be somewhat funny? The comment falls in there, too - if the now published comment magically disappears from the copy of my previous post, won't that be a bit odd?

I think I'll have to start embedding a "this content originally from http://mygreenpaste.blogspot.com/" statement into the middle of each of my posts from now on. I'm sure I'll forget, and I've probably only got one shot. That'll make for some nice, flowing reading. We'll see.

I do have some more thoughts about the Set the Priority of a Process By Name Automatically, in Vista topic that I expect to get out in my next post. I apologize for this distraction, and hope you'll stay tuned...

BTW - I may also have a follow up to this fork in the saga as well.

2008-01-27

Set the Priority of a Process By Name Automatically, in Vista

The other day I was playing around with the Image File Execution Options and Sysinternals' Process Monitor, in Vista. I saw an interesting query take place. Using notepad.exe as an example, I saw a query for a key called "PerfOptions" in [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\notepad.exe] when I ran notepad. The result was NAME NOT FOUND, so I decided to rectify that. After adding a key named "PerfOptions", I ran notepad again. In Process Monitor, I saw queries for four values:

  • IoPriority
  • PagePriority
  • CpuPriorityClass
  • WorkingSetLimitInKB

Because of recent explorations with process priorities*, CpuPriorityClass grabbed me right away. Looking at the SetPriorityClass function, one can see the different values for the dwPriorityClass parameter. I created a REG_DWORD named CpuPriorityClass in PerfOptions, and set the value to 0x80 in the hopes that notepad would launch with "HIGH_PRIORITY_CLASS". Instead, it launched with a priority of NORMAL_PRIORITY_CLASS (8) - the setting had not made any impact. Then, I set the value to 8 and launched notepad. Notepad launched with a priority of 8. I changed the value to 4, and that had no impact. I changed the value to 0 - no impact. I tried 10 - no impact. I couldn't see any tie in to any other listings of process priorities that I knew about, so I decided to try trial and error, starting from 0, with the following results:










CpuPriorityClass ValuePriority of NotepadPriority Class
14Idle
313High
56BelowNormal
610AboveNormal
Anything else^8Normal


^= I'm currently running a PowerShell script to iterate through all possible values (there's only about 2^32...) so it may be a while before the CpuPriorityClass value for REALTIME_PRIORITY_CLASS, should it exist, be uncovered. There may also be other values that can be used to specify a priority class that's been uncovered. I'll update or post a new topic if I uncover anything new...

The PowerShell script (don't laugh, it's my first substantial attempt at one):


$cpc=0
set-itemproperty "hklm:\software\microsoft\windows nt\currentversion\image file execution options\notepad.exe\perfoptions" cpupriorityclass $cpc
do
{
$pp = [diagnostics.process]::start("notepad.exe", "")
$ppc = $pp.PriorityClass
$pp.Kill()
if( $ppc -ne "Normal" )
{
Write-Host $cpc $ppc
}
$cpc++
set-itemproperty "hklm:\software\microsoft\windows nt\currentversion\image file execution options\notepad.exe\perfoptions" cpupriorityclass $cpc
}
while( $cpc -lt 4294967295 )


Hopefully, I'll find time to do some digging into the other values in PerfOptions - IoPriority, PagePriority, and WorkingSetLimitInKB. IoPriority and PagePriority sound like they may have something to do with memory prioritization and IO prioritization in Vista. WorkingSetLimitInKB sounds self-explanatory, but how it's applied or how it's used, and other circumstances, are quite vague.


*= SetThreadPriority, Vista, and Autostart Locations, Setting the Priority of a Service Process via Script