Wednesday, September 14, 2011

MessageBox of ring0

Author:achillis
The source code show MessageBox of ring0 with KeUserModeCallback . I learn code by russian worte . So I worte oneself.

Code here:

Tuesday, September 13, 2011

Hook specials finished

Hi, Hook specials finished yesterday. I will introduce news type article, You can read it and post , Thanks.

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;
}