关键文件1(源码):

  • AppOpsManager.java
  • AppOpsManager.cpp
  • AppOpsServices.cpp

adb命令:

  • adb shell dumpsys appops -h
  • adb shell appops help

enums.proto - OpenGrok cross reference for /frameworks/proto_logging/stats/enums/app/enums.proto

107 // AppOpsManager.java - operation ids for logging
108 enum AppOpEnum {
109     APP_OP_NONE = -1;
110     APP_OP_COARSE_LOCATION = 0;
111     APP_OP_FINE_LOCATION = 1;
112     APP_OP_GPS = 2;
113     APP_OP_VIBRATE = 3;
114     APP_OP_READ_CONTACTS = 4;
115     APP_OP_WRITE_CONTACTS = 5;
116     APP_OP_READ_CALL_LOG = 6;
117     APP_OP_WRITE_CALL_LOG = 7;
118     APP_OP_READ_CALENDAR = 8;
119     APP_OP_WRITE_CALENDAR = 9;
120     APP_OP_WIFI_SCAN = 10;
121     APP_OP_POST_NOTIFICATION = 11;
122     APP_OP_NEIGHBORING_CELLS = 12;
123     APP_OP_CALL_PHONE = 13;
124     APP_OP_READ_SMS = 14;
125     APP_OP_WRITE_SMS = 15;
126     APP_OP_RECEIVE_SMS = 16;
127     APP_OP_RECEIVE_EMERGENCY_SMS = 17;
128     APP_OP_RECEIVE_MMS = 18;
129     APP_OP_RECEIVE_WAP_PUSH = 19;
130     APP_OP_SEND_SMS = 20;
131     APP_OP_READ_ICC_SMS = 21;
132     APP_OP_WRITE_ICC_SMS = 22;
133     APP_OP_WRITE_SETTINGS = 23;
134     APP_OP_SYSTEM_ALERT_WINDOW = 24;
135     APP_OP_ACCESS_NOTIFICATIONS = 25;
136     APP_OP_CAMERA = 26;
137     APP_OP_RECORD_AUDIO = 27;
138     APP_OP_PLAY_AUDIO = 28;
139     APP_OP_READ_CLIPBOARD = 29;
140     APP_OP_WRITE_CLIPBOARD = 30;
141     APP_OP_TAKE_MEDIA_BUTTONS = 31;
142     APP_OP_TAKE_AUDIO_FOCUS = 32;
143     APP_OP_AUDIO_MASTER_VOLUME = 33;
144     APP_OP_AUDIO_VOICE_VOLUME = 34;
145     APP_OP_AUDIO_RING_VOLUME = 35;
146     APP_OP_AUDIO_MEDIA_VOLUME = 36;
147     APP_OP_AUDIO_ALARM_VOLUME = 37;
148     APP_OP_AUDIO_NOTIFICATION_VOLUME = 38;
149     APP_OP_AUDIO_BLUETOOTH_VOLUME = 39;
150     APP_OP_WAKE_LOCK = 40;
151     APP_OP_MONITOR_LOCATION = 41;
152     APP_OP_MONITOR_HIGH_POWER_LOCATION = 42;
153     APP_OP_GET_USAGE_STATS = 43;
154     APP_OP_MUTE_MICROPHONE = 44;
155     APP_OP_TOAST_WINDOW = 45;
156     APP_OP_PROJECT_MEDIA = 46;
157     APP_OP_ACTIVATE_VPN = 47;
158     APP_OP_WRITE_WALLPAPER = 48;
159     APP_OP_ASSIST_STRUCTURE = 49;
160     APP_OP_ASSIST_SCREENSHOT = 50;
161     APP_OP_READ_PHONE_STATE = 51;
162     APP_OP_ADD_VOICEMAIL = 52;
163     APP_OP_USE_SIP = 53;
164     APP_OP_PROCESS_OUTGOING_CALLS = 54;
165     APP_OP_USE_FINGERPRINT = 55;
166     APP_OP_BODY_SENSORS = 56;
167     APP_OP_READ_CELL_BROADCASTS = 57;
168     APP_OP_MOCK_LOCATION = 58;
169     APP_OP_READ_EXTERNAL_STORAGE = 59;
170     APP_OP_WRITE_EXTERNAL_STORAGE = 60;
171     APP_OP_TURN_SCREEN_ON = 61;
172     APP_OP_GET_ACCOUNTS = 62;
173     APP_OP_RUN_IN_BACKGROUND = 63;
174     APP_OP_AUDIO_ACCESSIBILITY_VOLUME = 64;
175     APP_OP_READ_PHONE_NUMBERS = 65;
176     APP_OP_REQUEST_INSTALL_PACKAGES = 66;
177     APP_OP_PICTURE_IN_PICTURE = 67;
178     APP_OP_INSTANT_APP_START_FOREGROUND = 68;
179     APP_OP_ANSWER_PHONE_CALLS = 69;
180     APP_OP_RUN_ANY_IN_BACKGROUND = 70;
181     APP_OP_CHANGE_WIFI_STATE = 71;
182     APP_OP_REQUEST_DELETE_PACKAGES = 72;
183     APP_OP_BIND_ACCESSIBILITY_SERVICE = 73;
184     APP_OP_ACCEPT_HANDOVER = 74;
185     APP_OP_MANAGE_IPSEC_TUNNELS = 75;
186     APP_OP_START_FOREGROUND = 76;
187     APP_OP_BLUETOOTH_SCAN = 77;
188     APP_OP_USE_BIOMETRIC = 78;
189     APP_OP_ACTIVITY_RECOGNITION = 79;
190     APP_OP_SMS_FINANCIAL_TRANSACTIONS = 80;
191     APP_OP_READ_MEDIA_AUDIO = 81;
192     APP_OP_WRITE_MEDIA_AUDIO = 82;
193     APP_OP_READ_MEDIA_VIDEO = 83;
194     APP_OP_WRITE_MEDIA_VIDEO = 84;
195     APP_OP_READ_MEDIA_IMAGES = 85;
196     APP_OP_WRITE_MEDIA_IMAGES = 86;
197     APP_OP_LEGACY_STORAGE = 87;
198     APP_OP_ACCESS_ACCESSIBILITY = 88;
199     APP_OP_READ_DEVICE_IDENTIFIERS = 89;
200     APP_OP_ACCESS_MEDIA_LOCATION = 90;
201     APP_OP_QUERY_ALL_PACKAGES = 91;
202     APP_OP_MANAGE_EXTERNAL_STORAGE = 92;
203     APP_OP_INTERACT_ACROSS_PROFILES = 93;
204     APP_OP_ACTIVATE_PLATFORM_VPN = 94;
205     APP_OP_LOADER_USAGE_STATS = 95;
206     APP_OP_DEPRECATED_1 = 96 [deprecated = true];
207     APP_OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED = 97;
208     APP_OP_AUTO_REVOKE_MANAGED_BY_INSTALLER = 98;
209     APP_OP_NO_ISOLATED_STORAGE = 99;
210     APP_OP_PHONE_CALL_MICROPHONE = 100;
211     APP_OP_PHONE_CALL_CAMERA = 101;
212     APP_OP_RECORD_AUDIO_HOTWORD = 102;
213     APP_OP_MANAGE_ONGOING_CALLS = 103;
214     APP_OP_MANAGE_CREDENTIALS = 104;
215     APP_OP_USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER = 105;
216     APP_OP_RECORD_AUDIO_OUTPUT = 106;
217     APP_OP_SCHEDULE_EXACT_ALARM = 107;
218     APP_OP_FINE_LOCATION_SOURCE = 108;
219     APP_OP_COARSE_LOCATION_SOURCE = 109;
220     APP_OP_MANAGE_MEDIA = 110;
221     APP_OP_BLUETOOTH_CONNECT = 111;
222     APP_OP_UWB_RANGING = 112;
223     APP_OP_ACTIVITY_RECOGNITION_SOURCE = 113;
224     APP_OP_BLUETOOTH_ADVERTISE = 114;
225     APP_OP_RECORD_INCOMING_PHONE_AUDIO = 115;
226 }

AppOpsManager.java - OpenGrok cross reference for /frameworks/base/core/java/android/app/AppOpsManager.java

2213      /**
2214       * This optionally maps a permission to an operation.  If there
2215       * is no permission associated with an operation, it is null.
2216       */
2217      @UnsupportedAppUsage
2218      private static String[] sOpPerms = new String[] {
2219              android.Manifest.permission.ACCESS_COARSE_LOCATION,
2220              android.Manifest.permission.ACCESS_FINE_LOCATION,
2221              null,
2222              android.Manifest.permission.VIBRATE,
2223              android.Manifest.permission.READ_CONTACTS,
2224              android.Manifest.permission.WRITE_CONTACTS,
2225              android.Manifest.permission.READ_CALL_LOG,
2226              android.Manifest.permission.WRITE_CALL_LOG,
2227              android.Manifest.permission.READ_CALENDAR,
2228              android.Manifest.permission.WRITE_CALENDAR,
2229              android.Manifest.permission.ACCESS_WIFI_STATE,
2230              null, // no permission required for notifications
2231              null, // neighboring cells shares the coarse location perm
2232              android.Manifest.permission.CALL_PHONE,
2233              android.Manifest.permission.READ_SMS,
2234              null, // no permission required for writing sms
2235              android.Manifest.permission.RECEIVE_SMS,
2236              android.Manifest.permission.RECEIVE_EMERGENCY_BROADCAST,
2237              android.Manifest.permission.RECEIVE_MMS,
2238              android.Manifest.permission.RECEIVE_WAP_PUSH,
2239              android.Manifest.permission.SEND_SMS,
2240              android.Manifest.permission.READ_SMS,
2241              null, // no permission required for writing icc sms
2242              android.Manifest.permission.WRITE_SETTINGS,
2243              android.Manifest.permission.SYSTEM_ALERT_WINDOW,
2244              android.Manifest.permission.ACCESS_NOTIFICATIONS,
2245              android.Manifest.permission.CAMERA,
2246              android.Manifest.permission.RECORD_AUDIO,
2247              null, // no permission for playing audio
2248              null, // no permission for reading clipboard
2249              null, // no permission for writing clipboard
2250              null, // no permission for taking media buttons
2251              null, // no permission for taking audio focus
2252              null, // no permission for changing global volume
2253              null, // no permission for changing voice volume
2254              null, // no permission for changing ring volume
2255              null, // no permission for changing media volume
2256              null, // no permission for changing alarm volume
2257              null, // no permission for changing notification volume
2258              null, // no permission for changing bluetooth volume
2259              android.Manifest.permission.WAKE_LOCK,
2260              null, // no permission for generic location monitoring
2261              null, // no permission for high power location monitoring
2262              android.Manifest.permission.PACKAGE_USAGE_STATS,
2263              null, // no permission for muting/unmuting microphone
2264              null, // no permission for displaying toasts
2265              null, // no permission for projecting media
2266              null, // no permission for activating vpn
2267              null, // no permission for supporting wallpaper
2268              null, // no permission for receiving assist structure
2269              null, // no permission for receiving assist screenshot
2270              Manifest.permission.READ_PHONE_STATE,
2271              Manifest.permission.ADD_VOICEMAIL,
2272              Manifest.permission.USE_SIP,
2273              Manifest.permission.PROCESS_OUTGOING_CALLS,
2274              Manifest.permission.USE_FINGERPRINT,
2275              Manifest.permission.BODY_SENSORS,
2276              Manifest.permission.READ_CELL_BROADCASTS,
2277              null,
2278              Manifest.permission.READ_EXTERNAL_STORAGE,
2279              Manifest.permission.WRITE_EXTERNAL_STORAGE,
2280              null, // no permission for turning the screen on
2281              Manifest.permission.GET_ACCOUNTS,
2282              null, // no permission for running in background
2283              null, // no permission for changing accessibility volume
2284              Manifest.permission.READ_PHONE_NUMBERS,
2285              Manifest.permission.REQUEST_INSTALL_PACKAGES,
2286              null, // no permission for entering picture-in-picture on hide
2287              Manifest.permission.INSTANT_APP_FOREGROUND_SERVICE,
2288              Manifest.permission.ANSWER_PHONE_CALLS,
2289              null, // no permission for OP_RUN_ANY_IN_BACKGROUND
2290              Manifest.permission.CHANGE_WIFI_STATE,
2291              Manifest.permission.REQUEST_DELETE_PACKAGES,
2292              Manifest.permission.BIND_ACCESSIBILITY_SERVICE,
2293              Manifest.permission.ACCEPT_HANDOVER,
2294              Manifest.permission.MANAGE_IPSEC_TUNNELS,
2295              Manifest.permission.FOREGROUND_SERVICE,
2296              Manifest.permission.BLUETOOTH_SCAN,
2297              Manifest.permission.USE_BIOMETRIC,
2298              Manifest.permission.ACTIVITY_RECOGNITION,
2299              Manifest.permission.SMS_FINANCIAL_TRANSACTIONS,
2300              null,
2301              null, // no permission for OP_WRITE_MEDIA_AUDIO
2302              null,
2303              null, // no permission for OP_WRITE_MEDIA_VIDEO
2304              null,
2305              null, // no permission for OP_WRITE_MEDIA_IMAGES
2306              null, // no permission for OP_LEGACY_STORAGE
2307              null, // no permission for OP_ACCESS_ACCESSIBILITY
2308              null, // no direct permission for OP_READ_DEVICE_IDENTIFIERS
2309              Manifest.permission.ACCESS_MEDIA_LOCATION,
2310              null, // no permission for OP_QUERY_ALL_PACKAGES
2311              Manifest.permission.MANAGE_EXTERNAL_STORAGE,
2312              android.Manifest.permission.INTERACT_ACROSS_PROFILES,
2313              null, // no permission for OP_ACTIVATE_PLATFORM_VPN
2314              android.Manifest.permission.LOADER_USAGE_STATS,
2315              null, // deprecated operation
2316              null, // no permission for OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED
2317              null, // no permission for OP_AUTO_REVOKE_MANAGED_BY_INSTALLER
2318              null, // no permission for OP_NO_ISOLATED_STORAGE
2319              null, // no permission for OP_PHONE_CALL_MICROPHONE
2320              null, // no permission for OP_PHONE_CALL_CAMERA
2321              null, // no permission for OP_RECORD_AUDIO_HOTWORD
2322              Manifest.permission.MANAGE_ONGOING_CALLS,
2323              null, // no permission for OP_MANAGE_CREDENTIALS
2324              Manifest.permission.USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER,
2325              null, // no permission for OP_RECORD_AUDIO_OUTPUT
2326              Manifest.permission.SCHEDULE_EXACT_ALARM,
2327              null, // no permission for OP_ACCESS_FINE_LOCATION_SOURCE,
2328              null, // no permission for OP_ACCESS_COARSE_LOCATION_SOURCE,
2329              Manifest.permission.MANAGE_MEDIA,
2330              Manifest.permission.BLUETOOTH_CONNECT,
2331              Manifest.permission.UWB_RANGING,
2332              null, // no permission for OP_ACTIVITY_RECOGNITION_SOURCE,
2333              Manifest.permission.BLUETOOTH_ADVERTISE,
2334              null, // no permission for OP_RECORD_INCOMING_PHONE_AUDIO,
2335      };

关键文件2:

/system/bin/appops

/data/system/appops.xml

/system/etc/appops_policy.xml


Android系统应用部分是后台运行,没有桌面图标,也不会跟用户交互的。但是,也涉及敏感行为,无法像三方应用那样,动态申请权限,所以,需要appops这套权限管理和行为管理机制。

AppOps虽然涵盖了App的权限管理,但是Google原生的设计并不仅仅是对“权限”的管理,而是对App的“动作”的管理。我们平时讲的权限管理多是针对具体的权限(App开发者在Manifest里申请的权限),而AppOps所管理的是所有可能涉及用户隐私和安全的操作,包括 access notification, keep weak lock, activate vpn, display toast 等等,有些操作是不需要Manifest里申请权限的。

AppOpsService也会被注入到各个相关的系统服务中,进行权限操作的检验。

各个权限操作对应的系统服务(比如定位相关的Location Service,Audio相关的Audio Service等)中注入AppOpsService的判断。如果用户做了相应的设置,那么这些系统服务就要做出相应的处理。(比如,LocationManagerSerivce的定位相关接口在实现时,会有判断调用该接口的app是否被用户设置成禁止该操作,如果有该设置,就不会继续进行定位。)

参考资料:

AppOps原理_在路上的大蜗牛-CSDN博客_appops使用详解


  • 动态运行时权限 VS appops权限

结论1:动态运行时权限 appops权限 是两套并行的敏感行为管控机制;

结论2:动态运行时权限,AndroidManifest.xml申请权限并不意味着敏感行为发生;代码中grant权限也不意味着敏感行为发生;因为他们都没有直接影响sendText这个接口;

结论3:为什么动态运行时权限并不能意味着敏感行为发生,而appops的log就意味着敏感行为发生了?因为appops直接注入到sendText这个接口,详见下面发送短信sendText接口代码;

远端 sendText() 函数首先通过 enforceCallingPermission() 函数来检查 App 是否在 AndroidManifest.xml 中申请了 android.permission.SEND_SMS 的权限。然后在通过调用 mAppOps (AppOpsService 的服务端实例 AppOpsManager) 调用 noteOp() 函数检查是否通过了用户的权限设置。如果没有通过检查,就直接 return。

    String text, PendingIntent sentIntent, PendingIntent deliveryIntent) {mPhone.getContext().enforceCallingPermission(Manifest.permission.SEND_SMS,"Sending SMS message");if (Rlog.isLoggable("SMS", Log.VERBOSE)) {log("sendText: destAddr=" + destAddr + " scAddr=" + scAddr +" text='"+ text + "' sentIntent=" +sentIntent + " deliveryIntent=" + deliveryIntent);}if (mAppOps.noteOp(AppOpsManager.OP_SEND_SMS, Binder.getCallingUid(),callingPackage) != AppOpsManager.MODE_ALLOWED) {return;}mDispatcher.sendText(destAddr, scAddr, text, sentIntent, deliveryIntent);

参考资料:

AppOps原理_在路上的大蜗牛-CSDN博客_appops使用详解


  • appops权限 用于cta进网信息安全测试 盲区

结论1:只有部分服务被appops的代码注入了,所以,需要跟cta测试标准对比一下,看看是否有遗漏

Setting UI通过AppOpsManager与AppOpsService交互,给用户提供入口管理各个app的操作。

AppOpsService具体处理用户的各项设置,用户的设置项存储在 /data/system/appops.xml文件中。

AppOpsService也会被注入到各个相关的系统服务中,进行权限操作的检验。

各个权限操作对应的系统服务(比如定位相关的Location Service,Audio相关的Audio Service等)中注入AppOpsService的判断。如果用户做了相应的设置,那么这些系统服务就要做出相应的处理。(比如,LocationManagerSerivce的定位相关接口在实现时,会有判断调用该接口的app是否被用户设置成禁止该操作,如果有该设置,就不会继续进行定位。)

参考资料:

AppOps原理_在路上的大蜗牛-CSDN博客_appops使用详解

结论2:部分被注入的服务,只调用了check,没有调用note,那么也不会被appops的log记录

1).一般的op都会走noteOperation,但是OP_RECORD_AUDIO却是不走这里,而是走checkOperation;
因为对于AUDIO有专门的方法checkAudioOperation,最终调用到checkOperation。
(2).checkOperation与noteOperation的区别可以查看checkOp及noteOp的函数说明:checkOp只是check;noteOp不仅check还note。至于具体调用哪个,看需求。一般的runtime权限都会进行check,少数非runtime也会check;多数非runtime权限会进行note,少数runtime权限也会note;这个看代码中的需求。

参考资料:

Android权限 - AppOps介绍_hanhan1016的专栏-CSDN博客

总结一下:appops用于cta测试

场景一:服务没有被注入,无法测试;

场景二:服务被注入,但是只调用check,没调用note,无法测试;

场景三:服务被注入,调用check,可以测试;


appops 实例分析

案例一:发送短信

AppOps原理_在路上的大蜗牛-CSDN博客_appops使用详解

权限管理AppOps_zhongfan520520的博客-CSDN博客_ops权限

案例二:定位

Android权限管理原理(含6.0-4.3)_happylishang的专栏-CSDN博客

案例三:camera

Appops权限管理_光着脚丫行一生的专栏-CSDN博客_ops权限

案例四:综合

Android权限 - AppOps介绍_hanhan1016的专栏-CSDN博客


adb shell dumpsys appops -h


adb shell appops help

Android-进阶教程-权限-特殊权限-AppOps相关推荐

  1. Android原生权限管理:AppOps

    --------------------- 从Android M开始,Google就正式推出了官方的权限管理机制Android Runtime Permission. AppOps终究没有走到台面^^ ...

  2. Android 权限清单大全,Android开发教程

    概述 权限 说明 访问登记属性 android.permission.ACCESS_CHECKIN_PROPERTIES 读取或写入登记check-in数据库属性表的权限 获取错略位置 android ...

  3. Android源码的Binder权限是如何控制,附超全教程文档

    从初中级到高级,移动端程序员的进阶宝典 想要成为一名优秀的Android开发,你需要一份完备的 知识体系,在这里,让我们一起成长为自己所想的那样. 下面我们就以 Android 开发为例,从硬技能和软 ...

  4. Android 在运行时请求权限

    2019独角兽企业重金招聘Python工程师标准>>> 从 Android 6.0(API 级别 23)开始,用户开始在应用运行时向其授予权限,而不是在应用安装时授予.此方法可以简化 ...

  5. android 动态获取权限有哪些,Android 6.0+ 动态获取权限

    Android 6.0+ 动态获取权限 这里有一个现成的库,可以直接拿来用.方便简单 1.向app下的gradle添加依赖: dependencies{ // android 6.0+ 动态获取权限 ...

  6. Android 6.0 运行时权限处理完全解析

    一.概述 随着Android 6.0发布以及普及,我们开发者所要应对的主要就是新版本SDK带来的一些变化,首先关注的就是权限机制的变化.对于6.0的几个主要的变化,查看查看官网的这篇文章http:// ...

  7. Android应用程序获得root权限

    我在博文<Android程序的安全系统>中提到两种让root权限的办法.最近在网上发现很多朋友转载那篇文章,但是对那篇文章中提到的第一种方法怎样实现,不是很明白.本文将会以一个例子实现来演 ...

  8. 关于android 1.6全部的权限介绍

    原文:关于android 1.6全部的权限介绍 我们在 AndroidManifest.xml里需要对一些软件需要的操作做一些权限的声明, 比如我们的软件有发送短信的功能,那么就需要在 Android ...

  9. 【Android 逆向】Linux 文件权限 ( Linux 权限简介 | 系统权限 | 用户权限 | 匿名用户权限 | 读 | 写 | 执行 | 更改组 | 更改用户 | 粘滞 )

    文章目录 一.Linux 权限简介 二.系统权限 / 用户权限 / 匿名用户权限 1.系统权限 2.用户权限 3.匿名用户权限 一.Linux 权限简介 Linux 是基于文件的系统 , 内存 , 设 ...

  10. 【Android 应用开发】Google 官方 EasyPermissions 权限申请库 ( 完整代码示例 | 申请权限 | 申请权限原理对话框 | 引导用户手动设置权限对话框 )

    文章目录 一.申请权限 二.申请权限原理对话框 三.引导用户手动设置权限对话框 四.在 AndroidManifest.xml 中配置权限 五.完整代码示例 六.GitHub 地址 一.申请权限 申请 ...

最新文章

  1. 改进,从一个数组中找出 N 个数,其和为 M 的所有可能
  2. RF中alert的处理
  3. Linux中的可重入函数和不可重入函数
  4. Linux系统下Apache与Tomcat整合
  5. 蓝桥杯-题目:猜算式
  6. 1015 德才论 (25分)
  7. 怎么把此电脑放到桌面_Win10我的电脑怎么放到桌面
  8. react 访问后端_react前端用nginx怎么配置跨域访问后端restful api?
  9. 传统的主从复制的概念和要点
  10. CTF比赛中关于zip的总结
  11. 同一张表sql省市区三级联动查询
  12. 建设医疗人工智能的“四步曲”
  13. 未明学院:被腾讯群面虐完后,我找到了未来的方向…
  14. 中文文案排版指北(转自GitHub)
  15. java泛型常用特点_?你必须知道的Java泛型
  16. DROP和DELETE的区别
  17. Kotlin学习笔记
  18. 印第安人与中国人的关系
  19. 词云中去重复的词_李清照特别经典的词,把相思写得淋漓尽致,读一次心疼一次...
  20. 通过修改rom包永久获取root权限和所有应用调试功能ro.debuggable

热门文章

  1. 【MMD动作+镜头下载】Chocolate Train
  2. java 单元测试 私有成员变量,单元测试时测试一个private私有方法 - - ITeye博客
  3. 用*号输出字母C的图案。
  4. 母亲大人辛苦了(snowfall.jquery实现爱心掉落)
  5. jquery/zepto 圣诞节雪花飞扬
  6. codeup刷题 2.6小节——C/C++快速入门->函数 ——《算法笔记》(胡凡)
  7. windows磁盘引导分区
  8. 小小知识点(一):辨别性相似度(Discriminative Similarity)
  9. windows7与linux,Windows7与Linux——操作系统大PK
  10. 用python画星空-python3的turtle画模仿3d星空,运动的恒星小宇宙