Все привет. Подскажите, как с помощью прямого вызова sysenter для XP и 2Eh для 2000 получить список процессов? Код (Text): DWORD WINAPI SyscallQueryInfo(...) { asm{ pop ebp mov eax,0x00AD mov ebx,esp sysenter ret 0x10 } } Это по аналогии попытался сделать, как у MS-Rem'a в статье написано, но не работает. Что не так? Подскажите плз... В Builder'e делаю. Заранее благодарен.
это только вызов системного сервиса. нужно ещё обработать информацию в буфере, заполненном после вызова сервиса.
Сделать сначала получение списка процессов через NtQuerySystemInformation, а потом NtQuerySystemInformation заменить на её syscall-аналог, примерно как ты написал
Спасибо за ответы... Вот приведу полностью, как делаю: Код (Text): DWORD WINAPI XpSystemcallZwQuerySystemInformation(UINT uiInfoType, PVOID pvBuffer, ULONG ulBufferSize, PULONG pulReturn) { asm{ pop ebp mov eax,0x00AD mov ebx,esp sysenter ret 0x10 } } DWORD GetSystemCallProcessesList() { ... ... do { pvBuffer = (PVOID)VirtualAlloc(NULL, ulBufferSize, MEM_COMMIT, PAGE_READWRITE); if( pvBuffer == NULL ) goto END; ntStatus = XpSystemcallZwQuerySystemInformation(SystemProcessesAndThreadsInformation, pvBuffer, ulBufferSize, NULL); if( ntStatus == STATUS_INFO_LENGTH_MISMATCH ) { VirtualFree(pvBuffer, 0, MEM_RELEASE); ulBufferSize *= 2; } else if( !NT_SUCCESS(ntStatus) ) { goto END; } } while( ntStatus == STATUS_INFO_LENGTH_MISMATCH ); ... ... } В XpSystemcallZwQuerySystemInformation при sysenter вылетает ошибка. Помогите плз разобраться.
Ни знаю на кой черт тебе какой то sysenter если всё делается оч просто: Код (Text): DWORD piBuf = 65536; //а лучше 0x20000 или 0x40000 LPVOID lpBuf = NULL; PSYSTEM_PROCESS_INFORMATION pInfo = NULL; DWORD ProcessCount=0; LPWSTR lpName = NULL; lpBuf = malloc(piBuf); NtQuerySystemInformation(5, lpBuf, piBuf, NULL); pInfo = (PSYSTEM_PROCESS_INFORMATION)lpBuf; for (;;) { ProcessCount++; lpName = pInfo->ProcessName.Buffer; if (lpName==NULL) lpName = L"Idle"; wprintf(L"> %ls\n", lpName); wprintf(L"\n"); wprintf(L"ID\t %d\n", pInfo->ProcessId); wprintf(L"Threads\t %d\n", pInfo->ThreadCount); wprintf(L"Handles\t %d\n", pInfo->HandleCount); wprintf(L"______________________________\n\n"); if (pInfo->NextEntryDelta == 0) break; pInfo = (PSYSTEM_PROCESS_INFORMATION)(((DWORD)pInfo) + pInfo->NextEntryDelta); } free(lpBuf); вся любовь :0)
Может так: Код (Text): DWORD WINAPI XpSystemcallZwQuerySystemInformation(UINT uiInfoType, PVOID pvBuffer, ULONG ulBufferSize, PULONG pulReturn) { asm{ pop ebp mov eax,0x00AD mov [b]edx[/b],esp sysenter ret 0x10 } } и поиск по форуму http://wasm.ru/forum/viewtopic.php?id=10962&p=1
Код (Text): mov ebx,esp sysenter ret 0x10 это по-любому круто. с учетом, что sysenter управления не возвращает
Great +1 prus Модель вызова: [esp+4*(N+1)]: Параметр N ... [esp+0C]: Параметр 2 [esp+8]: Параметр 1 [esp+4]: XXX [esp]: Адрес возврат из sysenter Регистр Edx указавает на адрес возврата в стеке, в регистре Eax номер сервиса. После возврата управление передаётся на адрес возврата, а регистр Esp увеличивается на 4.
Приветствую! Я не силен в asm, но по вашим ответам сворганил такое: Код (Text): DWORD WINAPI XpSystemcallZwQuerySystemInformation(UINT uiInfoType, PVOID pvBuffer, ULONG ulBufferSize, PULONG pulReturn) { asm{ pop ebp mov eax,0x00AD mov edx,esp sysenter ret 0x10 } } DWORD GetSystemCallProcessesList() { ... ... do { pvBuffer = (PVOID)VirtualAlloc(NULL, ulBufferSize, MEM_COMMIT, PAGE_READWRITE); if( pvBuffer == NULL ) goto END; ntStatus = XpSystemcallZwQuerySystemInformation(SystemProcessesAndThreadsInformation, pvBuffer, ulBufferSize, NULL); if( ntStatus == STATUS_INFO_LENGTH_MISMATCH ) { VirtualFree(pvBuffer, 0, MEM_RELEASE); ulBufferSize *= 2; } else if( !NT_SUCCESS(ntStatus) ) { goto END; } } while( ntStatus == STATUS_INFO_LENGTH_MISMATCH ); ... ... } Но почему-то XpSystemcallZwQuerySystemInformation возвращяет ошибочный статус. Не поможите плз еще немного ?
Оно должно выглядеть так: Код (Text): Function XpZwQuerySystemInfoCall(ASystemInformationClass: dword; ASystemInformation: Pointer; ASystemInformationLength: dword; AReturnLength: pdword): dword; stdcall; asm pop ebp mov eax, $AD call @SystemCall ret $10 @SystemCall: mov edx, esp sysenter end; А у тебя на стеке совсем не то, что ожидает увидеть sysenter.
prus, сказали же уже: sysenter - не возвращает управления Какой именно? Код NtQuerySystemInformation в нтдлл состоит из пары инструкций, неужели нельзя их посмотреть? ) Код (Text): 7C90E1AA >/$ B8 AD000000 mov eax,0AD 7C90E1AF |. BA 0003FE7F mov edx,7FFE0300 7C90E1B4 |. FF12 call dword ptr ds:[edx] -- mov edx, esp/sysenter 7C90E1B6 \. C2 1000 retn 10
Twister Спасиб, я по этому примеру и пытался сделать: Код (Text): asm { pop ebp mov eax, 0x00AD call SystemCall ret 0x10 SystemCall: mov edx, esp sysenter } но у меня Builder'овский компилятор ругается на строчку "call SystemCall" (Undefined symbol "SystemCall").
Clerk Это один из способов получить список процессов. То, про что говорите Вы, уже реализовано, спасиб!
Clerk Я тут под дебагером поглядел, что там в стеке происходит и все очень похоже на то, что Вы описали. Делаю так: Код (Text): asm { //INT 3 POP EBP MOV EAX, 0x00AD MOV EDX, ESP SYSENTER } В итоге выполнения вызова EAX = 0xC0000003 (STATUS_INVALID_INFO_CLASS). Т.е., насколько понимаю, не совсем прально параметры в стеке лежат. Что не так опять?
prus Можно так, Код (Text): SystemCall: mov edx,esp sysenter CallService: mov eax,0ADh call SystemCall ret 10h ;add esp,4 Или так. Код (Text): mov eax,0ADh push edx ;Esp-4 Call Delta Delta: sub dword ptr [esp],(offset Delta - offset Return) ;ptr Return mov edx,esp sysenter Return: add esp,4*4+4
prus PUCHAR pQuerySysInfo = (PUCHAR) GetProcAddress (GetModuleHandle("ntdll.dll"), "ZwQuerySystemInformation")); тогда *(PULONG)&pQuerySysInfo[1] - номер сервиса