Showing posts with label Object Hook. Show all posts
Showing posts with label Object Hook. Show all posts

Friday, September 9, 2011

Hook Specials 31 : Debugg driver

Author:softworm
Worte driver , Watch the driver to work, only learn driver. First register image loader message routine.

Code:
VOID LoadImageNotify (
  PUNICODE_STRING FullImageName,
  HANDLE ProcessId,
  PIMAGE_INFO ImageInfo
  )
{
  ANSI_STRING  asImageName;
  PCHAR    Delimiter;
  NTSTATUS  Status;
  ULONG    Base;
  ULONG    Entry;
  ULONG    Patch;
  ULONG    i;
 
 
  RtlUnicodeStringToAnsiString(&asImageName, FullImageName, TRUE);
 
  if (!ImageInfo->SystemModeImage)
  {
    goto __End; //不是驱动
  }
 
  Delimiter = strrchr(asImageName.Buffer, '\\');
  if (Delimiter == NULL)
    goto __End;
 
  Delimiter++;
 
  if( _strnicmp(Delimiter,"xxx.sys",strlen("xxx.sys")) != 0)
    goto __End;

  Base = (ULONG)ImageInfo->ImageBase;
       
  DbgPrint("%s Loaded, MappingAddress=%08X, Size=%08X\n",
     asImageName.Buffer,
     ImageInfo->ImageBase,
     ImageInfo->ImageSize );
 

  //The address immediate hard code, May analysis PE file and use disassemb engine
  // Original driver's DriverEntry export:
  //   leave
  //   retn    8
  //  
  //  

  Entry = Base + 0x1111;
  Patch = Base + 0x2222;
  g_ReturnAddress = Base + 0x3333;

  if (!(*(PULONG)Entry == 0x83EC8B55 &&  *(PUCHAR)(Entry+5) == 0x14)) //Check Entry
  {
    DbgPrint("Mismatched Entry!\n");
    goto __End;
  }

  if (*(PULONG)Patch != 0x0008C2C9)
  {
    DbgPrint("Mismatched Patch Point!\n");
    goto __End;
  }

  __asm
  {
    CLI
    MOV   EAX, CR0
    AND   EAX, NOT 10000H  //disable WP bit
    MOV   CR0, EAX
  }

  *(PUCHAR)Entry = 0xE9;
  *(PULONG)(Entry+1) = (ULONG)&SaveDriverObject - (Entry+5);

  *(PUCHAR)Patch = 0xE9;
  *(PULONG)(Patch+1) = (ULONG)&ReplaceDispatch - (Patch+5);
 

  __asm
  {
    MOV   EAX, CR0
    OR    EAX, 10000H  //enable WP bit
    MOV   CR0, EAX
    STI
  }
 
__End:
  RtlFreeAnsiString(&asImageName);
}
The function patch two part of original driver

DriverEntry entry of original driver, Be designed to get paramter of DriverObject, Because optimize compiler, The paramter is cleared to 0, So first save a share.

Second export of DriverEntry, Here replace dispatch function of DriverObject registered.

Code:
VOID __declspec (naked) SaveDriverObject()
{
  // 55               push    ebp
  // 8B EC            mov     ebp, esp
  // 83 EC 14         sub     esp, 14h

  __asm {
    pushad
    mov  eax, [esp+20h+4]
    mov  g_DrvObj, eax
    popad

    push ebp ; Original code
    mov  ebp, esp
    sub  esp, 14h

    jmp  [g_ReturnAddress]
  }
}


VOID __declspec (naked) ReplaceDispatch()
{
  __asm {
    pushad
   
    mov  eax, g_DrvObj 

    mov  ecx, [eax+18h]  ; DriverExtension
   
     
    mov  ebx, [eax+34h]  ; Unload
    mov  g_Unload, ebx
    mov  ebx, MyUnload
    mov  [eax+34h], ebx
   
    mov  ebx, [eax+38h]
    mov  g_Create, ebx
    mov  ebx, MyCreateCloseCleanup
    mov  [eax+38h], ebx  ; Create
    mov  [eax+40h], ebx  ; Close
    mov  [eax+80h], ebx  ; CleanUp
     
    mov  ebx, [eax+70h]
    mov  g_DeviceControl, ebx
    mov  ebx, MyDeviceControl
    mov  [eax+70h], ebx
   
    popad

    //Execute original export code 执行原出口代码

    __emit 0xC9 //VC6的汇编不支持leave
    retn  8
  }
}

Then may mount oneself code , Start only PassThru :

Code:
VOID MyUnload( PDRIVER_OBJECT DriverObject )
{
  DbgPrint("MyUnload\n");
  ((PDRIVER_UNLOAD)g_Unload)(DriverObject);
  return;
}


NTSTATUS MyCreateCloseCleanup( PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
  DbgPrint("MyCreateCloseCleanup\n");
  return ((PDRIVER_DISPATCH)g_Create)(DeviceObject, Irp);
}


NTSTATUS MyDeviceControl( PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
  PIO_STACK_LOCATION  irpSp;
  PVOID            inputBuff, outputBuff;
      ULONG            inputLen, outputLen, ctlCode;
  NTSTATUS          Status = STATUS_UNSUCCESSFUL;
   

  irpSp = IoGetCurrentIrpStackLocation(Irp);

  // Buffered io

  inputBuff  = Irp->AssociatedIrp.SystemBuffer;
      outputBuff = Irp->AssociatedIrp.SystemBuffer;
  inputLen   = irpSp->Parameters.DeviceIoControl.InputBufferLength;
      outputLen  = irpSp->Parameters.DeviceIoControl.OutputBufferLength;
  ctlCode    = irpSp->Parameters.DeviceIoControl.IoControlCode;

  switch (ctlCode)
  {
  case IOCTL_INIT:
      //逆的代码...
      break;

  default:
      DbgPrint("DeviceControl : Not Implemented IOCTL=%08X\n", ctlCode);
      return ((PDRIVER_DISPATCH)g_DeviceControl)(DeviceObject, Irp);
      break;
  }

__End:
  Irp->IoStatus.Information = outputLen;
  Irp->IoStatus.Status = Status;
      IoCompleteRequest (Irp, IO_NO_INCREMENT);
  return Status;
}

Then it doesn't matter, Reverse IOCTL code and one by one replace.

Hook Specials 30: Hook's note

Author:haithink
SendMessage() function send message to not entry message list to wait to get by GetMessage(), Immediate pass on window's function.
Example:
LRESULT CALLBACK MouseProc(
  int nCode,      // hook code
  WPARAM wParam,  // message identifier
  LPARAM lParam   // mouse coordinates
)
{
  return 1;       //Hook function return non-zero value, System isn't send message to program
}
HHOOK g_hKeyboard=NULL;
LRESULT CALLBACK KeyboardProc(
  int code,       // hook code
  WPARAM wParam,  // virtual-key code
  LPARAM lParam   // keystroke-message information
)
{
if(VK_SPACE==wParam)//Only shield space key, Mouse can  right click, use go to definition to view other virtual key
      return 1;
//if(VK_F4==wParam&&(1==(lParam>>29&1)))
  //return 1; 
//Shield Alt+F4,lParam第29位请查MSDN
  else
    return ::CallNextHookEx(g_hKeyboard,code,wParam,lParam);
}
BOOL CHookDemoDlg::OnInitDialog()
{
…….
::SetWindowsHookEx(WH_MOUSE,MouseProc,NULL,::GetCurrentThreadId());
  g_hKeyboard=::SetWindowsHookEx(WH_KEYBOARD,KeyboardProc,NULL,::GetCurrentThreadId());
}
Create back door for oneself program
Write the hook function:
LRESULT CALLBACK KeyboardProc(
  int code,       // hook code
  WPARAM wParam,  // virtual-key code
  LPARAM lParam   // keystroke-message information
)
{
//  if(VK_SPACE==wParam)
/*  if(VK_F4==wParam&&(1==(lParam>>29&1)))
      return 1;
  else
    return ::CallNextHookEx(g_hKeyboard,code,wParam,lParam);*/
  if(VK_F2==wParam)
  {
    ::SendMessage(g_hWnd,WM_CLOSE,0,0);
    UnhookWindowsHookEx(g_hKeyboard);
    UnhookWindowsHookEx(g_hKeyboard);
  }
  return 1;
}
Let's hook sub is related to all thread, SetWindowsHookEx's four paramter set 0,Thirdly is on dll of hook function.

Install to relevance all thread hook, Hook function wirte on dll, Remember to statement it to export function, in .def.
.dll中
#include<windows.h>
HHOOK g_hMouse;
HHOOK g_hKeyboard=NULL;
HWND g_hWnd;
/*HINSTANCE g_hInst;

BOOL WINAPI DllMain(
  HINSTANCE hinstDLL,  // handle to the DLL module
  DWORD fdwReason,     // reason for calling function
  LPVOID lpvReserved   // reserved
)
{
  g_hInst=hinstDll;
}
*/
LRESULT CALLBACK MouseProc(
  int nCode,      // hook code
  WPARAM wParam,  // message identifier
  LPARAM lParam   // mouse coordinates
)
{
  return 1;
}

LRESULT CALLBACK KeyboardProc(
  int code,       // hook code
  WPARAM wParam,  // virtual-key code
  LPARAM lParam   // keystroke-message information
)
{
  if(VK_F2==wParam)
  {
    ::SendMessage(g_hWnd,WM_CLOSE,0,0);
    UnhookWindowsHookEx(g_hMouse);
    ::UnhookWindowsHookEx(g_hKeyboard);
  }
  return 1;
}

void SetHook(HWND hwnd)

  g_hWnd=hwnd;
  g_hKeyboard=::SetWindowsHookEx(WH_KEYBOARD,KeyboardProc,GetModuleHandle("HOOk"),0);
  g_hMouse=::SetWindowsHookEx(WH_MOUSE,MouseProc,::GetModuleHandle("HOOK"),0);
  //::SetWindowsHookEx(WH_MOUSE,MouseProc,g_hInst,0);
}

.def中

LIBRARY HOOK         //此句可无
EXPORTS
SetHook

Aim module, First statement to external import function
_declspec(dllimport)void SetHook(HWND hwnd);
BOOL CHookTestDlg::OnInitDialog()
{
…………..
  int cxScreen,cyScreen;//Full screen current window, On top .
  cxScreen=::GetSystemMetrics(SM_CXSCREEN);
  cyScreen=::GetSystemMetrics(SM_CYSCREEN);
  SetWindowPos(&wndTopMost,0,0,cxScreen,cyScreen,SWP_SHOWWINDOW);

  SetHook(m_hWnd);
}
View Dll section
dumpbin  -headers xxx.dll

Method one in .cpp
#pragma data_seg("MySec")
HWND g_hWnd=NULL;
#pragma data_seg()                 //Define section

#pragma comment(linker,"/section:Mysec,RWS")//设置连接选项

Method two on .cpp

#pragma data_seg("MySec")
HWND g_hWnd=NULL;
#pragma data_seg()                  //Define a section

  on  .def
SEGMENTS
MySec READ WRITE SHARED

Hook Specials 32 : Api hook analyze in detail

Author:Alex(Yock.W)
Preface rudimentary knowledge

The article will overall analyze a fews api hook's method .

What is Hook?
 
Hook, is platform of windows message dispose machine-made, Application program may set sub program to keep watch on some kind of message of specials window above, and window of be kept watch on is created by other process. When message go to , Realize it on realize function of target window . Hook machine-made allow application program to intercept and capture for realize message of window or specials event.

Hook infact is program segment about dispose message, Through system call it, and load it on system. Whenever special message is sent, hook program catch the message before not go to aim window, That is hook function first get control power. Hook function may cure (change) the message now, passable not cure to continue and pass on the message, or force finished to pass on message.

Hook theory

Each Hook have a  related chain table, by system maintenance, Chain table point  callback function of is call by hook sub program .

LRESULT WINAPI HookCallBack(
int nCode,
WPARAM wParam,
LPARAM lParam);
nCode //Even code事件代码
wParam //message type
lParam //include message

When take place be hooked type related message, The message is passed on hook sub program of chain table point by system, Sub program dispose message inside.

Hook install and unlaod

Use API SetWindowsHookEx on window to install Hook chain table, set up hook lies  header of hook chain table.

HHOOK SetWindowsHookEx(
int idHook,
HOOKPROC lpfn,
HINSTANCE hMod,
DWORD dwThreadId);
idHook //hook type安装的钩子类型
lpfn // sub function pointer子程函数指针
hMod // Application program instance handle
dwThreadId // Hook related thread identifier 

When message type of be hooked take place, System call hook sub program with related chain table header. By sub program decide whether pass on the event to next sub program. Hook sub program pass on event to next hook need call API CallNextHookEx by Windows iffered.

LRESULT CallNextHookEx(
HHOOK hhk,
int nCode,
WPARAM wParam,
LPARAM lParam);
hhk //current handle of hook, by SetWindowsHookEx return
nCode //event code
wParam //type message
lParam // include message
 
Hook finish, need call UnHookWindowsHookEx to unload.

UnHookWindowsHookEx(
HHOOK hhk);
A few methods of Api Hook

One. Modify address space of function procedure mapping

Api Hook:

You know, When call function, first Call 0xFFFFFF, Go to function mapping to address space of memory , at this time, Esodic paramter had push, So we only modify header of function, jump to our custom procedure, Such we can reach  to keep watch on  api function aim. Like that, how much space to write code  for jump to our custom procedure?
 
Descend upon , Only five bytes , Why?  Watch code:

jmp 0xFFFFFFFF
jmp command only 1 byte, address is four bytes, So only five bytes.

Some people likely ask, Why use Call?

Because Call command will through ret to return call under command to continue execute after realize jump , and that Sub program control after Jmp command realize to jump .

We know above method through modify header of function to reach our aim, So We need get address of header first, Through LoadLibrary and GetProcAddress to get our address pointer of custodial function on memory mapping. Through MessageBoxA  to example:

typedef int (__stdcall *TMessageBoxA)(HWND hWnd,LPSTR lpText,LPSTR lpCaption,int uType);

extern "C" TMessageBoxA __fastcall GetPFuncAddr(LPSTR DllName,const char* FullName);

TMessageBoxA __fastcall GetPFuncAddr(LPSTR DllName,const char* FullName)
{
void *DllModule;
DllModule = LoadLibrary(DllName);
TMessageBoxA PAddr = (TMessageBoxA)GetProcAddress(DllModule,FullName);
return PAddr;
}
After point function header pointer of  memory mapping, Then read out five bytes of function header. Why read out five bytes of function header? of course write data for recover.
ReadProcessMemory:

BOOL ReadProcessMemory(
HANDLE hProcess,
LPCVOID lpBaseAddress,
LPVOID lpBuffer,
DWORD nSize,
LPDWORD lpNumberOfBytesRead);
hProcess //Process handle
lpBaseAddress //Read memory start address
lpBuffer 保存数据的指针
nSize 数据大小
lpNumberOfBytesRead //address of number of bytes read

BYTE *pFuncData = new BYTE[5];
LPDWORD iRead;

ReadProcessMemory((void *)GetCurrentProcess(),PMessageBoxA,pFuncData,5,iRead);

After save data of original entry point, Write to point address of our function   onself.

BYTE AsmCode[5];

AsmCode[0] = 0xE9;
__asm
{
lea eax, MyMessageBoxA
mov ebx,PMessageBoxA
sub eax,ebx
sub eax,5
mov dword ptr[AsmCode+1],eax
}
WriteProcessMemory((void *)GetCurrentProcess(),PMessageBoxA,AsmCode,5,iWrite);

MyMessageBoxA is created function by oneself:

int WINAPI MyMessageBoxA(HWND hWnd,LPSTR lpText,LPSTR lpCaption,int uType)
{
//Show messagebox, change eisodic caption paramter
//So first recover MessageBoxA
WriteProcessMemory((void *)GetCurrentProcess(),PMessageBoxA,pFuncData,5,iWrite);
int Result = MessageBoxA(hWnd,lpText,"ApiHook Test",uType);
WriteProcessMemory((void *)GetCurrentProcess(),PMessageBoxA,AsmCode,5,iWrite);
return Result;
}
Recover original entry data of API:

WriteProcessMemory((void *)GetCurrentProcess(),PMessageBoxA,pFuncData,5,iWrite);
Prevent to modify function entry data to proceed API HOOK:

Program start to save hinge five bytes of API entry, periodical inspection, if be modify, modify return.

----------------------------------------------------------------


Hook Specials 29 : A SEH'S HOOK [expansibility]

Peoples know SEH mechanism well. But may be do not understand code of try-except combined with SEH, That is undocumented.

Code:
#include <windows.h>
#include <stdio.h>

//The structure is vector table of try except (array),Undocumented
typedef struct __vect_handler
{
  DWORD vFlag;
  PVOID TryHandler;/*try-except{code}*/
  PVOID NextContiueCode;/*Exception handling behind next address of command */

}vect_handler;

typedef struct __EXCEPTION_LIST
{
  __EXCEPTION_LIST* next;//next SEH chain
  PVOID             handler;//exception handling program
  vect_handler*     vecthandler;
  DWORD             IndexVechandler;/*Cunrrent handling number of try-except , cast exception(on try-except) both modified it*/
 
}EXCEPTION_LIST;

char* ff = "try";

DWORD WINAPI handler()
{
  /*突破except{}里不能定义局部变量,增加局部变量*/
  /*debugger monitoring*/
  /*encryption TRY code*/
      __asm pushad
   
    __asm push 0
    __asm push 0
    __asm push ff
    __asm push 0
    __asm mov eax,MessageBoxA
    __asm call eax
    __asm popad
  //  __asm jmp OldExceptCode realize the line like perfect hook
    return EXCEPTION_EXECUTE_HANDLER/*jmp Contiue function*/;
};

void   Contiue()
{
        MessageBoxA( 0,"contiue",0,0);
    ExitProcess( 0 );
};

int main( int argn, char** argv )
{
  char k;
  char* v = 0;//&k;
  DWORD prepageprotect;

  DWORD ntry = 0;
  EXCEPTION_LIST* pe;
  EXCEPTION_LIST* currentpe;


  __asm mov eax, fs:[0]
    __asm mov pe, eax
   
  currentpe = pe;

  BOOL ok = VirtualProtect( &currentpe->vecthandler[0].TryHandler, 8, PAGE_EXECUTE_READWRITE, &prepageprotect );
  currentpe->vecthandler[0].TryHandler = handler;//hook try-except 【0 】block
  currentpe->vecthandler[0].NextContiueCode = Contiue;/*hook try-except 【0】 block 可以调到任何IP,可自己扩展功能*/
//以下do-while为显示SEH-try链没啥作用
    do
  {
    printf( "Next:%08x,handler:%08x\n", pe->next, pe->handler );
    if( pe->vecthandler )
    {
      vect_handler* v = pe->vecthandler;

      while( v->vFlag == 0xffffffff )
      {
        printf( "------try:%d,handler:%08x,NextCode:%08x\n", ntry, v->TryHandler, v->NextContiueCode );
        v++;
        ntry++;
      };
    };
    pe = pe->next;

  }while( pe!=(EXCEPTION_LIST*)0xffffffff );
 
  __try{
    /*ASM 这里会有mov [ebp-4],0*///try-except 【0】对应vecthandler[0]
    *v = 0;//将抛出异常,它已hooked
   
  }__except(EXCEPTION_EXECUTE_HANDLER)
  {
                          // 该异常处理将变化为调用handler函数
           //异常处理完好后将调用Contiue函数;
   
  };
 
  __try{
    /*ASM 这里会有mov [ebp-4],1*///try-except 【1】对应vecthandler[1]
    *v = 0;
   
  }__except(EXCEPTION_CONTINUE_EXECUTION)
  {
   
  };
  getchar();
  return 0;
}

Saturday, September 3, 2011

Hook Specials 27 : Find to Check object hook base on cross-reference

Author: sudami
Discuss object hook to check with VXK, While the way is simple base on PDB file analytic , That is unusefulness. Because only write general program to has symbol that is too fat on move and inconveniences, Seach file planed to do it. Happen to dummy wrote a article -- "Find all reference address of some specific address through relocation directives "  last year. some way apply to seach object hook.

Train of thought :
1.Create table 1 to save current Object Function Address of system. Open "\\ObjectTypes" to get RootDirectory, Traverse HashBuckets to get different addr by different object, Save on table 1.

2.Create table 2 to save original Object Function Address of system. Ntosxx of system kernel load to nonpagepool, Search on the range:
①To already export type (eg.IoDeviceObjectType、PsProcessType), Traverse ntosXX'EAT, Get RVA -- uAddr, Then call LookupImageXRef((ULONG)NtosCopy, uAddr, LookupXRefCallback); Search address on LookupXRefCallBack function, if we want to find function module, Feature matched to judge, for example:
      
      
       BOOLEAN
       NTAPI
         LookupXRefCallback(
            PULONG RefAddr
            )
      {
    ULONG tmp, address;
    PBYTE lpAddr = (PBYTE)RefAddr;
    ULONG x, i;
    int  time = 0;


    // If return True, Continue search , 否则Otherwise stop
//    DbgPrint("%08X --> %08X\n", RefAddr, RefAddr[0]);
    __try
    {
        //
        // Because large LoadPeFile called , The same system load to memory.
        // There already align. So (ULONG)RefAddr - (ULONG)NtosCopy;
        // It is RVA,Don't consider ImageBase. Good job; RefAddr is some function address load file to memory oneself, 
        // Such as I want to get A initio original n number bytes
        // Immediate take out from RefAddr
        // sudami 08/09/11 
        //
    tmp = (ULONG)RefAddr - (ULONG)NtosCopy; //RVA
//    DbgPrint("0x%08lx\n", (ULONG)ulKernelBase + tmp );


    //
    // To each RefAddr , From address + 4 of begining disassemble , find to match  code of xx function interior called.
    // There has original function address of IopXX,PspXX,CmpXX....
    // sudami 08/09/11 凌晨
    //

    //
    // coding
    //

    lpAddr+=4;

    switch ( g_nMethod )
    {
    case 1: // IopCreateObjectTypes function


   
            /*++ <IoDeviceObjectType>

        1.    C7 45 D4 B8 00 00 00 mov [ebp+var_2C], 0B8h
        2.    C7 45 E8 4D 57 4A 00 mov [ebp+var_18], offset IopParseDevice
            C6 45 AF 01 mov byte ptr [ebp+var_54+3], 1
        3.    C7 45 E4 9A 71 4C 00 mov [ebp+var_1C], offset IopDeleteDevice
        4.    C7 45 EC 8A 90 4D 00 mov [ebp+var_14], offset IopGetSetSecurityObject
            89 5D F0 mov [ebp+var_10], ebx
            E8 1F 40 F2 FF call ObCreateObjectType

            --*/
            time = 0;
            for(i=0;i<70;i++)
            {
                if ( !MmIsAddressValid( &lpAddr[i]) ){
                    continue ;
                }

                if(lpAddr[i]==0xC7 && lpAddr[i+1]==0x45)
                {
                    time+=1;
                    if (time==1)
                    {
                        x = *((DWORD *)((ULONG)RefAddr+i+3+4));
                        if(x!=0xB8)
                            return FALSE;
                    }
                    if(time==2)
                    {
                        x = *((DWORD *)((ULONG)RefAddr+i+3+4));
                       
                        DbgPrint("IopParseDevice - Orig: 0x%08lx\n", \
                            (ULONG)x + (ULONG)ulKernelBase - (ULONG)pNtH->OptionalHeader.ImageBase);

                        continue ;
                    }

                    if(time==3)
                    {
                        x = *((DWORD *)((ULONG)RefAddr+i+3+4));

                        DbgPrint("IopDeleteDevice - Orig: 0x%08lx\n", \
                            (ULONG)x + (ULONG)ulKernelBase - (ULONG)pNtH->OptionalHeader.ImageBase);

                        continue ;
                    }

                    if(time==4)
                    {
                        x = *((DWORD *)((ULONG)RefAddr+i+3+4));

                        DbgPrint("IopGetSetSecurityObject - Orig: 0x%08lx\n", \
                            (ULONG)x + (ULONG)ulKernelBase - (ULONG)pNtH->OptionalHeader.ImageBase);

                        break ;
                    }
                }
            }
           
            ...

     Like this, Realize to finde address of a part of Object function, Quick and stable seach than force seach.
    
     ② To type of non-export (eg.CmpKeyObjectType、ObpTypeObjectType), The way is verbose , I belive:
       
      
        ; Find pointer of there global variable of non-export, To already export type, such as IoDeviceObjectType, Get address on EAT of ntoskrnl.exe, Exactly point
        ; address of IoDeviceObjectType pointer, rathen than address of IoDeviceObjectType . So, It is no use MJ method to get real address of  CmpKeyObjectType, Must get it that point to address of 
        ; CmpKeyObjectType pointer, So do these to use method of dummy. See below:
        ;
        ; lkd> dd IoDeviceObjectType
        ; 80558ee4 817a9ca0 817a9900 817a9e70 817f0428
        ; | |
        ; | |-- IoDeviceObjectType own address本身的地址
        ; |-- Reference address, Point address of IoDeviceObjectType pointer
        ;
        ; 68 64 8D 48 00 push offset IoDeviceObjectType ; -->在callback函数中要找的引用地址是这样的
        ; ........... That is 80558ee4, rather than 817a9ca0
        ; C7 45 E8 4D 57 4A 00 mov [ebp+ParseProcedure], offset IopParseDevice
        ; 89 5D F0 mov [ebp+QueryNameProcedure], ebx
        ; E8 1F 40 F2 FF call ObCreateObjectType
        ; -- sudami 08/09/12
        ;
        ; Only The question resolved, Can need not Violence search. Traverse to finish all  type, Find address of these point type pointer , Then method of dummy to find quote,
        ; Can find real address of obj again... But I can't find solution now.
       
        ③ Can't find solution. As a result I use violence search, Main code as follow :
       
        // Through a series of read PE to get rva. Calculate some offset and space of memory about PE.
        // Allocate non-page memory
        // Content of file is read on here
        // Get size of file, Apple a memory block to save it
        //DbgPrint("Get size of file, Apple a memory block to save it\n");
        ZwQueryInformationFile (ntFileHandle, &ioStatus, &fsi,
                sizeof(FILE_STANDARD_INFORMATION), FileStandardInformation);

        FileContent =  ExAllocatePool (NonPagedPool, fsi.EndOfFile.LowPart);

        if (FileContent == NULL)
        {
            ntStatus = STATUS_UNSUCCESSFUL;
            ZwClose(ntFileHandle);

            DbgPrint("ExAllocatePool Error\n");
            goto End;
        }

        byteOffset.LowPart = 0;
        byteOffset.HighPart = 0;

        ntStatus = ZwReadFile(ntFileHandle,
            NULL,
            NULL,
            NULL,
            &ioStatus,
            FileContent,
            fsi.EndOfFile.LowPart,
            &byteOffset,
            NULL);

        if (!NT_SUCCESS(ntStatus))
        {
            ZwClose(ntFileHandle);
            ExFreePool(FileContent);

            DbgPrint("ZwReadFile 将要读的内容,读到一片非分页内存失败 Error\n");
            goto End;
        }

        if (fsi.EndOfFile.LowPart <= 0)
        {
            ntStatus = STATUS_NOT_FOUND;
            ZwClose(ntFileHandle);
            ExFreePool(FileContent);
            DbgPrint("NeedSize <= 0 Error\n");
            goto End;
        }

        GetHeaders (FileContent, &pfh, &poh, &psh);
       
        //DbgPrint("psh: %08lx\n", (PVOID)psh);
        //DbgPrint("start search....\n");
        // g_CmpCloseKeyObject_addr
        for (i = 0; i < fsi.EndOfFile.LowPart; i++)         
        {
            if ( (FileContent[i] == 0x8B) && (FileContent[i+1] == 0xFF) && (FileContent[i+2] == 0x55) && (FileContent[i+3] == 0x8B) &&
                (FileContent[i+4] == 0xEC) && (FileContent[i+5] == 0x83) && (FileContent[i+6] == 0x7D) && (FileContent[i+7] == 0x18) &&
                (FileContent[i+8] == 0x01) && (FileContent[i+9] == 0x77) && (FileContent[i+10] == 0x24) && (FileContent[i+11] == 0x56)
                )
            {
                //DbgPrint("文件偏移i: %08lx\n", (PVOID)i);
                sudami_1 = Offset2RVA( i, psh, pfh->NumberOfSections );
                if (sudami_1  == 0) {
                    DbgPrint("sudami_1 == 0 Error\n");
                    goto NotFound;
                }

                if (sudami_1  > SizeOfImage) {
                    DbgPrint("sudami_1 > SizeOfImage Error\n");
                    goto NotFound;
                }

                sudami_1 += ModuleBase;

                if (!MmIsAddressValid((PVOID)sudami_1 )) {
                    DbgPrint("!MmIsAddressValid((PVOID)sudami_1 ) Error\n");
                    goto NotFound;
                }

                g_CmpCloseKeyObject_addr = (DWORD)sudami_1;

                DbgPrint( "CmpCloseKeyObject - Orig:\t0x%08x\n", (ULONG)g_CmpCloseKeyObject_addr );
                break;
            }   
        }
       
       
After all, Check object hook, I can't find simple method.
I belive the thing available, So show it, You may use it...

Friday, September 2, 2011

Hook Specials 26 : Wrote a tool that is used to list MajorFunction

Author:zhuwg
Learn object hook recently,Wrote a tool that is used to list MajorFunction, It can list drvice and driver.

00000000  0.00000000  [majorfunc] DriverEntry: \REGISTRY\MACHINE\SYSTEM\ControlSet001\Services\majorfunc 
00000001  0.00006956  [majorfunc] Device Name \Device\devmajorfunc 
00000002  0.00013661  [majorfunc] SymbolicLink:\DosDevices\majorfunc 
00000003  0.00020198  ObReferenceObjectByName ok! 
00000004  0.00023411  \Driver\Atapi->MajorFunction[0]=F9998572 
00000005  0.00025115  \Driver\Atapi->MajorFunction[1]=805041BE 
00000006  0.00025869  \Driver\Atapi->MajorFunction[2]=F9998572 
00000007  0.00026512  \Driver\Atapi->MajorFunction[3]=805041BE 
00000008  0.00027154  \Driver\Atapi->MajorFunction[4]=805041BE 
00000009  0.00027797  \Driver\Atapi->MajorFunction[5]=805041BE 
00000010  0.00028411  \Driver\Atapi->MajorFunction[6]=805041BE 
00000011  0.00029026  \Driver\Atapi->MajorFunction[7]=805041BE 
00000012  0.00029669  \Driver\Atapi->MajorFunction[8]=805041BE 
00000013  0.00030283  \Driver\Atapi->MajorFunction[9]=805041BE 
00000014  0.00030926  \Driver\Atapi->MajorFunction[10]=805041BE 
00000015  0.00031540  \Driver\Atapi->MajorFunction[11]=805041BE 
00000016  0.00032183  \Driver\Atapi->MajorFunction[12]=805041BE 
00000017  0.00032797  \Driver\Atapi->MajorFunction[13]=805041BE 
00000018  0.00033440  \Driver\Atapi->MajorFunction[14]=F9998592 
00000019  0.00034055  \Driver\Atapi->MajorFunction[15]=F99947B4 
00000020  0.00034697  \Driver\Atapi->MajorFunction[16]=805041BE 
00000021  0.00035312  \Driver\Atapi->MajorFunction[17]=805041BE 
00000022  0.00035954  \Driver\Atapi->MajorFunction[18]=805041BE 
00000023  0.00036569  \Driver\Atapi->MajorFunction[19]=805041BE 
00000024  0.00037211  \Driver\Atapi->MajorFunction[20]=805041BE 
00000025  0.00037826  \Driver\Atapi->MajorFunction[21]=805041BE 
00000026  0.00038469  \Driver\Atapi->MajorFunction[22]=F99985BC 
00000027  0.00039083  \Driver\Atapi->MajorFunction[23]=F999F164 
00000028  0.00039726  \Driver\Atapi->MajorFunction[24]=805041BE 
00000029  0.00040340  \Driver\Atapi->MajorFunction[25]=805041BE 
00000030  0.00040983  \Driver\Atapi->MajorFunction[26]=805041BE 
00000031  0.00042687  [atapi] HOOKed Success 
00000032  0.00053359  IoGetDeviceObjectPointer ok 
00000033  0.00056292  \Device\Afd->DriverObject->MajorFunction[0]=F8391D40 
00000034  0.00058024  \Device\Afd->DriverObject->MajorFunction[1]=F8391D40 
00000035  0.00058778  \Device\Afd->DriverObject->MajorFunction[2]=F8391D40 
00000036  0.00059477  \Device\Afd->DriverObject->MajorFunction[3]=F8391D40 
00000037  0.00060147  \Device\Afd->DriverObject->MajorFunction[4]=F8391D40 
00000038  0.00060846  \Device\Afd->DriverObject->MajorFunction[5]=F8391D40 
00000039  0.00061516  \Device\Afd->DriverObject->MajorFunction[6]=F8391D40 
00000040  0.00062187  \Device\Afd->DriverObject->MajorFunction[7]=F8391D40 
00000041  0.00062857  \Device\Afd->DriverObject->MajorFunction[8]=F8391D40 
00000042  0.00063556  \Device\Afd->DriverObject->MajorFunction[9]=F8391D40 
00000043  0.00064226  \Device\Afd->DriverObject->MajorFunction[10]=F8391D40 
00000044  0.00064924  \Device\Afd->DriverObject->MajorFunction[11]=F8391D40 
00000045  0.00065595  \Device\Afd->DriverObject->MajorFunction[12]=F8391D40 
00000046  0.00066265  \Device\Afd->DriverObject->MajorFunction[13]=F8391D40 
00000047  0.00066936  \Device\Afd->DriverObject->MajorFunction[14]=F8391280 
00000048  0.00067634  \Device\Afd->DriverObject->MajorFunction[15]=F8391D40 
00000049  0.00068305  \Device\Afd->DriverObject->MajorFunction[16]=F8391D40 
00000050  0.00069003  \Device\Afd->DriverObject->MajorFunction[17]=F8391D40 
00000051  0.00069674  \Device\Afd->DriverObject->MajorFunction[18]=F8391D40 
00000052  0.00070344  \Device\Afd->DriverObject->MajorFunction[19]=F8391D40 
00000053  0.00071015  \Device\Afd->DriverObject->MajorFunction[20]=F8391D40 
00000054  0.00071713  \Device\Afd->DriverObject->MajorFunction[21]=F8391D40 
00000055  0.00072384  \Device\Afd->DriverObject->MajorFunction[22]=F8391D40 
00000056  0.00073082  \Device\Afd->DriverObject->MajorFunction[23]=F8391D40 
00000057  0.00073752  \Device\Afd->DriverObject->MajorFunction[24]=F8391D40 
00000058  0.00075792  \Device\Afd->DriverObject->MajorFunction[25]=F8391D40 
00000059  0.00076602  \Device\Afd->DriverObject->MajorFunction[26]=F8391D40