From cb60de30dca0ee6502ccfdf29900f8f8e6137cdc Mon Sep 17 00:00:00 2001 From: Mook Date: Fri, 24 Sep 2021 03:12:33 -0700 Subject: [PATCH] CopyManga: Update getting decrypt passwords. (#9209) Instead of looking for attributes on elements, we now have to evaluate JavaScript to get the decryption password. Fixes #9197 --- src/zh/copymanga/build.gradle | 2 +- .../extension/zh/copymanga/CopyManga.kt | 21 ++++++++++++++++--- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/zh/copymanga/build.gradle b/src/zh/copymanga/build.gradle index d6ece7935..257d41846 100644 --- a/src/zh/copymanga/build.gradle +++ b/src/zh/copymanga/build.gradle @@ -5,7 +5,7 @@ ext { extName = 'CopyManga' pkgNameSuffix = 'zh.copymanga' extClass = '.CopyManga' - extVersionCode = 16 + extVersionCode = 17 } apply from: "$rootDir/common.gradle" diff --git a/src/zh/copymanga/src/eu/kanade/tachiyomi/extension/zh/copymanga/CopyManga.kt b/src/zh/copymanga/src/eu/kanade/tachiyomi/extension/zh/copymanga/CopyManga.kt index d66f3b88a..a0bd7ea6a 100644 --- a/src/zh/copymanga/src/eu/kanade/tachiyomi/extension/zh/copymanga/CopyManga.kt +++ b/src/zh/copymanga/src/eu/kanade/tachiyomi/extension/zh/copymanga/CopyManga.kt @@ -3,6 +3,7 @@ package eu.kanade.tachiyomi.extension.zh.copymanga import android.app.Application import android.content.SharedPreferences import com.luhuiguo.chinese.ChineseUtils +import com.squareup.duktape.Duktape import eu.kanade.tachiyomi.lib.ratelimit.SpecificHostRateLimitInterceptor import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.source.ConfigurableSource @@ -20,6 +21,7 @@ import okhttp3.Request import okhttp3.Response import org.json.JSONArray import org.json.JSONObject +import org.jsoup.nodes.Document import org.jsoup.nodes.Element import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get @@ -179,7 +181,7 @@ class CopyManga : ConfigurableSource, HttpSource() { override fun chapterListRequest(manga: SManga) = mangaDetailsRequest(manga) override fun chapterListParse(response: Response): List { val document = response.asJsoup() - val disposablePass = document.select("div.detailPass").first()?.attr("disposable") + val disposablePass = this.evaluateScript(document, "dio") // Get encrypted chapters data from another endpoint val chapterResponse = @@ -234,7 +236,7 @@ class CopyManga : ConfigurableSource, HttpSource() { override fun pageListParse(response: Response): List { val document = response.asJsoup() val disposableData = document.select("div.imageData").first().attr("contentKey") - val disposablePass = document.select("div.imagePass").first()?.attr("contentKey") + val disposablePass = this.evaluateScript(document, "jojo") val pageJsonString = decryptChapterData(disposableData, disposablePass) val pageArray = JSONArray(pageJsonString) @@ -448,11 +450,24 @@ class CopyManga : ConfigurableSource, HttpSource() { } } + private fun evaluateScript(document: Document, expression: String): String { + return Duktape.create().use { duktape -> + document.select("script:not([src])").map(Element::data).forEach { script -> + try { + duktape.evaluate(script) + } catch (ex: Exception) { + // Ignore any exception from evaluating the script + } + } + duktape.evaluate(expression).toString() + } + } + // thanks to unpacker toolsite, http://matthewfl.com/unPacker.html private fun decryptChapterData(disposableData: String, disposablePass: String?): String { val prePart = disposableData.substring(0, 16) val postPart = disposableData.substring(16, disposableData.length) - val disposablePassByteArray = (disposablePass ?: "xxxmanga.abc.key").toByteArray(Charsets.UTF_8) + val disposablePassByteArray = (disposablePass ?: "hotmanga.aes.key").toByteArray(Charsets.UTF_8) val prepartByteArray = prePart.toByteArray(Charsets.UTF_8) val dataByteArray = hexStringToByteArray(postPart)