你皮任你皮 发表于 2022-2-16 13:36

破解某游戏存档字母移位加密

本帖最后由 你皮任你皮 于 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:}


janebos 发表于 2022-2-17 16:50

我昨天晚上找到某软件的服务器文档,也是字母移位加密的,并且根据视频提供的方法找到了加密的代码,但是我用视频提供的Java方法解密,解密的代码是视频up主提供的,我复制后运行提示错误,搞了半天都没得行解密

你皮任你皮 发表于 2022-2-16 19:33

hjtkxg 发表于 2022-2-16 17:57
那可能是复制错了吧,就这样吧文件都删了。反正是不可逆的,没意义

什么意思?没看懂。。。

wenz 发表于 2022-2-16 13:42

谢谢楼主分享

wanderz 发表于 2022-2-16 15:09

谢谢分享

anmonkey 发表于 2022-2-16 15:35

感谢楼主分享~~

深蓝浅蓝 发表于 2022-2-16 16:02

很有意思的思路,学习了,感谢

传说中的yang哥 发表于 2022-2-16 16:08

写的很详细

hjtkxg 发表于 2022-2-16 17:57

那可能是复制错了吧,就这样吧文件都删了。反正是不可逆的,没意义

gunxsword 发表于 2022-2-16 18:25

感谢分享!

lijisheng 发表于 2022-2-16 19:40

支持这个多久解密出来的
页: [1] 2 3
查看完整版本: 破解某游戏存档字母移位加密