青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

loop_in_codes

低調(diào)做技術(shù)__歡迎移步我的獨立博客 codemaro.com 微博 kevinlynx

一段tricky codes:函數(shù)調(diào)用的那些底層細(xì)節(jié)


有一天,被同事問到了下面這段代碼,就簡單分析了一下,發(fā)覺還有點意思:

__declspec(naked)
void call(void* pfn, 
{
    __asm 
    
{
        pop eax;
        add eax, 
3;
        xchg dword ptr[esp], eax;
        push eax;
        ret;
    }

}

 

再看它的用法:

 

void print_str( const char *s )
{
    printf( 
"%s\n", s );
}

call( print_str, 
"a string" );

 

call函數(shù)的大致作用,就是調(diào)用傳遞進(jìn)去的函數(shù)print_str,并將參數(shù)"a string"傳遞給目標(biāo)
函數(shù)。

但是它是怎么做到的呢?雖然call只有簡單的幾句匯編代碼,但是卻包含了很多函數(shù)在編譯
器中的匯編層實現(xiàn)。要了解這段代碼的意思,需要知道如下相關(guān)知識:

0、函數(shù)調(diào)用的實現(xiàn)中,編譯器通過系統(tǒng)堆棧(ESP寄存器指向)傳遞參數(shù);
1、C語言默認(rèn)的函數(shù)調(diào)用規(guī)則(_cdecl)中,調(diào)用者從右往左將參數(shù)壓入堆棧,并且調(diào)用者負(fù)
責(zé)堆棧平衡,也就是保證調(diào)用函數(shù)的前后,ESP不變;
2、匯編指令call本質(zhì)上是先將返回地址,通常是該條指令的下一條指令壓入堆棧,然后直
接跳轉(zhuǎn)到目標(biāo)位置;
3、匯編指令ret則是先從堆棧棧頂取出返回地址,然后跳轉(zhuǎn)過去;
4、匯編指令add加上其操作數(shù),貌似占3個字節(jié)長度;
5、在visual studio中,DEBUG模式下編譯器會在我們的代碼中插入各種檢測代碼,而
__declspec(naked)則是告訴編譯器:別往這里添加代碼。

了解了以上常識后,再看這段代碼,其本質(zhì)無非就是利用了這些規(guī)則,在代碼段跳來跳去。
我們來逐步分析一下:

在調(diào)用call函數(shù)的地方,大概的代碼為:

 

caller:
// 堆棧狀態(tài),從左往右分別表示棧頂至下
// ret_addr是call后的地址,即add esp, 8的位置
// a1, a2表示函數(shù)參數(shù),callee_addr是這里的print_str
// stack: ret_addr, callee_addr, a1, a2, 
call( print_str, "a string" ); 
add esp, 
8 //清除參數(shù)傳遞所占用的堆棧空間,維持堆棧平衡
end_label //位于add后的指令,后面會提到

call:
// 此時堆棧stack: ret_addr, a1, a2
pop eax // eax = ret_addr; stack: callee_addr, a1, a2, 
add eax, 3 // eax = end_label; stack: callee_addr, a1, a2, 
xchg dword ptr[esp], eax // eax = callee_addr; stack: end_label, a1, a2, 
push eax // stack: callee_addr, end_label, a1, a2, 
ret // 取出callee_addr并跳轉(zhuǎn),也就跳轉(zhuǎn)到print_str函數(shù)的入口,此時堆棧
    
// stack: end_label, a1, a2, 

callee(print_str):

 無視函數(shù)內(nèi)容

ret 
// print_str返回,此時正常情況下,堆棧stack: end_label, a1, a2, 
 
// 取出end_label并跳轉(zhuǎn),stack: a1, a2, 

 

那么當(dāng)callee結(jié)束時,則跳轉(zhuǎn)回caller函數(shù)中。不過,如過你所見,此時堆棧中還保留著再
調(diào)用call函數(shù)時傳入的參數(shù):stack: a1, a2, ...,所以,DEBUG模式下,VS就會提示你堆
棧不平衡。這里簡單的處理就是手動來進(jìn)行堆棧平衡:

 

    call( print_str, "a string" );
    __asm
    
{
        add esp, 
4
    }

 

傳入了多少個參數(shù),就得相應(yīng)地改變esp的值。

話說距離上篇博客都有半年了,自己都不知道時間晃得如此之快。最近業(yè)余折騰了下android開發(fā)
一不小心就跨年了。
 

posted on 2011-01-02 16:34 Kevin Lynx 閱讀(4932) 評論(4)  編輯 收藏 引用 所屬分類: c/c++

評論

# re: 一段tricky codes:函數(shù)調(diào)用的那些底層細(xì)節(jié) 2011-01-03 05:58 淘寶網(wǎng)

哈哈 不錯  回復(fù)  更多評論   

# re: 一段tricky codes:函數(shù)調(diào)用的那些底層細(xì)節(jié) 2011-01-06 12:30 miosys

整個懸念就是放在 add eax, 3;
這條指令就是為了在跳轉(zhuǎn)到最外層主調(diào)函數(shù)上時,留出一個指令空間來平棧。
如果用 ADD + WORD,應(yīng)該是 3。當(dāng)然不會BT到加 DWORD。  回復(fù)  更多評論   

# re: 一段tricky codes:函數(shù)調(diào)用的那些底層細(xì)節(jié) 2011-01-08 21:47 G++

圍觀,表示看不懂,哈哈哈哈哈~~~!  回復(fù)  更多評論   

# re: 一段tricky codes:函數(shù)調(diào)用的那些底層細(xì)節(jié)[未登錄] 2011-03-15 14:36 dophi

已閱  回復(fù)  更多評論   

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            国产精品亚洲一区二区三区在线| 日韩香蕉视频| 亚洲伦理在线| 亚洲精品中文字幕在线| 亚洲日本欧美| 一本到12不卡视频在线dvd| 亚洲日本中文字幕| 亚洲一区免费看| 欧美一进一出视频| 久久米奇亚洲| 亚洲国产影院| 亚洲视频精品| 亚洲欧洲日本国产| 欧美激情一区二区三区蜜桃视频| 欧美国产精品v| 国产精品theporn88| 国产亚洲在线| 在线亚洲伦理| 久久综合九色99| 亚洲日本视频| 久久久久国产精品www| 欧美伦理91i| 国产一区免费视频| 99精品热视频只有精品10| 欧美在线观看网址综合| 欧美激情片在线观看| 一区二区三区视频观看| 久久漫画官网| 国产精品视频免费观看www| 亚洲国产欧美精品| 久久精品三级| 一区二区高清在线观看| 久久欧美中文字幕| 国产精品亚洲一区二区三区在线| 日韩视频中午一区| 美脚丝袜一区二区三区在线观看 | 欧美日韩国产二区| 一区二区亚洲精品国产| 亚洲欧美制服另类日韩| 亚洲欧洲在线一区| 久久精品国产免费| 国产精品毛片在线看| 亚洲精品久久久久久下一站 | 久久av老司机精品网站导航| 亚洲人成网在线播放| 久久精品国产亚洲a| 国产欧美日韩在线观看| 小黄鸭精品密入口导航| 亚洲私拍自拍| 国产精品福利在线观看| 在线亚洲伦理| 亚洲精品免费电影| 欧美另类videos死尸| 亚洲精品美女在线| 亚洲成人在线视频播放| 免费观看成人鲁鲁鲁鲁鲁视频 | 国产一区二区三区四区| 亚洲一区在线播放| 99天天综合性| 国产精品激情| 欧美一区二区三区男人的天堂| av成人激情| 国产欧美亚洲视频| 极品少妇一区二区三区精品视频| 欧美日韩一区二区三区视频 | 久久精品免费| 午夜欧美大尺度福利影院在线看| 国产精品普通话对白| 性xx色xx综合久久久xx| 午夜视频在线观看一区二区三区 | 欧美一级久久久久久久大片| 亚洲无限乱码一二三四麻| 国产精品久久一卡二卡| 久久久久久久久久久久久女国产乱| 午夜精品久久久久| 黄色精品一区二区| 欧美国产日本韩| 欧美日韩精品二区| 亚久久调教视频| 久久青草福利网站| 在线一区二区三区四区| 亚洲伊人第一页| 影音先锋久久久| 日韩视频一区二区三区在线播放免费观看| 欧美日韩国产区| 久久岛国电影| 欧美激情网友自拍| 欧美一区二区三区视频在线 | 国产一区二区三区直播精品电影 | 国产一区二区三区成人欧美日韩在线观看| 久久久久久一区二区三区| 久色成人在线| 欧美一区二区成人| 欧美成人在线免费观看| 午夜精品一区二区三区在线视| 久久精品欧美日韩| 一区二区三区国产在线| 久久精品夜色噜噜亚洲aⅴ| 亚洲素人在线| 美日韩免费视频| 久久精品欧洲| 国产精品视频内| 亚洲欧洲精品成人久久奇米网 | 亚洲区免费影片| 国产在线播放一区二区三区| 日韩视频免费大全中文字幕| 狠狠色狠狠色综合系列| 一本色道婷婷久久欧美| 在线观看亚洲视频啊啊啊啊| 亚洲一区成人| 日韩一级二级三级| 美女日韩在线中文字幕| 久久久精品一品道一区| 久久婷婷人人澡人人喊人人爽| 亚洲美女在线观看| 极品尤物av久久免费看| 亚洲一二三级电影| 一本色道久久综合一区| 老色鬼久久亚洲一区二区| 久久精品国产亚洲精品| 国产精品久久久久久久久| 91久久综合| 亚洲人成在线播放| 久久只有精品| 看欧美日韩国产| 狠狠狠色丁香婷婷综合激情| 亚洲淫性视频| 亚洲男女自偷自拍| 欧美日韩在线亚洲一区蜜芽| 亚洲欧洲日产国码二区| 91久久国产精品91久久性色| 久久婷婷色综合| 欧美成人69av| 亚洲日本成人| 欧美激情亚洲自拍| 最新日韩中文字幕| 一区二区三区精品在线| 欧美日本韩国在线| 在线综合视频| 久久大香伊蕉在人线观看热2| 国产女人水真多18毛片18精品视频| 在线亚洲自拍| 欧美一区二区三区视频在线观看| 久久国产高清| 国产精品久久777777毛茸茸| 亚洲激情影院| 在线视频精品| 欧美性大战久久久久| 99亚洲精品| 久久激情五月婷婷| 国产一区二区三区av电影| 久久久青草婷婷精品综合日韩| 麻豆精品在线视频| 亚洲久久一区| 国产精品国产三级国产普通话三级 | 亚洲一区二区三区欧美 | 男人的天堂亚洲| 91久久精品国产91性色| 中文国产亚洲喷潮| 国产精品一区在线观看| 久久国产精品一区二区三区四区 | 午夜精品视频网站| 免费在线欧美视频| 亚洲天堂激情| 国产综合亚洲精品一区二| 麻豆成人综合网| 一本色道久久综合亚洲精品婷婷| 性欧美超级视频| 亚洲国产精品99久久久久久久久| 欧美精品亚洲精品| 亚洲欧美美女| 亚洲激情视频网| 欧美日在线观看| 久久午夜色播影院免费高清| 中文av字幕一区| 亚洲精品资源| 国产精品国产三级国产普通话三级 | 91久久精品一区二区三区| 欧美精品日韩| 久久精品视频va| 日韩一区二区精品视频| 久久久久久999| 亚洲手机在线| 亚洲精品久久嫩草网站秘色| 国产日韩欧美在线播放| 欧美精品日韩一区| 久久免费视频在线| 亚洲欧美日韩视频二区| 最新国产の精品合集bt伙计| 久久久精品视频成人| 亚洲一区二区三区影院| 亚洲卡通欧美制服中文| 好吊视频一区二区三区四区| 国产精品麻豆欧美日韩ww| 欧美日韩国产精品一区二区亚洲| 噜噜噜躁狠狠躁狠狠精品视频| 校园春色综合网| 亚洲综合电影一区二区三区| 99在线精品观看| 亚洲欧洲视频在线|