免費論壇 繁體 | 簡體
Sclub交友聊天~加入聊天室當版主
分享
返回列表 发帖

绕过所有用户层HOOK

A、分析API函数原理
   B、自写API函数
   C、SYSENTER指令
   D、硬编码_emit
   E、模拟FindWindow函数  
课时:43

PUNICODE_STRING
MOV EAX,117A
7C92E510 >  8BD4            MOV EDX,ESP
7C92E512    0F34            SYSENTER



//取得RtlInitUnicodeString地址
        typedef   (__stdcall *PRtlInitUnicodeString)( PUNICODE_STRING , PCWSTR  );
        PRtlInitUnicodeString  RtlInitUnicodeString;
        RtlInitUnicodeString=(PRtlInitUnicodeString)GetProcAddress(GetModuleHandle("ntdll.dll"),"RtlInitUnicodeString");
        //初始化PUNICODE_STRING字串结构 方法1
        //pname->Buffer= wName ;
        //pname->Length=wcslen(pname->Buffer)*2+1  ;
        //UnsafeModuleName.MaximumLength=0x0fff;

   //初始化PUNICODE_STRING字串结构 方法2
        RtlInitUnicodeString(pname,wName);
=========================================================

笔记:
自写API函数,脱离动态链接库的限制.这样做的目地并不是用于过保护,而主要是用于隐藏我们自己的代码.
新建一个MFC程序,调用FandWindow函数,来查找计算器标题.用OD来跟踪一下执行过程,里面有一个CALL的调用,再继续跟踪又有一个CALL的调用,在里面没有直接发现对标题的读取,仔细查看发现是UNICODE代码,000E0006,E代表最大长度,6代表字个数,再看一下里面的数值就发现了宽字符的”计算器”;再继续向下跟就发现了117A的索引号,然后CALL到内核函数.ntdll.kiFastSystemCall.写上代码后总提示错误,应该是UNICODE字符没有定义的原因,到驱动代码中找到结构定义,然后又将函数中多余的__stdcall参数去掉,但是调用出错还是要用到__stdcall

///////////////////////////////myApi.h//////////////////////////

#pragma pack(1)
typedef struct _UNICODE_STRING {                //因为不支持UNICODE所以要先定义结构
    USHORT Length;
    USHORT MaximumLength;  
    PWSTR  Buffer;
} UNICODE_STRING,*PUNICODE_STRING;
#pragma pack()
__declspec(naked)   void sysFastCall()        //模拟kiFastSystemCall 函数 以naked生成干净的汇编
{
        __asm
        {
        //        7C92E510 >  8BD4          MOV EDX,ESP
    //7C92E512    0F34            SYSENTER
                  mov edx,esp                                                //因为不支持SYSENTER所以硬编码
        __emit 0x0f
                __emit 0x34
        }
}
/*
77D28285   .  FF75 18       PUSH DWORD PTR SS:[EBP+18]       ;  0
77D28288   .  FF75 E8       PUSH DWORD PTR SS:[EBP-18]       ;  PU_LCatipn
77D2828B   .  FF75 F8       PUSH DWORD PTR SS:[EBP-8]        ;  NULL
77D2828E   .  FF75 0C       PUSH DWORD PTR SS:[EBP+C]        ;  0
77D28291   .  FF75 08       PUSH DWORD PTR SS:[EBP+8]        ;  0
77D28294   .  E8 13450000   CALL USER32.77D2C7AC             ;  NtUserFindWindow
*/
__declspec(naked) HWND  __stdcall My_FindWindow(        //模拟上一层CALL
                                                                                           int p1,
                                                                                           int p2,
                                                                                           PUNICODE_STRING pu_classname,
                                                                                           PUNICODE_STRING pu_catption,
                                                                                           int p5)
{
        __asm
        {
                MOV EAX,0x117A
        call sysFastCall
                RETN 0x14
        }
}



///////////////////////////////////调用的代码 test_API.cpp///////////////////////

void CTest_APIDlg::OnButtonMyFindwindow()
{
        UNICODE_STRING pu_className,pu_Caption;                //定义字串
        //调用驱动函数对字串进行初始化
        typedef   (__stdcall *PRtlInitUnicodeString)( PUNICODE_STRING , PCWSTR  );
        PRtlInitUnicodeString  RtlInitUnicodeString;
        RtlInitUnicodeString=(PRtlInitUnicodeString)GetProcAddress(GetModuleHandle("ntdll.dll"),"RtlInitUnicodeString");
        RtlInitUnicodeString(&pu_className,L"SciCalc");        //类名
        RtlInitUnicodeString(&pu_Caption,L"计算器");        //标题
        HWND h=My_FindWindow(0,0,&pu_className,&pu_Caption,0);
                ::SendMessage(h,WM_CLOSE,0,0);
}

写好函数后用OD加载测试,确实已经过了OD的断点,另外NtProc.h里有关于SetWindowsHookEx的保护代码.


#include <string.h>

/*
0012F628   10000000  ....  //hMod
0012F62C   0012F640  @?. //UnsafeModuleName
0012F630   00000000  ....//ThreadId
0012F634   00000002  ....//hookid =Wh_KeyBoard
0012F638   100010E0  ?..   GameDll.Gameproc //HookProc
0012F63C   00000002  .... //Ansi
0012F640   00660064  d.f.
0012F644   0012F678  x?.   UNICODE "I:\\VC_Code\\PassNP_Code\\MFC_EXE\\Release\\GameDll.dll"
DWORD tid=0;
HMODULE hdll=        LoadLibraryA("GameDll.dll");
HOOKPROC Gameproc=(HOOKPROC)GetProcAddress(hdll,"Gameproc");
        Nt_SetWindowsHookEx(WH_KEYBOARD,Gameproc,::GetModuleHandle("GameDll.dll"),tid);
       
          typedef struct _SetWindowsHookEx_Data
          {
          HINSTANCE hMod;
          PUNICODE_STRING UnsafeModuleName;
          DWORD ThreadId;
          int HookId;
          HOOKPROC HookProc;
          BOOL Ansi;
          
                }SetWindowsHookEx_Data;

*/

//#pragma pack(1)
typedef struct _UNICODE_STRING {
    USHORT Length;
    USHORT MaximumLength;
    PWSTR  Buffer;        
} UNICODE_STRING,*PUNICODE_STRING;
//#pragma pack()


__declspec(naked) void sysCall()
{

_asm
{

__emit   0x8B
__emit   0xD4
__emit   0x0F
__emit   0x34  
}
}


__declspec(naked) HHOOK __stdcall Nt_SetWindowsHookEx (HINSTANCE hMod, PUNICODE_STRING UnsafeModuleName, DWORD ThreadId, int HookId, HOOKPROC HookProc, BOOL Ansi)

{
         _asm
         {
                 MOV EAX,0x1225
                 call sysCall               
         retn 0x18
         }
       
}


void My_SetWindowsHookEx()
{   //取得RtlInitUnicodeString地址
        typedef   (__stdcall *PRtlInitUnicodeString)( PUNICODE_STRING , PCWSTR  );
        PRtlInitUnicodeString  RtlInitUnicodeString;
        RtlInitUnicodeString=(PRtlInitUnicodeString)GetProcAddress(GetModuleHandle("ntdll.dll"),"RtlInitUnicodeString");
    //
        HINSTANCE hMod=LoadLibraryA("gamedll.dll");
        UNICODE_STRING UnsafeModuleName;
        PUNICODE_STRING pname=&UnsafeModuleName;
        DWORD ThreadId=0;
        int HookId=WH_KEYBOARD;
        HOOKPROC Gameproc=(HOOKPROC)GetProcAddress(hMod,"Gameproc");
        BOOL Ansi=2;
        //初始化UnsafeModuleName 字串
        WCHAR wName[256];
        char Fullpath[256];
        GetCurrentDirectory(256,Fullpath);
        strcat(Fullpath, "\\gamedll.dll");//Fullpath=Fullpath+"gamedll.dll";
        //把Fullpath 转换成 宽字符串
        MultiByteToWideChar (CP_ACP, 0, Fullpath, -1, wName, sizeof(wName)*2+1);

        //初始化PUNICODE_STRING字串结构 方法1
        //pname->Buffer= wName ;
        //pname->Length=wcslen(pname->Buffer)*2+1  ;
        //UnsafeModuleName.MaximumLength=0x0fff;

           //初始化PUNICODE_STRING字串结构 方法2
        RtlInitUnicodeString(pname,wName);
        // hMod=GetModuleHandle("GameDll.dll");
        Nt_SetWindowsHookEx ( hMod,  &UnsafeModuleName,  ThreadId,  HookId,   Gameproc,  Ansi);

}
__declspec(naked) HWND __stdcall Nt_FindWindow (int p1,int p2,PUNICODE_STRING p3_ClassName,PUNICODE_STRING p4_Caption, int p5)
{


        __asm
        {
            mov eax,0x117a //NtUserFindWindowEx
                call sysCall
                retn 0x14
        }
}

返回列表