I compiled a very simple example of an application of type /SUBSYSTEM:NATIVE
writing "hello world".
It is launched thanks to the "BootExecute" key. The program works without errors.
Then I compiled a more complex example: NDK Cli. The source code was written in 2006 for Windows 32bit. I compiled it with VS2022 for Windows 64bit. The executable program is generated without error and with "level 4" for warnings.
But the RtlFreeAnsiString
API crashes the program that ends abruptly. Then the windows desktop is displayed normally.
With Procmon (during boot), the stack shows that the last call before the end of the program is RtlFreeAnsiString
.
Procmon also provides the source code line through the PDB file.
The program ends abruptly after the RtlFreeAnsiString
API.
0 FLTMGR.SYS FltGetFileNameInformation + 0x1e54 0xfffff8046c1b6d34 X:\windows\System32\drivers\FLTMGR.SYS
1 FLTMGR.SYS FltGetFileNameInformation + 0x1906 0xfffff8046c1b67e6 X:\windows\System32\drivers\FLTMGR.SYS
2 FLTMGR.SYS FltGetFileNameInformation + 0x992 0xfffff8046c1b5872 X:\windows\System32\drivers\FLTMGR.SYS
3 FLTMGR.SYS FltGetFileNameInformation + 0x71b 0xfffff8046c1b55fb X:\windows\System32\drivers\FLTMGR.SYS
4 ntoskrnl.exe IofCallDriver + 0x55 0xfffff80470a2eab5 X:\windows\system32\ntoskrnl.exe
5 ntoskrnl.exe IoBuildDeviceIoControlRequest + 0x67e 0xfffff80470ae3b9e X:\windows\system32\ntoskrnl.exe
6 ntoskrnl.exe KeInvalidateRangeAllCachesNoIpi + 0x7ab4 0xfffff80470a21444 X:\windows\system32\ntoskrnl.exe
7 ntoskrnl.exe PfFileInfoNotify + 0x2964 0xfffff80470a7dc14 X:\windows\system32\ntoskrnl.exe
8 ntoskrnl.exe MmProbeAndLockPages + 0x314b 0xfffff80470a5323b X:\windows\system32\ntoskrnl.exe
9 ntoskrnl.exe setjmpex + 0x4545 0xfffff80470c216f5 X:\windows\system32\ntoskrnl.exe
10 ntdll.dll LdrRscIsTypeExist + 0x2a8 0x7ffd4a616188 X:\Windows\System32\ntdll.dll
11 ntdll.dll RtlGetExtendedContextLength2 + 0x3dc 0x7ffd4a61682c X:\Windows\System32\ntdll.dll
12 ntdll.dll RtlWalkFrameChain + 0x2a 0x7ffd4a65f3fa X:\Windows\System32\ntdll.dll
13 ntdll.dll RtlCaptureStackBackTrace + 0x42 0x7ffd4a65f372 X:\Windows\System32\ntdll.dll
14 ntdll.dll _misaligned_access + 0x741 0x7ffd4a6f4eb1 X:\Windows\System32\ntdll.dll
15 ntdll.dll _misaligned_access + 0xac65 0x7ffd4a6ff3d5 X:\Windows\System32\ntdll.dll
16 ntdll.dll RtlGetCurrentServiceSessionId + 0xbcf 0x7ffd4a60817f X:\Windows\System32\ntdll.dll
17 ntdll.dll RtlFreeHeap + 0x51 0x7ffd4a607511 X:\Windows\System32\ntdll.dll
18 ntdll.dll RtlFreeAnsiString + 0x17 0x7ffd4a661fb7 X:\Windows\System32\ntdll.dll
19 native_64.exe GetFullPath + 0x19a, C:\MesData\informatique\2022\native_64\native_64_2\shell.c(63) 0x7ff7ee2245ba X:\Windows\System32\native_64.exe
20 native_64.exe RtlCliSetCurrentDirectory + 0x98, C:\MesData\informatique\2022\native_64\native_64_2\file.c(99) 0x7ff7ee221628 X:\Windows\System32\native_64.exe
21 native_64.exe RtlClipProcessMessage + 0x22c, C:\MesData\informatique\2022\native_64\native_64_2\main.c(161) 0x7ff7ee2225cc X:\Windows\System32\native_64.exe
22 native_64.exe NtProcessStartup + 0x91, C:\MesData\informatique\2022\native_64\native_64_2\main.c(489) 0x7ff7ee222d11 X:\Windows\System32\native_64.exe
23 ntdll.dll RtlUserThreadStart + 0x43 0x7ffd4a5e4873 X:\Windows\System32\ntdll.dll
In the few functions used during the error from the "main", I checked that there is no "cast". I modified this source code to create a "test command" that does this:
ANSI_STRING as;
RtlInitAnsiString(&as, "pb RtlFreeAnsiString");
RtlFreeAnsiString(&as);
This program does not work in a hyperV VM because the keyboard is not "recognized".
I can use WinDbg with a kernel debugger session with 2 PCs.
How to identify the origin of the error with Windbg?
Today, some additional information.
My last test : I commented on the lines containing RtlFreeAnsiString with "//". It is now the RtlFreeUnicodeString function that triggers the end of the program.
To be able to compile/link this program, I was forced to produce with "dumpbin.exe" the file ntdll.lib. Because the one provided by VS2022 is incomplete: it does not contain the NtDisplayString function, for example. In addition I use the "include" files of 2006 (from NDK CLI) because I do not find the right include files for various functions used. I also replaced the use of the GetProcessHeap function (not to be confused with GetProcessHeaps with a 's' at the end of the name) with the creation and use of a new "heap". //DirectoryInfo = RtlAllocateHeap(GetProcessHeap(), 0, 4096);
2 questions:
So could the parameters passed to the functions of ntdll.dll W11 not be the right ones?
Can the porting from 32bit to 64bit be incriminated?
I don't know where to look or how to look. Thank you for your ideas
I finally understood the origin of the anomalies related to the deallaction on the heap. I had never questioned the writing of the source code. The name of the author, the quality of the writing, the little compilation error when switching to 64bit, all this pushed me not to know where to look. But by dint of searching, and rereading the definition of the APIs, I ended up finding that the RtlInitAnsiString and RtlInitUnicodeString functions do not give rise to a buffer release by the RtlFreeAnsiString and RtlFreeUnicodeString functions. After this fix, the simple commands of the program work well. It remains to correct some minor anomalies, such as the use of a memory address in the kernel, hard-coded, and valid only in 32bit. Undocumented structures also generate errors. I don't think I could find a 64bit equivalent. Various sites describing these undocumented APIs haven't helped me yet.
That's it, everything works pretty well for me now.