CTF-Bugku逆向题Android方法归纳
1.signin題目:
reverse()
功能:反轉(zhuǎn)數(shù)組里的元素的順序
語(yǔ)法:arrayobject.reverse.()
這類方法會(huì)改變?cè)瓉?lái)的數(shù)組,不可逆轉(zhuǎn)
tostring()
功能:將各類進(jìn)制的數(shù)字轉(zhuǎn)化為字符串
語(yǔ)法:number.toString(radix)(radix代表進(jìn)制數(shù))
字符串的管理地方是string.xml
java在引用函數(shù)時(shí)要倒著引用
StringBuffer
當(dāng)對(duì)字符串進(jìn)行修改的時(shí)候,需要使用 StringBuffer 和 StringBuilder 類。
和 String 類不同的是,StringBuffer 和 StringBuilder 類的對(duì)象能夠被多次的修改,并且不產(chǎn)生新的未使用對(duì)象。
在使用 StringBuffer 類時(shí),每次都會(huì)對(duì) StringBuffer 對(duì)象本身進(jìn)行操作,而不是生成新的對(duì)象,所以如果需要對(duì)字符串進(jìn)行修改推薦使用 StringBuffer。
StringBuilder 類在 Java 5 里被提出,它和 StringBuffer 之間的最大不同在于 StringBuilder 的方法不是線程安全的(不能同步訪問)。
由于 StringBuilder 相較于 StringBuffer 有速度優(yōu)勢(shì),所以多數(shù)情況下建議使用 StringBuilder 類。
Toast:
Android里的Toast是一類簡(jiǎn)易的消息提示框。Toast是包含用戶點(diǎn)擊消息。Toast類會(huì)幫助你創(chuàng)建和顯示這些。
當(dāng)視圖顯示給用戶,在應(yīng)用程序里顯示為浮動(dòng)。
Toast類的思想就是盡可能不引人注意,同時(shí)還向用戶顯示信息,希望他們看到。而且Toast顯示的時(shí)間有限,Toast會(huì)根據(jù)用戶設(shè)置的顯示時(shí)間后自動(dòng)消失。
Toast 最常見的創(chuàng)建方式是使用靜態(tài)方法 Toast.makeText。
例如:
Toast.makeText(MainActivity.this, text “”, Toast.LENGTH_SHORT).show();
分析:
Toast是為了提醒用戶,而又不影響用戶的操作的提示欄。
方法里的MainActivity.this表示在MainActivity這個(gè)文件里顯示;
text在后面的引號(hào)里輸入想輸出的文本。
text可以替換為R.string.自己定義的文本,表示引用string下的文本的資源;
LENGTH_SHORT表示Toast的顯示時(shí)間一微秒計(jì)算,這里調(diào)用系統(tǒng)定義好的時(shí)間,也可自己寫入確定的時(shí)間。
.show(); 是用來(lái)將定義好的Toast顯示在MainActivity里的,如果不調(diào)用.show();方法定義的Toast就沒有任何意義。
getBaseContext()
getBaseContext() 返回由構(gòu)造函數(shù)指定或setBaseContext()設(shè)置的上下文
可以使用getContext()獲取視圖對(duì)象的上下文。 如果要?jiǎng)?chuàng)建一個(gè)只要存在活動(dòng)就存在的新對(duì)象,則使用活動(dòng)上下文或this,否則,活動(dòng)將不會(huì)被破壞并最后導(dǎo)致內(nèi)存泄漏。 如果需要與應(yīng)用程序的全局生命周期相關(guān)聯(lián)的上下文,并且應(yīng)該在需要?jiǎng)?chuàng)建當(dāng)前活動(dòng)之外存在的對(duì)象的任何地方使用上下文,則可以使用getApplicationContext()。
View.getContext():返回視圖當(dāng)前運(yùn)行的上下文。通常是當(dāng)前活躍的活動(dòng)。
Activity.getApplicationContext():返回整個(gè)應(yīng)用程序的上下文(所有活動(dòng)都在其內(nèi)部運(yùn)行的進(jìn)程)。如果您需要一個(gè)與整個(gè)應(yīng)用程序的生命周期相關(guān)聯(lián)的上下文,而不僅僅是當(dāng)前的活動(dòng),請(qǐng)使用它而不是當(dāng)前的活動(dòng)上下文。
ContextWrapper.getBaseContext()如果需要從另一個(gè)上下文里訪問上下文,則采納
ContextWrapper。從ContextWrapper內(nèi)部引用的上下文通過getBaseContext()訪問。
getString
getString表示以 Java 編程語(yǔ)言里String的形式獲取此 ResultSet對(duì)象的當(dāng)前行里指定列的值。
onCreate()
對(duì)onCreate()方法用super.onCreate()方法的理解,
首先要知道super.onCreate()方法的作用,就是用父類的onCreate方法記住當(dāng)前活動(dòng)的鏡像,當(dāng)下次再執(zhí)行到這個(gè)活動(dòng)的時(shí)候還是從這個(gè)鏡像開始執(zhí)行
但是此處需用super,因?yàn)檫@是調(diào)用父類的方法,為什么不能用this,是因?yàn)樵谧宇惱镉幸粋€(gè)和父類同名的方法就是onCreate,如果用this,就是用本類的實(shí)例來(lái)調(diào)用onCreate,而它偏偏又寫在了onCreate里,這就形成了遞歸調(diào)用,所以一定要用super
如果寫在你自己定義的一個(gè)OnCreate(),在這個(gè)函數(shù)里寫調(diào)用OnCreate的話,需要寫super.OnCreate(),否則會(huì)遞歸調(diào)用,
其他地方寫的話,super是調(diào)用父類的,this是調(diào)用你覆蓋的,不過一般沒有人會(huì)去手動(dòng)調(diào)用這玩意吧,因此一般是調(diào)用super.OnCreate().
首先我們可以看到, HelloWorldActivity 是繼承自 Activity 的。 Activity 是 Android 系統(tǒng)提供的一個(gè)活動(dòng)基類, 我們項(xiàng)目里所有的活動(dòng)都需要繼承它才能擁有活動(dòng)的特性。 然后可以 看到HelloWorldActivity里有兩個(gè)方法, onCreateOptionsMenu()這個(gè)方法是用于創(chuàng)建菜單的, 我們可以先無(wú)視它, 主要看下 onCreate()方法。 onCreate()方法是一個(gè)活動(dòng)被創(chuàng)建時(shí)要執(zhí)行的方法, 其里只有兩行代碼, 并且沒有 Hello world!的字樣。那么圖 1.15里顯示的 Hello world! 是在哪里定義的呢? 其實(shí) Android程序的設(shè)計(jì)講究邏輯和視圖分離, 因此是不推薦在活動(dòng)里直接編寫界面的, 更加通用的一類做法是, 在布局文件里編寫界面,然后在活動(dòng)里引入進(jìn)來(lái)。你可以看到,在 onCreate()方法的第二行調(diào)用了 setContentView()方法,就是這個(gè)方法給當(dāng)前的活動(dòng)引入了一 個(gè) hello_world_layout 布局,那 Hello world!一定就是在這里定義的了!
setContentView()
在Acitivty里setContentView()用來(lái)設(shè)置布局文件
findViewById()
findViewById()是找xml布局文件下的具體widget控件(如Button、TextView等)。
setOnClickListener監(jiān)聽
Android onClick 與 setOnClickListener區(qū)別
為Android Widgets添加點(diǎn)擊事件處理函數(shù)有兩類方法,一個(gè)是在Xml文件里添加onClick屬性,然后在代碼里添加對(duì)應(yīng)的函數(shù)。另一個(gè)是直接在代碼里添加setOnClickListener函數(shù)。兩者什么區(qū)別呢?
者的共同點(diǎn)
兩者底層沒有區(qū)別。
兩者的區(qū)別
使用第一類方法的注意事項(xiàng):
getText()
getText()為返回?cái)?shù)據(jù)窗口控件里懸浮在當(dāng)前行列之上的編輯框里的文本。
Timer題目:
JEB相當(dāng)于Windows平臺(tái)上的IDA
smali代碼:雙擊Bytecode,出現(xiàn)smali代碼;相較于C之匯編,那么smali之于Java
onCreate:
一個(gè)activity啟動(dòng)回調(diào)的第一個(gè)函數(shù)就是onCreate,這個(gè)函數(shù)主要做這個(gè)activity啟動(dòng)的一些需要的初始操作的工作。
onCreate之后調(diào)用了還有onRestart()和onStart()等。
System.loadLibrary:
System.load 和 System.loadLibrary詳解
1.它們都可以用來(lái)裝載庫(kù)文件,不論是JNI庫(kù)文件還是非JNI庫(kù)文件。在任何本地方法被調(diào)用之前需先用這個(gè)兩個(gè)方法之一把相應(yīng)的JNI庫(kù)文件裝載。
2.System.load 參數(shù)為庫(kù)文件的絕對(duì)路徑,可以是任意路徑。
例如你可以這樣載入一個(gè)windows平臺(tái)下JNI庫(kù)文件:
System.load(“C://Documents and Settings//TestJNI.dll”);。
3. System.loadLibrary 參數(shù)為庫(kù)文件名,不包含庫(kù)文件的擴(kuò)展名。
例如你可以這樣載入一個(gè)windows平臺(tái)下JNI庫(kù)文件
System. loadLibrary (“TestJNI”);
System.loadLibrary(“l(fā)hm”); // 它的作用即是把我們?cè)贘ava code里聲明的native方法的那個(gè)libraryload進(jìn)來(lái),或者load其他什么動(dòng)態(tài)連接庫(kù)
System.currentTimeMillis():
功能:產(chǎn)生一個(gè)當(dāng)前的毫秒,這個(gè)毫秒事實(shí)上就是自1970年1月1日0時(shí)起的毫秒數(shù),Date()事實(shí)上就是相當(dāng)于Date(System.currentTimeMillis());
由于Date類還有構(gòu)造Date(long date),用來(lái)計(jì)算long秒與1970年1月1日之間的毫秒差。
得到了這個(gè)毫秒數(shù)。利用函數(shù)Calendar的出的結(jié)果就是年月日分秒。
System.currentTimeMillis()
獲得的是自1970-1-01 00:00:00.000 到當(dāng)前時(shí)刻的時(shí)間距離,類型為long
View:
View是所有Android里所有控件的基類,是界面層次上的一類抽象
不管是簡(jiǎn)單的TextView,Button還是復(fù)雜的LinearLayout和ListView,它們的共同基類都是View;
View是一類界面層的控件的一類抽象,它代表了一個(gè)控件,除了View還有ViewGroup,從名字來(lái)看ViewGroup可以翻譯為控件組,即一組View;
在Android里,ViewGroup也繼承了View,這就意味著View可以是單個(gè)控件,也可以是由多個(gè)控件組成的一組控件;
Handler:
現(xiàn)在作為客戶,有這樣一個(gè)需求,當(dāng)打開Activity界面時(shí),開始倒計(jì)時(shí),倒計(jì)時(shí)結(jié)束后跳轉(zhuǎn)新的界面(類同于各個(gè)APP的歡迎閃屏頁(yè)面)。
作為初學(xué)者,可能覺得直接開啟一個(gè)包含倒序循環(huán)的子線程就ok了
邏輯很簡(jiǎn)單,但當(dāng)點(diǎn)進(jìn)入界面時(shí),會(huì)發(fā)現(xiàn)程序奔潰了。
由此我們發(fā)現(xiàn)在安卓開發(fā)里,例如上面的示例,我們常常通過一個(gè)線程來(lái)完成某些操作,然后同步顯示對(duì)應(yīng)的視圖控件UI上,安卓里無(wú)法直接通過子線程來(lái)進(jìn)行UI更新操作,對(duì)于這類情況,Android提供了一套異步消息處理機(jī)制Handler。
從開發(fā)角度角度來(lái)說(shuō),Handler是Android消息機(jī)制的上層接口,通過handler,可以將一個(gè)任務(wù)切換到handler所在的線程里執(zhí)行,我們通常使用handler來(lái)更新UI,但更新UI僅僅是的使用場(chǎng)景之一,handler并不是僅僅用來(lái)更新UI。
更新UI的具體情況是這樣的:和其他GUI庫(kù)一樣,Android的UI也是線程不安全的,也就是說(shuō)想要更新應(yīng)用程序里的UI元素,則需要在主線程里進(jìn)行。所以主線程又叫做UI線程。若在子線程里更新UI程序會(huì)報(bào)CalledFromWrongThreadException錯(cuò)誤。但是我們經(jīng)常有這樣一類需求:需要在子線程里完成一些耗時(shí)任務(wù)后根據(jù)任務(wù)執(zhí)行結(jié)果來(lái)更新相應(yīng)的UI。這就需要子線程在執(zhí)行完耗時(shí)任務(wù)后向主線程發(fā)送消息,主線程來(lái)更新UI。
簡(jiǎn)單來(lái)說(shuō),Handler就是用來(lái)傳遞消息的。
Handler可以當(dāng)成子線程與主線程的消息傳送的紐帶。在安卓開發(fā)里,在子線程里無(wú)法刷新UI,是因?yàn)閁I在子線程里刷新的話,是不安全的,就比如多個(gè)線程刷新UI,會(huì)造成UI更新沖突,這樣是不安全的。
所以,Handler的作用就來(lái)了,子線程可以通過Handler來(lái)將UI更新操作切換到主線程里執(zhí)行。
postDelayed:
這是一類可以創(chuàng)建多線程消息的函數(shù)
使用方法:
1,首先創(chuàng)建一個(gè)Handler對(duì)象
Handler handler=new Handler();
2,然后創(chuàng)建一個(gè)Runnable對(duì)象
Runnable runnable=new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
//要做的事情,這里再次調(diào)用此Runnable對(duì)象,以實(shí)現(xiàn)每?jī)擅雽?shí)現(xiàn)一次的定時(shí)器操作
handler.postDelayed(this, 2000);
}
};
3,使用PostDelayed方法,兩秒后調(diào)用此Runnable對(duì)象
handler.postDelayed(runnable, 2000);
實(shí)際上也就實(shí)現(xiàn)了一個(gè)2s的一個(gè)定時(shí)器
4,如果想要關(guān)閉此定時(shí)器,可以這樣操作
handler.removeCallbacks(runnable);
只要更改延時(shí)的時(shí)間就可以實(shí)現(xiàn)了,用一個(gè)static對(duì)象的話會(huì)比較容易操作。
是可以異步效果,但Runnable的執(zhí)行是在Handler對(duì)象所在的線程
如果其所在的線程是UI線程的話,Runnable里還是不能執(zhí)行耗時(shí)操作,不然會(huì)ANR
Native層:
分層方式里,Native層就是本地框架。
android native層是 相對(duì)于Java 層的底層,一般用c++開發(fā)
Java框架層就是常說(shuō)的Framework,這層里東西很多也很復(fù)雜,比如說(shuō)主要的一些系統(tǒng)服務(wù)如ActivityManagerService、PackageManagerService等,我們編寫的Android代碼之所以能夠正常識(shí)別和動(dòng)作,都要依賴這一層的支持。這一層也是由Java語(yǔ)言實(shí)現(xiàn)。
Native層這部分常見一些本地服務(wù)和一些鏈接庫(kù)等。這一層的一個(gè)特點(diǎn)就是通過C和C++語(yǔ)言實(shí)現(xiàn)。比如我們現(xiàn)在要執(zhí)行一個(gè)復(fù)雜運(yùn)算,如果通過java代碼去實(shí)現(xiàn),那么效率會(huì)非常低,此時(shí)可以選擇通過C或C++代碼去實(shí)現(xiàn),然后和我們上層的Java代碼通信(這部分在android里稱為jni機(jī)制)。又比如我們的設(shè)備需要運(yùn)行,那么必然要和底層的硬件驅(qū)動(dòng)交互,也要通過Native層。
JNI是Java Native Interface(Java本地接口)的縮寫,JNI不是Android專有,而是從Java繼承而來(lái)。Android作為一類嵌入式操作系統(tǒng),大量個(gè)驅(qū)動(dòng)、硬件相關(guān)的功能底層功能都必須在native層實(shí)現(xiàn),JNI的作用和重要性大大增強(qiáng)。
stringFromJNI2:
Native層一個(gè)底層的函數(shù)
onCreateOptionsMenu():
Android一共有三類形式的菜單:
1.選項(xiàng)菜單(optinosMenu)
2.上下文菜單(ContextMenu)
3.子菜單(subMenu)
其里最常用的就是選項(xiàng)菜單(optionsMenu), 該菜單在點(diǎn)擊 menu 按鍵 后會(huì)在對(duì)應(yīng)的Activity底部顯示出來(lái)。
public boolean onCreateOptionsMenu(Menu menu) {
/**
- 此方法用于初始操作菜單,其里menu參數(shù)就是即將要顯示的Menu實(shí)例。 返回true則顯示該menu,false 則不顯示;
- (只會(huì)在第一次初始操作菜單時(shí)調(diào)用) Inflate the menu; this adds items to the action bar
- if it is present.
*/
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
1.Activity菜單機(jī)制 (與dialog類似)
Activity有一套機(jī)制來(lái)實(shí)現(xiàn)對(duì)菜單的管理,方法如下:
1.public boolean onCreateOptionsMenu(Menu menu)
此方法用于初始操作菜單,其里menu參數(shù)就是即將要顯示的Menu實(shí)例。
返回true則顯示該menu,false 則不顯示;
(只會(huì)在第一次初始操作菜單時(shí)調(diào)用)
2.public boolean onPrepareOptionsMenu(Menu menu)
在onCreateOptionsMenu執(zhí)行后,菜單被顯示前調(diào)用;如果菜單已經(jīng)被創(chuàng)建,則在菜單顯示前被調(diào)用。
同樣的, 返回true則顯示該menu,false 則不顯示;
(可以通過此方法動(dòng)態(tài)的改變菜單的狀態(tài),比如加載不同的菜單等)
3.public void onOptionsMenuClosed(Menu menu)
每次菜單被關(guān)閉時(shí)調(diào)用.
(菜單被關(guān)閉有三類情形,menu按鈕被再次點(diǎn)擊、back按鈕被點(diǎn)擊或者用戶選擇了某一個(gè)菜單項(xiàng))
3+.public boolean onOptionsItemSelected(MenuItem item)
菜單項(xiàng)被點(diǎn)擊時(shí)調(diào)用,也就是菜單項(xiàng)的監(jiān)聽方法。
通過這幾個(gè)方法,可以得知,對(duì)于Activity,同一時(shí)間只能顯示和監(jiān)聽一個(gè)Menu 對(duì)象。
getMenuInflater():
MenuInflater是用來(lái)解析定義在menu 目錄下的菜單布局文件的,類似于LayoutInflater 是用來(lái)解析定義在layout 下的布局文件。傳統(tǒng)意義上的定義菜單感覺比較繁瑣,使用
MenuInflater 生成菜單會(huì)非常清晰簡(jiǎn)單。
我們知道,LayoutInflater是用來(lái)實(shí)例操作整個(gè)布局文件,而 MenuInflater是用來(lái)實(shí)例操作Menu目錄下的Menu布局文件的。
傳統(tǒng)意義上的菜單定義需要Override Activity的onCreateOptionsMenu,然后在里面調(diào)用Menu.add把Menu的一個(gè)個(gè)item加進(jìn)來(lái),比較復(fù)雜。而通過使用MenuInflater可以把Menu的構(gòu)造直接放在Menu布局文件里,真正實(shí)現(xiàn)模型(Model)與視圖(View)的分離,程序也看著清爽多了。
與LayoutInflater相比,MenuInflater的用法簡(jiǎn)單多了。首先,MenuInflater獲取方法只有一類:Activity.getMenuInflater();其次,MenuInflater.inflater(int menuRes,Menu menu)(這里不代表inflater就是static方法,可以這樣調(diào)用,只是為了描述方便)的返回值是void型,這就決定了MenuInflater.inflater后就沒有后續(xù)操作了。這說(shuō)明通過這類方式把Menu布局文件寫好后就不能在程序里動(dòng)態(tài)修改了,而不像LayoutInflater.inflater那樣,返回值是View型,可以進(jìn)行后續(xù)的進(jìn)一步操作。另外,MenuInflater只有一個(gè)void inflater(int menuRes,Menu menu)非構(gòu)造方法。
inflate():
inflate是用來(lái)把XML定義好的布局找出來(lái),inflate之后并沒有直接顯示,需要再加入到其他布局里才能顯示,以下是inflate的三類使用方法.
使用LayoutInflater.inflater方法
使用context.getSystemService方法
使用View.inflate方法
Inflate()作用就是將xml定義的一個(gè)布局找出來(lái),但僅僅是找出來(lái)而且隱藏的,沒有找到的同時(shí)并顯示功能。
android上還有一個(gè)與Inflate()類同功能的方法叫findViewById(),二者有時(shí)均可使用,但也有區(qū)別
區(qū)別在于:
如果你的Activity里用到別的layout,比如對(duì)話框layout,你還要設(shè)置這個(gè)layout上的其他組件的內(nèi)容,你就需以inflate()方法先將對(duì)話框的layout找出來(lái),然后再用findViewById()找到它上面的其它組件。例如:
View view1=View.inflate(this,R.layout.dialog_layout,null);
TextViewdialogTV=(TextView)view1.findViewById(R.id.dialog_tv);
dialogTV.setText(“abcd”);
注:R.id.dialog_tv是在對(duì)話框layout上的組件,而這時(shí)若直接
用 this.findViewById(R.id.dialog_tv)肯定會(huì)報(bào)錯(cuò)。
View viewStub = ((ViewStub) findViewById(R.id.stubView)).inflate();
Inflate()或可理解為“隱性膨脹”,隱性擺放在view里,inflate()前只是獲得控件,但沒有大小沒有在View里占據(jù)空間,inflate()后有一定大小,只是出于隱藏狀態(tài)
onOptionsItemSelected():
public boolean onOptionsItemSelected(MenuItem item)
菜單項(xiàng)被點(diǎn)擊時(shí)調(diào)用,也就是菜單項(xiàng)的監(jiān)聽方法。
只要菜單里的菜單項(xiàng)被點(diǎn)擊,都會(huì)觸發(fā)onOptionsItemSelected(MenuItem item)
item參數(shù)即為被點(diǎn)擊的菜單項(xiàng),那么需要在此方法內(nèi)判斷哪個(gè)Item被點(diǎn)擊了,從而實(shí)現(xiàn)不同的操作。
//當(dāng)客戶點(diǎn)擊MENU按鈕的時(shí)候,調(diào)用該方法
@Override
public boolean onCreateOptionsMenu(Menu menu) {
menu.add(0, 1, 1, R.string.exit);
menu.add(0,2,2,R.string.about);
return super.onCreateOptionsMenu(menu);
}
//當(dāng)客戶點(diǎn)擊菜單里的某一個(gè)選項(xiàng)時(shí),會(huì)調(diào)用該方法
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if(item.getItemId() == 1){
finish();
}
return super.onOptionsItemSelected(item);
}
getItemId:
它返回的是該postion對(duì)應(yīng)item的id
Mobile1題目:
java.security.MessageDigest類
功能:用于為應(yīng)用程序提供信息摘要算法的功能,如md5和SHA。換句話說(shuō),就是生成md5或者是SHA密碼。
相關(guān):
getinstance:靜態(tài)函數(shù),用來(lái)實(shí)例操作和初始操作。
update:處理數(shù)據(jù),更新摘要
reset:重置摘要
digest:明文變?yōu)槊芪?/p>
getBytes():
在Java里,String的getBytes()方法是得到一個(gè)操作系統(tǒng)默認(rèn)的編碼格式的字節(jié)數(shù)組。
Android系統(tǒng)下的String.getBytes()和new String()
Android屬于LINUX系統(tǒng),String是以UTF-8形式存儲(chǔ)的,因此默認(rèn)的String.getBytes()是長(zhǎng)度為3的數(shù)組,二通常WIN的String是以GBK形式存儲(chǔ)的。若不轉(zhuǎn)換,就可能出現(xiàn)亂碼
不同于getByte(),getByte()返回字符的ascii碼值
str.getBytes(UTF-8); 的意思是以UTF-8的編碼取得字節(jié)
Public class Test{
Public static void main(String args[]){
String str1 = new String(“runoob”);
Byte[] str2 = str1.getBytes();
System.out.println(str2);
str2 = str1.getBytes(“UTF-8”);
System.out.println(str2);
}
}
結(jié)果:
B@7852e922
B@4e25154f
toHexString():
Integer.toHexString():此方法返回的字符串表示的無(wú)符號(hào)整數(shù)參數(shù)所表示的值以十六進(jìn)制(基數(shù)為16)。
在加密代碼里,經(jīng)常看到類同Integer.toHexString(b[i] & 0xFF)這樣的代碼,那么這行代碼到底是什么意思呢(b是一個(gè)byte[])?為什么要&0xFF呢?
這句代碼的最后目的是把byte[]轉(zhuǎn)換為16進(jìn)制字符串
toHexString()是把一個(gè)int轉(zhuǎn)換為十六進(jìn)制String
& 0xFF是為了保證byte類型轉(zhuǎn)int后其二進(jìn)制的一致,即補(bǔ)零擴(kuò)展。那么為什么要補(bǔ)零擴(kuò)展呢?因?yàn)槲覀兪且衙恳粋€(gè)byte類型的數(shù)據(jù)都轉(zhuǎn)換位16進(jìn)制字符串,補(bǔ)零擴(kuò)展的話就可以忽略前24位
對(duì)于正數(shù),byte可以直接轉(zhuǎn)int,但是當(dāng)byte類型的數(shù)是負(fù)數(shù)時(shí),就比較特殊了。
int是32位,byte是8位,所以需要補(bǔ)位
負(fù)數(shù)在java里是以補(bǔ)碼表示
byte是一個(gè)字節(jié),最高位為符號(hào)位,則范圍為[10000000,01111111],即[-128,127],注意此處范圍邊界值10000000為-128。如:byte類型的-1是11111111
e.printStackTrace():
public void printStackTrace()將此 throwable 及其追隨輸出至標(biāo)準(zhǔn)錯(cuò)誤流。此方法將此
Throwable 對(duì)象的堆棧跟隨輸出至錯(cuò)誤輸出流,作為字段 System.err 的值。
當(dāng)try語(yǔ)句里出現(xiàn)異常時(shí),會(huì)執(zhí)行catch里的語(yǔ)句,java運(yùn)行時(shí)系統(tǒng)會(huì)自動(dòng)將catch括號(hào)里的Exception e 初始操作,也就是實(shí)例操作Exception類型的對(duì)象。e是此對(duì)象引用名稱。然后e(引用)會(huì)自動(dòng)調(diào)用Exception類里指定的方法,也就出現(xiàn)了e.printStackTrace() ;。
printStackTrace()方法的意思是:在命令行打印異常信息在程序里出錯(cuò)的位置及原因。
trim():
主要有2個(gè)用法:1、就是去掉字符串里前后的空白;這個(gè)方法的主要可以使用在判斷用戶輸入的密碼之類的。2、它不僅可以去除空白,還可以去除字符串里的制表符
equalsIgnoreCase():
equalsIgnoreCase() 方法用于將字符串與指定的對(duì)象比較,不考慮大小寫。
如果給定對(duì)象與字符串相等,則返回 true,否則返回 false。
equals() 會(huì)判斷大小寫區(qū)別,equalsIgnoreCase() 不會(huì)判斷大小寫區(qū)別:
First_Mobile題目:
getByte():
功能:返回字符的ascii碼值
不同于getBytes(),getBytes()方法是得到一個(gè)操作系統(tǒng)默認(rèn)的編碼格式的字節(jié)數(shù)組。
equals():
功能:用于將字符串與指定的對(duì)象比較。
結(jié)果:相等時(shí)返回true,反之返回false
getApplicationContext():
同上
LoopAndLoop題目:
Integer.parseInt():
這個(gè)方法是將字符串轉(zhuǎn)換為整型
方法解析字符串參數(shù)s為有符號(hào)十進(jìn)制整數(shù)。
將String字符類型數(shù)據(jù)轉(zhuǎn)換為Integer整型數(shù)據(jù)
.so文件:
Android里的so文件是動(dòng)態(tài)鏈接庫(kù),是二進(jìn)制文件,即ELF文件。多用于NDK開發(fā)里。
_JNIEnv::GetMethodID:
GetFieldID是得到j(luò)ava類里的參數(shù)ID,GetMethodID得到j(luò)ava類里方法的ID,它們只能調(diào)用類里聲明為 public的參數(shù)或方法。
_JNIEnv::CallIntMethod:
得到j(luò)ava類里Int類型的方法
SafeBox題目:
Math.abs():
abs() 返回參數(shù)的絕對(duì)值。參數(shù)可以是 int, float, long, double, short, byte類型。
easy-100題目:
new:
在Java里,new關(guān)鍵字被使用來(lái)創(chuàng)建一個(gè)新的對(duì)象,可以理解為創(chuàng)建的意思。使用關(guān)鍵字new來(lái)創(chuàng)建一個(gè)對(duì)象也叫類的實(shí)例化。關(guān)鍵字 new 意味著內(nèi)存的分配和初始操作,new 調(diào)用的方法就是類的構(gòu)造方法。
Byte a[] = new byte[1024]
new其實(shí)就是創(chuàng)建一個(gè)新的熟悉,在內(nèi)存里開辟一個(gè)空間。new 就是創(chuàng)建一個(gè)對(duì)象的意思。這里new就是創(chuàng)建一個(gè)byte數(shù)組,byte[1024]是數(shù)組長(zhǎng)度為1024
byte byt[] = new byte[1024]; //1024是什么意思
這里的1024是一個(gè)數(shù)字,表示這個(gè)byte數(shù)組的長(zhǎng)度。
// 推薦這么寫,你看main方法就知道String[] args 而不是 String args[]
byte[] byt = new byte[1024];
new String(XXX,UTF-8):
str.getBytes(UTF-8); 的意思是以UTF-8的編碼取得字節(jié)
new String(XXX,UTF-8); 的意思是以UTF-8的編碼生成字符串
new String(“參數(shù)”):
String str3 = new String(“abcd”)的實(shí)現(xiàn)過程:直接在堆里創(chuàng)建對(duì)象。如果后來(lái)又有String str4 = new String(“abcd”),str4不會(huì)指向之前的對(duì)象,而是重新創(chuàng)建一個(gè)對(duì)象并指向它,所以如果此時(shí)進(jìn)行str3==str4返回值是false,因?yàn)閮蓚€(gè)對(duì)象的地址不一樣,如果是str3.equals(str4),返回true,因?yàn)閮?nèi)容相同。
例如:
this.v = new String(v0_2, “utf-8”);
將v0_2數(shù)據(jù)保存在 v 字符串里。
Java 一個(gè)類調(diào)用另一個(gè)類里的方法:
如果另一個(gè)類里的那個(gè)方法是私有,就不能直接調(diào)用到,如果是其他類型的話看情況,如果是靜態(tài)的(static)話,直接用類名可以調(diào)用到,如果是非靜態(tài)的,就需要利用另一個(gè)類的實(shí)例(也就是用那個(gè)類生成的對(duì)象)來(lái)調(diào)用。
如:
class A{
public static void a(){}
public void b(){}
}
public class B{
public static void main(String[] args){
A.a();//靜態(tài),形式為類名.方法名()
new A().b();//非靜態(tài),形式為類名().方法名()
}
}
Puppy myPuppy = new Puppy( “tommy” );
注意:創(chuàng)建對(duì)象Puppy為類名
MainActivity.a(this.a, MainActivity.a(this.a), this.a.getText().toString())
其里第一個(gè)參數(shù)是句柄,第二個(gè)參數(shù)是調(diào)用了 a 函數(shù)(另外一個(gè)a)返回一個(gè)字符串,第三個(gè)參數(shù)是我們輸入的字符串。
getApplicationInfo():
ApplicationInfo是android.content.pm包下的一個(gè)實(shí)體類,用于封裝應(yīng)用的信息,flags是其里的一個(gè)成員變量public int flags = 0;用于保存應(yīng)用的標(biāo)志信息。
ApplicationInfo 通過它可以得到一個(gè)應(yīng)用基本信息。這些信息是從AndroidManifest.xml的< application >標(biāo)簽獲取的
以ApplicationInfo的實(shí)例對(duì)象info為例
系統(tǒng)應(yīng)用 -> info.flags & ApplicationInfo.FLAG_SYSTEM == ApplicationInfo.FLAG_SYSTEM
解讀:ApplicationInfo.FLAG_SYSTEM 是二進(jìn)制1左移0位,還是1,flags & 1 = 1,則flags的二進(jìn)制末位需為1,
因此只有flags是奇數(shù),對(duì)應(yīng)的應(yīng)用才會(huì)是系統(tǒng)應(yīng)用。其他的屬性用法類同。
InputStream:
在java里InputStream是字節(jié)輸入流,用來(lái)將文件里的數(shù)據(jù)讀取到j(luò)ava程序里。
InputStream為所有字節(jié)輸入流的頂層父類,是一個(gè)抽象類。如果要用,需要使用子類。
InputStream這個(gè)抽象類是所有基于字節(jié)的輸入流的超類,抽象了Java的字節(jié)輸入模型。
getResources():
getResources()這類方法就能夠獲取存在系統(tǒng)的資源
比如:把資源文件放到應(yīng)用程序的/raw/raw下。那么就能夠在應(yīng)用里通過getResources獲取資源后。以openRawResource方法(不帶后綴的資源文件名稱)打開這個(gè)文件
InputStream openRawResource(int id) 獲取資源的數(shù)據(jù)流,讀取資源數(shù)據(jù)
把一個(gè)圖片資源,添加你的文件到你工程里res/drawable/目錄里去,可以在代碼或XML布局里,引用它也可以用資源編號(hào),比如你選擇一個(gè)文件只要去掉后綴就可以了(例如:mmm_image.png 引用它是就是mm_image)。
當(dāng)需要使用的xml資源的時(shí)候,就可以使用context.getResources().getDrawable(R…資源的地址如:R.String.ok);
當(dāng)你方法里面沒有Context參數(shù),可以 this.getContext().getResources();這樣就可以了。
getAssets():
getAssets():訪問資產(chǎn)目錄
assets文件夾里面的文件都是保持原本的文件格式,需要用AssetManager以字節(jié)流的形式讀取文件。assets的讀取方式:先在Activity里面調(diào)用getAssets() 來(lái)獲取。
available():
要一次讀取多個(gè)字節(jié)時(shí),經(jīng)常用到InputStream.available()方法,這個(gè)方法可以在讀寫操作前先得知數(shù)據(jù)流里有多少個(gè)字節(jié)可以讀取。
read():
read() : 從輸入流里讀取數(shù)據(jù)的下一個(gè)字節(jié),返回0到255范圍內(nèi)的int字節(jié)值。如果因?yàn)橐呀?jīng)到達(dá)流末尾而沒有可用的字節(jié),則返回-1。在輸入數(shù)據(jù)可用、檢測(cè)到流末尾或者拋出異常前,此方法一直阻塞。
read(byte[] b) : 從輸入流里讀取一定數(shù)量的字節(jié),并將其存儲(chǔ)在緩沖區(qū)數(shù)組 b 里。以整數(shù)形式返回實(shí)際讀取的字節(jié)數(shù)。在輸入數(shù)據(jù)可用、檢測(cè)到文件末尾或者拋出異常前,此方法一直阻塞。
如果 b 的長(zhǎng)度為 0,則不讀取任何字節(jié)并返回 0;否則,嘗試讀取至少一個(gè)字節(jié)。如果因?yàn)榱魑挥谖募┪捕鴽]有可用的字節(jié),則返回值 -1;否則,至少讀取一個(gè)字節(jié)并將其存在 b 里。
將讀取的第一個(gè)字節(jié)存儲(chǔ)在元素 b[0] 里,下一個(gè)存儲(chǔ)在 b[1] 里,依次類推。讀取的字節(jié)數(shù)最多等于b 的長(zhǎng)度。設(shè) k 為實(shí)際讀取的字節(jié)數(shù);這些字節(jié)將存儲(chǔ)在 b[0] 到 b[k-1] 的元素里,不影響 b[k] 到b[b.length-1] 的元素。
System.arraycopy:
System.arrayCopy的源代碼聲明 :
public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
代碼解釋:
Object src : 原數(shù)組
int srcPos : 從原數(shù)據(jù)的起始位置開始
Object dest : 目標(biāo)數(shù)組
int destPos : 目標(biāo)數(shù)組的開始起始位置
int length : 要copy的數(shù)組的長(zhǎng)度
比如 :我們有一個(gè)數(shù)組數(shù)據(jù) byte[] srcBytes = new byte[]{2,4,0,0,0,0,0,10,15,50}; // 源數(shù)組
byte[] destBytes = new byte[5]; // 目標(biāo)數(shù)組
我們使用System.arraycopy進(jìn)行轉(zhuǎn)換(copy)
System.arrayCopy(srcBytes,0,destBytes ,0,5)
上面這段代碼就是 : 創(chuàng)建一個(gè)一維空數(shù)組,數(shù)組的長(zhǎng)度為 12位,然后將srcBytes源數(shù)組里 從0位 到 第5位之間的數(shù)值 copy 到 destBytes目標(biāo)數(shù)組里,在目標(biāo)數(shù)組的第0位開始放置.
那么這行代碼的運(yùn)行效果應(yīng)該是 2,4,0,0,0,
implements:
關(guān)鍵字implements是一個(gè)類,實(shí)現(xiàn)一個(gè)接口用的關(guān)鍵字,它是用來(lái)實(shí)現(xiàn)接口里定義的抽象方法。實(shí)現(xiàn)一個(gè)接口,需實(shí)現(xiàn)接口里的所有方法。使用 implements 關(guān)鍵字可以變相的令java具有多繼承的特性,使用范圍為類繼承接口的情況,可以同時(shí)繼承多個(gè)接口(接口跟接口之間采用逗號(hào)分隔)
還有幾點(diǎn)需要注意:
(1)接口可以被多重實(shí)現(xiàn)(implements),抽象類只能被單一繼承(extends)
(2)接口只有定義,抽象類可以有定義和實(shí)現(xiàn)
(3)接口的字段定義默認(rèn)為:public static final, 抽象類字段默認(rèn)是”friendly”(本包可見)
SecretKeySpec:
目前主流的加密方式有:(對(duì)稱加密)AES、DES (非對(duì)稱加密)RSA、DSA
SecretKeySpec類是KeySpec接口的實(shí)現(xiàn)類,用于構(gòu)建秘密密鑰規(guī)范。可根據(jù)一個(gè)字節(jié)數(shù)組構(gòu)造一個(gè)SecretKey,而無(wú)須通過一個(gè)(基于provider的)SecretKeyFactory。
//根據(jù)字節(jié)數(shù)組生成AES密鑰
this.a = new SecretKeySpec(arg1, “AES”);
MessageDigest:
MessageDigest 主要是用于數(shù)據(jù)加密
java.security.MessageDigest類用于為應(yīng)用程序提供信息摘要算法的功能,如 MD5 或 SHA 算法。簡(jiǎn)單點(diǎn)說(shuō)就是用于生成散列碼。信息摘要是安全的單向哈希函數(shù),它接收隨意大小的數(shù)據(jù),輸出固定長(zhǎng)度的哈希值。
MessageDigest 通過其getInstance系列靜態(tài)函數(shù)來(lái)進(jìn)行實(shí)例操作和初始操作。MessageDigest 對(duì)象通過update 方法處理數(shù)據(jù)。不論什么時(shí)候都能夠調(diào)用reset 方法重置摘要。一旦全部須要更新的數(shù)據(jù)都已經(jīng)被更新了,應(yīng)該通過digest 方法里的一個(gè)完畢哈希計(jì)算并返回結(jié)果。
對(duì)于給定數(shù)量的更新數(shù)據(jù),digest 方法僅僅能被調(diào)用一次。digest 方法被調(diào)用后,
MessageDigest 對(duì)象被又一次設(shè)置成其初始狀態(tài)。
MessageDigest(String algorithm):
創(chuàng)建具有指定算法名稱的MessageDigest 實(shí)例對(duì)象。
getInstance(String algorithm):
生成實(shí)現(xiàn)指定摘要算法的 MessageDigest 對(duì)象。
getInstance(String algorithm,Provider provider):
生成實(shí)現(xiàn)指定提供程序提供的指定算法的 MessageDigest 對(duì)象,假設(shè)該算法可從指定的提供程序得到。
getInstance(String algorithm,String provider):
生成實(shí)現(xiàn)指定提供程序提供的指定算法的 MessageDigest 對(duì)象,假設(shè)該算法可從指定的提供程序得到。
digest():
通過運(yùn)行諸如填充之類的操作完成哈希計(jì)算。
digest(byte[] input):
通過指定的字節(jié)數(shù)組對(duì)摘要進(jìn)行最后更新,然后完成摘要計(jì)算。
digest(byte[] buf,int offset,int len):
通過運(yùn)行諸如填充之類的操作完成哈希計(jì)算。
update(byte input)
通過指定的字節(jié)更新摘要。
update(bute[] input):
通過指定的字節(jié)數(shù)組更新摘要。
update(byte[] input,int offset,int len):
通過指定的字節(jié)數(shù)組,從指定的偏移量起更新摘要。
update(ByteBuffer input):
通過指定的 ByteBuffer 更新摘要。
Cipher.getInstance(“AES/ECB/PKCS5Padding”):
該類位于javax.crypto包下,此類為加密和解密提供密碼功能,它構(gòu)成了 Java Cryptographic Extension (JCE) 框架的核心。
Cipher創(chuàng)建:
創(chuàng)建 Cipher 對(duì)象,應(yīng)用程序調(diào)用 Cipher 的 getInstance 方法并將所請(qǐng)求轉(zhuǎn)換的名稱傳遞給它。還可以指定提供者的名稱(可選)。
轉(zhuǎn)換是一個(gè)字符串,它描述為產(chǎn)生某類輸出而在給定的輸入上執(zhí)行的操作(或一組操作)。轉(zhuǎn)換包括加密算法的名稱(例如AES,DES),后面可能跟有一個(gè)反饋模式和填充方案。如以下形式:
“算法/模式/填充”或“算法”(后一類情況下,使用模式和填充方案特定于提供者的默認(rèn)值)。例如:
//根據(jù)指定算法AES生成成密碼器
Cipher cipher = Cipher.getInstance(“AES/ECB/PKCS5Padding”);
Cipher cipher = Cipher.getInstance(“DES”);
goto:
跳出多重循環(huán)
跳轉(zhuǎn)的時(shí)候,直接跳過了這個(gè)循環(huán)
init():
init() 方法是初始操作方法,用于在啟動(dòng)Applet程序之前做一些需要的工作
Java對(duì)象在被創(chuàng)建時(shí),會(huì)進(jìn)行實(shí)例操作操作。該部分操作封裝在方法里,并且子類的方法里會(huì)首先對(duì)父類方法的調(diào)用。
init是對(duì)象構(gòu)造器方法,也就是說(shuō)在程序執(zhí)行 new 一個(gè)對(duì)象調(diào)用該對(duì)象類的 constructor 方法時(shí)才會(huì)執(zhí)行init方法。
doFinal():
屬于java.security和javax.crypto包下的類
此方法結(jié)束單部分加密或者解密操作。
此方法接收需要加密或者解密的完整報(bào)文,返回處理結(jié)果
此方法正常調(diào)用結(jié)束之后Cipher會(huì)重置為初始操作狀態(tài)。
例題:
加密算法:
解密算法:
總結(jié)
以上是生活随笔為你收集整理的CTF-Bugku逆向题Android方法归纳的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 多线程:管cheng法
- 下一篇: android面试service,And