久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 4006|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

從單片機(jī)指針說(shuō)到黑客程序

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:51472 發(fā)表于 2013-7-9 03:16 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
2004年7月的一天,在電子BBS討論區(qū)上溜達(dá),看到一個(gè)有趣的帖子,整個(gè)帖子內(nèi)容如下:

純C51復(fù)位功能函數(shù):一個(gè)大三學(xué)生,讓人又愛(ài)又怕

現(xiàn)單列復(fù)位部分如下:

main()

{

   unsigned char code rst[]={0xe4,0xc0,0xe0,0xc0,0xe0,0x32};  // 復(fù)位代碼

   (*((void (*)())(rst)))();  // 執(zhí)行上一行代碼,將rst數(shù)組當(dāng)函數(shù)調(diào)用

}

本來(lái)我告訴他嵌入如下代碼:

clr a

push acc

push acc

reti

結(jié)果他卻玩了前面哪一段,而數(shù)組rst[]中的內(nèi)容恰恰是上面的匯編機(jī)器碼,他的做法是將rst數(shù)組的數(shù)據(jù)當(dāng)作代碼保存,然后采用絕對(duì)地址方式指向該數(shù)組,將該數(shù)組中的代碼當(dāng)作函數(shù)來(lái)運(yùn)行。居然通過(guò)了!

我覺(jué)得有問(wèn)題,我說(shuō)即使如此,那絕對(duì)地址調(diào)用也應(yīng)該寫成(*((void (*)())(&rst)))() 才對(duì)呀,結(jié)果他反駁說(shuō),那樣的話,rst的地址就會(huì)當(dāng)成參數(shù)傳遞給這個(gè)絕對(duì)地址函數(shù),而實(shí)際LJMP調(diào)用的地址并非rst的地址,而是一個(gè)不確定的地址。于是我按照自己的說(shuō)法嘗試了一下,看看匯編結(jié)果,還真的是將rst的地址傳遞給了R1 R2,而絕對(duì)函數(shù)最終LJMP到了一個(gè)莫名其妙的地址上去了,死翹!

看來(lái)C真是一匹不容易駕馭的野馬,這個(gè)大三學(xué)生理解力在我之上,我30多歲的人了,干了這么多年還沒(méi)他的境界呢,唉,人家才學(xué)了幾天啊,翻了幾天書就這么厲害了,服了!

l         首先分析帖子的C語(yǔ)言代碼

第一句定義一個(gè)數(shù)組rst[],數(shù)組內(nèi)數(shù)據(jù)就是完成復(fù)位功能的匯編機(jī)器碼,具體對(duì)應(yīng)關(guān)系為:clr a == 0xe4、push acc == 0xc0,0xe0、reti ==0x32

第二句是一個(gè)函數(shù)指針的用法,函數(shù)指針用法稍微有點(diǎn)復(fù)雜,可參看本人著的書,:),以下為快速入門講解。

定義一個(gè)返回值是空函數(shù)指針的定義形式如下:

void (*p) ( )

當(dāng)把函數(shù)指針賦值后,就能通過(guò)函數(shù)指針調(diào)用函數(shù),調(diào)用形式如下,

      (*p) ( );

或等價(jià)的簡(jiǎn)化形式:

p ( );

假設(shè)rst就是函數(shù)指針,則如下調(diào)用形式就可以令單片機(jī)復(fù)位再起。

(*rst ) ( );  

但可惜,rst不是函數(shù)指針,而是數(shù)組名,雖然兩者都是地址,但不可直接調(diào)用數(shù)組名。

如同把char型變量a賦值給int型變量b,(int) 表示強(qiáng)制類型轉(zhuǎn)換:

b = (int) a

函數(shù)指針的強(qiáng)制類型轉(zhuǎn)換公式如下(C語(yǔ)言的哲學(xué)是定義形式和使用一致):

(  (void (*)()  ) rst

這樣經(jīng)過(guò)轉(zhuǎn)換后的rst就可以當(dāng)作函數(shù)指針使用了,簡(jiǎn)單的調(diào)用形式如下:

#define  K     (  (void (*)( )  ) rst

(*K) ( )

或:

(     * (  void (*)( )  )rst      ) ( );

這樣的語(yǔ)句就完成復(fù)位再啟功能了。類型轉(zhuǎn)換符()的優(yōu)先級(jí)跟指針運(yùn)算符*的優(yōu)先級(jí)相同,二者的結(jié)合方向是自右至左,所以上述語(yǔ)句就能完成復(fù)位功能了。保險(xiǎn)起見(jiàn)有些程序員常常喜歡再加個(gè)括號(hào):

#define  K     (   (  (void (*)( )  ) rst   )

(*K) ( )



(     *(   (  void (*)( )  )rst   )    ) ( );



由于沒(méi)有輸入?yún)?shù),上述復(fù)位代碼更嚴(yán)謹(jǐn)?shù)膶懛ㄊ牵?

#define  K     (   (  (void (*)(void )  ) rst   )

(*K) ( )



(     *(   (  void (*)(void )  )rst   )    ) ( );


l         關(guān)于帖子作者的解釋

千萬(wàn)不要犯“&rst”形式的錯(cuò)誤,對(duì)于一維數(shù)組而言,數(shù)組名rst就代表地址。以下二者等
價(jià),更常用的是等式左邊的形式:

rst == &rst[0]

整個(gè)函數(shù)指針無(wú)所謂參數(shù)傳遞,只是把rst當(dāng)作程序執(zhí)行地址調(diào)用而已,那個(gè)學(xué)生的解釋也有問(wèn)題。

還有一點(diǎn)必須提及,不是說(shuō)能通過(guò)編譯,甚至生成正確代碼,就表示某語(yǔ)句一定是對(duì)的。對(duì)很復(fù)雜的語(yǔ)句,要考慮到編譯器不嚴(yán)格甚至出錯(cuò)的可能性。

l         哈佛結(jié)構(gòu)和一個(gè)蠕蟲病毒

請(qǐng)注意,定義數(shù)組rst[]時(shí)用了關(guān)鍵字code,這是C51特有的關(guān)鍵字,意味著把數(shù)組定義到程序空間。標(biāo)準(zhǔn)C是沒(méi)有關(guān)鍵字code的。

哈佛結(jié)構(gòu)和普林斯頓結(jié)構(gòu):

哈佛結(jié)構(gòu)——程序空間和存儲(chǔ)空間分開的。C51算是不太嚴(yán)格的哈佛結(jié)構(gòu)——雖地址線分開,但數(shù)據(jù)線沒(méi)有分開。DSP是增強(qiáng)的哈佛結(jié)構(gòu)。

PC電腦上奔騰CPU是普林斯頓結(jié)構(gòu)——數(shù)據(jù)空間和程序空間統(tǒng)一編址。

如果數(shù)組rst[]數(shù)據(jù)的匯編機(jī)器碼是刪除文件的機(jī)器碼,這算不算是病毒?

曾經(jīng)流行過(guò)一種蠕蟲病毒,其發(fā)作機(jī)理采取的就是將惡意代碼保存成文本文件,然后通過(guò)指針調(diào)用執(zhí)行這個(gè)文本,很多殺毒程序也不會(huì)查詢文本文件。

程序也罷,數(shù)據(jù)也罷都是二進(jìn)制形式,如果數(shù)據(jù)空間和程序空間是統(tǒng)一編碼的, 數(shù)據(jù)當(dāng)然可以當(dāng)作程序運(yùn)行。

在這一點(diǎn)上,相對(duì)而言,哈佛結(jié)構(gòu)的CPU安全性會(huì)好一點(diǎn)點(diǎn)。但嵌入式應(yīng)用少有病毒,一般不用關(guān)心。



l         單片機(jī)復(fù)位的更好方法

帖子中匯編語(yǔ)言解釋如下:

clr a                      //清除ACC=0

push acc               //壓0到堆棧——8位

push acc               //再壓0到堆棧——再8位

reti                        //返回到0地址,從而執(zhí)行。

帖子作者的這種復(fù)位方法比較麻煩,更加簡(jiǎn)單的復(fù)位寫法是(摘自《C缺陷與陷阱》):

(     * (  void (*)( )  )0      ) ( );

本句的分析方法同上,但更加精煉,沒(méi)有多余的匯編語(yǔ)句。

上述復(fù)位的方法可稱為軟件復(fù)位。

軟件復(fù)位跟真正上電復(fù)位有很大差別:上電復(fù)位時(shí)大部分寄存器都有確定的復(fù)位值;軟件復(fù)位則只相當(dāng)于從0地址開始執(zhí)行而已,寄存器不會(huì)變?yōu)榇_定的復(fù)位值。
如果用戶要編程實(shí)現(xiàn)上電復(fù)位這種情況,在程序中不要踢看門狗即可。大部分單片機(jī)都有看門狗吧。

l         附錄

筆者精于DSP C24xx,但不太懂C51;讀者應(yīng)能從函數(shù)指針的定義和引用中看出來(lái),C語(yǔ)言的設(shè)計(jì)哲學(xué)是使用形式和定義形式一致,雖然這一點(diǎn)飽受質(zhì)疑。

如果你覺(jué)得雞蛋好吃時(shí),不必認(rèn)識(shí)那只母雞;但如果你覺(jué)得本文不錯(cuò),請(qǐng)來(lái)筆者網(wǎng)站坐坐。

可來(lái)信免費(fèi)轉(zhuǎn)載本文,請(qǐng)保持整篇文章的完整性,包括本句。            
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂1 踩
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 日韩精品 电影一区 亚洲 | 亚洲精品视频久久 | 一级黄色大片 | 国产一区三区视频 | 在线观看的av | 综合亚洲视频 | 日本国产精品视频 | 日日干日日射 | 99视频在线播放 | 国产目拍亚洲精品99久久精品 | 2019天天干夜夜操 | 久久99精品久久久久久 | 精品久久久久久久人人人人传媒 | 99伊人| 亚洲高清在线观看 | 免费观看a级毛片在线播放 黄网站免费入口 | 亚洲人成人一区二区在线观看 | 国产一区二区精品 | 韩国av一区二区 | 久久久这里只有17精品 | 中文字幕av在线 | 国产精品毛片一区二区在线看 | 久久久久久久久久久蜜桃 | 精品视频在线免费观看 | 日本不卡一区 | 香蕉久久久| а天堂中文最新一区二区三区 | a在线视频 | 国产日韩欧美中文字幕 | 中文字幕一区二区三区四区 | 色.com| 九九热在线精品视频 | 午夜看看| 欧美日韩精品专区 | 男女羞羞视频在线 | 中文字幕精品一区二区三区在线 | 毛片在线视频 | 91麻豆产精品久久久久久夏晴子 | 亚洲一区二区三 | av片免费 | 一区二区三区视频免费观看 |