Какой из 4-х (ntoskrnl.exe, ntkrnlmp.exe, ntkrnlpa.exe, ntkrpamp.exe) Как программно это узнать из юзермода? Пока что мысль только заюзать GetSystemInfo с дальнейшим в просмотром параметров: кол-во ядер и размер страницы. Или даже GetSystemInfo чтоб узнать кол-во процессоров + GlobalMemoryStatusEx чтобы узнать объем памяти.. Проще можно?
Clerk Я об этом знаю, но хотелось бы обойтись без нее, потому как тут трабла следующая: после вызова SystemModuleInformation у меня обламывается LoadLibraryEx("ntkrnlpa.exe", 0, 1) с ошибкой ERROR_INVALID_PARAMETER. Если вызывать их в обратном порядке - то все норм.
Aspire покажи код, так не должно быть. нужно избавлять не от симптомов, а от причин Могу тебя огорчить - параметром /KERNEL в boot.ini можно задать собственное ядро, указав например ntoskrnl.exe на многопроцессорной системе, либо вообще указать собственный файл, например chkdkrnl.exe - так делают при неполной устновке checked build файлов в систему (ядро, hal).
Проверить парамтры в boot.ini - не проблема Код (Text): start proc LOCAL pBUF:dword, szBUF:dword, hNtDll: dword, pKernelName: dword mov szBUF, 10000h mov hNtDll, f(GetModuleHandle, s("ntdll.dll")) mov pBUF, f(VirtualAlloc, 0, szBUF,MEM_COMMIT, PAGE_READWRITE) invoke GetProcAddress, hNtDll, s("NtQuerySystemInformation") xinvoke eax, SystemModuleInformation, pBUF, szBUF, NULL mov pKernelName, s("ntkrnlpa.exe") scan: @<xor ecx,ecx>, <xor eax,eax> mov ebx, pBUF mov ecx, dword ptr [ebx] ; число структур add ebx, 20h ;assume ebx: ptr SYSTEM_MODULE_INFORMATION .while ecx != 0 push ecx invoke strcmpr, ebx, pKernelName, 0Ch test eax,eax jne @f pop ecx .break @@: pop ecx dec ecx add ebx, sizeof SYSTEM_MODULE_INFORMATION .endw sub ebx, 14h mov eax, dword ptr [ebx] push eax inv VirtualFree, pBUF, szBUF, MEM_DECOMMIT invoke LoadLibraryEx, s("ntkrnlpa"), 0, 1 pop eax ret @@: invoke VirtualFree, pBUF, szBUF, MEM_DECOMMIT mov eax,-1 ret start endp Фигня в том, что если не сканировать стуктуры, то вызов лоадлибрари проходит, если сканируем - нет. При этом не важно совободили мы память или нет. Код сокращен до минимума, повырезал лишнее. Не пойму в чем шляпа. Подскажите, плиз.
Хз в чем смысл твоего кода который сканирует структуры ив се равно берет предопределенное имя ядра. Вот я переписал на Си - работает нормально. Выбирает имя ядра из структур Код (Text): #include <ntdll.h> #include <stdio.h> int main() { PVOID pBuffer; ULONG BufferLength = 0x10000; PSTR pKernelName = "ntkrnlpa.exe"; NTSTATUS Status; HANDLE hKernel; pBuffer = VirtualAlloc (0, BufferLength, MEM_COMMIT, PAGE_READWRITE); if (pBuffer) { Status = ZwQuerySystemInformation (SystemModuleInformation, pBuffer, BufferLength, NULL); if (NT_SUCCESS(Status)) { PSYSTEM_MODULE_INFORMATION modinfo = (PSYSTEM_MODULE_INFORMATION) pBuffer; char KernelName[1024]; GetSystemDirectory (KernelName, sizeof(KernelName)); KernelName[2] = 0; lstrcat (KernelName, (char*)modinfo->Modules[0].Name); pKernelName = KernelName; } VirtualFree (pBuffer, BufferLength, MEM_DECOMMIT); load: printf("KernelName = %s\n", pKernelName); hKernel = LoadLibraryEx (pKernelName, 0, 1); printf("hKernel = %08x (lasterr = %08x)\n", hKernel, GetLastError()); } return 0; } PS. в упор не понимаю зачем такой код на ассемблере писать есть же куда более удобный Си. PPS. Префикс sz означает не размер, а null-terminated строку.
Great Вообще верхняя процедура находит базу модуля по (заданному) его имени, посмотри по внимательнее. Этот факт замылен вызовом LoadLibraryEx, который я туда влепил для описания проблемы (на самом деле он находится в другой процедуре)
Но ведь сначала нужно найти имя - это раз. Во-вторых, ты утверждал, что LoadLIbraryEx не работает послe ZwQuerySystemInfformation - я тебе привел обратный пример, где находится имя ядра и загружается. все чудесно работает. А зачем тебе искать базу неизвестного ядра я так и не понял до сих пор
Great Вот скажи, у многих юзеров загружено ядро отличное от тех четырёх(ntoskrnl.exe, ntkrnlmp.exe, ntkrnlpa.exe, ntkrpamp.exe) ?
Передавать ZwQuerySystemInformation буфер фиксированного размера - большой фейл. Надо передать буфер, например размера 4 байта, функция вернет STATUS_INFO_LENGTH_MISMATCH, и заполнит переменную нужным размером.
Osen Имхо, но STATUS_INFO_LENGTH_MISMATCH просто возвращает true если памяти выделенной под буфер мало, а мы уже сами увеличиваем выделенный буфер. Код (Text): Status = ZwQuerySystemInformation(SystemProcessesAndThreadsInformation, pBuffer, cbBuffer, NULL); if (Status == STATUS_INFO_LENGTH_MISMATCH){ ExFreePool(pBuffer); cbBuffer *= 2; }
JCronuz Нет. Osen прав. Для некоторых инфоклассов не возвращается размер, для некоторых возвращается. Для SystemProcessesAndThreadsInformation возвращается требуемый размер. Код (Text): ZwQuerySystemInformation(SystemProcessesAndThreadsInformation, NULL, NULL, ReturnLength) вернёт в переменную ReturnLength необходимый размер буфера на момент вызова. Его следует немного увеличить, например на размер страницы.