Log in

View Full Version : WriteProcessMemory on XP services


kP^
December 29th, 2003, 21:22
Hi!

i wrote this little tool, wrapper for the WriteProcessMemory API, but i can't use it on system services.

Why ?

dELTA
December 29th, 2003, 22:11
Most services run as the "LocalSystem" user, and "normal programs" (e.g. those run as the administrator user) do not have debug or write privileges for these. Either change the user of the service or make your program run as LocalSystem too, and it should work fine.

Kayaker
December 29th, 2003, 22:40
Hi

I'm not sure how your app is implemented, but I suspect it may be due to the service tables being write protected in XP. Take a look at Windows NT System Service Table Hooking
http://www.wiretapped.net/~fyre/sst.html

--------------------------------------
In order to discourage people from using these undocumented interfaces, Microsoft attempted to write-protect the service tables in Windows XP. Writing to them causes a blue screen of death, unless the pages are somehow made writeable first.

The simplest method is to disable the WP bit in the i386's CR0 register before modifying the table. For example:

MOV EAX, CR0
AND EAX, NOT 10000H
MOV CR0, EAX
; modify table
MOV EAX, CR0
OR EAX, 10000H
MOV CR0, EAX

Another method is to modify the PTE's for the pages that the service table resides in so that the supervisor (executive/kernel) may write to them.
---------------------------


I'm curious about your approach, there's no source but if you're trying to manipulate the ServiceDescriptorTable in order to access the services, I'd be interested if one of the above solutions works for XP. I wrote some code which adds new user defined services by modifying the KeServiceDescriptorTableShadow, it works fine for Win2K but as I don't have XP I can't test this write protection issue.

Kayaker

kP^
December 29th, 2003, 22:59
well, let me be honest with you ...

i know i shouldn't give names, but i'm trying to patch deep freeze.
maybe you're not familiar with this app, it's a nice security solution from HyperTechnologies Inc.
while taking a look at it, i encountered this unique situation where the only vulnerable part of a system is its memory, so the only way to melt deepfreeze's protection i found was to modify the running service (not the ring 0 driver, but the ring3 usermode exe).

while on 9x i solved it with dede and my procpatch tool and units for getting a service's -process- handle and using the writeprocmem api on it, on nt platforms things are a little more complicated: i could not 'Openprocess' a Windows XP process with the PROCESS_VM_OPERATION flag for later VirtualProtectEx and WriteProcessMemory usage.

any suggestions ?
my softice won't bpx

kP^
December 29th, 2003, 23:03
i'll try this out the as soon as possible.
thanks!

doug
December 30th, 2003, 00:18
Hello, part of this code is from the Platform SDK, the rest is from something I wrote a few months ago,
http://www.woodmann.net/forum/showpost.php?p=29119&postcount=9

Code:

/* straight from sdk */
BOOL AdjustPrivilege(
HANDLE hToken, // access token handle
LPCTSTR lpszPrivilege, // name of privilege to enable/disable
BOOL bEnablePrivilege // to enable or disable privilege
)
{
TOKEN_PRIVILEGES tp;
LUID luid;

if ( !LookupPrivilegeValue(
NULL, // lookup privilege on local system
lpszPrivilege, // privilege to lookup
&luid ) ) // receives LUID of privilege
{
printf("LookupPrivilegeValue error: %u\n", GetLastError() );
return FALSE;
}

tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
if (bEnablePrivilege)
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
else
tp.Privileges[0].Attributes = 0;

// Enable the privilege or disable all privileges.

if ( !AdjustTokenPrivileges(
hToken,
FALSE,
&tp,
sizeof(TOKEN_PRIVILEGES),
(PTOKEN_PRIVILEGES) NULL,
(PDWORD) NULL) )
{
printf("AdjustTokenPrivileges error: %u\n", GetLastError() );
return FALSE;
}

return TRUE;
}


/*
Request debug privilege for the current process
otherwise it's not possible to get PROCESS_ALl_ACCESS on services.exe
*/
BOOL SetDebugPrivilege()
{
HANDLE TokHand;
BOOL retval;

if (OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &TokHand)==0)
return FALSE;

retval= AdjustPrivilege(TokHand, SE_DEBUG_NAME, TRUE);
CloseHandle(TokHand);
return retval;
}

/* gets handle to services.exe */
HANDLE getServicesProcessHandle(DWORD pid)
{
if (SetDebugPrivilege())
{
return OpenProcess( PROCESS_ALL_ACCESS, FALSE, pid );
}
else
return NULL;
}


Get the service's processID, then use:

Code:

services_hand=getServicesProcessHandle(services_pid)


I can assure you that method works, as I was injecting code into services.exe with an on/off switch to enable/disable the hook.

JMI
December 31st, 2003, 02:10
Ah wonderfully devious methods you all are using. Wish I had more time to study and play with these deeper issues. Working for a living is seriously impacting my play time.

Regards,