九色国产,午夜在线视频,新黄色网址,九九色综合,天天做夜夜做久久做狠狠,天天躁夜夜躁狠狠躁2021a,久久不卡一区二区三区

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
Android安全攻防戰(zhàn),反編譯與混淆技術(shù)完全解析(上)

轉(zhuǎn)載請注明出處:http://blog.csdn.net/guolin_blog/article/details/49738023
之前一直有猶豫過要不要寫這篇文章,畢竟去反編譯人家的程序并不是什么值得驕傲的事情。不過單純從技術(shù)角度上來講,掌握反編譯功能確實(shí)是一項(xiàng)非常有用的技能,可能平常不太會(huì)用得到,但是一旦真的需要用到的了,而你卻不會(huì)的話,那就非常頭疼了。另外既然別人可以反編譯程序,我們當(dāng)然有理由應(yīng)該對(duì)程序進(jìn)行一定程度的保護(hù),因此代碼混淆也是我們必須要掌握的一項(xiàng)技術(shù)。那么最近的兩篇文章我們就圍繞反編譯和混淆這兩個(gè)主題來進(jìn)行一次完全解析。


反編譯

我們都知道,Android程序打完包之后得到的是一個(gè)APK文件,這個(gè)文件是可以直接安裝到任何Android手機(jī)上的,我們反編譯其實(shí)也就是對(duì)這個(gè)APK文件進(jìn)行反編譯。Android的反編譯主要又分為兩個(gè)部分,一個(gè)是對(duì)代碼的反編譯,一個(gè)是對(duì)資源的反編譯,我們馬上來逐個(gè)學(xué)習(xí)一下。
在開始學(xué)習(xí)之前,首先我們需要準(zhǔn)備一個(gè)APK文件,為了尊重所有開發(fā)者,我就不拿任何一個(gè)市面上的軟件來演示了,而是自己寫一個(gè)Demo用來測試
這里我希望代碼越簡單越好,因此我們建立一個(gè)新項(xiàng)目,在Activity里加入一個(gè)按鈕,當(dāng)點(diǎn)擊按鈕時(shí)彈出一個(gè)Toast,就這么簡單,代碼如下所示:

public class MainActivity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        Button button = (Button) findViewById(R.id.button);        button.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                Toast.makeText(MainActivity.this, "you clicked button", Toast.LENGTH_SHORT).show();            }        });    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

activity_main.xml中的資源如下所示:

<?xml version="1.0" encoding="utf-8"?><RelativeLayout    xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:paddingBottom="@dimen/activity_vertical_margin"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin">    <Button        android:id="@+id/button"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="Button"/></RelativeLayout>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

然后我們將代碼打成一個(gè)APK包,并命名成Demo.apk,再把它安裝到手機(jī)上,結(jié)果如下所示:


好的,到這里準(zhǔn)備工作就已經(jīng)基本完成了,接下來就讓我們開始對(duì)這個(gè)Demo程序進(jìn)行反編譯吧。

反編譯代碼

要想將APK文件中的代碼反編譯出來,我們需要用到以下兩款工具:

將這兩個(gè)工具都下載好并解壓,然后我們就開始對(duì)Demo程序進(jìn)行反編譯。解壓dex2jar壓縮包后,你會(huì)發(fā)現(xiàn)有很多個(gè)文件,如下圖所示:


其中我們要用到的是d2j-dex2jar.bat這個(gè)文件,當(dāng)然如果你是linux或mac系統(tǒng)的話就要用d2j-dex2jar.sh這個(gè)文件。
然后我們將Demo.apk文件也進(jìn)行解壓,如果不知道怎么直接解壓的可以先將文件重命名成Demo.zip,然后用解壓軟件打開。解壓之后你會(huì)發(fā)現(xiàn)里面有一個(gè)classes.dex文件,如下圖所示:

這個(gè)classes.dex文件就是存放所有java代碼的地方了,我們將它拷貝到dex2jar解壓后的目錄下,并在cmd中也進(jìn)入到同樣的目錄,然后執(zhí)行:

d2j-dex2jar classes.dex
  • 1
  • 1

執(zhí)行結(jié)果如下圖所示:


沒有報(bào)任何錯(cuò)誤,這就說明我們已經(jīng)轉(zhuǎn)換成功了。現(xiàn)在觀察dex2jar目錄,你會(huì)發(fā)現(xiàn)多了一個(gè)文件,如下圖所示:

可以看到,classes-dex2jar.jar這個(gè)文件就是我們借助工具之后成功轉(zhuǎn)換出來的jar文件了。但是對(duì)于我們而言,jar文件也不是可讀的,因此這里還需要再借助一下jd-gui這個(gè)工具來將jar文件轉(zhuǎn)換成java代碼。
下面就很簡單了,使用jd-gui工具打開classes-dex2jar.jar這個(gè)文件,結(jié)果如下圖所示:

OK,由此可見,我們的代碼反編譯工作已經(jīng)成功了,MainActivity中的代碼非常清晰,基本已經(jīng)做到了90%以上的還原工作。但是如果想要做到100%的代碼還原還是非常有難度的,因?yàn)橄駍etContentView()方法傳入的參數(shù),其實(shí)就是一個(gè)資源的id值而已,那么這里反編譯也就只能將相應(yīng)的id值進(jìn)行還原,而無法變成像R.layout.activity_main這樣直觀的代碼展示。
另外,除了MainActivity之外,還有很多其它的代碼也被反編譯出來了,因?yàn)楫?dāng)前項(xiàng)目有引用support-v4和support-v7的包,這些引用的library也會(huì)作為代碼的一部分被打包到classes.dex文件當(dāng)中,因此反編譯的時(shí)候這些代碼也會(huì)一起被還原。
好的,學(xué)完了反編譯代碼,接下來我們看一下如何反編譯資源。

反編譯資源

其實(shí)細(xì)心的朋友可能已經(jīng)觀察到了,剛才Demo.apk的解壓目錄當(dāng)中不是已經(jīng)有資源文件了嗎,有AndroidManifest.xml文件,也有res目錄。進(jìn)入res目錄當(dāng)中,內(nèi)容如下圖所示:


這不是所有資源文件都在這里了么?其實(shí)這些資源文件都是在打包的時(shí)候被編譯過了,我們直接打開的話是看不到明文的,不信的話我們打開AndroidManifest.xml文件來瞧一瞧,內(nèi)容如下圖所示:

可以看到,這代碼是完全沒法閱讀的。當(dāng)然如果你去打開activity_main.xml看看,結(jié)果也不會(huì)好到哪兒去:

由此可見,直接對(duì)APK包進(jìn)行解壓是無法得到它的原始資源文件的,因此我們還需要對(duì)資源進(jìn)行反編譯才行。
要想將APK文件中的資源反編譯出來,又要用到另外一個(gè)工具了:

關(guān)于這個(gè)工具的下載我還要再補(bǔ)充幾句,我們需要的就是apktool.bat和apktool.jar這兩個(gè)文件。目前apktool.jar的最新版本是2.0.3,這里我就下載最新的了,然后將apktool_2.0.3.jar重命名成apktool.jar,并將它們放到同一個(gè)文件夾下就可以了,如下圖所示:


接下來的工作就很簡單了,我們將Demo.apk拷貝到和這兩個(gè)文件同樣的目錄當(dāng)中,然后cmd也進(jìn)入到這個(gè)目錄下,并在cmd中執(zhí)行如下命令:

apktool d Demo.apk
  • 1
  • 1

其中d是decode的意思,表示我們要對(duì)Demo.apk這個(gè)文件進(jìn)行解碼。那除了這個(gè)基本用法之外,我們還可以再加上一些附加參數(shù)來控制decode的更多行為:

  • -f 如果目標(biāo)文件夾已存在,則強(qiáng)制刪除現(xiàn)有文件夾(默認(rèn)如果目標(biāo)文件夾已存在,則解碼失?。?。
  • -o 指定解碼目標(biāo)文件夾的名稱(默認(rèn)使用APK文件的名字來命名目標(biāo)文件夾)。
  • -s 不反編譯dex文件,也就是說classes.dex文件會(huì)被保留(默認(rèn)會(huì)將dex文件解碼成smali文件)。
  • -r 不反編譯資源文件,也就是說resources.arsc文件會(huì)被保留(默認(rèn)會(huì)將resources.arsc解碼成具體的資源文件)。

常用用法就這么多了,那么上述命令的執(zhí)行結(jié)果如下圖所示:


這就說明反編譯資源已經(jīng)成功了。
當(dāng)然即使你在和我執(zhí)行一模一樣的操作,也有可能會(huì)在這里反編譯失敗,比如說會(huì)報(bào)如下錯(cuò)誤:

出現(xiàn)這個(gè)錯(cuò)誤的原因很有可能是你之前使用過apktool的老版本進(jìn)行過反編譯操作,然后apktool就會(huì)在你系統(tǒng)的C:\Users\Administrator\apktool\framework這個(gè)目錄下生成一個(gè)名字為1.apk的緩存文件,將這個(gè)緩存文件刪除掉,然后再重新執(zhí)行反編譯命令應(yīng)該就可以成功了。
現(xiàn)在你會(huì)發(fā)現(xiàn)在當(dāng)前目錄下多了一個(gè)Demo文件夾,這個(gè)文件夾中存放的就是反編譯的結(jié)果了。我們可以打開AndroidManifest.xml來瞧一瞧,如下圖所示:

怎么樣?這樣就完全能看得懂了吧,然后可以再到res/layout中看一下activity_main.xml文件,如下圖所示:

可以看到,activity_main.xml中的內(nèi)容基本和源代碼中的內(nèi)容是一致的,外層是一個(gè)RelativeLayout,里面則是一個(gè)Button。你可以再到其它目錄中去看一看別的資源,基本上都是可以正常還原的,這樣我們就把反編譯資源的方法也已經(jīng)掌握了。

重新打包

那么對(duì)于反編譯出來的文件夾,我們能不能重新把它打包成APK文件呢?答案是肯定的,只不過我實(shí)在想不出有什么義正言辭的理由可以讓我們這么做。有的人會(huì)說漢化,沒錯(cuò),漢化的方式確實(shí)就是將一個(gè)APK進(jìn)行反編譯,然后翻譯其中的資源再重新打包,但是不管怎么說這仍然是將別人的程序進(jìn)行破解,所以我并不認(rèn)為這是什么光榮的事情。那么我們就不去討論本身這件事情的對(duì)或錯(cuò),這里只是站在技術(shù)的角度來學(xué)習(xí)一下重新打包的相關(guān)知識(shí)。
首先我們來看一下通過apktool反編譯后的包目錄情況,如下圖所示:


其中,original文件夾下存放的是未經(jīng)反編譯過、原始的AndroidManifest.xml文件,res文件夾下存放的是反編譯出來的所有資源,smali文件夾下存放的是反編譯出來的所有代碼,AndroidManifest.xml則是經(jīng)過反編譯還原后的manifest文件。這里值得一提的是smali文件夾,如果你進(jìn)入到這個(gè)文件夾中你會(huì)發(fā)現(xiàn)它的目錄結(jié)構(gòu)和我們源碼中src的目錄結(jié)構(gòu)是幾乎一樣的,主要的區(qū)別就是所有的java文件都變成了smali文件。smali文件其實(shí)也是真正的源代碼,只不過它的語法和java完全不同,它有點(diǎn)類似于匯編的語法,是Android虛擬機(jī)所使用的寄存器語言,語法結(jié)構(gòu)大概如下所示:

看上去有點(diǎn)暈頭轉(zhuǎn)向是嗎?但是如果你一旦能夠看得懂smali文件的話,那么你就可以做很恐怖的事情了——你可以隨意修改應(yīng)用程序內(nèi)的邏輯,將其進(jìn)行破解!
不過我對(duì)這種黑技術(shù)并沒有什么太大的興趣,因此我也沒有去做具體研究,但即使是這樣,也已經(jīng)可以對(duì)程序的邏輯做一定程度的修改了。比如說當(dāng)我們點(diǎn)擊按鈕時(shí)會(huì)彈出you clicked button這樣一句Toast,邏輯是寫在MainActivity按鈕點(diǎn)擊事件的匿名類當(dāng)中的,因此這段代碼反編譯之后一定就會(huì)在MainActivity$1.smali這個(gè)文件當(dāng)中,讓我們打開瞧一瞧,部分代碼如下所示:

雖說多數(shù)的代碼我是看不懂的,但其中第47行實(shí)在太明顯了,Toast顯示的內(nèi)容不就是在這里定義的么,那么如果我們想把Demo程序hack掉,就可以將這段字符串給改掉,比如說我把它改成Your app is been hacked。
關(guān)于smali的語法,網(wǎng)上的資料也非常多,如果你對(duì)這門技術(shù)十分感興趣的話可以直接上網(wǎng)去搜,這里我只是簡單介紹一下,就不再深入講解相關(guān)知識(shí)了。
改了一處代碼后我們再來改一處資源吧,比如這里想要把Demo的應(yīng)用圖標(biāo)給換掉,那么首先我們要準(zhǔn)備好一張新的圖片,如下圖所示:

然后從AndroidManifest.xml文件中可以看出,應(yīng)用圖標(biāo)使用的是ic_launcher.png這張圖片,那么我們將上面籃球這張圖片命名成ic_launcher.png,然后拷貝到所有以res/mipmap開頭的文件夾當(dāng)中完成替換操作。
在做了兩處改動(dòng)之后,我們現(xiàn)在來把反編譯后的Demo文件夾重新打包成APK吧,其實(shí)非常簡單,只需要在cmd中執(zhí)行如下命令:

apktool b Demo -o New_Demo.apk
  • 1
  • 1

其中b是build的意思,表示我們要將Demo文件夾打包成APK文件,-o用于指定新生成的APK文件名,這里新的文件叫作New_Demo.apk。執(zhí)行結(jié)果如下圖所示:


現(xiàn)在你會(huì)發(fā)現(xiàn)在同級(jí)目錄下面生成了一個(gè)新的APK文件:

不過不要高興得太早了,目前這個(gè)New_Demo.apk還是不能安裝的,因?yàn)樗€沒有進(jìn)行簽名。那么如果這是別人的程序的話,我們從哪兒能拿到它原來的簽名文件呢?很顯然,這是根本沒有辦法拿到的,因此我們只能拿自己的簽名文件來對(duì)這個(gè)APK文件重新進(jìn)行簽名,但同時(shí)也表明我們重新打包出來的軟件就是個(gè)十足的盜版軟件。這里大家學(xué)學(xué)技術(shù)就好了,希望不要有任何人去做什么壞事情。
那么這里我就用一個(gè)之前生成好的簽名文件了,使用Android Studio或者Eclipse都可以非常簡單地生成一個(gè)簽名文件。
有了簽名文件之后在cmd中執(zhí)行簽名命令就可以進(jìn)行簽名了,命令格式如下:

jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore 簽名文件名 -storepass 簽名密碼 待簽名的APK文件名 簽名的別名
  • 1
  • 1

其中jarsigner命令文件是存放在jdk的bin目錄下的,需要將bin目錄配置在系統(tǒng)的環(huán)境變量當(dāng)中才可以在任何位置執(zhí)行此命令。
簽名之后的APK文件現(xiàn)在已經(jīng)可以安裝到手機(jī)上了,不過在此之前Android還極度建議我們對(duì)簽名后的APK文件進(jìn)行一次對(duì)齊操作,因?yàn)檫@樣可以使得我們的程序在Android系統(tǒng)中運(yùn)行得更快。對(duì)齊操作使用的是zipalign工具,該工具存放于<Android SDK>/build-tools/<version>目錄下,將這個(gè)目錄配置到系統(tǒng)環(huán)境變量當(dāng)中就可以在任何位置執(zhí)行此命令了。命令格式如下:

zipalign 4 New_Demo.apk New_Demo_aligned.apk
  • 1
  • 1

其中4是固定值不能改變,后面指定待對(duì)齊的APK文件名和對(duì)齊后的APK文件名。運(yùn)行這段命令之后就會(huì)生成一個(gè)New_Demo_aligned.apk文件,如下所示:


這個(gè)New_Demo_aligned.apk就是我們重新打包簽名對(duì)齊后的文件了,現(xiàn)在把它安裝到手機(jī)上,效果如下圖所示:

可以看到,應(yīng)用圖標(biāo)已經(jīng)成功改成了籃球,另外點(diǎn)擊按鈕后彈出的Toast的提示也變成了我們修改后的文字,說明重新打包操作確實(shí)已經(jīng)成功了。


好的,我們把反編譯代碼、反編譯資源、重新打包這三大主題的內(nèi)容都已經(jīng)掌握了,關(guān)于反編譯相關(guān)的內(nèi)容就到這里,下篇文章會(huì)介紹Android代碼混淆方面的相關(guān)技術(shù),感興趣的朋友請繼續(xù)閱讀: Android安全攻防戰(zhàn),反編譯與混淆技術(shù)完全解析(下) 。

關(guān)注我的技術(shù)公眾號(hào),每天都有優(yōu)質(zhì)技術(shù)文章推送。關(guān)注我的娛樂公眾號(hào),工作、學(xué)習(xí)累了的時(shí)候放松一下自己。

微信掃一掃下方二維碼即可關(guān)注:

        轉(zhuǎn)載請注明出處:http://blog.csdn.net/guolin_blog/article/details/49738023

之前一直有猶豫過要不要寫這篇文章,畢竟去反編譯人家的程序并不是什么值得驕傲的事情。不過單純從技術(shù)角度上來講,掌握反編譯功能確實(shí)是一項(xiàng)非常有用的技能,可能平常不太會(huì)用得到,但是一旦真的需要用到的了,而你卻不會(huì)的話,那就非常頭疼了。另外既然別人可以反編譯程序,我們當(dāng)然有理由應(yīng)該對(duì)程序進(jìn)行一定程度的保護(hù),因此代碼混淆也是我們必須要掌握的一項(xiàng)技術(shù)。那么最近的兩篇文章我們就圍繞反編譯和混淆這兩個(gè)主題來進(jìn)行一次完全解析。


反編譯

我們都知道,Android程序打完包之后得到的是一個(gè)APK文件,這個(gè)文件是可以直接安裝到任何Android手機(jī)上的,我們反編譯其實(shí)也就是對(duì)這個(gè)APK文件進(jìn)行反編譯。Android的反編譯主要又分為兩個(gè)部分,一個(gè)是對(duì)代碼的反編譯,一個(gè)是對(duì)資源的反編譯,我們馬上來逐個(gè)學(xué)習(xí)一下。
在開始學(xué)習(xí)之前,首先我們需要準(zhǔn)備一個(gè)APK文件,為了尊重所有開發(fā)者,我就不拿任何一個(gè)市面上的軟件來演示了,而是自己寫一個(gè)Demo用來測試。
這里我希望代碼越簡單越好,因此我們建立一個(gè)新項(xiàng)目,在Activity里加入一個(gè)按鈕,當(dāng)點(diǎn)擊按鈕時(shí)彈出一個(gè)Toast,就這么簡單,代碼如下所示:

public class MainActivity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        Button button = (Button) findViewById(R.id.button);        button.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                Toast.makeText(MainActivity.this, "you clicked button", Toast.LENGTH_SHORT).show();            }        });    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

activity_main.xml中的資源如下所示:

<?xml version="1.0" encoding="utf-8"?><RelativeLayout    xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:paddingBottom="@dimen/activity_vertical_margin"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin">    <Button        android:id="@+id/button"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="Button"/></RelativeLayout>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

然后我們將代碼打成一個(gè)APK包,并命名成Demo.apk,再把它安裝到手機(jī)上,結(jié)果如下所示:


好的,到這里準(zhǔn)備工作就已經(jīng)基本完成了,接下來就讓我們開始對(duì)這個(gè)Demo程序進(jìn)行反編譯吧。

反編譯代碼

要想將APK文件中的代碼反編譯出來,我們需要用到以下兩款工具:

將這兩個(gè)工具都下載好并解壓,然后我們就開始對(duì)Demo程序進(jìn)行反編譯。解壓dex2jar壓縮包后,你會(huì)發(fā)現(xiàn)有很多個(gè)文件,如下圖所示:


其中我們要用到的是d2j-dex2jar.bat這個(gè)文件,當(dāng)然如果你是linux或mac系統(tǒng)的話就要用d2j-dex2jar.sh這個(gè)文件。
然后我們將Demo.apk文件也進(jìn)行解壓,如果不知道怎么直接解壓的可以先將文件重命名成Demo.zip,然后用解壓軟件打開。解壓之后你會(huì)發(fā)現(xiàn)里面有一個(gè)classes.dex文件,如下圖所示:

這個(gè)classes.dex文件就是存放所有java代碼的地方了,我們將它拷貝到dex2jar解壓后的目錄下,并在cmd中也進(jìn)入到同樣的目錄,然后執(zhí)行:

d2j-dex2jar classes.dex
  • 1
  • 1

執(zhí)行結(jié)果如下圖所示:


沒有報(bào)任何錯(cuò)誤,這就說明我們已經(jīng)轉(zhuǎn)換成功了?,F(xiàn)在觀察dex2jar目錄,你會(huì)發(fā)現(xiàn)多了一個(gè)文件,如下圖所示:

可以看到,classes-dex2jar.jar這個(gè)文件就是我們借助工具之后成功轉(zhuǎn)換出來的jar文件了。但是對(duì)于我們而言,jar文件也不是可讀的,因此這里還需要再借助一下jd-gui這個(gè)工具來將jar文件轉(zhuǎn)換成java代碼。
下面就很簡單了,使用jd-gui工具打開classes-dex2jar.jar這個(gè)文件,結(jié)果如下圖所示:

OK,由此可見,我們的代碼反編譯工作已經(jīng)成功了,MainActivity中的代碼非常清晰,基本已經(jīng)做到了90%以上的還原工作。但是如果想要做到100%的代碼還原還是非常有難度的,因?yàn)橄駍etContentView()方法傳入的參數(shù),其實(shí)就是一個(gè)資源的id值而已,那么這里反編譯也就只能將相應(yīng)的id值進(jìn)行還原,而無法變成像R.layout.activity_main這樣直觀的代碼展示。
另外,除了MainActivity之外,還有很多其它的代碼也被反編譯出來了,因?yàn)楫?dāng)前項(xiàng)目有引用support-v4和support-v7的包,這些引用的library也會(huì)作為代碼的一部分被打包到classes.dex文件當(dāng)中,因此反編譯的時(shí)候這些代碼也會(huì)一起被還原。
好的,學(xué)完了反編譯代碼,接下來我們看一下如何反編譯資源。

反編譯資源

其實(shí)細(xì)心的朋友可能已經(jīng)觀察到了,剛才Demo.apk的解壓目錄當(dāng)中不是已經(jīng)有資源文件了嗎,有AndroidManifest.xml文件,也有res目錄。進(jìn)入res目錄當(dāng)中,內(nèi)容如下圖所示:


這不是所有資源文件都在這里了么?其實(shí)這些資源文件都是在打包的時(shí)候被編譯過了,我們直接打開的話是看不到明文的,不信的話我們打開AndroidManifest.xml文件來瞧一瞧,內(nèi)容如下圖所示:

可以看到,這代碼是完全沒法閱讀的。當(dāng)然如果你去打開activity_main.xml看看,結(jié)果也不會(huì)好到哪兒去:

由此可見,直接對(duì)APK包進(jìn)行解壓是無法得到它的原始資源文件的,因此我們還需要對(duì)資源進(jìn)行反編譯才行。
要想將APK文件中的資源反編譯出來,又要用到另外一個(gè)工具了:

關(guān)于這個(gè)工具的下載我還要再補(bǔ)充幾句,我們需要的就是apktool.bat和apktool.jar這兩個(gè)文件。目前apktool.jar的最新版本是2.0.3,這里我就下載最新的了,然后將apktool_2.0.3.jar重命名成apktool.jar,并將它們放到同一個(gè)文件夾下就可以了,如下圖所示:


接下來的工作就很簡單了,我們將Demo.apk拷貝到和這兩個(gè)文件同樣的目錄當(dāng)中,然后cmd也進(jìn)入到這個(gè)目錄下,并在cmd中執(zhí)行如下命令:

apktool d Demo.apk
  • 1
  • 1

其中d是decode的意思,表示我們要對(duì)Demo.apk這個(gè)文件進(jìn)行解碼。那除了這個(gè)基本用法之外,我們還可以再加上一些附加參數(shù)來控制decode的更多行為:

  • -f 如果目標(biāo)文件夾已存在,則強(qiáng)制刪除現(xiàn)有文件夾(默認(rèn)如果目標(biāo)文件夾已存在,則解碼失敗)。
  • -o 指定解碼目標(biāo)文件夾的名稱(默認(rèn)使用APK文件的名字來命名目標(biāo)文件夾)。
  • -s 不反編譯dex文件,也就是說classes.dex文件會(huì)被保留(默認(rèn)會(huì)將dex文件解碼成smali文件)。
  • -r 不反編譯資源文件,也就是說resources.arsc文件會(huì)被保留(默認(rèn)會(huì)將resources.arsc解碼成具體的資源文件)。

常用用法就這么多了,那么上述命令的執(zhí)行結(jié)果如下圖所示:


這就說明反編譯資源已經(jīng)成功了。
當(dāng)然即使你在和我執(zhí)行一模一樣的操作,也有可能會(huì)在這里反編譯失敗,比如說會(huì)報(bào)如下錯(cuò)誤:

出現(xiàn)這個(gè)錯(cuò)誤的原因很有可能是你之前使用過apktool的老版本進(jìn)行過反編譯操作,然后apktool就會(huì)在你系統(tǒng)的C:\Users\Administrator\apktool\framework這個(gè)目錄下生成一個(gè)名字為1.apk的緩存文件,將這個(gè)緩存文件刪除掉,然后再重新執(zhí)行反編譯命令應(yīng)該就可以成功了。
現(xiàn)在你會(huì)發(fā)現(xiàn)在當(dāng)前目錄下多了一個(gè)Demo文件夾,這個(gè)文件夾中存放的就是反編譯的結(jié)果了。我們可以打開AndroidManifest.xml來瞧一瞧,如下圖所示:

怎么樣?這樣就完全能看得懂了吧,然后可以再到res/layout中看一下activity_main.xml文件,如下圖所示:

可以看到,activity_main.xml中的內(nèi)容基本和源代碼中的內(nèi)容是一致的,外層是一個(gè)RelativeLayout,里面則是一個(gè)Button。你可以再到其它目錄中去看一看別的資源,基本上都是可以正常還原的,這樣我們就把反編譯資源的方法也已經(jīng)掌握了。

重新打包

那么對(duì)于反編譯出來的文件夾,我們能不能重新把它打包成APK文件呢?答案是肯定的,只不過我實(shí)在想不出有什么義正言辭的理由可以讓我們這么做。有的人會(huì)說漢化,沒錯(cuò),漢化的方式確實(shí)就是將一個(gè)APK進(jìn)行反編譯,然后翻譯其中的資源再重新打包,但是不管怎么說這仍然是將別人的程序進(jìn)行破解,所以我并不認(rèn)為這是什么光榮的事情。那么我們就不去討論本身這件事情的對(duì)或錯(cuò),這里只是站在技術(shù)的角度來學(xué)習(xí)一下重新打包的相關(guān)知識(shí)。
首先我們來看一下通過apktool反編譯后的包目錄情況,如下圖所示:


其中,original文件夾下存放的是未經(jīng)反編譯過、原始的AndroidManifest.xml文件,res文件夾下存放的是反編譯出來的所有資源,smali文件夾下存放的是反編譯出來的所有代碼,AndroidManifest.xml則是經(jīng)過反編譯還原后的manifest文件。這里值得一提的是smali文件夾,如果你進(jìn)入到這個(gè)文件夾中你會(huì)發(fā)現(xiàn)它的目錄結(jié)構(gòu)和我們源碼中src的目錄結(jié)構(gòu)是幾乎一樣的,主要的區(qū)別就是所有的java文件都變成了smali文件。smali文件其實(shí)也是真正的源代碼,只不過它的語法和java完全不同,它有點(diǎn)類似于匯編的語法,是Android虛擬機(jī)所使用的寄存器語言,語法結(jié)構(gòu)大概如下所示:

看上去有點(diǎn)暈頭轉(zhuǎn)向是嗎?但是如果你一旦能夠看得懂smali文件的話,那么你就可以做很恐怖的事情了——你可以隨意修改應(yīng)用程序內(nèi)的邏輯,將其進(jìn)行破解!
不過我對(duì)這種黑技術(shù)并沒有什么太大的興趣,因此我也沒有去做具體研究,但即使是這樣,也已經(jīng)可以對(duì)程序的邏輯做一定程度的修改了。比如說當(dāng)我們點(diǎn)擊按鈕時(shí)會(huì)彈出you clicked button這樣一句Toast,邏輯是寫在MainActivity按鈕點(diǎn)擊事件的匿名類當(dāng)中的,因此這段代碼反編譯之后一定就會(huì)在MainActivity$1.smali這個(gè)文件當(dāng)中,讓我們打開瞧一瞧,部分代碼如下所示:

雖說多數(shù)的代碼我是看不懂的,但其中第47行實(shí)在太明顯了,Toast顯示的內(nèi)容不就是在這里定義的么,那么如果我們想把Demo程序hack掉,就可以將這段字符串給改掉,比如說我把它改成Your app is been hacked。
關(guān)于smali的語法,網(wǎng)上的資料也非常多,如果你對(duì)這門技術(shù)十分感興趣的話可以直接上網(wǎng)去搜,這里我只是簡單介紹一下,就不再深入講解相關(guān)知識(shí)了。
改了一處代碼后我們再來改一處資源吧,比如這里想要把Demo的應(yīng)用圖標(biāo)給換掉,那么首先我們要準(zhǔn)備好一張新的圖片,如下圖所示:

然后從AndroidManifest.xml文件中可以看出,應(yīng)用圖標(biāo)使用的是ic_launcher.png這張圖片,那么我們將上面籃球這張圖片命名成ic_launcher.png,然后拷貝到所有以res/mipmap開頭的文件夾當(dāng)中完成替換操作。
在做了兩處改動(dòng)之后,我們現(xiàn)在來把反編譯后的Demo文件夾重新打包成APK吧,其實(shí)非常簡單,只需要在cmd中執(zhí)行如下命令:

apktool b Demo -o New_Demo.apk
  • 1
  • 1

其中b是build的意思,表示我們要將Demo文件夾打包成APK文件,-o用于指定新生成的APK文件名,這里新的文件叫作New_Demo.apk。執(zhí)行結(jié)果如下圖所示:


現(xiàn)在你會(huì)發(fā)現(xiàn)在同級(jí)目錄下面生成了一個(gè)新的APK文件:

不過不要高興得太早了,目前這個(gè)New_Demo.apk還是不能安裝的,因?yàn)樗€沒有進(jìn)行簽名。那么如果這是別人的程序的話,我們從哪兒能拿到它原來的簽名文件呢?很顯然,這是根本沒有辦法拿到的,因此我們只能拿自己的簽名文件來對(duì)這個(gè)APK文件重新進(jìn)行簽名,但同時(shí)也表明我們重新打包出來的軟件就是個(gè)十足的盜版軟件。這里大家學(xué)學(xué)技術(shù)就好了,希望不要有任何人去做什么壞事情。
那么這里我就用一個(gè)之前生成好的簽名文件了,使用Android Studio或者Eclipse都可以非常簡單地生成一個(gè)簽名文件。
有了簽名文件之后在cmd中執(zhí)行簽名命令就可以進(jìn)行簽名了,命令格式如下:

jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore 簽名文件名 -storepass 簽名密碼 待簽名的APK文件名 簽名的別名
  • 1
  • 1

其中jarsigner命令文件是存放在jdk的bin目錄下的,需要將bin目錄配置在系統(tǒng)的環(huán)境變量當(dāng)中才可以在任何位置執(zhí)行此命令。
簽名之后的APK文件現(xiàn)在已經(jīng)可以安裝到手機(jī)上了,不過在此之前Android還極度建議我們對(duì)簽名后的APK文件進(jìn)行一次對(duì)齊操作,因?yàn)檫@樣可以使得我們的程序在Android系統(tǒng)中運(yùn)行得更快。對(duì)齊操作使用的是zipalign工具,該工具存放于<Android SDK>/build-tools/<version>目錄下,將這個(gè)目錄配置到系統(tǒng)環(huán)境變量當(dāng)中就可以在任何位置執(zhí)行此命令了。命令格式如下:

zipalign 4 New_Demo.apk New_Demo_aligned.apk
  • 1
  • 1

其中4是固定值不能改變,后面指定待對(duì)齊的APK文件名和對(duì)齊后的APK文件名。運(yùn)行這段命令之后就會(huì)生成一個(gè)New_Demo_aligned.apk文件,如下所示:


這個(gè)New_Demo_aligned.apk就是我們重新打包簽名對(duì)齊后的文件了,現(xiàn)在把它安裝到手機(jī)上,效果如下圖所示:

可以看到,應(yīng)用圖標(biāo)已經(jīng)成功改成了籃球,另外點(diǎn)擊按鈕后彈出的Toast的提示也變成了我們修改后的文字,說明重新打包操作確實(shí)已經(jīng)成功了。


好的,我們把反編譯代碼、反編譯資源、重新打包這三大主題的內(nèi)容都已經(jīng)掌握了,關(guān)于反編譯相關(guān)的內(nèi)容就到這里,下篇文章會(huì)介紹Android代碼混淆方面的相關(guān)技術(shù),感興趣的朋友請繼續(xù)閱讀: Android安全攻防戰(zhàn),反編譯與混淆技術(shù)完全解析(下) 。

關(guān)注我的技術(shù)公眾號(hào),每天都有優(yōu)質(zhì)技術(shù)文章推送。關(guān)注我的娛樂公眾號(hào),工作、學(xué)習(xí)累了的時(shí)候放松一下自己。

微信掃一掃下方二維碼即可關(guān)注:

        

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Android 反編譯
獲取Android自己寫好了的apk以及反編譯
??Android反編譯神器,讓你輕松查看APK源碼!
APK應(yīng)用程序的解包、修改、編輯、打包及應(yīng)用 by SunnyOKOK
APK反編譯過程及用到的工具
將jar文件與dex文件的轉(zhuǎn)換
更多類似文章 >>
生活服務(wù)
熱點(diǎn)新聞
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服