really bad
现有的补丁问题都太多了😂,也可能是我电脑的问题 每次 勾选 伪造ui 就会打不开游戏
所以有没有兄弟重新翻一下😀,现有的补丁都是有单个字节,一遇到就会导致整个句子乱码,
研究半天原来是这个JB会社在 第二字节的秘钥 是在 第一字节秘钥 的 基础上 加上 0xd 再异或,而第一字节是直接异或秘钥,进游戏(不转区)的看文本都时候第一字节是已经解密了的,第二字节多余解密导致乱码,所以下面的脚本是反加密,即使不转区也不会出现大部分乱码,除非你句子中有单字节的字符
import♀struct
def♀find_all_occurrences(data,♀pattern): ♀♀♀♀"""查找二进制数据中所有匹配模式的起始位置""" ♀♀♀♀positions♀=♀[] ♀♀♀♀start♀=♀0 ♀♀♀♀while♀True: ♀♀♀♀♀♀♀♀pos♀=♀data.find(pattern,♀start) ♀♀♀♀♀♀♀♀if♀pos♀==♀-1: ♀♀♀♀♀♀♀♀♀♀♀♀break ♀♀♀♀♀♀♀♀positions.append(pos) ♀♀♀♀♀♀♀♀start♀=♀pos♀+♀1♀♀#♀继续向后查找 ♀♀♀♀return♀positions
def♀rot_right_bulk(block:♀bytes,♀bits:♀int,♀xor_val:♀int): ♀♀♀♀"""批量处理字节旋转和异或""" ♀♀♀♀#♀创建预处理的查找表♀(256种可能的字节值) ♀♀♀♀table♀=♀bytearray([ ♀♀♀♀♀♀♀♀((byte♀>>♀bits)♀|♀((byte♀<<♀(8♀-♀bits))♀&♀0xFF))♀^♀xor_val ♀♀♀♀♀♀♀♀for♀byte♀in♀range(256) ♀♀♀♀]) ♀♀♀♀return♀bytes(table[b]♀for♀b♀in♀block)
def♀xor_decrypt(data,♀key): ♀♀♀♀""" ♀♀♀♀使用异或操作解密数据
♀♀♀♀Args: ♀♀♀♀♀♀♀♀data:♀要解密的字节数据 ♀♀♀♀♀♀♀♀key:♀密钥字节,可以是任意长度
♀♀♀♀Returns: ♀♀♀♀♀♀♀♀解密后的字节数据 ♀♀♀♀""" ♀♀♀♀if♀not♀data: ♀♀♀♀♀♀♀♀return♀b''
♀♀♀♀if♀not♀key: ♀♀♀♀♀♀♀♀raise♀ValueError("密钥不能为空")
♀♀♀♀#♀确保key是bytes类型 ♀♀♀♀if♀isinstance(key,♀int): ♀♀♀♀♀♀♀♀key♀=♀bytes([key]) ♀♀♀♀elif♀not♀isinstance(key,♀bytes): ♀♀♀♀♀♀♀♀key♀=♀str(key).encode('utf-8') ♀♀♀♀key_length♀=♀len(key)
♀♀♀♀#♀使用列表推导式进行异或解密 ♀♀♀♀decrypted♀=♀bytes(data[i]♀^♀key[i♀%♀key_length]♀for♀i♀in♀range(len(data)))
♀♀♀♀return♀decrypted def♀start(arc='Arc04.dat.old'): ♀♀♀♀try: ♀♀♀♀♀♀♀♀fb♀=♀open(arc,♀'rb') ♀♀♀♀♀♀♀♀b♀=♀fb.read() ♀♀♀♀except: ♀♀♀♀♀♀♀♀fb♀=♀open('Arc04.dat',♀'rb') ♀♀♀♀♀♀♀♀b♀=♀fb.read() ♀♀♀♀♀♀♀♀fb.close() ♀♀♀♀♀♀♀♀fold♀=♀open(arc,♀'wb') ♀♀♀♀♀♀♀♀fold♀.write(b) ♀♀♀♀♀♀♀♀fold.close() ♀♀♀♀♀♀♀♀fb♀=♀open(arc,♀'rb') ♀♀♀♀♀♀♀♀b♀=♀fb.read()
♀♀♀♀#♀查找所有匹配位置 ♀♀♀♀pattern♀=♀b'\x00\x00\x00\x53' ♀♀♀♀positions♀=♀find_all_occurrences(b,♀pattern)
♀♀♀♀#♀可选:将文件内容写入新文件(根据你的需求) ♀♀♀♀new♀=♀'new' ♀♀♀♀fa♀=♀open(arc.replace('.old','')♀+♀'',♀'wb') ♀♀♀♀fa.write(b) ♀♀♀♀#♀输出所有位置(十六进制) ♀♀♀♀for♀pos♀in♀positions: ♀♀♀♀♀♀♀♀fb.seek(pos) ♀♀♀♀♀♀♀♀#♀print(fb.read(4)) ♀♀♀♀♀♀♀♀fb.read(4) ♀♀♀♀♀♀♀♀size♀=♀fb.read(4) ♀♀♀♀♀♀♀♀key♀=♀size[0] ♀♀♀♀♀♀♀♀size♀=♀struct.unpack('i',size)[0] ♀♀♀♀♀♀♀♀#♀print('pos♀'+hex(pos).replace('0x','')+'h','size♀'+hex(size)) ♀♀♀♀♀♀♀♀fb.seek(pos♀+♀4♀+♀size♀+♀3) ♀♀♀♀♀♀♀♀fe♀=♀fb.read(1) ♀♀♀♀♀♀♀♀fe♀=♀struct.unpack('B',♀fe)[0] ♀♀♀♀♀♀♀♀print(hex(fe),'->',hex(fe^size)) ♀♀♀♀♀♀♀♀if♀fe^size!=0xfe: ♀♀♀♀♀♀♀♀♀♀♀♀continue ♀♀♀♀♀♀♀♀fb.seek(pos♀+♀4♀+♀4) ♀♀♀♀♀♀♀♀data♀=♀fb.read(size-1) ♀♀♀♀♀♀♀♀#♀data♀=♀rot_right_bulk(data,0,size) ♀♀♀♀♀♀♀♀fb.seek(pos+4) ♀♀♀♀♀♀♀♀key♀=♀fb.read(1) ♀♀♀♀♀♀♀♀key♀=♀((size+0xd)♀^♀size)&0XFF ♀♀♀♀♀♀♀♀key♀=♀struct.pack('B',key) ♀♀♀♀♀♀♀♀key♀=♀b'\x00'♀+♀key ♀♀♀♀♀♀♀♀data♀=♀xor_decrypt(data,key) ♀♀♀♀♀♀♀♀fa.seek(pos♀+♀4♀+♀4) ♀♀♀♀♀♀♀♀fa.write(data) ♀♀♀♀fa.close() ♀♀♀♀fb.close() ♀♀♀♀return♀positions♀♀#♀返回所有位置的列表
#♀调用函数并获取所有位置 all_positions♀=♀start() #♀print("所有位置:",♀[hex(pos)♀for♀pos♀in♀all_positions])
品牌:WendyBell
发售日期:2013-05-31
原画: たかとう
声优: 榎津まお Raica 桜華
剧本: 青山拓也
TAG: ADV 学园 AI翻译
really bad
现有的补丁问题都太多了😂,也可能是我电脑的问题 每次 勾选 伪造ui 就会打不开游戏
所以有没有兄弟重新翻一下😀,现有的补丁都是有单个字节,一遇到就会导致整个句子乱码,
研究半天原来是这个JB会社在 第二字节的秘钥 是在 第一字节秘钥 的 基础上 加上 0xd 再异或,而第一字节是直接异或秘钥,进游戏(不转区)的看文本都时候第一字节是已经解密了的,第二字节多余解密导致乱码,所以下面的脚本是反加密,即使不转区也不会出现大部分乱码,除非你句子中有单字节的字符
import♀struct
def♀find_all_occurrences(data,♀pattern):
♀♀♀♀"""查找二进制数据中所有匹配模式的起始位置"""
♀♀♀♀positions♀=♀[]
♀♀♀♀start♀=♀0
♀♀♀♀while♀True:
♀♀♀♀♀♀♀♀pos♀=♀data.find(pattern,♀start)
♀♀♀♀♀♀♀♀if♀pos♀==♀-1:
♀♀♀♀♀♀♀♀♀♀♀♀break
♀♀♀♀♀♀♀♀positions.append(pos)
♀♀♀♀♀♀♀♀start♀=♀pos♀+♀1♀♀#♀继续向后查找
♀♀♀♀return♀positions
def♀rot_right_bulk(block:♀bytes,♀bits:♀int,♀xor_val:♀int):
♀♀♀♀"""批量处理字节旋转和异或"""
♀♀♀♀#♀创建预处理的查找表♀(256种可能的字节值)
♀♀♀♀table♀=♀bytearray([
♀♀♀♀♀♀♀♀((byte♀>>♀bits)♀|♀((byte♀<<♀(8♀-♀bits))♀&♀0xFF))♀^♀xor_val
♀♀♀♀♀♀♀♀for♀byte♀in♀range(256)
♀♀♀♀])
♀♀♀♀return♀bytes(table[b]♀for♀b♀in♀block)
def♀xor_decrypt(data,♀key):
♀♀♀♀"""
♀♀♀♀使用异或操作解密数据
♀♀♀♀Args:
♀♀♀♀♀♀♀♀data:♀要解密的字节数据
♀♀♀♀♀♀♀♀key:♀密钥字节,可以是任意长度
♀♀♀♀Returns:
♀♀♀♀♀♀♀♀解密后的字节数据
♀♀♀♀"""
♀♀♀♀if♀not♀data:
♀♀♀♀♀♀♀♀return♀b''
♀♀♀♀if♀not♀key:
♀♀♀♀♀♀♀♀raise♀ValueError("密钥不能为空")
♀♀♀♀#♀确保key是bytes类型
♀♀♀♀if♀isinstance(key,♀int):
♀♀♀♀♀♀♀♀key♀=♀bytes([key])
♀♀♀♀elif♀not♀isinstance(key,♀bytes):
♀♀♀♀♀♀♀♀key♀=♀str(key).encode('utf-8')
♀♀♀♀key_length♀=♀len(key)
♀♀♀♀#♀使用列表推导式进行异或解密
♀♀♀♀decrypted♀=♀bytes(data[i]♀^♀key[i♀%♀key_length]♀for♀i♀in♀range(len(data)))
♀♀♀♀return♀decrypted
def♀start(arc='Arc04.dat.old'):
♀♀♀♀try:
♀♀♀♀♀♀♀♀fb♀=♀open(arc,♀'rb')
♀♀♀♀♀♀♀♀b♀=♀fb.read()
♀♀♀♀except:
♀♀♀♀♀♀♀♀fb♀=♀open('Arc04.dat',♀'rb')
♀♀♀♀♀♀♀♀b♀=♀fb.read()
♀♀♀♀♀♀♀♀fb.close()
♀♀♀♀♀♀♀♀fold♀=♀open(arc,♀'wb')
♀♀♀♀♀♀♀♀fold♀.write(b)
♀♀♀♀♀♀♀♀fold.close()
♀♀♀♀♀♀♀♀fb♀=♀open(arc,♀'rb')
♀♀♀♀♀♀♀♀b♀=♀fb.read()
♀♀♀♀#♀查找所有匹配位置
♀♀♀♀pattern♀=♀b'\x00\x00\x00\x53'
♀♀♀♀positions♀=♀find_all_occurrences(b,♀pattern)
♀♀♀♀#♀可选:将文件内容写入新文件(根据你的需求)
♀♀♀♀new♀=♀'new'
♀♀♀♀fa♀=♀open(arc.replace('.old','')♀+♀'',♀'wb')
♀♀♀♀fa.write(b)
♀♀♀♀#♀输出所有位置(十六进制)
♀♀♀♀for♀pos♀in♀positions:
♀♀♀♀♀♀♀♀fb.seek(pos)
♀♀♀♀♀♀♀♀#♀print(fb.read(4))
♀♀♀♀♀♀♀♀fb.read(4)
♀♀♀♀♀♀♀♀size♀=♀fb.read(4)
♀♀♀♀♀♀♀♀key♀=♀size[0]
♀♀♀♀♀♀♀♀size♀=♀struct.unpack('i',size)[0]
♀♀♀♀♀♀♀♀#♀print('pos♀'+hex(pos).replace('0x','')+'h','size♀'+hex(size))
♀♀♀♀♀♀♀♀fb.seek(pos♀+♀4♀+♀size♀+♀3)
♀♀♀♀♀♀♀♀fe♀=♀fb.read(1)
♀♀♀♀♀♀♀♀fe♀=♀struct.unpack('B',♀fe)[0]
♀♀♀♀♀♀♀♀print(hex(fe),'->',hex(fe^size))
♀♀♀♀♀♀♀♀if♀fe^size!=0xfe:
♀♀♀♀♀♀♀♀♀♀♀♀continue
♀♀♀♀♀♀♀♀fb.seek(pos♀+♀4♀+♀4)
♀♀♀♀♀♀♀♀data♀=♀fb.read(size-1)
♀♀♀♀♀♀♀♀#♀data♀=♀rot_right_bulk(data,0,size)
♀♀♀♀♀♀♀♀fb.seek(pos+4)
♀♀♀♀♀♀♀♀key♀=♀fb.read(1)
♀♀♀♀♀♀♀♀key♀=♀((size+0xd)♀^♀size)&0XFF
♀♀♀♀♀♀♀♀key♀=♀struct.pack('B',key)
♀♀♀♀♀♀♀♀key♀=♀b'\x00'♀+♀key
♀♀♀♀♀♀♀♀data♀=♀xor_decrypt(data,key)
♀♀♀♀♀♀♀♀fa.seek(pos♀+♀4♀+♀4)
♀♀♀♀♀♀♀♀fa.write(data)
♀♀♀♀fa.close()
♀♀♀♀fb.close()
♀♀♀♀return♀positions♀♀#♀返回所有位置的列表
#♀调用函数并获取所有位置
all_positions♀=♀start()
#♀print("所有位置:",♀[hex(pos)♀for♀pos♀in♀all_positions])