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
This commit is contained in:
Mook 2021-09-24 03:12:33 -07:00 committed by GitHub
parent f26a96c95f
commit cb60de30dc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 19 additions and 4 deletions

View File

@ -5,7 +5,7 @@ ext {
extName = 'CopyManga'
pkgNameSuffix = 'zh.copymanga'
extClass = '.CopyManga'
extVersionCode = 16
extVersionCode = 17
}
apply from: "$rootDir/common.gradle"

View File

@ -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<SChapter> {
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<Page> {
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)