ºÜ¶àÈËдÎÄÕ£¬Ï²»¶°ÑʲôÐÐÒµÏÖ×´°¡£¬Ñо¿ÏÖ×´°¡Ê²Ã´µÄдÁËÒ»´óͨ£¬¸Ð¾õºÃÏñÔÚд±ÏÒµÂÛÎÄËÆµÄ£¬ÎÒÕâ²»·Ï»°£¬ÏÈÖ±½ÓÉϼ¸¸öͼ£¬¸ÐÊÜһϡ£

µÚÒ»ÕÅͼÊÇÔÚ°Ñ´úÂë×¢Èëµ½µØÍ¼ÀïÃæ£¬Æô¶¯Ê×Ò³µÄʱºòµ¯³ö¸ö¸¡´°£¬ÏÂÔØÍøÂçµÄͼƬ£¬²ÔÀÏʦÄãÃDz»»á²»ÈÏʶ°É£¿
µÚ¶þÕÅͼÊÇ΢ÐÅÔ˶¯²½Êý×÷±×£¬6²»6£¿
ok£¬ÄÇÎÒÃÇ´Óͷ˵Æð
1.·´±àÒë
Android µÄ·´±àÒ룬ÏàÐÅ´ó¼Ò¶¼Ó¦¸ÃÓÐËùÁ˽⣬apktool¡¢JEB
µÈ¹¤¾ß
ÎÒÃÇÏÈ¿´Ò»Ï Apk ÎļþµÄ½á¹¹°É£¬ÈçÏÂͼ£º
1.META-INF£ºÇ©ÃûÎļþ£¨Õâ¸öÊÇÈçºÎÉú³ÉµÄºóÃæ»áÌáµ½£©
2.res£º×ÊÔ´Îļþ£¬ÀïÃæµÄ xml ¸ñʽÎļþÔÚ±àÒë¹ý³ÌÖÐÓÉÎı¾¸ñʽת»¯Îª¶þ½øÖƵÄ
AXML Îļþ¸ñʽ
3.AndroidManifest.xml£ºandroid ÅäÖÃÎļþ£¬±àÒë¹ý³ÌÒÀÈ»±»×ª»»Îª
AXML ¸ñʽ
4.classes.dex£ºjava ´úÂë±àÒëºó²úÉúµÄÀàËÆ×Ö½ÚÂëµÄÎļþ£¨dalvik
×Ö½ÚÂ룩
5.resources.arsc£º¾ßÓÐ id Öµ×ÊÔ´µÄË÷Òý±í£¨asserts
Îļþ¼ÐÖеÄ×ÊÔ´²»»áÉú³ÉË÷Òý£©
6.ÆäËûÎļþ£º¿ÉÓÉ¿ª·¢Õß×Ô¼ºÌí¼Ó£¬ÖîÈç assets µÈ£¬»òÕß lib£¨native
so ´úÂ룩µÈĿ¼

apkµÄºËÐÄÂß¼Ö÷ÒªÔÚ classes.dex ÖУ¬ÆÆ½âºÍ¶þ´Î´ò°üÒ²»ù±¾É϶ÔÕâ¸öÎļþ×öÊֽţ¬ËùÒÔ¶ÔÕâ¸öÎļþµÄ±£»¤Ò²ÓÈÎªÖØÒª¡£

ÉÏͼΪһ°ã Apk µÄÆÆ½â¹ý³Ì£¨windows »Í¼¹¤¾ß»µÄ±È½Ï´ê£©
ÎÒÃÇÊ×ÏÈÓà apktool ¹¤¾ß·´±àÒ룺java -jar apktool.jar
d -f xxx.apk outDir(PS:outDir ²»Ð´»áÔÚµ±Ç°Ä¿Â¼Êä³ö)
·´±àÒëºóµÄĿ¼½á¹¹ÈçÏ£º

ÕâÀres ÀïµÄ xml ºÍ manifset.xml ¶¼ÒѾÊǽâ³öºóµÄ
xml ÁË£¬²»ÊÇ axml ¸ñʽÁË£¬res Ŀ¼ÀïµÄ values Ŀ¼Ï嵀 public.xml ¿ÉÒÔ¿´µ½×ÊÔ´¶ÔÓ¦µÄ
id
Èç¹ûÃüÁî java -jar apktool.jar d -fÔÙ¼ÓÈë -r ´ú±í×ÊÔ´Îļþ²»·´±àÒ룬ÉÏͼµÄĿ¼Öн«ÒÀÈ»ÓÐresources.arsc£¬xml
¶¼ÊÇ axml ¸ñʽµÄ£¬Ò²ÕÒ²»µ½ public.xml
ÆäʵÎÒÃÇÖ÷Òª¹Ø×¢µÄÊÇ smali Õâ¸öĿ¼£¬ÀïÃæÊǰ´ÕÕ android ³ÌÐò±àдµÄʱºò java ÎļþµÄĿ¼¸ñʽÉú³ÉµÄ£¬µ«ÊÇÀïÃæµÄÎļþ²¢²»ÊÇ
java ¸ñʽµÄ£¬¶øÊÇ smali ¸ñʽµÄ£¬ÀàËÆ MainActivity.smali¡£
ÄÇôʲôÊÇ smali ÎļþÄØ£¿
1.Smali ÊÇ Android µÄ Dalvik ÐéÄâ»úËùʹÓõÄÒ»ÖÖ
dex ¸ñʽµÄÖмäÓïÑÔ
2.¿ÉÒÔÀí½âΪ£¬C ÓïÑԺͻã±àÓïÑԵıàÒëÓë·´±àÒ룬°Ñ smali Àí½âΪһÖÖ»ã±àÓïÑÔ
ÎÒÃÇ¿ÉÒÔ´ò¿ªÒ»¸ö smali Îļþ¿´¿´£¬ÎÒÃÇ¿ÉÒÔʹÓà notepad++ ´ò¿ª£¬È»ºó¶¨Ò»Ï smali
Óï·¨µÄ¸ßÁÁÏÔʾ
½«ÏÂÃæÄÚÈݱ£´æµ½ C:\Users\Óû§Ãû\AppData\Roaming\Notepad++Ï£¬ÎļþÃûΪ
userDefineLang.xml

´ò¿ª MainActivity.smali Îļþ£¬Í·ÈýÐдúÂë´óÖÂÈçÏ£º
.class
public Lcom/example/hacktest/MainActivity;
.super Landroid/app/Activity;
.source "MainActivity.java
|
ÕâÀï¾Ù¸öÀý×Ó£¬ÎÒÃÇд¸ö³ÌÐò£¬Ò»¸ö edittext Ò»¸ö button£¬µ±
edit ÀïÃæÊäÈëÕýÈ·µÄÎÄ×ÖµÄʱºò£¬µã»÷ button ²Å»áµ¯³öÕýÈ·µÄ toast¡£
ÎÒÃÇ¿´Ò»Ï£¬·´±àÒëºóµÄ¹Ø¼ü´úÂë

¿ÉÒÔ¿´µ½ÕâÊÇÒ»¸ö²ÎÊýΪ string£¬·µ»ØÖµÎª boolean Ãû½Ð check
µÄº¯Êý£¬µ±ÊäÈëΪ¡°11¡±µÄʱºò²Å·µ»Ø true¡£
ÎÒÃÇ¿ÉÒ԰ѵÚÒ»¸öºì¿òλÖÃµÄ if-eqz ¸Ä³É if-nez,ÕâÑùÄãÊäÈë³ýÁË11µÄÈκÎ×Ö·û¶¼»á·µ»Ø
true¡£
»òÕ߰ѵڶþ¸öºì¿òλÖÃµÄ 0x1£¬¸Ä³É 0x0,£¨0´ú±í true£©£¬ÕâÑùÕâ¸öº¯Êý²»¹ÜÊäÈëʲô¶¼·µ»Ø
true¡£
OK£¬ÕâÑùÎÒÃǾ͸ÄÍêÁË£¬ÎÒÃÇÖØÐ±àÒ룺java -jar apktool.jar
b -f outDir xxx.apk
( PS:xxx.apk ¿ÉÒÔ²»Ð´£¬»áÔÚ outDir ÀïÉú³É dist
Ŀ¼£¬±àÒëºÃµÄ Apk ÔÚÕâÀïÃæ£©
Ç©Ãû£º¿ÉÒÔÍøÉÏÏÂÔØ¹¤¾ß autoSign£¬Ê¹Ó÷½·¨ÂÔ¡£

°²×° Apk ºóÑéÖ¤£¬Í¨¹ý¡£
µ«ÊÇÊÂÇé²¢²»×ÜÊÇÈçÎÒÃÇËùÔ¸£¬ÓÐЩ Apk »á×öһЩµÁ°æ¼ì²â»úÖÆ£¬¾ÍÊÇΪÁË·ÀÖ¹¶þ´ÎÖØ´ò°ü
ÒÔÊÖ»ú±©·çÓ°ÒôΪÀý£¬µ±Äã°´ÕÕÉÏÊö²½Öè·´±àÒë£¬ÖØÐ±àÒ룬ǩÃûÖ®ºó£¬½øÈë APP »á³öÏÖÕâ¸öÒ³Ãæ£¬ÎÞ·¨Õý³£Ê¹ÓÃ
ÒòΪÄ㲢ûÓÐÕâ¸ö APP µÄÕý°æÇ©ÃûÎļþ£¨¹ØÓÚÇ©ÃûÏà¹ØµÄ¶«Î÷£¬ÔÚºóÃæÎÒÔÙ×Ðϸ½²£©

ÄÇôÕâ¸öÔÀíÊÇÊ²Ã´ÄØ£¬ÎÒÃǴ󵨲²âһϣ¬Î޷ǾÍÊǺÍÉÏÒ»¸öÀý×ÓÀàËÆµÄ check
º¯Êý£¬Á½¸öÖµµÄ¶Ô±È£¬ÄÇôÕâ¸öÖµÒ»¶¨ÊÇÇ©Ãû¡£
ÎÒÃÇÏÈͨ¹ý·½·¨Äõ½Õý°æÊÖ»ú±©·çÓ°ÒôµÄÇ©Ãû md5£¬È»ºóÔÚ·´±àÒëºóµÄ´úÂëÖÐËÑË÷Ò»ÏÂÕâ¸öÖµ¡£

È»¶ø²¢Ã»ÓÐËѵ½£¬ÔÙ»»¸ö˼·£¬ÎÒÃÇËÑË÷»ñȡǩÃûµÄÕâ¸öº¯Êý£¬´Ó¶ø¶¨Î»¹Ø¼ü´úÂë,»ñȡӦÓÃÇ©ÃûµÄ
java ´úÂëÀàËÆÊÇ£º
PackageInfo pi = context.getPackageManager.().getPackageInfo(packname,packageManager.GET_SIGNATURES); ¶ÔÓ¦µÄsmali´úÂëÀàËÆÊÇ£º Landroid/content/pm/PackageInfo;->signatures:[Landroid/content/pm/Signature |
ÎÒÃÇÔÙËÑÓÃÕâ¶Î´úÂëËÑË÷£¬ÔÚ StormUtils2.smali ÀïÃæÕÒµ½ÁË£¬·¢ÏÖÔÚº¯Êý
getSignInfo ÀïÃæ£¬¼ÌÐø¸ú×Ùµ½ checkPiracy º¯Êý¡£
¿´µ½Õâ¸öº¯Êý·¢Ï־ͺÍÉÏÀýÖÐµÄ check º¯ÊýÀàËÆÁË£¬¸ÄһϷµ»ØÖµÎª true ¾ÍºÃÁË¡£
ÎÒÃÇÔÙ×Ðϸ¿´¿´Õâ¸öº¯Êý£¬·¢ÏֹؼüµÄÇ©Ãû md5 Öµ±»²ð¿ª´æ·ÅÁË£¬ËùÒÔÎÒÃDzÅûÓÐËѵ½£¬ÕâÒ²ÊÇ·À·¶ËÑË÷µÄÒ»¸ö¾Ù´ë°É£¨ËäÈ»ÎÒ¾õµÃ²¢Ã»Ê²Ã´Óã©
const-string/jumbo v3, "dbbf60f096b326003" const-string/jumbo v0, "c388a350d1578d5" |
ºÃµÄ£¬Ð޸ĺó£¬ÎÒÃÇÔÙÖØÐ±àÒ롢ǩÃû£¬Ñé֤ͨ¹ý¡£
£¨PS:¹ØÓÚÇ©Ãû¼ì²âµÄ³ýÁË java ²ãµÄ£¬¿ÉÄÜ»¹ÓÐÔÙ so ÀïÃæÐ£ÑéµÄºÍ·þÎñÆ÷ÑéÖ¤µÄ·½Ê½£¬ÔÚ
so ÀïµÄÓà IDA ´ò¿ª so ¸ú×ÙÐ޸쬷þÎñÆ÷ÑéÖ¤µÄ×¥°ü²é¿´£¬ÔÙÄ£Äâ·¢°üÖØ·Å¹¥»÷¾ÍºÃÁË£¬ÕâÀï¾Í²»¾ßÌå½éÉÜÁË£©
2. Android µÄÇ©Ãû±£»¤»úÖÆµ½µ×ÊÇʲô£¿
android ϵͳ½ûÖ¹¸üа²×°Ç©Ãû²»Ò»Ö嵀 apk£¬Èç¹ûÎÒÃÇÐÞ¸ÄÁË apk ÓÖÓñðµÄÇ©ÃûÎļþÇ©Ãû£¬¿Ï¶¨ÊDz»Ò»Öµġ£
ÎÒÃÇ´ÓÇ©Ãû¹¤¾ß autoSign ·ÖÎö£¬¿´Ò»Ï sign.bat ÎļþÄÚÈÝ£º
@ECHO OFF
Echo Auto-sign Created By Dave Da illest
1
Echo Update.zip is now being signed
and will be renamed to update_signed.zip
java -jar signapk.jar testkey.x509.pem testkey.pk8
update.apk update_signed.apk
Echo Signing Complete
Pause
EXIT
¿´Ò»Ï java -jar signapk.jar testkey.x509.pem testkey.pk8
update.apk update_signed.apk ÕâÐеÄÒâÒ壺
ÒÔtestkey.x509.pem Õâ¸ö¹«Ô¿ÎļþºÍ testkey.pk8 Õâ¸ö˽ԿÎļþ¶Ô update.apk
½øÐÐÇ©Ãû£¬Ç©Ãûºó±£´æÎª update_signed.apk
ÎÒÃÇ¿ÉÒÔ¿´µ½Ç©ÃûǰºÍÇ©Ãûºó±È½Ï£¬Ç©ÃûºóµÄÎļþÖжàÁËÒ»¸öÎļþ¼Ð¡°META-INF¡±£¬ÀïÃæÓÐÈý¸öÎļþ
MANIFEST.MF ¡¢ CERT.SF ¡¢ CERT.RSA
ÎÒÃÇͨ¹ý jd-gui ¹¤¾ß´ò¿ª signapk.jar£¬ÕÒµ½ main
º¯Êý£¬Í¨¹ýÕâ¸öº¯Êý¸ú×Ù´úÂë

1.addDigestsToManifest Õâ¸öº¯Êý£¬±éÀú apk ÖÐËùÓÐÎļþ£¬¶Ô·ÇÎļþ¼Ð·ÇÇ©ÃûÎļþµÄÎļþÖð¸öÉú³É
SHA1 Êý×ÖÇ©ÃûÐÅÏ¢£¬ÔÙ base64 ±àÂë
È»ºóÔÙдÈë MANIFEST.MF ÎļþÖУ¬Éú³ÉÎļþÈçÏ£º
Manifest-Version: 1.0
Created-By: 1.0 (Android)
Name: res/drawable-xhdpi/ic_launcher.png
SHA1-Digest: AfPh3OJoypH966MludSW6f1RHg4=
Name: AndroidManifest.xml
SHA1-Digest: NaPhUBH5WO7uGk/CfRu/SHsCvW0=
Name: res/drawable-mdpi/ic_launcher.png
SHA1-Digest: RRxOSvpmhVfCwiprVV/wZlaqQpw=
Name: res/drawable-hdpi/ic_launcher.png
SHA1-Digest: Nq8q3HeTluE5JNCBpVvNy3BXtJI=
Name: res/layout/activity_main.xml
SHA1-Digest: kxwMyILwF2K+n9ziNhcQqcCGWIU=
Name: resources.arsc
SHA1-Digest: q7Ystu6WoSWih53RGKXtE3LeTdc=
Name: classes.dex
SHA1-Digest: Ao1WOs5PXMxsWTDsjSijS2tfnHo=
Name: res/drawable-xxhdpi/ic_launcher.png
SHA1-Digest: GVIfdEOBv4gEny2T1jDhGGsZOBo=
SHA1 Éú³ÉµÄÕªÒªÐÅÏ¢£¬Èç¹ûÄãÐÞ¸ÄÁËij¸öÎļþ£¬apk °²×°Ð£Ñéʱ£¬È¡µ½µÄ¸ÃÎļþµÄÕªÒªÓë MANIFEST.MF
ÖжÔÓ¦µÄÕªÒª²»Í¬£¬Ôò°²×°²»³É¹¦
2.½ÓÏÂÀ´¶Ô֮ǰÉú³ÉµÄ manifest ʹÓà SHA1withRSA Ëã·¨£¬ ÓÃ˽ԿǩÃû£¬writeSignatureFile
Õâ¸öº¯Êý£¬×îºóÉú³É CERT.SF Îļþ£¬ÈçÏ£º
Signature-Version: 1.0
Created-By: 1.0 (Android)
HA1-Digest-Manifest: pNZ9UXN9GMqTgqAwKD6uEN6aD34=
Name: res/drawable-xhdpi/ic_launcher.png
SHA1-Digest: cIga++hy5wqjHl9IHSfbg8tqCug=
Name: AndroidManifest.xml
SHA1-Digest: oRzzLkwuvxC78suvJcAEvTqcjSA=
Name: res/drawable-mdpi/ic_launcher.png
SHA1-Digest: VY7kOF8E3rn8EUTvQC/DcBEN6kQ=
Name: res/drawable-hdpi/ic_launcher.png
SHA1-Digest: stS7pUucSY0GgAVoESyO3Y7SanU=
Name: res/layout/activity_main.xml
SHA1-Digest: Yr3img6SqiKB+1kwcg/Fga2fwcc=
Name: resources.arsc
SHA1-Digest: j1g8I4fI9dM9hAFKEtS9dHsqo5E=
Name: classes.dex
SHA1-Digest: Sci9MmGXNGnZ1d04rCrEEV7MWn4=
Name: res/drawable-xxhdpi/ic_launcher.png
SHA1-Digest: KKqaLh/DVvFp+v1KoaDw7xETvrI=
ÓÃ˽Կͨ¹ý RSA Ëã·¨¶Ô manifest ÀïµÄÕªÒªÐÅÏ¢½øÐмÓÃÜ£¬°²×°µÄʱºòÖ»ÄÜͨ¹ý¹«Ô¿½âÃÜ£¬½âÃÜÖ®ºó²ÅÄÜ»ñµÃÕýÈ·µÄÕªÒª£¬ÔÙ¶Ô±È
3.×îºó¾ÍÊÇÈçºÎÉú³É CERT.RSA£¬´ò¿ªÕâ¸öÎļþ¿´µ½µÄÊÇÂÒÂ룬˵Ã÷Õû¸öÎļþ¶¼±»±àÂë¼ÓÃÜÁË£¬¶øÇÒÕâ¸öÎļþºÍ¹«Ô¿ÓйØ
´ÓÔ´ÂëÖп´³öËûÊÇͨ¹ý PKCS7 ½«Õû¸öÎļþ¼ÓÃÜÁË
×ܽ᣺1.Ç©ÃûÖ»ÊǶÔÍêÕûÐÔºÍÇ©Ãû·¢²¼»ú¹¹µÄУÑé»úÖÆ 2.²»ÄÜ×èÖ¹ apk ±»Ð޸ģ¬Ö»ÊÇÇ©ÃûÎÞ·¨±£³ÖÒ»ÖÂ
3.²»Í¬Ë½Ô¿¶ÔÓ¦×Ų»Í¬µÄ¹«Ô¿£¬ÊµÖÊÉϲ»Í¬µÄ¹«Ô¿¾Í´ú±íÁ˲»Í¬µÄÇ©Ãû
3. Android ϵͳÈçºÎ»ñȡǩÃû
ÎÒÃÇ´Ó»ñÈ¡ÏÂÃæÒ»¶Î´úÂ뿪ʼ·ÖÎö£º
packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(),
PackageManager.GET_SIGNATURES );
Signature[] signs = packageInfo.signatures;
md5 = getMD5Str(signs[ 0].toByteArray());
context.getPackageManager()ÆäʵÄõ½µÄÊÇApplicationPackageManager |
¿´Ò»Ï context µÄʵÏÖÀà contextImpl ÀïµÄ getPackageManager()
@Override
public PackageManager getPackageManager() {
if (mPackageManager != null) {
return mPackageManager ;
}
IPackageManager pm = ActivityThread.getPackageManager
();
if (pm != null) {
// Doesn't matter if we make more than one instance.
return (mPackageManager = new ApplicationPackageManager(this,
pm));
}
return null ;
}
|
¿ÉÒÔ¿´µ½ ActivityThread Öз½·¨ getPackageManager
»ñÈ¡ IPackageManager
¼ÌÐø¿´ ActivityThread µÄ´úÂ룺
public static IPackageManager getPackageManager()
{
if (sPackageManager != null) {
//Slog.v("PackageManager", "returning
cur default = " + sPackageManager);
return sPackageManager ;
}
IBinder b = ServiceManager.getService("package");
//Slog.v("PackageManager", "default service
binder = " + b);
sPackageManager = IPackageManager.Stub.asInterface(b);
//Slog.v("PackageManager", "default service
= " + sPackageManager);
return sPackageManager;
} |
¿´Ô´ÂëÖªµÀÊÇͨ¹ý ServiceManager.getService(¡°package¡±);»ñÈ¡
PackageManagerService ²¢µÃµ½ IBinder¶ÔÏó£¬È»
ͨ¹ý asInterface º¯ÊýÈ¡µÃ½Ó¿ÚÀà IPackageManager
ʵÀý
È»ºó×÷Ϊ²ÎÊý¹¹Ôì ApplicationPackageManager
ÔÙ¿´ ApplicationPackageManager Õâ¸öÀàÀïµÄ·½·¨£º
@Override
public PackageInfo getPackageInfo(String packageName,
int flags)
throws NameNotFoundException {
try {
PackageInfo pi = mPM.getPackageInfo(packageName,
flags, mContext.getUserId());
if (pi != null) {
return pi;
}
} catch (RemoteException e) {
throw new RuntimeException( "Package manager
has died" , e);
}
throw new NameNotFoundException(packageName);
}
|
ÕâÀïµÄmPM¾ÍÊÇÉÏÃæ¹¹Ô캯Êý´«½øÀ´µÄ IPackageManager£¬¾Í¿ÉÒÔµ÷ÓÃ
PackageManagerService µÄ·½·¨ÁË
ÏÂͼÊÇ PackagerManager ¾²Ì¬Àà½á¹¹Í¼£º

ok£¬¿´ÍêÉÏͼµÄ½á¹¹Í¼£¬¼ÌÐø¸ú´úÂë £¬¿´µ½ÕâÀïÊÇ mPM ¼ÌÐøµ÷ÓõÄgetPackageInfo£¨´úÀíģʽ£©£¬Í¨¹ý½ø³ÌͨÐŵ½
PackageManagerService ÖÐÖ´ÐÐÏìÓ¦²Ù×÷
@Override
public PackageInfo getPackageInfo(String packageName,
int flags, int userId) {
if (!sUserManager.exists(userId)) return null;
enforceCrossUserPermission(Binder.getCallingUid (),
userId, false, "get package info");
// reader
synchronized (mPackages) {
PackageParser.Package p = mPackages.get(packageName);
if (DEBUG_PACKAGE_INFO)
Log.v (TAG, "getPackageInfo " + packageName
+ ": " + p);
if (p != null) {
return generatePackageInfo(p, flags, userId);
}
if((flags & PackageManager. GET_UNINSTALLED_PACKAGES
) != 0) {
return generatePackageInfoFromSettingsLPw(packageName,
flags, userId);
}
}
return null ;
} |
ÕâÀï mPackages ÊÇ hashMap£¬Æäµ÷ÓÃput·½·¨µÄʱ»úÊÇÔÚ
scanPackageLI ·½·¨ÖУ¬¶ø scanPackageLI µÄµ÷Óõط½ÊÇÔÚ³ÌÐò°²×°ºÍÌæ»»º¯ÊýÖУ¬»¹ÓоÍÊÇ
scanDirLi ÖУ¬´úÂëÂÔ¡£
scanDirLi ÊÇÓÃÀ´É¨ÃèһЩϵͳĿ¼µÄµÄ£¬ÔÚ PackageManagerService
µÄ¹¹Ô캯ÊýÖе÷ÓõÄ
File dataDir = Environment. getDataDirectory(); mAppDataDir = new File(dataDir, "data"); mAppInstallDir = new File(dataDir, "app"); mAppLibInstallDir = new File(dataDir, "app-lib" ); mAsecInternalPath = new File(dataDir, "app-asec" ).getPath(); mUserAppDataDir = new File(dataDir, "user"); mDrmAppPrivateInstallDir = new File(dataDir, "app-private" ); |
ÉÏÃæÊÇɨÃèµÄλÖáü¡ü¡ü¡ü¡ü¡ü¡ü
PackageManagerService ´¦Àí¸÷ÖÖÓ¦Óõݲװ¡¢Ð¶ÔØ¡¢¹ÜÀíµÈ¹¤×÷£¬¿ª»úʱÓÉ systemServer
Æô¶¯´Ë·þÎñ¡£¾ÍÊÇ˵֮ǰ°²×°¹ýµÄÓ¦ÓûòÕßϵͳӦÓÃÐÅÏ¢¶¼»áÔÚ¿ª»úɨÃè¹ý³ÌÖд浽 mPackages Õâ¸ö hashMap
ÖС£¿ª»úºóÓû§µÄ°²×°²Ù×÷Ò²»áͬÑù´æµ½Õâ¸ö hashMap ÀïÃæ¡£
¼ÌÐø¿´ getPackageInfo£¬µ÷ÓÃµÄ generatePackageInfo
£¬ ÀïÃæµ÷ÓõÄÊÇ PackageParser ÖÐµÄ generatePackageInfo£¬¼ÌÐø¸úÕâ¸öº¯ÊýµÄ´úÂë±È½Ï³¤£¬Ö»Ìù³ö²¿·Ö¹Ø¼ü´úÂ룺
if ((flags&PackageManager. GET_SIGNATURES ) != 0) { int N = (p.mSignatures != null) ? p.mSignatures.length : 0; if (N > 0) { pi.signatures = new Signature[N]; System.arraycopy (p.mSignatures, 0, pi. signatures, 0 , N); } } return pi; |
Õâ¶Î´úÂë֮ǰÖ÷ÒªÊÇ×öһЩ¸´ÖƵIJÙ×÷£¬¾ÍÊÇ new Ò»¸ö PackageInfo£¬È»ºó°Ñ
PackageParser.Package ¶ÔÏóÖеÄһЩÄÚÈݸ´ÖƵ½Õâ¸ö PackageInfo ÖÐ
´ÓÕâ¶Î´úÂë¿ÉÒÔ¿´³öÀ´£¬×îÖյõ½µÄ signatures ÐÅÏ¢¾ÍÊÇÖÐ p£¨PackageParser.Package
£©ÖеijÉÔ± mSignatures ÖеÃÀ´µÄ¡£ºÃÁË£¬ÏÖÔÚ¾ÍÊÇ¿´Õâ¸öPackageParser.PackageÊÇ´ÓÄÄÀ´µÄÁË£¬Í¨¹ý¸ú×Ù´úÂ룬installPackageLI
ºÍ scanPackageLI ÖÐµÄ final PackageParser.Package pkg =
pp.parsePackag (tmpPackageFile, null, mMetrics, parseFlags);ÕâÐдúÂëÖ»ÊÇÉú³ÉÁË
pkg£¬²¢Ã»Óи³ÖµÀïÃæµÄ mSignatures£¬¼ÌÐø¸ú×Ù£¬ÕÒµ½º¯Êý collectCertificatesLI£¬ÕÒµ½
pp.collectCertificates(pkg , parseFlags)
PS:×îÖÕÓÖ½øÐÐÁËһϵÁеĸú´úÂ룬ÕÒµ½ÁË JarVerifier.java Õâ¸öÀàµÄ readCertificates
Õâ¸ö¾ÍÊÇÓÃÀ´¶ÁÈ¡.RSA ÎļþµÄ,×îÖÕÎÒÃÇ¿´µ½µÄÀïÃæµÄ´úÂëÊÇͨ¹ý loadCertificates È¡µÃµÄ
certs ¸³Öµ¸øÁË pkg.mSignatures
ÖÁ´Ë£¬»ñȡǩÃûµÄËùÓÐÂß¼¾ÍËãÊǼòµ¥µÄ¹ýÒ»±éÁË£¬ÒÔÏÂÊǼòÂÔÁ÷³Ìͼ£º£¨·¢ÏÖ ppt »Í¼±È Windows
»Í¼¹¤¾ßºÃÓöàÁË£¬¹þ¹þ£©

ÔÚ¸ú´úÂëµÄ¹ý³ÌÖÐÒ²ÕÒµ½ÁËÇ©Ãû¶Ô±ÈµÄº¯Êý compareSignatures
£¬ÓпÕ×Ô¼º¿´¿´¾ÍºÃÁË¡£
OK£¬ÈÆÁËÕâô¾ÃÎÒÃÇÖÕÓÚÕÒµ½Ô´Í·ÁË£¬»ñȡǩÃû¾ÍÊÇÔÚ META-INF ÖÐѰÕÒ£¬²¢½âÎö¡£ÊÔÏëһϣ¬Èç¹ûÎÒÃÇÐÞ¸ÄÁËÕâ¸öº¯Êý£¬ÈÃËû½âÎöÔÀ´Õý°æµÄ
META-INF ÖÐµÄ CERT.RSA Îļþ£¬ÕâÑù¾Í¿ÉÒÔαÔìÎªÕæÕýµÄÇ©ÃûÁË¡£
ÄÇôÎÒÃǾÍÏëµ½ÁË HOOK£¬£¨ºÜ¶àÈ˶¼ÊÇ´Ó¿´Ñ©ÂÛ̳ÉÏÕÒµ½µÄһƪÎÄÕ¿´µ½µÄ http://bbs.pediy.com/showthread.php?t=186054£©
hook µÄÔÀ´¼òµ¥À´Ëµ¾ÍÊÇ£¬ÕÒµ½Ôº¯ÊýºÍк¯ÊýµÄÖ¸ÕëλÖã¬È»ºó¶Ò»»ÄÚÈÝ£¬½«Ðº¯ÊýÌæ´úÔº¯Êý¡£
¹ØÓÚ hook ÄØ£¬ÍøÉÏÒ²Óкܶà¿ò¼Ü¿ÉÒÔʹÓ㬱ÈÈ磺
1.Cydia substrate : http://www.cydiasubstrate.com/
2.Xposed : http://repo.xposed.info/
ÍøÉÏÒ²Óкܶà½Ì³Ì¿ÉÒÔ¿´¿´
ÎÚÔÆ£¨wooyun£©ÉÏÓÐһƪºÜÓÐÒâ˼µÄ½Ì³Ì£¬¾ÍÊÇÀûÓà hook ½øÐÐ΢ÐÅÔ˶¯×÷±×£¬ÔÌûµØÖ·http://drops.wooyun.org/tips/8416
ÏÂͼ¾ÍÊÇÎÒÓÃÁËÉÏÃæµÄ·½·¨²úÉúµÄЧ¹û£¬»¹²îµã±»Î¢ÐŲ¿ÃŵÄÈËÇëÈ¥ºÈ²è¡£
ÕâÀïÓõÄÊÇ Xposed ¿ò¼Ü£¬ÔÀí¾ÍÊÇ hook ÁËÊÖ»úµÄ¼Æ²½´«¸ÐÆ÷µÄ¶ÓÁк¯Êý£¬È»ºó°Ñ²½ÊýµÄ·µ»ØÖµÃ¿²½³Ë1000·µ»Ø£¬Ç°ÌáÊÇ£¬ÄãµÄÊÖ»úÓ²¼þ±¾ÉíÓмƲ½´«¸ÐÆ÷¹¦ÄÜ£¬ÕâÀï΢ÐÅÔ˶¯ÀïÃæÁгöÁËÖ§³ÖµÄÊÖ»úÁбíhttps://kf.qq.com/touch/sappfaq/151013AvyyeQ151013r63qmq.html?platform=15¡£ºÃÏñ×î¸ß¾ÍÊÇ98800ÁË£¬¿ÉÄÜÊÇ΢ÐÅ×öÁ˲½ÊýÏÞÖÆ°É
ÎÒÕâÀïÓõÄÊÇСÃ×4ÁªÍ¨°æ£¬·¢ÏÖËäÈ»ÊÇ1000»ùÊýµÄ¼Ó£¬µ«ÊǺÃÏñ¸ôÁ˺ܾòű仯£¬¹À¼ÆÓÖÊÇ MIUI ×öÁËһЩʡµç²ßÂÔ£¬´«¸ÐÆ÷µÄ²É¼¯×öÁË¶ÔÆë°É£¿
Xposed ¿ò¼Ü£¬ºÜ¶àÍæ»ú°®ºÃÕߣ¬»áÄÃËüÐÞ¸ÄһЩÖ÷Ì⣬×ÖÌåÖ®ÀàµÄ£¬»òÕßϵͳ½çÃæ£¬¶¨ÖÆ×Ô¼ºÏëÒªµÄϵͳ²å¼þµÈµÈ¡£È»¶ø£¬Ò²ÓÐȱµã£¬ÐèÒªÊÖ»úroot£¬¶øÇÒÕâ¸ö¿ò¼Ü£¬»¹ÓпÉÄÜÈÃÊÖ»ú±äש£¬»¹ÓеÄϵͳ¿ÉÄܶÔÕâ¸ö¿ò¼ÜÖ§³ÖµÄ²»ºÃ£¬»òÕß²»Ö§³Ö¡£XDA
ÂÛ̳ÀïÃæÒ²Óкܶà´óÉñ°Ñ Xposed ¶ÔijЩ»úÐÍ×öÁËÊÊÅ䣬´óÉñÒ»°ã¶¼ÊÇ˵£¬Èç¹ûÊÖ»ú±äשËûÃDz»¸ºÔ𣬹þ¹þ¡£
ÕýʽÓÉÓÚÕâЩ¿ò¼ÜµÄÖî¶à²»±ã£¬root µÈµÈµÄÎÊÌ⣬ÓÚÊǾÍÓÐÁËһЩ·Ç root µÄ hook µÄºÚ¿Æ¼¼£¬±ÈÈç°¢Àï°Í°ÍµÄ¿ªÔ´¿ò¼Ü
Dexposed£¨https://github.com/alibaba/dexposed£©ÆäÒ²ÊǸù¾Ý Xposed
¿ò¼ÜÐ޸ĶøÀ´µÄ£¬²»¹ý¿´ github ÉÏËûÃÇÒ²ºÃ¾Ãû¸üÐÂÁË¡£
Ò²ÓÐÏñÆäËû¸öÈËдµÄºÍÕâÖֱȽÏÀàËÆµÄ¿ò¼Ü£¬ÕâÀï¾Í²»½éÉÜÁË¡£µ«ÊÇÕâÀà¿ò¼ÜµÄȱµã¾ÍÊÇ£¬Ö»ÄÜÔڸýø³ÌÏÂhook£¬²»ÄÜÈ«¾Ö
hook£¬¼´Ö»¶ÔÕâ¸ö½ø³ÌµÄÓ¦ÓÃÆð×÷Ó㬲»ÄܶÔÁíÒ»¸öÓ¦ÓÃÆð×÷Óã¬ÓŵãÊÇ¿ÉÒÔ hook ×Ô¶¨Ò庯ÊýÒ²ÄÜhook
ϵͳº¯Êý£¬²¢ÇÒ²»Óà root ºÍÖØÆô¡£°¢ÀïÓÃÕâ¸ö¿ò¼ÜÀ´´òÔÚÏßÈȲ¹¶¡¡£
ÄǶÔÓÚ APP ÄÚ²¿Ç©ÃûУÑéµÄ¾Í²»ÓÃÔÙËÑÏàÓ¦µÄ´úÂëÁË£¬Ö±½Ó hook ¾ÍÒ»²½µ½Î»ÁË£¬android.app.ApplicationPackageManager
Õâ¸öÀàµÄ getPackageInfo Õâ¸ö·½·¨Ö±½Ó°ÑÕýÈ·µÄÇ©Ãû·µ»Ø¾ÍºÃÁË£¬½ÓÏÂÀ´ÎÒÃǾÍÐèÒª°Ñ hook
µÄ´úÂë×¢È뵽ij¸ö APP Àï¾ÍºÃÁË¡£
4. ¹ØÓÚÈçºÎ×¢È룿
¿ªÆªµÄʱºòÓиöͼƬ¾ÍÊÇÎÒÔÚÌÚѶµØÍ¼ÀïÃæ×¢ÈëÁËÒ»¸ö²ÔÀÏʦµÄͼƬÆäʵ¾ÍÊÇ£¬×Ô¼ºÐ´Á˸ö imageloader£¬ÓÃÀ´ÏÂÔØÍøÂçͼƬ£¬ÔÙд¸ö
activity »òÕß dialog À´³ÐÔØÕâ¸ö imageview£¬È»ºó±àÒ룬ÔÙ·´±àÒ룬ȡ³öÏàÓ¦µÄsmaliµÈÎļþ£¬±ÈÈçÌùµ½ÒѾ·´±àÒëºÃµÄÌÚѶµØÍ¼µÄÀïÃæ£¬°Ñ¿ªÆôÕâ¸ö²ÔÀÏʦͼƬÏÂÔØµÄÆô¶¯´úÂë·Åµ½ºÏÊÊλÖã¬×îºóÔÙ°ÑÌÚѶµØÍ¼ÖØÐ´ò°üÇ©Ãû£¬¾Íok
ÁË¡£
hook ´úÂëÒ²ÊÇͬÀí×¢È룬Ñé֤һϣ¬³É¹¦£¨ÎÒÕâ¿éдµÄ±È½Ï´ÖÂÔ£¬´úÂë±È½Ï¶à£¬Ö»ËµË¼Â·ÁË£©ÄÇôÕâÖÖ´úÂë×¢ÈëºÍ
hook Ïà½áºÏµÄ·½Ê½ÄܸÉÊ²Ã´ÄØ£¬ÎÒÃÇÒ²²»·Á¸ã³öµãÊÂÇéÀ´¡£Í¬ÑùÎÒÃÇ»¹ÊǽøÐÐ΢ÐÅÔ˶¯×÷±×µÄÊÂÇ飬ÆäʵºÜ¶àÔ˶¯ÀàµÄÈí¼þ¶¼¿ÉÒÔ°Ñ×Ô¼ºµÄÊý¾Ýͬ²½µ½Î¢ÐÅÔ˶¯À±ÈÈçСÃ×ÊÖ»·£¬ÀÖ¶¯Á¦£¬Ôö¯È¦µÈµÈ¡£
ÄÇÎÒÃǾÍÏÈÄÃÆäÖÐÒ»¸ö¿ªµ¶°É£º
¾¹ýһϵÁеĸú×Ù´úÂ붨룬×îÖÕ¶¨Î»µ½ÁËÕâ¸öÀà cn.ledongli.ldl.cppwrapper.DailyStats
ÀïµÄ f ·½·¨£¨f ÊÇÒòΪ´úÂë»ìÏýÁË£©È»ºóÎÒÃÇ×¢Èë²¢ hook ·½·¨£¬ÈÃËü·µ»Ø66666£¬ok£¬ÎÒÃÇ¿´µ½ÁËÈçÏÂЧ¹û£º
È»ºóÎÒÃÇÔÚÓ¦ÓÃÀïÃæµÇ½΢ÐÅÕ˺ţ¬ºÍ¶Ô½Óµ½Î¢ÐÅÔ˶¯µÄ¹¦ÄÜ£¬·¢ÏÖ²»ºÃÓã¬ÊÇÒòΪ£¬Î¢ÐÅÀïÃæ×öÁ˶ÔÓ¦ÓõÄÇ©ÃûУÑ飬ӦÓõÄÇ©ÃûÒѾ±äÁË
ËùÒÔÎÒÃÇÖ»ÄÜÆÆ½â΢ÐÅÁË£¨ÃÆÉù×÷´óËÀ£©£¬Í¬Ñù×¢Èë hook ´úÂ룬ÈÃ΢ÐÅ»ñȡӦÓõÄÇ©ÃûµÄʱºòÈ¡µÃÕýÈ·Ç©Ãû£¬¹Ø¼ü´úÂ룺
if( packageName.equals( "cn.ledongli.ldl")){ if ( result instanceof PackageInfo) { PackageInfo info = (PackageInfo) result; info. signatures[0] = new Signature( myHexLedongli); param.setResult( info); } } |
ÔÙ°ÑÕâ¸öµÁ°æµÄ΢ÐÅÖØÐ´ò°üÇ©Ãû£¬ÖØÐ½øÐÐÓ¦ÓõÄͬ²½Êý¾Ý²Ù×÷£¬ÔÙ½øÎ¢ÐÅÔ˶¯¿´¿´£¬ÊDz»ÊÇÒѾ66666ÁË¡£ÖÁ´Ë×÷±×Íê³É¡£
¡á¡á¡á¡á¡á¡á¡á¡á¡á¡áÎÒÊÇ»·ç²»Í¬µÄ·Ö¸îÏß¡á¡á¡á¡á¡á¡á¡á¡á¡á¡á¡á¡á
˵ÁËÕâô¶àÆÆ½âµÄ£¬Ò²¸ÃÁÄÁÄ·ÀÆÆ½âµÄÁË
google ×îÔç¸øµÄ¾ÍÊÇ´úÂë»ìÏýµÄ·½°¸£¬Æäʵһ°ãµÄ»ìÏýÖ»ÊǽµµÍÁË´úÂëµÄ¿É¶ÁÐÔ£¬ÈÃÄã¶Ô·´±àÒë³öÀ´µÄº¯ÊýÃüÃûµÈ²»ÖªµÀʲôÒâ˼£¬²»¹ý½â¶Á³öÀ´Ö»ÊÇʱ¼äÎÊÌâ¡£ºóÀ´»¹ÓÐ×ÊÔ´»ìÏýµÄ£¬µ«ÊÇÒâÒå²»´ó¡£
ºóÀ´ÓÐÁ˺ËÐÄ´úÂëÓà C ʵÏÖ£¬Ð´³É SO£¬¼Ó»¨Ö¸ÁîµÄ°ì·¨£¬Õâ¸ö°ì·¨È·Êµ»á×èÖ¹Ò»´ó²¿·ÖÈ˵ļÌÐøÆÆ½â£¬µ«ÊǶÔÓÚ¾³£×öÄæÏòµÄ¹¤³ÌʦÀ´ËµÒ²²»ÊÇʲôÄÑÌâ¡£
Æäʵ×öÕâô¶à´ó¶àÊýÈí¼þµÄ³õÖÔ¾ÍÊDz»ÏëÈí¼þ±»µÁ°æ£¬È»ºó±»×¢ÈëÂÒÆß°ËÔãµÄ¹ã¸æ£¬»òÕß±»µÁÈ¡ÐÅÏ¢µÈ£¬ºóÀ´¾ÍÓÐÁ˵Á°æ¼ì²â»úÖÆ¡£±ÈÈ磺JAVA
²ãµÄÇ©ÃûУÑ飬NDK ²ãУÑ飬·Ö¶Î´æ·ÅÇ©Ãû Hash ´®£¬·þÎñÆ÷УÑéµÈµÈ£¬µ«ÊÇÕâЩ·½·¨ÎÒ¶¼ÔÚÉÏÃæËµÁËÆÆ½â·½·¨
ÏÖÔÚ¹úÄÚµÄÒ»°ãÓ¦ÓÃÊг¡¶¼ÓÐ¶Ô APP Ç©ÃûµÄ¼ì²â£¬ÔÚÄãÏÂÔØµÄʱºò»á¸æËßÄãÕâ¸ö APP ÊDz»ÊǵÁ°æµÄ£¬´Ó¶øÈÃÓû§Çø·Ö³öÀ´¡£µ«ÊÇÓ¦ÓÃÊг¡×Ô¼º±¾ÉíÓÖ±»µÁ°æÁËÔõô°ìÄØ£¿
ÔÙºóÀ´£¬¾ÍÓÐÁËÏñ360¼Ó¹Ì±£ºÍÌÚѶµÄÀ̵ֹȲúÆ·£¬so ×öÁ˼ÓÃÜ£¬ÕæÕýµÄ dex Ò²²ØÆðÀ´ÁË£¬²»¹ý¸öÈ˾õµÃ£¬¾ÍËãÕæÕýµÄ
dex Ò²ÐèÒª±ä³É odex ÁË£¬root µÄÊÖ»úÈ¡µ½ odex£¬ÔÙת»Ø dex£¬¾ÍÄÜÄõ½ÕæÕýµÄ dex£¨ËäÈ»ÎÒûÊÔ¹ý£¬µ«ÊÇÎÒ¾õµÃ¿ÉÄÜÊÇÒ»¸ö˼·£©£¬ËùÒÔÕâ¸ö·½·¨¾Í¸üÄÑÆÆ½âÁË
ËäÈ»¼Ó¹Ì²úÆ·ºÜÀ÷º¦£¬µ«ÊÇÒ²»áÓÐËûµÄȱÏÝ£¬Android ϵͳ²»¶ÏµÄ¸üÐÂÉý¼¶£¬Ò²Ðí¾Í»»ÁËijЩģʽµÈµÈ£¬±ÈÈç
ART ¸Õ³öÀ´µÄʱºò£¬¼Ó¹Ì±£¼Ó¹ÌºóµÄ Apk£¬ÔÚ ART ģʽÔËÐÐϾͻá Crash¡£ÕâЩ¼Ó¹Ì²úÆ·Òª²»¶ÏµÄÊÊÅä¸÷ÖÖÐͺŵÄÊÖ»ú£¬CPU
ÀàÐÍ£¬ÔËÐÐģʽµÈµÈ£¬ËùÒԺܶà APP ΪÁË¿¼ÂǼæÈÝÐÔ£¬ËûÃÇÒ²²»»áÇáÒ×È¥¼Ó¹Ì×Ô¼ºµÄ²úÆ·¡£
¡á¡á¡á¡á¡á¡á¡á¡á¡á¡áÎÒÊÇ»·ç²»Í¬µÄ·Ö¸îÏß¡á¡á¡á¡á¡á¡á¡á¡á¡á¡á¡á¡á
¹ØÓÚÄæÏòÆÆ½â Android Ó¦Óã¬ÎÒ¾õµÃÄÍÐĺÜÖØÒª°É£¬´úÂë¸úÀ´¸úȥȷʵºÜ¿ÝÔ×ܽἸµãС¼¼ÇɰÉ
1.ÐÅÏ¢·´À¡£ºÍ¨¹ý½çÃæµÄһЩµ¯³öÐÅÏ¢£¬½çÃæÌØµãѰÕÒÍ»ÆÆµã
2.ÌØÕ÷º¯Êý£º±ÈÈçËÑ Toast£¬Log£¬getSignature µÈ
3.´úÂë×¢È룺°Ñ toast »òÕß log º¯Êý×¢Èëµ½³ÌÐòÖУ¬¸ú×ÙλÖÃ
4.´òÓ¡¶ÑÕ»£º²åÈë new Exception(¡°¶¨Î»¡±).printStackTrace();
5.ÍøÂç×¥°ü£ºÍ¨¹ý×¥°üµÃµ½µÄ¹Ø¼ü×ֶΣ¬ÔÚ´úÂëÖж¨Î»
дÔÚºóÃæ£º
ÕâÆªÎÄÕÂÕûÀíÁËÓÐÒ»¶Îʱ¼äÁË£¬¾õµÃ»¹ÊÇÓ¦¸Ãд³öÀ´£¬Ò²²»ÊÇʲô¸ßÉîµÄ¼¼ÊõÎÄÕ£¬¾ÍÊǸöÈË×ܽáµÄÒ»µãÐĵöøÒÑ¡£
¹ØÓÚÆÆ½âÓ¦ÓúܶàÈË¿ÉÄÜ»áÈ¥ÆÆ½â±ðÈ˵ÄÓ¦ÓÃ×¢Èë¹ã¸æÀ´»ñÈ¡ÀûÒæ£¬Ò²ÓпÉÄܵÁÈ¡±ðÈ˵ÄÐÅÏ¢¡£
²»¹ýÎÒÃÇ×÷ΪÓнڲٵĿª·¢¹¤³Ìʦ£¬Ó¦¸Ã±¾×ÅÈðÑ©µÄ¾«Éñ¿´´ý¼¼Êõ£¬Ñ§Ï°¼¼Êõ£¬¶ø²»ÊÇÂÒ¡á¸ã¡£µ«ÊÇÎÒÃÇÒ²Ó¦¸ÃÖªµÀ£¬ÎÒÃǵÄÓ¦ÓÃÓпÉÄܻᱻ±ðÈËÔõô¸ã¡¡
×îºóÍÆ¼öÒ»±¾×ÊÁÏÊ飬´ó¼Ò¿ÉÒÔÓпտ´¿´¡£
Èç¹ûÄã¾õµÃÄÚÈÝÒâÓÌδ¾¡£¬Èç¹ûÄãÏëÁ˽â¸ü¶àÏà¹ØÐÅÏ¢£¬ÇëɨÃèÒÔ϶þάÂ룬¹Ø×¢ÎÒÃǵĹ«ÖÚÕ˺ţ¬¿ÉÒÔ»ñÈ¡¸ü¶à¼¼ÊõÀà¸É»õ£¬»¹Óо«²Ê»î¶¯ÓëÄã·ÖÏí~
Bugly
|