Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2005.11.20;
Скачать: [xml.tar.bz2];

Вниз

Закрытие процесса   Найти похожие ветки 

 
Alex870   (2005-06-21 13:46) [0]

Подскажите пожалуйста, можно ли перехватить закрытие процесса моего приложения, выполнить какие-либо действия, а потом завершить процесс. Приложение у меня без формы:
program MyProg;
uses
Windows, messages;

var
M : tagMSG;

begin
while GetMessage( M, HInstance, 0, 0) do
   begin
    TranslateMessage(M);
    DispatchMessage(M);
   end;
end.

Если нет, подскажите, может создание формы поможет? Спасибо


 
kaZaNoVa ©   (2005-06-21 13:51) [1]

если закрывают методом TerminateProcess   или внедрением + Halt() то никак:(


 
kaZaNoVa ©   (2005-06-21 13:52) [2]

хотя ..  я не понял, он у тя с окном?


 
Игорь Шевченко ©   (2005-06-21 14:01) [3]


> можно ли перехватить закрытие процесса моего приложения,
> выполнить какие-либо действия, а потом завершить процесс


Если приложение с окном, то Task Manager при снятии приложения посылает окну WM_CLOSE, иначе никак.


 
Alex870   (2005-06-21 14:14) [4]

Окно создать не проблема, если это нужно для решения данной задачи, только оно должно быть невидимым. Я написал так
program ati2evxx;

uses
Windows, messages;

var
M : tagMSG;
wc : WndClass;
wndMain : HWND;

function WindowProc(wnd:HWND;Msg:UINT;wParam:WPARAM;lParam:LPARAM):LRESULT; stdcall;
begin
case msg of
WM_CLOSE : beep(100,100);
WM_DESTROY :
 begin
   postquitmessage(0);
   Result:=0;
   exit;
 end; else Result:=DefWindowProc(wnd,msg,wParam,lParam);
end;
end;

begin
wc.style:=CS_HREDRAW or CS_VREDRAW;
wc.lpfnWndProc:=@WindowProc;
wc.cbClsExtra:=0;
wc.cbWndExtra:=0;
wc.hInstance:=HInstance;
wc.hIcon:=LoadIcon(0,IDI_APPLICATION);
wc.hCursor:=LoadCursor(0,IDC_ARROW);
wc.hbrBackground:=COLOR_BTNFACE+1;
wc.lpszMenuName:=nil;
wc.lpszClassName:="Main";
RegisterClass(wc);
wndMain:=CreateWindow("Main","",ws_overlappedwindow,10,10,100,100,0,0,hInstance,nil);
while GetMessage( M, 0, 0, 0) do
   begin
    TranslateMessage(M);
    DispatchMessage(M);
   end;
end.

Но результатов (положительных) не получил.


 
kaZaNoVa ©   (2005-06-21 14:58) [5]

Удалено модератором
Примечание: Offtopic


 
MS-REM   (2005-06-21 15:16) [6]

Есть решение.

Если ID процесса перевести в нуль или ниже нуля.


 
Игорь Шевченко ©   (2005-06-21 15:18) [7]

MS-REM   (21.06.05 15:16) [6]


> Если ID процесса перевести в нуль или ниже нуля.


С этого места подробнее, про секретный прибор, о котором не знали физики.


 
Alex870   (2005-06-21 15:24) [8]


> MS-REM


> Если ID процесса перевести в нуль или ниже нуля.

Не могли бы пояснить, что значит ID процесса перевести в нуль, и что это даст.

> kaZaNoVa ©   (21.06.05 14:58) [5]

Мысль хорошая, но как запасной вариант, если не найду, как реализовать в одном приложении, однако большое спасибо!


 
MS-REM   (2005-06-21 15:32) [9]

Игорь Шевченко ©   (21.06.05 15:18) [7]
С этого места подробнее, про секретный прибор,
о котором не знали физики.

http://wasm.ru/article.php?article=apihook_3

Причем здесь физики.


 
kaZaNoVa ©   (2005-06-21 15:33) [10]

MS-REM   (21.06.05 15:16) [6]
ID процесса не может быть равно 0 .. возможно Вы намекаете на "подмену" ID ? имхо это неприемлимо в норимальных задачах :)


 
Игорь Шевченко ©   (2005-06-21 15:41) [11]

MS-REM   (21.06.05 15:32) [9]

Эта...долго читал, нифига не понял, где там слово "подмена ID процесса на 0 или меньше нуля"...А главное, зачем эта подмена нужна.

"Народ требует разъяснений"


 
MS-REM   (2005-06-21 15:56) [12]

Прилагаются примеры на DELPHI (Снизу статьй)
там есть пример.


 
Игорь Шевченко ©   (2005-06-21 16:03) [13]

MS-REM   (21.06.05 15:56) [12]

А...я понял. Дети Ивана Кулибина вышли на волю.

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

А от таких скрывальщиков процессов существует раскрывальщик и не один.


 
MS-REM   (2005-06-21 16:20) [14]

> Игорь Шевченко

Прочти внимательнно.


 
Игорь Шевченко ©   (2005-06-21 16:35) [15]

MS-REM   (21.06.05 16:20) [14]

Я, собственно говоря, читал. Если ты мне скажешь, на что именно надо обратить внимание, а еще лучше, приведешь конкретную цитату, тогда есть смысл продолжать дискуссию. Драйвера писать - дело нехитрое, только следует учесть, что права на загрузку драйвера есть не у всех, и плясать уже от этого факта.


 
Alex870   (2005-06-21 16:55) [16]


> А...я понял. Дети Ивана Кулибина вышли на волю.

10 баллов! (не за красоту, а за смысл). Однако мне лично статья показалась познавательной, так как мои знания еще далеки до MS-REM"a и до Ваших, однако применять такие вещи мне кажется  опасным, что подтверждает и автор статьи, хотя и не всегда явно. Одно я понял наверняка - кроме перехвата TerminateProcess выхода другого нет, ну или то, что предложил kaZaNoVa © в [5]. Всем огромное спасибо! Если у кого есть еще решения - буду очень признателен.


 
Игорь Шевченко ©   (2005-06-21 17:34) [17]

Alex870   (21.06.05 16:55) [16]

Вот если не секрет, какой смысл при завершении процесса выполнять некоторые действия ? Может, какой другой способ есть решить задачу ?

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


 
MS-MEN ©   (2005-06-21 19:52) [18]

Ну, во-первых, все, что относится к системе, если считать
низкокого уровня программирование то везде надо иметь
Админовские привилигие иначе не как.

Во - вторых там есть модуль, который также может работать
с нулевым кольцом (Без драйвера) и кстати тоже надо иметь
привилигие Админа, но этот вопрос уже решен.

Вот маленький переделанный код.

program Protection;

{$APPTYPE CONSOLE}

uses
 Windows,
 Ring0;

Var
MyPid:THandle; //  Текущий процесс.

begin
 InitialzeRing0Library(CALL_GATE); //  Переходим в  нулевое кольцо (Без драйвера)
 MyPid := GetCurrentProcessId(); // Берем текущий PID
 ChangeProcessName(MyPid, "System");  // Переименуем как системный
 ChangeProcessId(MyPid,0); // Также и PID укажем системный
 FreeRing0Library(); // Выгружаемся из нулевого кольца
end.

А  теперь попробуй удалить его из системы

Не помишает также скрыть сам файл или даже папку
это тоже возможно с помощью перехвата.

Пойщю может скину код для скрытия файлов/папок.


 
MS-MEN ©   (2005-06-21 19:55) [19]

Я запутался измените эту строку
ChangeProcessId(MyPid,0); // Также и PID укажем системный
на эту
ChangeProcessId(MyPid,4); // Также и PID укажем системный


 
kaZaNoVa ©   (2005-06-21 20:00) [20]

MS-MEN ©   (21.06.05 19:55) [19]
фантастика ... :)))
сейчас попробую:)


 
MS-MEN ©   (2005-06-21 20:02) [21]

Вообще надо иметь привилигие системы но к сожалению это возможно
только с помощью Драйвера, хотя и из нулевого кольца тоже возможно

Что я показал, не обращайте сильного внимание, так как это
и - за не правильного обращение к системному процессу может
вызвать BSOD (Синие окно).


 
kaZaNoVa ©   (2005-06-21 20:06) [22]

MS-MEN ©   (21.06.05 20:02) [21]
у меня вылетает на CallRing0, права админа...


 
MS-MEN ©   (2005-06-21 20:09) [23]

Например

Если в конце поставить Readln то процесс будет в бездействий  это будет, отложатся не только в диспетчере задач, а также во всей системе а если вы установите, например Repeat Until … то система пойдет в BSOD также отразится во всей системе, так как REPEAT и UNTIL используют ф-ций API, так как в драйвере запрещается использовать ф-ций WinAPI только NativeAPI (Их также можно использовать и в в третем кольце.


 
MS-MEN ©   (2005-06-21 20:14) [24]

>kaZaNoVa
 >у меня вылетает на CallRing0, права админа...

Это говорит о том что у тебя SP2 или 2003 попробуй получить  привилигию DEBUG
если не поможет тебе надо использовать системною привилигию DEBUG.


 
kaZaNoVa ©   (2005-06-21 20:15) [25]

MS-MEN ©   (21.06.05 20:09) [23]
проблема в данных типа:

case Version.dwBuildNumber of
2195 : begin // Windows 2000
        UndocData.ActivePsListOffset := $0A0;
        UndocData.PidOffset          := $09C;
        UndocData.NameOffset         := $1FC;
        UndocData.ppIdOffset         := $1C8;
        UndocData.ImgNameOffset      := $000;
       end;


для Windows 2003 Server - не подскажите что туда вписать?


 
kaZaNoVa ©   (2005-06-21 20:25) [26]

в Windows 2000 SP4, запущенной на VMware программа [18] тоже вылетает:( (Runtime Error 216)


 
kaZaNoVa ©   (2005-06-21 20:26) [27]

но иногда вылетает BSOD   :(


 
kaZaNoVa ©   (2005-06-22 01:22) [28]

MS-MEN ©   (21.06.05 20:14) [24]
DEBUG не помогла:(


 
MS-MEN ©   (2005-06-22 09:10) [29]

С драйвером?
Вместо CALL_GATE поставь DRIVER_GATE


 
Alex870   (2005-06-22 09:41) [30]


> Игорь Шевченко
>
> Вот если не секрет, какой смысл при завершении процесса
> выполнять некоторые действия ? Может, какой другой способ
> есть решить задачу ?


Конечно не секрет, извиняюсь, что сразу не описал. Моя программа должна следить за трафиком на определенной машине (НЕ сервере). Есть конечно много готовых (DUMeter, TMeter...), но они меня не устраивают, ведь после перезагрузки или смены пользователя они начинают считать трафик заново, а моя прога именно этот случай и должна отлавливать, и сохранять в файл время и значения in,out трафика на это время, а так же аккаунт (user name) пользователя.


 
Digitman ©   (2005-06-22 09:48) [31]


> Alex870   (22.06.05 09:41) [30]


а не проще ли написать свою собственную программу (сервис) для мониторинга траффика и ведения статистики ? не такое уж и сложное это дело


 
Alex870   (2005-06-22 10:00) [32]


> а не проще ли написать свою собственную программу (сервис)
> для мониторинга траффика и ведения статистики ? не такое
> уж и сложное это дело

Именно об этом я и говорю, может выразился не корректно. Я написал свою программу для подсчета трафика, но мне нужно чтобы она записывала событие в файл, когда её пытаются остановить, кто это делает и в какое время, а так же лог по перезагрузкам и сменам аккаунта, т.е. когда программу останавливает система.


 
Digitman ©   (2005-06-22 10:12) [33]


> написал свою программу


сист.сервис надо было писать
и стартовать его с правами системы, а не конкр.юзера
тогда простой смертный юзер не сможет его остановить


 
Игорь Шевченко ©   (2005-06-22 10:18) [34]

MS-MEN ©   (21.06.05 19:52) [18]

Может эта...прежде чем глючные поделки выкладывать, русский язык подучить ? Слегка так...А то читать не очень удобно.


> Ну, во-первых, все, что относится к системе, если считать
> низкокого уровня программирование то везде надо иметь
> Админовские привилигие иначе не как.


А вот Руссинович с Когсуэллом без них обходятся как-то :)
С чего бы ?


 
alpet ©   (2005-06-22 10:30) [35]

Вообще перевод процесса в отряд системных с помощью кода ориентированного на 0-кольцо, мало чего даст - его все равно можно будет уничтожить (в самом крайнем случае через Reset). Имхо для отслеживания вызовов TerminateProcess и других способов срочной терминации процесса, лучше использовать дополнительный сторожевой процесс, который ничем другим и не будет заниматься только ждать завершение первого:

WaitForSingleObject (hFirstProcess, INFINITE);
OnFirstProcessKilled;

В свою очередь из первого надо будет проверять целостность сторожевого процесса.


 
MS-MEN ©   (2005-06-22 10:30) [36]

> А вот Руссинович с Когсуэллом без них обходятся как-то :)
> С чего бы ?

Например, что именно?
Хотя можно если внедрить в системный процесс свой процесс
Но опять также надо иметь привилиги Debug.

Есть много способов, но во всех способах есть минусы.


 
Alex870   (2005-06-22 10:35) [37]


> тогда простой смертный юзер не сможет его остановить

А как же перезагрузка? Мне нужно чтобы данные о подсчете трафика сохранялись всегда, а при перезагрузке они обнуляются. Пример - Kerio Winroute он пишет в лог время остановки своей службы и кем она была остановлена.


 
MS-MEN ©   (2005-06-22 10:42) [38]

Alex870
Лучший способ это перехватить ф-ций иначе ты даже не сможешь
узнать, что за узер хотел завершить твой процесс.

Перехватывай ф-ций ядра, таким образом, не кто (ламер) не сможет
снять процесс, а также если есть опыт по защите то и профилю
будет лень :)

Это лучший совет (Другого не найдешь)


 
Игорь Шевченко ©   (2005-06-22 10:50) [39]

MS-MEN ©   (22.06.05 10:30) [36]


> Например, что именно?


Например, Process Explorer, показывающий много всего увлекательного без драйверов.

Еще раз - для решения большинства нужных задач ни драйверы, не перехват описанный тобой, нафиг не сдались. Все эти горе-драйверописатели неснимаемых/невидимых процессов занимаются либо полной ерундой для гнутия пальцев, либо откровенным вредительством.
Ни то, ни другое на этом форуме не приветствуется, равно как и рекомендации вырезать гланды через неподходящее для этого процесса отверстие.


 
KosilkA ©   (2005-06-22 11:10) [40]


> Например, Process Explorer, показывающий много всего увлекательного
> без драйверов.

Это от SysInternals который? Если зайти в диспетчер устройств>Вид>Показывать скрытые устройства то можно увидеть "PROCEXP", интересно что это? И с regmon"ом такая-же история=)


 
Alex870   (2005-06-22 11:29) [41]


> Перехватывай ф-ций ядра, таким образом, не кто (ламер) не
> сможет
> снять процесс, а также если есть опыт по защите то и профилю
>
> будет лень :)

Дело в том, что я бы все-таки хотел отлавливать завершение процесса и позволять его завершать, т.е. не делать явную защиту, а просто контролировать закрытие программы для ведения лога.


 
MS-MEN ©   (2005-06-22 11:32) [42]

> Игорь Шевченко

Это можно и без системных вызовов решить просто надо знать ф-ций.

Например NativeAPI в них 80%  ф-ций которые можно использовать
как в третям кольце, так и в нулевом это  лишь для WinNT платформ.

А что ты хочешь предложить вместо перехвата? Как ты собираешься
узнать, что процесс завершается методом Terminate Process? А если
на уровне нулевого кольца грохну? То даже перехват Win / Native –API
не помогут.

В - общем, другим способом решить это не возможно.

Я ещё раз говорю применение драйверов это означает что
Что над программой работали профессионалы. (Если это
касается системы) А применение WinAPI или коротко API
это только для третьего кольца.

> kaZaNoVa ©   (22.06.05 01:22) [28]
> DEBUG не помогла:(

Во-общем последние, что я могу предложить это включить
системною привилигию DEBUFG вот  маленький код
который завершает любой процесс с помощью сис. Debug.

{ убивание процесса отладочным методом }
Function DebugKillProcess(ProcessId: dword): boolean;
var
pHandle: dword;
myPID: dword;
HandlesInfo: PSYSTEM_HANDLE_INFORMATION_EX;
r: dword;
begin
Result := false;
myPID := GetCurrentProcessId();
if not EnableDebugPrivilege() then Exit;
//подключаемся к системе отладки и получаем DebugObject
if DbgUiConnectToDbg() <> STATUS_SUCCESS then Exit;
pHandle := OpenProcessEx(ProcessId);
//включаем отладку процесса
if DbgUiDebugActiveProcess(pHandle) <> STATUS_SUCCESS then Exit;
//надо найти полученный DebugObject
HandlesInfo := GetInfoTable(SystemHandleInformation);
if HandlesInfo = nil then Exit;
for r := 0 to HandlesInfo^.NumberOfHandles do
 if (HandlesInfo^.Information[r].ProcessId = myPID) and
    (HandlesInfo^.Information[r].ObjectTypeNumber = $8)  //DebugObject
    then begin
      //закрываем DebugObject, что приводит к уничтожению отлаживаемого процесса
      CloseHandle(HandlesInfo^.Information[r].Handle);
      Result := true;
      break;
    end;
VirtualFree(HandlesInfo, 0, MEM_RELEASE);
end;


 
MS-MEN ©   (2005-06-22 11:39) [43]

> Alex870
> Дело в том, что я бы все-таки хотел отлавливать завершение
> процесса и позволять его завершать, т.е. не делать явную защиту,
> а просто контролировать закрытие программы для ведения лога.

Извини, наверное, не так понял :(  Я думал ты собираешься
защитить от завершение.

Тогда можно просто создать маленьки на ASM или API
монитор вот и все.

:) Мозги Игорь Шевченко заморочил тоже мой извинение.


 
Игорь Шевченко ©   (2005-06-22 13:50) [44]

MS-MEN ©   (22.06.05 11:32) [42]


> Я ещё раз говорю применение драйверов это означает что
> Что над программой работали профессионалы.


Пальцы не гни, ладно ?
А то пишешь слова с ошибками, а пальцы гнешь.

KosilkA ©   (22.06.05 11:10) [40]

А ты не от администратора запусти. Удивись.


 
alpet ©   (2005-06-22 13:57) [45]

А чем вариант в [35] не устраивает? Или мульти-процессный подход сложным кажется? Помоему там единственная сложность - правильная отработка после завершения убитого процесса, которую к тому-же можно упростить, расшарив между процессами регион памяти. Во всяком случае второй процесс в этом случае сможет скинуть в файл данные которые не успел обработать второй процесс и записать в лог о не нормальном завершении.


 
kaZaNoVa ©   (2005-06-22 14:01) [46]

Игорь Шевченко ©   (22.06.05 10:50) [39]

> Например, Process Explorer, показывающий много всего
> увлекательного без драйверов.

я когда-то запускал Process Explorer без прав админа, он намного меньше информации показывал:(
(например вкладка Perfomance процесса - вообще нет инфы), имхо вывод - Process Explorer может нормально работать и выдавать всю информацию только с правами админа..


 
BiN ©   (2005-06-22 14:07) [47]

Alex870   (21.06.05 13:46)

Единственно верный ответ тебе уже дали в [33]. Остальное - от лукавого.


 
Alex870   (2005-06-22 15:14) [48]

Спасибо всем!
Наверно [35] это единственный правильный подход к решению проблемы. Я думаю что на этом обсуждение можно закрыть, а то это скоро перейдет в категорию "потрепаться". Еще раз всем спасибо!


 
Игорь Шевченко ©   (2005-06-22 15:20) [49]


> Наверно [35] это единственный правильный подход к решению
> проблемы


[35] тебе не поможет, в твоем случае, так как все, что гарантирует этот способ - это повторный запуск, а вовсе не перехват завершения и выполнение некоторых действий перед завершением.


 
Alex870   (2005-06-22 15:32) [50]


> [35] тебе не поможет, в твоем случае, так как все, что гарантирует
> этот способ - это повторный запуск, а вовсе не перехват
> завершения и выполнение некоторых действий перед завершением

Я же писал, что мне нужно оставить запись в логе при закрытии процесса (время, кем, инфа о трафике). Как ведет логи Kerio Winroute я не знаю, но там это реализовано (хотя winroute это служба).


 
alpet ©   (2005-06-22 15:40) [51]

Игорь Шевченко ©   (22.06.05 15:20) [49]

Почему повторный запуск? Если у процессов общая секция данных с структурой в которой сформированны некоторые данные, то непредвиденное завершение одно процесса, приведет к тому что второй записав в лог данные также завершится самостоятельно. Другое дело, что это решение не самое лучшее для таких случаев по сравнению с службами.


 
Игорь Шевченко ©   (2005-06-22 16:04) [52]

alpet ©   (22.06.05 15:40) [51]

Это, конечно, тоже способ, но при этом можно в лог записать только факт завершения наблюдаемого процесса, но не действия, предшествующие завершению. Поэтому я присоединяюсь к [33]


 
Alex870   (2005-06-22 16:22) [53]


> Это, конечно, тоже способ, но при этом можно в лог записать
> только факт завершения наблюдаемого процесса, но не действия,
> предшествующие завершению. Поэтому я присоединяюсь к [33]

Дело в том, что при определении трафика я использую IPHelper, т.е. драйвером Windows, поэтому потеря результатов работы программы меня не пугает - их просто нет, всю информацию можно получить с помощью драйвера и после завершения основного модуля.


 
MS-MEN ©   (2005-06-22 16:47) [54]

> Игорь Шевченко
> Пальцы не гни, ладно ?
> А то пишешь слова с ошибками, а пальцы гнешь.

И что ты хочешь мне этим сказать?


 
Игорь Шевченко ©   (2005-06-22 17:12) [55]

MS-MEN ©   (22.06.05 16:47) [54]

Только то, что не стоит выдавать за профессионализм использование драйверов.


 
MS-MEN ©   (2005-06-22 17:51) [56]

> Игорь Шевченко
> Только то, что не стоит выдавать за профессионализм
> использование драйверов.

Ладно, будем считать, по-твоему.

Каждый знающий Assembler и умет работать с системой
то я бы сказал, что это не для начинающих.

Люди просто так не будут создавать драйвера, поверь мне.

Я, например, могу создавать драйвера на ASM/VB/VC/DELPHI
так как системный программист, а знание системы это больше
чем ваше ООП программирование и не каждый возьмется за это.


 
Alexander Panov ©   (2005-06-22 17:53) [57]

MS-MEN ©   (22.06.05 17:51) [56]
а знание системы это больше
чем ваше ООП программирование и не каждый возьмется за это.


Снобизм?;)

Спор ни о чем.
Знание каждой области необходимо и системному, и прикладному программисту. Но разной степени глубины.

Ты знаешь ООП?


 
Игорь Шевченко ©   (2005-06-22 18:02) [58]

MS-MEN ©   (22.06.05 17:51) [56]


> Люди просто так не будут создавать драйвера, поверь мне.


Они будут создавать драйвера для скрытия/неснятия процессов, упиваться собственной крутостью и гнуть пальцы, что есть силы.

Лучше закончи архитектурный институт или изобрети самодвижущееся пресс-папье, толку будет гораздо больше, чем от скрытых процессов, поверь.


 
MS-MEN ©   (2005-06-22 19:47) [59]

> Игорь Шевченко [56]
 Тебе не кажется что ты сам пальцы загибаешь?
 
 Тебе автор нормальнно сказал прочти статью нормальнно
 там нет не каких жестких перехватов. Он лишь показывает
 как работать с сис. ф-ями в нулевом кольце что жестко
 относится к драйверам.

> Alexander Panov
 Вот приставь себе, не знаю.


 
Alexander Panov ©   (2005-06-22 20:41) [60]

MS-MEN ©   (22.06.05 19:47) [59]
Вот приставь себе, не знаю.


Ну тогда, как я понимаю, ты и сравнить не можешь.
Ограниченность ни к чему хорошему не приводит.
ВОобще, снобизм - характерная черта системщиков еще с незапамятных времен ЕС ЭВМ.


 
Kerk ©   (2005-06-22 20:56) [61]

MS-MEN ©   (22.06.05 17:51) [56]
ASM/VB/VC/DELPHI


Ну-ка, ну-ка...


 
Игорь Шевченко ©   (2005-06-22 22:43) [62]

MS-MEN ©   (22.06.05 19:47) [59]


>  Тебе не кажется что ты сам пальцы загибаешь?


Мне можно.


>  Тебе автор нормальнно сказал прочти статью нормальнно
>  там нет не каких жестких перехватов. Он лишь показывает
>  как работать с сис. ф-ями в нулевом кольце что жестко
>  относится к драйверам.


Да я ее читал. Я читать умею. Я и примеры смотрел. И не увидел, на какой хрен такие драйверы вообще пишут, кроме как показать свою немерянную крутость.

А что до драйверов, позволяющих пользователю работать с функциями ядра, так их еще в 2000 году Свен Шрайбер описал, так что бинома Ньютона тут нету. При этом, заметь, Свен пальцы не гнул, какой он крутой, а приводил реальные примеры, когда такую функциональность можно использовать. А у автора (читай - у тебя) все исключительно на скрытие/неснятие и прочую хрень нацелено.

Alexander Panov ©   (22.06.05 20:41) [60]


> ВОобще, снобизм - характерная черта системщиков еще с
> незапамятных времен ЕС ЭВМ.


А за наезд за системщиков ответить ? Ты учти, я не один, я Коншина позову :)


 
MS-MEN ©   (2005-06-22 23:19) [63]

> Игорь Шевченко
Я не чего против не имею просто знание драйверов это
говорит о том что ты дествительнно углубленно знаешь.

Перехват я каснул только и за того что тема заставила сказаьть.

И вообще ты модер закрой эту тему..! Хватит пальцы нагинать ;)


 
Kerk ©   (2005-06-22 23:22) [64]

MS-MEN ©   (22.06.05 23:19) [63]

Так пример драйвера на VB будет?


 
Digitman ©   (2005-06-23 08:54) [65]

про драйвер на VB мне тоже прелюбопытно было бы узнать)

я бы еще и на драйвер на Делфи (Д3 - не в счет) с удовольствием подивился)


> MS-MEN


не сподобишься ли продемонстрировать ? хотя бы скелет ?)


 
MS-MEN ©   (2005-06-23 09:11) [66]

Достали :( ;)

Вот драйвер на DELPHI который я делал для своего Firewall

unit Demo;

interface

{$I bcDDK_Root.inc}
{$I bcDDK_Io.inc}

CONST
     
     ProjectName = "ProcHunter";
     ProjectDescription = "ProcessHunter";

     DriverNameString = "\Device\"+ProjectName;
     DeviceNameString = "\DosDevices\"+ProjectName;
     EventNameString  = "\BaseNamedObjects\"+ProjectName;
     UserModeDeviceName = "\\.\Global\"+ProjectName;
     UserModeEventName = "Global\"+ProjectName;

     IOCTL_PSHUNT_GET_HOOKINFO   =
     (IOCTL_UNKNOWN_BASE shl 16) or
     ((FILE_READ_ACCESS) shl 14) or
     ($800 shl 2) or
     (METHOD_BUFFERED);

TYPE
     PProcessHookInfo = ^TProcessHookInfo;

     TProcessHookInfo = record
     ParentId : Cardinal;
     ProcessId : Cardinal;
     Create : LongBool;
    end;

function DriverEntry(
                    const DriverObject : PDRIVER_OBJECT;
                    const RegistryPath : PUNICODE_STRING
                    ) : NTStatus; stdcall;

implementation

{$I bcDDK_Debug.inc}
{$I bcDDK_NtStatus.inc}
{$I bcDDK_Rtl.inc}
{$I bcDDK_IoMacros.inc}
{$I bcDDK_Ps.inc}
{$I bcDDK_Zw.inc}
{$I bcDDK_Ke.inc}
{$I bcDDK_Mm.inc}
{$I bcDDK_BCore.inc}

var // strings
   DriverName    : UNICODE_STRING;
   DeviceName    : UNICODE_STRING;
   EventName     : UNICODE_STRING;
   // internal fields
   DeviceObject  : PDEVICE_OBJECT;
   NotifyEvent   : THandle;
   NotifyPKEVENT : PKEVENT;
   // interface variables
   ProcHookInfo  : TProcessHookInfo;

procedure CREATE_PROCESS_HOOK(const Parent : THandle;const Process :
THandle;const Create : DDKBoolean); stdcall;
begin
  ProcHookInfo.ParentId:=Parent;
  ProcHookInfo.ProcessId:=Process;
  ProcHookInfo.Create:=Create;
  KeSetEvent(NotifyPKEVENT,0,False);
  KeClearEvent(NotifyPKEVENT);
end;

procedure ADriverUnload
(const DriverObject : PDRIVER_OBJECT); stdcall;
begin
// -4. Stop Process Hooking
  PsSetCreateProcessNotifyRoutine(CREATE_PROCESS_HOOK,True);
// -3. Close Notify Event
  ZwClose(NotifyEvent);
// -2. Delete Symbolic Link
  IoDeleteSymbolicLink(@DeviceName);
// -1. Delete Device
  IoDeleteDevice(DeviceObject);
end;

function PSHuntCreateCloseDispatch(
        const DeviceObject : PDEVICE_OBJECT;
        const Irp : PIRP) : NTSTATUS; stdcall;
begin
  Irp^.IoStatus.ISBUnion.Status:=STATUS_SUCCESS;
  Irp^.IoStatus.Information:=0;
  IoCompleteRequest(Irp,IO_NO_INCREMENT);
  Result:=STATUS_SUCCESS;
end;

function PSHuntIOCTLDispatch(
        const DeviceObject : PDEVICE_OBJECT;
        const dIrp : PIRP) : NTSTATUS; stdcall;
var IRPStack : PIO_STACK_LOCATION;
BEGIN
 IRPStack:=IoGetCurrentIrpStackLocation(dIrp);
 CASE IRPStack^.Parameters.DeviceIoControl.IoControlCode OF
 IOCTL_PSHUNT_GET_HOOKINFO :
 BEGIN
 if  (IRPStack^.Parameters.DeviceIoControl.OutputBufferLength>=SizeOf(TProcessHookInfo))
 and (dIrp.AssociatedIrp.SystemBuffer<>nil) then
 BEGIN
 // load
 TProcessHookInfo(dIrp.AssociatedIrp.SystemBuffer^):=ProcHookInfo;
 dIrp.IoStatus.Information:=SizeOf(TProcessHookInfo);
 // report
 Result:=STATUS_SUCCESS;
 END
 else Result:=STATUS_UNSUCCESSFUL;
 END;
 ELSE Result:=STATUS_NOT_IMPLEMENTED;
END;
IoCompleteRequest(dIrp,IO_NO_INCREMENT);
END;

function DriverEntry;
begin
// 1. Create and initialize device object
RtlInitUnicodeString(DriverName,DriverNameString);
Result:=IoCreateDevice(
                       DriverObject,
                       0,
                       @DriverName,
                       FILE_DEVICE_UNKNOWN,
                       0,
                       False,
                       DeviceObject
                       );
if (Result=STATUS_SUCCESS) then
 BEGIN
  // 2. Create and initialize symbolic link
  RtlInitUnicodeString(DeviceName,DeviceNameString);
  Result:=IoCreateSymbolicLink(@DeviceName,@DriverName);
  if (Result=STATUS_SUCCESS) then
   BEGIN
    // 3. Create Notification Event
    RtlInitUnicodeString(EventName,EventNameString);
    NotifyPKEVENT:=IoCreateNotificationEvent(@EventName,@NotifyEvent);
    if (NotifyPKEVENT<>nil) then
     BEGIN
      KeClearEvent(NotifyPKEVENT);
      // 4. Establish Process Hooking
      Result:=PsSetCreateProcessNotifyRoutine(CREATE_PROCESS_HOOK,False);
      if (Result=STATUS_SUCCESS) then
       BEGIN
        // 5.1. Initialize Internal Structures
        // 5.2. Initialize Event Handlers
        DriverObject^.DriverUnload:=ADriverUnload;
        DriverObject^.MajorFunction[IRP_MJ_CREATE]:=PSHuntCreateCloseDispatch;
        DriverObject^.MajorFunction[IRP_MJ_CLOSE]:=PSHuntCreateCloseDispatch;

DriverObject^.MajorFunction[IRP_MJ_DEVICE_CONTROL]:=PSHuntIOCTLDispatch;
       END;
      if (Result<>STATUS_SUCCESS) then ZwClose(NotifyEvent);
     END
      else Result:=STATUS_UNSUCCESSFUL;
    // 3.c. check and cleanup
    if (Result<>STATUS_SUCCESS) then IoDeleteSymbolicLink(@DeviceName);
   END;
  // 2.c. check and cleanup
  if (Result<>STATUS_SUCCESS) then IoDeleteDevice(DeviceObject);
 END;
end;

end.


 
MS-MEN ©   (2005-06-23 09:13) [67]

Кстати для VisualBasic это не трудно перевести
так как VB это почти и даже тот-же DELPHI.


 
MS-MEN ©   (2005-06-23 09:17) [68]

Пример второй.

unit Demo;

interface

{$DEFINE DEBUG}

{$INCLUDE Driver.inc}
{$INCLUDE Ntoskrnl.inc}

type
Pfar_jmp = ^far_jmp;
far_jmp=packed record
PuhsOp: byte;
PushArg: pointer;
RetOp: byte;
end;

PProtected = ^TProtected;
TProtected = packed record
 //Protected
 PrArray:array[0..255] of dword;
 PrCount:dword;
 //True
 TrArray:array[0..15] of dword;
 TrCount:dword;
end;

function DriverEntry(
 const DriverObject : PDRIVER_OBJECT;
 const RegistryPath : PUNICODE_STRING
 ) : NTStatus; stdcall;

var
 //Far Jmp
 JmpNtOpenProcess:PFar_Jmp;
 //Old Code
 OldNtOpenProcess:Far_Jmp;
 ProtProc:PProtected;
 NewNtOpenProcessAdr:pointer;
 Protect:TProtected;

implementation

{$INCLUDE Functions.inc}

const
MapingName:PWideChar = "\BaseNamedObjects\ProtectedProcesses";

{$IFDEF DEBUG}
 Procedure DeinstallHooks;
 begin
   //Снимаем перехватчик NtOpenProcess
   asm cli end;
   JmpNtOpenProcess.PuhsOp:=OldNtOpenProcess.PuhsOp;
   JmpNtOpenProcess.PushArg:=OldNtOpenProcess.PushArg;
   JmpNtOpenProcess.RetOp:=OldNtOpenProcess.RetOp;
   asm sti end;
 end;

 Procedure ADriverUnload(
             const DriverObject : PDRIVER_OBJECT
             ); stdcall;
 const
  LinkName   : PWideChar = "\DosDevices\WinHunterSecurity";
 var
  ULinkName:TUnicodeString;
 begin
 //Удаляем символическую ссылку
 RtlInitUnicodeString(@ULinkName,LinkName);
 IoDeleteSymbolicLink(@ULinkName);
 //удаляем устройство
 IoDeleteDevice(DriverObject.DeviceObject);
 //Снимаем перехваты
 DeinstallHooks;
 DbgPrint("Драйвер выгружен");
 end;
{$ENDIF}

//проверка наличия процесса в списке доверенных
Function IsTruePresent(const PID:dword):boolean;
var
r:dword;
begin
Result:=false;
for r:=0 to Protect.TrCount do
if PID = Protect.TrArray[r] then
  begin
  Result:=true;
  exit;
  end;
end;

Function TrueNtOpenProcess(phProcess:PDWORD;
                         AccessMask:DWORD;
                         ObjectAttributes:PObjectAttributes;
                         ClientID:PClientID):NTStatus;
begin
//Снимаем перехватчик
asm cli end;
 JmpNtOpenProcess.PuhsOp:=OldNtOpenProcess.PuhsOp;
 JmpNtOpenProcess.PushArg:=OldNtOpenProcess.PushArg;
 JmpNtOpenProcess.RetOp:=OldNtOpenProcess.RetOp;
asm sti end;
//Вызываем функцию
result:=NtOpenProcess(phProcess,AccessMask,
                      ObjectAttributes,ClientID);
//Устанавливаем перехватчик
asm cli end;
 JmpNtOpenProcess.PuhsOp:=$68;
 JmpNtOpenProcess.RetOp:=$c3;
 JmpNtOpenProcess.PushArg:=NewNtOpenProcessAdr;
asm sti end;
end;

Function NewNtOpenProcess(phProcess:PDWORD;
                         AccessMask:DWORD;
                         ObjectAttributes:PObjectAttributes;
                         ClientID:PClientID):NTStatus;stdcall;
var
r:dword;
CurrentProcess:dword;
begin
CurrentProcess:=PsGetCurrentProcessId;
//Проверяем запрещен ли доступ по маске
if (AccessMask <> PROCESS_QUERY_INFORMATION) and
//не открывается ли текущий процесс
  (ClientID.UniqueProcess <> CurrentProcess) and
//Разрешить открытие системой
  (CurrentProcess <> 4)// and
//нет ли процесса в списке доверенных
 // not IsTruePresent(CurrentProcess)
  then
  for r:=0 to Protect.PrCount+1 do
    if ClientID.UniqueProcess=Protect.PrArray[r] then //защищаемый процесс
     begin
     phProcess^:=0;
     Result:=STATUS_ACCESS_DENIED; //отказано в доступе
      {$IFDEF DEBUG}
       DbgPrint("OpenProcess Blocked");
      {$ENDIF}
     exit;
     end;
{$IFDEF DEBUG}
 DbgPrint("OpenProcess");
{$ENDIF}
//открыть процесс
Result:=TrueNtOpenProcess(phProcess,AccessMask,ObjectAttributes,ClientID);
end;

Procedure SinchronizeMapping;
var
hMapping:dword;
begin
//открываем маппинг
 hMapping:=OpenFileMapping(SECTION_MAP_READ,MapingName);
 if hMapping<>INVALID_HANDLE_VALUE then
    begin
     {$IFDEF DEBUG}
       DbgPrint("Маппинг открыт");
     {$ENDIF}
    ProtProc:=MapViewOfFileEx(hMapping,SECTION_MAP_READ, 0, 0,
                         255,pointer($7FFFFFFF));
    if ProtProc<>nil then
       begin
        {$IFDEF DEBUG}
          DbgPrint("Маппинг присоединен");
        {$ENDIF}
        //синхронизируем
       CopyMem(ProtProc,@Protect,SizeOf(TProtected));
       //Размапитть
       ZwUnmapViewOfSection(INVALID_HANDLE_VALUE,ProtProc);
       end;
    NtClose(hMapping);
    end;
end;

Function Create(
         DeviceObject:PDEVICE_OBJECT;
         Irp : PIRP
         ):NTStatus;stdcall;
begin
irp.IoStatus.Status:=STATUS_SUCCESS;
irp.IoStatus.Information:=0;
IoCompleteRequest(Irp,IO_NO_INCREMENT);
result :=STATUS_SUCCESS;
//обновляем списки процессов
SinchronizeMapping;
{$IFDEF DEBUG}
 DbgPrint("Updated");
{$ENDIF}
end;

Function Control(
         DeviceObject:PDEVICE_OBJECT;
         Irp : PIRP
         ):NTStatus;stdcall;
var
data:pdword;
Control:PIO_STACK_LOCATION_CONTROL;
begin
irp.IoStatus.Status:=STATUS_SUCCESS;
irp.IoStatus.Information:=4;
data:=irp.AssociatedIrp.SystemBuffer;
//Control:=irp.Tail.Overlay.CurrentStackLocation;

DbgPrint(pchar(chr(data^)));
result :=STATUS_SUCCESS;
//data:=irp.CurrentStackLocation
//if data^=10 then DbgPrint("OK");
{$IFDEF DEBUG}
 DbgPrint("Writed");
{$ENDIF}
IoCompleteRequest(Irp,IO_NO_INCREMENT);
end;

Procedure SetHook;
begin
  NewNtOpenProcessAdr:=@NewNtOpenProcess;
 //Получаем адрес NtOpenProcess
 JmpNtOpenProcess:=GetRealPtr(@NtOpenProcess);
 //сохраняем старый код
 OldNtOpenProcess.PuhsOp:=JmpNtOpenProcess.PuhsOp;
 OldNtOpenProcess.PushArg:=JmpNtOpenProcess.PushArg;
 OldNtOpenProcess.RetOp:=JmpNtOpenProcess.RetOp;
 //Устанавливаем перехватчик
 asm cli end;
 JmpNtOpenProcess.PuhsOp:=$68;
 JmpNtOpenProcess.RetOp:=$c3;
 JmpNtOpenProcess.PushArg:=NewNtOpenProcessAdr;
 asm sti end;
end;

function DriverEntry;
const
 DeviceName : PWideChar = "\Device\WinHunterSecurity";
 LinkName   : PWideChar = "\DosDevices\WinHunterSecurity";
var
UDeviceName:TUnicodeString;
ULinkName:TUnicodeString;
Device:PDEVICE_OBJECT;
begin
 //Очищаем структуру
 ZeroMem(@Protect,SizeOf(TProtected));
 {$IFDEF DEBUG}
   DriverObject^.DriverUnload := @ADriverUnload;
 {$ENDIF}
 DriverObject^.MajorFunction[IRP_MJ_CREATE] := @Create;
 DriverObject^.MajorFunction[IRP_MJ_DEVICE_CONTROL] := @Control;
  {$IFDEF DEBUG}
    DbgPrint("Драйвер загрузился");
  {$ENDIF}

 //создаем устройство
 RtlInitUnicodeString(@UDeviceName,DeviceName);
 if IoCreateDevice(DriverObject,16,@UDeviceName,
                FILE_DEVICE_NULL,0,true,Device) = STATUS_SUCCESS then
    begin
    Device.Flags :=  DO_DIRECT_IO;
     {$IFDEF DEBUG}
       DbgPrint("Device Created");
     {$ENDIF}
    // создаем символическую ссылку
    RtlInitUnicodeString(@ULinkName,LinkName);
    if IoCreateSymbolicLink(@ULinkName,@UDeviceName) = STATUS_SUCCESS then
       begin
         {$IFDEF DEBUG}
           DbgPrint("LinkCreated");
         {$ENDIF}
         SinchronizeMapping;
       //Устанавливаем перехват
       SetHook;
       end;
    end;
Result := STATUS_SUCCESS;
end;

end.


 
Digitman ©   (2005-06-23 09:31) [69]


> Вот драйвер на DELPHI


т.е., как я понял, ты открыл Америку, умудрившись в Делфи версий выше 3-й собрать исп.модуль WDM-драйвера, одним нажатием Ctrl-F9, при том что дельфийские сборщики этих версий попросту не умеют строить образы WDM-драйверов, а объектные файлы, генерируемые дельфийскими компиляторами, несовместимы по формату с теми с которыми работает мелкомягкий линкер, заведомо умеющий строить эти образы ?)


 
MS-MEN ©   (2005-06-23 09:35) [70]

Это не я открыл а просто хорошие люди подумали и посторались
http://rsdn.ru/article/delphi/kmdelphi.xml


 
MS-MEN ©   (2005-06-23 09:40) [71]

> Digitman ©   (23.06.05 09:31) [69]

Я лишь воспользовался идеей и создал свой драйвер
но все равно придерживаюсь ASSEMBLER это лучше
и многое адаптировано под  этот язык и вообще
Assembler как раз для этого и создано!


 
Kerk ©   (2005-06-23 09:43) [72]

MS-MEN ©   (23.06.05 9:40) [71]
но все равно придерживаюсь ASSEMBLER


Полтора-два года назад наверно так же бы сказал.
Сейчас повзрослел. :o)


 
Digitman ©   (2005-06-23 10:06) [73]


> MS-MEN ©   (23.06.05 09:35) [70]
> Это не я открыл а просто хорошие люди подумали и посторались


так там же черным по белому написано (цитирую) :

Delphi версии выше 3 создают несовместимый с Intel OMF формат, хотя и внешне похожий
..

Опция, позволяющая сгенерировать объектный файл, в компиляторах Borland есть, но из-за внесенных Borland изменений формата такие объектные файлы понимают лишь компиляторы самой Borland, а сборщик Microsoft не распознаёт их как корректные


и это проверено, и это так и есть на самом деле, по кр.мере вплоть до Д7)


 
MS-MEN ©   (2005-06-23 10:21) [74]

Давно бы так. )


 
Digitman ©   (2005-06-23 10:34) [75]

вот именно)

ну так и как же ты умудрился написать WDM-драйвер в Делфи вервии выше тройки ?)


 
MS-MEN ©   (2005-06-23 10:41) [76]

>Digitman
>вот именно)
>ну так и как же ты умудрился написать WDM-драйвер в Делфи >вервии выше тройки ?)

ну так и как же ты умудрился написать WDM-драйвер
Что ты тормозишь? Я тебе ещё раз говорю это SYS драйвер!

Где ты видел что бы я писал выше тройки? компилятор у меня 3 :D


 
Digitman ©   (2005-06-23 11:12) [77]


>  ещё раз говорю это SYS драйвер


> Что ты тормозишь?


вот ты про свой SYS шарманку завел)

причем здесь расширение имени файла-то ?)

файл исп.модуля драйвера вправе иметь произвольное расширение (просто по дифолту НТ-драйверы режима ядра принято именовать с расширением SYS), но сам бин.образ драйвера обязан соответствовать одной из поддерживаемых системой моделей)


> Где ты видел что бы я писал выше тройки?


а где ты об этом упомянул ранее ?)

ты тычешь и тычешь в статью, будто ее никто кроме тебя не читал)..

и ежу понятно что в 3-ке было кое-что допустимо в этом плане, в отличие от старших версий !) ...

Но ! Даже в 3-йке создать НТ-драйвер режима ядра нельзя БЕЗ привлечения стороннего линкера) ... А уж когда привлечен нештатный для Делфи-среды инструментарий, утверждение о том что ты "создал драйвер в Делфи" липовое - все равно так или иначе ты сходил на поклон к Майкрософту и взял у него сборщик для означенной цели)


 
MS-MEN ©   (2005-06-23 12:14) [78]

Я тебя не понял.

Знаешь если ты такой умный так сам и разберись!

Зачем я код драйвера выложил :(

Закрыто.


 
Digitman ©   (2005-06-23 12:27) [79]


> Зачем я код драйвера выложил


а шут тебя знает) ... мож ты пуп земли зондируешь) .. нет бы просто ссылку привести в кач-ве своего imho))

затем, вероятно, чтобы подтвердить диагноз ИШ)

вся эта марахайка твоя, разумеется, компилируется без проблем, и речь не об этом)

и это, кстать, не столь интересно, сколь твои заявы насчет VB) ...


 
Koresh   (2005-06-23 15:13) [80]

>ВОобще, снобизм - характерная черта системщиков еще с незапамятных времен ЕС ЭВМ.

Хы, Вы то как писали на своем Delphi, так и останетесь, а здесь через пару лет поменяют систему- и ты не у дел.
Но "лучше 30 лет питаться свежей кровью, чем 300 лет падалью."


 
alpet ©   (2005-06-23 15:18) [81]

Koresh   (23.06.05 15:13) [80]
В смысле на многоядерную RISC архитектуру вроде Cell. Дык компиляторы Delphi однозначно будут под нее портированы, а вот с ассемблером на ней будет ой как тяжело. Так что я не понимаю вашего злорадства.


 
Digitman ©   (2005-06-23 15:24) [82]


> Koresh   (23.06.05 15:13) [80]


это не "падалью" отдает)

это отдает известным "Акелла промахнулся !" (с) из-за угла, шакалье


 
Игорь Шевченко ©   (2005-06-23 19:24) [83]

Двигатель был очень похож на настоящий, но не работал...


 
Koresh   (2005-06-24 08:41) [84]

alpet>я не понимаю вашего злорадства.
А я не злорадствую. Вы наверно прочитали не внимательно. Delpi"сты смогут писать и на других платформах, а системщики- надо переучиваться или отходить. Так что снобизм тут не причем- профессия такая.


 
alpet ©   (2005-06-24 10:43) [85]

Koresh   (24.06.05 08:41) [84]
Что ж, видимо пост трудный к распознанию оказался :)
Вобщем резюме - знать и уметь то и другое - полезно, возводить что-то одно в ранг религии - вредно.


 
NikNet ©   (2005-06-24 20:40) [86]

Удалено модератором


 
Ms-Rem (real)   (2005-07-17 20:49) [87]

Удалено модератором


 
MS-MEN ©   (2005-08-29 00:25) [88]

Удалено модератором


 
alpet ©   (2005-08-29 00:28) [89]

Удалено модератором


 
имя   (2005-09-21 19:10) [90]

Удалено модератором


 
OldNaum ©   (2005-09-21 20:06) [91]

я только что увидел одну вещь, когда ветку перечитывал. вы всеми усилиями, всем форумом помогали вирусописателю. обратите внимание на его исходник - program ati2evxx - именно такое имя носит ATI Radeon драйвер в процессах.

з.ы. я говорю это к тому - что безобидные вопросы многие называют хакерскими и отказываются отвечать, еще и хамят в догонку. а когда явно мы имеем дело с попыткой "балоства" - помогаем всем форумом решить человеку "мааленькую" проблемку.

прошу не стирать мой пост! это не оффтопик - это лишний повод призадуматься многим. а вот господин (21.09.05 19:10) [90] просто урод!



Страницы: 1 2 3 вся ветка

Форум: "WinAPI";
Текущий архив: 2005.11.20;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.77 MB
Время: 0.039 c
11-1111916035
RadaR
2005-03-27 13:33
2005.11.20
UNICODE


2-1130767781
stud
2005-10-31 17:09
2005.11.20
получить код ошибки


6-1122277100
AbrosimovA
2005-07-25 11:38
2005.11.20
Закрыть открытый порт


2-1130410496
kosha
2005-10-27 14:54
2005.11.20
Перегрузка виртуального метода


14-1130486099
Igorek
2005-10-28 11:54
2005.11.20
Мой любимец распускает пятый листочек





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский