I dont think this is the right place to ask about usermode code and undocumented at that but you should atleast be able to verify some of the undocumentedness with a debugger in hand
Your Prototype appears to be Wrong the function appears to be take 8 parameters instead of 7 as in your prototype
you should be aware win32u.dll is just a stub that does a syscall
the actual implementation is in win32kfull.sys
dumping the UNWIND_INFO for that particular function and looking for further argumets apart from 4 passed in registers
i can notice it takes 4 more parameters (total 8 in all)
here is how to do it
: kd> .fnent win32kfull!NtUserBuildHwndList
Debugger function entry 000001b6`b2179ae8 for:
(fffff65d`7aabc6c0) win32kfull!NtUserBuildHwndList | (fffff65d`7aabc9ec) win32kfull!xxxImeWindowPosChanged
Exact matches:
win32kfull!NtUserBuildHwndList (void)
BeginAddress = 00000000`0005c6c0
EndAddress = 00000000`0005c9e5
UnwindInfoAddress = 00000000`002e5060
Unwind info at fffff65d`7ad45060, 1c bytes
version 2, flags 1, prolog 16, codes 8
handler routine: win32kfull!_C_specific_handler (fffff65d`7abaacd2), data 1
00: offs 9, unwind op 6, op info 0 UWOP_EPILOG Length: 9. Flags: 0
01: offs 5, unwind op 6, op info 1 UWOP_EPILOG Offset from end: 105 (FFFFF65D7AABC8E0)
02: offs 16, unwind op 2, op info d UWOP_ALLOC_SMALL.
03: offs 12, unwind op 0, op info f UWOP_PUSH_NONVOL reg: r15.
04: offs 10, unwind op 0, op info d UWOP_PUSH_NONVOL reg: r13.
05: offs e, unwind op 0, op info c UWOP_PUSH_NONVOL reg: r12.
06: offs c, unwind op 0, op info 7 UWOP_PUSH_NONVOL reg: rdi.
07: offs b, unwind op 0, op info 6 UWOP_PUSH_NONVOL reg: rsi.
0: kd> $$ UWOP_ALLOC_SMALL opinfo is 0xd so size allocated is 0xd * 0x8 + 0x8
0: kd> ? 0xd * 0x8 + 0x8
Evaluate expression: 112 = 00000000`00000070
0: kd> $$ homeparamspace = 0x20 + ret addr = 0x8 + 5 nv regs are saved = 0x28
0: kd> so the fifth arg will be at 0xc0 and so on
Debug Options: <none>
0: kd> # mov*,*rsp+*c0 win32kfull+5c6c0 win32kfull + 5c9e5
win32kfull!NtUserBuildHwndList+0xb8:
fffff65d`7aabc778 8b8c24c0000000 mov ecx,dword ptr [rsp+0C0h]
win32kfull!xxxImeWindowPosChanged+0x28d:
fffff65d`7aabcc79 4c8bbc24c0000000 mov r15,qword ptr [rsp+0C0h]
win32kfull!FindWindowEx+0x1fe:
fffff65d`7aabd226 488b8c24c0000000 mov rcx,qword ptr [rsp+0C0h]
0: kd> # mov*,*rsp+*c8 win32kfull+5c6c0 win32kfull + 5c9e5
win32kfull!NtUserBuildHwndList+0x12e:
fffff65d`7aabc7ee 8b9424c8000000 mov edx,dword ptr [rsp+0C8h]
win32kfull!xxxImeWindowPosChanged+0x295:
fffff65d`7aabcc81 4c8bac24c8000000 mov r13,qword ptr [rsp+0C8h]
win32kfull!FindWindowEx+0x246:
fffff65d`7aabd26e 4c8b8424c8000000 mov r8,qword ptr [rsp+0C8h]
0: kd> # mov*,*rsp+*d0 win32kfull+5c6c0 win32kfull + 5c9e5
win32kfull!NtUserBuildHwndList+0x13f:
fffff65d`7aabc7ff 488b8c24d0000000 mov rcx,qword ptr [rsp+0D0h]
win32kfull!NtUserBuildHwndList+0x189:
fffff65d`7aabc849 488b8c24d0000000 mov rcx,qword ptr [rsp+0D0h]
win32kfull!FindWindowEx+0x2b7:
fffff65d`7aabd2df 448bb424d0000000 mov r14d,dword ptr [rsp+0D0h]
0: kd> # mov*,*rsp+*d8 win32kfull+5c6c0 win32kfull + 5c9e5
win32kfull!NtUserBuildHwndList+0x153:
fffff65d`7aabc813 4c8ba424d8000000 mov r12,qword ptr [rsp+0D8h]
0: kd> # mov*,*rsp+*e0 win32kfull+5c6c0 win32kfull + 5c9e5
0: kd> $$ function takes 8 params
0: kd> $$ where did you find the prototype
just prototyping with random type it seems to work properly with here
#include <stdio.h>
#include <windows.h>
typedef NTSTATUS ( NTAPI * NtUserBuildHwndList)(
UINT64 a, UINT64 b, UINT64 c, UINT64 d, UINT64 e, UINT64 f, UINT64 *g, UINT64 *h );
int main( void )
{
NtUserBuildHwndList nubhwlist;
HMODULE hMod = LoadLibraryA("win32u.dll");
printf("%I64x\n", hMod);
if (hMod) {
nubhwlist = (NtUserBuildHwndList) GetProcAddress(hMod, "NtUserBuildHwndList");
if (nubhwlist) {
printf("%I64x\n", nubhwlist);
UINT64 count = 0xbeadb0b5beadb0b5;
UINT64 List[4096] = { 0xbeadb0b5 };
NTSTATUS stat = nubhwlist(0, 0, 0, 0, 0, 512 , List, &count);
printf("%x\t%I64x\n", stat, count);
}
}
}
resulting in 0x164 handles
:\>ntubhwlist.exe
7ff8710a0000
7ff8710a1410
0 beadb0b500000164