|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
很简单OBJCAVFoundation---播放视频相关的库最近正在学习这些算是学iOS开发的一些方法(前三节有关背景先容请至:《Android玩乐系列:修正汇编代码撑持原生高清来电年夜头贴(一)》)
4、修正前的筹办事情
=======
这里先容一些Android上的逆向工程的基本。起首,我们要操纵Phone.apk,它实在也就是一个.zip文件,个中包含四个次要信息:
-资本文件:res*.*和resources.arsc
-代码文件:classes.dex
-使用形貌:AndroidManifest.xml
-署名信息:META-INF*.*
apktool这个工具能够处置前三种数据,而署名信息则必需利用一个signapk.jar(有些工具包称为AutoSign)。
1)解包(缺省至Phone目次)
apktoold-fPhone.apk
注重我们接上去的修正都不会动到资本,以是现实上也能够不解开个中的资本文件。能够如许利用命令行:
apktoold-f-rPhone.apk
如许在编译归去的时分会快一点,并且也能够制止一些毛病。——但良多时分的修正必要对比着资本文件来看,以是你也能够解一份有资本文件的版本放在中间作参照。
2)编译回.apk(指定从Phone目次)
apktoolb-fPhonePhone2.apk
3)对Phone2.apk加署名
java-jarsignapk.jarplatform.x509.pemplatform.pk8Phone2.apkPhone2_signed.apk
注重这时候利用的署名文件为platform.x509.pem和platform.pk8,而不是我们寻常用的testkey*.*。这是很关头的一处:Phone.apk必需利用platform.*来署名。
5、修正:开端
=======
我们将Phone.apk解到Phone目次以后。能够找到以下子目次:
Phonesmalicomandroidphone
我们接上去次要修正两个文件:
CallCard.smali
InCallScreen.smali
注重这里的*.smali是另外一种格局的源代码,它反编译自Dalvik假造机中实行码(opcode)。基础上,你能够以为这*.smali就是汇编代码(基于存放器的假造机引擎)。好吧,但我们既然要“原生的”,那末就只好来改改这些汇编代码了。:(
1)对InCallScreen.smali只必要做一处修正
---------
找到:
- .fieldprivatemMainFrame:Landroid/view/ViewGroup;
改成:
- .fieldpublicmMainFrame:Landroid/view/ViewGroup;
我们必要在CallCard.smali中会见这个成员,以是它必需是公然的(public)。
2)修正CallCard.smali,针对updateDisplayForPerson()办法
---------
找到:
- .methodprivateupdateDisplayForPerson(Lcom/android/internal/telephony/CallerInfo;...
在该办法中,找到独一一处showCachedImage()挪用:
- invoke-static{v0,v1},Lcom/android/phone/CallCard;->showCachedImage(Landroid/widget/ImageView;Lcom/android/internal/telephony/CallerInfo;)Z
- move-resultv4
- if-nezv4,:cond_2
注重两点,一是我们要修正这个:
以是要先记下这个cond_2。第二点,下面的v0,v1,v4大概在详细的代码中有所分歧,这也要寄望,查找时不克不及根据这些存放器。而修正时,也要注重存放器的抵触和利用,有修正履历的就未几言了;没有履历的,则要细心回忆一下汇编言语的常识。
接上去,我们修改上述一行,使之酿成为:
- ##===》》》
- if-eqzv4,:cond_20
- move-object/from16v0,p0
- move-object/from16v5,p4
- invoke-virtual{v0,v1,v5},Lcom/android/phone/CallCard;->showCachedBackground(Lcom/android/internal/telephony/CallerInfo;Lcom/android/internal/telephony/Call;)Z
- move-resultv4
- goto:cond_2
- :cond_20
- ##endfix.
这里,if-nez酿成了if-eqz,而:cond_20这一标签用于拔出一段代码,当这些代码实行完成时,仍旧会到:
这就是下面要记着cond_2的缘故原由。至于:cond_20是能够随便取的,编译程序是按16进制主动升序来编号这些标签,而0x20号标签一样平常已对照年夜了,不会与现有的标签抵触。固然,写成cond_30或cond_50也行的。
别的,这里还必需要注重v0,v5,v1和v4这四个存放器的利用,必需参考这里的代码高低文为决意利用哪些个余暇的存放器。个中v1是承继利用了后面的存放器值,假如此前v1中不是放着CallerInfo的话,则要依据高低文再调剂。归正,假如存放器用错了的话……哈哈……Crash~~
【注:有一个复杂的办法能够制止用错存放器的成绩,就是在将办法入手下手处的.localsnnn这里的nnn值改年夜几个,必要用几个存放器,就加上几个。然后在我们拔出的代码中,只利用最初的这几个存放器号,也就不会抵触了。比方本来是.locals4,改成.locals8,则v4,v5,v6,v7这新增加的4个存放器号,就老是平安的。】
3)修正CallCard.smali,针对updatePhotoForCallState()办法
---------
这里的修正与上一例是类似的,只不外是针对updatePhotoForCallState()办法罢了。找到:
- invoke-static{v9,v3},Lcom/android/phone/CallCard;->showCachedImage(Landroid/widget/ImageView;Lcom/android/internal/telephony/CallerInfo;)Z
- move-resultv9
- if-nezv9,:cond_2##《《《《===修正此处
修改下面最初一行。酿成:
- ##===》》》
- if-eqzv9,:cond_20
- move-object/from16v5,p1
- invoke-virtual{p0,v3,v5},Lcom/android/phone/CallCard;->showCachedBackground(Lcom/android/internal/telephony/CallerInfo;Lcom/android/internal/telephony/Call;)Z
- move-resultv9
- goto:cond_2
- :cond_20
- ##endfix.
4)增加新下面代码所必要的办法:showCachedBackground()
---------
下面两段函数都挪用了一个办法,这个showCachedBackground()是我们这里“来电全屏年夜头贴”的次要功效完成代码。别的的修正,实在只是插个桩罢了。代码以下,把它间接插到CallCard.smali这个文件的某个办法前/前面就能够了(我一样平常将它放在showCachedImage()函数声明的前面):
- ##
- ##【主函数:更新全屏年夜头贴】
- ##
- .methodpublicshowCachedBackground(Lcom/android/internal/telephony/CallerInfo;Lcom/android/internal/telephony/Call;)Z
- .locals6
- .parameter"ci"
- .parameter"call"
- .prologue
- invoke-virtual{p2},Lcom/android/internal/telephony/Call;->getState()Lcom/android/internal/telephony/Call$State;
- move-result-objectv0
- invoke-virtual{v0},Lcom/android/internal/telephony/Call$State;->isAlive()Z
- move-resultv0
- if-nezv0,:cond_0
- :goto_0
- returnv0
- :cond_0
- if-nezp1,:cond_1
- :goto_1
- const/4v0,0x0
- goto:goto_0
- :cond_1
- iget-booleanv2,p1,Lcom/android/internal/telephony/CallerInfo;->isCachedPhotoCurrent:Z
- if-eqzv2,:goto_1
- iget-objectv2,p1,Lcom/android/internal/telephony/CallerInfo;->cachedPhoto:Landroid/graphics/drawable/Drawable;
- if-eqzv2,:goto_1
- iget-objectv3,p0,Lcom/android/phone/CallCard;->mInCallScreen:Lcom/android/phone/InCallScreen;
- const/16v4,0xF0
- invoke-virtual{v2},Landroid/graphics/drawable/Drawable;->getIntrinsicWidth()I
- move-resultv5
- if-ltv5,v4,:goto_1
- const/16v4,0xF0
- invoke-virtual{v2},Landroid/graphics/drawable/Drawable;->getIntrinsicHeight()I
- move-resultv5
- if-ltv5,v4,:goto_1
- iget-objectv3,v3,Lcom/android/phone/InCallScreen;->mMainFrame:Landroid/view/ViewGroup;
- if-eqzv3,:goto_1
- invoke-virtual{v3,v2},Landroid/view/ViewGroup;->setBackgroundDrawable(Landroid/graphics/drawable/Drawable;)V
- const/16v2,0x8
- iget-objectv3,p0,Lcom/android/phone/CallCard;->mPhoto:Landroid/widget/ImageView;
- invoke-virtual{v3,v2},Landroid/widget/ImageView;->setVisibility(I)V
- ##const/16v2,0x0
- ##invoke-virtual{p0,v2},Lcom/android/phone/CallCard;->setPersonInfoStyle(Z)V
- goto:goto_0
- .endmethod
6、对开端修正的申明
=======
除2、3步中的插桩代码以外,全部功效实在就依附一个完整手写汇编的showCachedBackground()。它必要操纵到以后类CallCard的
- CallCard.InCallScreen.mMainFrame
成员。而该成员在InCallScreen类中被声明为private,以是必要在第1步中把InCallScreen中的该声明改成public。
showCachedBackground()的思绪很复杂。因为CallCard.smali老是要从“接洽人”中装载头像,而此前我们已用“HDContactPhotos”把这个头像存成了“高清、全屏年夜头贴(图片)”,那末就只需将这个掏出来的头像贴在背景上就能够了。
高清全屏来电年夜头贴,不就是把年夜头贴在背景上嘛。^^.
以是在剖析全部Phone.apk时,我发明它底本取到一个mPhoto以后,为了便于显现就将它存在CallerInfo.cachedPhoto里了。既云云,那末在原有流程的updatePhotoForCallState()与updateDisplayForPerson()办法中,当它挪用showCachedImage()来显现了图片以后,我们也就只必要把这个图片在背景上“贴”一下就能够了。
而这个背景,就是:CallCard.InCallScreen.mMainFrame
很复杂嘛。
下面的showCachedBackground()汇编代码翻译成java代码就是:
- publicbooleanshowCachedBackground(CallerInfoparamCallerInfo,CallparamCall)
- {
- //德律风是在用形态(来电或呼出或接通)
- booleanbool=paramCall.getState().isAlive();
- //paramCallerInfo.isCachedPhotoCurrent无效
- bool=bool&&(paramCallerInfo!=null)&¶mCallerInfo.isCachedPhotoCurrent;
- if(bool){
- DrawablelocalDrawable=paramCallerInfo.cachedPhoto;
- if((localDrawable.getIntrinsicWidth()<240)||(localDrawable.getIntrinsicHeight()<240)){
- bool=false
- }
- else{
- //置mMainFrame的背景
- this.mInCallScreen.mMainFrame.setBackgroundDrawable(localDrawable);
- //使mPhoto不显现(本来的头像就不用显现了嘛)
- this.mPhoto.setVisibility(8);
- //修正作团体信息的显现作风(备用,后文注释)
- //setPersonInfoStyle(false);
- }
- }
- returnbool;
- }
继承自相应的不可变类比如NSMutableArray继承自NSArray他们都添加了可以改变对象内容的方法比如-(void)addObject:(id)anObject添加对象-(void)removeObject:(id)anObject删除对象上面只是一个大概的总结 |
|