安卓单机游戏绘制教程10-1:认识数组
单机安卓游戏绘制教程10-2:IDA找敌人数组相关函数思路(有符号so)
单机安卓游戏绘制教程10-3:IDA找敌人数组相关函数调用关系(有符号so)
单机安卓游戏绘制教程10-4:IDA找敌人数组基址偏移(有符号so)
本文是教程10的最后一篇:遍历敌人数组,
然后今天录一个视频,展示遍历敌人数组的效果(因为我怀疑专栏文章推送几率很低,似乎很多观众不知道有这几篇专栏),如果本系列专栏对你有收获,不妨给这个效果视频点点赞,谢谢啦~
教程系列视频、专栏点过赞的用户名我会记下来,将来会发些小福利(比如开发的软件优先对你们开放测试,诸如此类)
教程11是绘图部分,然后本系列教程就完结了,补前面视频字幕,然后打算讲讲正向开发的内容(比如Bash···如果有时间),或者是做编程科普类视频···
之前答应过,发单机CF(最后战役X)修复无法飞天BUG的思路,最后战役X的GG的Xa功能思路(高空掉落不掉血、一击必杀)、静默自瞄(时间待定)、骨骼绘制(待定),这些仍然会不定期更新。
回到主题,接下来把教程10剩下部分写了:
关于坐标,从代码分析有些复杂了,直接Ctrl+B观察内存就行了,如图所示:
淡入淡出时间可以改大一些
淡入淡出我设置的6000ms,根据自己习惯改一下,
关于血量,敌人尺寸,可以看如图所示这个函数:
GmSimInitAITanks
注意GmSimAiInitTankFromLevelTankData的参数一,已经相对结构体偏移了0x40,然后在这个函数能看到血量、大小等 初始化代码:
由此可知,当前血量偏移:+0x40+0x4
最大血量偏移:+0x40+0x258
尺寸偏移:+0x40+0x214
v26可能表示“坦克种类”
另外,gAiHitPoints之类的是rodata段数据,可以双击跳转到如图所示:
可以理解成常量
现在基址偏移全都拿到了,开始写C语言代码,为了接下来写起来方便,首先封装几个函数:
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
|
uintptr_t readPtr(uintptr_t addr){
lseek64(mem_fd, addr, SEEK_SET);
read(mem_fd, &addr, sizeof(uintptr_t));
return addr;
}
char readByte(uintptr_t addr){
char res = 0;
lseek64(mem_fd, addr, SEEK_SET);
read(mem_fd, &res, sizeof(char));
return res;
}
int readInt(uintptr_t addr){
int res = 0;
lseek64(mem_fd, addr, SEEK_SET);
read(mem_fd, &res, sizeof(int));
return res;
}
float readFloat(uintptr_t addr){
float res = 0;
lseek64(mem_fd, addr, SEEK_SET);
read(mem_fd, &res, sizeof(float));
return res;
}
void readData(uintptr_t addr, int len, void* target){
lseek64(mem_fd, addr, SEEK_SET);
read(mem_fd, target, len);
}
|
关于这部分,可以参考我的这个视频:单机安卓手游绘制教程08-1:用读取文件的函数跨进程读内存
main函数
test函数代码:
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
|
void test(){
printf("test(): \n");
uintptr_t gmc = readPtr(so_addr + 0x689CC);
uintptr_t p1 = readPtr( gmc + 0x28 * readPtr(gmc + 0x120) + 0x20 );
uintptr_t p2 = readPtr( p1 + 0x20 );
uintptr_t p3 = readPtr( p2 + 0xB890 );
uintptr_t p4 = readPtr( p3 + 0x20 );
int count = readInt(p4 + 0x14) ;
printf("遍历终止条件: i < %d\n", count);
printf("\n");
int i = 0;
while( i < count){
uintptr_t p5 = p4 + 0x2d4 * i ; //敌人i的结构体地址
if( readByte(p5 + 0x48) ){
//照着IDA F5之后的代码写就行了.
printf("敌人id=%2d\tpos={%f,%f,%f}\tsize=%f\thp= %d/%d \n",
i,
readFloat(p5 + 0x19c),
readFloat(p5 + 0x19c + 4),
readFloat(p5 + 0x19c + 8),
readFloat(p5 + 0x40 + 0x214),
readInt(p5 + 0x40 + 0x4),
readInt(p5 + 0x40 + 0x258)
);
}
i++;
}
} 作者:赶码人 https://www.bilibili.com/read/cv15051215?spm_id_from=333.999.0.0 出处:bilibili
|
最终效果请看视频吧~
做教程、写文章不容易,若有收获,欢迎给视频点赞~感谢鼓励。