感谢大佬,圆了童年的梦,
文件名都是杂乱的,先弄个皮卡丘,其他有空慢慢整理
皮卡丘.zip (466.4 KB)
感谢 cyb464b6
这里包内文件名经过混淆可使用这个脚本还原
import json
import os
import shutil
from pathlib import Path
def restore_files_from_mapping(json_path, search_dir, output_dir):
# 读取JSON文件
with open(json_path, 'r', encoding='utf-8') as f:
mapping_data = json.load(f)
# 确保输出目录存在
os.makedirs(output_dir, exist_ok=True)
# 统计处理结果
total_files = len(mapping_data)
success_count = 0
failed_count = 0
failed_files = []
# 遍历JSON中的每一项
for original_path, info in mapping_data.items():
mapping_path = info.get('mapping')
if not mapping_path:
print(f"警告: {original_path} 没有mapping信息,跳过")
failed_count += 1
failed_files.append(original_path)
continue
# 构建完整的源文件路径和目标文件路径
source_file = os.path.join(search_dir, mapping_path)
dest_file = os.path.join(output_dir, original_path)
try:
# 确保目标目录存在
os.makedirs(os.path.dirname(dest_file), exist_ok=True)
# 复制文件
shutil.copy2(source_file, dest_file)
print(f"成功: {mapping_path} -> {original_path}")
success_count += 1
except FileNotFoundError:
print(f"错误: 找不到文件 {mapping_path}")
failed_count += 1
failed_files.append(original_path)
except Exception as e:
print(f"错误: 处理 {original_path} 时发生异常 - {str(e)}")
failed_count += 1
failed_files.append(original_path)
# 输出统计信息
print("\n处理完成:")
print(f"总文件数: {total_files}")
print(f"成功: {success_count}")
print(f"失败: {failed_count}")
if failed_files:
print("\n失败的文件列表:")
for file in failed_files:
print(file)
if __name__ == "__main__":
# 配置路径
json_file_path = input("请输入repo.mapping文件路径: ").strip()
search_directory = r"C:\Users\youname\Desktop\apkunpack\MyLuaGame_9.8415\assets"
output_directory = r"C:\Users\youname\Desktop\resout"
# 执行恢复操作
restore_files_from_mapping(json_file_path, search_directory, output_directory)
# 等待用户按Enter退出
input("\n按Enter键退出...")
repo.mapping文件可在解包后\assets\repository下找到
感谢大佬的恢复文件名方法
他的视频下载下来还还需要解密不过审计了他的代码你只需要将这几个文件替换即可无视好感度解锁所有内容
repository.zip (7.2 KB)
下载下来后替换安装包内的文件如果是iOS就去https://www.csyproject.site/channel/FX01/mhbkm_9.7280403.ipa
下载ipa包然后使用Sideloadly签名安装注意勾选
之后使用爱思助手替换他文档路径下的文件即可
这个网站还有色漫对决和幻想三国志都是这种加密,不知道该怎么写hook脚本,我太菜了
hook在一个月前现学现用了一次忘了。。。
这是当时使用的脚本(应该。。。修改了一下函数还没试这个版本的宝可梦)
var so_name = "libcocos2dlua.so";
var fun_name = "_ZN8CCCrypto12decryptXXTEAEPhiS0_iPi";
function do_hook() {
var addr = Module.findExportByName(so_name, fun_name);
console.log(addr);
Interceptor.attach(addr, {
onEnter: function (args) {
console.log('key: ' + Memory.readCString (args[2]));
},
onLeave: function (retval) {
}
})
}
function load_so_and_hook() {
var dlopen = Module.findExportByName(null, "dlopen");
var android_dlopen_ext = Module.findExportByName(null, "android_dlopen_ext");
Interceptor.attach(dlopen, {
onEnter: function (args) {
var path_ptr = args[0];
var path = ptr(path_ptr).readCString();
console.log("[dlopen:]", path);
this.path = path;
}, onLeave: function (retval) {
if (this.path.indexOf(so_name) !== -1) { // 如果包含我想要的so文件
console.log("[dlopen:]", this.path);
do_hook();
}
}
});
Interceptor.attach(android_dlopen_ext, {
onEnter: function (args) {
var path_ptr = args[0];
var path = ptr(path_ptr).readCString();
this.path = path;
}, onLeave: function (retval) {
if (this.path.indexOf(so_name) !== -1) {
console.log("\nandroid_dlopen_ext加载:", this.path);
do_hook();
}
}
});
}
load_so_and_hook();
大佬有无密钥获取方法可分享一下
从某个奇妙的地方扒了一段代码似乎是密钥生成逻辑
#!/usr/bin/python
# -*- coding: utf-8 -*-
import os
import struct
import binascii
import md5
import lz4 # pip install lz4==0.8.2
# import zstd # 1.4.3.2
import subprocess
import tjutil
kCompanyName = "TianJi Information Technology Inc."
kCompanyShortName = "TianJi"
#####################################
# static char _toConfuse(char ch)
# {
# if (ch >= 'a' && ch <= 'z') return ch - 'a' + 'A';
# else if (ch == '_') return '+';
# else if (ch == '.' || ch == '6') return ';';
# return ch;
# }
# static std::string _toLuaPwd(std::string version)
# {
# // for code confusion
# // 1. a = _toConfuse("hello"+kCompanyShortName+",world"+kCompanyName)
# // 2. b = MD5(a) + string("20140516"+version+kCompanyShortName)
# // 3. c = _toConfuse(b)
# // 4. d = reverse(c)
# // 5. e = MD5(d)
# int pos = version.find_last_of('.'); //把最后一位舍掉了
# std::string confusion = "hello" + std::string(kCompanyShortName) + ",world" + kCompanyName;
# std::transform(confusion.begin(), confusion.end(), confusion.begin(), _toConfuse);
# std::string updatePass = ymextra::CCCrypto::MD5String((void*)confusion.c_str(), confusion.length());
# updatePass += "20140516" + version.substr(0, pos) + kCompanyShortName;
# std::transform(updatePass.begin(), updatePass.end(), updatePass.begin(), _toConfuse);
# std::reverse(updatePass.begin(), updatePass.end());
# return ymextra::CCCrypto::MD5String((void*)updatePass.c_str(), updatePass.length());
# }
def reverse(str):
return str[::-1]
def toConfuse(str):
ret = str.upper()
ret = ret.replace('_','+')
ret = ret.replace('.',';')
ret = ret.replace('6',';')
#return reverse(ret)
return ret
def getMd5(str) :
hash = md5.new()
hash.update(str)
return hash.hexdigest()
def toLuaPwd(version):
pos = version[::-1].find('.')+1
a = toConfuse("hello"+kCompanyShortName+",world"+kCompanyName)
b = getMd5(a) + str("20140516"+version[:-pos]+kCompanyShortName)
c = toConfuse(b)
d = reverse(c)
e = getMd5(d)
return e
kAppVersion = str(os.environ.get('kAppVersion', '2.1.0.0'))
XXTEA_SIGN = kCompanyShortName
XXTEA_KEY = toLuaPwd(kAppVersion)
print 'tjz.kAppVersion', kAppVersion
print 'tjz.XXTEA_SIGN', XXTEA_SIGN
print 'tjz.XXTEA_KEY', XXTEA_KEY
print 'lz4.VERSION', lz4.VERSION
lz4compress = None
lz4uncompress = None
if lz4.VERSION == '0.8.2':
# def compress(s):
# lenpack = struct.pack('>L', len(s))[:4]
# return lenpack + lz4.compress(s)
lz4compress = lz4.compress
lz4uncompress = lz4.uncompress
else:
import lz4.block # pip install lz4==1.1.0
lz4compress = lz4.block.compress
lz4uncompress = lz4.block.decompress
def dataCompress(data, mode='lz4'):
if mode == 'lz4':
return lz4compress(data)
# elif mode == 'zstd':
# return zstd.compress(data)
raise Exception('no such compress mode')
def isCompressed(data):
# tj! = tjz + tje, use lz4
# 整包少10+MB,暂时不替换,仍然用lz4
# tj# = tjs + tje, use zstd
return data[:3] in ('tjz', 'tje', 'tj!', 'tjs', 'tj#')
# tjz[4 bytes size][lz4 data...]
def compress(data, useLZ4=True):
lenpack = struct.pack('<L', len(data))[:4]
if useLZ4:
return 'tjz' + lenpack + dataCompress(data, 'lz4')
# else:
# return 'tjs' + lenpack + dataCompress(data, 'zstd')
def compressToFile(data, path, useLZ4=True):
with open(path, 'wb') as fp:
fp.write(compress(data, useLZ4=useLZ4))
# tje[16 bytes pass][4 bytes size][data...]
def encodeToFile(data, pwd, path, pwdIsHex=True):
rnd = os.urandom(16)
# rnd = '\0' * 16
if pwdIsHex:
pwd = binascii.unhexlify(pwd)
bb = [ord(x) for x in pwd]
aa = [ord(x) for x in rnd]
cc = [0] * 16
for i in xrange(max(len(aa), len(bb))):
cc[i%16] = cc[i%16] ^ aa[i%len(aa)] ^ bb[i%len(bb)]
newpwd = ''.join([chr(c) for c in cc])
lenpack = struct.pack('<L', len(data))[:4]
# print len(newpwd), repr(newpwd)
with open(path, 'wb') as fp:
fp.write(data)
# xxtea
XXTEA_SIGN = 'tje' + rnd + lenpack
cmd = [tjutil.xxtea_exe, '-eh', binascii.hexlify(newpwd), '-sh', binascii.hexlify(XXTEA_SIGN), path, path]
cmd = ' '.join(cmd)
ret = subprocess.call(cmd, shell=True)
if ret != 0:
raise Exception('xxtea error')
# tj![16 bytes pass][4 bytes size][lz4 data...]
def encodeAndCompressToFile(data, pwd, path, pwdIsHex=True, useLZ4=True):
rnd = os.urandom(16)
# rnd = '\0' * 16
if pwdIsHex:
pwd = binascii.unhexlify(pwd)
bb = [ord(x) for x in pwd]
aa = [ord(x) for x in rnd]
cc = [0] * 16
for i in xrange(max(len(aa), len(bb))):
cc[i%16] = cc[i%16] ^ aa[i%len(aa)] ^ bb[i%len(bb)]
newpwd = ''.join([chr(c) for c in cc])
# compress
lenpack = struct.pack('<L', len(data))[:4]
zdata = dataCompress(data, 'lz4' if useLZ4 else 'zstd')
with open(path, 'wb') as fp:
fp.write(zdata)
# xxtea
flag = 'tj!' if useLZ4 else 'tj#'
XXTEA_SIGN = flag + rnd + lenpack
cmd = [tjutil.xxtea_exe, '-eh', binascii.hexlify(newpwd), '-sh', binascii.hexlify(XXTEA_SIGN), path, path]
cmd = ' '.join(cmd)
ret = subprocess.call(cmd, shell=True)
if ret != 0:
raise Exception('xxtea error')
def decode(data, pwd, pwdIsHex=True):
if not isCompressed(data):
return data
rawdata = data
isLZ4 = data[2] == '!' or data[2] == 'z'
isXXTEA = data[2] == '!' or data[2] == 'e'
if pwdIsHex:
pwd = binascii.unhexlify(pwd)
sign = data[:3]
data = data[3:] # flag
if isXXTEA:
rnd = data[:16] # rnd
sign += rnd
data = data[16:]
bb = [ord(x) for x in pwd]
aa = [ord(x) for x in rnd]
cc = [0] * 16
for i in xrange(max(len(aa), len(bb))):
cc[i%16] = cc[i%16] ^ aa[i%len(aa)] ^ bb[i%len(bb)]
pwd = ''.join([chr(c) for c in cc])
length = struct.unpack('<L', data[:4]) # lenpack
sign += data[:4]
data = data[4:]
# print '!!!sign', repr(sign)
# print '!!!rnd', repr(rnd), len(rnd)
# print '!!!length', length
# print '!!!data', len(data)
if isXXTEA:
path = 'decode.tmp'
with open(path, 'wb') as fp:
fp.write(rawdata)
cmd = [tjutil.xxtea_exe, '-dh', binascii.hexlify(pwd), '-sh', binascii.hexlify(sign), path, path]
cmd = ' '.join(cmd)
ret = subprocess.call(cmd, shell=True)
if ret != 0:
raise Exception('xxtea error')
with open(path, 'rb') as fp:
data = fp.read()
if isLZ4:
data = lz4uncompress(data)
return data
这个版本的解密成功了参考密钥生成脚本
import hashlib
# 逆向出的查表数据
byte_D375B6 = [
0x3F, 0x3C, 0x05, 0x23, 0x3C, 0x04, 0x6B, 0x61, 0x3D, 0x55,
0x35, 0x24, 0x18, 0x6D, 0x10, 0x6B, 0x3F, 0x35, 0x63, 0x57,
0x68, 0x18, 0x6E, 0x18, 0x1A, 0x6D, 0x6B, 0x05, 0x68, 0x63,
0x5F
]
byte_D375D5 = [
0x45, 0x77, 0x53, 0x09, 0x4E, 0x49, 0x30, 0x16, 0x7C, 0x1B,
0x59, 0x3E, 0x3A, 0x1F, 0x17, 0x0B, 0x73, 0x43, 0x7A, 0x1A,
0x48, 0x78, 0x36, 0x00, 0x6F, 0x1E, 0x67, 0x12, 0x72, 0x29,
0x7D, 0x70, 0x32, 0x40, 0x3B, 0x57, 0x62, 0x4F, 0x3F, 0x60,
0x31, 0x2C, 0x56, 0x2B, 0x04, 0x4D, 0x27, 0x25, 0x76, 0x4C,
0x37, 0x34, 0x26, 0x65, 0x7B, 0x2A, 0x75, 0x39, 0x11, 0x66,
0x41, 0x61, 0x50, 0x54, 0x5B, 0x6A, 0x23, 0x0E, 0x21, 0x13,
0x42, 0x35, 0x1C, 0x5E, 0x03, 0x46, 0x0A, 0x6B, 0x06, 0x64,
0x07, 0x0D, 0x5A, 0x4B, 0x58, 0x6D, 0x02, 0x68, 0x5D, 0x7E,
0x3C, 0x5F, 0x71, 0x44, 0x69, 0x2E, 0x2F, 0x47, 0x01, 0x63,
0x33, 0x18, 0x5C, 0x1D, 0x6E, 0x08, 0x14, 0x20, 0x51, 0x79,
0x6C, 0x19, 0x22, 0x52, 0x7F, 0x05, 0x15, 0x38, 0x74, 0x55,
0x4A, 0x28, 0x24, 0x3D, 0x2D, 0x0F, 0x10, 0x0C, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
]
def decode_company_name():
"""通过查表解码隐藏的公司全名"""
decoded_bytes = [byte_D375D5[b] for b in byte_D375B6]
return bytes(decoded_bytes).decode('latin1')
def to_confuse(s):
"""字符替换规则"""
s = s.upper()
return s.replace('_', '+').replace('.', ';').replace('6', ';')
def generate_key(version="2.1.0.0"):
# 常量定义
COMPANY_SHORT = "Gameboys" # 伪代码中硬编码的短名称
DATE_STRING = "2o20o516" # 伪代码中插入的日期
# 1. 解码公司全名
company_full = decode_company_name() # 结果为"TianJi Information Technology Inc."
# 2. 处理版本号(去掉最后的小版本)
version_main = version[:version.rfind('.')] if '.' in version else version
# 3. 构建第一阶段字符串
phase1_str = f"hell0{COMPANY_SHORT},w0rld{company_full}"
# 4. 字符混淆处理
processed_phase1 = to_confuse(phase1_str)
# 5. 第一次MD5
md5_phase1 = hashlib.md5(processed_phase1.encode('utf-8')).hexdigest()
# 6. 构建第二阶段字符串
phase2_str = f"{md5_phase1}{DATE_STRING}{version_main}{COMPANY_SHORT}"
# 7. 二次混淆处理
processed_phase2 = to_confuse(phase2_str)
# 8. 反转字符串
reversed_str = processed_phase2[::-1]
# 9. 最终MD5生成密钥
final_key = hashlib.md5(reversed_str.encode('utf-8')).hexdigest()
return final_key
if __name__ == "__main__":
# 测试输出
test_version = "2.1.0.0"
print(f"Version: {test_version}")
print(f"Generated Key: {generate_key(test_version)}")
# 验证解码结果
print(f"\nDecoded Company Name: {decode_company_name()}")
AppDelegate函数伪代码
void __fastcall AppDelegate::AppDelegate(AppDelegate *this)
{
__int64 v2; // x8
int v3; // w10
signed __int64 v4; // x21
_BYTE *v5; // x9
char *v6; // x9
bool v7; // zf
char *v8; // x8
char *v9; // x8
char *v10; // x8
char *v11; // x8
char *v12; // x8
char *v13; // x8
__int64 v14; // x0
__int64 v15; // x0
__int64 i; // x9
char *v17; // x13
char *v18; // x1
size_t v19; // x2
__int64 v20; // x0
int v21; // w2
unsigned __int64 v22; // x11
CCCrypto *v23; // x12
unsigned int v24; // w13
unsigned __int64 v25; // x9
CCCrypto *v26; // x10
int v27; // w11
CCCrypto *v28; // x0
unsigned __int64 v29; // x1
size_t v30; // x8
unsigned __int64 v31; // x9
_BYTE *v32; // x21
size_t v33; // x20
char *v34; // x22
__int64 v35; // x0
_BYTE *v36; // x8
unsigned __int64 v37; // x8
char *v38; // x9
bool v39; // zf
char *v40; // x9
size_t v41; // x8
char *v42; // x9
char *v43; // x9
char *v44; // x9
char *v45; // x9
char *v46; // x9
char *v47; // x1
size_t v48; // x2
__int64 v49; // x0
char *v50; // x1
size_t v51; // x2
int v52; // w2
unsigned __int64 v53; // x9
char *v54; // x10
size_t v55; // x12
unsigned __int64 v56; // x11
_BYTE *v57; // x13
int v58; // w9
size_t v59; // x13
char *v60; // x11
char *v61; // x13
unsigned __int64 v62; // x9
char v63; // w12
bool v64; // cc
bool v65; // zf
unsigned __int64 v66; // x9
CCCrypto *v67; // x0
unsigned __int64 v68; // x1
int v69; // w2
cocos2d::FileUtils *v70; // x0
unsigned __int64 v71; // x1
unsigned __int8 v72; // [xsp+8h] [xbp-128h]
_BYTE v73[15]; // [xsp+9h] [xbp-127h] BYREF
void *v74; // [xsp+18h] [xbp-118h]
__int64 v75; // [xsp+20h] [xbp-110h] BYREF
unsigned int v76; // [xsp+28h] [xbp-108h]
void *v77; // [xsp+30h] [xbp-100h]
__int64 v78; // [xsp+38h] [xbp-F8h] BYREF
size_t v79; // [xsp+40h] [xbp-F0h]
void *v80; // [xsp+48h] [xbp-E8h]
__int64 v81; // [xsp+50h] [xbp-E0h] BYREF
size_t v82; // [xsp+58h] [xbp-D8h]
void *v83; // [xsp+60h] [xbp-D0h]
unsigned __int64 v84; // [xsp+68h] [xbp-C8h] BYREF
size_t v85; // [xsp+70h] [xbp-C0h]
void *v86; // [xsp+78h] [xbp-B8h]
__int128 v87; // [xsp+80h] [xbp-B0h] BYREF
void *v88; // [xsp+90h] [xbp-A0h]
__int128 v89; // [xsp+A0h] [xbp-90h] BYREF
char *v90; // [xsp+B0h] [xbp-80h]
__int128 v91; // [xsp+C0h] [xbp-70h] BYREF
CCCrypto *v92; // [xsp+D0h] [xbp-60h]
_ReadStatusReg(ARM64_SYSREG(3, 3, 13, 0, 2));
cocos2d::Application::Application(this);
v2 = 0LL;
*(_QWORD *)this = off_1025FF0;
*((_QWORD *)this + 1) = 0LL;
*((_QWORD *)this + 2) = 0LL;
*((_QWORD *)this + 3) = 0LL;
v72 = 14;
v74 = 0LL;
strcpy(v73, "2.1.0.0");
v73[8] = 0;
*(_WORD *)&v73[9] = 0;
*(_DWORD *)&v73[11] = 0;
while ( v2 != -7 )
{
v3 = (unsigned __int8)v73[v2-- + 6];
if ( v3 == 46 )
{
v4 = &v73[v2 + 7] - v73;
goto LABEL_6;
}
}
LODWORD(v4) = -1;
LABEL_6:
v85 = 0LL;
v86 = 0LL;
v84 = 0LL;
std::string::append((int)&v84, 8uLL, 0);
v5 = v86;
if ( (v84 & 1) == 0 )
v5 = (char *)&v84 + 1;
*v5 = 71;
v6 = (char *)v86;
v7 = (v84 & 1) == 0;
if ( (v84 & 1) == 0 )
v6 = (char *)&v84 + 1;
v6[1] = 97;
v8 = (char *)v86;
if ( v7 )
v8 = (char *)&v84 + 1;
v8[2] = 109;
v9 = (char *)v86;
if ( v7 )
v9 = (char *)&v84 + 1;
v9[3] = 101;
v10 = (char *)v86;
if ( v7 )
v10 = (char *)&v84 + 1;
v10[4] = 98;
v11 = (char *)v86;
if ( v7 )
v11 = (char *)&v84 + 1;
v11[5] = 111;
v12 = (char *)v86;
if ( v7 )
v12 = (char *)&v84 + 1;
v12[6] = 121;
v13 = (char *)v86;
if ( v7 )
v13 = (char *)&v84 + 1;
v13[7] = 115;
v14 = std::string::insert((int)&v84, 0, "hell0", 5uLL);
v88 = *(void **)(v14 + 16);
v87 = *(_OWORD *)v14;
*(_QWORD *)(v14 + 8) = 0LL;
*(_QWORD *)(v14 + 16) = 0LL;
*(_QWORD *)v14 = 0LL;
v15 = std::string::append((int)&v87, ",w0rld", 6uLL);
v90 = *(char **)(v15 + 16);
v89 = *(_OWORD *)v15;
*(_QWORD *)(v15 + 8) = 0LL;
*(_QWORD *)(v15 + 16) = 0LL;
*(_QWORD *)v15 = 0LL;
v82 = 0LL;
v83 = 0LL;
v81 = 0LL;
std::string::append((int)&v81, 0x1FuLL, 0);
for ( i = 0LL; i != 31; ++i )
{
if ( (v81 & 1) != 0 )
v17 = (char *)v83;
else
v17 = (char *)&v81 + 1;
v17[i] = byte_D375D5[byte_D375B6[i]];
}
if ( (v81 & 1) != 0 )
v18 = (char *)v83;
else
v18 = (char *)&v81 + 1;
if ( (v81 & 1) != 0 )
v19 = v82;
else
v19 = (unsigned __int64)(unsigned __int8)v81 >> 1;
v20 = std::string::append((int)&v89, v18, v19);
v92 = *(CCCrypto **)(v20 + 16);
v91 = *(_OWORD *)v20;
*(_QWORD *)(v20 + 8) = 0LL;
*(_QWORD *)(v20 + 16) = 0LL;
*(_QWORD *)v20 = 0LL;
if ( (v81 & 1) != 0 )
{
operator delete(v83);
if ( (v89 & 1) == 0 )
{
LABEL_35:
if ( (v87 & 1) == 0 )
goto LABEL_36;
goto LABEL_72;
}
}
else if ( (v89 & 1) == 0 )
{
goto LABEL_35;
}
operator delete(v90);
if ( (v87 & 1) == 0 )
{
LABEL_36:
if ( (v84 & 1) == 0 )
goto LABEL_38;
goto LABEL_37;
}
LABEL_72:
operator delete(v88);
if ( (v84 & 1) != 0 )
LABEL_37:
operator delete(v86);
LABEL_38:
v22 = (unsigned __int8)v91;
v24 = DWORD2(v91);
v23 = v92;
v25 = (unsigned __int64)(unsigned __int8)v91 >> 1;
if ( (v91 & 1) != 0 )
{
v25 = *((_QWORD *)&v91 + 1);
v26 = v92;
}
else
{
v26 = (CCCrypto *)((char *)&v91 + 1);
}
if ( v25 )
{
while ( 1 )
{
v27 = *(unsigned __int8 *)v26;
if ( (unsigned int)(v27 - 97) > 0x19 )
{
switch ( v27 )
{
case '.':
goto LABEL_47;
case '_':
LOBYTE(v27) = 43;
break;
case '6':
LABEL_47:
LOBYTE(v27) = 59;
break;
}
}
else
{
LOBYTE(v27) = v27 - 32;
}
--v25;
*(_BYTE *)v26 = v27;
v26 = (CCCrypto *)((char *)v26 + 1);
if ( !v25 )
{
v22 = (unsigned __int8)v91;
v24 = DWORD2(v91);
v23 = v92;
break;
}
}
}
if ( (v22 & 1) != 0 )
v28 = v23;
else
v28 = (CCCrypto *)((char *)&v91 + 1);
if ( (v22 & 1) != 0 )
v29 = v24;
else
v29 = (unsigned int)(v22 >> 1);
CCCrypto::MD5String(&v81, v28, (void *)v29, v21);
v30 = (int)v4;
v85 = 0LL;
v86 = 0LL;
if ( (v72 & 1) != 0 )
v31 = *(_QWORD *)&v73[7];
else
v31 = (unsigned __int64)v72 >> 1;
if ( (v72 & 1) != 0 )
v32 = v74;
else
v32 = v73;
if ( v31 >= v30 )
v33 = v30;
else
v33 = v31;
v84 = 0LL;
if ( v33 >= 0xFFFFFFFFFFFFFFF0LL )
std::__basic_string_common<true>::__throw_length_error(&v84);
if ( v33 >= 0x17 )
{
v34 = (char *)operator new((v33 + 16) & 0xFFFFFFFFFFFFFFF0LL);
v85 = v33;
v86 = v34;
v84 = (v33 + 16) & 0xFFFFFFFFFFFFFFF0LL | 1;
goto LABEL_75;
}
v34 = (char *)&v84 + 1;
LOBYTE(v84) = 2 * v33;
if ( v33 )
LABEL_75:
memcpy(v34, v32, v33);
v34[v33] = 0;
v35 = std::string::insert((int)&v84, 0, "2o20o516", 8uLL);
v88 = *(void **)(v35 + 16);
v87 = *(_OWORD *)v35;
*(_QWORD *)(v35 + 8) = 0LL;
*(_QWORD *)(v35 + 16) = 0LL;
*(_QWORD *)v35 = 0LL;
v79 = 0LL;
v80 = 0LL;
v78 = 0LL;
std::string::append((int)&v78, 8uLL, 0);
if ( (v78 & 1) != 0 )
v36 = v80;
else
v36 = (char *)&v78 + 1;
*v36 = 71;
v37 = (unsigned __int8)v78;
v38 = (char *)v80;
v39 = (v78 & 1) == 0;
if ( (v78 & 1) == 0 )
v38 = (char *)&v78 + 1;
v38[1] = 97;
v40 = (char *)v80;
v41 = v37 >> 1;
if ( v39 )
v40 = (char *)&v78 + 1;
v40[2] = 109;
v42 = (char *)v80;
if ( v39 )
v42 = (char *)&v78 + 1;
v42[3] = 101;
v43 = (char *)v80;
if ( v39 )
v43 = (char *)&v78 + 1;
v43[4] = 98;
v44 = (char *)v80;
if ( v39 )
v44 = (char *)&v78 + 1;
v44[5] = 111;
v45 = (char *)v80;
if ( v39 )
v45 = (char *)&v78 + 1;
v45[6] = 121;
v46 = (char *)v80;
if ( v39 )
v46 = (char *)&v78 + 1;
v46[7] = 115;
if ( v39 )
v47 = (char *)&v78 + 1;
else
v47 = (char *)v80;
if ( v39 )
v48 = v41;
else
v48 = v79;
v49 = std::string::append((int)&v87, v47, v48);
v90 = *(char **)(v49 + 16);
v89 = *(_OWORD *)v49;
*(_QWORD *)(v49 + 8) = 0LL;
*(_QWORD *)(v49 + 16) = 0LL;
*(_QWORD *)v49 = 0LL;
if ( (v89 & 1) != 0 )
v50 = v90;
else
v50 = (char *)&v89 + 1;
if ( (v89 & 1) != 0 )
v51 = *((_QWORD *)&v89 + 1);
else
v51 = (unsigned __int64)(unsigned __int8)v89 >> 1;
std::string::append((int)&v81, v50, v51);
if ( (v89 & 1) != 0 )
{
operator delete(v90);
if ( (v78 & 1) == 0 )
{
LABEL_107:
if ( (v87 & 1) == 0 )
goto LABEL_108;
goto LABEL_155;
}
}
else if ( (v78 & 1) == 0 )
{
goto LABEL_107;
}
operator delete(v80);
if ( (v87 & 1) == 0 )
{
LABEL_108:
if ( (v84 & 1) == 0 )
goto LABEL_110;
goto LABEL_109;
}
LABEL_155:
operator delete(v88);
if ( (v84 & 1) != 0 )
LABEL_109:
operator delete(v86);
LABEL_110:
v53 = (unsigned __int8)v81;
v55 = v82;
v54 = (char *)v83;
v56 = (unsigned __int64)(unsigned __int8)v81 >> 1;
if ( (v81 & 1) != 0 )
{
v56 = v82;
v57 = v83;
}
else
{
v57 = (char *)&v81 + 1;
}
if ( v56 )
{
while ( 1 )
{
v58 = (unsigned __int8)*v57;
if ( (unsigned int)(v58 - 97) > 0x19 )
{
switch ( v58 )
{
case '.':
goto LABEL_119;
case '_':
LOBYTE(v58) = 43;
break;
case '6':
LABEL_119:
LOBYTE(v58) = 59;
break;
}
}
else
{
LOBYTE(v58) = v58 - 32;
}
--v56;
*v57++ = v58;
if ( !v56 )
{
v53 = (unsigned __int8)v81;
v55 = v82;
v54 = (char *)v83;
break;
}
}
}
if ( (v53 & 1) != 0 )
v59 = v55;
else
v59 = v53 >> 1;
if ( (v53 & 1) != 0 )
v60 = v54;
else
v60 = (char *)&v81 + 1;
if ( v59 )
{
v61 = &v60[v59];
if ( v61 - 1 > v60 )
{
v62 = (unsigned __int64)(v61 - 2);
do
{
v63 = *v60;
*v60++ = *(_BYTE *)(v62 + 1);
v64 = v62 > (unsigned __int64)v60;
*(_BYTE *)(v62-- + 1) = v63;
}
while ( v64 );
v53 = (unsigned __int8)v81;
LODWORD(v55) = v82;
v54 = (char *)v83;
}
}
v65 = (v53 & 1) == 0;
v66 = v53 >> 1;
if ( v65 )
v67 = (CCCrypto *)((char *)&v81 + 1);
else
v67 = (CCCrypto *)v54;
if ( v65 )
v68 = (unsigned int)v66;
else
v68 = (unsigned int)v55;
CCCrypto::MD5String(&v75, v67, (void *)v68, v52);
if ( (v81 & 1) != 0 )
{
operator delete(v83);
if ( (v91 & 1) == 0 )
{
LABEL_142:
if ( (v72 & 1) == 0 )
goto LABEL_144;
goto LABEL_143;
}
}
else if ( (v91 & 1) == 0 )
{
goto LABEL_142;
}
operator delete(v92);
if ( (v72 & 1) != 0 )
LABEL_143:
operator delete(v74);
LABEL_144:
if ( (v75 & 1) != 0 )
v70 = (cocos2d::FileUtils *)v77;
else
v70 = (cocos2d::FileUtils *)((char *)&v75 + 1);
if ( (v75 & 1) != 0 )
v71 = v76;
else
v71 = (unsigned __int64)(unsigned __int8)v75 >> 1;
cocos2d::FileUtils::lua_cocos2dx_ui_RichElement_equalType__Terminology(v70, (const char *)v71, v69);
if ( (v75 & 1) != 0 )
operator delete(v77);
}
其中两个数组数据
unsigned char byte_D375B6[] =
{
0x3F, 0x3C, 0x05, 0x23, 0x3C, 0x04, 0x6B, 0x61, 0x3D, 0x55,
0x35, 0x24, 0x18, 0x6D, 0x10, 0x6B, 0x3F, 0x35, 0x63, 0x57,
0x68, 0x18, 0x6E, 0x18, 0x1A, 0x6D, 0x6B, 0x05, 0x68, 0x63,
0x5F
};
unsigned char byte_D375D5[] =
{
0x45, 0x77, 0x53, 0x09, 0x4E, 0x49, 0x30, 0x16, 0x7C, 0x1B,
0x59, 0x3E, 0x3A, 0x1F, 0x17, 0x0B, 0x73, 0x43, 0x7A, 0x1A,
0x48, 0x78, 0x36, 0x00, 0x6F, 0x1E, 0x67, 0x12, 0x72, 0x29,
0x7D, 0x70, 0x32, 0x40, 0x3B, 0x57, 0x62, 0x4F, 0x3F, 0x60,
0x31, 0x2C, 0x56, 0x2B, 0x04, 0x4D, 0x27, 0x25, 0x76, 0x4C,
0x37, 0x34, 0x26, 0x65, 0x7B, 0x2A, 0x75, 0x39, 0x11, 0x66,
0x41, 0x61, 0x50, 0x54, 0x5B, 0x6A, 0x23, 0x0E, 0x21, 0x13,
0x42, 0x35, 0x1C, 0x5E, 0x03, 0x46, 0x0A, 0x6B, 0x06, 0x64,
0x07, 0x0D, 0x5A, 0x4B, 0x58, 0x6D, 0x02, 0x68, 0x5D, 0x7E,
0x3C, 0x5F, 0x71, 0x44, 0x69, 0x2E, 0x2F, 0x47, 0x01, 0x63,
0x33, 0x18, 0x5C, 0x1D, 0x6E, 0x08, 0x14, 0x20, 0x51, 0x79,
0x6C, 0x19, 0x22, 0x52, 0x7F, 0x05, 0x15, 0x38, 0x74, 0x55,
0x4A, 0x28, 0x24, 0x3D, 0x2D, 0x0F, 0x10, 0x0C, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
其他的游戏类似加密方式都可以参考这个方法
这里还有一个版本
我记得就俩版本我提供的这个脚本密钥的版本就是h365的那个版本应该,早期好感度道具是通用的后面为了骗米搞了vip还有不同角色使用的好感度道具
进游戏看像是一样的,但密钥不一样
87这个版本密钥是fee1cb9fce8a5d6cfa330efe666b0b8b
我知道,我看见你发的脚本了
佬,你发的这个游戏skel和atlas还有png名字好乱啊
佬,密钥脚本是生成87版的,有H365的密钥吗,365版动画文件多一些,跪求~duang~duang~duang…dddd…