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