Консультация № 175280
15.12.2009, 08:20
35.00 руб.
0 10 1
Здравствуйте, уважаемые эксперты. Не ответите ли на ряд вопросов по программе, которая дана в приложении.
1. Почему пишется end DriverEntry, а не просто end, при чём тут добавление DriverEntry, может ли это прибавление считаться точкой входа, ведь строка DriverEntry закомментирована в начале кода. Может, для драйверов свои правила оформления?
2. В строке начала процедуры DriverEntry proc одновременно указаны и параметры функции: pDriverObject:PDRIVER_OBJECT, pusRegistryPath:PUNICODE_STRING. Это параметры функции DriverEntry, разве возможно через название процедуры передавать ещё и параметры функции.
3. Можно ли строку DriverEntry proc pDriverObject:PDRIVER_OBJECT, pusRegistryPath:PUNICODE_STRING переделать через invoke?
DriverEntry proc
invoke DriverEntry, pDriverObject:PDRIVER_OBJECT, pusRegistryPath:PUNICODE_STRING
4. Автор программы пишет:
«Прототип DriverEntry выглядит так:
DriverEntry proto DriverObject:PDRIVER_OBJECT, RegistryPath:PUNICODE_STRING
К сожалению, Microsoft отошла от принципа "венгерской нотации" при составлении заголовочных файлов и документации DDK. Поэтому DriverObject превращается в pDriverObject, а RegistryPath в pusRegistryPath».
Что автор имел в виду под "венгерской нотацией", и почему он добавляет к названию параметра DriverObject букву p, а к параметру RegistryPath добавляет pus. Что это означает?
Заранее спасибо.


Приложение:
;@echo off
;goto make
.386
.model flat, stdcall
option casemap:none

include \masm32\include\w2k\ntstatus.inc
include \masm32\include\w2k\ntddk.inc
.code
;DriverEntry
DriverEntry proc pDriverObject:PDRIVER_OBJECT, pusRegistryPath:PUNICODE_STRING

mov eax, STATUS_DEVICE_CONFIGURATION_ERROR
ret
DriverEntry endp
end DriverEntry

:make
\masm32\bin\ml /nologo /c /coff simplest.bat
\masm32\bin\link /nologo /driver /base:0x10000 /align:32 /out:simplest.sys /subsystem:native simplest.obj
del simplest.obj
echo.
pause

Обсуждение

Неизвестный
15.12.2009, 08:35
общий
1 "DriverEntry закомментирована в начале кода" DriverEntry - имя процедуры оно не закомментированно
2 это не передача параметров, а описание параметров функции
3 это разные вещи proc - директива это описание функции, invoke - директива вызова
4 "венгерская нотация" буква перед именем указывающая на тип
pDriverObject - pointer указатель на объект типа DRIVER_OBJECT
pusRegistryPath - pointer unicode string - думаю смысл ясен
Неизвестный
15.12.2009, 11:17
общий
По поводу первого вопроса. Получается, что вариант:
.code
start:
<имя> proc

<имя> endp
end start

это одно и то же, что и:
.code
<имя> proc

<имя> endp
end <имя>

По вопросу три: а смысл описывать функцию, не предполагая её вызова? Думаю, что вызов всё же предполагается, но не пойму, где. И всё равно должен же быть эквивалент строке:
DriverEntry proc pDriverObject:PDRIVER_OBJECT, pusRegistryPath:PUNICODE_STRING
По последнему, четвёртому, вопросу: обязательно ли соблюдение "венгерской нотации", т.е. добавление p и pus. Microsoft же не соблюдает, зачем тогда и нам соблюдать?
давно
Посетитель
7438
7205
15.12.2009, 11:46
общий
1) Имя PROC практически ничем не отличается от любой метки, поэтому, действительно, оба варианты единтичны.
3) Вызов будет делать системаВсе драйвера должны иметь один и тот же синтаксис вызова.
4) "Венгерская нотация" придумана исключительно для понимания человеком, чтобы один программист легко читал программы другого. Лично Вас никто не обязывает придерживаться этого правила формирования имен. Компилятору "параллельны" имена переменных. Но, согласитесь, намного удобнее, когда одного взгляда достаточно, чтобы определить тип переменной, чем сначала искать, где она определена... Это нужно, в первую очередь, Вам самому и, естественно, тем программистам, которые позже будут разбираться в Вашем коде... И если в ЯВУ компиляторы проверяют типы переменных, то в Ассемблере вся проверка типов целиком лежит на программисте... Почему бы не облегчить хоть чуть-чуть себе жизнь?
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
15.12.2009, 11:52
общий
это ответ
Здравствуйте, Masada.
1. "DriverEntry закомментирована в начале кода" DriverEntry - имя процедуры оно не закомментированно
2. это не передача параметров, а описание параметров функции
3. это разные вещи proc - директива это описание функции, invoke - директива вызова
4. "венгерская нотация" буква перед именем указывающая на тип
pDriverObject - pointer указатель на объект типа DRIVER_OBJECT
pusRegistryPath - pointer unicode string - думаю смысл ясен
давно
Старший Модератор
31795
6196
15.12.2009, 13:14
общий
Masada:
Цитата: 127543
это одно и то же, что и:

Да.

Цитата: 127543
По вопросу три: а смысл описывать функцию, не предполагая её вызова?Думаю, что вызов всё же предполагается, но не пойму, где. И всё равно должен же быть эквивалент строке:

Вы пишете Драйвер, он будет вызыватся из другого места системой или другой программой.
Да, такой эквивалент есть.
метка proc язык тип USES регистры ; TASM
или
метка proc тип язык USES регистры ; MASM/WASM
...
ret
метка endp
Все операнды PROC необязательны.
USES — список регистров, значения которых изменяет процедура. Ассемблер помещает в начало процедуры набор команд PUSH, а перед командой RET — набор команд POP, так что значения перечисленных регистров будут восстановлены.

Эта информация для 16-битного компилятора, для 32-х битных, аналогично формируется стандарная точка входа и выхода для этого драйвера.
Посмотрите на результат компилирования кода
Код:
dlgproc proc hWin:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD
.if uMsg == WM_COMMAND
.if wParam == IDCANCEL
jmp dlg_end
.endif

Код:
.text:0040116E ; BOOL __stdcall DialogFunc(HWND,UINT,WPARAM,LPARAM)
.text:0040116E DialogFunc proc near
.text:0040116E
.text:0040116E hDlg = dword ptr 8
.text:0040116E arg_4 = dword ptr 0Ch
.text:0040116E arg_8 = dword ptr 10h
.text:0040116E push ebp
.text:0040116F mov ebp, esp
.text:00401171 cmp [ebp+arg_4], 111h;это мой комментарий:WM_COMMAND equ 111h
.text:00401178 jnz short loc_401184
.text:0040117A cmp [ebp+arg_8], 2;это тоже мой комментарий: IDCANCEL equ 2
.text:0040117E jnz short loc_401194

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

Цитата: 127543
обязательно ли соблюдение "венгерской нотации", т.е. добавление p и pus. Microsoft же не соблюдает, зачем тогда и нам соблюдать?

Нет, необязательно, но должны же мы чем-то отличатся от программистов Microsoft, которые даже в основных библиотеках gdi32, kernel32 и user32 нарушают правила работы со стеком и это не говоря о какой-то "венгерской нотации".
После нас, другие программисты легко разберутся в коде и документации, а не будут считать и сушить байты.
Удачи!
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

Неизвестный
15.12.2009, 14:44
общий
Спасибо, становится яснее!
Драйвер запускается из .exe-программы с помощью функции StartService, например:
invoke StartService, hService, 0, NULL. Это понятно. В hService находится строка с полным путем к файлу драйвера, именно потому StartService знает, что нужно передать управление DriverEntry, а не чему-то иному?
Ещё один непредвиденный вопрос возник, возможно, глупый, но он об удалении драйвера из системы в связи с «возможностью ошибиться на какой-то байтик». Если в драйвер дописать
mov al, 0FEh
out 64h, al
то произойдёт перезагрузка системы, а если дописать в .exe-программе автозагрузку, то ОС постоянно будет перезагружаться. Как удалить в таком случае драйвер? Сделать загрузку с дискеты, а что на дискету записать: Norton, Hiew или что-то другое? И как в реестр попасть. В ОС всё просто, через regedit.
Неизвестный
15.12.2009, 14:54
общий
помоему hService это не строка, это дескриптор и что бы его получить нужно еще повызывать функции API
давно
Посетитель
7438
7205
15.12.2009, 15:16
общий
Да, надо сначала вызвать OpenSCManager, чтобы подключиться к базе сервисов (получить handle of service control manager database).
Затем, надо создать сервис CreateService, получив handle сервиса (здесь одним из параметров - путь с именем файла)
А уж потом его запускать...

Например, можно загрузиться в Safe Mode... Он для того и сделан, чтобы не грузить ничего лишнего.
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Старший Модератор
31795
6196
15.12.2009, 15:27
общий
Masada:
Цитата: описание функции
BOOL StartService(
SC_HANDLE hService, // handle of service
DWORD dwNumServiceArgs, // number of arguments
LPCTSTR *lpServiceArgVectors // address of array of argument string pointers
);
Parameters:
hService - Identifies the service. This handle is returned by the OpenService or CreateService function, and it must have SERVICE_START access.
dwNumServiceArgs - Specifies the number of argument strings in the lpServiceArgVectors array. If lpServiceArgVectors is NULL, this parameter can be zero.
lpServiceArgVectors - Points to an array of pointers that point to null-terminated argument strings passed to a service. Driver services do not receive these arguments. If no arguments are passed to the service being started, this parameter can be NULL. The service accesses these arguments through its ServiceMain function. Note that in the array of arguments passed to the ServiceMain function, the first argument (argv[0]) is the name of the service by default, followed by the arguments, if any, in the lpServiceArgVectors array.

hService - идентифицирует сервис, указатель возвращается функцией OpenService или CreateService и должен иметь SERVICE_START доступ.

Есть несколько режимов старта системы, один из них - пошаговый, где Вы указываете запустить или нет сервис (службу) .
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

Неизвестный
15.12.2009, 16:29
общий
Спасибо! Читаю, разбираюсь.
В .exe-программе поочерёдно вызываются OpenSCManager, GetFullPathName, CreateService, StartService, … , просто мои вопросы не о них были. Но в связи с функциями:
«Вызов StartService синхронный. Это значит, что она не вернет управление до тех пор, пока не отработает процедура DriverEntry в драйвере. Если инициализация драйвера прошла успешно, DriverEntry вернет STATUS_SUCCESS, а функция StartService вернет значение отличное от нуля».
Я так понимаю, возвращаемые значения нужно смотреть в eax, туда функции возвращают свои значения.
"CreateService и должен иметь SERVICE_START доступ" - да, я это понял.
Форма ответа