doskey大牛学习!偶还是菜鸟只好找个驱动软西柿子来捏!
正好前几天中了一堆病毒马马.删除了N个EXE.最后发现驻留了一个SYS.拿了一个最弱的捏!其实直到我把源代码逆出来了为直.因为我这里暂时搞不到完整的Window _KPROCESS结构体.很有有关它的偏移地址给大家就解释不了了,也就是它的主要功能不知道了.以后在说吧!我是菜鸟!!!当一次学习逆向的过程!
大牛别踩!!!

IRP_MJ_CREATE和IRP_MJ_CLOSE,DriverUnload例程很简单可以看下面逆出的C代码。
关键IRP_MJ_DEVICE_CONTROL例程有点复杂和用户层通信.如下:
.text:000103DB ; int __stdcall sub_103DB(PDRIVER_OBJECT DeviceObject,PIRP Irp)
.text:000103DB sub_103DB       proc near               ; DATA XREF: start+5Eo
.text:000103DB
.text:000103DB Information     = dword ptr -8
.text:000103DB ntStatus        = dword ptr -4
.text:000103DB DeviceObject    = dword ptr  8
.text:000103DB Irp             = dword ptr  0Ch
.text:000103DB
.text:000103DB                 push    ebp
.text:000103DC                 mov     ebp, esp
.text:000103DE                 add     esp, 0FFFFFFF8h
.text:000103E1                 push    esi
.text:000103E2                 push    edi
.text:000103E3                 push    ebx
.text:000103E4                 mov     [ebp+Information], 0
.text:000103EB                 mov     [ebp+ntStatus], 0C0000001h
.text:000103F2                 mov     esi, [ebp+Irp]
.text:000103F5                 mov     eax, esi
.text:000103F7                 mov     eax, [eax+60h]  ; IrpStack
.text:000103FA                 mov     edi, eax
.text:000103FC                 mov     eax, [edi+0Ch]
.text:000103FF                 push    edi             ; IrpStack
.text:00010400                 cmp     eax, 22E000h
.text:00010405                 jnz     loc_104C3
.text:00010405
.text:0001040B                 mov     ecx, 34h
.text:00010410                 cmp     [edi+4], ecx
.text:00010413                 jb      loc_104B7
.text:00010413
.text:00010419                 mov     edi, [esi+0Ch]  ; Irp->AssociatedIrp.SystemBuffer
.text:0001041C                 push    edi             ; VirtualAddress
.text:0001041D                 call    MmIsAddressValid
.text:0001041D
.text:00010422                 test    al, al
.text:00010424                 jz      loc_10547
.text:00010424
.text:0001042A                 mov     esi, [edi]
.text:0001042C                 movzx   eax, byte ptr [edi+4]
.text:00010430                 movzx   edx, byte ptr [edi+5]
.text:00010434                 mov     VarA, eax
.text:00010439                 mov     VarB, edx
.text:0001043F                 push    esi             ; VirtualAddress__PUnKownData
.text:00010440                 call    MmIsAddressValid ; XXXXXXXXXXXXXXXXX
.text:00010440
.text:00010445                 test    al, al
.text:00010447                 jz      loc_10547
.text:00010447
.text:0001044D                 mov     ecx, 34h
.text:00010452                 push    esi             ; PUnKownData
.text:00010453                 push    edi             ; inBuf
.text:00010454                 rep movsb
.text:00010456                 pop     edi             ; inBuf
.text:00010457                 pop     esi             ; PUnKownData
.text:00010458                 mov     esi, [edi+24h]
.text:0001045B                 cmp     esi, 0FFFFFFFFh
.text:0001045E                 jz      short loc_104A1
.text:0001045E
.text:00010460                 mov     ebx, [edi+8]
.text:00010463                 mov     ebx, [ebx]
.text:00010465                 mov     ecx, UnKnowVariable_1
.text:0001046B                 mov     ebx, [ecx+ebx]
.text:0001046E                 push    ebx             ; VirtualAddress
.text:0001046F                 call    MmIsAddressValid
.text:0001046F
.text:00010474                 or      al, al
.text:00010476                 jnz     short loc_1047F
.text:00010476
.text:00010478                 mov     esi, 0FFFFFFFFh
.text:0001047D                 jmp     short loc_104A1
.text:0001047D
.text:0001047F ; ---------------------------------------------------------------------------
.text:0001047F
.text:0001047F loc_1047F:                              ; CODE XREF: sub_103DB+9Bj
.text:0001047F                 mov     eax, VarA
.text:00010484                 mov     ebx, [eax+ebx]
.text:00010487                 push    ebx             ; VirtualAddress
.text:00010488                 call    MmIsAddressValid
.text:00010488
.text:0001048D                 or      al, al
.text:0001048F                 jnz     short loc_10498
.text:0001048F
.text:00010491                 mov     esi, 0FFFFFFFFh
.text:00010496                 jmp     short loc_104A1
.text:00010496
.text:00010498 ; ---------------------------------------------------------------------------
.text:00010498
.text:00010498 loc_10498:                              ; CODE XREF: sub_103DB+B4j
.text:00010498                 add     ebx, VarB
.text:0001049E                 mov     esi, [ebx+esi*4]
.text:0001049E
.text:000104A1
.text:000104A1 loc_104A1:                              ; CODE XREF: sub_103DB+83j
.text:000104A1                                         ; sub_103DB+A2j
.text:000104A1                                         ; sub_103DB+BBj
.text:000104A1                 mov     [edi+30h], esi
.text:000104A4                 mov     [ebp+Information], 34h
.text:000104AB                 mov     [ebp+ntStatus], 0
.text:000104B2                 jmp     loc_10547
.text:000104B2
.text:000104B7 ; ---------------------------------------------------------------------------
.text:000104B7
.text:000104B7 loc_104B7:                              ; CODE XREF: sub_103DB+38j
.text:000104B7                 mov     [ebp+ntStatus], 0C0000023h ; STATUS_BUFFER_TOO_SMALL
.text:000104BE                 jmp     loc_10547
.text:000104BE
.text:000104C3 ; ---------------------------------------------------------------------------
.text:000104C3
.text:000104C3 loc_104C3:                              ; CODE XREF: sub_103DB+2Aj
.text:000104C3                 cmp     eax, 22E004h
.text:000104C8                 jnz     short loc_10547
.text:000104C8
.text:000104CA                 cmp     dword ptr [edi+4], 18h
.text:000104CE                 jb      short loc_10540
.text:000104CE
.text:000104D0                 mov     edi, [esi+0Ch]
.text:000104D3                 push    edi             ; VirtualAddress
.text:000104D4                 call    MmIsAddressValid
.text:000104D4
.text:000104D9                 test    al, al
.text:000104DB                 jz      short loc_10547
.text:000104DB
.text:000104DD                 mov     esi, [edi]
.text:000104DF                 push    esi             ; VirtualAddress
.text:000104E0                 call    MmIsAddressValid
.text:000104E0
.text:000104E5                 test    al, al
.text:000104E7                 jz      short loc_10547
.text:000104E7
.text:000104E9                 mov     esi, [esi]
.text:000104EB                 push    esi             ; VirtualAddress
.text:000104EC                 call    MmIsAddressValid
.text:000104EC
.text:000104F1                 test    al, al
.text:000104F3                 jz      short loc_10547
.text:000104F3
.text:000104F5                 push    esi
.text:000104F6                 call    IoThreadToProcess
.text:000104F6
.text:000104FB                 mov     ebx, eax
.text:000104FD                 push    ebx             ; VirtualAddress
.text:000104FE                 call    MmIsAddressValid
.text:000104FE
.text:00010503                 test    al, al
.text:00010505                 jz      short loc_10547 ; xxxxxxxxxxxxx
.text:00010505
.text:00010507                 mov     ecx, UnKnowVariable_2
.text:0001050D                 push    dword ptr [ecx+esi]
.text:00010510                 pop     dword ptr [edi]
.text:00010512                 mov     ecx, UnKnowVariable_3
.text:00010518                 push    dword ptr [ecx+esi]
.text:0001051B                 pop     dword ptr [edi+4]
.text:0001051E                 mov     ecx, 10h
.text:00010523                 mov     esi, UnKnowVariable_4
.text:00010529                 add     esi, ebx
.text:0001052B                 add     edi, 8
.text:0001052E                 rep movsb
.text:00010530                 mov     [ebp+Information], 18h
.text:00010537                 mov     [ebp+ntStatus], 0
.text:0001053E                 jmp     short loc_10547
.text:0001053E
.text:00010540 ; ---------------------------------------------------------------------------
.text:00010540
.text:00010540 loc_10540:                              ; CODE XREF: sub_103DB+F3j
.text:00010540                 mov     [ebp+ntStatus], 0C0000023h
.text:00010540
.text:00010547
.text:00010547 loc_10547:                              ; CODE XREF: sub_103DB+49j
.text:00010547                                         ; sub_103DB+6Cj
.text:00010547                                         ; sub_103DB+D7j
.text:00010547                                         ; sub_103DB+E3j
.text:00010547                                         ; sub_103DB+EDj
.text:00010547                                         ; sub_103DB+100j ...
.text:00010547                 pop     edi             ; IrpStack
.text:00010548                 mov     esi, [ebp+Irp]
.text:0001054B                 push    [ebp+ntStatus]
.text:0001054E                 pop     dword ptr [esi+18h]
.text:00010551                 push    [ebp+Information]
.text:00010554                 pop     dword ptr [esi+1Ch]
.text:00010557                 push    0
.text:00010559                 push    [ebp+Irp]
.text:0001055C                 call    IoCompleteRequest
.text:0001055C
.text:00010561                 mov     eax, [ebp+ntStatus]
.text:00010564                 pop     ebx
.text:00010565                 pop     edi
.text:00010566                 pop     esi
.text:00010567                 leave
.text:00010568                 retn    8
.text:00010568
.text:00010568 sub_103DB       endp
.text:00010568




下面给出所有逆向出来的C源代码:里边用的数据类型很生硬,PVOID指针多处用到我都是根据寄存器和内存的长度才转化成特定的类型的.
#include <ntddk.h>
#include <ntdef.h>

#define  dHook_CtlCode_A  0x22E000
#define  dHook_CtlCode_B  0x22E004

VOID dHookUnloadDriver(
     IN PDRIVER_OBJECT DriverObject);

NTSTATUS dHookCreateClose(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    );

NTSTATUS dHookDeviceControl(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    );
    
NTSYSAPI PEPROCESS NTAPI 
  IoThreadToProcess(
    IN PETHREAD  Thread
    ); 
    
UNICODE_STRING  DeviceNameString;    
UNICODE_STRING  LinkDeviceNameString;
ULONG  UnKnowVariable[4];
NTSTATUS DriverEntry (IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath)
{
   ULONG  MajorVersion;
   ULONG  MinorVersion;
   PDEVICE_OBJECT  deviceObject = NULL; 
   NTSTATUS ntStatus=STATUS_DEVICE_CONFIGURATION_ERROR;
   
   RtlInitUnicodeString( &DeviceNameString,    L"\\Device\\devEnumHook2" );
   RtlInitUnicodeString( &LinkDeviceNameString,L"\\DosDevices\\slEnumHook2");

    
   ntStatus = IoCreateDevice(
                DriverObject,
                0,                     
                &DeviceNameString,
                FILE_DEVICE_DISK_FILE_SYSTEM,//8790H
                FILE_DEVICE_SECURE_OPEN,
                FALSE,
                & deviceObject );

    if (!NT_SUCCESS( ntStatus )) 
    {

        return ntStatus;;
    }

   ntStatus = IoCreateSymbolicLink(
                (PUNICODE_STRING) &LinkDeviceNameString,
                (PUNICODE_STRING) &DeviceNameString
                );

   if (!NT_SUCCESS(ntStatus))
    {
        IoDeleteDevice(deviceObject);
        return ntStatus;;
    }
  
  DriverObject->MajorFunction[IRP_MJ_CREATE] = dHookCreateClose;
  DriverObject->MajorFunction[IRP_MJ_CLOSE] =  dHookCreateClose;
  DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = dHookDeviceControl;
 
  DriverObject->DriverUnload=dHookUnloadDriver;

  PsGetVersion(&MajorVersion,&MinorVersion,NULL,NULL);

  ntStatus=STATUS_SUCCESS;
  
  if(MajorVersion!=5)
   {
      ntStatus=STATUS_DEVICE_CONFIGURATION_ERROR;
      return ntStatus;
   }
   
  if(MinorVersion==0)
   {
          UnKnowVariable[0]=0x22C;//这些常量在dHook_CtlCode_B过程中调用修改Window进程结构_KPROCESS体用的.
          UnKnowVariable[1]=0x124;//具体我这里也没有各个window 的内核_KPROCESS结构体详细文挡.
          UnKnowVariable[2]=0x1E0;
          UnKnowVariable[3]=0x1E4;
          UnKnowVariable[4]=0x1FC;
   }
  else if(MinorVersion==1)
       {
          UnKnowVariable[0]=0x220;
          UnKnowVariable[1]=0x130;
          UnKnowVariable[2]=0x1EC;
          UnKnowVariable[3]=0x1F0;
          UnKnowVariable[4]=0x174;
         
       }
       else if(MinorVersion==2)
         { 
                  
          UnKnowVariable[0]=0x228;
          UnKnowVariable[1]=0x14C;
          UnKnowVariable[2]=0x1F4;
          UnKnowVariable[3]=0x1F8;
          UnKnowVariable[4]=0x154;  
                  
         }

     return ntStatus; ;

}

VOID dHookUnloadDriver(
    IN PDRIVER_OBJECT DriverObject)
{
      
    IoDeleteSymbolicLink(&LinkDeviceNameString);
    
    IoDeleteDevice( DriverObject->DeviceObject );  
}

NTSTATUS dHookCreateClose(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )


    Irp->IoStatus.Status = STATUS_SUCCESS;   
    Irp->IoStatus.Information = 0;
    IoCompleteRequest( Irp, IO_NO_INCREMENT );
    return STATUS_SUCCESS;
}

NTSTATUS dHookDeviceControl(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )

{
  PVOID PUnKownData,PUnKownData_A,PUnKownData_B;
  ULONG  outBufLength,inBufLength;
  PIO_STACK_LOCATION IrpStack;  
  char VarA,VarB, VarC;
  PEPROCESS peProcess;
  PVOID  inBuf, PInfoProcess_A,PInfoProcess_B; 
  int counter=0 ;
  ULONG UEnd;
  
  NTSTATUS ntStatus= STATUS_UNSUCCESSFUL;
  Irp->IoStatus.Information = 0;
  inBuf = Irp->AssociatedIrp.SystemBuffer;
  IrpStack = IoGetCurrentIrpStackLocation( Irp );
  
  outBufLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;//[ebp+60H+4]
 
  switch(IrpStack->Parameters.DeviceIoControl.IoControlCode )
    {
        case dHook_CtlCode_A: 
            if(outBufLength<0x34)
             {
                ntStatus= STATUS_BUFFER_TOO_SMALL;
                break;
             }
            if(!MmIsAddressValid(inBuf))
             {
                 break;
             }
              PUnKownData=(PVOID)((PLONG)inBuf)[0];//I/0包中前四个字节数据类型是另一个缓冲区的(指针)虚拟地址,因为下边用传数据用. PUnKownData
               VarA=(char)((PCHAR)inBuf)[4];//取出I/0包第5个字节
               VarB=(char)((PCHAR)inBuf)[5];//取出I/0包第6个字节
             if(!MmIsAddressValid(PUnKownData))
               {
                 break;
               }  
                                 
            for(counter=0;counter<=34;counter++)
               {                   
              VarC=*(((PCHAR)PUnKownData)+counter); //PUnKownData做源缓冲区地址,inBuf做目源缓冲区地址
              VarC=(char)((PCHAR)inBuf)[counter];//counter=34传34个字节
               }  
                         
             UEnd=(ULONG)((PLONG)inBuf)[24];//传输完毕,inBuf有了新的内容.要检测是否为0XFFFFFFF;  
             if(UEnd==-1)//用-1做end标志.
              {
                (ULONG)((PULONG)inBuf)[30]=-1;//把设置-1标志做结束
                Irp->IoStatus.Information=0x34;//记录I/0包传的字节数量
                ntStatus=STATUS_SUCCESS;//设置成功
                break;
              }
                           
            PUnKownData_A=(PVOID)((PULONG)inBuf)[8];  //inBuf[8]里又是一个指针的指针:PUnKownData_A
            PUnKownData_B=(PVOID)((PULONG)*(PULONG)((*(PULONG)PUnKownData_A)+UnKnowVariable[1]));//取出一个指针给PUnKownData_B
            if(!MmIsAddressValid(PUnKownData_A))
             {
               (ULONG)((PULONG)inBuf)[30]=-1;
                break;
             }    
             PUnKownData_B=(PULONG)*((PULONG)PUnKownData_B+(ULONG)VarA);    //设置缓冲区的偏移地址加VarA                               
           
           if(!MmIsAddressValid(PUnKownData_B))
             {
               (ULONG)((PULONG)inBuf)[30]=-1;
                break;
             }    
           PUnKownData_B=(PULONG)*((PULONG)PUnKownData_B+(ULONG)VarB);  //缓冲区的偏移地址加VarB
          (ULONG)((PULONG)inBuf)[30]=(ULONG)*((PULONG)PUnKownData_B+(ULONG)(UEnd*0x04));       
        break;

       case dHook_CtlCode_B:
          if(outBufLength< 0x18)
            {
                ntStatus= STATUS_BUFFER_TOO_SMALL;
                break;
            }
            if(!MmIsAddressValid(inBuf))
             {
                 break;
             }
          PUnKownData=(PVOID)*((PLONG)inBuf);
          if(!MmIsAddressValid(PUnKownData))
               {
                 break;
               }    
         PUnKownData_A=(PVOID)*(PULONG)PUnKownData; 
         peProcess=IoThreadToProcess((PETHREAD)PUnKownData_A);//获取进程上下文
         if(!MmIsAddressValid(peProcess))
               {
                 break;
               }  
         PInfoProcess_A=(PULONG)peProcess+UnKnowVariable[2];//修改进程
         *(PULONG)inBuf=(ULONG)*(PULONG)PInfoProcess_A;
         PInfoProcess_B=(PULONG)peProcess+UnKnowVariable[3];//修改进程
         ((PULONG)inBuf)[1]=(ULONG)*(PULONG)PInfoProcess_B;
       
         PInfoProcess_A=(PULONG)peProcess+UnKnowVariable[4];//修改进程
         PInfoProcess_B=(PULONG)inBuf+2;
         for(counter=0;counter<=0x10;counter++)
         {        
              VarC=*((PCHAR)PInfoProcess_A+counter);
              *((PCHAR)PInfoProcess_A+counter)=VarC;
         }
                 
            break;        
    }   
    
    IoCompleteRequest( Irp, IO_NO_INCREMENT );
    return ntStatus;
}

=============================================
  用户把一个函数或变量的虚拟地址或指针写入I/0缓冲区.然后驱动读出里边数据,通信的数据类型可能有常量,变量,或指针.函数指针等.
方便期间各个举了个例子,用C写点.可以放在VC.60中编译通过.
[注意下面的例子仅仅是针对我上边那个IRP_MJ_DEVICE_CONTRL例程中一些各个类型访问用的]

           char Data[256];
           int a;
   PVOID PUnKnowData;
   PVOID PAdd;//定义函数指针
   ULONG A=1;//偏移地址A

   PUnKnowData=Data;

   ((PCHAR)PUnKnowData)[2]='1';//写个某个类型的常量
   char c= ((PCHAR)PUnKnowData)[2];//读

   ((PLONG)PUnKnowData)[4]=(ULONG)&a; //写入某个变量地址
      a=((PLONG)PUnKnowData)[4];//读

   ((PULONG)PUnKnowData)[4]=(ULONG)add;//写入某个函数地址   
     PAdd=(PVOID)((PULONG)PUnKnowData)[4];//读
   
    (ULONG)(*(PULONG)PUnKnowData)=(ULONG)add;//指针方式写
      PAdd=(PULONG)((ULONG)(*(PULONG)PUnKnowData));//读

    (ULONG)(*((PULONG)PUnKnowData+A))=(ULONG)add; //用户把一个函数或变量的虚拟地址或指针写入I/0缓冲区任意++或--的偏移地址A中
      PAdd=(PULONG)(*((PULONG)PUnKnowData+A));   //这里是驱动的读出是个反向操作.

=============================================
源代码在附件中.多谢指正Bug!

特此声明:感谢六楼的throb同学指点如下:

mov     ecx, UniqueProcess ; 1E0h
push    dword ptr [ecx+esi] ; esi  = PETHREAD ; dt _ETHREAD -b;
                            ; ethread + 1e0h = UniqueProcess
pop     dword ptr [edi]; 从AssociatedIrp.Systembuffer返回UniqueProcess
mov     ecx, UniqueThread ; 1E4h
push    dword ptr [ecx+esi] ; ethread +1e4h =UniqueThread
pop     dword ptr [edi+4] ; ThreadListEntry->Flink ?
mov     ecx, 10h
mov     esi, NameOffSet
add     esi, ebx        ; esi = Get ImageName
add     edi, 8
rep movsb
mov     dword ptr [ebp-8], 18h ; szInformation ,这个地方我的代码用 Undefine 弄坏了
mov     dword ptr [ebp-4], 0 ; NtStatus
jmp     short RetIoctlControl


那个地方不是dt _KPROCESS -b 吧,
用到的几个变量的结构:
dt _EPROCESS -b
dt _ETHREAD -b
_KPROCESS的结构可以用
dt _KPROCESS -b得到




---------------------------------------------@
我是阿赖耶识....