|
xwj 發(fā)表于 2009-3-5 10:03 侃單片機 ←返回版面 ![]()
|
樓主: 《反忽悠秘笈》--老x(chóng)教你怎樣抵擋老Hotel的“紅杏出墻裝瘋拳” |
HotC51 發(fā)表于 2009-3-9 19:37 裸奔式實(shí)時(shí)操作系統HotTask51 ←返回版面 ![]()
|
樓主: HotC51共產(chǎn)兒童團第十五課:菜農點(diǎn)評__HotASM_START__看誰(shuí)是尿童 |
開(kāi)課:
xwj 發(fā)表于 2009-3-5 12:28 侃單片機 ←返回版面 ![]() |
17樓: “紅杏出墻裝瘋拳”詳解--第一招: |
/*---------------------------------------------
HotTask51系統啟動(dòng)函數
void __HotASM_START__(void)
入口: 無(wú)
Keil DPTR = &__HotASM_START__[0]
R2D1 = DPTR
出口: 無(wú)
結果: 二次RETI后繼續執行
特點(diǎn): 本“函數”可以“動(dòng)態(tài)加載”
-----------------------------------------------*/
--老x(chóng):上面是注釋?zhuān)谥袊线^(guò)學(xué)的都能看懂,就不用啰嗦了
--觀(guān)眾:這還不啰嗦?暈!
--老x(chóng):甭暈啊,這都還沒(méi)開(kāi)始呢...
HotASM (__HotASM_START__)//(void) --定義個(gè)code區的數組,相當于code const unsigned char __HotASM_START__
--為什么呀?
--為什么?先去看下HotASM.h啊,里面先一招typedef code const unsigned char HotASM_ARRAY;//類(lèi)型定義
然后一招#define HotASM(NAME) HotASM_ARRAY(NAME)[]=
--嗯,象這樣的問(wèn)題老x以后就不再回答了,免得浪費時(shí)間,還把老x(chóng)也累得要死...
{//DPTR保存的是匯編數組函數的首地址__HotASM_START__
#define lable__HotASM_START__Exit \
( size_CLR_A() + size_MOV_REG_A() + size_JZ() + size_LJMP() + 2 * size_MOV_A_REG() + 2 * size_ADD_A() + 2 * size_PUSH_REG())
--嗯,這個(gè)是用來(lái)計算跳轉多少個(gè)字節的,因為后面有個(gè)分支,一個(gè)分支分支就會(huì )有2個(gè)出口,有2個(gè)出口當然就會(huì )有不同的跳轉偏移...
--暈,老x(chóng)今天怎么這么象唐僧?
--嗯,那就先不管了,其實(shí)老x(chóng)覺(jué)得啊,這樣子好麻煩啊,還要把中間跳過(guò)的指令都復制過(guò)來(lái),還要統計中間的字節數,真是麻煩啊~~~,老x(chóng)覺(jué)得啊,可以有更簡(jiǎn)單的方法啊,比如直接就RETI啊...
--少啰嗦,快說(shuō)正題!
--好好,老x(chóng)接著(zhù)分析啊~~
asm_CLR_A(), --想不用想,把ACC清零(有什么用呢?)
asm_MOV_IE_A(),//關(guān)中斷 --哦,原來(lái)是IE=ACC; 關(guān)中斷。(那...為什么不干脆CLR EA呢?)
asm_JZ(size_LJMP() - 1),//NOP() --A為零跳轉(這不是那脫褲子排氣嗎?A肯定為0啊,剛剛才清過(guò)呢)
asm_LJMP(0x5500),// --跳過(guò)去了,永遠運行不到
asm_MOV_A_DPL(), --ACC=DPL;
asm_ADD_A(lable__HotASM_START__Exit),//__HotASM_START__0 --加上偏移,進(jìn)位的話(huà)影響CY
asm_PUSH_ACC(),//壓入跳入地址__HotASM_START__0低8位 --ACC入棧,SP加一
asm_MOV_A_DPH(),// --ACC=DPH;
asm_ADDC_A(0), --前面加偏移時(shí)可能會(huì )進(jìn)位,把可能的進(jìn)位加進(jìn)去
asm_PUSH_ACC(),//壓入跳入地址__HotASM_START__0高8位 --ACC入棧,SP又加一;這是堆棧中最高2字節是下一個(gè)出口的地址
//lable__HotASM_START__Exit:
asm_RETI()//(連續調用RETI二次) --明明只有一次RETI嗎,看來(lái)老Hotel真是老糊涂了
--RETI和RET的作用可大了它的作用就是把堆棧中最高2字節裝入PC(程序地址指針寄存器),把SP-2,這樣下一個(gè)指令就返回到堆棧中最高2字節對應的地址位置繼續執行了
--這就相當于一個(gè)可以任意設置跳轉位置的LJMP,所有的OS可都要玩到這一招哦
};
首先可以看出XWJ很少“反匯編”,而且C51的匯編應該屬于“尿童級”。
asm_CLR_A(), --想不用想,把ACC清零(有什么用呢?)
asm_MOV_IE_A(),//關(guān)中斷 --哦,原來(lái)是IE=ACC; 關(guān)中斷。(那...為什么不干脆CLR EA呢?)
asm_JZ(size_LJMP() - 1),//NOP() --A為零跳轉(這不是那脫褲子排氣嗎?A肯定為0啊,剛剛才清過(guò)呢)
asm_LJMP(0x5500),// --跳過(guò)去了,永遠運行不到
在這4句里,隱藏了反逆向技術(shù)。
首先,asm_CLR_A(),得到一確定的事情,ACC肯定為0
asm_MOV_IE_A(),//關(guān)中斷,因為是初始化函數,就應該初始化干凈。
否則軟中斷后,EX0等IE內的5個(gè)中斷標志不會(huì )被清除。
下面這2句誰(shuí)能看出來(lái)???
asm_JZ(size_LJMP() - 1),//NOP() --A為零跳轉(這不是那脫褲子排氣嗎?A肯定為0啊,剛剛才清過(guò)呢)
asm_LJMP(0x5500),// --跳過(guò)去了,永遠運行不到
脫褲子排屁是臭逆向者的~~~因為此時(shí)ACC為0,它跳入了asm_LJMP(0x5500),的第2操作數0x00。
0x00是數據,但代碼確實(shí)NOP!!!
0x5500就是引誘反匯編去0x5500處折騰的,正常的程序永遠不會(huì )執行到~~~
這是系列反逆向技術(shù)的一招。請團員們切記。!
大家可以耐心地debug,可以看到好好的反匯編窗口在執行開(kāi)始沒(méi)有NOP指令,
單步到JZ后,在單步發(fā)現指令列表突然變化了---出現了NOP!!!
試想,團員們用菜農的“250”招后,誰(shuí)還再來(lái)反匯編???
暈都暈死它~~~
俺是“反匯編”的“革命先烈”~~~最近“反水”,所以俺最知道對付“自己人”
~~~
程序雖小,不暈則好。
有時(shí)間繼續點(diǎn)評其他HotC51Demo內的小程序~~~
注意,每個(gè)都有課本上學(xué)不到的知識~~~
課畢
HotC51@126.com 2009.3.9于菜地。
團部:http://group.ednchina.com/1623/
|
|
|
|