破解某游戏存档字母移位加密
本帖最后由 你皮任你皮 于 2022-2-16 13:37 编辑首先声明一下,本人小白一枚,能在百度的帮助下大概看懂一些简单的代码,写这篇文章的目的是提供一些破解思路以供像我一样的小白学习,文中如果有误欢迎大佬指正。{:1_893:}
话不多说,直接上存档:
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
<int name="mbnazHlxuChfvBfBf" value="2" />
<int name="mbnazHlxuChfvCe" value="2" />
<string name="lwobvPxuvlxzsBfAgAg"></string>
<int name="heeCalhzSdbeeCaljdRlylzUylkTbflyTukhs" value="210901" />
<int name="ydbeeCalhzLlpleCaljdBfAgCe" value="210901" />
<int name="ydbeeCalhzLlpleCaljdBfCeFb" value="210921" />
<int name="alxuUvnxhklLlpleBf" value="55" />
<string name="lwobvPxuvlxzsGaFb"></string>
<string name="lwobvPxuvlxzsAg"></string>
<int name="mbnazHlxuChfvJl" value="2" />
<string name="lwobvPxuvlxzsJlBf"></string>
<int name="bgmuSauvDhbesRlqhxkTbfly" value="49" />
<string name="lwobvUvnxhklErvFb">103</string>
<int name="ydbeeLlpleBfCeEc" value="10" />
<int name="yauvDbhfugkAkyTbfly" value="76" />
<string name="lwobvPxuvlxzsDdBf"></string>
<int name="mbnazHlxuJuiDd" value="2" />
<int name="lwobvCalhzUvnxhklCaljdLlpleEc" value="211933" />
<string name="lwobvUvnxhklErvBf">209</string>
<string name="lwobvPxuvlxzsHnJl"></string>
<int name="mxllAkyNllkTbfly" value="-141" />
<string name="lwobvPxuvlxzsBfAg"></string>
<int name="lwobvSuxzIkLhyz" value="326" />
<string name="lwobvPxuvlxzsImBf">01048016120090330090450090450200340100320080330060</string>
<string name="lwobvPxuvlxzsEcGa"></string>
<string name="lwobvPxuvlxzsBfAgEc"></string>
<int name="Screenmanager%20Resolution%20Width" value="1080" />
<int name="ydbeeCalhzLlpleCaljdBfDdFb" value="210901" />
<int name="lwobvUylkIkCe" value="94" />
<int name="ydbeeCalhzLlpleCaljdBfFbCe" value="210901" />
<int name="ydbeeLlpleBfFbCe" value="0" />
<int name="ydbeeCalhzLlpleCaljdBfEc" value="210941" />
<int name="ydbeeCalhzLlpleCaljdAg" value="210941" />
<string name="lwobvCalhzUvnxhklCaljdErvBf">211319</string>
<string name="lwobvPxuvlxzsEcDd"></string>
<string name="lwobvPxuvlxzsFbHn"></string>
<int name="mbnazHlxuPuyFb" value="9" />
<int name="ydbeeLlpleBfEcDd" value="0" />
<string name="lwobvUvnxhklErvCe">305</string>
<string name="lwobvPxuvlxzsEcIm"></string>
<string name="lwobvPxuvlxzsEcBf"></string>
<string name="lwobvPxuvlxzsGaBf"></string>
<int name="mbnazHlxuPuyIm" value="5" />
</map>
存档内容较多,这里选取了一部分贴出来,可以看到这个存档仅仅对name做了加密,加密过后看起来是混乱的字母组合,我们假设这就是字母移位的加密,按照这个思路分析一下试试:
为了方便分析,我们尽量控制变量,先把游戏存档删除,开个初始存档保存一下,然后再进去玩一下,获得第一件装备后再保存一个存档,通过比对这两个存档,我发现获得装备后的存档多了一行:
<string name="lwobvPxuvlxzsImBf">01048016120090330090450090450200340100320080330060</string>
再对比游戏里装备的属性,发现后面的数值能完美对应,OK,我们可以确定这一行存档就代表装备了,想改装备的话改后面的数字就行了,但是到这一步我们肯定不能满足啊,毕竟还有好多存档不知道对应着什么,所以我们尝试一下破解。
装备用英语怎么说?幸好我的英语还没丢{:301_978:},果断上百度搜了一下:equipment,反手掏出我的Excel开始尝试对应:
先把a~z输入进去,加上编上号,取上面string name的前9个字母lwobvPxuv对应equipment:
填好之后我陷入了沉思{:301_983:},这明显不对啊!equipment有俩e,一个对应l一个对应x。。。。
莫非我之前的推测有误?这并不是字母移位加密?不死心的我决定再试试:
这时候我想到一个大概率会存在的单词:skill-技能,而且这个单词比较有特色,有两个连续的L,如果移位加密的话得出的结果肯定有连续两个相同的字母,通过一番查找,我发现存档里多次出现的“ydbee“”嫌疑很大,再放入我的字母表试一下:
我们发现有三个字母都是向上偏移了7位,感觉这个思路是正确的,但是还有个不是偏移7位的怎么说!{:301_1003:}
然后。。。。破解又陷入了僵局。。。。{:301_1004:}
上面说过,我已经确定了装备怎么改,已经能修改出变态装备各种秒了,本来是准备放弃的,但是我不甘心啊。。。
于是我祭出了一件大杀器 ——Il2CppDumper
{:301_993:}感谢大佬编写这么好用的工具,让我拿到了dump.cs这个文件!
在dump出的文件里搜索skill:
private int[] skillCheatLevelCheck; // 0x524
<int name="ydbeeCalhzLlpleCaljdBfAgCe" value="210901" />
这个skillCheatLevelCheck跟下面的ydbeeCalhzLlpleCaljd明显就呼应上了啊!而且我发现貌似大写字母是不做移位处理的!Excel继续工作:
填上去之后就很明显了啊,前7个字母下移7位,7到14个字母上移7位,也就是前7个字母和它们下面的7个互换,26个字母除去这14个还剩12个,大胆推测下这12个也是6个一组互换:
按照这个规律带入刚才的推测的equipment试一下:lwobvPxuvlxzsImBf = equipPropertyIfBm
{:301_1009:}我没错!错的是百度和游戏作者!百度翻译的装备英文是equipment,结果这里是equip!{:301_981:}
到这儿,解密工作已经完成了,如果是大佬肯定随手贴出几行代码,运行一下就解密完了,但是我不会啊。。。。难道几百行的游戏存档你让我手工翻译?
不存在的,虽然我不会敲代码,但是我会借(抄)鉴(袭)啊{:301_976:}
直接贴上大佬的代码:
def main():
s=open("1.txt",'r')
for line in s.readlines():
line=line.strip(' ')
result=shu(line)
print(result)
def shu(line):
temp=''
z="abcdefghijklmnopqrstuvwxyz"
zz="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
for i in range(0,len(line)):
if line in z:
m=ord(line)-96
if m<=13:
temp+=z
else:
temp+=z
elif line in zz:
m=ord(line)-64
if m<=13:
temp+=zz
else:
temp+=zz
elif line=='\n':
temp+='\n'
else:
temp+=line
return temp
if __name__ == '__main__':
main()
经过一番认真阅(百)读(度),我大致懂了大佬的思路:通过返回字母对应的十进制整数进行移位操作,再对应到创建的a~z的字符串,不得不感叹大佬思路的精妙啊,开始修改:
def main():
s=open("1.txt",'r')
for line in s.readlines():
line=line.strip(' ')
result=shu(line)
print(result)
def shu(line):
temp=''
z="abcdefghijklmnopqrstuvwxyz"
# zz="ABCDEFGHIJKLMNOPQRSTUVWXYZ"大写字母不用处理都注释掉
for i in range(0,len(line)):
if line in z:
m=ord(line)-96
if m<=7:# 前7位+7
temp+=z
elif 7<m<=14:# 8-14位加-7
temp+=z
elif 14<m<=20:# 15-20位+6
temp+=z
elif 20<m<=26:# 21-26位-6
temp+=z
# elif line in zz:
# m=ord(line)-64
# if m<=13:
# temp+=zz
# else:
# temp+=zz
elif line=='\n':# 不知道大佬为什么要处理换行,感觉可以直接算到下面的else里啊
temp+='\n'
else:
temp+=line
return temp
if __name__ == '__main__':
main()
F5跑一下看看结果:
================ RESTART: C:\Users\Administrator\Desktop\zimu.py ===============
Traceback (most recent call last):
File "C:\Users\Administrator\Desktop\zimu.py", line 35, in <module>
main()
File "C:\Users\Administrator\Desktop\zimu.py", line 5, in main
result=shu(line)
File "C:\Users\Administrator\Desktop\zimu.py", line 19, in shu
temp+=z
IndexError: string index out of range
额。。。报错了 IndexError: string index out of range 为什么会超出啊?{:301_979:}
经过一番研(百)究(度),发现是因为字符串的第一位下标是0,所以z=a,正确的移位应该是再减去1:7-1=6,-7-1=-8,6-1=5,-6-1=-7,修改好再跑一次:
================ RESTART: C:\Users\Administrator\Desktop\zimu.py ===============
<?rfe plxybug='1.0' lgjukbgn='ozm-8' yzhgkheugl='sly' ?>
<fhv>
<bgz ghfl="fightHeroCampIf" pheol="2" />
<bgz ghfl="skillLeftPoint" pheol="0" />
<yzxbgn ghfl="inCheatGameCheckLastTime">3289843741</yzxbgn>
<bgz ghfl="skillSelectRandSaveCl" pheol="4400" />
<bgz ghfl="skillCheatSelectCheckRandSaveAn" pheol="231109" />
<bgz ghfl="fightHeroJobIf" pheol="2" />
<bgz ghfl="Sjxllgfhghnlx%20Foeeyjxllg%20fukl" pheol="-1" />
<yzxbgn ghfl="inGameLastTime">1644816420</yzxbgn>
<bgz ghfl="skillSelectRandSaveAn" pheol="10104" />
<bgz ghfl="infoCheatInCheckGameSeconds" pheol="210905" />
<bgz ghfl="skillLevelIf" pheol="1" />
<bgz ghfl="inGameLastDay" pheol="20220214" />
<bgz ghfl="skillSelectRandSaveBm" pheol="6104" />
<yzxbgn ghfl="playerExp">2</yzxbgn>
<yzxbgn ghfl="playerCheatExpCheck">210905</yzxbgn>
<bgz ghfl="skillCheatSelectCheckRandSaveBm" pheol="223109" />
<bgz ghfl="infoCheatInCheckGameDays" pheol="210903" />
<bgz ghfl="skillCheatLevelCheckIf" pheol="210903" />
<bgz ghfl="Sjxllgfhghnlx%20Rlyueozbug%20Wbkza" pheol="1080" />
<bgz ghfl="skillCheatLeftCheckPoint" pheol="210901" />
<bgz ghfl="infoInGameDays" pheol="1" />
<bgz ghfl="Sjxllgfhghnlx%20Rlyueozbug%20Hlbnaz" pheol="2277" />
<bgz ghfl="skillCheatSelectCheckRandSaveCl" pheol="219701" />
<bgz ghfl="isPrivacyAgreed" pheol="1" />
<bgz ghfl="__UNITY_PLAYERPREFS_VERSION__" pheol="1" />
<bgz ghfl="infoInGameSeconds" pheol="2" />
<bgz ghfl="inCheatGameCheckLastDay" pheol="40651329" />
</fhv>
额。。。成功了,但又没有完全成功,名字是对上了,本来对的又全错了,理论上也能凑合看,但我忍不了啊。。。{:301_971:}
经过观察存档结构,大致的思路是这样的:首先查找“name=”,开头到“name=”后面这段不做处理直接输出,从“name=”后面开始查找第一个引号,这一段内容移位处理,引号后面也不处理:
定义好start和end
start=str(line).find("name=",0,len(line))+6 #name=“占了6个字符,所以加6
end=str(line).find("\"",start,len(line))#引号要用“\”转义
完整代码如下,思路都在注释里了:
def main():
s=open("1.xml",'r') #存档是xml格式的
for line in s.readlines():
#line=line.strip(' ')不需要删空格,注释掉
result=shu(line)
print(result)
with open('D:\\1.xml','a',encoding='utf-8') as f: #加个写入直接生成文件
f.write(result)
def shu(line):
temp=''
start=str(line).find("name=",0,len(line))+6 #name=“占了6个字符,所以加6
end=str(line).find("\"",start,len(line)) #引号要用“\”转义
z="abcdefghijklmnopqrstuvwxyz"
# zz="ABCDEFGHIJKLMNOPQRSTUVWXYZ"大写字母不用处理都注释掉
if start<6:#当本行搜不到name时会返回-1,但是因start后面+6了,所以找不到时可以写为<6或==5
for i in range(0,len(line)):
temp+=line#本行没有name就直接输出
else:
for i in range(0,start):
temp+=line#能搜到开头到“name=”后面这段不做处理直接输出
for i in range(start,end):
if line in z:#中间需要移位的4种情况
m=ord(line)-96
if m<=7:
temp+=z
elif 7<m<=14:
temp+=z
elif 14<m<=20:
temp+=z
elif 20<m<=26:
temp+=z
else:
temp+=line#中间有小写字母以外的字符也是直接输出
for i in range(end,len(line)):
temp+=line#最后部分直接输出
return temp
if __name__ == '__main__':
main()
运行结果如下:
=============== RESTART: C:\Users\Administrator\Desktop\zimu2.py ===============
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
<int name="fightHeroCampBmBm" value="2" />
<int name="fightHeroCampCl" value="2" />
<string name="equipPropertyBmAnAn"></string>
<int name="allCheatSkillCheckResetUsedTimesToday" value="210901" />
<int name="skillCheatLevelCheckBmAnCl" value="210901" />
<int name="skillCheatLevelCheckBmClFi" value="210921" />
<int name="heroUpgradeLevelBm" value="55" />
<string name="equipPropertyGhFi"></string>
<string name="equipPropertyAn"></string>
<int name="fightHeroCampJe" value="2" />
<string name="equipPropertyJeBm"></string>
<int name="infoShopDailyRewardTimes" value="49" />
<string name="equipUpgradeExpFi">103</string>
<int name="skillLevelBmClEj" value="10" />
<int name="shopDiamondAdsTimes" value="76" />
<string name="equipPropertyDkBm"></string>
<int name="fightHeroJobDk" value="2" />
<int name="equipCheatUpgradeCheckLevelEj" value="211933" />
<string name="equipUpgradeExpBm">209</string>
<string name="equipPropertyHgJe"></string>
<int name="freeAdsNeedTimes" value="-141" />
<string name="equipPropertyBmAn"></string>
<int name="equipSortIdLast" value="326" />
<string name="equipPropertyIfBm">01048016120090330090450090450200340100320080330060</string>
<string name="equipPropertyEjGh"></string>
<string name="equipPropertyBmAnEj"></string>
<int name="Sjxllgfhghnlx%20Rlyueozbug%20Wbkza" value="1080" />
<int name="skillCheatLevelCheckBmDkFi" value="210901" />
<int name="equipUsedIdCl" value="94" />
<int name="skillCheatLevelCheckBmFiCl" value="210901" />
<int name="skillLevelBmFiCl" value="0" />
<int name="skillCheatLevelCheckBmEj" value="210941" />
<int name="skillCheatLevelCheckAn" value="210941" />
<string name="equipCheatUpgradeCheckExpBm">211319</string>
<string name="equipPropertyEjDk"></string>
<string name="equipPropertyFiHg"></string>
<int name="fightHeroPosFi" value="9" />
<int name="skillLevelBmEjDk" value="0" />
<string name="equipUpgradeExpCl">305</string>
<string name="equipPropertyEjIf"></string>
<string name="equipPropertyEjBm"></string>
<string name="equipPropertyGhBm"></string>
<int name="fightHeroPosIf" value="5" />
</map>
D盘下也生成了解密后的文件,至此存档字母移位加密破解完成!{:301_978:}
后记:
写的很详(啰)细(嗦),因为我想把思考的过程也写出来,给跟我一样的小白一些思路,其实中间走了很多弯路,特别是最后的代码,一直在不停的试错,最后全靠百度一点点搞定的,因为我真的是小白,真的不会编程啊!
能够耐心看到这儿的靓仔,确定不给个评分再走吗?{:301_974:}
我昨天晚上找到某软件的服务器文档,也是字母移位加密的,并且根据视频提供的方法找到了加密的代码,但是我用视频提供的Java方法解密,解密的代码是视频up主提供的,我复制后运行提示错误,搞了半天都没得行解密 hjtkxg 发表于 2022-2-16 17:57
那可能是复制错了吧,就这样吧文件都删了。反正是不可逆的,没意义
什么意思?没看懂。。。 谢谢楼主分享 谢谢分享 感谢楼主分享~~ 很有意思的思路,学习了,感谢 写的很详细 那可能是复制错了吧,就这样吧文件都删了。反正是不可逆的,没意义 感谢分享! 支持这个多久解密出来的