Android学习的第一个java层的shell,理解了不少东西,主要理解了Ref反射机制。学习路径来自F8LEFT视频。
要求
1、手机版本5.0以上
代码
MyApplication
import android.app.Application;
import android.content.Context;
import android.util.Log;
public class MyApplication extends Application {
public void onCreate(){
super.onCreate();
}
protected void attachBaseContext(Context base)
{
super.attachBaseContext(base);
}
}
MainActivity
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tvinfo = (TextView) findViewById(R.id.tvinfo);
TextView tvwd = (TextView) findViewById(R.id.tvwd);
tvwd.setText("Shell has been loaded");
if(getApplication() instanceof MyApplication)
{
tvinfo.setText("MyApplication has been loaded");
}
}
}
<TextView
android:id="@+id/tvinfo"
android:layout_width="wrap_content"
android:layout_height="33dp"
android:text="0"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tvwd"
android:layout_width="wrap_content"
android:layout_height="38dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:text="Application not load,Nooo"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.554"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tvinfo"
app:layout_constraintVertical_bias="1.0" />
AndroidManifest.xml文件中做一下声明,<application xxxx>中添加:
android:name=".MyApplication"
生成apk,提取dex
java -jar ShakaApktool.jar bs classes.dex -o classes
保留两个smali:-->MainActivity.smali MyApplication.smali
编译成dex
java -jar ShakaApktool.jar s classes -o encrypt.dex
shell
1、创建一个asset目录,将encrypt.dex复制进去。
2、删除MainActivity.java MyApplication.java
3、模拟系统加载的流程
write
首先、接管程序的Application中的两个函数[这是控制的最开始两个函数]。
1 ---> attachBaseContext(context)
2 ---> onCreate()
ProxyApplication
创建ProxyApplication继承父类android.app.Application,选择重构attachBaseContext()与onCreate()。
ProxyApplication.java
package esebitcoin.yshell;
import android.app.Application;
import android.app.Instrumentation;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.util.ArrayMap;
import java.io.File;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import dalvik.system.DexClassLoader;
public class ProxyApplication extends Application {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
File cache = getDir("eshell",MODE_PRIVATE);
String sDex = cache +"/encrypt.dex";
File dexFile = FileManager.releaseAssetsFile(this,"encrypt.dex",sDex,null);
ClassLoader cl = new DexClassLoader(sDex,getDir("eshell_aot",MODE_PRIVATE).getAbsolutePath(), getApplicationInfo().nativeLibraryDir,getClassLoader());
Object currentActivityThread = RefInvoke.invokeStaticMethod("android.app.ActivityThread", "currentActivityThread",new Class[]{},new Object[]{});
ArrayMap mPackages = (ArrayMap) RefInvoke.getFieldOjbect("android.app.ActivityThread", "mPackages",currentActivityThread);
WeakReference wr = (WeakReference) mPackages.get(getPackageName());
RefInvoke.setFieldOjbect("android.app.LoadedApk","mClassLoader",wr.get(),cl);
return;
}
@Override
public void onCreate() {
super.onCreate();
Object currentActivityThread = RefInvoke.invokeStaticMethod("android.app.ActivityThread", "currentActivityThread",new Class[]{},new Object[]{});
Object mBoundApplication = RefInvoke.getFieldOjbect("android.app.ActivityThread", "mBoundApplication",currentActivityThread);
Object loadedApkInfo = RefInvoke.getFieldOjbect("android.app.ActivityThread$AppBindData", "info",mBoundApplication);
RefInvoke.setFieldOjbect("android.app.LoadedApk","mApplication",loadedApkInfo,null);
String srcAppName = "esebitcoin.yshell.MyApplication";
ApplicationInfo appInfo_LoadedApke = (ApplicationInfo) RefInvoke.getFieldOjbect("android.app.LoadedApk", "mApplicationInfo",loadedApkInfo);
appInfo_LoadedApke.className = srcAppName;
ApplicationInfo appinfo_In_AppBindData = (ApplicationInfo) RefInvoke.getFieldOjbect("android.app.ActivityThread$AppBindData", "appInfo",mBoundApplication);
appinfo_In_AppBindData.className = srcAppName;
Application oldApplication = (Application) RefInvoke.getFieldOjbect("android.app.ActivityThread", "mInitialApplication",currentActivityThread);
ArrayList<Application> mAllApplications = (ArrayList<Application>) RefInvoke.getFieldOjbect("android.app.ActivityThread", "mAllApplications",currentActivityThread);
mAllApplications.remove(oldApplication);
Application realApp = (Application) RefInvoke.invokeMethod("android.app.LoadedApk", "makeApplication",new Class[]{boolean.class,Instrumentation.class}, loadedApkInfo,new Object[]{false,null});
realApp.onCreate();
RefInvoke.setFieldOjbect("android.app.ActivityThread","mInitialApplication", currentActivityThread,realApp);
return;
}
}
FileManager.java
package esebitcoin.yshell;
import android.content.Context;
import android.content.res.AssetManager;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.lang.reflect.Method;
public class FileManager {
public static File releaseAssetsFile(Context ctx, String assetFile, String releaseFile, Method decMethod)
{
AssetManager manager = ctx.getAssets();
try{
InputStream is = manager.open(assetFile);
ByteArrayOutputStream os = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
int iRead;
while ((iRead = is.read(buf)) != -1) {
os.write(buf, 0, iRead);
}
byte[] dec = decMethod != null ? (byte[]) decMethod.invoke (null, os. toByteArray()) : os.toByteArray();
is.close();
os.close();
FileOutputStream of = new FileOutputStream(new File(releaseFile));
of.write(dec);
of.close();
return new File(releaseFile);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
修改xml
AndroidManifest.xml
---> android:name=".ProxyApplication"
Android程序例子下载
网友评论