㈠ android studio 開發app,如何抵抗動態調試,反調試代碼怎麼寫請寫上詳細代碼。
為了保護關鍵代碼被逆向分析,一般放在應用程序初始化過程中,如init_array,或jni_onload函數里進行檢查代碼執行。
1.調試檢測
對調試器的檢測(ida,gdb,strace, ltrace等調試工具)
a.父進程檢測
b.當前運行進程檢測
例如對android_server進程檢測。針對這種檢測只需將android_server改名就可繞過
[objc] view plain
pid_t GetPidByName(const charchar *as_name) {
DIR *pdir = NULL;
struct dirent *pde = NULL;
FILEFILE *pf = NULL;
char buff[128];
pid_t pid;
char szName[128];
// 遍歷/proc目錄下所有pid目錄
pdir = opendir("/proc");
if (!pdir) {
perror("open /proc fail.\n");
return -1;
}
while ((pde = readdir(pdir))) {
if ((pde->d_name[0] < '0') || (pde->d_name[0] > '9')) {
continue;
}
sprintf(buff, "/proc/%s/status", pde->d_name);
pf = fopen(buff, "r");
if (pf) {
fgets(buff, sizeof(buff), pf);
fclose(pf);
sscanf(buff, "%*s %s", szName);
pid = atoi(pde->d_name);
if (strcmp(szName, as_name) == 0) {
closedir(pdir);
return pid;
}
}
}
closedir(pdir);
return 0;
}
c.讀取進程狀態(/proc/pid/status)
State屬性值T 表示調試狀態,TracerPid 屬性值正在調試此進程的pid,在非調試情況下State為S或R, TracerPid等於0
d.讀取 /proc/%d/wchan
下圖中第一個紅色框值為非調試狀態值,第二個紅色框值為調試狀態:
[objc] view plain
static void get_process_status(pid_t pid,const char* info,charchar *outline)
{
FILEFILE *fp;
char filename;
char line = {0};
snprintf( filename, sizeof(filename), "/proc/%d/status", pid );
fp = fopen( filename, "r" );
if ( fp != NULL )
{
while ( fgets( line, sizeof(line), fp ) )
{
if ( strstr( line, info ) )
strcpy(outline,line);
}
fclose( fp ) ;
}
return ;
}
static int getProcessStatus(int pid)
{
char readline = {0};
int result = STATUS_ELSE;
get_process_status(pid,"State",readline);
if(strstr(readline,"R"))
result = STATUS_RUNNING;
else if(strstr(readline,"S"))
result = STATUS_SLEEPING;
else if(strstr(readline,"T"))
result = STATUS_TRACING;
return result;
}
static int getTracerPid(int pid)
{
char readline = {0};
int result = INVALID_PID;
get_process_status(pid,"TracerPid",readline);
charchar *pidnum = strstr(readline,":");
result = atoi(pidnum + 1);
return result;
}
static int getWchanStatus(int pid)
{
FILEFILE *fp= NULL;
char filename;
char wchaninfo = {0};
int result = WCHAN_ELSE;
char cmd = {0};
sprintf(cmd,"cat /proc/%d/wchan",pid);
LOGANTI("cmd= %s",cmd);
FILEFILE *ptr; if((ptr=popen(cmd, "r")) != NULL)
{
if(fgets(wchaninfo, 128, ptr) != NULL)
{
LOGANTI("wchaninfo= %s",wchaninfo);
}
}
if(strncasecmp(wchaninfo,"sys_epoll\0",strlen("sys_epoll\0")) == 0)
result = WCHAN_RUNNING;
else if(strncasecmp(wchaninfo,"ptrace_stop\0",strlen("ptrace_stop\0")) == 0)
result = WCHAN_TRACING;
return result;
}
e. ptrace 自身或者fork子進程相互ptrace
[objc] view plain
ptrace me
if (ptrace(PTRACE_TRACEME, 0, 1, 0) < 0) {
printf("DEBUGGING... Bye\n");
return 1;
}
void anti_ptrace(void)
{
pid_t child;
child = fork();
if (child)
wait(NULL);
else {
pid_t parent = getppid();
if (ptrace(PTRACE_ATTACH, parent, 0, 0) < 0)
while(1);
sleep(1);
ptrace(PTRACE_DETACH, parent, 0, 0);
exit(0);
}
}
f. 防止mp
利用Inotify機制,對/proc/pid/mem和/proc/pid/pagemap文件進行監視。inotify API提供了監視文件系統的事件機制,可用於監視個體文件,或者監控目錄。具體原理可參考:http://man7.org/linux/man- pages/man7/inotify.7.html
偽代碼:
[objc] view plain
void __fastcall anitInotify(int flag)
{
MemorPagemap = flag;
charchar *pagemap = "/proc/%d/pagemap";
charchar *mem = "/proc/%d/mem";
pagemap_addr = (charchar *)malloc(0x100u);
mem_addr = (charchar *)malloc(0x100u);
ret = sprintf(pagemap_addr, &pagemap, pid_);
ret = sprintf(mem_addr, &mem, pid_);
if ( !MemorPagemap )
{
ret = pthread_create(&th, 0, (voidvoid *(*)(voidvoid *)) inotity_func, mem_addr);
if ( ret >= 0 )
ret = pthread_detach(th);
}
if ( MemorPagemap == 1 )
{
ret = pthread_create(&newthread, 0, (voidvoid *(*)(voidvoid *)) inotity_func, pagemap_addr);
if(ret > 0)
ret = pthread_detach(th);
}
}
void __fastcall __noreturn inotity_func(const charchar *inotity_file)
{
const charchar *name; // r4@1
signed int fd; // r8@1
bool flag; // zf@3
bool ret; // nf@3
ssize_t length; // r10@3
ssize_t i; // r9@7
fd_set readfds; // @2
char event; // @1
name = inotity_file;
memset(buffer, 0, 0x400u);
fd = inotify_init();
inotify_add_watch(fd, name, 0xFFFu);
while ( 1 )
{
do
{
memset(&readfds, 0, 0x80u);
}
while ( select(fd + 1, &readfds, 0, 0, 0) <= 0 );
length = read(fd, event, 0x400u);
flag = length == 0;
ret = length < 0;
if ( length >= 0 )
{
if ( !ret && !flag )
{
i = 0;
do
{
inotity_kill((int)&event);
i += *(_DWORD *)&event + 16;
}
while ( length > i );
}
}
else
{
while ( *(_DWORD *)_errno() == 4 )
{
length = read(fd, buffer, 0x400u);
flag = length == 0;
ret = length < 0;
if ( length >= 0 )
}
}
}
}
g. 對read做hook
因為一般的內存mp都會調用到read函數,所以對read做內存hook,檢測read數據是否在自己需要保護的空間來阻止mp
h. 設置單步調試陷阱
[objc] view plain
int handler()
{
return bsd_signal(5, 0);
}
int set_SIGTRAP()
{
int result;
bsd_signal(5, (int)handler);
result = raise(5);
return result;
}
㈡ android開發如何調試
能夠在eclipse上運行調試應用程序之前,你必須為它創建一個啟動項。啟動項指定哪個工程將被啟動,哪個activity開始工作,以及使用哪些模擬器選項等。
按照以下步驟為Eclipse版本的應用程序創建合適的啟動項:
打開啟動項管理工具。
在Eclipse 3.3 (Europa)的版本中,酌情選擇 Run > Open RunDialog... or Run > Open Debug Dialog... 。
在Eclipse3.4 (Ganymede)版本中,酌情選擇 Run > Run Configurations...or Run > Debug Configurations... 。
在左邊的工程類型列表選擇Android Application選擇,雙擊(或者點擊右鍵選擇new),創建一個新的啟動項。
輸入啟動項名稱。
在Android標簽中,瀏覽要開始的工程和Activity 。
在Target標簽中,設置想要顯示的屏幕及網路屬性,以及其他任何模擬器啟動選項。
你可以在Common標簽中設置更多的選項.
按下Apply保存啟動配置,或者按下Run或Debug()。
運行和調試應用程序
一旦你設定了工程和工程啟動配置,你就可以按照以下的說明運行和調試應用程序了。
從eclipse主菜單,根據情況選擇Run>Run 或者 Run>Debug,開始運行或者調試活動啟動項。
注意,這里活動啟動項是在運行配置管理中最最近一次選中的那個。它不一定就是在Eclipse Navigation 面板中選擇的程序(如果有的話)
設置和修改活動啟動項,可以使用啟動項管理工具。如何獲得啟動項管理工具可以參考創建一個啟動項
運行或調試應用程序將觸發以下動作:
啟動模擬器,如果他還沒有開始運行。
編譯工程, 如果在上次編譯的基礎上修改過代碼,將重新編譯。在模擬器上安裝應用程序。
Run選項,開始運行程序。
Debug 在"Wait for debugger "模式下啟動程序,然後打開調試窗口並將Eclipse java調試器和程序關聯。
利用其他IDEs和工具開發Android應用程序
通常我們使用安裝有ADT插件的eclipse Eclipse with the ADT plugin.來開發Android程序,這個插件將編輯,build和調試功能集成到IDE上。
然而,如果你想在其他的IDE上開發程序,例如IntelliJ,或者使用沒有ADT插件的eclipse也可以。SDK提供了安裝,編譯,調試應用程序所需要的工具。
創建一個android工程
Android SDK包含一個activityCreator的程序,它將為工程產生多個stub文件和一個build文件。你可以用這個程序創建一個新的 Android工程或者在現有代碼上創建工程,如SDK中包含的例子。對於Linux 和Mac系統,SDK提供activityCreator.py,一個 Python腳本,Windows上則是activityCreator.bat一個批處理腳本。無論是哪種平台,用法是一樣的。
按以下步驟運行activityCreator創建Android工程:
在命令行下,切換到SDK下的tools/目錄下,為你的工程文件新建一個目錄。如果你是在現有代碼上創建工程,切換到程序的根目錄下。
運行activityCreator。在命令行下,你必須指定完全合格的類名作為參數。如果你是創建一個全新的工程,這個類代表的與它同名的stub類和腳本文件。如果是在現有代碼上創建工程,必須指定軟體包中其中一個Activity類的名稱。命令選項的腳本包括:
--out <folder> 設定輸出目錄。默認情況下輸出目錄為當前目錄。如果你想為工程文件創建一個新的目錄,可以使用這個選項來指向它。
--ide intellij, 在一個新的項目中生成IntelliJIDEA 工程文件。
這里有個例子:
~/android_linux_sdk/tools $ ./activityCreator.py --out myprojectyour.package.name.ActivityName
package: your.package.name
out_dir: myproject
activity_name: ActivityName
~/android_linux_sdk/tools $
activityCreator腳本生成以下文件和目錄(但是不能重寫已有文件):
AndroidManifest.xml 程序的清單文件,同時為工程指定Activity類。
build.xml 一個Ant文件,用來編譯/打包應用程序。
src/your/package/name/ActivityName.java 你指定的輸入Activity類。
your_activity.iml, your_activity.ipr, your_activity.iws [only with the-ide intelliJ flag] intelliJ工程文件
res/ 資源目錄.
src/ 源代碼目錄.
bin/ build腳本的輸出目錄.
現在你可以將開發文件夾移到任何地方,但是記住,必須使用tool/文件夾下的adb程序將文件發送到模擬器上。因此你需要在你工作環境和tools/文件夾之間活動。
當然你需要避免移動SDK目錄,因為它將打斷編譯腳本。(再重新build之前需要手動更新SDK的映射路徑)
編譯 android應用程序
使用activityCreator生成的Ant文件build.xml來編譯程序
如果你沒有,你可以通過Apache Ant home page得到Ant文件。安裝它,並確定它在你的可執行文件路徑下。
呼叫Ant之前,你需聲明JAVA_HOME環境變數,並將它設置為JDK的安裝路徑。
注 意:在windows上,JDK默認的安裝路徑為"ProgramFiles",這個路徑將會引起Ant失敗,因為路徑中間有空格。解決這個問題,你可以像這樣指定環境變數 JAVA_HOME:JAVA_HOME=c:\Prora~1\Java\ 然而簡單的解決方法是將JDK安裝在沒有空格的目錄下。例如:c:\java\jdk1.6.0_02.
如果你還沒有這么准備好,按照上面創建一個新的工程的介紹建立一個工程。
現在你可以為你的工程運行Ant編譯文件,只需在build.xml同文件夾下輸入ant即可。每次修改原文件或是資源,都需要重新運行ant,它將把最新版的應用程序打包以便deploy.
運行Android程序
運行一個編譯好的程序,你需要用adb工具將.apk文件載入到模擬器的/data/app/目錄下,用法如下面介紹。
啟動模擬器(命令行下運行sdk目錄下的/tools/emulator)。
模擬器切換到主畫面(最好不要在程序運行的時候向模擬器安裝程序,可以按home鍵離開應用程序)。
運 行adb,安裝myproject/bin./<appname>.apk文件。例如,安裝Lunar Lander 示例,命令行下,切換到SDK目錄下的/sample/LunarLander子目錄下,輸入../../tools/adbinstall bin/LunarLander.apk
在模擬器中,打開可執行程序列表,卷動屏幕,選中並啟動你的應用程序。
注意:當你第一次安裝一個Activity時,你可能需要在啟動項顯示之前,或者其它程序調用它之前重新啟動模擬器。因為軟體包管理工具通常只有在模擬器啟動時才能完全的審查manifests。
為程序附加調試器
這一節我們介紹如何在屏幕上顯示調試信息(例如CPU使用率),以及如何將IDE和模擬器上運行的程序關聯起來。
使用eclipse插件可以自動的生成調試器。但你也可以通過配置IDES來監聽調試埠得到調試信息。
啟動Dalvik Debug Monitor Server (DDMS) 工具 ,它在IDE和模擬器之間扮演著埠轉換服務的角色。?
設置模擬器調試配置選項。例如,等到調試信息被載入後才啟動應用程序。注意,很多調試選項無需DDMS也可以使用,例如模擬器上顯示CPU的使用效率,或者屏幕的刷新頻率。
配置IDE,使得調試時IDE與8700埠關聯 .how to set up Eclipse to debug your project. 包含以下信息。
配置IDE附加調試埠
DDMS將為每一個虛擬機分配一個特殊的調試埠,這個埠在模擬器上可以找到。你必須將你的IDE與此埠(虛擬機上信息欄中有列出這些埠)關聯或者是默認的埠8700。這樣可以使IDE 連接到模擬器上程序列表中的任一個程序。
你的IDE需要能夠關聯模擬器上正在運行的程序,顯示它的線程,並允許你掛起它,檢查它的狀態,設置斷點。如果你在開發設置面板選擇了「等待調試」,應用程序將等到Eclipse連接後才運行,所以你需要在連接之前設置斷點。
修改正在調試的程序,或者在當前程序運行時選擇「等待調試」將引起系統殺死這個應用程序。如果你的程序處於一種壞的狀態,你可以使用方式殺死它,方法很簡單,只需要設置和鉤掉復選框。
㈢ 【Android】如何使用ADB進行調試
1、adb devices
( 用於查看當前adb連接的設備有哪些,這里目前是無)
(3)androidapk動態調試擴展閱讀:
無線使用ADB(Android Debug Bridge)非常的實用,它能夠讓你的手機用無線來取代USB連接,與電腦鏈接起來更加的方便快捷,還可以保護電池。需要root。
還可以進行以下的操作:
1、快速更新設備或手機模擬器中的代碼,如應用或Android系統升級;
2、在設備上運行shell命令;
3、管理設備或手機模擬器上的預定埠;
4、在設備或手機模擬器上復制或粘貼文件;
老玩家對adb這個調試工具肯定不陌生了,不過一般都是用USB連接來玩兒,這次帶來的是用無線進行連接,就太強大了,畢竟usb連接對電池的壽命有一定影響。
㈣ Android編程:關於自定義APK圖標(動態的設置)
void addShortcutToDesktop(){
Intent shortcut = new Intent(ACTION_INSTALL);
BitmapDrawable iconBitmapDrawabel = null;
// 獲取應用基本信息
String label = this.getPackageName();
PackageManager packageManager = getPackageManager();
try {
iconBitmapDrawabel = (BitmapDrawable) packageManager.getApplicationIcon(label);
} catch (NameNotFoundException e) {
e.printStackTrace();
}
// 設置屬性
shortcut.putExtra(Intent.EXTRA_SHORTCUT_NAME, label);
shortcut.putExtra(Intent.EXTRA_SHORTCUT_ICON, iconBitmapDrawabel.getBitmap());
// 是否允許重復創建 -- fase-->否
shortcut.putExtra("plicate", false);
// 設置啟動程序
ComponentName comp = new ComponentName(label,"." + this.getLocalClassName());
shortcut.putExtra(Intent.EXTRA_SHORTCUT_INTENT, new Intent(Intent.ACTION_MAIN).setComponent(comp));
sendBroadcast(shortcut);
}
android支持發送Intent.EXTRA_SHORTCUT_ICON_RESOURCE的方式添加圖標,這個是在activity中用的方法,怎麼自定義一看就懂了
㈤ 安卓開發怎麼保證軟體不被動態調試
你說的動態調試是?你也可以單步調試的啊,按F5
㈥ android應用怎樣防止別人動態調試
主要通過以下幾個步驟: 1、手機通過數據線連接在電腦上 2、設置android手機為USB調試模式。步驟: menu- 設置 - 應用程序 - 開發 , 選擇【USB調試】 3、如果是window系統,系統會提示安裝驅動: 選擇正確的android sdk安裝目錄,然後點擊下一步,系統就開始安裝驅動了 4、驅動安裝完成之後,重啟電腦(通常系統會有「安裝新驅動,重啟才能生效」的提示),這但應該明白吧 5、重復第1步和第2步,打開命令窗口,檢測手機設備是否已經被識別,如下所示: 「HT99YLG11834 device」就是檢測到得手機設備 6、接下來就開始在eclipse上調試android程序了, 右擊android工程-Run as-Android Application ,彈出如下窗口:(重新啟動系統之後才有這樣的效果) 7、選中手機設備,點擊OK之後,程序就開始在真機上安裝了,控制台輸出如下信息: 8. 設置應用程序為調試模式。操作: 編輯AndroidManifest.xml 增加調試參數android:debuggable=true, 如下: <application android:icon=@drawable/icon android:label=@string/app_name android:debuggable=true 9. 執行真機調試操作:ECLIPSE調試對話框中,Target窗口中選擇Manual,點擊【debug】按鈕,選擇真機設備,開始調試。 注:不管是否啟用ECLIPSE環境,任何Android軟體只要在真機上運行發生異常,都可以在命令行窗口下查看具體異常信息: 執行:./adb logcat 可以查看到更多的系統異常消息。在這些消息中要注意查看Caused by:打 頭的行,這些行指明了在哪行代碼出的錯誤10、運行這個應用程序,這樣就可以使用手機來測試了
㈦ android studio怎麼調試apk
調試基礎
一般來說我們有兩種辦法調試一個debuggable的apk;其一是下好斷點,然後用debug模式編譯安裝這個app;其二是 attach process,在Android Studio裡面就是這么一個對話框:
Attach Process
第二種方法比較常用,我們可以在啟動apk之後,直接下斷點,然後attach process到制定進程,條件觸發之後就可以直接進入調試模式。
其他的一些單步執行,step into, step out, force step into 等就不提了;基本的跟蹤手段。
還是提一下,下斷點最簡單的辦法,是在代碼編輯器的左側,行號右邊滑鼠點擊一下即可。
Evaluate Expression
㈧ 如何使用ida在apk執行前動態調試其so中的函數
安卓手機用ida在apk執行前動態調試其so中的函數 方法1 1、解包對方APK,插入一個:對應SMALI: android.os.SystemClock.sleep(20000);const-wide/16 v0, 0x2710 #20秒invoke-static {v0, v(X-1)}, Landroid/os/SystemClock;->sleep(J)V這里(X-1)對應.local X。 2 另外,有的包在你要調試的那個SO裡面有簽名保護,反正你重新打了包之後會導致程序運行崩潰,這個相比JAVA修改困難些,建議你用那個簽名漏洞來打包。事實上我調試那個SO也遇到過這樣,然後打了個簽名漏洞的包嵌入的延時函數就可以了。 方法2 1) am start -D -n 包名/類名; 2) IDA pro attach 進程, 設置新線程,載入so時斷點,continue; 3) 打開ddms, 查看調試埠, jdb attach port; 4) 這個時候應該已經斷在新線程,或者載入so處了,在你感興趣的so處停下來; 5) 另外用ida 打開so,查看你感興趣的函數偏移, 加上你感興趣的so的基地址,打上斷點,continue, 就大功告成了。 注意事項 windows下ida6.1不行,linux ida 6.4可以,不知是ida的問題還是windows的問題,你可以在linux下用wine測一下。 經驗內容僅供參考,如果您需解決具體問題(尤其法律、醫學等領域),建議您詳細
㈨ android怎麼動態調試dex
根據android的官方文檔,如果要調試一個apk裡面的dex代碼,必須滿足以下兩個條件中的任何一個:
1.apk中的AndroidManifest.xml文件中的Application標簽包含屬性android:debuggable=」true」
2./default.prop中ro.debuggable的值為1
由於一般軟體發布時都會把android:debuggable設置為false,所以要達成條件1需要反編譯原apk,修改AndroidManifest.xml並進行重新打包,這樣不僅麻煩,而且很多軟體進行了加固,要破解很難。所以想辦法滿足第2個條件是個一勞永逸的辦法。
由於default.prop是保存在boot.img的ramdisk中,這部分每次重新啟動都會重新從rom中載入,所以要到目的必須修改boot.img中的ramdisk並重新刷到設備中。修改步驟如下:
1.從Google官方網站下載到boot.img
2.使用工具(abootimg,gunzip, cpio)把boot.img完全解開,獲取到default.prop
3.修改default.prop
4.把修改後的文件重新打包成boot_new.img
5.使用fastboot工具把boot_new.img刷入設備(fastboot flash boot boot_new.img)
具體可參考: http://www.cnblogs.com/goodhacker/p/4106139.html
由於我們這篇文章的重點是如何動態調試dex代碼,所以我們就假設該dex是可調試的。
1.用ida打開apk文件,選擇dex文件進行載入
2.設置debugger選項,Debugger->Debugger options->Set specific options,按如圖1所示進行設置,然後一路確定返回
3.找到要下斷點的位置,游標移到要下斷點的那一行,按f2下斷點
4.手機開啟調試選項,連接到電腦,運行apk
5.選中IDA pro窗口,按f9運行,如果出現如圖2的畫面,就說明設置成功,可以進行動態調試了。
㈩ 如何動態調試Android軟體
由於android手機安裝之後不好調試,你可以使用一些第三方的工具,比如findbugs,就可以集成到app上。