Log in

View Full Version : Native_MapFile


BanMe
June 10th, 2009, 22:30
if bilbo reads this, a deep thank you for pointing me to the error display routine.. ive fixed it and plan to update the code very soon

Kind regards BanMe

Kayaker
June 11th, 2009, 02:21
You may want to check the correct syntax for NtOpenDirectoryObject. I dumped the whole snippet into a driver (changing Nt to Zw where required) and ran your code.

(Zw)OpenDirectoryObject call returned C000003Bh:

; MessageId: STATUS_OBJECT_PATH_SYNTAX_BAD
; MessageText:
; Object Path Component was not a directory object.

STATUS_OBJECT_PATH_SYNTAX_BAD equ 0C000003Bh


The initialized unicode directory string was, as specified, "C:\Windows\System32".

I'm not sure you can specify a plain file directory as a Directory Object Name for use with NtOpenDirectoryObject. It probably requires a 'standard' object name such as L"\Driver", \Device, \Callbacks, \KernelObjects, \DosDevices.

Do not confuse object directories with file system directories. Object directories exist only within the object manager, and do not correspond to any directory on disk. (File system directories are, in fact, represented as file objects.)

http://msdn.microsoft.com/en-us/library/aa489526.aspx


Couldn't you just specify the full pathname in NtCreateFile, instead of doing a 2 step process and referring to a directory handle which isn't needed otherwise?

Maybe that's not the same source of error for you, but it is when the code is run in kernel mode.

GamingMasteR
June 11th, 2009, 03:41
NtOpenObjectDirectory is not for dealing with directory files as kayaker said, it's for kernel object directories !

Just use NT path with NtCreateFile :
"\\??\\C:\\Windows\\System32\\Csrsrv.dll"

Regards,
[GM]

BanMe
June 11th, 2009, 10:44
actually Kayaker Ive hit that error a few times..I've also tried "\\DosDevices\\C:\\Windows\\System32\\csrsrv.dll" and the one suggested by GamingMasteR also a few others, these all return STATUS_SHARING_VIOLATION or some such similar error..nice to know same error occurs in Kernelmode..and is not a error in my coding..
So this behavior has to be something to do with how Csrss loads csrsrv.dll..ie csrss probably Opens a exclusive | permanent handle to it preventing the techinque I am using..if this is the case(dont know for sure, have to look) then im pretty sure my solution lies in LdrLoadDll somewhere..(more to come on that) ;}

regards BanMe

GamingMasteR
June 11th, 2009, 13:15
Why not open the file and section for read/execute ? get rid of ALL_ACCESS flag ...

BanMe
June 11th, 2009, 14:10
lol

Thank you GamingMasteR

I dont really need Write Access to the "file" anyway and UNC paths work now yay xD

all over write access...

much more to come now that this small hurdle is overcome.

regards BanMe

BanMe
June 11th, 2009, 17:58
removed temporary fix.. see explanation below for details on a more reliable fix

Kayaker
June 12th, 2009, 23:54
Quote:
[Originally Posted by BanMe;81069]The error resides in the call to NtMapViewOfSection and is NTSTATUS code 0xc0000220 or STATUS_MAPPED_ALIGNMENT..


You're lucky, it just BSOD's for me at that API

Of course that's when simply running it in kernel mode, as is, without taking into consideration parameters or overall programming logic under that condition.

Just to clarify, this code is running as a native application which executes during boot up and before the Win32 gui subsystem has fully loaded, is that right?

How are you debugging btw? Wouldn't a VMWare/WinDbg setup or boot loaded Softice allow you to place an Int3 before NtMapViewOfSection so you could trace into it and find exactly which parameter or condition is causing the error?

BanMe
June 13th, 2009, 01:08
lol i compile it as subsystem:windows and just use the vc++ debugger ... debugging it during runtime is a bad idea when it is running as a native application before win32 subsystem completely loads, if it errors BSOD, which isnt good for debugging..also if any threads executes NtTerminateProcess it will cause the system/VM to BSOD with Subsystem Process Exited with Status 0x0(0x0,0x0)...so I think it is best to compile it in win32 Mode and change minor things and then debug it, as I would rather work the errors out in win32 mode where if it errors the program just dies.After that is done, I then analyze crash dumps in Native mode to work out the other bugs, a two step process but i gain more this way

BanMe
June 13th, 2009, 05:21
it turns out to be a really simple solution to this current problem

STATUS_MAPPED_ALIGNMENT:means the module doesnt line up in memory with the module's desired base address..

this hit me after reading Phrack #66 "backdooring juniper firewalls" by Graeme. so all's that is needed to make this function run smoothly is a simple query of the modules current imagebase in csrss or working it out of the PE of the File(both methods with be investigated)... then simply place the returned imagebase (if ! 0) into TargetRegion, and then call NtMapViewOfSection... to test this use a tool that displays csrss dll's and place the ImageBase into TargetRegion..(I used RkUnhooker,and Icesword to verify).. you know, the funny thing in all this, is that the solution came from a "completely" unrelated area of study,just goes to show that if you work hard enough and are determined answers can come from anywhere at anytime...it came after i gave up and decided to read some stuff. which works for me

Native_MapFile replaced by Native_MapModuleQueryAlignment
Code:

//szPathToModule = NT Path to module

//Pid targets the process we want to map to :d

//MapSelf true = mapfile to self, Pid is assumed to be 0
//and we check what LoadCheckAlignment is,
//if it is FALSE then we default to checking csrss for imagebase.
//if LoadCheckAlignment is true we do the mentioned process below
//and load the module into memory before via LdrLoadDll and then map it to self.

//MapSelf false = map file to process specified by Pid

//LoadCheckAlignment if true LdrLoadDll is called with StripPath(szPathToModule) and passed
//as a parameter and upon success query the modules memory alignment.

HANDLE Native_MapModuleQueryAlignment(__in wchar_t *szPathToModule,__in_opt ULONG Pid,__in BOOLEAN MapSelf,BOOLEAN LoadCheckAlignment)
{
HANDLE hSection = 0;
HANDLE hFile = 0;
HANDLE TargetProcess = 0;
ULONG TargetRegion = 0;
ULONG Index = 0;
PVOID TargetModule = 0;
FILE_STANDARD_INFORMATION FileInformation = {0};
LARGE_INTEGER FileSize = {0};
OBJECT_ATTRIBUTES oa;
DEBUG_BUFFER *pDbgbuf = {0};
IO_STATUS_BLOCK StatusBlock = {0};
UNICODE_STRING Unicode = {0};
CLIENT_ID ClientId = {0};
char mbPath[255] = {0};
wchar_t Err[255] = {0};
SIZE_T ViewSize = 0;
NTSTATUS Status = 0;
BOOLEAN Enabled = 0;
int Pathtest = 1;

__try
{
Status = RtlAdjustPrivilege( 20L ,true,false,&Enabled);
if(!NT_SUCCESS(Status))
{
RtlInitUnicodeString(&Unicode,L"RtlAdjustPrivilege Status:";
__leave;
}
if(MapSelf == TRUE)//use csrss
{
Pid = CsrGetProcessIdEx();
TargetProcess = NtCurrentProcess();
if(Pid == 0)
{
RtlInitUnicodeString(&Unicode,L"CsrGetProcessIdEx returned 0";
__leave;
}
}
else//open the process
{
ClientId.UniqueProcess = (HANDLE)Pid;
ClientId.UniqueThread = 0;
Status = NtOpenProcess(&TargetProcess,PROCESS_ALL_ACCESS,0,&ClientId);
if(!NT_SUCCESS(Status))
{
RtlInitUnicodeString(&Unicode,L"NtOpenProcess Status";
__leave;
}
LoadCheckAlignment = TRUE;
}
if(LoadCheckAlignment == FALSE)
{
RtlInitUnicodeString(&Unicode,szPathToModule);
pDbgbuf = RtlCreateQueryDebugBuffer(0,0);
Status = RtlQueryProcessDebugInformation(Pid,PDI_MODULES,pDbgbuf);
if(!NT_SUCCESS(Status))
{
RtlInitUnicodeString(&Unicode,L"RtlQueryProcessDebugInformation Status:";
__leave;
}
wcscpy((wchar_t*)&Err,Unicode.Buffer);
Index = 0;
do
{
Index++;
Pathtest = wcsncmp(&Err[Index],L"C",1);
}while(Pathtest != 0);
wcstombs((char*)&mbPath,(wchar_t*)&Err[Index],wcslen((wchar_t*)&Err[Index]));
for(Index = 0;Index<=pDbgbuf->ModuleInformation->Count;Index++)
{
Pathtest = strcmp((char*)pDbgbuf->ModuleInformation->DbgModInfo[Index].ImageName,(char*)&mbPath);
if(Pathtest == 0)
{
TargetRegion = pDbgbuf->ModuleInformation->DbgModInfo[Index].Base;
break;
}
}
Status = RtlDestroyQueryDebugBuffer(pDbgbuf);
if(!NT_SUCCESS(Status))
{
RtlInitUnicodeString(&Unicode,L"RtlDestroyQueryDebugBuffer Status:";
__leave;
}
RtlAdjustPrivilege(20L,false,false,&Enabled);
}
if(LoadCheckAlignment == TRUE)
{
RtlInitUnicodeString(&Unicode,szPathToModule);
wcscpy((wchar_t*)&Err,Unicode.Buffer);
do
{
if(wcsncmp(&Err[Pathtest],L"C",1) == 0)
{
break;
}
Pathtest++;
}while(Pathtest <= Unicode.MaximumLength);
Pathtest = (int)wcslen((wchar_t*)&Err);
do
{
if(wcsncmp(&Err[Pathtest],L"\\",1) == 0)
{
break;
}
Pathtest--;
}while(Pathtest != 0);
RtlInitUnicodeString(&Unicode,&Err[Pathtest+1]);
Status = LdrLoadDll(0,0,&Unicode,&TargetModule);
if(!NT_SUCCESS(Status))
{
RtlInitUnicodeString(&Unicode,L"LdrLoadDll Status:";
__leave;
}
TargetRegion = (ULONG)TargetModule;
LdrUnloadDll((HANDLE)TargetModule);
}
RtlInitUnicodeString(&Unicode,szPathToModule);
InitializeObjectAttributes(&oa,&Unicode,OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE,0,0);
Status = NtCreateFile(&hFile,GENERIC_READ | GENERIC_EXECUTE,&oa,&StatusBlock,0,FILE_ATTRIBUTE_NORMAL,0,FILE_OPEN,0,0,0);
if(!NT_SUCCESS(Status))
{
RtlInitUnicodeString(&Unicode,L"NtCreateFile Status:";
__leave;
}
Status = NtQueryInformationFile(hFile,&StatusBlock,&FileInformation,sizeof(FILE_STANDARD_INFORMATION),FileStandardInformation);
if(!NT_SUCCESS(Status))
{
RtlInitUnicodeString(&Unicode,L"NtQueryInformationFile Status:";
__leave;
}
memcpy(&FileSize,&FileInformation.EndOfFile,sizeof(LARGE_INTEGER));
Status = NtCreateSection(&hSection,SECTION_ALL_ACCESS,0,&FileSize,PAGE_EXECUTE_READ,SEC_IMAGE,hFile);
if(!NT_SUCCESS(Status))
{
RtlInitUnicodeString(&Unicode,L"NtCreateSection Status:";
__leave;
}
if(TargetRegion == 0)
{
RtlInitUnicodeString(&Unicode,L"Could not find Module";
__leave;
}
else
{
Status = NtMapViewOfSection(hSection,TargetProcess,(PVOID*)&TargetRegion,0,0,0,&ViewSize,ViewUnmap,0,PAGE_EXECUTE_READWRITE);
if(!NT_SUCCESS(Status))
{
RtlInitUnicodeString(&Unicode,L"NtMapViewOfSection Status:";
__leave;
}
}
if(TargetProcess != INVALID_HANDLE_VALUE)
{
NtClose(TargetProcess);
}
NtClose(hFile);
return hSection;
}
__except(1)
{
if(TargetProcess != INVALID_HANDLE_VALUE)
NtClose(TargetProcess);
if(hSection != INVALID_HANDLE_VALUE)
NtClose(hSection);
if(hFile != INVALID_HANDLE_VALUE)
NtClose(hFile);
NtDisplayString(&Unicode);
_ultow(Status,(wchar_t*)&Err,16);
RtlInitUnicodeString(&Unicode,(wchar_t*)&Err);
NtDisplayString(&Unicode);
NtDelayExecutionEx(6);
}
return false;
}


both these work equally well... Pid field for remote mapping is some what tested. but still use that at own risk
Code:

if(!Native_MapModuleQueryAlignment(L"\\??\\C:\\WINDOWS\\system32\\CSRSRV.dll",0,TRUE,FALSE))
{
__leave;
}
if(!Native_MapModuleQueryAlignment(L"\\??\\C:\\WINDOWS\\system32\\CSRSRV.dll",0,TRUE,TRUE))
{
__leave;
}


See Main Thread "Thread Based code\behavior Profiling" for sources :}

regards BanMe