一、分析角色 HP/MP 地址

我们的目标是这个,热血江湖。我们要找出基本信息中,所有数据的地址。

我们要用到一款工具,CE。打开之后点击左上角打开进程,会弹出进程列表,我们需要选择游戏的进程。

我们可以点击下面的“窗口列表”,然后从打开的窗口中搜索,这样可能比较好找。

由于 HP 数值变动较快,我们把扫描类型改为“两者之间的数值”,在上面把数值设置为 352 和 370(视具体情况而定),然后点“首次扫描”。

左边就会出现结果。因为结果太多,我们不知道是哪个,需要进一步筛选。

我们把扫描类型改为“增加的数值”,点击“再次扫描”。这个很重要,因为再次扫描是在上一次的结果中搜索,可以缩小范围。游戏中一些值是不变的,可以过滤一些。

我们双击唯一的结果,它会在底部的列表中出现,双击描述可以修改名称。双击地址会弹出这样一个框。

我们可以看到,地址采用模块名称(基址)加偏移来描述。这是因为一些模块是共享库,加载时会改变基址。因为我们这是一个 EXE,不需要这个名称也可以。

接下来我们尝试寻找 MP(蓝的那个)的地址。我们不需要重新搜索。我们假设程序以int保存这些数值,而int在 windows x86/x64 上是四个字节。我们还假设这些东西是挨着存储的。所以我们将那个地址加四。

我们看到右边的 251 正好的游戏的 MP,说明我们找对了。

二、分析角色金钱基址

我们查看金币数量,是 173061:

这个数值不太可能有重的,所以我们直接搜索:

我们选上面那个,因为它和我们上节课的地址在一个段里面。

我们找到了金钱的地址。但这样一个一个找太麻烦了,有没有可能一次找到全部呢?

首先记下基本信息:

我们打开 OD 并用它附加游戏。

然后执行dd 2f86170,在左下角的窗口中,我们可以看到这个地址附近的数据。

我们双击第一行第一列,将第一列转换为偏移形式:

我们看到第二列是十六进制形式,需要将其转换为十进制。

地址 数值 属性
(0x2f86170)+0x0 381 HP
0x4 252 MP
0x8 390 愤怒值
0xc 381 最大 HP
0x10 252 最大 MP
0x14 1000 最大愤怒值
0x18 QWORD 12185 经验值
0x20 QWORD 24782 下一级所需的经验值
0x28 10
0x2c 27138 历练
0x30 51
0x34 54
0x38 31
0x3c 91
0x40 0
0x44 0

我们可以根据数值猜出绝大部分。但是 HP 之前还有个昵称,这里没有,可能我们需要向前找找。

我们点击右键,点击“文本->ASCII(32 字符)”:

-0x80的地方找到了角色名称。我们切换为十六进制视图,然后把这个地方作为新的基址:

我们得到了一些新的东西:

地址 数值 属性
(0x2f860f0)+0x0 STR - 角色名称
0x30 11
0x34 BYTE 0x17 等级
0x35 BYTE 0x1 几转
0x36 STR - 名声

并且之前那些地址需要加上0x80,这里就不再写一遍了。

我们回到 CE,可以点击右边的“手动加入地址”,保存它们。

三、分析角色气功加点

这次我们要分析角色的气功点数:

我们首先寻找第一个,因为其它气功很可能在第一个后面。

并且,我们不知道这个属性用几个字节来表示。但如果多于一个字节,那么14应该在它的最低字节。也就是说,无论怎么表示,我们都可以搜索一个字节14

(实际上气功点数最大为 20,剩余点数最大为 100,不超出一个字节的最大值。就算它多于一个字节,高字节也用不上。)

搜索结果太多了,我们让它变化一下,给它加一点变成 15,然后再搜。

最上面的两个以0x02f开头,和上一节的其它数据在同一个段里面。那么到底哪个是呢?

我们用 OD 附加进程(其它很多软件都可以),查看具体的内存布局。首先是第一个0x02f861e4

0x02f861e4是第一个气功点数,每隔0x4就有一个气功点数。0x02f861e0是剩余点数。所有点数都是一字节。

然后是第二个0x02f888a0

这个地址中没有剩余点数,而且都是紧密挨着的。

下面我们验证一下,将第二个气功的点数加一。

这是第一个地址0x02f861e0

我们看到第二个气功的点数变成了 2。

然后是第二个地址0x02f888a0

也变了,说明两个地址都有效。我们选择第一个,因为它和我们上一节的基址近一些。我们减一下,得到第一个地址的偏移是0xf0

下面我们总结一下信息:

地址 数值 属性
(0x2f860f0)+0xf0 BYTE 2 气功剩余点数
0xf4 BYTE 15 第一个气功点数
0xf0+4*i BYTE - i个气功点数

四、注入 DLL

一般来说,在同一个进程中读取数据比较方便。所以我们编写 DLL,将其注入同一个进程中。

打开 VS,新建项目,选择“MFC DLL”。创建项目完成后,我们的目录是这样:

接下来我们创建窗口,点击资源视图(左下角),然后右键添加资源对话框(Dialog):

然后我们新建类CMainDialogWnd,使用 MFC 创建类向导:

然后打开“源文件->MainDialogWnd.h”,代码是这样。

class CMainDialogWnd: public CDialogEx
{DECLARE_DYNAMIC(CMainDialogWnd)public:CMainDialogWnd(CWnd* pParent=NULL); //标准构造函数virtual ~CMainDialogWnd();//对话框数据enum { IDD = IDD_DIALOG1 }protected:virtual void DoDataExchange(CDataExchange* pDX) //DDX/DDV 支持DECLARE_MESSAGE_MAP()
}

我们打开MFC_DLL.cpp,创建全局变量:

CMainDialogWnd *PMainDialog;

CMFC_DLLApp::InitInstance中添加:

PMainDialog = new CMainDialogWnd;
PMainDialog->DoModal();
delete PMainDialog;
// 释放 DLL,以便反复注入
FreeLibraryAndExitThread(theApp.m_hInstance, 1);

但这样有个问题,这个窗口是模态的。窗口显示的时候会卡住游戏。我们可以将其放到子线程中。把上面的代码移到一个函数中:

DWORD WINAPI ShowDialog(LPARAM lpData)
{PMainDialog = new CMainDialogWnd;PMainDialog->DoModal();delete PMainDialog;// 释放 DLL,以便反复注入FreeLibraryAndExitThread(theApp.m_hInstance, 1);return TRUE;
}

CMFC_DLLApp::InitInstance中编写:

CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)ShowDialog, NULL, NULL, NULL);

我们编译它,在debug目录下面得到MFC_DLL.dll。然后我们打开CodeInEx注入工具,点击左上角的按钮:

我们首先在上面的列表中选择要注入的进程,然后点击下面的“注入DLL”按钮,会弹出一个选择框。我们在里面选择刚才的 DLL。

之后我们发现我们的窗口打开了,并且游戏还有反应。

五、手动编写注入代码

上一节中,我们使用工具来注入 DLL。这一节我们尝试自己编程来实现。

首先新建 Win32 控制台项目,在“源文件”目录下创建InjectDll.cpp(名字不重要)。

我们首先要获取窗体类名,之后要拿它获取窗口句柄。为什么这样,是因为窗体类名是永远不变的,句柄可能每次启动都要变。我们打开Spy++

句柄是D3D Window。我们在代码开头定义一个常量:

#define GameClassName "D3D Window"

我们还需要定义 DLL 的路径:

#define DllFullPath "path\\to\\your\\dll"

之后我们编写函数InjectDll

bool InjectDll()
{// 根据窗口类名获得句柄HWND hWnd = FindWindow(GameClassName, NULL);if(hWnd == NULL) return false;DWORD pid = 0;// 根据窗口句柄获取 PIDGetWindowThreadProcessId(hWnd, &pid);if(pid == 0)return false;// 根据 PID 获取进程句柄HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);if(hProcess == NULL)return false;// 在游戏内存中分配一片空间LPVOID address = VirtualAllocEx(hProcess, NULL, 256, MEM_COMMIT, PAGE_READWRITE);if(address == NULL)return false;// 写入 DLL 全路径名DWORD bytesWritten;WriteProcessMemory(hProcess, address, DllFullPath, strlen(DllFullPath) + 1, &bytesWritten);if(bytesWritten < strlen(DllFullPath))return false;// 在目标进程中启动线程// 加载动态链接库HANDLE hThread = CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLibraryA, address, NULL, NULL);// 等待WaitForSingleObject(hThread, 0xffffffff);// 回收CloseHandle(hThread);VirtualFreeEx(hProcess, address, 256, MEM_DECOMMIT);CloseHandle(hProcess);return true;
}

然后编写main

int main()
{// 注入 DLL 代码printf("注入 DLL\n");if(!InjectDll())printf("注入 DLL 失败\n");// 让控制台停住getchar();return 0;
}

编译运行之后,DLL 就被注入,我们也就能看到熟悉的窗口了。

郁金香商业辅助教程 2016 笔记 1~5相关推荐

  1. 郁金香商业辅助教程 2016 笔记 11~15

    11 背包分析 上一节中我们发现,背包对象储存物品对象的指针,并且如果某一栏没有物品,那么那个位置就是NULL.我们可以以此快速寻找某个位置的地址. 比如说,我们先把第二个位置留空,在 CE 中搜索 ...

  2. 郁金香商业辅助教程 2016 笔记 6~10

    六.相对路径 我们希望把 DLL 和这个程序放到一起,那么 DLL 路径就是程序所在路径加上 DLL 的名称. 将DllFullPath的定义注释掉,换成DllName: #define DllNam ...

  3. 2018任鸟飞郁金香骷髅易语言/C++辅助教程

    2018任鸟飞郁金香骷髅易语言/C++辅助教程 免费试看教程:链接: https://pan.baidu.com/s/1QRf-UN8qy4NDAaijYqiEKA 提取码: 3wwd 更多官方视频教 ...

  4. 大数据Hadoop教程-学习笔记02【Apache Hadoop、HDFS】

    视频教程:哔哩哔哩网站:黑马大数据Hadoop入门视频教程 教程资源:https://pan.baidu.com/s/1WYgyI3KgbzKzFD639lA-_g 提取码: 6666 [P001-P ...

  5. python课程开课吧怎么样-廖雪峰总结的Python商业爬虫教程,请查收!

    原标题:廖雪峰总结的Python商业爬虫教程,请查收! 2018 IEEE最热门48种编程语言榜,Python雄踞四项第一! 据介绍,IEEE Spectrum 的排序是综合 10 个精选线上数据源, ...

  6. 阿里云高校计划视觉AI五天训练营教程学习笔记

    阿里云高校计划视觉AI五天训练营教程学习笔记 Day 1 Topic: 视觉生产技术 定义:通过(一个或者一系列)视觉过程,产出 **新的** 视觉表达. 分类 通用基础框架 关键维度 精细理解--举 ...

  7. 《SAS编程与数据挖掘商业案例》学习笔记之十五

    继续<SAS编程与数据挖掘商业案例>读书笔记,本次重点:输出控制 主要内容包含:log窗体输出控制.output窗体输出控制.ods输出控制 1.log窗体输出控制 将日志输出到外部文件 ...

  8. 《SAS编程与数据挖掘商业案例》学习笔记之十九

    继续<SAS编程与数据挖掘商业案例>学习笔记,本文侧重数据处理实践,包括:HASH对象.自定义format.以及功能强大的正则表达式 一:HASH对象 Hash对象又称散列表,是根据关键码 ...

  9. 《SAS编程与数据挖掘商业案例》学习笔记之十六

    <SAS编程与数据挖掘商业案例>学习笔记,本次重点:sas宏变量 内容包括:宏变量.宏函数.宏参数.通配函数.字符函数.计算函数.引用函数.宏语句.宏应用 1.宏触发器: %name-to ...

  10. 《SAS编程与数据挖掘商业案例》学习笔记之十四

    继续<SAS编程与数据挖掘商业案例>学习笔记系列,本次重点:常用全程语句 所谓全程语句,是指可以用在任何地方的sas语句,既可以用在data数据步语句里面,也可以用在proc过程步里面,甚 ...

最新文章

  1. leetcode -python 三数之和原创
  2. 一篇文章带你搞定Python返回函数
  3. 一步步学习如何安装并使用SAP HANA Express Edition
  4. 如何搭建私密云存储之ownCloud
  5. C#中的变量类型(值类型、引用类型)
  6. windows键按了没反应_windows快捷键使用 - 小怜
  7. bundle中vim相关快捷键的使用
  8. 《Python程序设计开发宝典》第一波转发积攒活动中奖名单
  9. 捷信达酒店管理系统密码修改SQL语句
  10. 电话系统服务器,局域网电话系统的两种解决方案——是否需要I
  11. Postman下载及WebApi测试遇到问题点
  12. USB Type C 接口引脚详解
  13. 还在用 ZXing ? 试试华为统一扫码服务吧!
  14. Joyoshare Media Cutter for Mac(智能媒体剪辑软件)激活版
  15. java 子类克隆_Java对象克隆了解
  16. JAVA zip 压缩包 导出
  17. # 计算圆周长和面积
  18. MapStruct、ignore
  19. 2017年秋季学期软件工程第一次作业(曹洪茹)
  20. openssh移植 for pycharm 远程调试 sftp

热门文章

  1. 飘逸的python - 使用图像匹配SIFT算法进行LOGO检测
  2. C/C++之奔跑的小人(小游戏,自娱自乐)
  3. 互联网晚报 | 1月10日 星期一 | 天猫年货节正式开启;哪吒汽车第10万台量产车下线;三星永久关闭Tizen应用商店...
  4. win10编译OpenCV4Android系列2-编译OpenCV4.5.2+opencv_contrib
  5. CUDA10,Torch安装解决NOTFOUND CUDA_cublas_device_LIBRARY,Ubuntu16.04安装torch遇到的错误
  6. FudanNLP  java -based
  7. 思维模型 后天天赋(盖洛普天赋分析)
  8. wiley 期刊Stix字体问题
  9. 怎么看python帮助手册常见问题商家认证_常见问题(FAQ) - Scrapy 中文文档
  10. 笔记本电脑计算机恢复出厂设置密码,笔记本电脑怎么恢复出厂设置?