在ES?PLUS系列計算器上實現(xiàn)“編程”——(十)構造hackstring

pop pc 到底做了什么

如果想要了解更多細節(jié)臀规,請閱讀CPU手冊。簡而言之栅隐,CPU將棧頂?shù)?個字節(jié)放入pc塔嬉,接下來的一個字節(jié)放入csr,最后一個字節(jié)忽略租悄,然后將sp增加4

注意:盡管CPU支持16個段谨究,計算器只使用了2個, 所以只有lcsrcsr的最低位有意義,其他位永遠是0泣棋。 除此之外胶哲,由于內(nèi)存對齊的特性,pc寄存器的最低位永遠是0


所以潭辈,這對實現(xiàn)“編程”有什么用途呢鸯屿?

我們很容易發(fā)現(xiàn),代碼中存在大量的pop pc(大多數(shù)函數(shù)的末尾都是pop pc),這條指令會把棧頂?shù)?個字節(jié)以上述方式放入pc寄存器中并執(zhí)行把敢。因此寄摆,如果我們控制好棧中的數(shù)據(jù),就可以跳轉(zhuǎn)到任意位置技竟,執(zhí)行任意位置的代碼冰肴。

剩下的問題就是如何寫ROP程序了


例子

我們來看看這個hackstring(適用于991ES PLUS):

52個任意字符 cv24 M 1 - 0 cv26 X - Int cs23 0 - cv24 M 1 - 0 cv26 cs4 - A 4 0 - ! cs32 0 - 20個任意字符

注意:cv指的是單位轉(zhuǎn)換屈藐,cs指的是科學常數(shù)榔组,后面數(shù)字是對應編號熙尉。
我們先對照符號表把它轉(zhuǎn)化成16進制的形式:

?? ?? ?? ... (52個任意字符) ... ?? ?? ??
ee 54 31 ?? 30 f0 58 ?? 6a 27 30 ??
ee 54 31 ?? 30 f0 04 ?? 41 34 30 ?? 57 b6 30 ??

??的意思是這個位置的數(shù)值不重要。

這個hackstring如何運作搓扯?

首先检痰,基本溢出會導致這100字節(jié)在內(nèi)存中循環(huán)出現(xiàn)(具體原因在前幾節(jié)中)

具體地說, 地址x (8154h <= x < 8e00h) 具有hackstring中第 (x - 8154h) mod 100個字節(jié)的值。

最終锨推,根據(jù)計算铅歼,可知當關鍵的pop pc執(zhí)行時,棧頂?shù)乃膫€字節(jié)恰好是hackstring的第53-56字節(jié)换可。

也就是說椎椰,當pop oc被執(zhí)行后,pc=0x54EE沾鳄,csr=1慨飘,CPU執(zhí)行1:54EE處的代碼,這個地方的代碼是:

    pop xr0                        ; 154EE
    pop pc                         ; 154F0

我們把類似于 1:54EE這樣位置的代碼叫做gadget译荞,這是ROP領域的一個術語瓤的,這些地方往往位于某個函數(shù)的末尾。因為函數(shù)返回之前要將開頭備份的寄存器的值還原吞歼,所以存在大量的類似于上面這樣的位置圈膏,可以實現(xiàn)在ROP中控制寄存器的值,甚至向某個內(nèi)存單元中寫入特定的值等操作篙骡。

計算器將棧頂?shù)?個字節(jié)popxr0中稽坤,然后將棧頂?shù)?個字節(jié)poppc中(注意每次從棧中彈出值都會使sp自動增加,指向后面的值),現(xiàn)在er0=0xF030 r2=0x58糯俗,CPU又把6A 27 30 ??這四個字節(jié)放到pc寄存器中慎皱,即CPU又跳到了0:276A處執(zhí)行代碼:

    st r2, [er0]                   ; 0276A
    pop pc                         ; 0276C

接下來就不說了,跟前面一樣叶骨。關鍵處在這hackstring的最后8個字節(jié):

41 34 30 ?? 57 b6 30 ??

.


要理解這8個字節(jié)茫多,你得了解nX/U8函數(shù)調(diào)用的規(guī)范。

首先忽刽,對于會調(diào)用子函數(shù)的函數(shù)天揖,我們知道它們以push lr開頭,以pop pc結尾
這是一些函數(shù)的位置及功能(991ES PLUS)

  • 0:343Eh: 一個函數(shù), 接受一個地址er0和一個數(shù)字r2, 輸出位于地址er0處的r2行字符
  • 0:B654h: 一個函數(shù)跪帝,不接受參數(shù)也不返回值 (void f(void))今膊,閃爍光標,并等待用戶按下SHIFT鍵后返回伞剑。

這8個字節(jié)

41 34 30 ?? 57 b6 30 ??

按順序調(diào)用了這兩個函數(shù)

注意我提到了多行打印的函數(shù)位于0:343e斑唬,為什么我要跳轉(zhuǎn)到0:3441呢?

首先,實際pc的值其實是3440(內(nèi)存對齊),選擇41只是因為輸入方便而已。

現(xiàn)在恕刘,假設我們跳轉(zhuǎn)到了0:343E缤谎,那么CPU會先執(zhí)行push lr,最后函數(shù)末尾執(zhí)行pop pc時褐着,pc的值會被設定為最開始入棧的lr坷澡,但這并不是我們想要的結果(我們無法操縱lr的值)。我們的目的是想讓CPU繼續(xù)把棧頂?shù)闹祻棾龅?code>pc中含蓉,以便繼續(xù)控制程序流频敛。

因此,我們跳轉(zhuǎn)到push lr后的一條指令馅扣,而不是函數(shù)開頭斟赚。這樣就可以避免函數(shù)保存lr,最后pop pc就會繼續(xù)彈出棧頂?shù)闹档?strong>pc寄存器中差油,從而繼續(xù)控制程序流汁展。

(總結:跳到緊跟著push lr后的那條指令大多數(shù)情況下都是正確的,但在某些情況下厌殉,也可以有別的選項)

  1. 如果我們跳轉(zhuǎn)到push lr前面一條或若干條指令食绿,那么程序往往會執(zhí)行到一些無法預料的地方,因為push lr前面往往是另一個函數(shù)的末尾公罕,即pop pcrt器紧。
  2. 如果我們跳轉(zhuǎn)到push lr指令,那么最后在pop pc時楼眷,CPU會跳轉(zhuǎn)到開始時lr中的地址執(zhí)行塔沃,這只有在我們能夠控制寄存器lr的內(nèi)容時才可以控制程序流欢摄。
    一個類似的情況是:如果我們跳轉(zhuǎn)到一個以rt結尾的函數(shù)開頭或中間。我們也需要保證寄存器lr的值是可控的。
  3. 如果我們跳轉(zhuǎn)到push lr后的一條指令持偏,CPU會執(zhí)行完函數(shù)本身景鼠,然后彈出棧頂?shù)?個字節(jié)到pc寄存器中霞势。這是最理想的情況油额。
  4. 如果我們跳轉(zhuǎn)到push lr后的若干條指令,CPU會執(zhí)行函數(shù)體的大部分指令肮蛹,除了開頭的幾條指令(往往是備份寄存器)勺择,這往往會破壞棧平衡,因此需要仔細研究伦忠。

一般情況下我們在調(diào)用函數(shù)時只使用選項3省核,在某些情況下也會用到2和4,這些例子會另行說明昆码。


循環(huán)

唯一在ROP中實現(xiàn)循環(huán)的方法就是修改sp的值气忠,如果你在源代碼中搜索sp邻储,你會發(fā)現(xiàn)修改了sp的值而又離rtpop pc足夠近的指令只有:

  • mov sp, er14 (后面往往是pop er14pop pc)
  • add sp, #... (正數(shù)表示從棧中彈出相應字節(jié))

目前只有第一種用于循環(huán):

所以,為了循環(huán)我們需要:

  • 保證沒有執(zhí)行一些會破壞棧的函數(shù)(幾乎所有函數(shù)都會使用到棧用作臨時存儲)
  • 執(zhí)行gadget pop er14; pop pc 然后把 A-2 放在這個gadget的后面(A就是sp的新值).
  • 執(zhí)行gadget mov sp, er14; pop er14; pop pc.

(在有函數(shù)破壞了棧的情況下旧噪,循環(huán)依然是有可能的吨娜,在后面會提及)

當最后一個gadget mov sp, er14; pop er14; pop pc 被執(zhí)行時,發(fā)生了:

  • mov sp, er14: sp 的值變?yōu)?A - 2舌菜。
  • pop er14: sp 增加 2 字節(jié). er14 就是那兩個字節(jié)的內(nèi)容(不重要)萌壳。
  • pop pc: pc 的值現(xiàn)在變成了 A處的4個字節(jié)亦镶。

PS:可以認為這一串10個字節(jié)一起構成了goto A這樣一個gadget日月。


例子:

<52個任意符號> cv24 M 1 - Fvar cv26 cv40 - Int cs23 0 - tan-1 D 0 - cs26 cv26 cs16 D 1 - cv12 = 0 - sin 2 0 - 0 cv34 Int cs23 0 - (-) cs32 0 - frac Ans ^ cs32 0 - <后面填滿100個字節(jié)>

16進制表示:

?? ... (52 bytes) ... ??
ee 54 31 ?? 46 f0 fe ?? 6a 27 30 ?? b2 44 30 ?? 40 f0
1d 44 31 ?? e2 3d 30 ?? a0 32 30 ?? 30 f8
6a 27 30 ?? 60 b6 30 ?? ae 8b 5e b6 30 ??
?? ??

只有最后10個字節(jié)實現(xiàn)了循環(huán)

60 b6 30 ?? 跳轉(zhuǎn)到 0:b660h。 從 0:b660h0:b662h 的指令被執(zhí)行缤骨。
接下來爱咬,ae 8b 被彈出到 er14. (也就是0x8BAE)
5e b6 30 ?? 跳轉(zhuǎn)到 0:b65eh。與上述過程類似绊起,只不過多執(zhí)行了mov sp, er14精拟。


含有修改棧的循環(huán)

注意:

  • pop指令只會增加sp的值,不會修改棧本身
  • push指令大多數(shù)時候都會修改棧的內(nèi)容虱歪,只有當被push的值能夠確保恰好跟棧頂前的值相同的時候才不會修改棧的內(nèi)容蜂绎。(包括push lr)

所以,要在這種情況下循環(huán)笋鄙,我們需要在之前的循環(huán)方式之前加上還原堆棧的部分

大多數(shù)時候师枣,我們通過調(diào)用strcpy函數(shù)還原棧,在前面我們已經(jīng)知道內(nèi)存中全部是輸入?yún)^(qū)100字節(jié)的拷貝萧落,那么只要隨便把一個拷貝還原到剛才的地方就可以了践美。

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市找岖,隨后出現(xiàn)的幾起案子陨倡,更是在濱河造成了極大的恐慌,老刑警劉巖许布,帶你破解...
    沈念sama閱讀 216,544評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件兴革,死亡現(xiàn)場離奇詭異,居然都是意外死亡蜜唾,警方通過查閱死者的電腦和手機帖旨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來灵妨,“玉大人解阅,你說我怎么就攤上這事∶诨簦” “怎么了货抄?”我有些...
    開封第一講書人閱讀 162,764評論 0 353
  • 文/不壞的土叔 我叫張陵述召,是天一觀的道長。 經(jīng)常有香客問我蟹地,道長积暖,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,193評論 1 292
  • 正文 為了忘掉前任怪与,我火速辦了婚禮夺刑,結果婚禮上,老公的妹妹穿的比我還像新娘分别。我一直安慰自己遍愿,他們只是感情好,可當我...
    茶點故事閱讀 67,216評論 6 388
  • 文/花漫 我一把揭開白布耘斩。 她就那樣靜靜地躺著沼填,像睡著了一般。 火紅的嫁衣襯著肌膚如雪括授。 梳的紋絲不亂的頭發(fā)上坞笙,一...
    開封第一講書人閱讀 51,182評論 1 299
  • 那天,我揣著相機與錄音荚虚,去河邊找鬼薛夜。 笑死,一個胖子當著我的面吹牛版述,可吹牛的內(nèi)容都是我干的梯澜。 我是一名探鬼主播,決...
    沈念sama閱讀 40,063評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼院水,長吁一口氣:“原來是場噩夢啊……” “哼腊徙!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起檬某,我...
    開封第一講書人閱讀 38,917評論 0 274
  • 序言:老撾萬榮一對情侶失蹤撬腾,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后恢恼,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體民傻,經(jīng)...
    沈念sama閱讀 45,329評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,543評論 2 332
  • 正文 我和宋清朗相戀三年场斑,在試婚紗的時候發(fā)現(xiàn)自己被綠了漓踢。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,722評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡漏隐,死狀恐怖喧半,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情青责,我是刑警寧澤挺据,帶...
    沈念sama閱讀 35,425評論 5 343
  • 正文 年R本政府宣布取具,位于F島的核電站,受9級特大地震影響扁耐,放射性物質(zhì)發(fā)生泄漏暇检。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,019評論 3 326
  • 文/蒙蒙 一婉称、第九天 我趴在偏房一處隱蔽的房頂上張望块仆。 院中可真熱鬧,春花似錦王暗、人聲如沸悔据。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蜜暑。三九已至铐姚,卻和暖如春策肝,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背隐绵。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評論 1 269
  • 我被黑心中介騙來泰國打工之众, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人依许。 一個月前我還...
    沈念sama閱讀 47,729評論 2 368
  • 正文 我出身青樓棺禾,卻偏偏與公主長得像,于是被迫代替她去往敵國和親峭跳。 傳聞我的和親對象是個殘疾皇子膘婶,可洞房花燭夜當晚...
    茶點故事閱讀 44,614評論 2 353