iOS_逆向(6)_ARM匯編相關(guān)的iOS逆向理論基礎(chǔ)(待補(bǔ)充...待完善...)

ARM匯編相關(guān)的iOS逆向理論基礎(chǔ)

ARM官方資料:http://infocenter.arm.com

1.1 ARM匯編基礎(chǔ)

“ARM匯編的基本概念相當(dāng)于26個(gè)字母和音標(biāo)模暗;指令相當(dāng)于單詞利职,它們的變種相當(dāng)于單詞的各種形態(tài)聚请;調(diào)用規(guī)則相當(dāng)于語(yǔ)法淫痰,定義句子之間的聯(lián)系∥塍希”

1.1.1

1.寄存器鞋邑、內(nèi)存和棧

在ARM匯編里,操作對(duì)象是寄存器(register)秒裕、內(nèi)存和棧(stack)袱蚓。
其中,寄存器可以看成CPU自帶的變量几蜻,它們的數(shù)量一般是很有限的喇潘;
當(dāng)需要更多變量時(shí),就可以把它們存放在內(nèi)存中梭稚;
不過(guò)颖低,數(shù)量上去了,質(zhì)量也下來(lái)了哨毁,對(duì)內(nèi)存的操作比對(duì)寄存器的操作要慢得多枫甲。

棧其實(shí)也是一片內(nèi)存區(qū)域,但它具有棧的特點(diǎn):先進(jìn)后出扼褪。ARM的棧是滿遞減(Full Descending)的想幻,向下增長(zhǎng),也就是開口朝下话浇,新的變量被存放到棧底的位置脏毯;越靠近棧底,內(nèi)存地址越小幔崖,”

“一個(gè)名為“stack pointer”(簡(jiǎn)稱SP)的寄存器保存棧的棧底地址食店,稱為棧地址渣淤;可以把一個(gè)變量給入(push)棧以保存它的值,也可以讓它出(pop)棧吉嫩,恢復(fù)變量的原始值价认。在實(shí)際操作中,棧地址會(huì)不斷變化自娩;但是在執(zhí)行一塊代碼的前后用踩,棧地址應(yīng)該是不變的,不然程序就要出問(wèn)題了忙迁∑瓴剩”

2.特殊用途的寄存器

ARM處理器中的部分寄存器有特殊用途

R0-R3           傳遞參數(shù)與返回值
R7              幀指針,指向母函數(shù)與被調(diào)用子函數(shù)在棧中的交界
R9              在iOS 3.0以前被系統(tǒng)保留
R12             內(nèi)部過(guò)程調(diào)用寄存器姊扔,dynamic linker會(huì)用到它
R13             SP寄存器
R14             LR寄存器惠奸,保存函數(shù)返回地址
R15             PC寄存器


3.分支跳轉(zhuǎn)與條件判斷

處理器中名為“program counter”(簡(jiǎn)稱PC)的寄存器用于存放下一條指令的地址。一般情況下恰梢,計(jì)算機(jī)一條接一條地順序執(zhí)行指令佛南,處理器執(zhí)行完一條指令后將PC加1,讓它指向下一條指令删豺,

亂序”的學(xué)名叫“分支”(branch):指令的執(zhí)行順序被打亂”
條件分支:滿足一定條件才得以觸發(fā)的分支是最實(shí)用的

·操作結(jié)果為0(或不為0)共虑;

·操作結(jié)果為負(fù)數(shù)愧怜;

·操作結(jié)果有進(jìn)位呀页;

·運(yùn)算溢出(比如兩個(gè)正數(shù)相加得到的數(shù)超過(guò)了寄存器位數(shù))∮堤常”

1.1.2 ARM/THUMB指令解讀

ARM處理器用到的指令集分為ARM和THUMB兩種蓬蝶;
ARM指令長(zhǎng)度均為32bit,
THUMB指令長(zhǎng)度均為16bit猜惋。
所有指令可大致分為3類丸氛,分別是數(shù)據(jù)操作指令、內(nèi)存操作指令和分支指令著摔。

1.數(shù)據(jù)操作指令

1)所有操作數(shù)均為32bit缓窜;

2)所有結(jié)果均為32bit,且只能存放在寄存器中谍咆。

基本格式:op{cond}{s} Rd, Rn, Op2

“cond”和“s”是兩個(gè)可選后綴禾锤;

“cond”的作用是指定指令“op”在什么條件下執(zhí)行”
17種條件

EQ              結(jié)果為0(EQual to 0)
NE              結(jié)果不為0(Not Equal to 0)
CS              有進(jìn)位或借位(Carry Set)
HS              同CS(unsigned Higher or Same)
CC              沒(méi)有進(jìn)位或借位(Carry clear)
LO              同CC(unsigned LOwer)
MI              結(jié)果小于0(MInus)
PL              結(jié)果大于等于0(PLus)
VS              溢出(oVerflow Set)
VC              無(wú)溢出(oVerflow Clear)
HI              無(wú)符號(hào)比較大于(unsigned HIgher)
LS              無(wú)符號(hào)比較小于等于(unsigned Lower or Same)
GE              有符號(hào)比較大于等于(signed Greater than or Equal)
LT              有符號(hào)比較小于(signed Less Than)
GT              有符號(hào)比較大于(signed Greater Than)
LE              無(wú)符號(hào)比較小于等于(signed Less than or Equal)
AL              無(wú)條件(ALways,默認(rèn))

"cond"的用法:

比較 R0, R1
移動(dòng) GE R2, R0 
移動(dòng) LT R2, R1
等價(jià):
if(R0 >=R1){
   R2 =R0
}else{
   R2=R!
}

“s”的作用是指定指令“op”是否設(shè)置flag

有下面4種flag:

N(Negative)
如果結(jié)果小于0則置1摹察,否則置0恩掷;
Z(Zero)
如果結(jié)果是0則置1,否則置0供嚎;
C(Carry)
對(duì)于加操作(包括CMN)來(lái)說(shuō)黄娘,如果產(chǎn)生進(jìn)位則置1峭状,否則置0;對(duì)于減操作(包括CMP)來(lái)說(shuō)逼争,Carry相當(dāng)于Not-Borrow优床,如果產(chǎn)生借位則置0,否則置1誓焦;對(duì)于有移位操作的非加/減操作來(lái)說(shuō)羔巢,C置移出值的最后一位;對(duì)于其他的非加/減操作來(lái)說(shuō)罩阵,C的值一般不變竿秆;
V(oVerflow)
如果操作導(dǎo)致溢出,則置1稿壁,否則置0幽钢。

C flag表示無(wú)符號(hào)數(shù)運(yùn)算結(jié)果是否溢出;V flag表示有符號(hào)數(shù)運(yùn)算結(jié)果是否溢出傅是。

算數(shù)操作:

ADD R0, R1, R2          ; R0 = R1 + R2
ADC R0, R1, R2          ; R0 = R1 + R2 + C(arry)
SUB R0, R1, R2          ; R0 = R1 - R2
SBC R0, R1, R2          ; R0 = R1 - R2 - !C
RSB R0, R1, R2          ; R0 = R2 - R1
RSC R0, R1, R2          ; R0 = R2 - R1 - !C

ADD和SUB是基礎(chǔ),其他是變種;
RSB=Reverse SuB =把SUB的兩個(gè)操作數(shù)調(diào)換位置;
以C結(jié)尾=Carry=代表有進(jìn)位和錯(cuò)位的加減法,當(dāng)產(chǎn)生進(jìn)位或沒(méi)有借位的時(shí),將Carryflage置1

邏輯操作:

AND R0, R1, R2          ; R0 = R1 & R2
ORR R0, R1, R2          ; R0 = R1 | R2
EOR R0, R1, R2          ; R0 = R1 ^ R2
BIC R0, R1, R2          ; R0 = R1 &~ R2
MOV R0, R2              ; R0 = R2

LSL 邏輯左移;
LSR 邏輯右移;
ASR算數(shù)右移;
ROR循環(huán)右移;

比較操作:

CMP R1, R2           ; 執(zhí)行R1 - R2并依結(jié)果設(shè)置flag
CMN R1, R2           ; 執(zhí)行R1 + R2并依結(jié)果設(shè)置flag
TST R1, R2           ; 執(zhí)行R1 & R2并依結(jié)果設(shè)置flag
TEQ R1, R2           ; 執(zhí)行R1 ^ R2并依結(jié)果設(shè)置flag

乘法操作:

MUL R4, R3, R2               ; R4 = R3 * R2
MLA R4, R3, R2, R1           ; R4 = R3 * R2 + R1

乘法操作的操作數(shù)必須來(lái)自寄存器匪燕。

2.內(nèi)存操作指令
基本格式:

op{cond}{type} Rd, [Rn,?Op2]

其中Rn是基址寄存器,用于存放基地址喧笔;
“cond”的作用與數(shù)據(jù)操作指令相同帽驯;
“type”指定指令“op”操作的數(shù)據(jù)類型,共有4種:

B(unsigned Byte)
無(wú)符號(hào)byte(執(zhí)行時(shí)擴(kuò)展到32bit书闸,以0填充)尼变;
SB(Signed Byte)
有符號(hào)byte(僅用于LDR指令;執(zhí)行時(shí)擴(kuò)展到32bit浆劲,以符號(hào)位填充)嫌术;
H(unsigned Halfword)
無(wú)符號(hào)halfword(執(zhí)行時(shí)擴(kuò)展到32bit,以0填充)牌借;
SH(Signed Halfword)
有符號(hào)halfword(僅用于LDR指令度气;執(zhí)行時(shí)擴(kuò)展到32bit,以符號(hào)位填
充)膨报。

如果不指定“type”磷籍,則默認(rèn)數(shù)據(jù)類型是word。

ARM內(nèi)存操作基礎(chǔ)指令只有兩個(gè):

LDR(LoaD Register)將數(shù)據(jù)從內(nèi)存中讀出來(lái)现柠,存到寄存器中院领;STR(STore Register)將數(shù)據(jù)從寄存器中讀出來(lái),存到內(nèi)存中晒旅。

LDR

LDR Rt, [Rn {, #offset}]        ; Rt = *(Rn {+ offset})雏亚,{}代表可選
LDR Rt, [Rn, #offset]!          ; Rt = *(Rn + offset); Rn = Rn + offset
LDR Rt, [Rn], #offset           ; Rt = *Rn; Rn = Rn + offset

STR
STR Rt, [Rn {, #offset}]      ; *(Rn {+ offset}) = Rt
STR Rt, [Rn, #offset]!        ; *(Rn {+ offset}) = Rt; Rn = Rn + offset
STR Rt, [Rn], #offset         ; *Rn = Rt; Rn = Rn + offset

變種,操作雙字,一次性操作2個(gè)寄存器:LDRD和STRD

格式:

op{cond} Rt, Rt2, [Rn {, #offset}]
STRD
STRD R4, R5, [R9,#offset]        ;  *(R9 + offset)= R4; *(R9 + offset + 4)= R5

·LDRD
LDRD R4, R5, [R9,#offset]       ;  R4 = *(R9 + offset); R5 = *(R9 + offset + 4)

LDM(LoaD Multiple)和STM(STore Multiple)進(jìn)行塊傳輸;
一次性操作多個(gè)寄存器;
基本格式:

op{cond}{mode} Rd{!}, reglist

其中Rd是基址寄存器俗或,
可選的“!”指定Rd變化后的值是否寫回Rd;
reglist是一系列寄存器溅呢,用大括號(hào)括起來(lái),它們之間可以用“,”分隔,也可以用“-”表示一個(gè)范圍,比如,{R4–R6,R8}表示寄存器R4该编、R5、R6硕淑、R8课竣;這些寄存器的順序是按照自身的編號(hào)由小到大排列的,與大括號(hào)內(nèi)的排列順序無(wú)關(guān)置媳。

需要特別注意的是于樟,LDM和STM的操作方向與LDR和STR完全相反:LDM是把從Rd開始,地址連續(xù)的內(nèi)存數(shù)據(jù)存入reglist中拇囊,STM是把reglist中的值存入從Rd開始迂曲,地址連續(xù)的內(nèi)存中。

“cond”的作用與數(shù)據(jù)操作指令相同寥袭÷放酰“mode”指定Rd值的4種變化規(guī)律,如下所示:

IA(Increment After)
每次傳輸后增加Rd的值传黄;
IB(Increment Before)
每次傳輸前增加Rd的值杰扫;
DA(Decrement After)
每次傳輸后減少Rd的值;
DB(Decrement Before)
每次傳輸前減少Rd的值膘掰。

例子:
foo():
    LDMIA R0, {R4 – R6}                 ; R4 = 5, R5 = 6, R6 = 7
    LDMIB R0, {R4 – R6}                 ; R4 = 6, R5 = 7, R6 = 8
    LDMDA R0, {R4 – R6}                 ; R4 = 5, R5 = 4, R6 = 3
    LDMDB R0, {R4 – R6}                 ; R4 = 4, R5 = 3, R6 = 2

3.分支指令

無(wú)條件分支和條件分支;

無(wú)條件分支:

B Label         ; PC = Label
BL Label        ; LR = PC – 4; PC = Label
BX Rd           ; PC = Rd并切換指令集
例子:
foo():
        B Label                 ; 跳轉(zhuǎn)到Label處往下執(zhí)行
        ......                  ; 得不到執(zhí)行
Label:
        ......

條件分支

cond            flag
EQ              Z = 1
NE              Z = 0
CS              C = 1
HS              C = 1
CC              C = 0
LO              C = 0
MI              N = 1
PL              N = 0
VS              V = 1
VC              V = 0
HI              C = 1 & Z = 0
LS              C = 0 | Z = 1
GE              N = V
LT              N !=  V
GT              Z = 0 & N = V
LE              Z = 1 | N != V
在條件分支指令前會(huì)有一條數(shù)據(jù)操作指令來(lái)設(shè)置flag章姓,分支指令根據(jù)flag的值來(lái)決定代碼走向:
Label:
    LDR R0, [R1], #4
    CMP R0, 0           ; 如果R0 == 0,Z = 1炭序;否則Z = 0
    BNE Label          ; Z == 0則跳轉(zhuǎn)

4.THUMB指令

THUMB指令集是ARM指令集的一個(gè)子集啤覆,每條THUMB指令均為16bit;因此THUMB指令比ARM指令更節(jié)省空間惭聂,且在16位數(shù)據(jù)總線上的傳輸效率更高。有得必有失相恃,除了“b”之外辜纲,所有THUMB指令均無(wú)法條件執(zhí)行;桶式移位無(wú)法結(jié)合其他指令執(zhí)行拦耐;大多數(shù)THUMB指令只能使用R0~R7這8個(gè)寄存器等耕腾。

THUMB特點(diǎn):

1.指令數(shù)減少;
2.沒(méi)有條件執(zhí)行
3.所有指令默認(rèn)附帶"s";
4.桶式移位無(wú)法結(jié)合其他指令執(zhí)行;
5.寄存器使用受限;
6.立即數(shù)和第二操作數(shù)使用受限
7.不支持?jǐn)?shù)據(jù)

1.1.3ARM 調(diào)用規(guī)則

當(dāng)一個(gè)函數(shù)調(diào)用另一個(gè)函數(shù)時(shí),常常需要傳遞參數(shù)和返回值杀糯;如何傳遞這些數(shù)據(jù)扫俺,稱為ARM匯編的調(diào)用規(guī)則。

函數(shù)的前4個(gè)參數(shù)存放在R0到R3中固翰,其他參數(shù)存放在棧中狼纬;返回值放在R0中

2.tweak的編寫套路

1.進(jìn)入進(jìn)程

$cycript -p XXX

2.查看UI層次

開啟expand
cy#?expand
expand==true

cy# [[UIApp keyWindow] recursiveDescription]

3.通過(guò)Cycript的"#"操作符可以拿到windows上的任意view

cy# tabView = #0x146e1af0

4.app所有windows

cy# [UIApp windows]

5.隱藏控件:

cy# [#0x146e6060 setHidden:YES]

6.獲取響應(yīng)函數(shù):

“cy# button = #0x14798410
#"<UIToolbarButton: 0x14798410; frame = (285 0; 23 44); hidden = YES; opaque = NO; gestureRecognizers = <NSArray: 0x14799510>; layer = <CALayer: 0x14798510>>"
cy# [button allTargets]
[NSSet setWithArray:@[#"<ComposeButtonItem: 0x14609d00>"]]]
cy# [button allControlEvents]
64
cy# [button actionsForTarget:#0x14609d00 forControlEvent:64]
@["_sendAction:withEvent:"]”

7.nextResponder
利用響應(yīng)者鏈,可以找到某個(gè)view的父類;

cy# [#0x17f92890 nextResponder]
#"<UITableViewWrapperView: 0x17eb4fc0; frame = (0 0; 320 504); gestureRecognizers = <NSArray: 0x17ee5230>; layer = <CALayer: 0x17ee5170>; contentOffset: {0, 0}; contentSize: {320, 504}>"
cy# [#0x17eb4fc0 nextResponder]
#"<UITableView: 0x16c69e00; frame = (0 0; 320 568); autoresize = W+H; gestureRecognizers = <NSArray: 0x17f4ace0>; layer = <CALayer: 0x17f4ac20>; contentOffset: {0, -64}; contentSize: {320, 717.5}>"
cy# [#0x16c69e00 nextResponder]

3LLDB的使用技巧

...待完善

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末羹呵,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子疗琉,更是在濱河造成了極大的恐慌冈欢,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,884評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件盈简,死亡現(xiàn)場(chǎng)離奇詭異凑耻,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)柠贤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門香浩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人臼勉,你說(shuō)我怎么就攤上這事弃衍。” “怎么了坚俗?”我有些...
    開封第一講書人閱讀 158,369評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵镜盯,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我猖败,道長(zhǎng)速缆,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,799評(píng)論 1 285
  • 正文 為了忘掉前任恩闻,我火速辦了婚禮艺糜,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘幢尚。我一直安慰自己破停,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,910評(píng)論 6 386
  • 文/花漫 我一把揭開白布尉剩。 她就那樣靜靜地躺著真慢,像睡著了一般。 火紅的嫁衣襯著肌膚如雪理茎。 梳的紋絲不亂的頭發(fā)上黑界,一...
    開封第一講書人閱讀 50,096評(píng)論 1 291
  • 那天,我揣著相機(jī)與錄音皂林,去河邊找鬼朗鸠。 笑死,一個(gè)胖子當(dāng)著我的面吹牛础倍,可吹牛的內(nèi)容都是我干的烛占。 我是一名探鬼主播,決...
    沈念sama閱讀 39,159評(píng)論 3 411
  • 文/蒼蘭香墨 我猛地睜開眼沟启,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼忆家!你這毒婦竟也來(lái)了犹菇?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,917評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤弦赖,失蹤者是張志新(化名)和其女友劉穎项栏,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蹬竖,經(jīng)...
    沈念sama閱讀 44,360評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡沼沈,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,673評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了币厕。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片列另。...
    茶點(diǎn)故事閱讀 38,814評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖旦装,靈堂內(nèi)的尸體忽然破棺而出页衙,到底是詐尸還是另有隱情,我是刑警寧澤阴绢,帶...
    沈念sama閱讀 34,509評(píng)論 4 334
  • 正文 年R本政府宣布店乐,位于F島的核電站,受9級(jí)特大地震影響呻袭,放射性物質(zhì)發(fā)生泄漏眨八。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,156評(píng)論 3 317
  • 文/蒙蒙 一左电、第九天 我趴在偏房一處隱蔽的房頂上張望廉侧。 院中可真熱鬧,春花似錦篓足、人聲如沸段誊。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)辱魁。三九已至,卻和暖如春染簇,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背锻弓。 一陣腳步聲響...
    開封第一講書人閱讀 32,123評(píng)論 1 267
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留青灼,地道東北人暴心。 一個(gè)月前我還...
    沈念sama閱讀 46,641評(píng)論 2 362
  • 正文 我出身青樓杂拨,卻偏偏與公主長(zhǎng)得像专普,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子弹沽,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,728評(píng)論 2 351

推薦閱讀更多精彩內(nèi)容