Skip to content

Commit

Permalink
new file
Browse files Browse the repository at this point in the history
  • Loading branch information
EasyAuthorize committed Jul 4, 2023
1 parent 529e189 commit 50c7b1f
Show file tree
Hide file tree
Showing 23 changed files with 705 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
1 change: 1 addition & 0 deletions app/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
26 changes: 26 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
apply plugin: 'com.android.application'

android {
compileSdkVersion 29
buildToolsVersion "29.0.3"

defaultConfig {
applicationId "com.easy.tgPlus"
minSdkVersion 19
targetSdkVersion 23
versionCode 1
versionName "1.0"
}

buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}

dependencies {
compile files('libs/XposedBridgeAPI-89.jar')
//implementation fileTree(dir: "libs", include: ["*.jar"])
}
Binary file added app/libs/XposedBridgeAPI-89.jar
Binary file not shown.
21 changes: 21 additions & 0 deletions app/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
34 changes: 34 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?xml version='1.0' encoding='utf-8'?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.easy.tgPlus">

<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme"
android:resizeableActivity="true">

<activity
android:name=".MainActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>

<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>

<meta-data
android:name="android.max_aspect"
android:value="4.0"/>

<meta-data android:name="xposedmodule" android:value="true"/>
<meta-data android:name="xposeddescription" android:value="Telegram++"/>
<meta-data android:name="xposedminversion" android:value="89"/>
<meta-data android:name="xposedscope" android:resource="@array/TgApp"/>

</application>

</manifest>
1 change: 1 addition & 0 deletions app/src/main/assets/xposed_init
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
com.easy.tgPlus.Leader
179 changes: 179 additions & 0 deletions app/src/main/java/com/easy/tgPlus/Leader.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
package com.easy.tgPlus;

import de.robv.android.xposed.IXposedHookInitPackageResources;
import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_InitPackageResources;
import de.robv.android.xposed.callbacks.XC_LoadPackage;
import android.content.res.XModuleResources;
import android.content.res.XResources;
import de.robv.android.xposed.XC_MethodHook;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.text.SimpleDateFormat;
import de.robv.android.xposed.XC_MethodReplacement;
import java.util.List;
import java.util.Arrays;
import android.widget.LinearLayout;
import android.view.View;
import android.content.Context;
import android.widget.Toast;
import android.view.ViewGroup;
import android.text.SpannableStringBuilder;
import java.util.ArrayList;

public class Leader implements IXposedHookLoadPackage,IXposedHookInitPackageResources {

public static final List hookPackages = Arrays.asList("org.telegram.messenger", "org.telegram.messenger.web", "org.telegram.messenger.beta", "nekox.messenger", "com.cool2645.nekolite", "org.telegram.plus", "com.iMe.android", "org.telegram.BifToGram", "ua.itaysonlab.messenger", "org.forkclient.messenger", "org.forkclient.messenger.beta", "org.aka.messenger", "ellipi.messenger", "org.nift4.catox", "it.owlgram.android");

boolean isTargetPackage;

int res_msg_send_Id = 0;

//Context con = AndroidAppHelper.currentApplication();

@Override
public void handleInitPackageResources(XC_InitPackageResources.InitPackageResourcesParam resparam) throws Throwable {

if (!hookPackages.contains(resparam.packageName))return;

String resPackageName = resparam.res.getPackageName();
XposedBridge.log("资源包:" + resPackageName + "已处理");
int delete = resparam.res.getIdentifier("Delete", "string", resPackageName);
String rawStr = resparam.res.getString(delete);
resparam.res.setReplacement(delete, "(删除)");
logStringResHook(delete, rawStr);

int en = resparam.res.getIdentifier("EditName", "string", resPackageName);
rawStr = resparam.res.getString(en);
resparam.res.setReplacement(en, "(编辑名称)");
logStringResHook(en, rawStr);

res_msg_send_Id = resparam.res.getIdentifier("msg_send", "drawable", resPackageName);

if (resparam.packageName.equals("org.telegram.messenger.web")) {
int id = resparam.res.getIdentifier("AppName", "string", resPackageName);
rawStr = resparam.res.getString(id);
resparam.res.setReplacement(en, "Telegram(Web)");
logStringResHook(id, rawStr);

id = resparam.res.getIdentifier("Page1Title", "string", resPackageName);
rawStr = resparam.res.getString(id);
resparam.res.setReplacement(en, "Telegram(Web)");
logStringResHook(id, rawStr);
return;
}

}


@Override
public void handleLoadPackage(final XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {
if (lpparam.packageName.equals("com.easy.tgPlus")) {
Class<?> mainActivity = lpparam.classLoader.loadClass("com.easy.tgPlus.MainActivity");
XposedHelpers.findAndHookMethod(mainActivity, "isActivate", XC_MethodReplacement.returnConstant(true));
return;
}

if (!hookPackages.contains(lpparam.packageName))return;

final boolean isWebPackage = lpparam.packageName.equals("org.telegram.messenger.web");

XposedBridge.log(isWebPackage ?"TG(Web)运行~": "TG运行~" + new SimpleDateFormat("yyyy年MM月dd日 a hh:mm:ss").format(System.currentTimeMillis()) + "\n");
XposedBridge.log("Hook~\n");
XposedHelpers.findAndHookConstructor("org.telegram.messenger.LocaleController", lpparam.classLoader, new XC_MethodHook(){
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
//实例化之后执行
Object mLocaleController = param.thisObject;
HashMap<String,String> mlocaleValues = (HashMap<String,String>)XposedHelpers.getObjectField(mLocaleController, "localeValues");
mlocaleValues.put("Delete", "(删除)");
if (isWebPackage) {
mlocaleValues.put("AppName", "Telegram(Web)");
mlocaleValues.put("Page1Title", "Telegram(Web)");
}
}
});

//解锁复制保存
XposedHelpers.findAndHookMethod("org.telegram.messenger.MessagesController", lpparam.classLoader, "isChatNoForwards", lpparam.classLoader.loadClass("org.telegram.tgnet.TLRPC$Chat"), XC_MethodReplacement.returnConstant(false));

//if(true)return;

//复读机
final Class<?> AndroidUtilities = lpparam.classLoader.loadClass("org.telegram.messenger.AndroidUtilities");
final Class<?> abm = lpparam.classLoader.loadClass("org.telegram.ui.ActionBar.ActionBarMenuSubItem");
XposedHelpers.findAndHookMethod("org.telegram.ui.Components.ChatScrimPopupContainerLayout", lpparam.classLoader, "setPopupWindowLayout", lpparam.classLoader.loadClass("org.telegram.ui.ActionBar.ActionBarPopupWindow$ActionBarPopupWindowLayout"), new XC_MethodHook(){
@Override
protected void beforeHookedMethod(MethodHookParam param) {
Object t = param.thisObject;
XposedBridge.log(t.toString());
final Object main = XposedHelpers.getObjectField(t, "this$0");
final Context con = (Context)XposedHelpers.callMethod(main, "getParentActivity");
Object popupLayout = param.args[0];
Object fd = XposedHelpers.newInstance(abm, new Class[]{Context.class,boolean.class,boolean.class}, new Object[]{con,false,false});
//如果dp函数在回调外面调用,emoji会缩成一坨
int dp200 = XposedHelpers.callStaticMethod(AndroidUtilities, "dp", new Class[]{float.class}, new Object[]{200f});
XposedHelpers.callMethod(fd, "setMinimumWidth", new Class[]{int.class}, new Object[]{dp200});
XposedHelpers.callMethod(fd, "setTextAndIcon", new Class[]{String.class,int.class}, new Object[]{"+1",res_msg_send_Id});
XposedHelpers.callMethod(fd, "setOnClickListener", new Class[]{View.OnClickListener.class}, new Object[]{new View.OnClickListener(){

@Override
public void onClick(View v) {
XposedHelpers.callMethod(main, "closeMenu", new Class[]{boolean.class}, new Object[]{true});
Object selectedObject = XposedHelpers.getObjectField(main,"selectedObject");
Object selectedObjectGroup = XposedHelpers.getObjectField(main,"selectedObjectGroup");
SpannableStringBuilder content = (SpannableStringBuilder)XposedHelpers.callMethod(main,"getMessageContent",new Class[]{selectedObject.getClass(),long.class,boolean.class},new Object[]{selectedObject,0,false});
Object sendMsgHelper = XposedHelpers.callMethod(main,"getSendMessagesHelper");

try {
Class<?> msgObj = lpparam.classLoader.loadClass("org.telegram.messenger.MessageObject");
Class<?> rpcWebPage = lpparam.classLoader.loadClass("org.telegram.tgnet.TLRPC$WebPage");
Class<?> rpcReplyMarkup = lpparam.classLoader.loadClass("org.telegram.tgnet.TLRPC$ReplyMarkup");
Class<?> msgObjSendData = lpparam.classLoader.loadClass("org.telegram.messenger.MessageObject$SendAnimationData");
//这里还需要判断消息类型调用对应的send方法
XposedHelpers.callMethod(sendMsgHelper, "sendMessage", new Class[]{String.class,long.class,msgObj,msgObj,rpcWebPage,boolean.class,ArrayList.class,rpcReplyMarkup,HashMap.class,boolean.class,int.class,msgObjSendData,boolean.class}, new Object[]{content.toString(),XposedHelpers.getObjectField(main,"dialog_id"),null, null, null, false, null, null, null, true, 0, null, false});
Toast.makeText(con, "复读机:"+content.toString() ,Toast.LENGTH_SHORT).show();
} catch (ClassNotFoundException e) {
XposedBridge.log(e);
}

}
}});
XposedHelpers.callMethod(popupLayout, "addView", new Class[]{View.class}, new Object[]{fd});
}
});

//debug
if (isWebPackage) {
//打印getString调用堆栈
XposedHelpers.findAndHookMethod("org.telegram.messenger.LocaleController", lpparam.classLoader, "getString", String.class , int.class, new XC_MethodHook(){
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
if ((int)param.args[1] == res_msg_send_Id) {
// 获取调用堆栈信息
StringBuilder sb = new StringBuilder();
StackTraceElement[] stackElements = Thread.currentThread().getStackTrace();
if (stackElements != null) {
for (int i = 0; i < stackElements.length; i++) {
sb.append("\tat ");
sb.append(stackElements[i].getClassName()).append(".");
sb.append(stackElements[i].getMethodName());
sb.append("(").append(stackElements[i].getFileName()).append(":");
sb.append(stackElements[i].getLineNumber()).append(")\n");
}
}
XposedBridge.log(sb.toString());
}
}
});
}

}

public static void logStringResHook(int id, String rawStr) {
XposedBridge.log("资源id:" + Integer.toHexString(id) + "(\"" + rawStr + "\")hook成功~\n");
}

}
71 changes: 71 additions & 0 deletions app/src/main/java/com/easy/tgPlus/MainActivity.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package com.easy.tgPlus;

import android.app.Activity;
import android.os.Bundle;
import android.widget.LinearLayout;
import android.widget.Button;
import android.view.Gravity;
import android.view.View;
import android.widget.Toast;
import android.widget.TextView;

public class MainActivity extends Activity {

private View.OnClickListener myOnclick = new View.OnClickListener(){

@Override
public void onClick(View v) {
int oid = v.getId();

if (oid == R.id.Btn_start) {

} else if (oid == R.id.Btn_stop) {
Toast.makeText(MainActivity.this, "测试" + getApplicationContext().getPackageResourcePath() + 10 / 0, Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this, "此ID(" + oid + ")事件未注册", Toast.LENGTH_SHORT).show();
}
}

};

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

LinearLayout rootlayout = new LinearLayout(this);

TextView info = new TextView(MainActivity.this);
info.setText(isActivate()?"模块已激活":"模块未激活");
rootlayout.addView(info);

Button btn = new Button(MainActivity.this);
btn.setAllCaps(false);
btn.setText("Start");
btn.setId(R.id.Btn_start);
btn.setOnClickListener(myOnclick);
rootlayout.addView(btn);

btn = new Button(MainActivity.this);
btn.setText("stop");
btn.setId(R.id.Btn_stop);
btn.setOnClickListener(myOnclick);
rootlayout.addView(btn);

Button untest = new Button(MainActivity.this);
untest.setText("未注册的按钮");
untest.setId(3);
untest.setOnClickListener(myOnclick);
rootlayout.addView(untest);

rootlayout.setGravity(Gravity.CENTER);
rootlayout.setOrientation(LinearLayout.VERTICAL);
rootlayout.setBackgroundColor(0xFF545454);

setContentView(rootlayout);
}

private static boolean isActivate(){
return false;
}

}
Binary file added app/src/main/res/drawable/ic_launcher.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions app/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

</LinearLayout>
9 changes: 9 additions & 0 deletions app/src/main/res/values-v21/styles.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="AppTheme" parent="@android:style/Theme.Material.Light.DarkActionBar">
<item name="android:colorPrimary">@color/colorPrimary</item>
<item name="android:colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="android:colorAccent">@color/colorAccent</item>
<item name="android:navigationBarColor">?android:colorPrimary</item>
</style>
</resources>
9 changes: 9 additions & 0 deletions app/src/main/res/values/AuthScope.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="TgApp">
<!-- TG -->
<item>org.telegram.messenger</item>
<!-- TG-WEB -->
<item>org.telegram.messenger.web</item>
</string-array>
</resources>
6 changes: 6 additions & 0 deletions app/src/main/res/values/colors.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#6200EE</color>
<color name="colorPrimaryDark">#3700B3</color>
<color name="colorAccent">#03DAC5</color>
</resources>
5 changes: 5 additions & 0 deletions app/src/main/res/values/ids.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="Btn_start" type="id"></item>
<item name="Btn_stop" type="id"></item>
</resources>
4 changes: 4 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">TG++</string>
</resources>
5 changes: 5 additions & 0 deletions app/src/main/res/values/styles.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="AppTheme" parent="@android:style/Theme.Holo.Light.DarkActionBar">
</style>
</resources>
Loading

0 comments on commit 50c7b1f

Please sign in to comment.