在看雪了里,学到了不少大牛HOOK的技术,这里就不一一的感谢了。不过终究还是离不开这种模式:修改原函数头+N个字节处,实现跳转到自己A函数,在自己的A函数里加一些特别功能,再执行原函数被修改的代码,再跳到原修改处的下一句代码。

     我就想(我是菜鸟),既然到跳的A函数了,能不能永远不跳回原代码,就让它在A函数里直接就行,返回了事,这样可以,清除所有的其它 内联HOOK。

     思路:从源文件中,找到导出函数地址,把这个地址反汇编到自己的空间里的A函数里,修改源函数,使之跳转到A函数里。和以前不同的是不跳转回源函数。

     我在R0做了一试实验.代码如下:

代码:
#define EMPTP_ASM_32(x) __asm { __asm _emit x __asm _emit x __asm _emit x __asm _emit x __asm _emit x __asm _emit x __asm _emit x __asm _emit x }

#define CLR_WP() \
    __asm cli \
    __asm mov  eax,cr0 \
    __asm and  eax,not 10000h \
    __asm mov  cr0,eax 
      
#define SET_WP() \
    __asm mov  eax,cr0 \
    __asm or   eax,10000h \
    __asm mov  cr0,eax \
    __asm sti

//1K的空位
__declspec( naked )  IMP_NtOpenProcess(OUT PHANDLE ProcessHandle, IN ACCESS_MASK DesiredAccess,   IN POBJECT_ATTRIBUTES ObjectAttributes, IN PCLIENT_ID ClientId OPTIONAL )
{
EMPTP_ASM_32(0x90) EMPTP_ASM_32(0x90) EMPTP_ASM_32(0x90) EMPTP_ASM_32(0x90) EMPTP_ASM_32(0x90) EMPTP_ASM_32(0x90) EMPTP_ASM_32(0x90) EMPTP_ASM_32(0x90)
.....
EMPTP_ASM_32(0x90) EMPTP_ASM_32(0x90) EMPTP_ASM_32(0x90) EMPTP_ASM_32(0x90) EMPTP_ASM_32(0x90) EMPTP_ASM_32(0x90) EMPTP_ASM_32(0x90) EMPTP_ASM_32(0x90)
}

NTSTATUS  Skip_NtOpenProcess(OUT PHANDLE ProcessHandle, IN ACCESS_MASK DesiredAccess,   IN POBJECT_ATTRIBUTES ObjectAttributes, IN PCLIENT_ID ClientId OPTIONAL )
{
  DWORD   dwJmpFunAddr =  (DWORD)IMP_NtOpenProcess;
  DWORD   dwRunAdd;
        NTSTATUS rc;
  __asm
  {  
    mov   dwJmpFunAddr, offset _HX_EXIT_SIGN               
      push  ClientId
      push   ObjectAttributes
      push   DesiredAccess
      push   ThreadHandle        
      push  dwRunAdd   
      push  dwJmpFunAddr      
      ret
_HX_EXIT_SIGN:
          mov rc, eax 
        add esp, 10H    
        
  }
  return rc;
  
 }
//这个函数是抄的

ULONG GetKernelBaseAddress(OUT PCHAR lpszModule)
{
   NTSTATUS ntStatus;
   ULONG NeededSize, KernelAddr;//uLoop
   PMODULE_LIST pModuleList;
   
   KernelAddr = 0;

   ZwQuerySystemInformation( SystemModuleInformation, &NeededSize, 0, &NeededSize);
   pModuleList = ExAllocatePool( NonPagedPool, NeededSize );
   ntStatus = ZwQuerySystemInformation( SystemModuleInformation, pModuleList, NeededSize, NULL );
   if ( NT_SUCCESS(ntStatus) )
   {
      //ntoskrnl is always first there
      KernelAddr = (ULONG)pModuleList->SysModuleInfo[0].Base;
      strcpy( lpszModule, "\\SystemRoot\\System32\\" );
      strcat( lpszModule, pModuleList->SysModuleInfo[0].ModuleNameOffset
                          + pModuleList->SysModuleInfo[0].ImageName );
   }
   ExFreePool(pModuleList);
    
   return KernelAddr;
}
//这个函数是抄的


PUCHAR GetExportFunFormBase(PCHAR ImageBase, PCSTR Name)
{
   PIMAGE_DOS_HEADER    DosHeader;
   PIMAGE_NT_HEADERS    PeHeader;
   PIMAGE_DATA_DIRECTORY  ImageExportDirectoryEntry;
   ULONG            ExportDirectorySize, ExportDirectoryOffset, i;
   PIMAGE_EXPORT_DIRECTORY  ExportDirectory;
   PULONG          ExportAddressTable;
   PSHORT          ExportOrdinalTable;
   PULONG          ExportNameTable;

   if ( (DosHeader = (PIMAGE_DOS_HEADER)ImageBase) == NULL)
       return NULL;

   if (DosHeader->e_magic != IMAGE_DOS_SIGNATURE)
      return NULL;

   if (DosHeader->e_lfanew > 1024*1024)
      return NULL;

   if ( (PeHeader = (PIMAGE_NT_HEADERS) (ImageBase + DosHeader->e_lfanew)) == NULL)
      return NULL;

   //if (PeHeader->Signature != IMAGE_PE_SIGNATURE)
   if (PeHeader->Signature != IMAGE_NT_SIGNATURE)
      return NULL;

   if ( (ImageExportDirectoryEntry = PeHeader->OptionalHeader.DataDirectory + IMAGE_DIRECTORY_ENTRY_EXPORT) == NULL)
      return NULL;

   ExportDirectorySize = ImageExportDirectoryEntry->Size;
   ExportDirectoryOffset = ImageExportDirectoryEntry->VirtualAddress;

   if ( (ExportDirectory = (PIMAGE_EXPORT_DIRECTORY) (ImageBase + ExportDirectoryOffset)) == NULL)
      return NULL;

   ExportAddressTable = (PULONG)(ImageBase + ExportDirectory->AddressOfFunctions);
   ExportOrdinalTable = (PSHORT)(ImageBase + ExportDirectory->AddressOfNameOrdinals);
   ExportNameTable =    (PULONG)(ImageBase + ExportDirectory->AddressOfNames);

   for (i = 0; i < ExportDirectory->NumberOfNames; i++)
   {
      ULONG ord = ExportOrdinalTable[i];

      if ( ExportAddressTable[ord] < ExportDirectoryOffset ||
           ExportAddressTable[ord] >= ExportDirectoryOffset + ExportDirectorySize)
      {
         if (strcmp(ImageBase + ExportNameTable[i], Name) == 0)
         {
            return ImageBase + ExportAddressTable[ord];
         }
      }
   }
   return NULL;
}

BOOL HookNtOpenProcessFunction(PUCHAR jmpFun,OUT PUCHAR sotreFun/*输出反汇编代码*/)
{
    //取ntoskrnl ImageBase 略过,
     PUCHAR pOrgiAddr=GetExportFunFormBase(ImageBase,"NtOpenProcess");
     PUCHAR pCurrAddr=(PUCHAR)NtOpenProcess;
     PUCHAR pOutAddr= sotreFun;
     UCHAR jmp_hook_code[]={ 0xe9, 0x00, 0x00, 0x00, 0x00,
                0x90,0x90,0x90,0x90,0x90,0x90};  
    
    UINT nJmpHookCodeLen = sizeof(jmp_hook_code)-6; //跳转代码长度
     UINT nNextLen=0,i=0;
     UINT bIsOK=FALSE;

    while(TRUE) //复制代码
    {    
                        //反汇编 见附件              
      nNextLen=getNextInstruction(pOrgiAddr,1,pOutAddr,10);
      i+=nNextLen;
      pOutAddr+=nNextLen;
      pOrgiAddr+=nNextLen;

      if(!bIsOk && i>=nJmpHookCodeLen ) //保证是完整指令替换
      {
        nJmpHookCodeLen=i;
        bIsOk=TRUE;
      }
                         
                        //是否到函数的结尾
      if( (pOrgiAddr[0]==0x90 && pOrgiAddr[1]==0x90 && pOrgiAddr[2]==0x90 && pOrgiAddr[3]==0x90 ) ||
        (pOrgiAddr[0]==0xCC && pOrgiAddr[1]==0xCC && pOrgiAddr[2]==0xCC && pOrgiAddr[3]==0xCC )  )
      {
        nNextLen=4;
        IsJmpBack=FALSE;
        RtlCopyMemory(pOutAddr,pOrgiAddr,nNextLen);
        i+=nNextLen;
        pOutAddr+=nNextLen;
        pOrgiAddr+=nNextLen;
        break;
      }

  
    }
                if(i>0)
               {
                        *((ULONG*)(jmp_orig_code + 1) )=(ULONG)jmpFun;
                        CLR_WP();
      RtlCopyMemory(originalCode,jmp_hook_code,nJmpHookCodeLen);
      SET_WP();
                        return TRUE;
               }
              return FALSE;
}



void InitHook()
{
    
    PUCHAR addr1=(PUCHAR)Skip_NtOpenProcess;
    PUCHAR addr2=(PUCHAR)IMP_NtOpenProcess;//
    HookNtOpenProcessFunction(addr1,addr2);/*从ntoskrnl.exe 文件中,读NtOpenProcess真实地址,,并对NtOpenProcess从文件进行反汇编输出*/
}
以上为代码,不过这段代码老是出问题,开始会成功,后面就挂了。
上传的附件 反汇编.rar