Skip to content

Commit

Permalink
Fix one click like exception
Browse files Browse the repository at this point in the history
  • Loading branch information
whitechi73 committed Jan 24, 2024
1 parent ad38c72 commit 8f1a46c
Show file tree
Hide file tree
Showing 11 changed files with 140 additions and 33 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,13 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
```

## 感谢以下项目

- [QAuxiliary](https://github.com/cinit/QAuxiliary): Plagiarism of the project code
- [LSPosed](https://github.com/LSPosed/LSPosed): Hook framework
- [vue](https://cn.vuejs.org/): Setting page framework
- [OpenShamrock](https://github.com/whitechi73/OpenShamrock): Protocol Hook

## 贡献者

[![][contrib-image]][contrib-link]
Expand Down
17 changes: 3 additions & 14 deletions app/src/main/java/moe/fuqiuluo/entries/DvmKitStructure.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import moe.qwq.miko.internals.locators.ClassLocator
import moe.qwq.miko.internals.locators.FieldLocator
import moe.qwq.miko.internals.locators.MethodLocator
import moe.qwq.miko.internals.locators.QQSettingMeConfigLocator
import moe.qwq.miko.internals.locators.VoteHelperVoteLocator
import moe.qwq.miko.internals.locators.WebSecurityPluginV2PluginLocator
import java.lang.reflect.Array as JavaReflectArray

Expand Down Expand Up @@ -38,6 +39,7 @@ enum class MethodEnum(
) {
@Deprecated("Lower Speed")
@SerialName("QQSettingMeConfig.GetItems") QQSettingMeConfigGetItems,
@SerialName("VoteHelper.Vote") VoteHelperVote(VoteHelperVoteLocator),
}

@Serializable
Expand All @@ -52,23 +54,14 @@ data class ClassInfo(
@SerialName("full_name") val fullName: String,
@SerialName("array") val isArray: Boolean,
) {
val isVoid: Boolean = fullName == "void"

fun toClass(): Class<*>? {
if (isVoid) {
return Void.TYPE
}
if (isArray) {
return LuoClassloader.load(fullName)?.let {
JavaReflectArray.newInstance(it, 0).javaClass
}
}
return LuoClassloader.load(fullName)
}

companion object {
val VOID = ClassInfo("void", false)
}
}

@Serializable
Expand Down Expand Up @@ -100,22 +93,18 @@ data class MethodInfo(
@SerialName("private") val private: Boolean,
@SerialName("static") val static: Boolean,
@SerialName("args") val args: List<ClassInfo>,
@SerialName("return_type") val returnType: ClassInfo,
) {
fun toMethod(): Method? {
val cls = parent.toClass()
?: return null
val argTypes = args.map {
it.toClass() ?: return null
}.toTypedArray()
val returnType = returnType.toClass()
?: return null
return cls.declaredMethods.firstOrNull {
Modifier.isStatic(it.modifiers) == static &&
Modifier.isPrivate(it.modifiers) == private &&
it.name == methodName &&
it.parameterTypes.contentEquals(argTypes) &&
it.returnType == returnType
it.parameterTypes.contentEquals(argTypes)
}
}
}
2 changes: 2 additions & 0 deletions app/src/main/java/moe/qwq/miko/ActionManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ object ActionManager {
FetchService::class.java,
PacketHijacker::class.java,

OneClickLike::class.java,

BrowserAccessRestrictions::class.java,
SimplifyHomepageSidebar::class.java,
DefaultPacketHijacker::class.java,
Expand Down
16 changes: 10 additions & 6 deletions app/src/main/java/moe/qwq/miko/internals/helper/DvmLocator.kt
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ object DvmLocator {

fun findClass(cls: ClassEnum, locator: ClassLocator? = cls.locator): Class<*>? {
if (locator != null && !cacheMap.classes.containsKey(cls)) {
locateClass(cls, runCatching { locator() }.getOrNull())
val locatedClass = runCatching { locator() }.getOrNull()
locateClass(cls, locatedClass)
return locatedClass
}
if(cacheMap.classes.containsKey(cls)) {
val ret = cacheMap.classes[cls]!!.toClass()
Expand All @@ -54,7 +56,9 @@ object DvmLocator {

fun findField(field: FieldEnum, locator: FieldLocator? = field.locator): Field? {
if (locator != null && !cacheMap.fields.containsKey(field)) {
locateField(field, runCatching { locator() }.getOrNull())
val locatedField = runCatching { locator() }.getOrNull()
locateField(field, locatedField)
return locatedField?.second
}
return cacheMap.fields[field]?.toField()
}
Expand All @@ -77,20 +81,20 @@ object DvmLocator {

fun findMethod(method: MethodEnum, locator: MethodLocator? = method.locator): Method? {
if (locator != null && !cacheMap.methods.containsKey(method)) {
locateMethod(method, runCatching { locator() }.getOrNull())
val locatedMethod = runCatching { locator() }.getOrNull()
locateMethod(method, locatedMethod)
return locatedMethod?.second
}
return cacheMap.methods[method]?.toMethod()
}

fun locateMethod(method: MethodEnum, result: Pair<Class<*>, Method>?) {
if (result != null && !cacheMap.methods.containsKey(method)) {
val returnType = if (result.second.returnType == Void.TYPE) ClassInfo.VOID
else if (result.second.returnType.isArray) ClassInfo(result.second.returnType.componentType.name, true)
if (result.second.returnType.isArray) ClassInfo(result.second.returnType.componentType.name, true)
else ClassInfo(result.second.returnType.name, false)
cacheMap.methods[method] = MethodInfo(
parent = ClassInfo(result.first.name, false),
methodName = result.second.name,
returnType = returnType,
private = Modifier.isPrivate(result.second.modifiers),
static = Modifier.isStatic(result.second.modifiers),
args = result.second.parameterTypes.map {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
@file:OptIn(DelicateCoroutinesApi::class)

package moe.qwq.miko.internals.hooks

import android.content.Context
import com.tencent.common.app.AppInterface
import com.tencent.qphone.base.remote.ToServiceMsg
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import moe.qwq.miko.actions.IAction
import moe.qwq.miko.ext.hookMethod
import moe.qwq.miko.internals.helper.AppRuntimeFetcher
Expand All @@ -19,22 +24,32 @@ class DefaultPacketHijacker: IAction {
if (app !is AppInterface) return

AppInterface::class.java.hookMethod("sendToService").before {
val to = it.args[0] as ToServiceMsg
if (QwQSetting.disableUselessPacket && to.serviceCmd in TRASH_PACKET) {
val toServiceMsg = it.args[0] as ToServiceMsg
if (QwQSetting.disableUselessPacket && toServiceMsg.serviceCmd in TRASH_PACKET) {
it.result = Unit
} else if (QwQSetting.disableUpdateCheck && to.serviceCmd == "ProfileService.CheckUpdateReq") {
} else if (QwQSetting.disableUpdateCheck && toServiceMsg.serviceCmd == "ProfileService.CheckUpdateReq") {
it.result = Unit
} else if (QwQSetting.oneClickLike && to.serviceCmd == "VisitorSvc.ReqFavorite") {
var total = 0
val toServiceMsg = it.args[0] as ToServiceMsg
while (total != 20) {
val random = Random.nextInt(1 .. 10)
toServiceMsg.extraData.putInt("iCount", random)
app.sendToService(toServiceMsg)
total += random
}

/* 协议一键赞 问题多多
else if (QwQSetting.oneClickLike && toServiceMsg.serviceCmd == "VisitorSvc.ReqFavorite" &&
!toServiceMsg.extraData.getBoolean("qwq", false)
) {
toServiceMsg.extraData.putBoolean("qwq", true)
GlobalScope.launch {
var total = 0
while (total < 20) {
var random = Random.nextInt(1 .. 10)
if (20 - total < random) {
random = 20 - total
}
toServiceMsg.extraData.putInt("iCount", random)
app.sendToService(toServiceMsg)
total += random
}
}
it.result = Unit
}
}*/
}
}

Expand Down
59 changes: 59 additions & 0 deletions app/src/main/java/moe/qwq/miko/internals/hooks/OneClickLike.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package moe.qwq.miko.internals.hooks

import android.content.Context
import android.view.View
import com.tencent.mobileqq.activity.VisitorsActivity
import com.tencent.mobileqq.data.CardProfile
import com.tencent.mobileqq.profile.vote.VoteHelper
import com.tencent.mobileqq.profilecard.base.component.AbsProfileHeaderComponent
import de.robv.android.xposed.XposedBridge
import moe.fuqiuluo.entries.MethodEnum.VoteHelperVote
import moe.fuqiuluo.entries.MethodEnum.valueOf
import moe.qwq.miko.actions.IAction
import moe.qwq.miko.ext.hookMethod
import moe.qwq.miko.internals.helper.DvmLocator
import moe.qwq.miko.internals.setting.QwQSetting
import moe.qwq.miko.internals.setting.QwQSetting.ONE_KEY_LIKE
import java.lang.reflect.Method


class OneClickLike: IAction {
override fun invoke(ctx: Context) {
val setting = QwQSetting.getSetting(ONE_KEY_LIKE)
runCatching {
val vote = DvmLocator.findMethod(VoteHelperVote)
val voteHelperField = VisitorsActivity::class.java.declaredFields.firstOrNull {
it.type == VoteHelper::class.java
}
if (voteHelperField == null || vote == null) {
setting.isFailed = true
return
}

if (!QwQSetting.oneClickLike) return@runCatching

VisitorsActivity::class.java.hookMethod("onClick").before {
val view = it.args[0] as View
val profile = view.tag
if (profile == null || profile !is CardProfile) return@before
val voteHelper = voteHelperField.get(it.thisObject) as VoteHelper
for (i in 0..20) {
vote.invoke(voteHelper, profile, view)
}
it.result = Unit
}

AbsProfileHeaderComponent::class.java.hookMethod("handleVoteBtnClickForGuestProfile").before {
val selfMethod = it.method as Method
if (!selfMethod.isAccessible) {
selfMethod.isAccessible = true
}
for (i in 0..19) {
selfMethod.invoke(it.thisObject, it.args[0])
}
}
}.onFailure {
setting.isFailed = true
}
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
@file:Suppress("LocalVariableName")
package moe.qwq.miko.internals.locators

import android.widget.ImageView
import com.tencent.mobileqq.activity.qqsettingme.config.QQSettingMeBizBean
import com.tencent.mobileqq.data.CardProfile
import com.tencent.mobileqq.profile.vote.VoteHelper
import de.robv.android.xposed.XposedBridge
import de.robv.android.xposed.XposedBridge.log
import moe.fuqiuluo.entries.ClassEnum
Expand All @@ -24,4 +27,13 @@ object QQSettingMeConfigGetItemsLocator: MethodLocator {
return QQSettingMeConfig to method
}
}
*/
*/

object VoteHelperVoteLocator: MethodLocator {
override fun invoke(): Pair<Class<*>, Method>? {
val method = VoteHelper::class.java.declaredMethods.firstOrNull {
it.parameterCount == 2 && it.parameterTypes[0] == CardProfile::class.java && it.parameterTypes[1] == ImageView::class.java
} ?: return null
return VoteHelper::class.java to method
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.tencent.mobileqq.activity;

public class VisitorsActivity {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.tencent.mobileqq.data;

public class CardProfile {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.tencent.mobileqq.profile.vote;

public class VoteHelper {



}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.tencent.mobileqq.profilecard.base.component;

public class AbsProfileHeaderComponent {
}

0 comments on commit 8f1a46c

Please sign in to comment.