arm opcode hook
/**************************************
/*?作者:半斤八兩
/*?博客:http://cnblogs.com/bjblcracked
/*?日期:2013-09-05??11:11
/**************************************
只是感興趣,沒有其他目的。失誤之處敬請諸位大俠賜教!
因工作需要,最近一直在研究arm.
看到論壇也有不少arm的破解文章,于是自己也寫了個"CM",把玩一下.
這里就不講破解了,重點(diǎn)講ARM?HOOK.
所需平臺1:ubuntu?x86?(build?arm)
所需平臺2:win7?x86?(debug?arm)
所需平臺3:android手機(jī)一部(root)
所需工具1:ida(analysis)
所需工具2:pscp(upload,download?file)
所需工具3:putty(connect?ubuntu)
所需工具4:gcc(build?arm)
首先用標(biāo)準(zhǔn)C寫個簡單的cm.
代碼:
1 #include <stdio.h> 2 3 int IsAdd(int* pNumOne, int* pNumTwo) 4 { 5 return *pNumOne + *pNumTwo; 6 } 7 8 int main() 9 { 10 int nNumOne = 0; 11 int nNumTwo = 0; 12 int nNumResult = 0; 13 14 printf("hi arm code.\r\n"); 15 16 printf("Please Input a Name:"); 17 scanf("%d", &nNumOne); 18 19 printf("\r\n"); 20 21 printf("Please Input a Password:"); 22 scanf("%d", &nNumTwo); 23 24 printf("\r\n"); 25 26 nNumResult = IsAdd(&nNumOne, &nNumTwo); 27 28 printf("%d + %d = %d\r\n", nNumOne, nNumTwo, nNumResult); 29 30 if(nNumResult != 2013) 31 { 32 printf("error\r\n"); 33 } 34 else 35 { 36 printf("success\r\n"); 37 } 38 39 return 1; 40 }?
測試代碼,寫的不嚴(yán)謹(jǐn).
1).?連接ubuntu.
login?as:?root
root@192.168.83.150's?password:
Welcome?to?Ubuntu?12.04.2?LTS?(GNU/Linux?3.5.0-23-generic?x86_64)
?*?Documentation:??https://help.ubuntu.com/
258?packages?can?be?updated.
89?updates?are?security?updates.
Last?login:?Thu?Aug?29?11:05:46?2013?from?john-pc.local
root@i-G31MXP-K-T1:~#?whoami
root
root@i-G31MXP-K-T1:~#
用putty.exe連接上ubuntu了,我們再把我們的源碼上傳上來.
2).?upload?cm?src.
D:\Me\Company>pscp.exe?-l?root?-pw?password?D:\Me\Company\armhook.c?root@192.168.83.150:/root/zs/
armhook.c??????????????????????|?0?kB?|???0.6?kB/s?|?ETA:?00:00:00?|?100%
D:\Me\Company>
這里我們用pscp.exe上傳源碼.
3).?build?arm.
root@i-G31MXP-K-T1:~/zs#?arm-none-linux-gnueabi-gcc?-static?armhook.c?-o?armhook
root@i-G31MXP-K-T1:~/zs#?ls?-l
total?640
-rwxr-xr-x?1?root?root?649852?Aug?29?16:16?armhook
-rw-r--r--?1?root?root????623?Aug?29?16:11?armhook.c
root@i-G31MXP-K-T1:~/zs#
用gcc編譯arm.這里一定要靜態(tài)編譯,要不然在你的android手機(jī)上是運(yùn)行不了的.
4).?下載bin到pc端
D:\Me\Company>pscp.exe?-l?root?-pw?password?root@192.168.83.150:/root/zs/armhook?D:\Me\Company
armhook????????????????????????|?634?kB?|?634.6?kB/s?|?ETA:?00:00:00?|?100%
再用pscp.exe下載回來.
bin下載到PC上時,我們就可以用IDA調(diào)試了,我們先發(fā)到手機(jī)里面,運(yùn)行一下,看看效果.
5).?bin發(fā)送到手機(jī)端.
C:\Users\john\Desktop\Tools>adb?push?d:/me/company/armhook?/data/local/tmp/
2173?KB/s?(649852?bytes?in?0.292s)
C:\Users\john\Desktop\Tools>adb?shell
shell@android:/?$?su
su
shell@android:/?#?pwd
pwd
/
shell@android:/?#?cd?data/local/tmp
cd?data/local/tmp
shell@android:/data/local/tmp?#?ls
ls
armhook
shell@android:/data/local/tmp?#?./armhook
./armhook
sh:?./armhook:?can't?execute:?Permission?denied
126|shell@android:/data/local/tmp?#?chmod?777?armhook
chmod?777?armhook
shell@android:/data/local/tmp?#?./armhook
./armhook
hi?arm?code.
Please?Input?a?Name:2000
2000
Please?Input?a?Password:12
12
2000?+?12?=?2012
error
1|shell@android:/data/local/tmp?#?./armhook
./armhook
hi?arm?code.
Please?Input?a?Name:2000
2000
Please?Input?a?Password:13
13
2000?+?13?=?2013
success
1|shell@android:/data/local/tmp?#
6).?靜態(tài)調(diào)試分析.
手機(jī)上測試完了,下面我們就用IDA來看看程序.
代碼:
1 .text:00008204 ; =============== S U B R O U T I N E ======================================= 2 .text:00008204 ; Attributes: noreturn bp-based frame 3 .text:00008204 EXPORT main 4 .text:00008204 main ; DATA XREF: _start+20o 5 .text:00008204 ; .text:off_8154o 6 .text:00008204 var_10 = -0x10 7 .text:00008204 var_C = -0xC 8 .text:00008204 var_8 = -8 9 .text:00008204 00 48 2D E9 STMFD SP!, {R11,LR} ; Store Block to Memory 10 .text:00008208 04 B0 8D E2 ADD R11, SP, #4 ; Rd = Op1 + Op2 11 .text:0000820C 10 D0 4D E2 SUB SP, SP, #0x10 ; Rd = Op1 - Op2 12 .text:00008210 00 30 A0 E3 MOV R3, #0 ; Rd = Op2 13 .text:00008214 0C 30 0B E5 STR R3, [R11,#var_C] ; Store to Memory 14 .text:00008218 00 30 A0 E3 MOV R3, #0 ; Rd = Op2 15 .text:0000821C 10 30 0B E5 STR R3, [R11,#var_10] ; Store to Memory 16 .text:00008220 00 30 A0 E3 MOV R3, #0 ; Rd = Op2 17 .text:00008224 08 30 0B E5 STR R3, [R11,#var_8] ; Store to Memory 18 .text:00008228 BC 00 9F E5 LDR R0, =aHiArmCode_ ; "hi arm code.\r" 19 .text:0000822C 19 0B 00 EB BL puts ; Branch with Link 20 .text:00008230 B8 30 9F E5 LDR R3, =aPleaseInputANa ; "Please Input a Name:" 21 .text:00008234 03 00 A0 E1 MOV R0, R3 ; Rd = Op2 22 .text:00008238 80 0A 00 EB BL printf ; Branch with Link 23 .text:0000823C B0 20 9F E5 LDR R2, =aD ; "%d" 24 .text:00008240 0C 30 4B E2 SUB R3, R11, #-var_C ; Rd = Op1 - Op2 25 .text:00008244 02 00 A0 E1 MOV R0, R2 ; Rd = Op2 26 .text:00008248 03 10 A0 E1 MOV R1, R3 ; Rd = Op2 27 .text:0000824C 8A 0A 00 EB BL __isoc99_scanf ; Branch with Link 28 .text:00008250 A0 00 9F E5 LDR R0, =asc_6FE98 ; "\r" 29 .text:00008254 0F 0B 00 EB BL puts ; Branch with Link 30 .text:00008258 9C 30 9F E5 LDR R3, =aPleaseInputAPa ; "Please Input a Password:" 31 .text:0000825C 03 00 A0 E1 MOV R0, R3 ; Rd = Op2 32 .text:00008260 76 0A 00 EB BL printf ; Branch with Link 33 .text:00008264 88 20 9F E5 LDR R2, =aD ; "%d" 34 .text:00008268 10 30 4B E2 SUB R3, R11, #-var_10 ; Rd = Op1 - Op2 35 .text:0000826C 02 00 A0 E1 MOV R0, R2 ; Rd = Op2 36 .text:00008270 03 10 A0 E1 MOV R1, R3 ; Rd = Op2 37 .text:00008274 80 0A 00 EB BL __isoc99_scanf ; Branch with Link 38 .text:00008278 78 00 9F E5 LDR R0, =asc_6FE98 ; "\r" 39 .text:0000827C 05 0B 00 EB BL puts ; Branch with Link 40 .text:00008280 0C 20 4B E2 SUB R2, R11, #-var_C ; Rd = Op1 - Op2 41 .text:00008284 10 30 4B E2 SUB R3, R11, #-var_10 ; Rd = Op1 - Op2 42 .text:00008288 02 00 A0 E1 MOV R0, R2 ; Rd = Op2 43 .text:0000828C 03 10 A0 E1 MOV R1, R3 ; Rd = Op2 44 .text:00008290 CD FF FF EB BL IsAdd ; Branch with Link 45 .text:00008294 08 00 0B E5 STR R0, [R11,#var_8] ; Store to Memory 46 .text:00008298 60 10 9F E5 LDR R1, =aDDD ; "%d + %d = %d\r\n" 47 .text:0000829C 0C 20 1B E5 LDR R2, [R11,#var_C] ; Load from Memory 48 .text:000082A0 10 30 1B E5 LDR R3, [R11,#var_10] ; Load from Memory 49 .text:000082A4 01 00 A0 E1 MOV R0, R1 ; Rd = Op2 50 .text:000082A8 02 10 A0 E1 MOV R1, R2 ; Rd = Op2 51 .text:000082AC 03 20 A0 E1 MOV R2, R3 ; Rd = Op2 52 .text:000082B0 08 30 1B E5 LDR R3, [R11,#var_8] ; Load from Memory 53 .text:000082B4 61 0A 00 EB BL printf ; Branch with Link 54 .text:000082B8 08 20 1B E5 LDR R2, [R11,#var_8] ; Load from Memory 55 .text:000082BC 40 30 9F E5 LDR R3, =0x7DD ; Load from Memory 56 .text:000082C0 03 00 52 E1 CMP R2, R3 ; Set cond. codes on Op1 - Op2 57 .text:000082C4 02 00 00 0A BEQ loc_82D4 ; Branch 58 .text:000082C8 38 00 9F E5 LDR R0, =aError ; "error\r" 59 .text:000082CC F1 0A 00 EB BL puts ; Branch with Link 60 .text:000082D0 01 00 00 EA B loc_82DC ; Branch 61 .text:000082D4 loc_82D4 ; CODE XREF: main+C0j 62 .text:000082D4 30 00 9F E5 LDR R0, =aSuccess ; "success\r" 63 .text:000082D8 EE 0A 00 EB BL puts ; Branch with Link 64 .text:000082DC loc_82DC ; CODE XREF: main+CCj 65 .text:000082DC 01 30 A0 E3 MOV R3, #1 ; Rd = Op2 66 .text:000082E0 03 00 A0 E1 MOV R0, R3 ; Rd = Op2 67 .text:000082E4 04 D0 4B E2 SUB SP, R11, #4 ; Rd = Op1 - Op2 68 .text:000082E8 00 88 BD E8 LDMFD SP!, {R11,PC} ; Load Block from Memory 69 .text:000082E8 ; End of function main 70 .text:000082EC 6C FE 06 00 off_82EC DCD aHiArmCode_ ; DATA XREF: main+24r 71 .text:000082EC ; "hi arm code.\r" 72 .text:000082F0 7C FE 06 00 off_82F0 DCD aPleaseInputANa ; DATA XREF: main+2Cr 73 .text:000082F0 ; "Please Input a Name:" 74 .text:000082F4 94 FE 06 00 off_82F4 DCD aD ; DATA XREF: main+38r 75 .text:000082F4 ; main+60r 76 .text:000082F4 ; "%d" 77 .text:000082F8 98 FE 06 00 off_82F8 DCD asc_6FE98 ; DATA XREF: main+4Cr 78 .text:000082F8 ; main+74r 79 .text:000082F8 ; "\r" 80 .text:000082FC 9C FE 06 00 off_82FC DCD aPleaseInputAPa ; DATA XREF: main+54r 81 .text:000082FC ; "Please Input a Password:" 82 .text:00008300 B8 FE 06 00 off_8300 DCD aDDD ; DATA XREF: main+94r 83 .text:00008300 ; "%d + %d = %d\r\n" 84 .text:00008304 DD 07 00 00 dword_8304 DCD 0x7DD ; DATA XREF: main+B8r 85 .text:00008308 C8 FE 06 00 off_8308 DCD aError ; DATA XREF: main+C4r 86 .text:00008308 ; "error\r" 87 .text:0000830C D0 FE 06 00 off_830C DCD aSuccess ; DATA XREF: main:loc_82D4r 88 .text:0000830C ; "success\r" 89 .text:00008310 ; =============== S U B R O U T I N E =======================================?
程序很簡單,看反匯編代碼,一眼就能定位到magic?jump.
代碼:
1 .text:000082B8 ; --------------------------------------------------------------------------- 2 .text:000082B8 08 20 1B E5 LDR R2, [R11,#var_8] ; Load from Memory 3 .text:000082BC 40 30 9F E5 LDR R3, =0x7DD ; Load from Memory 4 .text:000082C0 03 00 52 E1 CMP R2, R3 ; Set cond. codes on Op1 - Op2 5 .text:000082C4 02 00 00 0A BEQ loc_82D4 ; Branch 6 .text:000082C8 38 00 9F E5 LDR R0, =aError ; "error\r" 7 .text:000082CC F1 0A 00 EB BL puts ; Branch with Link 8 .text:000082D0 01 00 00 EA B loc_82DC ; Branch 9 .text:000082D4 ; ---------------------------------------------------------------------------?
我們只要把beq改成?bne就可以了.
或者直接改成?B???loc_82D4?.這樣都可以實(shí)現(xiàn)爆破.
文本重點(diǎn)是講HOOK,就不多說破解過程了.
CM寫的很簡潔,就一個isadd函數(shù),那么我們就來嘗試HOOK?IsAdd函數(shù).
?
其HOOK思路和x86下是一樣的.
不同的是更"繁瑣"些,而且"jmp"計(jì)算公式也略有不同.
在arm中,沒有jmp指令,而是只有bcc指令(類似jcc).
之所以說HOOK繁瑣,主要是對arm指令集不了解,所以HOOK起來感覺更繁瑣些,其實(shí)都一樣的,甚至更簡單些?:)
具體的bcc,大家可以看我博客收集的一篇文章.
傳送門:
ARM?Cortex?M3指令集
在arm中hook我們需要用到?bl?這個轉(zhuǎn)移指令?.
其效果和x86中的?call?有點(diǎn)類似.
下面來說說arm?bcc的公式.(自己多次嘗試總結(jié)的,如果有不對的地方希望大家能指點(diǎn)一下.)
計(jì)算opcode:
(dst?-?src)?/?4?-?2?=?opcode
計(jì)算dst:
src?+?(opcode?+?2)?*?4?=?dst
?
不明看例:)
?
下面開始HOOK,我們需要先把入口代碼和地址記下來.
要HOOK地址:000081CC
OPCODE:04?B0?2D?E5
下面我們再程序中找段空數(shù)據(jù)地址.
?
我找的這個沒用的數(shù)據(jù)地址.來寫我們的HOOK代碼.
我們套用opcode計(jì)算公式.
(dst?-?src)?/?4?-?2?=opcode
(00072320?-?000081CC)?/?4?-?2?=?0x01A853
我們計(jì)算出opcode等于0x1A852?
bl?指令對應(yīng)的指令是?0xeb
那么合起來就是,??53?a8?01?eb?(arm很有意思,所有的指令都是4字節(jié)對齊的.)
修改,我們就直接用IDA的插件.?組合熱鍵是?alt+e+p+b?.
IDA的這個插件對ARM支持不是很友好,不能直接編寫匯編代碼.
因此我們只能按字節(jié)來修改了.(字節(jié)之間都要有空格,不區(qū)分大小寫.)
打開后,我們在前四個字節(jié),輸入?53?a8?01?eb?然后確定就行了.
改了后如下效果.
[COLOR="red"]
[/CODE]
注意看81cc處的指令已經(jīng)被我們改了.
現(xiàn)在我們要到?loc_72310?這里,?
我們就來打印一個"hi?arm?hook"?吧.
打印的話,我們要調(diào)用?puts?函數(shù),
我們來看一下函數(shù)地址.
?
puts地址:0000AE98
函數(shù)原型:
就一個參數(shù).?arm的程序都有點(diǎn)類似delphi的_fastcall.?通過寄存器傳參.
當(dāng)參數(shù)超過四個后,就會通過棧來傳參.?寄存器順序是?r0?r1?r2?r3.
puts?就一個參數(shù),我們只要把?"hi?arm?hook"?地址賦給?r0?即可.
傳地址不能用?mov?.要用類似?lea?的?ldr?指令.??opcode:?0x0000e59f
前面說了arm是四字節(jié)指令,?光?ldr?就占了?2個字節(jié)?3?和?4字節(jié).
那么第2個字節(jié)表示的是?寄存器.?第一個字節(jié)?表示字符串的偏移.
因?yàn)閍rm的risc指令為單字指令,所以他的尋址只能是255.
我們在剛才找的空數(shù)據(jù)地址段下面寫上?"hi?arm?hook"?
?
在x86上,我們HOOK前要保存現(xiàn)場,在ARM中,也同樣需要保護(hù)現(xiàn)場.
STMFD?指令是用來保存現(xiàn)場的,滿遞減堆棧
恢復(fù)的話,我們就用
LDMFD指令.滿遞減堆棧
因?yàn)槲覍rm指令集并不熟悉,x86上也沒有發(fā)現(xiàn)有什么比較好的指令和匯編轉(zhuǎn)換工具.
所以我也不知道代碼對應(yīng)的opcode是多少,也沒有時間一個個去試.
所以我就直接找puts函數(shù)入口處的opcode
保存現(xiàn)場
F0?47?2D?E9?????????STMFD???SP!,?{R4-R10,LR}??//?將R4-R10?LR?入棧,滿遞減堆棧
恢復(fù)現(xiàn)場
F0?87?BD?E8?????????LDMFD???SP!,?{R4-R10,PC}??//?將R4-R10?LR?出棧,滿遞減堆棧
00072320處,我們填寫?F0?47?2D?E9?保存現(xiàn)場.
保護(hù)好現(xiàn)場后,我們就來實(shí)現(xiàn)我們要打印的內(nèi)容.
00072324處,我們把這個字符串裝進(jìn)r0.
ldr?1字節(jié)換算公式:
dst?-?src?-?8?=?opcode
套進(jìn)去后:
00072350?-?00072324?-?8?=?24
24?00?9f?e5
?
下面我們就剩跳到puts了.
再來看一下公式.
(dst?-?src)?/?4?-?2?=opcode
puts地址:0000AE98
(0000AE98?-?00072328)?/?4?-?2?=?FFFF?FFFF?FFFE?62DA
我們只要取三字節(jié)就行了,也就是??da62fe加上bl?eb
?
現(xiàn)在弄完了,別忘了恢復(fù)我們前面HOOK的四個字節(jié).
直接復(fù)制?opcode?在?00072328?這個地址補(bǔ)丁即可.
完事后,別忘了再跳回去.
跳回去我們直接用上面說過的?ldmfd?指令.
恢復(fù)現(xiàn)場
F0?87?BD?E8?????????LDMFD???SP!,?{R4-R10,PC}??//?將R4-R10?LR?出棧,滿遞減堆棧
現(xiàn)在好像已經(jīng)弄完了,但是在我實(shí)驗(yàn)過程中,發(fā)現(xiàn)還是有問題的.
問題是puts的參數(shù),應(yīng)該傳一個字符串指針.
這里和x86有點(diǎn)不一樣.所以我們應(yīng)該在?0007235C?處寫個地址,指向?00072350.?要不然程序弄到手機(jī)上運(yùn)行是會出錯的.
00072324?處的也要改一下.改成??30?00?9F?E5.
改完后,如下.
?
在IDA里面改完后,其實(shí)并沒有改完.因?yàn)镮DA不支持直接在原文件里面修改.
那么我們可以通過WINHEX來修改.
在IDA里面,我們用組合快捷鍵.?alt+f+p+d?導(dǎo)出dif文件.?
然后用記事本打開dif文件,?用winhex對應(yīng)著dif文件來修改即可.
7).?趕緊傳手機(jī)上測試.
上傳手機(jī):
C:\Users\john\Desktop\Tools>adb?push?D:\Me\Company\armhook3?/data/local/tmp/
1507?KB/s?(649852?bytes?in?0.421s)
8).?執(zhí)行程序:
$?ls
ls
armhook
armhook_ok
$?chmod?711?armhook_ok
chmod?711?armhook_ok
$?./armhook_ok
./armhook_ok
hi?arm?code1.
Please?Input?a?Name:2010
2010
Please?Input?a?Password:3
3
hi?arm?hook!
2010?+?3?=?13
error
$?./armhook_ok
./armhook_ok
hi?arm?code1.
Please?Input?a?Name:2
2
Please?Input?a?Password:2
2
hi?arm?hook!
2?+?2?=?13
error
$
我們可以看到?"hi?arm?hook!"?字符串了,說明我們HOOK是很成功的.
但是我們可以看到我運(yùn)行了2次,返回的值始終是13.?
有興趣的可以看看是怎么回事?這里我就不做解釋了,我們的arm?opcode?hook就這樣完成了
?
源碼和程序下載地址:看雪學(xué)院
轉(zhuǎn)載于:https://www.cnblogs.com/BjblCracked/p/3302914.html
總結(jié)
以上是生活随笔為你收集整理的arm opcode hook的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: UVAlive 6131 dp+斜率优化
- 下一篇: java DOM4J 读取XML