美文网首页
QQ连连看小外挂

QQ连连看小外挂

作者: MagicalGuy | 来源:发表于2018-10-10 00:48 被阅读0次
    1. 找到程序本身的 exe
    2. 去掉程序中的广告
    3. 写一个 QQ 连连看的外挂

    先双击运行 qqllk.exe,出现一广告窗口,后点击开始游戏按钮,出现另外一个百度广告窗口。
    通过 PChunter32 查看可知 qqllk.ocx 是 qqllk.exe 的子进程广告程序,qqllk.exe 又是 explorer.exe
    的子进程。在百度广告窗口点击继续按钮就打开了真正的游戏窗口 kyodai.exe。

    image.png

    然后使用 PEid 扫描程序所在文件夹就知道存在这三个程序执行文件。

    image.png

    Qqllk.exe delphi 程序
    Qqllk.ocx 是一个加 aps 壳可执行文件
    Keyodai.exe 可执行文件
    发现直接打开 keydai.exe 运行不了游戏
    火绒剑检测 Qqllk.ocx 行为,发现修改了 Keyodai.exe

    image.png

    想要了解程序的执行流程,看看程序之间到底干了什么,可以直接把 qqllk.exe 拖到 OD
    CreateWindowExW CreateProcessW api 下断点

    系统 api 代码

    image.png image.png

    第一个广告窗口


    image.png

    第二个程序进程


    image.png

    第二个广告窗口


    image.png

    打开第二个 OD,附加或者直接打开第二个广告程序,但是要先设置 strongOD 才能调试多个


    image.png

    然后重启 OD。
    CreateprocessA 或 W 下断点

    image.png

    查看到 kyodai.exe 被创建即被挂起

    image.png

    直接用另一个 OD 打开游戏程序找到 winmain 函数


    image.png

    跟进去看看
    一看貌似没有恢复

    image.png

    当执行完第二个广告后 Winmain 代码被改变,游戏程序便能正常执行


    image.png

    猜测是第二个广告程序在创建游戏进程挂起的时候修改了 winmian 的地方。
    那么我们可以在 Qqllk.ocx 程序中的 resumethread 和 writeprocessmemory 下断点

    image.png

    然后执行唤起操作

    image.png

    由此去广告暂时有了两个方案:
    1、只要启动 keyoai.exe 到指定的 0x43817A 地址上修改,使用 loadPE 计算出这个地址在文件
    中的位置,然后将其值修改成 0 就可以了。
    2、通过运行第二个广告程序后,运行到游戏程序的 OEPC 处直接 dump。

    直接用第二种方式:
    现在第一个 OD 运行 Qqllk.ocx,执行到唤起处,
    另外一个 OD 附加 keyoai.exe,然后查看内存,查看 PE 头,找到 OEP 下断,
    第一个 OD 继续执行,另外一个 OD 继续执行到 OEP 处直接 dump 出来即可。

    image.png

    到此处 dump

    image.png

    然后可以直接双击打开运行 dump 出来的程序,即可正常运行。
    /*思路一 : 指南针 配合清除函数
    1.根据 ce 搜索到减少道具数值的地方
    2.跟出减少道具数值函数
    3.来到 调用减少道具数值函数的地方

    1. 查找是谁调用的减少道具数值函数
      5.即可找到关键点 道具分发函数 f0-fb 间
      6.可以通过该函数调用多个道具
      */
      思路二 : 查找炸弹函数

    可以先从简单的思路二入手,尝试查找炸弹函数,内联汇编调用
    经过观察,可以通过炸弹的声效文件 flystar.wav 查找所有参考文本字串

    image.png

    查找所有命令 push 00459250

    image.png

    全部命令下断点
    再次运行游戏,玩到点击炸弹的时候,断点在下图

    image.png

    然后查看堆栈调用

    image.png

    回车,在此下断点,重新运行游戏(注意每次运行游戏可以选 A 级别然后点击练习可以简
    单点),玩到获得炸弹道具后,点击炸弹道具,运行到此后单步步过执行

    image.png

    执行到此发现 edx 发生变化,多次执行其他道具可以发现

    image.png

    指南针对应 edx = F0
    重列对应 edx = F1
    炸弹对应 edx = F4
    执行完 0041de5c 处后断到 0041ec07,执行完后炸弹减少,两个卡牌消失
    在此往上找到 case F4,可知是道具分支调用

    image.png

    因此 0041de5c 处 call 的是道具分发函数
    由此内嵌调用以下汇编代码即可调用炸弹做出一个小外挂

    0041DE4D |. 8B86 94040000 MOV EAX,DWORD PTR DS:[ESI+0x494] ; dump.0044CE70
    0041DE53 |. 8D8E 94040000 LEA ECX,DWORD PTR DS:[ESI+0x494]
    0041DE59 |. 52 PUSH EDX
    0041DE5A |. 53 PUSH EBX
    0041DE5B |. 53 PUSH EBX
    0041DE5C |. FF50 28 CALL DWORD PTR DS:[EAX+0x28]

    据观察,edx,ebx的赋值容易,但是要找esi的值。

    image.png

    但是由于栈保存的值不是固定的,所以要找到固定的。

    可以打开CE软件,打开调试进程查找12A1F4,找到几个静态地址

    image.png

    经过测试上面三个绿色地址都可以赋值给esi。

    下面就可以编写外挂插件

    新建MFC DLL 工程

    image.png

    关键文件代码如下:

    QQPlugin.cpp

    #include "stdafx.h"
    
    #include "QQPlugin.h"
    
    #include "QQPlugindll.h"
    
    #ifdef _DEBUG
    
    #define new *DEBUG_NEW*
    
    #endif
    
    // CQQPluginApp
    
    *BEGIN_MESSAGE_MAP*(CQQPluginApp, *CWinApp*)
    
    *END_MESSAGE_MAP*()
    
    // CQQPluginApp 构造
    
    CQQPluginApp::CQQPluginApp()
    
    {
    
    // TODO:  在此处添加构造代码,
    
    // 将所有重要的初始化放置在 InitInstance 中
    
    }
    
    // 唯一的一个 CQQPluginApp 对象
    
    CQQPluginApp theApp;
    
    // CQQPluginApp 初始化
    
    #define WM_MOD_WINNAME *WM_USER*+110
    
    *LRESULT* *CALLBACK* WindowProc(*HWND* hWnd, *UINT* uMsg,*WPARAM* wParam, *LPARAM* lParam)
    
    {
    
    if (uMsg== WM_MOD_WINNAME)
    
    {
    
    *OutputDebugString*(L"ok");
    
    }
    
    else if (uMsg== *WM_KEYDOWN*)
    
    {
    
    if (wParam== *VK_F**1*)
    
    {
    
    int BaseAddr = 0x45DEBC;
    
    int m_Esi = *(int*)BaseAddr;
    
    _asm
    
    {
    
    mov esi, [m_Esi];
    
    mov eax, dword *ptr* ds : [esi + 0x494];
    
    lea ecx, dword *ptr* ds : [esi + 0x494];
    
    *push* 0xf4;
    
    *push* ebx;
    
    *push* ebx;
    
    *call*dword *ptr* ds : [eax + 0x28];
    
    }
    
    }
    
    return *DefWindowProc*(hWnd, uMsg, wParam, lParam);
    
    }
    
    return *CallWindowProc*(theApp.m_pOldProc, hWnd, uMsg, wParam, lParam);
    
    }
    
    *UINT* __stdcall ThreadProc(*PVOID* pVar)
    
    {
    
    // 初始化,防止崩溃
    
    *AFX_MANAGE_STATE*(*AfxGetStaticModuleState*());
    
    QQPlugindll* pDlg= new QQPlugindll;
    
    pDlg->*Create*(IDD_DIALOG1);
    
    pDlg->*ShowWindow*(*SW_SHOW*);
    
    pDlg->*RunModalLoop*();
    
    return 0;
    
    }
    
    *BOOL* CQQPluginApp::InitInstance()
    
    {
    
    //CWinApp::InitInstance();
    
    *OutputDebugString*(L"InitInstance");
    
    m_hMainWnd= *FindWindow*(*NULL*, L"QQ连连看");
    
    m_pOldProc = (*WNDPROC*)*SetWindowLongPtr*(m_hMainWnd, *GWLP_WNDPROC*,
    
    (*LONG_PTR*)WindowProc);
    
    ::*SendMessage*(m_hMainWnd, WM_MOD_WINNAME, 0, 0);
    
    // 创建线程,在线程中启动一个对话框
    
    *_beginthreadex*(0, 0, ThreadProc, this, 0, 0);
    
    return *TRUE*;
    
    }
    

    QQPlugindll.cpp

    #include "stdafx.h"
    
    #include "QQPlugin.h"
    
    #include "QQPlugindll.h"
    
    #include "afxdialogex.h"
    
    // QQPlugindll 对话框
    
    *IMPLEMENT_DYNAMIC*(QQPlugindll, *CDialogEx*)
    
    QQPlugindll::QQPlugindll(*CWnd** pParent /*=NULL*/)
    
    : *CDialogEx*(IDD_DIALOG1, pParent)
    
    {
    
    }
    
    QQPlugindll::~QQPlugindll()
    
    {
    
    }
    
    void QQPlugindll::DoDataExchange(*CDataExchange** pDX)
    
    {
    
    *CDialogEx*::*DoDataExchange*(pDX);
    
    }
    
    *BEGIN_MESSAGE_MAP*(QQPlugindll, *CDialogEx*)
    
    *ON_BN_CLICKED*(IDC_BUTTON1, &QQPlugindll::OnBnClickedButton1)
    
    *END_MESSAGE_MAP*()
    
    // QQPlugindll 消息处理程序
    
    //循环炸弹
    
    void QQPlugindll::OnBnClickedButton1()
    
    {
    
    // TODO: 在此添加控件通知处理程序代码
    
    for (int i= 0; i< 100; i++)
    
    {
    
    ::*SendMessage*(theApp.m_hMainWnd, *WM_KEYDOWN*, *VK_F**1*, 0);
    
    }
    
    }
    

    最后使用注入工具往游戏程序注入生成的dll文件,出现一个窗口,点击一键消消乐按钮后实现一键消除。

    效果图如下:

    image.png

    解决完后可以再说说思路一的做法:

    每次按练习后都会随机生成地图

    由此可以给关键api函数下断,bp rand

    image.png

    找到地图数据

    483AC8 地图数据地址

    483AC8内存拷贝给12BB50

    12BB50=[Esi+0x195C] 地图地址

    地图数组首地址是12BB50,但是数据开始的地方是12BB58,前面八个字节没用。

    在点击游戏中两张相同卡牌或点击指南针之前,找两个相同数字靠在一起的下硬件访问断点

    尝试断下来通过栈回溯找指南针函数和消除函数的地方

    image.png

    相关文章

      网友评论

          本文标题:QQ连连看小外挂

          本文链接:https://www.haomeiwen.com/subject/knayaftx.html