When League of Legends game released update 13.23 it stopped working in Wine.
Initially we didn't know why it stopped working and due to anti-cheat it was quite difficult to figure out what exactly is happening and so we were just trying to implement random things.
One of the differences when comparing previous version with this version was the addition of something like this to their anti-cheat: ```c size_t size = 0x100000; int finalClass = 0xef; char *buffer = malloc(size * finalClass); ULONG length; for (int informationClass=0x00, informationClass < finalClass; informationClass++) { NtQuerySystemInformation(informationClass, buffer + size * informationClass, size, &length); } // later use stuff from there, of course everything's highly obfuscated ```
Essentially this hides what exactly they need since it could be any of classes.
So we started to implement most likely classes that might be used to work like they do in Windows.
This MR contains improvement of `SystemModuleInformationEx` so result will match pretty much exactly how it would on Windows.
I only didn't include more modules but if anyone ever needs that it's very simple to add those.
Also one of the things I noticed is that on Windows even if you give smaller buffer size it will still fill it with data unlike current Wine implementation and this is true for most of classes.
Anyway in the end it turned out not to be issue/needed but I think it still could be useful.
From: Dāvis Mosāns davispuh@gmail.com
This makes it match more closely how it works on Windows. --- dlls/ntdll/unix/system.c | 58 +++++++++++++++++++++++++++++----------- 1 file changed, 42 insertions(+), 16 deletions(-)
diff --git a/dlls/ntdll/unix/system.c b/dlls/ntdll/unix/system.c index 879a5893758..75b0de575e3 100644 --- a/dlls/ntdll/unix/system.c +++ b/dlls/ntdll/unix/system.c @@ -3162,35 +3162,61 @@ NTSTATUS WINAPI NtQuerySystemInformation( SYSTEM_INFORMATION_CLASS class, case SystemModuleInformationEx: /* 77 */ { /* FIXME: return some fake info for now */ - static const char *fake_modules[] = - { - "\SystemRoot\system32\ntoskrnl.exe", - "\SystemRoot\system32\hal.dll", - "\SystemRoot\system32\drivers\mountmgr.sys" + static struct { + const char *Name; + ULONG ImageSize; + ULONG Flags; + WORD LoadCount; + ULONG ImageCheckSum; + } fake_modules[] = + { + /* Name ImageSize Flags LoadCount ImageCheckSum */ + { "\SystemRoot\system32\ntoskrnl.exe", 0x0001046000, 0x0000008804080, 0x0001, 0x00a5fdd6 }, + { "\SystemRoot\system32\hal.dll", 0x0000006000, 0x0000008004080, 0x0001, 0x0000d94f }, + { "\SystemRoot\system32\kd.dll", 0x000000b000, 0x0000008804080, 0x0002, 0x00004ef6 }, + { "\SystemRoot\System32\drivers\CLFS.SYS", 0x000006d000, 0x0000008004080, 0x0004, 0x0007115b }, + { "\SystemRoot\System32\drivers\mountmgr.sys", 0x000001e000, 0x0000008804080, 0x0001, 0x00024bd0 }, };
ULONG i; RTL_PROCESS_MODULE_INFORMATION_EX *module_info = info;
len = sizeof(*module_info) * ARRAY_SIZE(fake_modules) + sizeof(module_info->NextOffset); - if (len <= size) + if (size == 0) ret = STATUS_INFO_LENGTH_MISMATCH; + else if (!info) ret = STATUS_ACCESS_VIOLATION; + else if (size >= sizeof(module_info->NextOffset)) { - memset( info, 0, len ); + size_t address = 0xfffff805115a0000; for (i = 0; i < ARRAY_SIZE(fake_modules); i++) { + if (size < (i + 1) * sizeof(*module_info) + sizeof(module_info->NextOffset)) break; + + module_info[i].NextOffset = sizeof(*module_info); RTL_PROCESS_MODULE_INFORMATION *sm = &module_info[i].BaseInfo; - sm->ImageBaseAddress = (char *)0x10000000 + 0x200000 * i; - sm->ImageSize = 0x200000; + /* sm->Section - Windows leaves this uninitialized */ + sm->MappedBaseAddress = 0x0000000000000000; + sm->ImageBaseAddress = address; + sm->ImageSize = fake_modules[i].ImageSize; + sm->Flags = fake_modules[i].Flags; sm->LoadOrderIndex = i; - sm->LoadCount = 1; - strcpy( (char *)sm->Name, fake_modules[i] ); - sm->NameOffset = strrchr( fake_modules[i], '\' ) - fake_modules[i] + 1; - module_info[i].NextOffset = sizeof(*module_info); + sm->InitOrderIndex = 0; + sm->LoadCount = fake_modules[i].LoadCount; + strcpy( (char *)sm->Name, fake_modules[i].Name ); + sm->NameOffset = strrchr( fake_modules[i].Name, '\' ) - fake_modules[i].Name + 1; + + module_info[i].ImageCheckSum = fake_modules[i].ImageCheckSum; + module_info[i].TimeDateStamp = 0; + module_info[i].DefaultBase = 0; + + if (i == 0) sm->ImageBaseAddress = 0xfffff80515c00000; + else address = (address + fake_modules[i].ImageSize + 0x10000) & ~0xFFFF; + if (address >= 0xfffff80513000000) address = 0xfffff80518400000; + } - module_info[ARRAY_SIZE(fake_modules)].NextOffset = 0; - } - else ret = STATUS_INFO_LENGTH_MISMATCH; + module_info[i].NextOffset = 0; + if (i < ARRAY_SIZE(fake_modules)) ret = STATUS_INFO_LENGTH_MISMATCH;
+ } else ret = STATUS_INFO_LENGTH_MISMATCH; break; }
This breaks the build