首页
社区
课程
招聘
关于没有源码的情况下界面注入
发表于: 2013-3-20 20:41 5794

关于没有源码的情况下界面注入

2013-3-20 20:41
5794
以前都是用axmlparse.jar就可以将androidmanifest.xml文件 变成我们所谓的明文,然后在用apktool.jar再变为Android支持的axml格式,但是我有时候仅仅需要的就是这么个文件,不想牵扯出apk文件。查资料知道获取了axmlparse的源码:
/* AXML Parser
* https://github.com/claudxiao/AndTools
* Claud Xiao <iClaudXiao@gmail.com>

当然apltool的源码里面也有,但那是java版的.这个确实可以在Windows和Linux下面编译的代码,交接任务的时候,上个同事就用的这个,没注意,还以为是他自己写的,汗。现在我想做的就是直接的效果就是xml2axml。这个算法都给出来,再按相反的逻辑列个算法应该就可以做到了。
(问题二)—— 注入自己的smali代码时,ListView不能使用的,因为里面的适配器是需要R.java文件来管理的
还有就是很显然现在大家都在对apk植入了代码,对于,植入代码的好处以及带来的那些影响先不论及,大家也勿批,很多人都在做了,对于今天我在smali中植入的ListView的失败经历 让我很伤心,但是,那就是ListView不得不依赖与R.java 而这个文件又是ADT插件自动生成的,AAPT也可以生成,但是附带那么多的选项,我表示,我只想要跳过R.java的影响而已.于是总结,插入的activity中,放一个imageview是可以简单的做到的,插入的图片可以放到assets文件夹内,但是对于要使用代码设计的界面又要和R.java所管理的文件做交互的话,貌似不可以。
(问题二 解决方法)——使用scrollView和TableView来替换,ListView的列表滑动效果。
package com.ooxx.iapp;

import java.io.IOException;
import java.io.InputStream;


import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.Toast;

public class IappActivity extends Activity {

	public DisplayMetrics metric = new DisplayMetrics();
	// 进入游戏框的宽度
	public int AdsWidth = 600;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		setTitle("测试程序");

		// 获取屏幕
		getWindowManager().getDefaultDisplay().getMetrics(metric);
		int width = metric.widthPixels; // 屏幕宽度(像素)
		int height = metric.heightPixels; // 屏幕高度(像素)
		getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
				WindowManager.LayoutParams.FLAG_FULLSCREEN);
		// 注入界面
		InjectActivity(width, height);
	}

	public void InjectActivity(int width, int height) {
		// 布局的设置
		InitLayout(width, height);
	}

	public void InitLayout(int width, int height) {
		// 主层次的设置
		LinearLayout LL = new LinearLayout(this);
		LinearLayout.LayoutParams localLayoutlmain = new LinearLayout.LayoutParams(
				width, height);
		LL.setLayoutParams(localLayoutlmain);
		LL.setBackgroundColor(0x3ef);

		// 声明了两大LinearLayout板块
		LinearLayout LinearLayoutGame = new LinearLayout(this);
		LinearLayout LinearLayoutTAds = new TableLayout(this);

		// 初始化LinearLayout
		InitlGame(LinearLayoutGame, width, height);
		InitlAds(LinearLayoutTAds, width, height);

		// 添加两大版块到主层次上
		LL.addView(LinearLayoutTAds);
		LL.addView(LinearLayoutGame);

		// 最后再添加主层次
		setContentView(LL);
	}

	// 右边进入游戏框架
	public void InitlGame(LinearLayout lGame, int width, int height) {
		lGame.setOrientation(LinearLayout.VERTICAL); // 垂直
		// 设置规格
		LinearLayout.LayoutParams layourparams_Game = new LinearLayout.LayoutParams(
				width - AdsWidth, height);
		lGame.setLayoutParams(layourparams_Game);

		// ----------------------------------------------------------------
		// 添加进入游戏的图片
		ImageView imageStartGame = new ImageView(this);
		InputStream is = null;
		try {
			is = getResources().getAssets().open("image/startgame.jpg");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		Bitmap bitmap = BitmapFactory.decodeStream(is);
		imageStartGame.setImageBitmap(bitmap);

		// 图片规格
		LinearLayout.LayoutParams localLayoutParams1 = new LinearLayout.LayoutParams(
				bitmap.getWidth(), bitmap.getHeight());
		imageStartGame.setLayoutParams(localLayoutParams1);

		// 图片插入LinearLayout中
		lGame.addView(imageStartGame);

		// 图片的点击,跳转到游戏画面
		imageStartGame.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				Intent it = new Intent(IappActivity.this,IappActivity.class);
				startActivity(it);
			}
		});		
	}

	// 展示页在左边
	public void InitlAds(LinearLayout lAds, int width, int height) {
		lAds.setOrientation(LinearLayout.HORIZONTAL); // 垂直

		// 设置规格
		LinearLayout.LayoutParams layourparams_Ads = new LinearLayout.LayoutParams(
				AdsWidth, height);
		lAds.setLayoutParams(layourparams_Ads);

		ScrollView scrollView = new ScrollView(this);
		TableLayout tableLayout = new TableLayout(this);
		
		for (int row = 1; row <= 22; row++) {
			TableRow tableRow = new TableRow(this);
			ImageView imageAds = new ImageView(this);
			InputStream is = null;
			try {
				is = getResources().getAssets().open(
						"image/Ads_0" + row + ".jpg");
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			Bitmap bitmap = BitmapFactory.decodeStream(is);
			imageAds.setImageBitmap(bitmap);
			tableRow.addView(imageAds);
			tableLayout.addView(tableRow);
		}
		scrollView.addView(tableLayout); //scrollView中只能有一个组件
		lAds.addView(scrollView);
	}
}

注入需要我们代码来写界面,对于这个不熟的,所有的调试建议在真机上运行,因为这样比较快。java代码写好后用反编译工具,弄成smali代码。然后注入界面其实只用四步
1、将我们需要的资源文件放入目标环境
   这里说环境是因为 你有很多选择,直接读取文件系统,或者是放在assets文件中,使getassets().open("assets里面文件夹的目录/文件名.xxx"的形式访问);
2、将我们的这个com目录下面的ooxx/iapp/IappActivity.smali,以及IappActivity$1.smali,这些$符号开始的,是它的一些子类或者是一些子类的方法,都拷进去.
3、将Androidmanifest.xml文件中改为如下所示,为的是在一开始点击图标的时候就执行我们的这个Activity。
<?xml version="1.0" encoding="utf-8"?>
<manifest android:versionCode="1" android:versionName="1.0" package="com.example.test"
  xmlns:android="http://schemas.android.com/apk/res/android">
    <application android:theme="@style/AppTheme" android:label="@string/app_name" android:icon="@drawable/ic_launcher" android:debuggable="true" android:allowBackup="true">
        <activity android:label="@string/app_name" android:name="com.example.test.MainActivity">
        </activity>
		<activity android:label="测试程序" android:name="com.ooxx.iapp.IappActivity" android:screenOrientation="landscape">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

4、最后需要的工作是我们展示完这个界面后,需要点击某处,然后继续回到原程序的界面上
使用:
// 图片的点击,跳转到游戏画面
		imageStartGame.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				Intent it = new Intent(IappActivity.this,IappActivity.class);
				startActivity(it);
			}
		});		

---------------------------------------------------------------------------------------------------
总的说来,界面注入很没技术含量,不如Android平台下的进程注入那么神秘,但是界面注入也是有一些可以利用的地方,比方说,在我们的Activity的oncreate逻辑里面添加一下,检测手机Model的代码,检测google play服务和亚马逊服务是否存在,以及google账户是否登录等等,用来辅助 游戏正常运行。但是很多apk还是有自己的方法不让别人来进行这样的操作的,比方说异常,检查签名,以及这里的这个例子,原apk只要检测主Activity是否被替换,就可以了。方法很多,留给帖子供大家交流

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//