-
-
[原创]《我叫mt》数据包解包记录(java版)
-
发表于:
2013-6-14 11:47
14158
-
临时会员,希望这个可以成为转正贴。
看到用ida获取key,然后用npk方法解包的帖子,但是本人是java出身,而且汇编也不好,gdb也不会用,就想到用代码直接解包。
思路:
1、找到文件列表。(# ID处就是文件列表开始的地方。)
2、把文件数据和文件列表数据分开。
3、根据文件列表还原文件数据。
首先,第一步,找# ID,
第二步,写代码分离后面和前面的数据。
结果如图
部分关键代码:
//首先分离文件索引
args = ("cutfile -out "+INDEX_FILE+" -in "+DATA_FILE+" -off 0x3982e19 -len 0x39a0090").split(" ");
cutdata = new CutData();
result = cutdata.parseParams(args);//这里就是解析参数,输入文件,输入文件,数据开始位置和长度
if (result.equals(Tool.PARSE_SUC)) {
cutdata.excute();
} else {
cutdata.failed();
}
//分离出数据包
args = ("cutfile -out "+RESOURCE_FILE+" -in "+DATA_FILE+" -off 0 -len 0x3982e19").split(" ");
cutdata = new CutData();
result = cutdata.parseParams(args);//这里就是解析参数,输入文件,输入文件,数据开始位置和长度
if (result.equals(Tool.PARSE_SUC)) {
cutdata.excute();
} else {
cutdata.failed();
}
//分离方法
public void excute() {
//这里的参数就是从上面那个方法解析出来的。
String outfile = mparams[OUT_FILE];
String infile = mparams[IN_FILE];
String start = mparams[START_FILE];
String end = mparams[FILE_LEN];
int dataoff = Utils.parseString(start);
int dataLen = Utils.parseString(end);
// Utils.makeFile(outfile);
byte[] data = Utils.getArrayByte(infile);//这个是读取文件,转成数组。
if (data != null) {
if (dataLen > data.length - dataoff) {
dataLen = data.length - dataoff;
}
byte[] dest = new byte[dataLen];
System.arraycopy(data, dataoff, dest, 0, dataLen);//拷贝数组
Utils.writeFile(dest, outfile);//写入输出文件。
} else {
Debug.print("没有获取到数据呢。");
}
}
第三步,根据数据文件从里面还原文件。
//从数据包里面分离数据文件。
args = ("splitmt -outfolder "+OUT_FOLDER+" -infile " +RESOURCE_FILE+" -indexfile "+INDEX_FILE).split(" ");
cutdata = new SplitMTData();
result = cutdata.parseParams(args);//解析参数,就是输出文件夹,解析文件路径,索引文件路径。
if (result.equals(Tool.PARSE_SUC)) {
cutdata.excute();
} else {
cutdata.failed();
}
//还原方法
public void excute() {
//从上面参数取得
String root = params[IDX_OUT];
String infile = params[IDX_IN];
String indexfile = params[IDX_INDEX];
Utils.makeFolder(root);
byte[] inarray = Utils.getArrayByte(infile);
String index = new String(Utils.getArrayByte(indexfile));
StringBuffer sb = new StringBuffer();
sb.append((char)0x0d);
sb.append((char)0x0a);
String[] lines = index.split(sb.toString());
sb = new StringBuffer();
sb.append((char)9);
//获取总长度,因为需要从后往前读文件。
int endpoint = Utils.parseString("0x3982e19");
/////////////////////////////////
int size = lines.length;
for (int i=size-1;i>=0;i--) {//这里需要从后面往前面读,最前面的是npk的文件头吧。
String[] cell = lines[i].split(sb.toString());
if (cell != null && cell.length > 3) {
if (cell[ID].trim().startsWith("#") || cell[ID].trim().equals("INT")) {//跳过索引文件的头2行
continue;
}
int len = Integer.valueOf(cell[Size].trim());//读取此文件的大小。
String filename = cell[Path].trim() + cell[Name].trim();
byte[] file = new byte[len];
endpoint -= len;
int srcpos = endpoint;
System.arraycopy(inarray, srcpos, file, 0, len);//拷贝
Utils.writeFile(file, root+"\\"+filename);//写入文件
// totalLen += len;
}
}
}
文件结构:
整个包太大,附上文件索引表和战斗的表。
fight.lua= ui.zip
file index = index .txt
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!