一.BroadcastReceiver简介
BraodcastReceiver(广播接收器)是为了实现系统广播而提供的一种组件,它和事件处理机制类似,但是事件处理机制是程序组件级别的,而广播事件处理机制是系统级别的。比如,我们可以发出一种广播来测试手机电量的变化,这时候就可以定义一个BraodcastReceiver来接受广播,当手机电量较低时提示用户。我们既可以用Intent来启动一个组件,也可以用sendBroadcast()方法发起一个系统级别的事件广播来传递消息。我们同样可以在自己的应用程序中实现BroadcastReceiver来监听和响应广播的Intent。
在程序中使用BraodcastReceiver是比较简单的。首先要定义一个类继承BraodcastReceiver,并且覆盖onReceiver()方法来响应事件。然后注册在程序中BraodcastReceiver。最后构建Intent对象调用sendBroadcast()方法将广播发出。
二.BroadcastReceiver的注册方式
1.静态注册方式
静态注册方式是在AndroidManifest.xml的application里面定义receiver并设置要接收的action。静态注册方式的特点:不管改应用程序是否处于活动状态,都会进行监听,比如某个程序时监听内存 的使用情况的,当在手机上安装好后,不管改应用程序是处于什么状态,都会执行改监听方法中的内容。
下面是具体的例子:
MainActivity.java
在“com.android.broadcast”包中定义一个MyReceiver类,继承于BroadcastReceiver,覆盖onReceive()方法。
MyReceiver.java
main.xml
在AndroidManifest.xml配置文件中16~20行声明receiver
效果图:
当我们点击按钮的时候,程序会调用onReceive()方法,LogCat输出信息如下:
2.动态注册方式
动态注册方式在activity里面调用函数来注册,和静态的内容差不多。一个形参是receiver,另一个是IntentFilter,其中里面是要接收的action。动态注册方式特点:在代码中进行注册后,当应用程序关闭后,就不再进行监听。
下面是具体的例子:
MainActivity.java
在“com.android.broadcast”包中定义一个MyReceiver类,继承于BroadcastReceiver,覆盖onReceive()方法。
MyReceiver.java
main.xml
效果图:
①当我们首先点击按钮的时候,因为程序没有注册BraodcastReceiver,所以LogCat没有输出任何信息。
②当我们先点击再点击按钮的时候,这时程序会动态的注册BraodcastReceiver,之后会调用onReceive()方法,LogCat输出信息如下:
③当我们点击按钮的时候,这时程序会注销BraodcastReceiver,再点击,LogCat没有输出任何信息。
三.BroadcastReceiver 的生命周期
一个BroadcastReceiver 对象只有在被调用onReceive(Context, Intent)的才有效的,当从该函数返回后,该对象就无效的了,结束生命周期。
本文出自 “IT的点点滴滴” 博客,请务必保留此出处http://liangruijun.blog.51cto.com/3061169/655885
package com.jf.getservice;
import java.util.Iterator;
import java.util.List;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningServiceInfo;
import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.os.Bundle;
public class getRunningServicesInfo extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
getRunningServicesInfo(this);
}
//RunningServicesInfo
public static String getRunningServicesInfo(Context context) {
StringBuffer serviceInfo = new StringBuffer();
final ActivityManager activityManager = (ActivityManager) context
.getSystemService(Context.ACTIVITY_SERVICE);
List<RunningServiceInfo> services = activityManager.getRunningServices(100);
Iterator<RunningServiceInfo> l = services.iterator();
while (l.hasNext()) {
RunningServiceInfo si = (RunningServiceInfo) l.next();
serviceInfo.append("pid: ").append(si.pid);
serviceInfo.append("\nprocess: ").append(si.process);
serviceInfo.append("\nservice: ").append(si.service);
serviceInfo.append("\ncrashCount: ").append(si.crashCount);
serviceInfo.append("\nclientCount: ").append(si.clientCount);
serviceInfo.append("\nactiveSince: ").append(si.activeSince);
serviceInfo.append("\nlastActivityTime: ").append(si.lastActivityTime);
serviceInfo.append("\n\n");
}
System.out.println(serviceInfo.toString());
return serviceInfo.toString();
}
}
一.必要知识
对汇编语言有所了解.我其实也没用过arm汇编,.但是因为有80x86的经验.对于arm指令看10分钟也就会了.
对android程序编写有一定了解。掌握程序加载执行流程。
对函数调用流程有所了解.因为papago主体用的是gnu c++写的,所以symbol表比较清楚。很容易对照判别。而且对于arm elf程序函数的参数传递和寻址要有一定了解才能更好的破解。有破解经验更好
二.实用工具。
本来最好是在linux下。符合android环境。但是我破解多半是windows程序……linux大半不用破解……所以这里用的都是windows工具
1.不用说 IDA PRO…大名鼎鼎。我们都用它。
2.Ultraedit。恩。还行吧。任何一个hex editor都可以。
3.Baksmali 反编译dex
4.Gdb和strace备用
5.电脑和人脑
三.破解过程
1.初步分析
由于android出来不久,相应的加密加壳程序基本不存在。所以相对来说比较方便静态反编译。但是同样。动态跟踪程序也太少。Android gdb也不支持调试没有-g编译的代码。所以主要以静态反编译破解分析为主。
加密原理,按照dopod惯例,绑定IMEI.所以从IMEI函数入手。
首先把下载的dopod navigator.apk用winrar等直接解压缩。可以看到class.dex和libpapago.so,libpapago.so高达 2M。而class.dex 不到100k。确定是以JNI为主体的结构。那么加密判断是在java中呢还是c中,还不确定。
拿出baksmali.进行分析。反编译class.dex,得到编译文件。开始分析。
Sorry。我这台电脑没有保存smali文件。就不细说了。看activity和JNI class可以看到。IMEI是由java获取。 (BTW..那个函数居然叫JNIGetIMEI,我还以为是java从JNI得到IMEI。纳闷半天,还以为papago这么厉害能从native c或得IMEI,后来才发现是java从telephony类获取IME保存到C中),找遍了整个class.dex,再也没发现任何IMEI相关的判断。所以。基本判断主体是在libpapago中。