




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
【移動應(yīng)用開發(fā)技術(shù)】Android中安全地打印日志的示例
這篇文章主要介紹了Android中安全地打印日志的示例,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓在下帶著大家一起了解一下。在Android開發(fā)過程中,不管是寫Demo還是實戰(zhàn)項目中,都會打印一些日志用于記錄數(shù)據(jù),調(diào)試來著,Android中的日志工具類是Log,這個類提供了一些方法來打印日志。五個級別,v、d、i、w、e,各有不同的重載。當(dāng)談到如何打印日志?很多人會想這不是很簡單,直接使用android.util.Log這個類不就行了?然而,日志屬于非常敏感的信息;逆向工程師在逆向你的程序的時候,本來需要捕捉你程序的各種輸出,然后進(jìn)行推測,順藤摸瓜然后得到需要的信息;一旦你的日志泄漏,無異于門戶洞開,破解你的程序如入無人之境。安全的概念本來就是相對的,如果破解你程序的代價遠(yuǎn)遠(yuǎn)大于破解得到的價值,那么就可以認(rèn)為程序是“安全的”;這里就分析一下,為了提高程序的安全性,在打印日志的時候應(yīng)該注意什么。首先看看絕大部分公司以及開發(fā)者的做法:日志開關(guān)+日志類為了在release版本里面沒有日志輸出,一個最簡單的想法是:把所有打印日志的語句放在一個if(DEBUG)的語句里面;在日常開發(fā)的時候,DEBUG開關(guān)打開,發(fā)布正式版本的時候關(guān)閉這個開關(guān)即可,大致思路如下://
LogUtil.java
public
class
LogUtil
{
private
static
boolean
DEBUG
=
true;//
發(fā)布的時候修改為false
public
static
void
d(String
tag,
String
msg)
{
if
(DEBUG)
android.util.Log.d(TAG,
msg);
}
//
其他debug方法
}接下來看一個真實的例子,國外的一個apk,名字叫做powerclean;包名:com.lionmobi.powerclean;我們安裝這個包;發(fā)現(xiàn)很正常,沒有任何日志輸出;然后我們逆向這個apk;隨便翻看幾個類,發(fā)現(xiàn)很多地方有類似日志輸出:日志輸出圖片我們打開這個叫做x的類,雖然被混淆過了,但是意思很明白,跟我們上面的思路一樣:package
com.lionmobi.util;
import
android.util.Log;
public
class
x
{
private
static
boolean
a;
static
{
x.a
=
false;
}
public
static
void
d(String
arg1,
String
arg2)
{
if(x.a)
{
Log.d(arg1,
arg2);
}
}
public
static
void
e(String
arg1,
String
arg2)
{
if(x.a)
{
Log.e(arg1,
arg2);
}
}
public
static
void
i(String
arg1,
String
arg2)
{
if(x.a)
{
Log.i(arg1,
arg2);
}
}
}這是一個真實的例子,而且這個app的用戶還不少;接下來我們看看這種方式有什么問題。靜態(tài)反編譯打開日志開關(guān)上面的那種方式有一個問題:雖然在release版本里面,確實沒有日志輸出;但是輸出日志的代碼依然存在,只是沒有執(zhí)行到!(if條件不成立)所以,有沒有辦法讓這些代碼執(zhí)行到呢?簡單來說,就是能不能在release版本里面把這個DEBUG變量弄成true呢?當(dāng)然可以!而且做法還非常簡單。我們使用apktool反編譯得到這個apk的smali代碼;然后上面的反編譯告訴我們,這個日志類的位置是:com.lionmobi.util.x我們打開這個x.smali文件,內(nèi)容如下:.class
public
Lcom/lionmobi/util/x;
.super
Ljava/lang/Object;
#
static
fields
.field
private
static
a:Z
#
direct
methods
.method
static
constructor
<clinit>()V
.locals
1
const/4
v0,
0x0
#
修改為0x1
(True)
sput-boolean
v0,
Lcom/lionmobi/util/x;->a:Z
#初始化位置
return-void
.end
method
.method
public
static
d(Ljava/lang/String;Ljava/lang/String;)V
.locals
1
sget-boolean
v0,
Lcom/lionmobi/util/x;->a:Z
if-eqz
v0,
:cond_0
invoke-static
{p0,
p1},
Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
:cond_0
return-void
.end
method
.method
public
static
e(Ljava/lang/String;Ljava/lang/String;)V
.locals
1
sget-boolean
v0,
Lcom/lionmobi/util/x;->a:Z
if-eqz
v0,
:cond_0
invoke-static
{p0,
p1},
Landroid/util/Log;->e(Ljava/lang/String;Ljava/lang/String;)I
:cond_0
return-void
.end
method
.method
public
static
i(Ljava/lang/String;Ljava/lang/String;)V
.locals
1
sget-boolean
v0,
Lcom/lionmobi/util/x;->a:Z
if-eqz
v0,
:cond_0
invoke-static
{p0,
p1},
Landroid/util/Log;->i(Ljava/lang/String;Ljava/lang/String;)I
:cond_0
return-void
.end
method很明白,那個叫做a的靜態(tài)變量就是我們的開關(guān),它的初始化在哪個靜態(tài)代碼塊里面;新建了一個局部變量0x0然后賦值給了a;因此,我們把這個0x0修改為0x1就打開了這個開關(guān)。很簡單吧,接下來我們把修改好的smali打包回去,然后簽名得到一個新的可以運行的apk;運行一下看看結(jié)果。果然,一大堆的日志輸出了出來,你的程序每一步在干什么都自己告訴別人了,都不需要去猜;我就隨便截個圖,感受下:泄漏的日志信息讓release版本里面不包含日志代碼從上面的分析我們得到一個結(jié)論:如果需要程序是“日志安全的”,那么release版本里面不應(yīng)該存在輸出日志的代碼。如何做到這一點呢?我們可以做一個工具,開發(fā)的時候,正常打印日志;一旦需要發(fā)布版本,把所有打印日志的語句代碼,全部刪除掉。代碼很簡單,用一些正則表達(dá)式就可以做到。事實上,我們也可以使用一些別的工具,來實現(xiàn)這個類似的功能;那就是proguard;提到這個工具,很多認(rèn)只是覺得他是一個代碼混淆的工具,實際上,它還可以幫你剔除無用代碼!什么樣的代碼是無用代碼呢?if
(true)
{
//
statement;
}類似于這樣,靜態(tài)編譯的時候被認(rèn)為“永遠(yuǎn)不會執(zhí)行的代碼”,就被認(rèn)為是無用代碼,會被這個工具直接優(yōu)化掉,生成的class文件里面,這個if語句直接就沒有了。這個功能,完美符合我們的需求;我們只需要把輸出日志的代碼用這樣的if語句包圍起來,然后release的時候肯定會用這個工具混淆;然后,在release版本里面,所有的輸出日志的代碼全部都沒有了!不會像以前一樣,留下一個影子,只是不做事。正確的做法最終,我們所有打印日志的語句應(yīng)該如下:private
static
final
boolean
DEBUG
=
true;
//
必須是static
final
也就是常量,這樣才能在編譯器優(yōu)化;刪除if塊
if
(DEBUG)
{
android.util.Log.d(TAG,
"msg
to
print");
}然后,使用proguard優(yōu)化代碼即可??雌饋砗唵?,好像也與最初的“日志開關(guān)”沒有什么區(qū)別,仔細(xì)分析一下:日志開關(guān)必須是靜態(tài)常量對比一下正確的做法與最開始的日志開關(guān),一個是一個靜態(tài)變量,一個是靜態(tài)常量;如果是常量的話,那么就是永遠(yuǎn)不變的,那么當(dāng)DEBUG變量為False的時候proguard可以理所當(dāng)然地認(rèn)為,這一部分代碼時絕對不會被執(zhí)行的,這樣,打印日志的語句就會被優(yōu)化(刪除)掉;如果是一個變量,那么在運行期間就有可能改變它的值(private僅僅是對于程序員的改變,對于編譯器以及運行時,沒有什么改不了),這樣proguard就會置之不理,這樣你的日志代碼就暴露出來了,一字之差,失之千里。拋棄日志類假設(shè)我們使用了靜態(tài)常量代碼塊以及proguard優(yōu)化代碼的技術(shù);但是依然采用上面的日志類的技術(shù),會發(fā)生什么呢?public
class
LogUtil
{
private
static
final
boolean
DEBUG
=
false;
public
static
void
d(String
tag,
String
msg)
{
if
(DEBUG)
android.util.Log.d(tag,
msg);
}
}我寫了一個demo,自己打包然后反編譯,得到這個日志類如下(為了方便看,沒有混淆):package
com.example.test.app;
public
class
LogUtil
{
private
static
final
boolean
DEBUG;
public
LogUtil()
{
super();
}
public
static
void
d(String
tag,
String
msg)
{
}
}我們看到,if代碼塊已經(jīng)沒有了,確實不會輸出任何日志;但是,我們看看調(diào)用這個類的地方!掩耳盜鈴的日志這個LogUtil.d的調(diào)用,無異于掩耳盜鈴;雖然破解者沒辦法讓android.util.Log這個類輸出任何日志,但是你這里的這個調(diào)用還是告訴了別人你在干什么;所以,要屏蔽日志的輸出,必須使用if代碼塊直接包含要被剔除的日志。上面的那個日志類,要被優(yōu)化掉,那就是:if
(DEBUG)
{
LogUtil.d(TAG,
"msg");
}這里,不是多此一舉嗎,寫一個日志類就是想不想重復(fù)地寫if(DEBUG),這里為了使這一句隱藏,還是逃不掉;但是很抱歉,逃得了和尚逃不了廟,這種方法沒辦法做到完全隱藏信息;必須拋棄日志類包裹日志代碼的做法!解放雙手的補充也許有人說,為了這個所謂的日志安全,每次輸出日志都的寫一個if語句,那不麻煩死;簡直反人類,我懶!實際上,要少寫幾行代碼,我們可以選擇復(fù)用(代碼級別,比如上面的日志類),也可以選擇生成(
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- Module 4單元備課(教學(xué)設(shè)計)-2024-2025學(xué)年外研版(一起)英語三年級上冊
- 2025年合作伙伴誠信合同協(xié)議
- 1、我們的消化(教學(xué)設(shè)計)四年級科學(xué)上冊湘教版
- 6《千人糕》 (教學(xué)設(shè)計)2023-2024學(xué)年統(tǒng)編版語文二年級下冊
- 2025年廈門企業(yè)人才租賃合同示范文本
- 項目管理崗位勞動合同范文2025版
- 14 小狗學(xué)叫 教學(xué)設(shè)計-2024-2025學(xué)年語文三年級上冊統(tǒng)編版
- 2025年在線商務(wù)運營勞動合同模板
- Unit 6 Food (教學(xué)設(shè)計)-2024-2025學(xué)年人教精通版(2024)英語三年級上冊
- 2025年勞動報酬分期支付策劃合同范本
- GB/T 33365-2016鋼筋混凝土用鋼筋焊接網(wǎng)試驗方法
- GB/T 16799-2018家具用皮革
- GB/T 14541-2017電廠用礦物渦輪機油維護管理導(dǎo)則
- GB 10133-2014食品安全國家標(biāo)準(zhǔn)水產(chǎn)調(diào)味品
- 講題比賽游戲中的必勝策略問題-(取棋子游戲)課件
- 旅游學(xué)概論李天元版復(fù)習(xí)總結(jié)
- 人教版八年級上歷史思維導(dǎo)圖課件
- 重慶大學(xué)介紹課件
- 江蘇省南京市2020年中考英語試題
- 《電氣裝配車間生產(chǎn)工序流程卡》中英文對譯版
- 四年級下冊英語課件:Unit 4 There are seven days in a week-Lesson 19人教精通版
評論
0/150
提交評論