NtOpenSection (L "\\ Device \\ PhysicalMemory") returns STATUS_OBJECT_NAME_NOT_FOUND

I am using SMBIOS read function for windows systems. Since API levels vary, there are several ways to support:

  • without any problems GetSystemFirmwareTable('RSMB')

    is available in Windows Server 2003 and later versions;
  • hardcore NtOpenSection(L"\\Device\\PhysicalMemory")

    for legacy systems up to and up to Windows XP;
  • critical WMI data en route L"Win32_ComputerSystemProduct"

    through cumbersome COM automation calls as a backup.

Methods 1 and 3 are already implemented, but I am stuck at \ Device \ PhysicalMemory as it NtOpenSection

always gives 0xC0000034 (STATUS_OBJECT_NAME_NOT_FOUND) - definitely not one of the possible result codes in the documentation ZwOpenSection

. Of course, I know that access to this section is denied starting with Windows Server 2003sp1 and possibly Windows XP-64, so I am trying to do this on a regular Windows XP-32 system and the result is no different from the result For example, Windows 7 -64. I also know that admin rights may be required even on legacy systems, but people who came across this issue have reported more appropriate error codes for such a scenario, such as 0xC0000022 (STATUS_ACCESS_DENIED) and 0xC0000005 (STATUS_ACCESS_VIOLATION).

My approach is based on Dell's Libsmbios library , which I believe works.

UNICODE_STRING wsMemoryDevice;
OBJECT_ATTRIBUTES oObjAttrs;
HANDLE hMemory;
NTSTATUS ordStatus;

RtlInitUnicodeString(&wsMemoryDevice, L"\\Device\\PhysicalMemory");
InitializeObjectAttributes(&oObjAttrs, &wsMemoryDevice,
    OBJ_CASE_INSENSITIVE, NULL, NULL);

ordStatus = NtOpenSection(&hMemory, SECTION_MAP_READ, &oObjAttrs);
if (!NT_SUCCESS(ordStatus)) goto Finish;

      

I thought it was possible to debug this, but the built-in API seems transparent to debuggers like OllyDbg: execution returns immediately when SYSENTER takes control. So I have no idea why Windows cannot find this object. I also tried changing the name of the section, as there are several options in the examples available on the internet, but it always gives 0xC0000033 (STATUS_OBJECT_NAME_INVALID).

+3


source to share


1 answer


Finally, I found the reason for this strange behavior, thanks to you people, confirming that my piece of code (it was an actual snippet, not a fake example) actually works. The problem was that I didn't have the Windows DDK initially installed (I now have it, but I still can't integrate it with Visual Studio so that the Windows SDK will automatically integrate), so it became necessary to write the definitions manually. Specifically, when I realized what InitializeObjectAttributes

is actually a preprocessor macro and not a Win32 function, I defined it RtlInitUnicodeString

as a macro, since its effect is even simpler. However, I was not careful enough to notice that UNICODE_STRING.Length

and .MaximumLength

is really designed for content size , and buffersize instead of length , i. that is, the number of bytes , not the number of characters . Consequently, my macro was setting the fields to half of the expected value, so Windows only saw the first half of the line L"\\Device\\PhysicalMemory"

, with the obvious result.



0


source







All Articles