⑴ python os.rename 報錯OSError: [Errno 2] No such file or directory
for APK in apklist:
portion = os.path.splitext(APK)
if portion[1] == ".apk":
newname = portion[0] + ".zip"
os.rename(os.path.join(path,APK),newname) #os.rename是在當前目錄下操作,是不是得加上path這個路徑
⑵ python 能開發 android 應用嗎
python可以開發Android應用。
Python是一種解釋型腳本語言,可以應用於以下領域:
1、Web 和 Internet開發;
2、科學計算和統計;
3、人工智慧;
4、教育;
5、桌面界面開發;
6、軟體開發;
7、後端開發。
(2)python調用dex擴展閱讀:
操作系統與應用程序的溝通橋梁,應用分為兩層:函數層(Library)和虛擬機(Virtual Machine)。 Bionic是 Android 改良libc的版本。
Android 同時包含了Webkit,所謂的Webkit 就是Apple Safari 瀏覽器背後的引擎。Surface flinger 是就2D或3D的內容顯示到屏幕上。Android使用工具鏈(Toolchain)為Google自製的Bionic Libc。
Android採用OpenCORE作為基礎多媒體框架。
Open CORE可分7大塊:PVPlayer、PVAuthor、Codec、PacketVideo Multimedia Framework(PVMF)、Operating System Compatibility Library(OSCL)、Common、OpenMAX。
Android 使用skia 為核心圖形引擎,搭配OpenGL/ES。skia與Linux Cairo功能相當,但相較於Linux Cairo, skia 功能還只是雛形的。
2005年Skia公司被Google收購,2007年初,Skia GL源碼被公開,Skia 也是Google Chrome 的圖形引擎。
Android的多媒體資料庫採用SQLite資料庫系統。資料庫又分為共用資料庫及私用資料庫。用戶可通過ContentResolver類(Column)取得共用資料庫。
Android的中間層多以java 實現,並且採用特殊的Dalvik 虛擬機(Dalvik Virtual Machine)。Dalvik虛擬機是一種「暫存器型態」(Register Based)的Java虛擬機,變數皆存放於暫存器中,虛擬機的指令相對減少。
Dalvik虛擬機可以有多個實例(Instance), 每個Android應用程序都用一個自屬的Dalvik虛擬機來運行,讓系統在運行程序時可達到優化。Dalvik 虛擬機並非運行Java位元組碼(Bytecode),而是運行一種稱為.dex格式的文件。
參考資料:網路-Android
⑶ python怎麼獲取某個人的微信朋友圈的信息
1、Python(KK 英語發音:/'paɪθɑn/, DJ 英語發音:/ˈpaiθən/)是一種面向對象、直譯式計算機程序設計語言,由Guido van Rossum於1989年底發明。第一個公開發行版發行於1991年。Python語法簡捷而清晰,具有豐富和強大的類庫。
2、它常被昵稱為膠水語言,它能夠很輕松的把用其他語言製作的各種模塊(尤其是C/C++)輕松地聯結在一起。常見的一種應用情形是,使用python快速生成程序的原型(有時甚至是程序的最終界面),然後對其中有特別要求的部分,用更合適的語言改寫。比如3D游戲中的圖形渲染模塊,速度要求非常高,就可以用C++重寫。
3、從UI獲取文本信息是最為簡單的方法,於是應該優先逆向UI代碼部分。逆向微信apk首先解包微信apk,用dex2jar反編譯classes.dex,然後用JD-GUI查看jar源碼。當然,能看到的源碼都是經過高度混淆的。但是,繼承自安卓重要組件(如Activity、Service等)的類名無法被混淆,於是還是能從中看到點東西。首先定位到微信APP packagecom.tencent.mm。在 com.tencent.mm中,我們找到一個 ui包,有點意思。展開 com.tencent.mm.ui,發現多個未被混淆的類,其中發現 MMBaseActivity直接繼承自 Activity, MMFragmentActivity繼承自 ActionBarActivity, MMActivity繼承自MMFragmentActivity,並且 MMActivity是微信中大多數Activity的父類。
4、現在需要找出朋友圈的Activity,為此要用Xposed hook MMActivity。創建一個Xposed模塊,參考[TUTORIAL]Xposed mole devlopment,創建一個Xposed項目。簡單Xposed模塊的基本思想是:hook某個APP中的某個方法,從而達到讀寫數據的目的。
5、在findAndHookMethod方法中,第一個參數為完整類名,第三個參數為需要hook的方法名,其後若干個參數分別對應該方法的各形參類型。在這里,Activity.setContentView(View view)方法只有一個類型為Vie的形參,因此傳入一個View.class。
6、結果是運行時可以從Log中讀取到每個Activity中的所有的TextView的顯示內容。但是,因為View中的數據並不一定在setContentView()時就載入完畢,因此小編的實驗結果是,log中啥都沒有。
⑷ python怎麼爬取某個人的微信朋友圈的信息
主要思路
從UI獲取文本信息是最為簡單的方法,於是應該優先逆向UI代碼部分。
逆向微信apk
首先解包微信apk,用dex2jar反編譯classes.dex,然後用JD-GUI查看jar源碼。當然,能看到的源碼都是經過高度混淆的。但是,繼承自安卓重要組件(如Activity、Service等)的類名無法被混淆,於是還是能從中看到點東西。
首先定位到微信APP package。我們知道這個是 com.tencent.mm。
在 com.tencent.mm
中,我們找到一個 ui
包,有點意思。
展開 com.tencent.mm.ui
,發現多個未被混淆的類,其中發現 MMBaseActivity直接繼承自 Activity
, MMFragmentActivity
繼承自 ActionBarActivity
, MMActivity
繼承自 MMFragmentActivity
,並且 MMActivity
是微信中大多數Activity的父類:
public class MMFragmentActivity
extends ActionBarActivity
implements SwipeBackLayout.a, b.a {
...
}
public abstract class MMActivity
extends MMFragmentActivity {
...
}
public class MMBaseActivity
extends Activity {
...
}
現在需要找出朋友圈的Activity,為此要用Xposed hook MMActivity。
創建一個Xposed模塊
參考 [TUTORIAL]Xposed mole devlopment,創建一個Xposed項目。
簡單Xposed模塊的基本思想是:hook某個APP中的某個方法,從而達到讀寫數據的目的。
小編嘗試hook com.tencent.mm.ui.MMActivity.setContentView這個方法,並列印出這個Activity下的全部TextView內容。那麼首先需要遍歷這個Activity下的所有TextView,遍歷ViewGroup的方法參考了SO的以下代碼:
private void getAllTextViews(final View v) {if (v instanceof ViewGroup) {
ViewGroup vg = (ViewGroup) v;
for (int i = 0; i < vg.getChildCount(); i++) {View child = vg.getChildAt(i);
getAllTextViews(child);
}
} else if (v instanceof TextView ) {
dealWithTextView((TextView)v); //dealWithTextView(TextView tv)方法:列印TextView中的顯示文本}
}
Hook MMActivity.setContentView
的關鍵代碼如下:
findAndHookMethod("com.tencent.mm.ui.MMActivity", lpparam.classLoader, "setContentView", View.class, new XC_MethodHook() {...
});
在findAndHookMethod方法中,第一個參數為完整類名,第三個參數為需要hook的方法名,其後若干個參數分別對應該方法的各形參類型。在這里, Activity.setContentView(View view)方法只有一個類型為 View
的形參,因此傳入一個 View.class
。
現在,期望的結果是運行時可以從Log中讀取到每個Activity中的所有的TextView的顯示內容。
但是,因為View中的數據並不一定在 setContentView()時就載入完畢,因此小編的實驗結果是,log中啥都沒有。
意外的收獲
當切換到朋友圈頁面時,Xposed模塊報了一個異常,異常源從 com.tencent.mm.plugin.sns.ui.SnsTimeLineUI這個類捕捉到。從類名上看,這個很有可能是朋友圈首頁的UI類。展開這個類,發現更多有趣的東西:
這個類下有個子類 a
(被混淆過的類名),該子類下有個名為 gyO的 ListView
類的實例。我們知道, ListView
是顯示列表類的UI組件,有可能就是用來展示朋友圈的列表。
順藤摸瓜
那麼,我們先要獲得一個 SnsTimeLineUI.a.gyO的實例。但是在這之前,要先獲得一個 com.tencent.mm.plugin.sns.ui.SnsTimeLineUI.a的實例。繼續搜索,發現 com.tencent.mm.plugin.sns.ui.SnsTimeLineUI有一個名為 gLZ
的 SnsTimeLineUI.a
實例,那麼我們先取得這個實例。
經過測試, com.tencent.mm.plugin.sns.ui.SnsTimeLineUI.a(boolean, boolean, String, boolean)這個方法在每次初始化微信界面的時候都會被調用。因此我們將hook這個方法,並從中取得 gLZ。
findAndHookMethod("com.tencent.mm.plugin.sns.ui.SnsTimeLineUI", lpparam.classLoader, "a", boolean.class, boolean.class, String.class, boolean.class, new XC_MethodHook() {@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {XposedBridge.log("Hooked. ");
Object currentObject = param.thisObject;
for (Field field : currentObject.getClass().getDeclaredFields()) { //遍歷類成員field.setAccessible(true);
Object value = field.get(currentObject);
if (field.getName().equals("gLZ")) {
XposedBridge.log("Child A found.");
childA = value;
//這里獲得了gLZ
...
}
}
}
});
現在取得了 SnsTimeLineUI.a
的一個實例 gLZ
,需要取得這個類下的 ListView
類型的 gyO
屬性。
private void dealWithA() throws Throwable{if (childA == null) {
return;
}
for (Field field : childA.getClass().getDeclaredFields()) { //遍歷屬性field.setAccessible(true);
Object value = field.get(childA);
if (field.getName().equals("gyO")) { //取得了gyOViewGroup vg = (ListView)value;
for (int i = 0; i < vg.getChildCount(); i++) { //遍歷這個ListView的每一個子View...
View child = vg.getChildAt(i);
getAllTextViews(child); //這里調用上文的getAllTextViews()方法,每一個子View里的所有TextView的文本...
}
}
}
}
現在已經可以將朋友圈頁面中的全部文字信息列印出來了。我們需要根據TextView的子類名判斷這些文字是朋友圈內容、好友昵稱、點贊或評論等。
private void dealWithTextView(TextView v) {String className = v.getClass().getName();String text = ((TextView)v).getText().toString().trim().replaceAll("\n", " ");if (!v.isShown())
return;
if (text.equals(""))
return;
if (className.equals("com.tencent.mm.plugin.sns.ui.AsyncTextView")) {//好友昵稱
...
}
else if (className.equals("com.tencent.mm.plugin.sns.ui.SnsTextView")) {//朋友圈文字內容
...
}
else if (className.equals("com.tencent.mm.plugin.sns.ui.MaskTextView")) {if (!text.contains(":")) {
//點贊
...
} else {
//評論
...
}
}
}
自此,我們已經從微信APP里取得了朋友圈數據。當然,這部分抓取代碼需要定時執行。因為從 ListView中抓到的數據只有當前顯示在屏幕上的可見部分,為此需要每隔很短一段時間再次執行,讓用戶在下滑載入的過程中抓取更多數據。
剩下的就是數據分類處理和格式化輸出到文件,受本文篇幅所限不再贅述,詳細實現可參考作者GitHub上的源碼。
⑸ xposed + python 怎麼爬取微信朋友圈的數據
有JAVA的,你參考一下
主要思路
從UI獲取文本信息是最為簡單的方法,於是應該優先逆向UI代碼部分。
逆向微信apk
首先解包微信apk,用dex2jar反編譯classes.dex,然後用JD-GUI查看jar源碼。當然,能看到的源碼都是經過高度混淆的。但是,繼承自安卓重要組件(如Activity、Service等)的類名無法被混淆,於是還是能從中看到點東西。
首先定位到微信APP package。我們知道這個是 com.tencent.mm
。
在 com.tencent.mm
中,我們找到一個 ui
包,有點意思。
展開 com.tencent.mm.ui
,發現多個未被混淆的類,其中發現 MMBaseActivity
直接繼承自 Activity
, MMFragmentActivity
繼承自 ActionBarActivity
, MMActivity
繼承自 MMFragmentActivity
,並且 MMActivity
是微信中大多數Activity的父類:
public class MMFragmentActivity
extends ActionBarActivity
implements SwipeBackLayout.a, b.a {
...
}
public abstract class MMActivity
extends MMFragmentActivity {
...
}
public class MMBaseActivity
extends Activity {
...
}
現在需要找出朋友圈的Activity,為此要用Xposed hook MMActivity
。
創建一個Xposed模塊
參考 [TUTORIAL]Xposed mole devlopment
,創建一個Xposed項目。
簡單Xposed模塊的基本思想是:hook某個APP中的某個方法,從而達到讀寫數據的目的。
小編嘗試hook com.tencent.mm.ui.MMActivity.setContentView
這個方法,並列印出這個Activity下的全部TextView內容。那麼首先需要遍歷這個Activity下的所有TextView,遍歷ViewGroup的方法參考了SO的以下代碼:
private void getAllTextViews(final View v) {
if (v instanceof ViewGroup) {
ViewGroup vg = (ViewGroup) v;
for (int i = 0; i < vg.getChildCount(); i++) {
View child = vg.getChildAt(i);
getAllTextViews(child);
}
} else if (v instanceof TextView ) {
dealWithTextView((TextView)v); //dealWithTextView(TextView tv)方法:列印TextView中的顯示文本
}
}
Hook MMActivity.setContentView
的關鍵代碼如下:
findAndHookMethod("com.tencent.mm.ui.MMActivity", lpparam.classLoader, "setContentView", View.class, new XC_MethodHook() {
...
});
在findAndHookMethod方法中,第一個參數為完整類名,第三個參數為需要hook的方法名,其後若干個參數分別對應該方法的各形參類型。在這里, Activity.setContentView(View view)
方法只有一個類型為 View
的形參,因此傳入一個 View.class
。
現在,期望的結果是運行時可以從Log中讀取到每個Activity中的所有的TextView的顯示內容。
但是,因為View中的數據並不一定在 setContentView()
時就載入完畢,因此小編的實驗結果是,log中啥都沒有。
意外的收獲
當切換到朋友圈頁面時,Xposed模塊報了一個異常,異常源從 com.tencent.mm.plugin.sns.ui.SnsTimeLineUI
這個類捕捉到。從類名上看,這個很有可能是朋友圈首頁的UI類。展開這個類,發現更多有趣的東西:
這個類下有個子類 a
(被混淆過的類名),該子類下有個名為 gyO
的 ListView
類的實例。我們知道, ListView
是顯示列表類的UI組件,有可能就是用來展示朋友圈的列表。
順藤摸瓜
那麼,我們先要獲得一個 SnsTimeLineUI.a.gyO
的實例。但是在這之前,要先獲得一個 com.tencent.mm.plugin.sns.ui.SnsTimeLineUI.a
的實例。繼續搜索,發現 com.tencent.mm.plugin.sns.ui.SnsTimeLineUI
有一個名為 gLZ
的 SnsTimeLineUI.a
實例,那麼我們先取得這個實例。
經過測試, com.tencent.mm.plugin.sns.ui.SnsTimeLineUI.a(boolean, boolean, String, boolean)
這個方法在每次初始化微信界面的時候都會被調用。因此我們將hook這個方法,並從中取得 gLZ
。
findAndHookMethod("com.tencent.mm.plugin.sns.ui.SnsTimeLineUI", lpparam.classLoader, "a", boolean.class, boolean.class, String.class, boolean.class, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
XposedBridge.log("Hooked. ");
Object currentObject = param.thisObject;
for (Field field : currentObject.getClass().getDeclaredFields()) { //遍歷類成員
field.setAccessible(true);
Object value = field.get(currentObject);
if (field.getName().equals("gLZ")) {
XposedBridge.log("Child A found.");
childA = value;
//這里獲得了gLZ
...
}
}
}
});
現在取得了 SnsTimeLineUI.a
的一個實例 gLZ
,需要取得這個類下的 ListView
類型的 gyO
屬性。
private void dealWithA() throws Throwable{
if (childA == null) {
return;
}
for (Field field : childA.getClass().getDeclaredFields()) { //遍歷屬性
field.setAccessible(true);
Object value = field.get(childA);
if (field.getName().equals("gyO")) { //取得了gyO
ViewGroup vg = (ListView)value;
for (int i = 0; i < vg.getChildCount(); i++) { //遍歷這個ListView的每一個子View
...
View child = vg.getChildAt(i);
getAllTextViews(child); //這里調用上文的getAllTextViews()方法,每一個子View里的所有TextView的文本
...
}
}
}
}
現在已經可以將朋友圈頁面中的全部文字信息列印出來了。我們需要根據TextView的子類名判斷這些文字是朋友圈內容、好友昵稱、點贊或評論等。
private void dealWithTextView(TextView v) {
String className = v.getClass().getName();
String text = ((TextView)v).getText().toString().trim().replaceAll("\n", " ");
if (!v.isShown())
return;
if (text.equals(""))
return;
if (className.equals("com.tencent.mm.plugin.sns.ui.AsyncTextView")) {
//好友昵稱
...
}
else if (className.equals("com.tencent.mm.plugin.sns.ui.SnsTextView")) {
//朋友圈文字內容
...
}
else if (className.equals("com.tencent.mm.plugin.sns.ui.MaskTextView")) {
if (!text.contains(":")) {
//點贊
...
} else {
//評論
...
}
}
}
自此,我們已經從微信APP里取得了朋友圈數據。當然,這部分抓取代碼需要定時執行。因為從 ListView
中抓到的數據只有當前顯示在屏幕上的可見部分,為此需要每隔很短一段時間再次執行,讓用戶在下滑載入的過程中抓取更多數據。
剩下的就是數據分類處理和格式化輸出到文件,受本文篇幅所限不再贅述,詳細實現可參考作者GitHub上的源碼。
⑹ python怎麼發sorkect包
有以下幾個步驟:
1.用aapt命令生成R.java文件
2.用aidl命令生成相應java文件
3.用javac命令編譯java源文件生成class文件
4.用dx.bat將class文件轉換成classes.dex文件
5.用aapt命令生成資源包文件resources.ap_
6.用apkbuilder.bat打包資源和classes.dex文件,生成unsigned.apk
7.用jarsinger命令對apk認證,生成signed.apk
⑺ Android反編譯(三)— 手動編譯
PS: 最近沒工作,沒工作就沒需求,沒需求就沒什麼技術總結的靈感,那就沒更新什麼。但是兩個月不更新了,要是三個月不更新就會出大事,所以這次打算做一件有意思又不難的事。
之前有發文章寫過反編譯,今天就來試試反編譯之正編譯,開玩笑的,就是試試手動編譯的過程, 平時我們在項目中編譯出包都是使用Gradle直接執行assemble任務就能解決,我打算試試手動模擬整個過程。當然我也是第一次這樣搞,所以如果有寫得不對的地方,還望指出。
眾所周知,apk實質上就是一個壓縮包。復習一下,我們寫個最簡單的Demo,然後打包,然解壓,注意是解壓,不是反編譯,意義是不同的。
注意我這個Demo很簡單,什麼都不引入
然後我們看看整個出包的過程,隨便從網上拿張圖
然後這里我們用Android SDK給我們提供的工具來完成整個流程,工具在sdk文件夾下的build-tools文件夾下,有什麼aapt.exe、dx.bat,用的就是這些
這步應該是整個流程最簡單的吧,我感覺,所以從最簡單的開始。
我們先看看生成的dex有什麼
對比項目,我是一開始最基本的項目,什麼都沒動,所以只有一個MainActivity.clas,所以這里肯定是要先想辦法得到BuildConfig.class和R.class。
輸入命令:
aapt p -f -m -J <輸出路徑> -S <res路徑> -I <android.jar路徑> -M <Manifest路徑>
下一步,我們需要BuildConfig.class
這個BuildConfig.java是由gradle在我們配置好gradle之後自己幫我們生成的,所以我們直接拿來用,然後再javac就得到class文件了
然後我們再編譯我們的MainActivity.java並將它們放到同一個文件夾下, MainActivity因為引用了Android.jar和R文件,所以編譯時注意點,我為此被動好好的復習了一遍javac,都是淚
最後一步,我們用dx工具就能打出dex文件了
然後執行命令就得到一個Dex文件,看看這個文件裡面和上面直接打出的apk中的Dex文件有什麼不同:
看圖,我們上一步已經生成.dex了,那麼我們需要和compiled Resource 還有 Other Resource 一起生成APK。
我們先來生成compiled Resource,也就是resources.arsc
發現之前使用aapt生成R文件的時候沒寫完整,當時可以加一個-F參數直接生成arsc和Manifest
導出的abc.zip裡面就有resources.arsc和AndroidManifest.xml。
因為之前寫漏了,所以肯定要重新編一次MainActivity.java和Dex
我們把剛才的dex文件和aapt生成的resources.arsc、AndroidManifest.xml和res放到一個文件夾裡面。
PS:res文件夾也是上面aapt的命令生成的
然後我們對比這個文件夾和之前apk解壓的文件夾
最後運行
看來是成功了。
再說說遇到的還有兩個問題,並說下我解決問題的思路
(1)我把它們都放到一個文件夾之後,我壓縮成壓縮包,然後改後綴成.apk,然後發現安裝不了,我就直接反編譯,發現發編譯失敗,提示包有問題,以我多點玩包的經驗,我感覺就是壓縮工具出了問題,然後我去下個「好壓」(這不是廣告啊),然後就能正常反編譯了。
(2)但是還是安裝不了,再根據我多年的玩包經驗,我感覺是簽名問題,然後我隨便給這個包上一個簽名,就能正常安裝得到上圖的結果了。
總體來說,還真挺好玩的,這整個過程,就是翻車了幾次。做完之後感覺非常牛逼,為什麼這樣說,因為我知道這整個過程,我就可以做到,我不經過gradle來打包,我自己寫個python腳本來調用aapt和dx來打包也是能做到的。
當然上面純屬異想天開,因為這是個什麼都沒有的Demo所以覺得簡單,要是一個真實的項目,我感覺肯定要有很多坑,別的先不說,一個項目那麼多依賴關系,我這javac要搞死人。
最後如果有不對的地方,希望有大佬能夠指出,畢竟能運行也不能證明完全沒問題。然後我使用的build-tools是28的,不敢保證其它版本包括以後版本的玩法都一樣。
⑻ pathclassloader和dexclassloader的區別
pathclassloader和dexclassloader的區別如下:
1.DexClassLoader和PathClassLoader都屬於符合雙親委派模型的類載入器(因為它們沒有重載loadClass方法)。也就是說,它們在載入一個類之前,回去檢查自己以及自己以上的類載入器是否已經載入了這個類。如果已經載入過了,就會直接將之返回,而不會重復載入。
2.DexClassLoader和PathClassLoader其實都是通過DexFile這個類來實現類載入的。這里需要順便提一下的是,Dalvik虛擬機識別的是dex文件,而不是class文件。因此,我們供類載入的文件也只能是dex文件,或者包含有dex文件的.apk或.jar文件。
3.PathClassLoader是通過構造函數new DexFile(path)來產生DexFile對象的;而DexClassLoader則是通過其靜態方法loadDex(path, outpath, 0)得到DexFile對象。這兩者的區別在於DexClassLoader需要提供一個可寫的outpath路徑,用來釋放.apk包或者.jar包中的dex文件。換個說法來說,就是PathClassLoader不能主動從zip包中釋放出dex,因此只支持直接操作dex格式文件,或者已經安裝的apk(因為已經安裝的apk在cache中存在緩存的dex文件)。而DexClassLoader可以支持.apk、.jar和.dex文件,並且會在指定的outpath路徑釋放出dex文件。
4.另外,PathClassLoader在載入類時調用的是DexFile的loadClassBinaryName,而DexClassLoader調用的是loadClass。因此,在使用PathClassLoader時類全名需要用」/」替換」.」