初始思路
实现功能
1.找到源程序
1.加壳:脱壳
2.多进程:
使用进程遍历工具分析
调试,CreateProcessA/W下端分析
2.去掉程序中的广告
1.广告:
对话框
网页
2.去广告(API)
DialogBoxA/W 弹出窗口
CreateWindowExA/W 创建窗口API
WinExec 启动可执行文件、打开一个网址
CreateProcelssA/W 创建进程
ShellExecuteA/W 创建进程
3.写一个连连看的外挂
1.功能:意见秒杀
2.分析+算法+模拟点击:
找到连连看数组,使用算法完成自动连接
模拟点击对应位置,实现一键秒杀
3.利用游戏本身功能函数完成一键秒杀:
分析道具,使用指南针完成自动连接
找到消除CALL,实现一键秒杀
已知条件
程序特点
分析工具
1.Ollydbg
2.Cheat Engine
3.Visual Studio
需要使用的技术:
1.MFC DLL使用MFC DLL,方便之处在于不需要自己写DLLMain的case了,直接写在Initlnstance函数中即可,且调试时使用Cstring比较方便。
2.SetWindowLong修改窗口回调函数,在自己的窗口回调函数中处理快捷键响应。
3.CallWindowProc,调用指定窗口回调函数
4.多线程
边分析边测试
在搭建完框架之后,就是边分析边测试,流程如下:
1.先去广告2.分析数据
3.搭建框架、测试。
4.分析道具CALL、测试5.分析消除CALL,测试
分析
CreateProcess
WriteProcessMemory
ResumeThread
提取源程序
方法一:从内存dump下exe
http://www.kanhaige.com/post-67.html
方法二:
栈回溯rand
跳转到随机数并且下断点,点击“练习”
调用堆栈窗口找到调用这个函数的地址
代码
创建MFC的静态共享库
//stdafx.h
//增加三个消息的宏定义
#define WM_DATA1 WM_USER+1
#define WM_DATA2 WM_USER+2
#define WM_DATA3 WM_USER+3
// MFCLLK.cpp: 定义 DLL 的初始化例程。
//
#include "stdafx.h"
#include "MFCLLK.h"
#include "CMyDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
//
//TODO: 如果此 DLL 相对于 MFC DLL 是动态链接的,
// 则从此 DLL 导出的任何调入
// MFC 的函数必须将 AFX_MANAGE_STATE 宏添加到
// 该函数的最前面。
//
// 例如:
//
// extern "C" BOOL PASCAL EXPORT ExportedFunction()
// {
// AFX_MANAGE_STATE(AfxGetStaticModuleState());
// // 此处为普通函数体
// }
//
// 此宏先于任何 MFC 调用
// 出现在每个函数中十分重要。 这意味着
// 它必须作为以下项中的第一个语句:
// 出现,甚至先于所有对象变量声明,
// 这是因为它们的构造函数可能生成 MFC
// DLL 调用。
//
// 有关其他详细信息,
// 请参阅 MFC 技术说明 33 和 58。
//
// CMFCLLKApp
BEGIN_MESSAGE_MAP(CMFCLLKApp, CWinApp)
END_MESSAGE_MAP()
// CMFCLLKApp 构造
CMFCLLKApp::CMFCLLKApp()
{
// TODO: 在此处添加构造代码,
// 将所有重要的初始化放置在 InitInstance 中
}
// 唯一的 CMFCLLKApp 对象
CMFCLLKApp theApp;
WNDPROC g_OldhProc;
// CMFCLLKApp 初始化
LRESULT CALLBACK WindowProc(
_In_ HWND hWnd,
_In_ UINT Msg,
_In_ WPARAM wParam,
_In_ LPARAM lParam)
{
if (Msg == WM_DATA1)
{
//调试技巧
//_asm {
// mov eax,eax
// mov eax,eax
//}
_asm {
mov ecx, 0x45DEBC
mov ecx,[ecx]
lea ecx,DWORD PTR DS:[ecx+0x494]
push 0xF0
push 0
push 0
mov eax,0x0041E691
call eax
}
return DefWindowProc(hWnd, Msg, wParam, lParam);
}
else if (Msg==WM_DATA2)
{
//1.获取可以连接的两个点
POINT pt1 = { 0 };
POINT pt2 = { 0 };
//调试技巧
//_asm {
// mov eax,eax
// mov eax,eax
//}
_asm {
mov ecx, 0x45DEBC
mov ecx, [ecx]
lea ecx, DWORD PTR DS : [ecx + 0x494]
mov ecx, DWORD PTR DS : [ecx + 0x19F0]
lea eax, pt1.x
push eax
lea eax, pt2.x
push eax
mov eax ,0x0042923F
call eax
}
CString strCode;
strCode.Format(L"点1 x=%d,y=%d,点2 x=%d,y=%d", pt1.x, pt1.y, pt2.x, pt2.y);
OutputDebugString(strCode);
if (pt1.x==0&&pt1.x==pt1.y)
{
return DefWindowProc(hWnd, Msg, wParam, lParam);
}
//2.调用消除call
_asm {
//传递ecx
mov ecx, 0x45DEBC
mov ecx, [ecx]
//第一个参数,固定值
push 0x4
//第二个参数:坐标点数组
lea eax, DWORD PTR DS : [ecx + 0x494]
mov eax, DWORD PTR DS : [eax + 0x19F0]
add eax,0x40
push eax
//第三个参数 坐标点1
lea eax, pt1.x
push eax
//第四个参数 坐标点2
lea eax, pt2.x
push eax
//第五个参数
lea eax, DWORD PTR DS : [ecx + 0x494]
mov eax, DWORD PTR DS : [eax + 0x19F0]
mov eax, DWORD PTR DS : [eax + 0x4]
push eax
//第六个参数
push 0
mov eax,0x0041C68E
call eax
}
return DefWindowProc(hWnd, Msg, wParam, lParam);
}
return CallWindowProc(g_OldhProc, hWnd, Msg, wParam, lParam);
}
unsigned _stdcall ThreadProc()
{
//模态对话框
CMyDlg pDlg;
pDlg.DoModal();
return 0;
}
BOOL CMFCLLKApp::InitInstance()
{
CWinApp::InitInstance();
//1.通过查找窗口,获取窗口句柄
m_Wnd = ::FindWindow(NULL, L"QQ连连看");
if (NULL == m_Wnd)
{
OutputDebugString(L"无法找到 QQ连连看窗口");
return false;
}
//2.设置窗口回调函数
g_OldhProc = (WNDPROC)SetWindowLong(m_Wnd, GWL_WNDPROC, (LONG)WindowProc);//设置窗口句柄(窗口句柄,索引值,)
if (NULL == g_OldhProc)
{
OutputDebugString(L"设置窗口回调函数 失败");
return false;
}
//3/弹出对话框
_beginthreadex(0, 0, _beginthreadex_proc_type(ThreadProc), 0, 0, 0);
return TRUE;
}
创建CMyDlg的窗口类
//CMyDlg.cpp
//添加的三个按钮
#include "stdafx.h"
#include "MFCLLK.h"
#include "CMyDlg.h"
#include "afxdialogex.h"
void CMyDlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
//响应指南针
CMFCLLKApp* pApp = (CMFCLLKApp*)AfxGetApp();//返回的是the APP对象的指针
pApp->m_Wnd;//获取窗口的句柄
::SendMessage(pApp->m_Wnd, WM_DATA1, 0, 0);
}
void CMyDlg::OnBnClickedButton2()
{
// TODO: 在此添加控件通知处理程序代码
CMFCLLKApp* pApp = (CMFCLLKApp*)AfxGetApp();//返回的是the APP对象的指针
pApp->m_Wnd;//获取窗口的句柄
::SendMessage(pApp->m_Wnd, WM_DATA2, 0, 0);
}
void CMyDlg::OnBnClickedButton3()
{
// TODO: 在此添加控件通知处理程序代码
//循环消除
CMFCLLKApp* pApp = (CMFCLLKApp*)AfxGetApp();//返回的是the APP对象的指针
for (int i=0;i<100;i++)
{
int Ret = ::SendMessage(pApp->m_Wnd, WM_DATA2, 0, 0);
if (Ret==-1)
{
break;
}
}
}