Using mapped section in KMDF

Hello everybody.

I’m actually trying to setup a mapped section from kernel mode that any apps can use. (I know it’s not really secure and all but i’m doing it to test the limits of Windows Internals).

So i run into a problem. My section is created correctly and i’m setting a value to the view of this section successfully. But, when i try to map a view of this section in usermode. It will recover some garbage value. As if it was dereferencing a pointer.

Here are some snippets :

Kernel mode →

`
namespace shared
{
class KeSharedManager
{
private:
HANDLE handle_ke_shared_section_;
SECURITY_DESCRIPTOR sec_desc_ke_shared_section_;
UNICODE_STRING ustring_section_name_;
LARGE_INTEGER large_int_section_view_size_;
void* p_section_view_;

    void SetupSecurityDescriptor();
    void SetupKernelSharedSection();
    void RefreshSectionView();

public:
    KeSharedManager(const wchar_t* section_name)
    {
        /* Create a security descriptor that allow us to access the section from usermode */
        SetupSecurityDescriptor();

        /* Initialize the attributes that are going to be useful in SetupKernelSharedSection() */
        RtlInitUnicodeString(&this->ustring_section_name_, section_name);
        this->large_int_section_view_size_.HighPart = 0;
        this->large_int_section_view_size_.LowPart  = 1024 * 10;

        /* Create the kernel shared section with the rights to access it from usermode */
        /* By rights i mean that we attach a security descriptor to the shared section */
        SetupKernelSharedSection();

        /* If a section is already mapped, unmap it. Then use ZwMapViewOfSection       */
        RefreshSectionView();

        /* Write a debug value to the view of the mapped section */
        this->p_section_view_ = (void*)7777;
    
        DbgPrintEx(0, 0, "Section view value -> %d\n", (int)this->p_section_view_);
    }
};

}
`

So this will successfully print that the section have been created and that the value is successfully assigned. I have to mention that i don’t have any destructor in this class.

The call :

`
NTSTATUS DriverEntry(PDRIVER_OBJECT p_driver_object,
PUNICODE_STRING p_registry_path)
{
UNREFERENCED_PARAMETER(p_registry_path);

p_driver_object->DriverUnload = DriverUnload;

shared::KeSharedManager ke_shared_manager = shared::KeSharedManager(L"\\BaseNamedObjects\\Cerberus");

return STATUS_SUCCESS;

}
`

How i recover and print my value from usermode :

`int main()
{
HANDLE handle_ke_section_read_ = OpenFileMappingA(FILE_MAP_READ,
false,
“Global\Cerberus”);

HANDLE handle_ke_section_write_ = OpenFileMappingA(FILE_MAP_WRITE,
    false,
    "Global\\Cerberus");

void* test = MapViewOfFile(handle_ke_section_read_, SECTION_MAP_READ, 0, 0, sizeof(int));
std::cout << "buffer -> " << (int)test << std::endl;

std::cin.get();

}
`

One of my guess is that the problem comes from the fact that i print a mapped view in my usermode that maybe not valid or expired.

Im really lost here.
Thanks in advance for any help.
Ayuro.

Yes, you are absolutely printing a pointer. The next to the last line of code in your app should be

std::cout << "buffer => " << *(int*)test << std::endl;

Thanks for your answer. The problem is that i tried the exact same thing as you said a few times. It’s always printing a 0. It should normally print a “7777” I thought about either the security descriptor, or that the view is getting refreshed by an “auto destructor” of my kernel class.

You have exactly the same problem in your driver. You are changing the pointer, not the data. The fact that you had to cast to (void*) should have been a clue. Not sure why you keep saying “this->”; I find that distracting.

*(int*)p_section_view_ = 7777;

Ooh alright, i’m going to try this. Thanks for the advice. Also, for the this pointer it’s because i’m studying IT and our teachers want us to use this everytime we can.

It’s giving me a page fault, something weird is that the arg2 of the page fault is neither 0 or 1. It’s 2. Which correspond to nothing afaik. https://imgur.com/a/Xo2Sxn3

p_section_view_ points to invalid memory.

You didn’t show us the code that creates p_section_view_, so we can’t say very much about it.

I believe your teacher is giving you bad advice. If you look at C++ in the wild, no one writes code that way. It’s not a bad idea to have some coding convention that identifies member variables (i still use the Hungarian prefix m_).

And while I’m critiquing your style, it’s a bad practice to start your own classes and variables in a kernel driver with Ke or Mm or Zw or Ex. Those prefixes indicate kernel APIs, and you’re just going to cause yourself confusion later.

One might also ask why a C++ beginner is attempting to write kernel code, but that’s a topic for another day.

I’m not really a beginner in cpp in itself (Even tho im not sure if i’m as experienced as you all). but i am in kernel programming. This is how im creating my section view. And also, yeah i read something like Mm stand for memory management and all. I might change this in the future.

`void shared::KeSharedManager::RefreshSectionView()
{
if(this->p_section_view_)
ZwUnmapViewOfSection(NtCurrentProcess(), this->p_section_view_);

size_t view_size = 1024*10;

ZwMapViewOfSection(this->handle_ke_shared_section_, NtCurrentProcess(),
	&this->p_section_view_, 0, view_size, 0, &view_size, 
	ViewShare, 0, PAGE_READWRITE);

}`

standard cavate: the debate between C and C++ has been ongoing for a long time and all sides have meritorious arguments. But if you can’t program in either, fix that in UM before you try KM it seems

There is no “C” i did in the project.

Except C-style casting.