观前须知:

本人毫无任何逆向经验,此次所有开发均大程度依赖vibe coding,因此文章中可能存在大量错误,仅作为个人开发记录

随机的一天里,我打开了Mihon找漫画看,然后在官方库里翻到了8comic的这个图源,一搜发现资源居然意外地挺全,于是急头白脸加了一堆书架准备日后再看,结果随手点开一本却发现根本加载不了,报错unexpected end of string。

抱着求知若渴的精神我点开了仓库的Github,果然找到了关于这个源的issue

显然除了前面提到的Header问题确实没有什么对修这玩意有帮助的。

于是我选择开始和Gemini辩论,开始找解决办法。

第一章:天才的陨落

按照issue里提到的请求头需要加Referer的问题,交给G指导以后果然很快就解决了

只需要在请求里加上这么一段就行

    override fun pageListRequest(chapter: SChapter): Request = GET(newReadUrl + chapter.url, headers.newBuilder().set("Referer", "$baseUrl/").build())

现在在Mihon中已经可以通过WebView正确打开源网址了,可喜可贺可喜可贺,就在我以为之后也会如此顺利的时候,图片界面的报错马上就把我打回原形了

第二章:瞪眼法

显然让AI完全接管破解加密这件事在现在还难以实现,因此我能做的也只是边通过AI学爬虫知识边想办法看懂网站的加密方式。

在G指导的悉心教导下,我终于学会了在浏览器终端里看网页当前的各个变量和源码。

在不知道多久但是总之应该很久的查找之后,我终于是发现了一些契机

https://img7.8comic.com/3/17873/1/001_2sJ.jpg
https://img7.8comic.com/3/17873/1/002_nM2.jpg
https://img7.8comic.com/3/17873/1/003_H3x.jpg

这是漫画具体图片的地址,可以看出除了前面的域名之外,图片后缀的3个字符实在引人注目

同时,在网站变量中还有两个醒目的字符串

一个是长40的

2sJnM2H3x65Pr7jjh9C5YBRrK5bPR2VSbFwTQ4s4

而另一个则是……

ab2sJnM2H3x65Pr7jjh9C5YBRrK5bPR2VSbFwTQ4s4apbv0acRp4aU7F7mwKKdR69bMFBCFWy9Ac2AuPCpE77C95dambv0adN65rA8PSd62RpJ9ksN6QQWKyESh3PkXX2Y6WH7w6aqbv0aeE3NdHdMW3wGNb5ubk2AW43R93XkD8eQGdXeA6Bafaobv0af6x63QjK3ppXJxPf2dDD5F7XgQ5nQS8H2rWnPRGnqaobv0agWtPpXqH7cfEFjA3q6RGBTB5rCBq3B3BK5Uv3CNy2aobv0ahB22wWvBA2b4U7Jff877B3HMeE72FFy8W3EhRQVm8aobv0ai8g3dDxHVtjG3gBjsq9VQEY9eKP7GUqGHdYhGWTdyaobv0ajDqEtSaPXtpED4SstsVEWJV5jDSw6NgPEc3t7YT2vatbQ0akGuU7QeD257T7uFqd2JPFWT7s5J2YT4D2eN7T8QcxaqbQ0alDu798r27gn4TjX4d6WG2PHGqRQ7JUcG9xChTENtfapbQ0amTtN4Xu8796ESpP82gEYP8EPrWMv6U9VKgTmVJWxcatbQ0an3cCwC4P4ub2RrBccaWTNF3X96HeRG9YVuKx4UHqpaqbQ0aoDqNtBrKXgfRHrFybbD53NUWu844NWpM6hN8RDAdxaobQ0apE6MeXvTQyeRJ5S2hbVSBUV3eNRy2Q55C4227QBdrasbQ0aqBs9pX4TDbfAYnXmnkHDTDQ6dJDbMKhMCsV9PDN45anbQ0arC8Jf89H6hnDU4Cke65AS6SVaW8aEDpMJuUcQR42jaqbQ0as5hQyYm44gk4E3Tu7nSKUSWBaR2f7YcMGt89GGUt7aFbu0atVsW5W4PAk689dJ2rhPKNG5U8ADcB7cDRsDtQAX6taCbQ0auKrDj8pTU62NTvHtm5XVU8HYeYN5F8dDC52wN9E35aubQ0avE5HgH635kkNVfYa8n2K2JKReNGwFBhRE5GyQSWebapbQ0awKnYv83D5jwXWrVng3SP793GqMQyBJtTGw8m2UJyhasbQ0axC347WbTWtq48b3c6sHUAKD879DfC7gPT6H2XDNqjaobQ0ay4q37HbGVjjWP98v3gEJR4MEhDN63Yy982Fj99FyyasbQ0azEbMs6kPHce77tQ5wrKTTTMFm8D6XMbHD4YxY6A9caqbQ0aAQ2YgKtP8th9SrRmyb488EAKaGSmD6yNBc5mEPGncambQ0aBWhG2VmNUrvYYpAby9WG6T4Rs6BnHPvGRdD442W93aqbQ0aCHtPmMq65xw75qJv7r28NVR3cH8xEV7JMeFdUWJjbambQ0aDQhUb8mFNayPTtPp4xX4SQG9f7CqGHpU7hHv63XnnanbQ0aE3bW2HrDG5mS6462xuNQ7RDR47TgB7aU7tAkJDUv4anbQ0aF88M424KC43F8wXhrjVBVQ4J6FSg6J2G6mPwH5WubanbQ0aG3rNuJsSSms92f9a4kN2QUNH5SA5D86WBc73B3Uajanbv0aHX8PbYu2De2N8r2df3PQ58575XTaEMv7WpR338S4canbv0aIVs7qRvXEd53X2FbarGYQD2K8H9vD9jF8tUsFTP5wakbv0aJKwVvFxQYnh44342hw75QQY792K9FDxYD6CkV98syavbu0aK6nS6JjK5jrQ5g6qrvD7WMA6qJRyRVk5P4U5DUXanaobu0aLUyEf5bKD4pNHj58pbVSH2M23ACgACwYRtQfXBSupaybu0aMPt7jPnRPhnMPaVupv5RTAVDtY6nTBrDP25nS4865akbu0aNXp4s8cWJqx36e7ubuE4VQ7YbJS7MFpBUsTyK965cafbu0aO58Rc7hCBa2EVeF2ngWASC8Cv9Gx25p6U7Ta9JJxeambQ0aPMfQ3R7F3ygG47At8w73DMWYdX6tC33JRfWsGB99tapbQ0aQ7uVmMkTQtaH6gNjabPMR792vD695HnRRmMmFAEqgasbv0aRF5BnRb36bu53qAmdgCWP9APjA6xVGnSR66aUCKeyavbu0aSNqBn2548ajTC32fevV9PF5Cd4X8MP8A38WxC6Xuralbw0aTXg672vW9u7CMj699w56K9ERsM4x3T7GW6Cp9BBcqavbw0aUV62eRg6FaqTChRe2kB3FENXj4RrGUcVJbNg2B69yaobj0aVYt3w4sNE6yJPy4wpfKW24C9cMX73YaRDaSt4HWc5aobj0aWG22mNgR6ugMVrWr9vUQKC4VvCM3EVn7AjVcCBKnhajbj0aXTnFh29KEegRTtK37mEV2MG3mHWt3X456uC58HHggaqbj0aYBvE8KwP65xT2kEus2QPMV8P58KpDUfH35EnFA7svajbj0aZRr42JqW7a9T3d73qePADFMDeMUdFD4S5q73SD5daavbt0baP77qVbYC7dAKtJxw4TSSGS4gQAuPBmUN44629Rm2avbt0bbNmAd9w2H3jQ4aXu6rYA7GYSkTQbV95W7f2a84Euraybt0bc7aVqP5UEmu2Mf4q3pEVQ5KMsJXfNSa7YqM54PP5gaAbj0bdN4X24eRPwcXEp9wg9656UUYaTAjBVwS4fJkUW2t3aBbj0beUfV7Ut7AtxCAu53j4SMA8USsS53PP9THkW868N88aAbj0bfEuJbTrD6n8H5kJ8t2QK4SFY3DYpD7tBF4UdHNBk8aqbj0bg2r3hNaQJypRC67c8x4U3YG6k9PwHXr6WqUsJNYq4aqbk0bhVkF5JqMJ96XGyNfr5XS3HMXt6NkGWjHPaD4NNKvfaybk0biB9HhFySFtsF87V7j8D43THAeYRw3ReY5wDq59WdkaCbk0bjRjByX9XG9gBNgTppuGKYJDTtRKr76qW87QkA7Yjhaqbj0bjEdEfQt2YaqB3sMstdV3EBF3tA2aPJpQV3NjJJWu9aibjebkYxF2KeBEd3JP6X72aKRJ2XFyCDsK6m8JcQ9UPN9yaJbk0blGrGw37YHggMQh7jk5DYMGTK2C4x3P2YY45pV82xbarbk0bmCdCh974H5v7Ju6k8fKMC7E8cTX7JAnSQ67dXNY5eaubj0546865496d67696d67636f6d69632e6a7067burjbpcrkknnjmukjslmbxhuymdbqegrdxkwnhvqqwsntyv

不难看出,上面一段和图片后缀的字符一样,同时也包含在下面这段中

在大段丢进Gemini对话框之后,我大概懂了上面的大概是密钥,下面就是储存整个漫画路径的字符串

在肉眼对照了几十张图之后,我大概得出了一个结论。

每47字符为一节,一节中有连续的30个字符作为本节的图片的后缀,每三个为一张,每十张后从开头开始循环但向后偏移一位,例如刚才的例子中第十一张后缀应该为’sJn‘。

同时可以看到,每节中的固定位置有‘ab’‘ac’‘ad’等顺序增长的字符,询问后得知这应该是存储章节号的字符,ab=1,ac=2,ad=3(跟没有一样的加密)

同理可以对照每话页数找到存储页数的位置。

于是我迫不及待叫G指导帮我写好代码编译出来测试,结果是,完全正确,我完美打开了在电脑上测试的那部漫画。

就在我准备满心欢喜的收摊的时候,我顺手开了另一部漫画。

毫无意外的,打不开。

第三章:Gemini藏东西了

急头白脸问了一个多小时得到的结果都不尽如人意,已经到了放弃的边缘了。

突然灵光乍现,在聊天框的结尾突发奇想的加了一句:‘如果你需要什么数据请告诉我,我来帮你查找’

于是乎Gemin交了焚诀,在浏览器加载网页前运行一小段JS代码用来定位是那个函数赋值了密钥变量。

然后……

甚至不需要G指导来解释,这一大段写在一起的函数让我根本不废什么力就直接读懂了,之前提到的所有信息都有一个偏移值,偏移直接代表了这些信息在字符串中的位置,只要抓取到这些偏移值,就能轻而易举的解析所有图片。

后面就是无聊的vibe coding环节(以及我个人不建议拿Gemini vibe coding,太坑了,具体会在下一章讲到)。

在最后一次编译测试之后,我打开了3部喜欢的漫画,全部正常,于是乎准备收工……

第四章:中道崩殂

不出意外的出意外了,更多的漫画都无法被解析。

在经过几分钟的检查后,噩耗传来

前面的域名也是加密的,密文来自之前提到的长字符串的尾段84个字符

0546865496d67696d67636f6d69632e6a7067twjrxwkaqygccfikeepvknwtkrgdunwvchtjlfcyyixwybs
0546865496d67696d67636f6d69632e6a7067burjbpcrkknnjmukjslmbxhuymdbqegrdxkwnhvqqwsntyv
0546865496d67696d67636f6d69632e6a7067jtxejuhhngowxcgskknhxwlwqxgygflpujsxfsdvmgjdkax

而之前没有查出的原因竟然是,我顺手找的几个我喜欢的漫画,前面的域名一模一样,因此在硬编码域名时表现的没问题。

在进一步修改排查中发现,Gemini竟偷偷硬编码了几个特殊值,就导致无论怎么测这几部都不会报错,但其他漫画则呈现出完全不同的逻辑。在查出问题前这几乎是除了加密外我最困惑的事了。

就像世间大多数人那样,遗憾总是充斥着我们的人生,这个故事当然也不例外,倒不是因为我真的被最后这点加密急哭了(也有一点),而是从开始研究以来,我的屁股已经像粘狗屎一样粘在椅子上十个小时了,除了这行为对一个肾结石,痔疮等一堆职业病(职业在哪)缠身的人来说纯是在作,另一个就是,作为一个有作业,实验报告等一堆东西要交的大三学生,我真的没时间了。

总而言之还是很开心的,这次大概有一多半的漫画都在图源上能看了,在G指导的硬编码特殊值的威能下,我自己追的那几部也能直接看了。对爬虫和图源的运行原理有了更深的理解(难说)总而言之,学习自己感兴趣的总是令人开心的。