拆包简介和使用工具:

首先拆包最简单的无非就是拆取游戏资源,例如游戏立绘,音频,视频等,再深层次一点有拆取游戏配置文件,apk反编译得到部分源码等
在本文,我们只介绍拆取游戏资源和对游戏资源的后期处理,但是这里的方法不能保证所有的手游立绘都能提取,不同游戏对立绘等游戏文件的处理不同,这里只提供几种思路 XD

可能需要用到的工具有 Unity Studio ,装有 opencv 的python或C++, PhotoShop
其中
Unity Studio 是必要工具,可以用来提取市面上大部分手游的游戏资源
装有 opencv 的python或C++, PhotoShop 等可以对提取的游戏资源(立绘)进行处理,如果是要批量处理的话首推 C++ python 虽然方便但是太慢, PhotoShop 也可以进行批量处理,但是麻烦且慢

PS:如果有其他有同样功能的工具也可以,不限于上面的几个软件,点击蓝色可以进网盘下载,理论上用 python的 PIL库 更好,不过我直接用 opencv 了,导致最后生成的可执行文件比较大

提取资源的方法:

首先,如果要拆取立绘等文件,就需要对应用程序进行处理,最简单的有两种方式:

  1. 对下载的 apk 安装包 进行解压
    方法如下,在电脑上下载对应游戏的apk安装包,把后缀 .apk 改为压缩包文件格式,如 .rar 等,利用解压软件对其进行解压得到解压文件夹
  2. 对已经安装在手机的游戏,寻找系统目录,找到其文件夹
    以少女前线为例,通常在手机上安装的软件,会把资源文件等放在 Android 文件夹的 data 文件夹下,这个时候找到其对应的游戏文件夹即可,下图是 少女前线 的文件夹,明日方舟比较特殊,它将资源文件隐藏在了其他文件目录下,所以最好使用第一种方法
    在这里插入图片描述
    通常进入文件夹后按照顺序进入以下文件夹 files 文件夹—— AB 文件夹 —— Android 文件夹,会看到里面的游戏资源文件,如果你是按照第一个解压方法做的,也可以看到上面的文件路径,按照该顺序点进去就行,然后根据游戏的不同,不同的文件可能会被放在一起,也可能会被分类在不同文件夹中,这个时候只需要按照自己需要的进行 复制提取 到电脑上就好了, 注意不要剪切 ,特别是用第二种方法的, 千万别剪切

当然,到这里还没有结束,我们看到的资源文件并不是原来格式,而是以 ab后缀的文件 展示的,这个时候就需要 Unity Studio 来提取目标文件(当然不是所有手游都会用Unity,所以这个方法并不适用于所有手游,如果以后我遇到其他类型的再更新吧XD)
在这里插入图片描述
这里我们以明日方舟为例,如果你正确的找到了路径,那么你可以看到一个名为 charpack 的文件夹,其中储存了明日方舟的干员立绘文件
在这里插入图片描述
这个时候打开 Unity Studio ,用如下选项 Extract folder 批量解压提取ab文件,之后使用 load folder 加载处理后的文件
在这里插入图片描述
然后在 Asset List 中就可以看到提取的内容
在这里插入图片描述
在这里插入图片描述

资源的后续处理:

提取出来的图片大部分情况下是有瑕疵的,因为他们需要进一步处理才能得到原图
而对于其中提取的内容,我们通常需要关心很多文件
常规情况下 (使用通道分离压缩图片的):我们需要找到一个是Type为Texture2D的原图,一个是Type为Texture2D或Sprite的透明度背景图,而且通常情况下,原图有一个文件名,对应透明度背景图文件名会在原图文件名后面加上alpha字样,我们通过处理这两个图才能得到最终的png图像文件,所以现在就将所有对应的图片文件从 Unity Studio 导出
还有一些情况 ,有些手游会对图片进行加密或者是做一些额外处理:这种情况我们就需要按照情况来分析哪些文件有用,哪些文件没用,例如碧蓝航线需要使用一张图片 + 一张obj 3D模型文件来还原原图

A. 通道分离图像的合成:

首先我们在前面提到过,如果我们能找到一个是Type为Texture2D的原图,一个是Type为Texture2D或Sprite的透明度背景图,那么就说明这个立绘需要进行通道分离图像的合成来得到原图

那么这个时候我们应该如何处理呢,首先 png 图像有4个通道,前三个是 RGB 颜色通道,第四个是透明度通道,实际上为了减少图片的大小,大部分游戏厂商都会先对图片进行 ETC 等压缩算法的处理,再将透明通道单独剥离出去,以达到最大程度的压缩,其中你会发现我们经手的立绘和在游戏中展示的一样,但仔细看会发现不够清晰,正是因为在打包成apk文件之前,游戏公司就已经先对图片进行了压缩处理,丧失了一部分信息,所以说并不是画师的原图,如果想提高清晰度,有两种方法,一种是找原画师或官方公布等途径得到原图,一种是利用图片优化软件对其进行清晰度优化

进入正题,如何处理我们得到文件?

1. 利用 PS 进行处理:

这里我们直接引用一下这位贴吧老哥的方法: 透明立绘简单合成方法,小白一键操作

方法很简单,但缺点是对大量处理文件十分无力,而且需要手工对文件顺序进行排序,也没法判断两个图片尺寸比,适合小量立绘的手工处理

效果图:
在这里插入图片描述
输出效果:
在这里插入图片描述

2. 利用python或C++进行处理:

这个方法适合大量处理,而且不用对图片进行分类,甚至你在 Untiy Studio 上导出图片时,可以毫无顾忌的将图片一股脑导出来,让程序自己去找原图和透明度背景图
在这里我用到的工具是 opencv 库

以明日方舟为例: 可以发现它 Alpha 图像中 R 通道 的值代表原图片透明度,那么我只需要将这个图片矩阵的 R 通道 信息赋值给原图像的 透明度通道 即可,然后注意一下有些Alpha图像是原图像大小的 1/2 倍,需要放大 2
其中放大方法调用的是 双立方插值算法 ,这个算法效果比较好
另外就是 PhotoShop 的默认放大算法也是这个算法

python代码: (本来想用C++的,但无奈python太方便了Orz,导致处理速度会慢很多)

# -*- coding: utf-8 -*-
import shutil
import time
import cv2
import os
def read_png(s):
	img = cv2.imread(s, cv2.IMREAD_UNCHANGED)
	return img
def save_png(s, img):
	cv2.imwrite(s, img, [int(cv2.IMWRITE_PNG_COMPRESSION), 9])
def exchange(img, x): #放大图像
	w, h = img.shape[0:2]
	tempimg = cv2.resize(img,(w*x,h*x), interpolation=cv2.INTER_CUBIC)
	return tempimg
def Do(a, b):
    a[:,:,3] = b[:,:,0] #合成的基本思路
    return a
print("提取图片/合成立绘?1/2")
a = input()
if a == '1': #提取立绘
    file_list = os.listdir("./Input")
    print("共%d个图片:" %len(file_list))
    print('begin')
    for i in file_list:
      	img = cv2.imread("./Input/" + i, cv2.IMREAD_UNCHANGED)
        	if img is not None and img.shape[0] > 512:
         	if '#' in i:
          	i2 = i.replace(i[i.find('#'):], '#1[alpha].png')
            	i3 = i.replace(i[i.find('#'):], '#1.png')
         	else:
         		i2 = i.replace(".png", '[alpha].png')
         		i3 = i
         	if i2 in file_list:
         		hutil.copy("./Input/" + i, "./Texture2D_A/" + i3)
         		os.remove("./Input/" + i)
         		shutil.copy("./Input/" + i2, "./Texture2D_B/" + i2)
         		os.remove("./Input/" + i2)
    	print('over')
    	os.system('pause')
if a == '2': #合成立绘
	file_list = os.listdir("./Texture2D_A")
	print("待合成%d个图片:" %len(file_list))
    	for i in file_list:
    		print('正在处理%s' %i)
    		time_start = time.time()
    		i2 = i.replace(".png", '[Alpha].png')
    		a = read_png('./Texture2D_A/' + i)
    		b = read_png('./Texture2D_B/' + i2)
    		if a.shape[0]/b.shape[0] != 1:
    			b = exchange(b, int(a.shape[0]/b.shape[0]))
    			save_png('./Picture/' + i, Do(a, b))
    			shutil.copy("./Texture2D_A/" + i, "./Used/" + i)
    			os.remove("./Texture2D_A/" + i)
    			time_end = time.time()
    			print("耗时 %f s" %(time_end-time_start))
    	print('over')
    	os.system('pause')

具体操作就是:
1:你只需要把提取出来的立绘图像(可以包括小人动态的分割图像)放进 Input 文件夹中
2:运行exe文件,先输入 1 提取所有合理的立绘图像
3:再次运行exe文件,输入 2 合成立绘,最后图像在 Picture 文件夹中
在这里插入图片描述
其中 Texture2D_A Texture2D_B Used 都是程序运行的中间文件夹,可以不用去管,另外就是这个程序支持中断操作,也就是说你在合成图片或提取图片时因为某些原因终止了程序,那么程序会保留你之前的记录,你想要把剩余的图片处理完,只需要再次运行即可


明日方舟立绘集合 ,目前更新至2019年7月20号:
明日方舟立绘集合,提取码:5iyj
明日方舟立绘合成器 ,目前更新至2019年7月20号: 明日方舟立绘合成器,提取码:dsfd

同理,少女前线也是使用了通道分离来处理立绘图像,所以代码都差不多,就不贴了

少女前线立绘集合 ,目前更新至2019年7月27号: 少女前线立绘集合,提取码:xmts
少女前线立绘合成器 ,目前更新至2019年8月3号: 少女前线立绘合成器,提取码:50f9

B. 碎块图像合成:

比较典型的就是就是碧蓝航线,这款游戏没有用通道分离来压缩图像,而是因不明原因,将图像换成了碎块和记录碎块在原图信息的 obj 文件组成

22 举例:

碎块图(尸块图):

在这里插入图片描述
obj文件:
在这里插入图片描述
打开obj文件分析就会发现其中的 v 记录的是每个碎块在原图像的顶点坐标, 4 个为一组:
在这里插入图片描述
其中的 vt 记录的是每个碎块在碎块图像的顶点坐标(分别乘上碎块图像长和宽之后就是顶点坐标,这个小数代表在碎块图像中的比例位置),也是 4 个为一组:
在这里插入图片描述
那么通过读取 obj 文件的信息来拼接碎尸图,就可以系统的将原图拼接好

python代码:

# -*- coding: utf-8 -*-
import numpy as np
import shutil
import time
import cv2
import os
def read_file(s):
	List1 = []
	Filer = open(s,'r')
	List2 = Filer.readlines()
	Filer.close()
	for i0 in range(0, len(List2)):
		List2[i0] = List2[i0].replace("\n", "")
		List1.append(List2[i0].split())
	return List1
def read_png(s):
	img = cv2.imread(s, cv2.IMREAD_UNCHANGED)
	return img
def save_png(s, img):
	cv2.imwrite(s, img, [int(cv2.IMWRITE_PNG_COMPRESSION), 9])
def rotate(img):
	new_img = cv2.flip(img, -1)
	return new_img
def manage(s1, s2):
	s1 = "./Mesh/" + s1
	max_height = max_weight = vtjShu = firstx = endx = firsty = endy = 0
	print('正在处理%s' %s2)
	time_start = time.time()
	List = read_file(s1)
	img = read_png("./Texture2D/" + s2)
	height = img.shape[0]
	eight = img.shape[1]
	img = rotate(img)
	img = cv2.flip(img, 1
	for i in range(1, len(List)):
		if List[i][0] != 'v':
			vtjShu = i
			break
		if abs(int(List[i][1])) > max_weight:
			max_weight = abs(int(List[i][1]))
		if abs(int(List[i][2])) > max_height:
			max_height = abs(int(List[i][2])
	Base_img = np.zeros([max_height+1, max_weight+1, 4], np.uint8)
	jShu = vtjShu
	while vtjShu < len(List):
		if List[vtjShu][0] != 'vt':
			break
		firsty = int(float(List[vtjShu][1]) * float(weight) + 0.5)
		firstx = int(float(List[vtjShu][2]) * float(height) + 0.5)
		endy = int(float(List[vtjShu+2][1]) * float(weight) + 0.5)
		endx = int(float(List[vtjShu+2][2]) * float(height) + 0.5)
		y1 = abs(int(List[vtjShu-jShu+1][1]))
		x1 = abs(int(List[vtjShu-jShu+1][2]))
		for i in range(firstx, endx):
			for j in range(firsty, endy):
				Base_img[x1+i-firstx][y1+j-firsty] = img[i][j]
		vtjShu += 4
	Base_img = rotate(Base_img)
	save_png("./Picture/"+s2, Base_img)
	time_end = time.time()
	print("处理完毕,耗时 %f s" %(time_end-time_start))
Mesh_list = os.listdir("./Mesh")
Texture2D_list = os.listdir("./Texture2D")
print("检测到%d组" %len(Texture2D_list))
for i in range(0, len(Texture2D_list)):
	s = Texture2D_list[i].replace(".png", "-mesh.obj")
	if s not in Mesh_list:
		print("Can't find the %s in Mesh" %s)	
	else:
		manage(s, Texture2D_list[i])
		shutil.copy("./Texture2D/" + Texture2D_list[i], "./Used/" + Texture2D_list[i])
		os.remove("./Texture2D/" + Texture2D_list[i])
print("Over")
os.system("pause")


碧蓝航线立绘集合 ,目前更新至2019年7月31号:
碧蓝航线立绘集合,提取码:65wf
碧蓝航线立绘合成器 ,目前更新至2019年8月5号: 碧蓝航线立绘合成器,提取码:slcg

具体操作就是:
1:你只需要把提取出来的立绘图像放在 Texture2D 中,而 obj 文件放进 Mesh 文件夹中,不必考虑顺序问题,程序会自己找
2:运行exe文件即可,最后结果在 Picture 文件夹中
在这里插入图片描述
其中 Used 是程序运行的中间文件夹,可以不用去管,另外就是这个程序跟上一个明日方舟立绘合成的程序一样也支持中断操作,所以中途暂停再运行是会按照原来的进度继续,而不是从头开始

C. 其他类型待更

其他手游的资源提取方法和后期处理方法可能会有所不同,而有些手游则相同,所以需要变通,如果有时间的话这个博客应该会一直更新

本人拆包立绘仅出于学习目的,不用做商业用途 (舔老婆 prpr)

蓝毒小天使天下第一!本文拆包教程不限于明日方舟,在后面也会给出其他手游的拆包教程,例如少女前线首先拆包最简单的无非就是拆取游戏资源,例如游戏立绘,音频,视频等,再深层次一点有拆取游戏配置文件,apk反编译得到部分源码在本文,我们只介绍拆取游戏资源和对游戏资源的后期处理(因为另外两个讲道理我也没太搞懂,虽然可以提取游戏配置文件,但似乎大部分重要的数据都有加密,反编译出来的源码也只是部分,...
0:30 2011-12-10 更新下程序的版本 \解包工具& 教程 (0 folders, 5 files, 649.65 KB, 649.65 KB in total.)   demo.exe 625.67 KB 重做下录像   Readme.txt 506 bytes   UnFSPak.exe 19.75 KB   UnFSPak.ini 63 bytes   WinUnFSPak.exe 3.92 KB 升级到 0.981 19:23 2011-12-9 @JuncoJet \WinUnFSPak (0 folders, 4 files, 730.15 KB, 730.15 KB in total.)   demo.exe 706.42 KB 演示录像   UnFSPak.exe 19.75 KB 命令行解包工具   UnFSPak.ini 63 bytes 配置文件   WinUnFSPak.exe 3.91 KB 图形化解包工具
这是一款提取 游戏 资源的工具 开发环境:Windows XP SP2,Core2Duo E6700、内存 2 GB VC 2005 Express Edition运行环境:Windows XP Vista Win7 如何使用? 打开,请选择文件-> 打开的文件或窗口打开您想要部署并拖放的存档文件。 如果打开的文件支持与如此諦めれ (Oh 不相符,则打开但是,如果存档文件的内容是 AHX、 BMP、 JPG、 MID、 MPG、 OGG、 PNG、 WAV、 WMV 揪出可能的。[解压缩],选择您要检索的文件以后打开-k 是 > 选择中提取。如果您想要检索所有提取-k 是 > 提取所有。 此外,双击所选的文件的意见发挥是可能的。 基本设置列表设置字符颜色和背景色要显示文件信息的列表。 如何指定的颜色表示 16 小数 RGB (RRGGBB 格式)。 若要搜索文件或查找哪些类型的文件从归档文件不兼容设置。 如果您知道已存档的文件来检查只是可取 (表面速度)。精度的搜索OGG 寻找只能用"OggS",看看小小的检查设置。 我通常保持精度,以避免误报,很好。 提取设置-为每个文件夹中提取当您检查文件夹名称中包含要提取的文件夹来生成的文件的文件名。 -固定 OGG 文件 CRC当您检查正确的 CRC,以提取。不能播放由于 CRC 不匹配,可能能够在正确的 CRC 中发挥 OGG。 简单的解码功能,以实现和标记,会有人用简单的解码过程加密的文件。 到目前为止唯一脚本文件的 bmp、 jpg、 mpg、 ogg、 png、 tlg、 吉 hagil 里。 输出图像格式输出图像的文件格式。 谁想要最小化 PNG 是更好的空间。 0 表示无压缩的压缩级别,9 最大压缩。 此外,原始文件 (如 JPG 或 PNG 的 JPG 或 PNG 输出。 -执行 alpha 混合如果您检查,背景颜色设置为 alpha 混合和输出的 24 位。 好,如果不需要的 alpha 值,则检查。-背景色要使用 alpha 混合时价值。 如何指定的颜色表示 16 小数 RGB (RRGGBB 格式)。 -目标每次您提取对话框中显示指定每个指定目的地的时间。 "同一目的地文件夹"创建一个文件夹具有相同的名称和文件打开的如果到位置打开的文件和输出中。 存储文件具有相同的名称和它的位置创建一个文件夹,如果一个。 如果下面的文件夹,设置如下的输出文件夹。 缓冲区大小内存,用于提取文件的大小。 -临时文件夹一个位置来提取临时视图,如果您通过双击播放。 当您打开存档文件或当您退出 ExtractData 时,将删除暂时提取的文件。
bool LobbyServer::SendPbMsgToClient(PlayerNode *lpPlayerNode, unsigned short type, void *buf, long len, int end) __log(_ERROR, __FUNCTION__, "type[%d],len[%d],end[%d]", type, len, end); tagNetMsg pNe
每天学习一点新知识(一)——Unity开发 游戏 的解包 用了CSDN有一段时间了,但一直都没有写过blog,只是在输入,没有输出。而且一直主要都是在查一些作业、题解什么的,还是希望自己能够多学到一些新东西吧,不管是语言也好,技术也好,提高自己就可以。 所以打算写这么一个系列,就是每天学一点新知识、每天有一点提高。可能其中主要的还是学习一些CSDN和Github上的小项目,争取每周写一篇,如果简单的话...
简单 python 爬虫爬取 游戏 wiki 立绘 玩二次元 手游 是感叹美少女 立绘 真好看啊,可惜就是抽不到,于是看到b站wiki上有角色 立绘 ,就写了个爬虫准备将 立绘 趴下来欣赏(舔)。 本人爬虫的技术只算是初学,代码大家看个乐就成^_^ 例如,爬取 手游 碧蓝档案的 游戏 立绘 流程就是,首先爬取角色列表页面,获得每个角色详情页面的链接,之后进入每个角色页面,将角色 立绘 下载下来。 from bs4 import BeautifulSoup import re import urllib.request,urllib.
Ren’Py 是一个视觉小说引擎,全球数千名创作者都在使用它,它可以帮助您使用文字,图像和声音来讲述在计算机和移动设备上运行的交互式故事。这些既可以是视觉小说,也可以是生活模拟 游戏 。易于学习的脚本语言允许任何人有效地撰写大型视觉小说,而其 Python 脚本足以用于复杂的模拟游。 首先列出所需的工具: 【1】Renpy引擎: https://www.renpy.org/latest.html 【2】unrpyc+ python 2: https://github.com/CensoredUsername/unrp
### 回答1: "圣女战旗"是一款冒险战斗类 游戏 ,在 游戏 中,玩家可以扮演各种 游戏 角色进行战斗和探险。 游戏 中的角色 立绘 是提供 游戏 玩家了解和认识角色外貌特征的重要组成部分。 这款 游戏 提供的 游戏 角色全身免扣PNG 立绘 ,意味着角色的 立绘 图像没有背景,可以直接使用。这方便了玩家在制作宣传海报、编辑视频、设计 游戏 界面等方面的创作。玩家可以根据自己的需求,将 立绘 图像与背景、特效等进行组合,创造出更具个性和创意的形象。 通过 游戏 角色全身免扣PNG 立绘 ,玩家可以更加直观地了解角色的服饰、装备、姿势等细节,从而更好地展示角色的个性和特点。 立绘 的精细细节和丰富表情也能够增加玩家对角色的情感共鸣,进一步提升 游戏 的沉浸感和可玩性。 在 游戏 角色全身免扣PNG 立绘 的基础上,玩家还可以通过自己对角色的创作和改编,打造出更加独特和个性化的形象。这种自由度和创造性可以激发玩家的想象力和创作力,使得 游戏 角色在玩家心目中的形象更加丰富多样。 总之,圣女战旗 游戏 角色全身免扣PNG 立绘 为玩家提供了更大的创作空间和表现力,帮助玩家更好地展示和赋予 游戏 角色个性和深度。这种 立绘 形式为 游戏 的美术效果和玩家体验增添了更多的亮点和魅力。 ### 回答2: 《圣女战旗》是一款受欢迎的 游戏 ,角色们的 立绘 以全身免扣png格式呈现。PNG格式是一种支持透明背景的图片格式,因此在 游戏 中使用这种 立绘 可以更好地展示角色的细节和动态。 这些 立绘 是以圣女战旗 游戏 中各个角色的形象为基础绘制而成的。每个角色都经过精心设计和绘制,从头到脚的细节都被展现出来。这些 立绘 的像素化效果非常高,可以轻松适应不同的屏幕分辨率和 游戏 界面要求。 使用全身免扣png 立绘 的好处是,玩家可以将角色 立绘 放置在 游戏 画面的任何位置,而不必为背景的颜色和元素所限制。这样一来,角色 立绘 可以更加融入 游戏 场景,增强了 游戏 的沉浸感。 另外,全身免扣png 立绘 在制作海报和宣传材料时也非常实用。开发者可以使用这些 立绘 来制作精美的海报、广告和宣传画,吸引更多的玩家来体验 游戏 。 总的来说,圣女战旗 游戏 角色的全身免扣png 立绘 非常有助于增强 游戏 的画面效果和推广效果。这些 立绘 的高像素化和透明背景使其在 游戏 中具有更好的表现力和灵活性,为 游戏 玩家提供更好的 游戏 体验。 ### 回答3: 《圣女战旗》是一款富有创新的 游戏 ,该 游戏 的角色 立绘 是以全身免扣png的形式呈现的。这种形式的 立绘 呈现方式,有着诸多优点。 首先,全身免扣png 立绘 可以完整地展现 游戏 角色的造型和细节。玩家可以清晰地看到角色的服饰、装备以及其他饰品等。这样一来,玩家可以更加直观地了解角色的形象和特点,增强了 游戏 的可玩性。 其次,全身免扣png 立绘 可以提供更大的自由度。由于该 立绘 形式将角色完整地呈现出来, 游戏 设计师可以更加自由地给予角色动作和表情,增加了角色的丰富性和活力。玩家在 游戏 中观看到的角色 立绘 将更加生动逼真。 再次,全身免扣png 立绘 方便制作和使用。这种形式的 立绘 可以方便地与 游戏 场景和其他元素进行组合。 游戏 开发人员可以根据需要调整 立绘 的大小和位置,使其完美地融入 游戏 界面。同时,该 立绘 可以独立于背景,方便进行替换和编辑,提高了 游戏 制作的效率和灵活性。 综上所述,圣女战旗 游戏 角色全身免扣png 立绘 具有展现细节、提供自由度和方便使用等优点。这种 立绘 形式为 游戏 增添了更多的乐趣和互动,使玩家能够更好地融入 游戏 世界中。