手机卫士-12
课1
手机杀毒模块
杀毒原理:
1、什么是病毒:特殊的程序,存在在硬盘里面。 - 如何定义计算机病毒:
1、侵犯用户的隐私,偷窃你的私隐数据
2、盗号,偷钱。(特洛伊,木马)灰鸽子
3、恶意程序,危害设备
前提:在用户不知情的情况下安装,在特殊的情况下出发。
红蜘蛛,灰鸽子
2、如何杀毒?
把硬盘上的病毒程序,文件删除掉
删除问题:
1、不知道哪个文件是病毒。
2、无法清除。互相守护。A.exe B.exe C.exe
3、杀毒软件的工作
1、找到病毒
2、删除病毒
3、修复系统。
研究一个项目的流程:1、起源、2、Demo、3、成型项目
王江民:反病毒专家 kv20--->江民杀毒软件
江民炸弹:逻辑炸弹(非常恶意的病毒)。报复盗版: mbr:硬盘的引导区 逻辑炸弹就是破坏mbr,导致电脑启动不了。
4、杀毒软件工具的原理
1、识别应用程序的特征码
什么是特征码?
5、新建工程:获取特征码
项目使用到的算法
SHA1
MD5
项目逻辑:
1、获取一个数字摘要器
2、循环的读取文件的每一个byte,获取每个byte的数字签名
获取到了文件的用MD5或SHA1加密的数字摘要
如果我们改变了文件里面的内容,那么文件的数字摘要就改变了。
6、早起的杀毒软件工作的原理就是:
1、手机常见病毒的特征码,把特征码存放在数据库(病毒库)
2、遍历所有的系统文件,计算他们的特征码,跟病毒数据库进行对比
3、根据比对的结果确定文件是否是病毒。卡巴斯基:非常安全,因为病毒库很庞大,但是读取数据库数据量太大,占用cpu资源,卡。
7、杀毒的问题:
1、如何搜集这么多的病毒:蜜罐,互联网云查杀(把用户的电脑变成蜜罐)
2、病毒库太大了,效率怎么办。(杀毒引擎,优化后的数据库查询算法)
缺陷
1、根据数据库查杀,只能查杀已知的病毒,不能查杀未知的病毒。
8、新技术:主动防御
1、根据软件的行为,判断软件是否是病毒
1.看门狗:后台while死循环,监视系统
2.拦截系统API:SystemService.jar,主动提醒用户是否允许行为
把金山的病毒数据库复制过来
我们杀毒的逻辑:遍历系统的文件,查看文件的特征码,并比对病毒数据库的特征码。
看雪论坛:
主动防御技术,安卓注入术
课2
乌云网:查漏洞
社会工程学:设密码的习惯
程序员设密码的讲究
1、钱
2、社交
3、下载一下
实现手机杀毒的功能
金山杀毒界面:
新建AntiVirusActivity.java+清单
<activity
android:name="com.itheima.mobile47.AntiVirusActivity"
android:configChanges="orientation|screenSize|keyboardHidden" >
</activity>
MainActivity+case 5 手机杀毒
布局:activityantivirus.xml
activityantivirus.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
style="@style/textview_title_style"
android:text="病毒查杀" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<FrameLayout
android:layout_width="80dip"
android:layout_height="80dip" >
<ImageView
android:layout_width="80dip"
android:layout_height="80dip"
android:src="@drawable/ic_scanner_malware" />
<ImageView
android:id="@+id/iv_scan"
android:layout_width="80dip"
android:layout_height="80dip"
android:src="@drawable/act_scanning_03" />
</FrameLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="80dip"
android:gravity="center"
android:orientation="vertical" >
<TextView
android:id="@+id/tv_scan_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="扫描状态"
android:textSize="20sp" />
<ProgressBar
android:id="@+id/pb_scan"
android:layout_width="fill_parent"
android:layout_height="15dip"
android:layout_marginLeft="20dip"
android:layout_marginRight="20dip"
android:indeterminateOnly="false"
android:progressDrawable="@drawable/progress_horizontal" />
</LinearLayout>
</LinearLayout>
<ScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<LinearLayout
android:id="@+id/ll_container"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
</LinearLayout>
</ScrollView>
</LinearLayout>
布局:主要是雷达动画和进度条
给scanning的ImageView图片加上旋转的动画 图片沿着自己的中心点旋转:
iv_scan = (ImageView) findViewById(R.id.iv_scan);
RotateAnimation ra = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
ra.setRepeatCount(Animation.INFINITE);
ra.setDuration(2000);
iv_scan.startAnimation(ra);
给病毒数据库新建数据库dao(分析下数据库:)
sql查询语句:
select desc from datable where md5 = "2222" --->空:不存在病毒 有:存在病毒
AntiVirusdao.java
public class AntiVirusDao {
private static final String path ="/data/data/com.itheima.mobile47/files/antivirus.db";
/**
* 查询病毒数据库,
* @param md5 应用程序的特征码
* @return 不为空是病毒描述,null不是病毒
*/
public static String find(String md5){
String desc = null;
SQLiteDatabase db = SQLiteDatabase.openDatabase(path, null, SQLiteDatabase.OPEN_READONLY);
Cursor cursor = db.rawQuery("select desc from datable where md5=?", new String[]{md5});
if(cursor.moveToNext()){
desc = cursor.getString(0);
}
cursor.close();
db.close();
return desc;
}
}
AntiVirusActivity.java-->scanVirus();//杀毒 把MD5Util工具类写好
1、拿到系统里所有应用的包数据集合
2、遍历他们,并配合上一节课的示例代码:获取特征码
3、获取某个路径文件的MD5值(特征码)
4、那该md5值和数据库做对比(空:不是病毒,不空:是病毒)
for循环发现如果是病毒:画面的变化
MD5Util.java
public class MD5Util {
public static String encode(String result) {
try {
StringBuilder sb = new StringBuilder();
// 设置加密摘要
MessageDigest digest = MessageDigest.getInstance("md5");
byte[] digests = digest.digest(result.getBytes());
for (byte b : digests) {
// 获取到低八位
int number = b & 0xff;
String hex = Integer.toHexString(number);
if (hex.length() == 1) {
sb.append("0" + hex);
} else {
sb.append(hex);
}
}
return sb.toString();
} catch (Exception e) {
// TODO: handle exception
}
return "";
}
/**
* 获取某个路径文件的md5值
*
* @param path
* 文件路径
* @return md5值
*/
public static String getFileMd5(String path) {
try {
// 1.获取一个数字摘要器
MessageDigest digest = MessageDigest.getInstance("md5");
File file = new File(path);
FileInputStream fis = new FileInputStream(file);
// 2.循环的读取文件的每一个byte,获取每个byte的数字签名
byte[] buffer = new byte[1024];
int len = 0;
while ((len = fis.read(buffer)) != -1) {
digest.update(buffer, 0, len);
}
fis.close();
StringBuffer sb = new StringBuffer();
byte[] result = digest.digest();
for (byte b : result) {
// 获取到低八位
int number = b & 0xff;
String hex = Integer.toHexString(number);
if (hex.length() == 1) {
sb.append("0" + hex);
} else {
sb.append(hex);
}
}
return sb.toString();
} catch (Exception e) {
e.printStackTrace();
return "";
}
}
}
AntiVirusActivity.java
public class AntiVirusActivity extends Activity {
protected static final int ISVIRUS = 1;
protected static final int NOVIRUS = 2;
protected static final int FINISH = 3;
private ImageView iv_scan;
private ProgressBar pb_scan;
private PackageManager pm;
private LinearLayout ll_container;
private TextView tv_scan_status;
private Handler handler = new Handler(){
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case ISVIRUS:
tv_scan_status.setText("正在扫描");
PackageInfo packinfo = (PackageInfo) msg.obj;
TextView tv1 = new TextView(getApplicationContext());
tv1.setTextColor(Color.RED);
tv1.setText("发现病毒:"+packinfo.applicationInfo.loadLabel(pm));
ll_container.addView(tv1, 0);
break;
case NOVIRUS:
tv_scan_status.setText("正在扫描");
PackageInfo packinfo2 = (PackageInfo) msg.obj;
TextView tv2 = new TextView(getApplicationContext());
tv2.setTextColor(Color.GREEN);
tv2.setText("扫描安全:"+packinfo2.applicationInfo.loadLabel(pm));
ll_container.addView(tv2,0);
break;
case FINISH:
iv_scan.clearAnimation();
tv_scan_status.setText("扫描完毕");
break;
}
};
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
pm = getPackageManager();
setContentView(R.layout.activity_anti_virus);
iv_scan = (ImageView) findViewById(R.id.iv_scan);
pb_scan = (ProgressBar) findViewById(R.id.pb_scan);
ll_container = (LinearLayout) findViewById(R.id.ll_container);
tv_scan_status = (TextView) findViewById(R.id.tv_scan_status);
RotateAnimation ra = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
ra.setRepeatCount(Animation.INFINITE);
ra.setDuration(2000);
iv_scan.startAnimation(ra);
scanVirus();
}
//耗时的操作
private void scanVirus() {
new Thread(){
public void run() {
PackageManager pm = getPackageManager();
//添加一个flag 把系统所有的文件都扫描出来 包括哪些没有卸载干净的 还保留有数据的应用程序
List<PackageInfo> packinfos = pm.getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES);
pb_scan.setMax(packinfos.size());
int progress = 0;
for(PackageInfo packinfo:packinfos){
String path = packinfo.applicationInfo.sourceDir;
String md5 = MD5Util.getFileMd5(path);
System.out.println(md5);
String desc = AntiVirusDao.find(md5);
Message msg = Message.obtain();
if(desc!=null){
//是病毒
msg.what = ISVIRUS;
}else{
//扫描安全
msg.what = NOVIRUS;
}
msg.obj = packinfo;
handler.sendMessage(msg);
progress++;
pb_scan.setProgress(progress);
try {
Thread.sleep(30);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Message msg = Message.obtain();
msg.what =FINISH;
handler.sendMessage(msg);
};
}.start();
}
}
课3
实现查杀出来的病毒文件的删除
给scanVirus();来个线程睡眠,让杀毒不要杀得太快。 显示在查杀病毒时横竖屏切换所显示的bug:横竖屏切换又重新来查杀一遍(因为这样使Activity重新创建了一遍):修改清单文件
<activity
android:name="com.itheima.mobile47.AntiVirusActivity"
android:configChanges="orientation|screenSize|keyboardHidden" >
</activity>
更新病毒库功能:
在金山的病毒数据库里有一个version的表:
更新的流程:
1、首先连接服务器匹配服务器的数据库版本号和金山的病毒数据库里version的表的版本号是否一样 2、不一样的话,就从服务器下载json数据,然后把里面的对象数据导出来,使用更新SQL语句:更新到我们的数据库中。
activitysettingcenter.xml
<TextView
android:onClick="updateVirusDB"
android:layout_width="match_parent"
android:layout_height="40dp"
android:background="@drawable/list_selector"
android:clickable="true"
android:enabled="true"
android:focusable="true"
android:text="更新病毒数据库"
android:textSize="24sp" />
SettingCenterActivity.java里updateVirusDB()//更新病毒数据库
/**
* 更新病毒数据库。
* @param view
*/
public void updateVirusDB(View view){
//1.获取本地病毒数据库的版本号
//获取subcnt
//2.联网获取服务器的配置信息。
//serversubcnt
//3.比对 serversubcnt 和 本地subcnt的大小。
//4.如果服务器端serversubcnt 比 本地subcnt要大 说明有新的病毒信息需要更新。
//5.计算本地版本和服务器版本的差异大小, 假设相差5个版本号
//6.带着这个版本号差别请求服务器 获取更新信息
//压缩后的sql语句。
//7.解压sql语句,添加数据到数据到本地数据库。
}
实现病毒卸载的功能:在查到的前提下,也不实现了
解决手机卫士的边边角角的小问题
1、屏幕适配问题:
AppManagerActivity.java--->popupWindow 我们编程时用像素编程:那么会有各种手机屏幕不适配的问题:那么我们的像素单位要讲究:
view.getLocationInWindow(location);// 获取了view对象在窗体上的位置
//50 px 像素,注意: 在代码里面写的所有的长度单位 全部都是像素
//dp dip 像素密度。屏幕宽高和像素的一个比例值。
int dip = 50;
int px = DensityUtil.dip2px(getApplicationContext(), dip);
System.out.println(px);
popupWindow.showAtLocation(parent, Gravity.LEFT
+ Gravity.TOP,px , location[1] - 15);
拷贝了一个DensityUtil的工具类:
DensityUtil.java
public class DensityUtil {
/**
* 根据手机的分辨率从 dip 的单位 转成为 px(像素)
*/
public static int dip2px(Context context, float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
/**
* 根据手机的分辨率从 px(像素) 的单位 转成为 dp
*/
public static int px2dip(Context context, float pxValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (pxValue / scale + 0.5f);
}
}
处理像素后:
2、水平低的程序员写出的项目中的死循环中打印的log太多,可能泄露用户信息。
我们变成时需要约定一个方式来打印log,那么不同人接触项目时可以自由地开启或禁用掉log LogUtil.java
public class LogUtil {
public static final boolean mode = true;
public static void d(Object obj,String msg){
if(mode){
Log.d(obj.getClass().getSimpleName(), msg);
}
}
}
3、开发周期短时市面上的app一般测试版上线或带病上线怎么办
SettingCenterActivity.java模拟空指针异常:
这是应用还没发布是的小问题 如果这种问题已经随同app一起上线了,怎么办?
在app里加一个功能:收集用户问题 新建MobileSafeApplication.java继承Applition+配置清单文件,这样去抓取异常出现时弹出的系统终止框的信息,这样可以获取用户体验app时出现问题时获取问题的信息
重写用户app的异常处理器
MobileSafeApplication.java
/**
* 注意:一定要记得在清单文件中配置
* @author Administrator
*
*/
public class MobileSafeApplication extends Application {
//Called when the application is starting当应用程序被开启的时候调用
//before any other application objects have been created
@Override
public void onCreate() {
//老母子的方法。 基地
//重新系统的异常处理器
Thread.currentThread().setUncaughtExceptionHandler(new MyExceptionHander());
super.onCreate();
}
private class MyExceptionHander implements UncaughtExceptionHandler{
@Override
public void uncaughtException(Thread thread, Throwable ex) {
//留下了 留下遗嘱的时间
System.out.println("发生了异常,但是被我们给捕获了。。");
try {
StringWriter wr = new StringWriter();
PrintWriter pw = new PrintWriter(wr);
ex.printStackTrace(pw);
File file = new File(Environment.getExternalStorageDirectory(),"error.log");
FileOutputStream fos = new FileOutputStream(file);
fos.write(wr.toString().getBytes());
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
//专注自杀的方法,就是杀死自己的进程, 早死早超生
android.os.Process.killProcess(android.os.Process.myPid());
}
}
}
这过程可以把异常捕获到后写到了sd卡里的log文件里,这样可以让用户反馈回来给我们调错排错。
然后考虑到用户体验:加入以下代码:
课4
介绍目前市面上公司的盈利模式
公司盈利模式+
1、做自己的产品
1.互联网公司 30%
2.传统行业(想通过互联网让客户更多,跨界)
3.游击队(什么赚钱搞什么,一般老板不懂技术,有钱,风险投资vc),占50%,为什么占这么多?
以下是为什么游击队生产模式占app市场份额这么大
App类型:
1、App付费:在中国行不通,破解,可以发布到欧美市场,go桌面。
2、App内付费:腾讯天天跑酷。
3、免费应用带免费广告:cnbeta.com
广告类型:
1、cpm: 有效展现率 千次展现1块5。和派传单的原理差不多
2、cpc: 有效点击率(点进了网页) 1毛钱~3毛钱
3、cpa:有效行动(进了淘宝连接并且真的买了里面的东西) 5毛~几十块
一个App如果有20万的用户:20万的下载量,两年内,30%保有量:20万其中的6万用户,小游戏。30分钟过关,这么多人就一共120分钟 * 3 (3代表展现广告的次数) = 3600000展现
一天就1670元。所以一个活跃的app每天5000上下没问题。黑马学生(刘福双):600万谷歌下载量,3000美金1天。
蓝海:app找到了一个新开发的需求领域,现实生活中别人没人干过的事情。
红海:懂得操作,csdn蒋涛:看哪个游戏火就做哪个,其中可能就火了。
移动互联网思维:对红海的反思维,哪些需求赚钱就逆其道而行之,百度一下,有趣!
App赚钱需求:
1、女人爱美类
2、男人好色类
3、婴幼儿教育类:国外
4、老人类软件。Eg:BigLauncher
5、特殊人群:魔兽攻略,lol攻略之类。
2、外包公司 软通动力 博廖科技
1.外包人
2.外包项目:带来问题,被一层一层外包,不用心
如何在app里嵌入广告
百度上搜:移动广告平台,很多广告接口提供 百度移动联盟:老师推荐 有米:老师推荐
植物大战僵尸项目:对我们找工作帮助不大,但是对我们了解开发游戏开发app有帮助。
课5
谷歌市场对中国程序员开放了
老师植入广告挣钱效果
演示在项目中植入广告
有米网
1、下载sdk
2、把文档里的jar包烤进来
3、读开发者文档:需要配置的权限
4、配置广告的组件:
5、加标签:
6、MainActivity里植入代码:
MainActivity.java
AdManager.getInstance(this).init("847377901819a2fb", "f2c5d51b6066058c", true);
setContentView(R.layout.activity_main);
initView();
sp = getSharedPreferences("config", MODE_PRIVATE);
// 实例化广告条
AdView adView = new AdView(this, AdSize.FIT_SCREEN);
// 获取要嵌入广告条的布局
LinearLayout adLayout=(LinearLayout)findViewById(R.id.adLayout);
// 将广告条加入到布局中
adLayout.addView(adView);
7、调用方法:
具体方法查开发者文档。
8、activity_main.xml和MainActivity加入代码(布局和方法):
测试:
如何发布app
体力活:需要拍照,身份证认证,两三天的审核,上传应用,平台检查apk是否带广告
想办法推广。软玩推广,
打品牌:减少别人山寨的几率。逆向助手:抄布局,抄代码,反编译
怎么防止反编译。(重要)
解决方案:
百度apk防止反编译:
项目中的project.properties,混淆代码来保护apk隐私
把路径下的文件复制到项目中,并修改代码:
然后发布app,这app就是加密了的apk了。但是我们项目里的有米代码已经混淆过了,所以以下步骤
可以避免我们项目加密过程的报错
混淆:动态的全局替换类名方法名和变量名
课6
混淆后的apk不一定好用
测试:如果app里面含有一些特殊的逻辑,那么apk可能有问题