This would be a lot easier if I wasn't chasing red herrings. Case in point:
Error: exception 0xC0000005 (access violation). When a thread awakens from a call to Sleep(), it finds that EIP is invalid and throws an exception.
What's really happening: netman is making an API call that causes a thread to get spawned, but unloads the DLL before it can complete.
Here's an assembly code snippet from netman.dll:
.text:7627C5BB push offset aWzcsvc ; "wzcsvc" .text:7627C5C0 call ds:LoadLibraryW .text:7627C5C6 mov esi, eax .text:7627C5C8 test esi, esi .text:7627C5CA jz short loc_7627C5F0 .text:7627C5CC push offset aWzctrayiconrea ; "WZCTrayIconReady" .text:7627C5D1 push esi ; hModule .text:7627C5D2 call ds:GetProcAddress .text:7627C5D8 test eax, eax .text:7627C5DA jz short loc_7627C5E5 .text:7627C5DC lea ecx, [ebp+NameBuffer] .text:7627C5E2 push ecx .text:7627C5E3 call eax .text:7627C5E5 .text:7627C5E5 loc_7627C5E5: ; CODE XREF: CConnectionManager::Advise(IUnknown *,ulong *)+18Fj .text:7627C5E5 test esi, esi .text:7627C5E7 jz short loc_7627C5F0 .text:7627C5E9 push esi ; hLibModule .text:7627C5EA call ds:FreeLibrary .text:7627C5F0 .text:7627C5F0 loc_7627C5F0:
And this is what it means in C:
hModule = LoadLibraryW(L"wzcsvc");
hModuleA = hModule;
if ( hModule )
{
WZCTrayIconReady = GetProcAddress(hModule, "WZCTrayIconReady");
if ( WZCTrayIconReady )
{
((void (__stdcall *)(WCHAR *))WZCTrayIconReady)(&NameBuffer);
}
if ( hModuleA )
{
FreeLibrary(hModuleA);
}
}
So basically it loads wzcsvc.dll, calls WZCTrayIconReady, and then unloads it. The problem is that WZCTrayIconReady spawns a worker thread via QueueUserWorkItem, and the worker routine does a Sleep() for 1 second. So when the call immediately returns to netman, it immediately unloads wzcsvc--and when the worker thread wakes up, BOOM! Even the MSDN documentation for QueueUserWorkItem() points out to make sure to not unload a DLL before the work item has completed.
XP fixes this by statically linking wzcsvc.dll into netman.dll. Now, it's possible that my slowing things down with all the debugging output is causing the error to manifest itself. I might have to fix netman before I can continue on my kernel32 rewrite mission.
(sigh)



Help
Back to top










