首页
社区
课程
招聘
保护sendmessage函数(转)
发表于: 2007-2-5 17:14 3929

保护sendmessage函数(转)

2007-2-5 17:14
3929
  菜鸟追风学习NP,这篇是瞎逛发现的,不知道对NP适不适用
,转来看雪分享。
  附带个请求,熟悉C和delphi的前辈能帮我翻译成delphi的吗?有几处语法不明白,C++还停留在概念上。。。虽然感觉有点不劳而获先SORRY了。
//---------------------------------------------------------------------------

#ifndef ApiHelperH
#define ApiHelperH

#include <windows.h>

//---------------------------------------------------------------------------
#define   OS2000_F1   0x55
#define OS2000_F2   0x8b
#define OS2000_F3   0xec
#define OS2000_F4   0x56
#define OS2000_F5   0x8b

#define   OS2000_2_F1   0x8b
#define OS2000_2_F2   0xc0
#define OS2000_2_F3   0x55
#define OS2000_2_F4   0x8b
#define OS2000_2_F5   0xec

#define OS98_F1      0xe8
#define OS98_F2      0x15
#define OS98_F3      0xf6
#define OS98_F4      0xff
#define OS98_F5      0xff

#define OSME_F1
#define OSME_F2
#define OSME_F3
#define OSME_F4
#define OSME_F5

#define OSXP_F1      0x8b
#define OSXP_F2      0xff
#define OSXP_F3      0x55
#define OSXP_F4      0x8b
#define OSXP_F5      0xec

typedef BOOL (WINAPI * SendMessageProc ) (  HWND hWnd, UINT value, WPARAM wp, LPARAM lp );

extern  SendMessageProc         _MySendMessage;
bool ProtectFunction();

//---------------------------------------------------------------------------
#endif

代码:

//---------------------------------------------------------------------------

#pragma hdrstop

#include "ApiHelper.h"
#include "Common.h"
#include "Log.h"

extern  cLog            * g_pLog;

SendMessageProc         _MySendMessage;
SendMessageProc         OldSendMessageFunc;
BYTE    fnFuncEntry[255];   //  旧函数入口

//---------------------------------------------------------------------------
bool Func_2k()
{
   DWORD pp   = (DWORD) OldSendMessageFunc;
   DWORD pp1   = (DWORD) _MySendMessage;

   fnFuncEntry[7] = 0xe9;      // jump 指令
   int * p = (int*)(fnFuncEntry+8);
   *p   =   pp - pp1 - 5;

#ifdef LOG
    g_pLog->AddText( "// Protect function success....(Window2000)!" );
#endif

   return   true;
}

//---------------------------------------------------------------------------
bool Func_2k_2()
{
   DWORD pp   = (DWORD) OldSendMessageFunc;
   DWORD pp1   = (DWORD) _MySendMessage;

   fnFuncEntry[9] = 0xe9;      // jump 指令
   int * p = (int*)(fnFuncEntry+10);
   *p   =   pp - pp1 - 5;

#ifdef LOG
    g_pLog->AddText( "// Protect function success....(Window2000 V20050603)!" );
#endif

   return   true;
}

//---------------------------------------------------------------------------
bool Func_xp()
{
   DWORD pp   = (DWORD) OldSendMessageFunc;
   DWORD pp1   = (DWORD) _MySendMessage;

   fnFuncEntry[6] = 0xe9;      // jump 指令
   int * p = (int*)(fnFuncEntry+7);
   *p   =   pp - pp1 - 5;

#ifdef LOG
    g_pLog->AddText( "// Protect function success....(WindowsXP)!" );
#endif

   return   true;
}

//---------------------------------------------------------------------------
bool Func_98()
{
   DWORD pp   = (DWORD) OldSendMessageFunc;
   DWORD pp1   = (DWORD) _MySendMessage;

   int * p = (int*)(fnFuncEntry + 1 );   //   重新计算出call的位置
   int   offset = (DWORD)pp + *p + 5;

   int   jj      =   offset - pp1 - 5;

   *p   =   jj;
   offset = (DWORD)pp1 + *p + 5;

   fnFuncEntry[5]   =   0xe9;         //   将后的面的指令改为一个jump
   p = (int*) (fnFuncEntry + 6);
   *p   =   pp - pp1 - 5;

#ifdef LOG
    g_pLog->AddText( "// Protect function success....(Windows98)!" );
#endif

   return   true;
}

//---------------------------------------------------------------------------
bool ProtectFunction( )
{

    HMODULE hInst   =   LoadLibrary( "User32.dll" );
    OldSendMessageFunc =   ( SendMessageProc ) GetProcAddress( hInst, "SendMessageA" );

    if ( OldSendMessageFunc == NULL )
    {
        MessageBox( NULL, "Protect Win32 function failed.", "Warning", MB_OK );
        return  false;
    }

    memcpy( fnFuncEntry, (BYTE*)OldSendMessageFunc, 50 );

   if ( fnFuncEntry[0] == 0xE9 )   //   发现已经修改过的指令
   {
      MessageBox( NULL, "Protect Win32 function failed.(pls reset lineage client)", "Warning", MB_OK );
      return   false;
   }

   DWORD dwAddress = reinterpret_cast<DWORD>(fnFuncEntry);
   _MySendMessage = (SendMessageProc)dwAddress;

   // ----------------- 2000 判断
   if ( (fnFuncEntry[0] == OS2000_F1) &&
       (fnFuncEntry[1] == OS2000_F2) &&
       (fnFuncEntry[2] == OS2000_F3) &&
       (fnFuncEntry[3] == OS2000_F4) &&
       (fnFuncEntry[4] == OS2000_F5) )
   {
      return   Func_2k();
   }

   // ----------------- 2000 判断 v2
   if ( (fnFuncEntry[0] == OS2000_2_F1) &&
       (fnFuncEntry[1] == OS2000_2_F2) &&
       (fnFuncEntry[2] == OS2000_2_F3) &&
       (fnFuncEntry[3] == OS2000_2_F4) &&
       (fnFuncEntry[4] == OS2000_2_F5) )
   {
      return   Func_2k_2();
   }

   // ----------------- 98 判断
   if ( (fnFuncEntry[0] == OS98_F1) &&
       (fnFuncEntry[1] == OS98_F2) &&
       (fnFuncEntry[2] == OS98_F3) &&
       (fnFuncEntry[3] == OS98_F4) &&
       (fnFuncEntry[4] == OS98_F5) )
   {
      return   Func_98();
   }

   // ----------------- xp 判断
   if ( (fnFuncEntry[0] == OSXP_F1) &&
       (fnFuncEntry[1] == OSXP_F2) &&
       (fnFuncEntry[2] == OSXP_F3) &&
       (fnFuncEntry[3] == OSXP_F4) &&
       (fnFuncEntry[4] == OSXP_F5) )
   {
      return   Func_xp();
   }

    MessageBox( NULL, "Your's os unprotected win32 api function.", "Warning", MB_OK );

    return  true;
}

//---------------------------------------------------------------------------

#pragma package(smart_init)

[课程]Android-CTF解题方法汇总!

收藏
免费 0
支持
分享
最新回复 (1)
雪    币: 297
活跃值: (10)
能力值: ( LV9,RANK:250 )
在线值:
发帖
回帖
粉丝
2
大概看了下代码,有点看不明白作者的意图。
有几个问题:
1:仅仅判断SendMessage入口的前五个字节是不可靠的。恶意代码者可能选择修改后面的字节来实现Hook.
2:既然前五个字节已经确认没有被修改,为什么还把整个SendMessage的指令(况且这种方法很不通用,如果是其他API的指令很大或者很小怎么办?)拷贝到一份自己的定义的该函数的拷贝中去呢?然后又用一个跳转跳到原来的SendMessage的指令中去?那还不如直接发现前五字节没有改变后,直接调用该函数。
3:在判断是否被修改了,犯了一个错误,
   if ( fnFuncEntry[0] == 0xE9 )   //   发现已经修改过的指令
   {...}
这里,如果检查别人修改的话则不一定只是jump指令,其他跳转指令都可以。
4:还有一个致命的错误是,在调用自己定义的这个函数的拷贝时,开始会有一些压栈的指令被重复执行两次,这样在第二次跳转后真正执行SendMessage时,原理依赖于EBP来实现的参数和局部变量的寻址将导致内存读写错误,即使侥幸没有内存错误,其运行结果也将不正确,更重要的是在函数ret时,栈不会被正确清理,这时又将跳转到未知的指令(又是一个内存访问错误)。

PS:用来判断操作系统版本到是可以。
2007-2-5 20:58
0
游客
登录 | 注册 方可回帖
返回
//