目录

10-1:认识数组

目录

做教学视频又耗时又累,白嫖率(收藏和点赞的比例)偏高(如下图所示),并且本人录制和剪辑效率低,蚌埠住了,

https://cdn.jsdelivr.net/gh/xinqinew/pic@main/img/c22244e459d9a95da77bb2f3811fcad7f1ce433b.png

如果直接摆烂宣布放弃,会愧对于 点过赞、投过币、充过电的朋友,所以停更是不可能的,本系列教程剩下的部分做成图文版,这样也能提高你的浏览效率;大约每2000字~3000字发布一次。

前面的教程1~9在视频的开头都有一个目录,那个目录就是个大致方向,从这期开始不展示目录了,本系列教程写完之后会有一篇文章专门用于导航。

有问题直接在文章底部评论,我懂的问题会回复,同时也欢迎在本文评论区纠错。

本系列教程【新手向】(本人在此方面也算初学者),大佬勿喷。

https://cdn.jsdelivr.net/gh/xinqinew/pic@main/img/4adb9255ada5b97061e610b682b8636764fe50ed.png

这里以坦克英雄激光战争为例(因为它是纯粹的单机游戏,并且多年未更新;后文简称"T游戏"),纯路人不必担心本文破坏游戏体验(相反,逆向工程会维护游戏环境、提升你的游戏体验),本文与各种联网游戏完全无关,本文内容仅供学习IDA基本操作,提高编程开发以及逆向工程的学习兴趣,以及为将来的维护游戏安全、反外挂工作提供思路、“埋下种子”。

https://i0.hdslb.com/bfs/article/db75225feabec8d8b64ee7d3c7165cd639554cbc.png

准备好IDA,本系列教程不需要懂汇编,跟着我无脑F5看伪代码,会看LR寄存器就够了。

首先要知道,通常游戏逆向领域所谓的找数组,数组是最常见的用于存储敌人信息的结构,这个数组当中的每个元素都对应着一个敌人的结构体,数组里的元素可能是这个结构体的地址(大部分游戏是这样的),也可能直接就是某个结构体(某个结构体类型的数组,T游戏是这种)。

这里随便举个例子吧(虽然意义不大):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include <stdio.h>

struct Role{
	int hp; //血量
	float x;
	float y;
	float z;
  	//...实际上,属性会多的很,并且可能有指向另一个结构体(比如武器)的指针,这里省略...
};

#define ROLE_MAX_COUNT 20

struct GameData1{
	int roleCount; //敌人实际数量
	struct Role* roles[ROLE_MAX_COUNT]; //敌人数组
	//...省略
} gd1;

struct GameData2{
	int roleCount; //敌人实际数量
	struct Role roles[ROLE_MAX_COUNT]; //敌人数组
	//...省略
} gd2;

int main(void){
	gd1.roleCount = 3;
	struct Role r1, r2, r3;
	r1.hp = 100;
	r1.x = 1;
	r1.y = 2;
	r1.z = 3;

	r2.hp = 90;
	r2.x = 10;
	r2.y = 2;
	r2.z = 30;
	
	r3.hp = 95;
	r3.x = 30;
	r3.y = 2;
	r3.z = 20;
	gd1.roles[0] = &r1;
	gd1.roles[1] = &r2;
	gd1.roles[2] = &r3;
	
	gd2.roleCount = 3;
	
	gd2.roles[0].hp = 100;
	gd2.roles[0].x = 1;
	gd2.roles[0].y = 2;
	gd2.roles[0].z = 3;
	
	gd2.roles[1].hp = 90;
	gd2.roles[1].x = 10;
	gd2.roles[1].y = 2;
	gd2.roles[1].z = 30;
	
	gd2.roles[2].hp = 95;
	gd2.roles[2].x = 30;
	gd2.roles[2].y = 2;
	gd2.roles[2].z = 20;
	
	getchar();
	
	return 0;
}

代码中gd1和gd2就是两种不同的敌人数组的形式,

用NDK编译,推到手机运行,ce+ceserver附加(我前面视频教程演示过,本文省略),添加地址两次,分别直接写gd1和gd2:

https://cdn.jsdelivr.net/gh/xinqinew/pic@main/img/c6bbce2ff2b6b2a0bbe76902c5e0be3f7e94d6bc-20220130104216638.png

https://cdn.jsdelivr.net/gh/xinqinew/pic@main/img/5cdcfd214bae69bffa16782477bd0a175a7f09f1.png

https://cdn.jsdelivr.net/gh/xinqinew/pic@main/img/4d8049d8d502f1fae62ad3e51af5f906d80c28cd.png

情况一

https://cdn.jsdelivr.net/gh/xinqinew/pic@main/img/9cba49d0809e29afcf94aa4362d960b123f6d455.png

情况二

GG视角:

https://cdn.jsdelivr.net/gh/xinqinew/pic@main/img/cd06a9660f36866ea875e6aa5bbb3efd7b407a67.png

情况一(GG视角)

https://cdn.jsdelivr.net/gh/xinqinew/pic@main/img/fab9c0f69a3ee18458e9f6eae218309ac9248ee1.png

情况二(GG视角)

拿捏了敌人数组,就可以获取全部敌人的各种属性了,比如坐标和血量。

https://cdn.jsdelivr.net/gh/xinqinew/pic@main/img/4adb9255ada5b97061e610b682b8636764fe50ed.png

蚌埠住了,时间太晚了,天亮继续更新