Page 1 of 3

Написание драйвера.

Posted: Tue Jun 07, 2011 3:52 pm
by popovpa
Здравствуйте!

Пишу драйвер, и возник вопрос, что значит вот этот код, что он делает, и можно ли обойтись без макросов?

proc START stdcall, state:dword

Re: Написание драйвера.

Posted: Tue Jun 07, 2011 4:06 pm
by CleverMouse
Это оформление процедуры с конвенцией вызова stdcall. Без макросов обойтись можно всегда.
Код

Code: Select all

proc START stdcall,state:dword
mov eax,[state]
ret
endp
раскрывается примерно в

Code: Select all

START:
push ebp
mov ebp,esp
mov eax,[ebp+8]
pop ebp
ret 4
Естественно, при ручном написании можно обойтись без ebp, адресуя параметры через esp, но если таких адресаций больше четырёх, то это оказывается невыгодным по размеру - адресация через esp на байт длиннее.

Re: Написание драйвера.

Posted: Tue Jun 07, 2011 6:40 pm
by popovpa
Спасибо! Стало чуть понятней. Но вот вопрос, зачем это нужно, это именно особенность работы драйвера в 0 кольце? Или мне ещё что-то почитать "глубинное" нужно? :)

Re: Написание драйвера.

Posted: Tue Jun 07, 2011 6:50 pm
by mike.dld
Почитать можно это: http://en.wikipedia.org/wiki/Function_prologue
Не искал, но должно быть что-то и на русском.

Re: Написание драйвера.

Posted: Tue Jun 07, 2011 7:20 pm
by b00bl1k
popovpa wrote:Но вот вопрос, зачем это нужно, это именно особенность работы драйвера в 0 кольце?
Это необходимо, ибо ядро использует вызов stdcall и передает параметр state через стек (core\dll.inc):

Code: Select all

mov ebx, [start]
stdcall ebx, DRV_ENTRY 
как написала CleverMouse можно и вручную получить параметр state, но через макрос удобнее и нагляднее.

Re: Написание драйвера.

Posted: Wed Jun 08, 2011 8:07 am
by Serge

Re: Написание драйвера.

Posted: Wed Jun 08, 2011 8:50 pm
by popovpa
Всем большое спасибо! Почти разобрался, но у меня обычно этот процесс затянутый...озаряет через неделю не раньше...ещё вопрос появился, не понял как осуществить без макроса вот этот вызов:

stdcall RegService, my_service, service_proc

И ещё вопросик, я компилирую драйвер, кладу его в ../driver, а как операционная система осуществит загрузку моего драйвера? она сканирует папку и загружает от туда всё подряд или где-то как то надо прописать вызов моего драйвера?

Re: Написание драйвера.

Posted: Wed Jun 08, 2011 8:56 pm
by CleverMouse
popovpa, этот код раскрывается в

Code: Select all

push service_proc
push my_service
call RegService
Папка с драйверами называется drivers. Ядро никаких массовых запусков из папок не ведёт, а драйвера загружает только по команде - это может быть либо вызов функции 68.16 из приложения, либо вызов stdcall load_driver, <string with driver name> изнутри ядра. Я надеюсь, во что раскрывается этот вызов, уже понятно.

Re: Написание драйвера.

Posted: Wed Jun 08, 2011 8:59 pm
by popovpa
Немного не так спросил видимо, я имею ввиду что без подключения вот этих файлов:

include 'proc32.inc'
include 'imports.inc'

Нельзя будет сделать этот вызов? Если только полностью в драйвер не переносить код RegService?

Re: Написание драйвера.

Posted: Wed Jun 08, 2011 9:01 pm
by CleverMouse
proc32.inc нужен для макроса stdcall. imports.inc объявляет все используемые функции ядра, применительно к RegService это эквивалентно

Code: Select all

extrn RegService

Re: Написание драйвера.

Posted: Sat Jun 11, 2011 7:17 pm
by popovpa
Здравствуйте!

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

Вот код:

Code: Select all

format MS COFF

include 'imports.inc'

struc IOCTL
{  .handle	dd ?
   .io_code	dd ?
   .input	dd ?
   .inp_size	dd ?
   .output	dd ?
   .out_size	dd ?
}

virtual at 0
  IOCTL IOCTL
end virtual

section '.flat' code readable align 16

START:
	push 	ebp
	mov ebp,esp
	mov	eax,[esp+8]
	cmp	eax,1
	pop	ebp

	ret	4
Запуская вот так:

Code: Select all

use32              ; включить 32-битный режим ассемблера
  org    0x0         ; адресация с нуля

  db     'MENUET01'  ; 8-байтный идентификатор MenuetOS
  dd     0x01        ; версия заголовка (всегда 1)
  dd     START       ; адрес первой команды
  dd     I_END       ; размер программы
  dd     0x1000      ; количество памяти
  dd     0x1000      ; адрес вершины стэка
  dd     0x0         ; адрес буфера для параметров (не используется)
  dd     0x0         ; зарезервировано

START:
mov eax,68
mov ebx,16
mov ecx,bcm
int 0x40

bcm db	'bcm4312',0

I_END:
Доска отладки показала вот это:

Code: Select all

in module bcm4312
K : Process - forced terminate PID: 00000039
K : Undefined Exception
K : EAX : 00000000 EBX : 00000010 ECX : 00000035
K : EDX : 00000000 ESI : 00000000 EDI : 00000000
K : EBP : 00000000 EIP : 00000035 ESP : 00001000
K : Flags : 00011202 CS : 0000001B (application)
Видимо что-то пошло не так...и я не очень понимаю что...что самое обидное...

Re: Написание драйвера.

Posted: Sun Jun 12, 2011 7:52 am
by Serge

Code: Select all

START:
mov eax,68
mov ebx,16
mov ecx,bcm
int 0x40

после этой команды код заканчивается и процессор начинает выполнять данные.

bcm db   'bcm4312',0

Re: Написание драйвера.

Posted: Sun Jun 12, 2011 7:56 am
by popovpa
Спасибо большое...да моя невнимательность...нельзя в программировании кусочничать...сел программировать, так и не чего работай человека отвлекать :)

Re: Написание драйвера.

Posted: Tue Jun 14, 2011 7:24 pm
by popovpa
Здравствуйте!

Продолжаю разбираться дальше. Вот 2 кода, один урезанный пример из помощи, второй немного переработанный без макросов, ни один не выводит надписи на доску отладки. Выводит только это: "in module bcm4312, или in module test но это показывает что отработала функция 68 подфункция 16. Подскажите, пожалуйста, что не так?
Spoiler:1. с макросами.

Code: Select all

format MS COFF

include 'proc32.inc'
include 'imports.inc'

;OS_BASE 	equ 0;
;new_app_base	equ 0x80000000

struc IOCTL
{  .handle	dd ?
   .io_code	dd ?
   .input	dd ?
   .inp_size	dd ?
   .output	dd ?
   .out_size	dd ?
}

virtual at 0
  IOCTL IOCTL
end virtual

public START
;public version

DRV_ENTRY  equ 1
DRV_EXIT   equ -1

section '.flat' code readable align 16

proc START stdcall, state:dword

	   cmp [state], DRV_ENTRY
	   jne .exit

	mov	esi,msgStart
	call	SysMsgBoardStr

.entry:
	   stdcall RegService, my_service, service_proc
	   ret

.exit:

	mov	esi,msgBad
	call	SysMsgBoardStr

	   xor eax, eax
	   ret
endp

handle	   equ	IOCTL.handle
io_code    equ	IOCTL.io_code
input	   equ	IOCTL.input
inp_size   equ	IOCTL.inp_size
output	   equ	IOCTL.output
out_size   equ	IOCTL.out_size

proc service_proc stdcall, ioctl:dword

	mov	esi,msgProc
	call	SysMsgBoardStr


	mov	edi, [ioctl]
	mov	eax, [edi+io_code]

	xor	eax, eax
	ret
endp

version 	dd	0x50005
my_service	db	'test',0

section '.data' data readable writable align 16

msgStart db 'Start...',0
msgProc db 'Proc...',0
msgBad db 'Bad...',0
Spoiler:2. Без макросов

Code: Select all

format MS COFF

include 'proc32.inc'
include 'imports.inc'


section '.flat' code readable align 16

	push	ebp
	mov	ebp,esp
	mov	eax,[ebp+8]

	cmp	eax,1
	jnz	.exit

	mov	esi, msgStart
	call	SysMsgBoardStr

	push	 service_proc
	push	 my_service
	call	RegService

.exit:
	mov	esi, msgBad
	call	SysMsgBoardStr

	pop	ebp
	ret	4

service_proc:

	push	ebp
	mov	ebp,esp
	mov	edi,[ebp+8]
	mov	eax,[edi+4]

	mov	esi, msgProc
	call	SysMsgBoardStr

	pop	ebp
	ret	4

version 	dd	0x50005
my_service	db	'bcm4312',0

section '.data' data readable writable align 16

msgStart db 'Start...',0
msgProc db 'Proc...',0
msgBad db 'Bad...',0
Запускаю вот так:

Code: Select all

use32		   ; включить 32-битный режим ассемблера
  org	 0x0	     ; адресация с нуля

  db	 'MENUET01'  ; 8-байтный идентификатор MenuetOS
  dd	 0x01	     ; версия заголовка (всегда 1)
  dd	 START	     ; адрес первой команды
  dd	 I_END	     ; размер программы
  dd	 0x1000      ; количество памяти
  dd	 0x1000      ; адрес вершины стэка
  dd	 0x0	     ; адрес буфера для параметров (не используется)
  dd	 0x0	     ; зарезервировано

START:
mov eax,68
mov ebx,16
mov ecx,bcm
int 0x40

mov eax,-1
int 0x40

I_END:

bcm db	'bcm4312',0

Re: Написание драйвера.

Posted: Tue Jun 14, 2011 7:44 pm
by SoUrcerer
А откуда берется SysMsgBoardStr? У меня в proc32.inc и imports.inc не определен.