mirror of
https://github.com/whitechi73/OpenShamrock.git
synced 2024-08-14 05:12:17 +00:00
Compare commits
3 Commits
ba7058a838
...
b9cfe73eae
Author | SHA1 | Date | |
---|---|---|---|
b9cfe73eae | |||
8d6d984849 | |||
25fe9fab37 |
@ -16,10 +16,11 @@
|
||||
|
||||
## 简介
|
||||
|
||||
☘ 基于 Xposed 实现 OneBot 标准的 QQ 机器人框架,原作者[**fuqiuluo**](https://github.com/fuqiuluo)已脱离开发,接下来由白池接手哦!本项目为OpenShamrock,不会有任何收费行为,欢迎大家的加入!
|
||||
☘ 基于 Lsposed(**Non**-Riru) 实现 OneBot 标准的 QQ 机器人框架,原作者[**fuqiuluo**](https://github.com/fuqiuluo)已脱离开发,接下来由白池接手哦!本项目为OpenShamrock,不会有任何收费行为,欢迎大家的加入!
|
||||
|
||||
> 本项目仅提供学习与交流用途,请在24小时内删除。
|
||||
> 本项目目的是研究 Xposed 和 LSPosed 框架的使用。 Epic 框架开发相关知识。
|
||||
> Riru可能导致封禁,请减少使用。
|
||||
> 如有违反法律,请联系删除。
|
||||
> 请勿在任何平台宣传,宣扬,转发本项目,请勿恶意修改企业安装包造成相关企业产生损失,如有违背,必将追责到底。
|
||||
> 官方论坛,[点我直达](https://forum.libfekit.so/)!
|
||||
|
@ -15,6 +15,8 @@ static std::vector<std::string> qemu_detect_props = {
|
||||
|
||||
static int (*backup_system_property_get)(const char *name, char *value);
|
||||
static FILE* (*backup_fopen)(const char *filename, const char *mode);
|
||||
static int (*backup_memcmp)(const void* __lhs, const void* __rhs, size_t __n);
|
||||
//static const char* (*backup_strstr)(const char* h, const char* n);
|
||||
|
||||
//int fake_system_property_get(const char *name, char *value);
|
||||
//FILE* fake_fopen(const char *filename, const char *mode);
|
||||
|
@ -85,8 +85,6 @@ int fake_system_property_get(const char *name, char *value) {
|
||||
return backup_system_property_get(name, value);
|
||||
}
|
||||
|
||||
|
||||
|
||||
FILE* fake_fopen(const char *filename, const char *mode) {
|
||||
if (strstr(filename, "qemu_pipe")) {
|
||||
LOGI("[Shamrock] bypass qemu detection");
|
||||
@ -117,6 +115,54 @@ FILE* fake_fopen(const char *filename, const char *mode) {
|
||||
return backup_fopen(filename, mode);
|
||||
}
|
||||
|
||||
char * __cdecl my_strstr(const char *lhs, const char *rhs) {
|
||||
char *cur = (char *)lhs;
|
||||
char *l;
|
||||
char *r;
|
||||
if (!*rhs) {
|
||||
return ((char *)lhs);
|
||||
}
|
||||
while (*cur) {
|
||||
l = cur;
|
||||
r = (char *)rhs;
|
||||
while (*r && !(*l - *r)) {
|
||||
l++;
|
||||
r++;
|
||||
}
|
||||
if (!*r) {
|
||||
return cur;
|
||||
}
|
||||
cur++;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int fake_memcmp(const void* __lhs, const void* __rhs, size_t __n) {
|
||||
//if (my_strstr((const char*) __rhs, "lsposed")) {
|
||||
//return -1;
|
||||
//}
|
||||
//if (my_strstr((const char*) __rhs, "xposed")) {
|
||||
// return -1;
|
||||
//}
|
||||
if (my_strstr((const char*) __rhs, "shamrock")) {
|
||||
if (backup_memcmp(__lhs, __rhs, __n) == 0) {
|
||||
// 底层广播判断
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
if (my_strstr((const char*) __rhs, "riru")) {
|
||||
return -1;
|
||||
}
|
||||
//if (my_strstr((const char*) __rhs, "zygisk")) {
|
||||
// return -1;
|
||||
//}
|
||||
//if (my_strstr((const char*) __rhs, "magisk")) {
|
||||
// return -1;
|
||||
//}
|
||||
return backup_memcmp(__lhs, __rhs, __n);
|
||||
}
|
||||
|
||||
void on_library_loaded(const char *name, void *handle) {
|
||||
|
||||
}
|
||||
@ -136,5 +182,8 @@ Java_moe_fuqiuluo_shamrock_xposed_actions_AntiDetection_antiNativeDetections(JNI
|
||||
if (hook_function == nullptr) return false;
|
||||
hook_function((void*) __system_property_get, (void *)fake_system_property_get, (void **) &backup_system_property_get);
|
||||
hook_function((void*) fopen, (void*) fake_fopen, (void**) &backup_fopen);
|
||||
//hook_function((void*) strstr, (void*) fake_strstr, (void**) &backup_strstr);
|
||||
hook_function((void*) memcmp, (void*) fake_memcmp, (void**) &backup_memcmp);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -18,6 +18,11 @@ internal class WebSocketClientService(
|
||||
) : WebSocketClientServlet(address, heartbeatInterval, wsHeaders) {
|
||||
private val eventJobList = mutableSetOf<Job>()
|
||||
|
||||
init {
|
||||
startHeartbeatTimer()
|
||||
initTransmitter()
|
||||
}
|
||||
|
||||
override fun submitFlowJob(job: Job) {
|
||||
eventJobList.add(job)
|
||||
}
|
||||
|
@ -264,8 +264,10 @@ internal object GlobalEventTransmitter: BaseSvc() {
|
||||
suspend fun transGroupMemberNumChanged(
|
||||
time: Long,
|
||||
target: Long,
|
||||
targetUid: String,
|
||||
groupCode: Long,
|
||||
operation: Long,
|
||||
operator: Long,
|
||||
operatorUid: String,
|
||||
noticeType: NoticeType,
|
||||
noticeSubType: NoticeSubType
|
||||
): Boolean {
|
||||
@ -275,11 +277,14 @@ internal object GlobalEventTransmitter: BaseSvc() {
|
||||
postType = PostType.Notice,
|
||||
type = noticeType,
|
||||
subType = noticeSubType,
|
||||
operatorId = operation,
|
||||
operatorId = operator,
|
||||
userId = target,
|
||||
senderId = operation,
|
||||
senderId = operator,
|
||||
target = target,
|
||||
groupId = groupCode
|
||||
groupId = groupCode,
|
||||
targetUid = targetUid,
|
||||
operatorUid = operatorUid,
|
||||
userUid = targetUid
|
||||
))
|
||||
return true
|
||||
}
|
||||
@ -287,6 +292,7 @@ internal object GlobalEventTransmitter: BaseSvc() {
|
||||
suspend fun transGroupAdminChanged(
|
||||
msgTime: Long,
|
||||
target: Long,
|
||||
targetUid: String,
|
||||
groupCode: Long,
|
||||
setAdmin: Boolean
|
||||
): Boolean {
|
||||
@ -298,6 +304,7 @@ internal object GlobalEventTransmitter: BaseSvc() {
|
||||
subType = if (setAdmin) NoticeSubType.Set else NoticeSubType.UnSet,
|
||||
operatorId = 0,
|
||||
target = target,
|
||||
targetUid = targetUid,
|
||||
groupId = groupCode
|
||||
))
|
||||
return true
|
||||
@ -306,8 +313,10 @@ internal object GlobalEventTransmitter: BaseSvc() {
|
||||
suspend fun transGroupBan(
|
||||
msgTime: Long,
|
||||
subType: NoticeSubType,
|
||||
operation: Long,
|
||||
operator: Long,
|
||||
operatorUid: String,
|
||||
target: Long,
|
||||
targetUid: String,
|
||||
groupCode: Long,
|
||||
duration: Int
|
||||
): Boolean {
|
||||
@ -317,12 +326,14 @@ internal object GlobalEventTransmitter: BaseSvc() {
|
||||
postType = PostType.Notice,
|
||||
type = NoticeType.GroupBan,
|
||||
subType = subType,
|
||||
operatorId = operation,
|
||||
operatorId = operator,
|
||||
userId = target,
|
||||
senderId = operation,
|
||||
senderId = operator,
|
||||
target = target,
|
||||
groupId = groupCode,
|
||||
duration = duration
|
||||
duration = duration,
|
||||
operatorUid = operatorUid,
|
||||
targetUid = targetUid
|
||||
))
|
||||
return true
|
||||
}
|
||||
|
@ -35,24 +35,22 @@ import java.net.URI
|
||||
import kotlin.concurrent.timer
|
||||
|
||||
internal abstract class WebSocketClientServlet(
|
||||
url: String,
|
||||
private val url: String,
|
||||
private val heartbeatInterval: Long,
|
||||
private val wsHeaders: Map<String, String>
|
||||
) : BaseTransmitServlet, WebSocketClient(URI(url), wsHeaders) {
|
||||
init {
|
||||
if (connectedClients.containsKey(url)) {
|
||||
throw RuntimeException("WebSocketClient已存在: $url")
|
||||
}
|
||||
}
|
||||
|
||||
private val sendLock = Mutex()
|
||||
|
||||
override fun allowTransmit(): Boolean {
|
||||
return ShamrockConfig.openWebSocketClient()
|
||||
}
|
||||
|
||||
override fun onOpen(handshakedata: ServerHandshake?) {
|
||||
LogCenter.log("WebSocketClient onOpen: ${handshakedata?.httpStatus}, ${handshakedata?.httpStatusMessage}")
|
||||
|
||||
startHeartbeatTimer()
|
||||
pushMetaLifecycle()
|
||||
initTransmitter()
|
||||
}
|
||||
|
||||
override fun onMessage(message: String) {
|
||||
GlobalScope.launch {
|
||||
handleMessage(message)
|
||||
@ -84,6 +82,16 @@ internal abstract class WebSocketClientServlet(
|
||||
respond?.let { send(it) }
|
||||
}
|
||||
|
||||
override fun onOpen(handshakedata: ServerHandshake?) {
|
||||
LogCenter.log("WebSocketClient onOpen: ${handshakedata?.httpStatus}, ${handshakedata?.httpStatusMessage}")
|
||||
|
||||
connectedClients[url] = this
|
||||
|
||||
//startHeartbeatTimer()
|
||||
pushMetaLifecycle()
|
||||
//initTransmitter()
|
||||
}
|
||||
|
||||
override fun onClose(code: Int, reason: String?, remote: Boolean) {
|
||||
if (code == 403) {
|
||||
if (wsHeaders.containsKey("authorization")) {
|
||||
@ -95,11 +103,13 @@ internal abstract class WebSocketClientServlet(
|
||||
}
|
||||
LogCenter.log("WebSocketClient onClose: $code, $reason, $remote")
|
||||
cancelFlowJobs()
|
||||
connectedClients.remove(url)
|
||||
}
|
||||
|
||||
override fun onError(ex: Exception?) {
|
||||
LogCenter.log("WebSocketClient onError: ${ex?.message}")
|
||||
cancelFlowJobs()
|
||||
connectedClients.remove(url)
|
||||
}
|
||||
|
||||
protected suspend inline fun <reified T> pushTo(body: T) {
|
||||
@ -113,14 +123,14 @@ internal abstract class WebSocketClientServlet(
|
||||
}
|
||||
}
|
||||
|
||||
private fun startHeartbeatTimer() {
|
||||
fun startHeartbeatTimer() {
|
||||
if (heartbeatInterval <= 0) {
|
||||
LogCenter.log("被动WebSocket心跳间隔为0,不启动心跳", Level.WARN)
|
||||
return
|
||||
}
|
||||
timer(
|
||||
name = "heartbeat",
|
||||
initialDelay = 0,
|
||||
initialDelay = heartbeatInterval,
|
||||
period = heartbeatInterval,
|
||||
) {
|
||||
if (isClosed || isClosing || !isOpen) {
|
||||
@ -143,7 +153,7 @@ internal abstract class WebSocketClientServlet(
|
||||
status = "正常",
|
||||
good = true
|
||||
),
|
||||
interval = 1000L * 15
|
||||
interval = heartbeatInterval
|
||||
)
|
||||
)
|
||||
)
|
||||
@ -169,4 +179,8 @@ internal abstract class WebSocketClientServlet(
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val connectedClients = mutableMapOf<String, WebSocketClientServlet>()
|
||||
}
|
||||
}
|
@ -67,14 +67,20 @@ internal data class NoticeEvent(
|
||||
@SerialName("post_type") val postType: PostType,
|
||||
@SerialName("notice_type") val type: NoticeType,
|
||||
@SerialName("sub_type") val subType: NoticeSubType = NoticeSubType.None,
|
||||
@SerialName("group_id") val groupId: Long = -1,
|
||||
@SerialName("operator_id") val operatorId: Long = -1,
|
||||
@SerialName("user_id") val userId: Long = -1,
|
||||
@SerialName("sender_id") val senderId: Long = -1,
|
||||
@SerialName("duration") val duration: Int = -1,
|
||||
@SerialName("message_id") val msgId: Int = -1,
|
||||
@SerialName("group_id") val groupId: Long = Long.MIN_VALUE,
|
||||
@SerialName("operator_id") val operatorId: Long = Long.MIN_VALUE,
|
||||
@SerialName("operator_uid") val operatorUid: String = "",
|
||||
@SerialName("user_id") val userId: Long = Long.MIN_VALUE,
|
||||
@SerialName("user_uid") val userUid: String = "",
|
||||
@SerialName("sender_id") val senderId: Long = Long.MIN_VALUE,
|
||||
@SerialName("duration") val duration: Int = Int.MIN_VALUE,
|
||||
@SerialName("message_id") val msgId: Int = Int.MIN_VALUE,
|
||||
@SerialName("tip_text") val tip: String = "",
|
||||
@SerialName("target_id") val target: Long = -1,
|
||||
|
||||
@SerialName("target_id") val target: Long = Long.MIN_VALUE,
|
||||
@SerialName("target_uid") val targetUid: String = "",
|
||||
|
||||
|
||||
@SerialName("file") val file: GroupFileMsg? = null,
|
||||
@SerialName("private_file") val privateFile: PrivateFileMsg? = null,
|
||||
@SerialName("flag") val flag: String? = null,
|
||||
@ -92,7 +98,7 @@ internal data class NoticeEvent(
|
||||
// 群打卡
|
||||
@SerialName("sign_detail") val signDetail: SignDetail? = null,
|
||||
|
||||
)
|
||||
)
|
||||
|
||||
/**
|
||||
* 不要使用继承的方式实现通用字段,那样会很难维护!
|
||||
|
@ -14,6 +14,7 @@ import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.json.JsonElement
|
||||
import moe.fuqiuluo.proto.*
|
||||
import moe.fuqiuluo.qqinterface.servlet.FriendSvc.requestFriendSystemMsgNew
|
||||
import moe.fuqiuluo.qqinterface.servlet.GroupSvc
|
||||
import moe.fuqiuluo.qqinterface.servlet.GroupSvc.requestGroupSystemMsgNew
|
||||
import moe.fuqiuluo.qqinterface.servlet.TicketSvc.getLongUin
|
||||
import moe.fuqiuluo.shamrock.helper.MessageHelper
|
||||
@ -302,11 +303,10 @@ internal object PrimitiveListener {
|
||||
LogCenter.log("onGroupPokeAndGroupSign error: ${e.stackTraceToString()}", Level.WARN)
|
||||
}
|
||||
}
|
||||
var groupId:Long
|
||||
try {
|
||||
groupId = detail[4].asULong
|
||||
val groupId = try {
|
||||
detail[4].asULong
|
||||
}catch (e: ClassCastException){
|
||||
groupId = detail[4].asList.value[0].asULong
|
||||
detail[4].asList.value[0].asULong
|
||||
}
|
||||
|
||||
detail = if (detail[26] is ProtoList) {
|
||||
@ -392,13 +392,21 @@ internal object PrimitiveListener {
|
||||
val groupCode = pb[1, 3, 2, 1].asULong
|
||||
val targetUid = pb[1, 3, 2, 3].asUtf8String
|
||||
val type = pb[1, 3, 2, 4].asInt
|
||||
val operation = ContactHelper.getUinByUidAsync(pb[1, 3, 2, 5].asUtf8String).toLong()
|
||||
|
||||
GroupSvc.getGroupMemberList(groupCode.toString(), true).onFailure {
|
||||
LogCenter.log("新成员加入刷新群成员列表失败: $groupCode", Level.WARN)
|
||||
}.onSuccess {
|
||||
LogCenter.log("新成员加入刷新群成员列表成功,群成员数量: ${it.size}", Level.INFO)
|
||||
}
|
||||
|
||||
val operatorUid = pb[1, 3, 2, 5].asUtf8String
|
||||
val operator = ContactHelper.getUinByUidAsync(operatorUid).toLong()
|
||||
val target = ContactHelper.getUinByUidAsync(targetUid).toLong()
|
||||
LogCenter.log("群成员增加($groupCode): $target, type = $type")
|
||||
|
||||
if (!GlobalEventTransmitter.GroupNoticeTransmitter
|
||||
.transGroupMemberNumChanged(
|
||||
time, target, groupCode, operation, NoticeType.GroupMemIncrease, when (type) {
|
||||
time, target, targetUid, groupCode, operator, operatorUid, NoticeType.GroupMemIncrease, when (type) {
|
||||
130 -> NoticeSubType.Approve
|
||||
131 -> NoticeSubType.Invite
|
||||
else -> NoticeSubType.Approve
|
||||
@ -413,11 +421,19 @@ internal object PrimitiveListener {
|
||||
val groupCode = pb[1, 3, 2, 1].asULong
|
||||
val targetUid = pb[1, 3, 2, 3].asUtf8String
|
||||
val type = pb[1, 3, 2, 4].asInt
|
||||
val operation = try {
|
||||
ContactHelper.getUinByUidAsync(pb[1, 3, 2, 5, 1, 1].asUtf8String).toLong()
|
||||
val operatorUid = try {
|
||||
pb[1, 3, 2, 5, 1, 1].asUtf8String
|
||||
} catch (e: Throwable) {
|
||||
ContactHelper.getUinByUidAsync(pb[1, 3, 2, 5].asUtf8String).toLong()
|
||||
pb[1, 3, 2, 5].asUtf8String
|
||||
}
|
||||
|
||||
GroupSvc.getGroupMemberList(groupCode.toString(), true).onFailure {
|
||||
LogCenter.log("新成员加入刷新群成员列表失败: $groupCode", Level.WARN)
|
||||
}.onSuccess {
|
||||
LogCenter.log("新成员加入刷新群成员列表成功,群成员数量: ${it.size}", Level.INFO)
|
||||
}
|
||||
|
||||
val operator = ContactHelper.getUinByUidAsync(operatorUid).toLong()
|
||||
val target = ContactHelper.getUinByUidAsync(targetUid).toLong()
|
||||
val subtype = when (type) {
|
||||
130 -> NoticeSubType.Leave
|
||||
@ -431,7 +447,7 @@ internal object PrimitiveListener {
|
||||
LogCenter.log("群成员减少($groupCode): $target, type = $subtype ($type)")
|
||||
|
||||
if (!GlobalEventTransmitter.GroupNoticeTransmitter
|
||||
.transGroupMemberNumChanged(time, target, groupCode, operation, NoticeType.GroupMemDecrease, subtype)
|
||||
.transGroupMemberNumChanged(time, target, targetUid, groupCode, operator, operatorUid, NoticeType.GroupMemDecrease, subtype)
|
||||
) {
|
||||
LogCenter.log("群成员减少推送失败!", Level.WARN)
|
||||
}
|
||||
@ -452,7 +468,7 @@ internal object PrimitiveListener {
|
||||
LogCenter.log("群管理员变动($groupCode): $target, isSetAdmin = $isSetAdmin")
|
||||
|
||||
if (!GlobalEventTransmitter.GroupNoticeTransmitter
|
||||
.transGroupAdminChanged(msgTime, target, groupCode, isSetAdmin)
|
||||
.transGroupAdminChanged(msgTime, target, targetUid, groupCode, isSetAdmin)
|
||||
) {
|
||||
LogCenter.log("群管理员变动推送失败!", Level.WARN)
|
||||
}
|
||||
@ -465,18 +481,18 @@ internal object PrimitiveListener {
|
||||
val targetUid = if (wholeBan) "" else pb[1, 3, 2, 5, 3, 1].asUtf8String
|
||||
val rawDuration = pb[1, 3, 2, 5, 3, 2].asInt
|
||||
|
||||
val operation = ContactHelper.getUinByUidAsync(operatorUid).toLong()
|
||||
val operator = ContactHelper.getUinByUidAsync(operatorUid).toLong()
|
||||
val duration = if (wholeBan) -1 else rawDuration
|
||||
val target = if (wholeBan) 0 else ContactHelper.getUinByUidAsync(targetUid).toLong()
|
||||
val subType = if (rawDuration == 0) NoticeSubType.LiftBan else NoticeSubType.Ban
|
||||
|
||||
if (wholeBan) {
|
||||
LogCenter.log("群全员禁言($groupCode): $operation -> ${if (subType == NoticeSubType.Ban) "开启" else "关闭"}")
|
||||
LogCenter.log("群全员禁言($groupCode): $operator -> ${if (subType == NoticeSubType.Ban) "开启" else "关闭"}")
|
||||
} else {
|
||||
LogCenter.log("群禁言($groupCode): $operation -> $target, 时长 = ${duration}s")
|
||||
LogCenter.log("群禁言($groupCode): $operator -> $target, 时长 = ${duration}s")
|
||||
}
|
||||
if (!GlobalEventTransmitter.GroupNoticeTransmitter
|
||||
.transGroupBan(msgTime, subType, operation, target, groupCode, duration)
|
||||
.transGroupBan(msgTime, subType, operator, operatorUid, target, targetUid, groupCode, duration)
|
||||
) {
|
||||
LogCenter.log("群禁言推送失败!", Level.WARN)
|
||||
}
|
||||
|
@ -5,12 +5,14 @@ import android.content.Context
|
||||
import android.content.pm.PackageManager
|
||||
import android.content.pm.VersionedPackage
|
||||
import android.os.Build
|
||||
import android.os.Looper
|
||||
import de.robv.android.xposed.XC_MethodReplacement
|
||||
import de.robv.android.xposed.XSharedPreferences
|
||||
import de.robv.android.xposed.XposedHelpers
|
||||
import moe.fuqiuluo.shamrock.helper.Level
|
||||
import moe.fuqiuluo.shamrock.helper.LogCenter
|
||||
import moe.fuqiuluo.shamrock.remote.service.config.ShamrockConfig
|
||||
import moe.fuqiuluo.shamrock.tools.MethodHooker
|
||||
import moe.fuqiuluo.shamrock.tools.hookMethod
|
||||
import moe.fuqiuluo.shamrock.xposed.XposedEntry
|
||||
import moe.fuqiuluo.shamrock.xposed.loader.LuoClassloader
|
||||
@ -181,6 +183,22 @@ class AntiDetection: IAction {
|
||||
return className.isModuleStack()
|
||||
}
|
||||
|
||||
val stackTraceHooker: MethodHooker = {
|
||||
val result = it.result as Array<StackTraceElement>
|
||||
var zygote = false
|
||||
val newResult = result.filter {
|
||||
if (it.className == ZYGOTE_NAME) {
|
||||
zygote = true
|
||||
}
|
||||
!it.isModuleStack()
|
||||
}.toTypedArray()
|
||||
if (!zygote && Thread.currentThread() == Looper.getMainLooper().thread) {
|
||||
it.result = arrayListOf(StackTraceElement(ZYGOTE_NAME, "main", ZYGOTE_NAME, 0), *newResult)
|
||||
} else {
|
||||
it.result = newResult
|
||||
}
|
||||
}
|
||||
|
||||
Thread::class.java.hookMethod("getName").after {
|
||||
val result = it.result as String
|
||||
if (result.contains("fuqiuluo") || result.contains("shamrock") || result.contains("whitechi")) {
|
||||
@ -188,30 +206,15 @@ class AntiDetection: IAction {
|
||||
}
|
||||
}
|
||||
|
||||
Thread::class.java.hookMethod("getStackTrace").after {
|
||||
val result = it.result as Array<StackTraceElement>
|
||||
it.result = result.filter {
|
||||
!it.isModuleStack()
|
||||
}.toTypedArray()
|
||||
}
|
||||
|
||||
Throwable::class.java.hookMethod("getStackTrace").after {
|
||||
val result = it.result as Array<StackTraceElement>
|
||||
it.result = result.filter {
|
||||
!it.isModuleStack()
|
||||
}.toTypedArray()
|
||||
}
|
||||
|
||||
Throwable::class.java.hookMethod("getOurStackTrace").after {
|
||||
val result = it.result as Array<StackTraceElement>
|
||||
it.result = result.filter {
|
||||
!it.isModuleStack()
|
||||
}.toTypedArray()
|
||||
}
|
||||
Thread::class.java.hookMethod("getStackTrace").after(stackTraceHooker)
|
||||
Throwable::class.java.hookMethod("getStackTrace").after(stackTraceHooker)
|
||||
Throwable::class.java.hookMethod("getOurStackTrace").after(stackTraceHooker)
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
var isAntiFindPackage = false
|
||||
|
||||
const val ZYGOTE_NAME = "com.android.internal.os.ZygoteInit"
|
||||
}
|
||||
}
|
@ -115,7 +115,11 @@ internal class InitRemoteService : IAction {
|
||||
LogCenter.log("被动WebSocket地址不合法: $url", Level.ERROR)
|
||||
}
|
||||
} catch (e: Throwable) {
|
||||
LogCenter.log(e.stackTraceToString(), Level.ERROR)
|
||||
if (e is RuntimeException) {
|
||||
LogCenter.log(e.message ?: e.stackTraceToString(), Level.ERROR)
|
||||
} else {
|
||||
LogCenter.log(e.stackTraceToString(), Level.ERROR)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user