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

Assembler programming questions
  • Это оформление процедуры с конвенцией вызова 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 на байт длиннее.
    Сделаем мир лучше!
  • Спасибо! Стало чуть понятней. Но вот вопрос, зачем это нужно, это именно особенность работы драйвера в 0 кольце? Или мне ещё что-то почитать "глубинное" нужно? :)
  • Почитать можно это: http://en.wikipedia.org/wiki/Function_prologue
    Не искал, но должно быть что-то и на русском.
    in code we trust
  • popovpa wrote:Но вот вопрос, зачем это нужно, это именно особенность работы драйвера в 0 кольце?
    Это необходимо, ибо ядро использует вызов stdcall и передает параметр state через стек (core\dll.inc):

    Code: Select all

    mov ebx, [start]
    stdcall ebx, DRV_ENTRY 
    
    как написала CleverMouse можно и вручную получить параметр state, но через макрос удобнее и нагляднее.
  • Всем большое спасибо! Почти разобрался, но у меня обычно этот процесс затянутый...озаряет через неделю не раньше...ещё вопрос появился, не понял как осуществить без макроса вот этот вызов:

    stdcall RegService, my_service, service_proc

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

    Code: Select all

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

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

    Нельзя будет сделать этот вызов? Если только полностью в драйвер не переносить код RegService?
  • proc32.inc нужен для макроса stdcall. imports.inc объявляет все используемые функции ядра, применительно к RegService это эквивалентно

    Code: Select all

    extrn RegService
    
    Сделаем мир лучше!
  • Здравствуйте!

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

    Вот код:

    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)
    
    Видимо что-то пошло не так...и я не очень понимаю что...что самое обидное...
  • Code: Select all

    START:
    mov eax,68
    mov ebx,16
    mov ecx,bcm
    int 0x40
    
    после этой команды код заканчивается и процессор начинает выполнять данные.
    
    bcm db   'bcm4312',0
    
  • Спасибо большое...да моя невнимательность...нельзя в программировании кусочничать...сел программировать, так и не чего работай человека отвлекать :)
  • Здравствуйте!

    Продолжаю разбираться дальше. Вот 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
    
  • А откуда берется SysMsgBoardStr? У меня в proc32.inc и imports.inc не определен.
  • Who is online

    Users browsing this forum: No registered users and 1 guest