При запуске драйвера через Atsiv утекает 1G памяти.

Тема в разделе "WASM.BEGINNERS", создана пользователем serj, 5 июн 2009.

  1. serj

    serj New Member

    Публикаций:
    0
    Регистрация:
    27 сен 2005
    Сообщения:
    13
    Я как-то сделал простенький драйвер для x64 на основе примера A05 от FASM Win64 drivers example.
    Вышло кривенько, но работает и (вроде-бы) проблем нет. Точнее небыло, пока сидел на XP x64.
    Пришла Vista/W7 и светлая полоса закончилась. Не очень понравилась игра с сертификатами и решил воспользоваться Atsiv. Драйвер через него стартует нормально, в работе проблем нет ... и тут меня порадовали - при запуске программы куда-то исчезает 1G памяти.
    При запуске моего драйвера через Atsiv (с ключем -f) 'Kernel Memory' возрастает на 1G. Если драйвер снять через Atsiv (с ключем -u), то все возвращается в норму.
    При этом моя программа не запущена. Как оказалось, оригинальный драйвер A05 от FASM страдает той-же болезнью. Если взять какой-нибудь другой драйвер x64 и запустить его через тот-же Atsiv, то такого безобразия нет.
    По своей серости я могу только предположить, что что-то забыли настроить, чего Win сам настраивает, а Atsiv понимает слишком буквально.
    Пожалуйста, помогите поправить ошибку. Очень много 'сразу непонятного' - и формат драйвера и передача параметров х64, да и сам FASM 'очень облегчает жизнь' после MASM.

    Драйвер A05 не очень большой, не будете возражать, если я выложу его код?
    Код (Text):
    1. format PE64 native 5.02 at 10000h
    2. entry start
    3.  
    4.  
    5. include 'a05.inc'
    6. include 'KMD64.inc'
    7.  
    8.  
    9. section '.text' code readable executable notpageable
    10.  
    11. start:
    12. ; lpDriverObject, lpusRegistryPath
    13. ; rcx=pDriverObject rdx=pDriverPath
    14.  
    15.     push    rbx
    16.     sub rsp,8*(4+8)     ; reserve 12 qwords on the stack, 8 for us
    17.                     ; Low 4 qwords may be destroyed by API, we can't use them
    18. ; RSP is now aligned 16
    19.     lea rbx,[rcx]       ; Save RCX to RBX. RBX is protected against destroing by API.
    20.  
    21.     ; load structure to point to IRP handlers
    22. virtual at 0
    23. DriverObject    DRIVER_OBJECT
    24. end virtual
    25.     lea rax,[DriverUnload]
    26.     mov qword [rbx + DriverObject.DriverUnload],rax
    27.  
    28.     lea rax,[DispatchCreateClose]
    29.     mov qword [rbx + DriverObject.MajorFunction + IRP_MJ_CREATE_OFFSET],rax
    30.     mov qword [rbx + DriverObject.MajorFunction + IRP_MJ_CLOSE_OFFSET],rax
    31.  
    32.     lea rax,[DispatchWrite]
    33.     mov qword [rbx + DriverObject.MajorFunction + IRP_MJ_WRITE_OFFSET],rax
    34.  
    35.     lea rdx,[cusDevice_string]
    36.     lea rcx,[rsp+8*(4+4)]   ; use 2 quadwords reserved on the stack
    37.     call    qword [RtlInitUnicodeString]
    38.  
    39.     ; create and initialize device object
    40.     lea rax,[rsp+8*(4+3)]   ; 1 quadword for [DeviceObject] - we use stack for it
    41.     mov qword [rsp+8*(4+2)],rax ; pass address for [DeviceObject] - 7th arg to the API
    42.     xor eax,eax         ; zeroing rax
    43.     mov qword [rsp+8*(4+1)],rax ; false -> rax = 0
    44.     mov qword [rsp+8*(4+0)],rax ; 5th arg for API
    45.     mov r9d,FILE_DEVICE_UNKNOWN ; 4th arg for API
    46.     lea r8,[rsp+8*(4+4)]    ; [rsp+8*(4+4)] created by RtlInitUnicodeString
    47.     xor edx,edx         ; AMD64 zero extend this xor to rdx
    48.     lea rcx,[rbx]       ; lpDriverObject - 1st arg for API
    49.     call    qword [IoCreateDevice]
    50. if STATUS_SUCCESS = 0
    51.     or  eax,eax         ; 2 bytes opcode - smaller than cmp eax,0
    52. else
    53.     cmp eax,STATUS_SUCCESS
    54. end if
    55.     jnz driver_return       ; break on error
    56.  
    57.     ; create symbolic link to the user-visible name
    58.     lea rdx,[cusSymbolicLink_string]
    59.     lea rcx,[rsp+8*(4+6)]   ; use 2 quadwords reserved on the stack
    60.     call    qword [RtlInitUnicodeString]
    61.  
    62.     lea rdx,[rsp+8*(4+4)]   ; 2nd arg for API
    63.     lea rcx,[rsp+8*(4+6)]   ; 1st arg for API
    64.     call    qword [IoCreateSymbolicLink]
    65.  
    66. if STATUS_SUCCESS = 0
    67.     or  eax,eax
    68. else
    69.     cmp eax,STATUS_SUCCESS
    70. end if
    71.     jz  driver_return
    72.  
    73.     ; save status
    74.     xchg    ebx,eax         ; 1 byte opcode, smaller than 2 byte opcode for mov ebx,eax
    75.  
    76.     ; unsuccess, delete device object
    77.     mov rcx,qword [rsp+8*(4+3)] ; 1 quadword for [DeviceObject] - we use stack for it
    78.                     ; qword is filled when call IoCreateDevice
    79.     call    qword [IoDeleteDevice]
    80.  
    81.     ; assign result
    82.     xchg    ebx,eax
    83.  
    84. driver_return:
    85.     add rsp,8*(4+8)
    86.     pop rbx
    87.     ret
    88.  
    89. align 10h
    90. DriverUnload:
    91. ;proc DriverUnload lpDriverObject
    92. ; rcx = lpDriverObject
    93.     push    rbx
    94.     sub rsp,8*(4+2)         ; reserve 6 qwords on the stack, top 2 qword can be used, low 4 qwords may be destroyed because API can use them.
    95.     lea rbx,[rcx]
    96.     lea rdx,[cusSymbolicLink_string]
    97.     lea rcx,[rsp+8*(4+0)]       ; need 2 quadwords reserved
    98.     call    qword [RtlInitUnicodeString]
    99.     lea rcx,[rsp+8*(4+0)]
    100.     call    qword [IoDeleteSymbolicLink]
    101.     mov rcx,[rbx + DriverObject.DeviceObject]
    102.     call    qword [IoDeleteDevice]
    103.     add rsp,8*(4+2)
    104.     pop rbx
    105.     ret
    106.  
    107. align 10h
    108. DispatchCreateClose:
    109. ;proc DispatchCreateClose pDeviceObject, lpIrp
    110. ; rcx = pDeviceObject , rdx = lpIrp
    111.     sub rsp,8*(4+1)         ; align 16 stack
    112. virtual at 0
    113. vIRP    IRP
    114. end virtual
    115.  
    116.     xor eax,eax
    117. if STATUS_SUCCESS = 0
    118.     mov dword [rdx + vIRP.IoStatus.Status],eax
    119. else
    120.     mov dword [rdx + vIRP.IoStatus.Status],STATUS_SUCCESS
    121. end if
    122.     mov qword [rdx + vIRP.IoStatus.Information],rax
    123.     lea rcx,[rdx]
    124. if IO_NO_INCREMENT=0
    125.     xor edx,edx
    126. else
    127.     mov edx,IO_NO_INCREMENT
    128. end if
    129.     call    qword [IofCompleteRequest]
    130. if STATUS_SUCCESS=0
    131.     xor eax,eax
    132. else
    133.     mov eax,STATUS_SUCCESS
    134. end if
    135.     add rsp,8*(4+1)
    136.     ret
    137.  
    138. align 10h
    139. DispatchWrite:
    140. ; function called when write to the device
    141. ;proc DispatchWrite lpDeviceObject, lpIrp
    142. ; rcx = lpDeviceObject , rdx = lpIrp
    143.     push    rbp
    144.     push    rsi
    145.     push    rdi
    146.     push    rcx
    147.     push    rdx
    148.     push    rbx
    149.     push    r8
    150.     push    r9
    151.     push    r10
    152.     push    r11
    153.     push    r12
    154.     push    r13
    155.     push    r14
    156.     push    r15
    157. ; we protect so much registers because calling routine in user-mode application may destroy them
    158.     sub rsp,8*(4+1)     ; stack is now aligned 16
    159.  
    160.     mov ebx,STATUS_UNSUCCESSFUL     ; rbx : current status
    161.     lea rdi,[rdx]           ; rdi = lpIrp = PIRP
    162.  
    163. ;   lea rcx,[rdx]
    164. ;   call    qword [IoIs32bitProcess]
    165. ;   cmp al,1                ; 0 = 64 bit process, 1 = 32 bit process (aka WOW64)
    166. ;   jz  compactibility_32_bit_process
    167. ; not necessary for our purposed, maybe for another driver...
    168.  
    169.     xor eax,eax
    170.     mov [rdi + vIRP.IoStatus.Information],rax
    171.  
    172.     mov rsi, [rdi + vIRP.Tail.Overlay.CurrentStackLocation]
    173.  
    174. ; word [rsi] must contain IRP_MJ_WRITE = 4
    175. ; But we don't check this because we are sure on DispatchWrite procedure.
    176. ; Usefull for branch if one procedure handle more functions, e.g. Write and Read from driver.
    177.  
    178. ; structure used by driver to comunicate with write_device.exe
    179. virtual at 0
    180. a05dq   A05DriverQuery
    181. end virtual
    182.  
    183. virtual at 0
    184. iosl    IO_STACK_LOCATION
    185. end virtual
    186.  
    187.     cmp [rsi + iosl.Parameters.Write.Length],size_of_A05DriverQuery;size_of_A05DriverQuery
    188.     jnz egzyduz         ; number of bytes written to device match or differ ?
    189.  
    190. ; get address of DriverQuery
    191.     mov rsi,[rdi + vIRP.UserBuffer] ; PDriverQuery
    192.  
    193. ; assume we have failed until we don't have success
    194.     mov ebx,STATUS_NOT_IMPLEMENTED
    195.  
    196. ; get iocode from DriverQuery
    197.     mov eax,[rsi + a05dq.iocode]    ; eax : user I/O code
    198.     cmp eax,DRIVER_QUERY_PROC_NOARGS
    199.     jz  proc_noargs
    200.     cmp eax,DRIVER_QUERY_PROC_STDCALL
    201.     jz  proc_stdcall
    202.     cmp eax,DRIVER_QUERY_PORT_IN_BYTE
    203.     jz  port_in_byte
    204.     cmp eax,DRIVER_QUERY_PORT_IN_WORD
    205.     jz  port_in_word
    206.     cmp eax,DRIVER_QUERY_PORT_IN_DWORD
    207.     jz  port_in_dword
    208.     cmp eax,DRIVER_QUERY_PORT_OUT_BYTE
    209.     jz  port_out_byte
    210.     cmp eax,DRIVER_QUERY_PORT_OUT_WORD
    211.     jz  port_out_word
    212.     cmp eax,DRIVER_QUERY_PORT_OUT_DWORD
    213.     jz  port_out_dword
    214.     jmp egzyduz
    215.  
    216. proc_noargs:
    217. ; call a procedure from user program with privileged instructions without params
    218.     call    qword [rsi + a05dq.wparam]
    219.     jmp egzyduz_STATUS_SUCCESS
    220.  
    221. proc_stdcall:
    222. ; get argument for procedure
    223.     mov rcx,qword [rsi + a05dq.lparam]
    224. ; call a procedure from user program
    225.     call    qword [rsi + a05dq.wparam]
    226. ; call procedure may destroy regs !!! we will handle it at egzyduz
    227.     jmp egzyduz_STATUS_SUCCESS
    228.  
    229. port_in_byte:
    230. ; read from a port is ring0 privileged instruction so allowed to be executed by win64 driver
    231.     mov edx,dword [rsi + a05dq.wparam]
    232.     in  al,dx
    233. ; We save value readed from port to a DriverQuery.lparam
    234.     mov dword [rsi + a05dq.lparam],eax
    235.     jmp egzyduz_STATUS_SUCCESS
    236.  
    237. port_in_word:
    238. ; get port number from DriverQuery
    239.     mov edx,dword [rsi + a05dq.wparam]
    240.     in  ax,dx
    241.     mov dword [rsi + a05dq.lparam],eax
    242.     jmp egzyduz_STATUS_SUCCESS
    243.  
    244. port_in_dword:
    245.     mov edx,dword [rsi + a05dq.wparam]
    246.     in  eax,dx
    247.     mov dword [rsi + a05dq.lparam],eax
    248.     jmp egzyduz_STATUS_SUCCESS
    249.  
    250. port_out_byte:
    251.     mov edx,dword [rsi + a05dq.wparam]
    252.     mov eax,dword [rsi + a05dq.lparam]
    253.     out dx,al
    254.     jmp egzyduz_STATUS_SUCCESS
    255.  
    256. port_out_word:
    257.     mov edx,dword [rsi + a05dq.wparam]
    258.     mov eax,dword [rsi + a05dq.lparam]
    259.     out dx,ax
    260.     jmp egzyduz_STATUS_SUCCESS
    261.  
    262. port_out_dword:
    263.     mov edx,dword [rsi + a05dq.wparam]
    264.     mov eax,dword [rsi + a05dq.lparam]
    265.     out dx,eax
    266. egzyduz_STATUS_SUCCESS:
    267. if STATUS_SUCCESS = 0
    268.     xor ebx,ebx
    269. else
    270.     mov ebx,STATUS_SUCCESS
    271. end if
    272.  
    273. egzyduz:
    274.     mov rdi,qword [rsp + 8*(4+1+9)] ; restore rdi=lpIrp in case call qword [rsi + 8] destroy rdi register
    275.                         ; lpIrp was saved in stack when push rdx
    276.     mov dword [rdi + vIRP.IoStatus.Status], ebx
    277.  
    278. if IO_NO_INCREMENT=0
    279.     xor edx,edx
    280. else
    281.     mov edx,IO_NO_INCREMENT
    282. end if
    283.     lea rcx,[rdi]       ; lpIrp
    284.     call    qword [IofCompleteRequest]
    285.  
    286.     xchg    ebx,eax         ; put result to eax e.g. STATUS_SUCCESS
    287.  
    288.     add rsp,8*(4+1)
    289.     pop r15
    290.     pop r14
    291.     pop r13
    292.     pop r12
    293.     pop r11
    294.     pop r10
    295.     pop r9
    296.     pop r8
    297.     pop rbx
    298.     pop rdx
    299.     pop rcx
    300.     pop rdi
    301.     pop rsi
    302.     pop rbp
    303.     ret
    304.  
    305. ;compactibility_32_bit_process:
    306. ;   jmp ...
    307.  
    308.  
    309. align 10h
    310. cusDevice_string    du  '\Device\a05',0
    311.  
    312. align 10h
    313. cusSymbolicLink_string  du  '\DosDevices\a05',0
    314.  
    315.  
    316. section '.rdata' readable notpageable  
    317.  
    318. data 12  
    319.  
    320. ImportLookup:  
    321. RtlInitUnicodeString    dq  rva szRtlInitUnicodeString
    322. IoCreateDevice      dq  rva szIoCreateDevice
    323. IoCreateSymbolicLink    dq  rva szIoCreateSymbolicLink
    324. IoDeleteDevice      dq  rva szIoDeleteDevice
    325. IoDeleteSymbolicLink    dq  rva szIoDeleteSymbolicLink
    326. IofCompleteRequest  dq  rva szIofCompleteRequest
    327. ;IoIs32bitProcess   dq  rva szIoIs32bitProcess
    328.             dq  0
    329.  
    330. end data
    331.  
    332.  
    333. section 'INIT' data import readable notpageable
    334.  
    335.             dd  rva ImportAddress
    336.             dd  0
    337.             dd  0
    338.             dd  rva szntoskrnl
    339.             dd  rva ImportLookup
    340.         times 5 dd  0
    341.  
    342. ImportAddress       dq  rva szRtlInitUnicodeString
    343.             dq  rva szIoCreateDevice
    344.             dq  rva szIoCreateSymbolicLink
    345.             dq  rva szIoDeleteDevice
    346.             dq  rva szIoDeleteSymbolicLink
    347.             dq  rva szIofCompleteRequest
    348. ;           dq  rva szIoIs32bitProcess
    349.             dq  0
    350.  
    351. szRtlInitUnicodeString  dw  0
    352.             db  'RtlInitUnicodeString',0
    353. szIoCreateDevice    dw  0
    354.             db  'IoCreateDevice',0
    355. szIoCreateSymbolicLink  dw  0
    356.             db  'IoCreateSymbolicLink',0
    357. szIoDeleteDevice    dw  0
    358.             db  'IoDeleteDevice',0
    359. szIoDeleteSymbolicLink  dw  0
    360.             db  'IoDeleteSymbolicLink',0
    361. szIofCompleteRequest    dw  0
    362.             db  'IofCompleteRequest',0
    363. ;szIoIs32bitProcess dw  0
    364. ;           db  'IoIs32bitProcess',0
    365.  
    366. szntoskrnl      db  'ntoskrnl.exe',0
     
  2. serj

    serj New Member

    Публикаций:
    0
    Регистрация:
    27 сен 2005
    Сообщения:
    13
    Никаких мыслей нет? Жаль. :dntknw: При моем 'опыте' отладки х64 драйверов эта проблема может кончится печально. Ну чтож, пойду в IDAG64.

    Может подскажете какой инструмент, чтоб посмотреть ресурсы, которые потребляет драйвер?
    Я посмотрел, но как-то ничего осмысленного программы не сообщают.
     
  3. Jupiter

    Jupiter Jupiter

    Публикаций:
    0
    Регистрация:
    12 авг 2004
    Сообщения:
    532
    Адрес:
    Russia
    не майся с астивом и подписывай своим доверенным сертификатом
     
  4. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    поставь бряк на DirverEntry, и погляди в какой момент происходит этот скачек, сразу же после загрузки, или после выполнения какой-то API?
     
  5. serj

    serj New Member

    Публикаций:
    0
    Регистрация:
    27 сен 2005
    Сообщения:
    13
    n0name, спасибо за совет. Но для меня это сложно.
    Пробовал несколько иначе - взял драйвер, который нормально запускается через Atsiv и переносил его фрагменты инициализации в свой драйвер. Первая попытка кончилась предсказуемо, никакой реакции. Как был +1G, так и осталось.
    Закралась глупая мысль, что что-то нехорошее в PE заголовке и Atsiv радостно считает файл драйвера 'ну очень большим', но ничего странного в PE я не углядел. Да и создается PE не руками.

    Спасибо! Извините, что побеспокоил.
    Скорее всего, вопрос откладывается на потом.
     
  6. serj

    serj New Member

    Публикаций:
    0
    Регистрация:
    27 сен 2005
    Сообщения:
    13
    Очень уж нехотелось писать программу, полез в драйвер.
    Разбор atsiv.exe и его трассировка ничего умного не дало, 'выброс' памяти происходил при выдачи запроса в его драйвер на загрузку моего. Полез в егоный драйвер и как-то сразу насторожила деятельность с загрузкой файла. Если есть проблемы с секцией, то должны быть проблемы с памятью. А у меня 'драйвер' и секции ресурсов нет. О?
    Добавляю эту секцию и 'о чудо', драйвер загрузился нормально без '+1G' ..... мда.
     
  7. at0s

    at0s New Member

    Публикаций:
    0
    Регистрация:
    13 июл 2009
    Сообщения:
    91
    serj
    нужен atsiv или его заменитель, Гугл выдает только несуществуюшие ссылки, на родном сайте вместо него Rainbar подсовывают. Скиньте или ссылочку дайте
    спс