日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

栈溢出笔记1.5 换一个汇编工具

發(fā)布時(shí)間:2025/3/15 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 栈溢出笔记1.5 换一个汇编工具 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
?

前面的內(nèi)容中我們使用VC++內(nèi)聯(lián)匯編,雖然很方便,但是無(wú)法定義字符串常量,導(dǎo)致我們需要把字符串的ASCII碼找到,再一個(gè)一個(gè)壓入棧中,比較繁瑣,本節(jié),我們換一個(gè)匯編工具——nasm,選擇它是因?yàn)樗梢钥缙脚_(tái)使用。

有了這個(gè)匯編工具,我們就可以定義字符串常量了,例如:

/*****************************************************************************/ DB “example_1”, 0x00 DB “HelloWorld”, 0x00 /*****************************************************************************/
  • 1
  • 2
  • 3
  • 4

這樣方便是方便了,但是出現(xiàn)了新的問(wèn)題,我們不可能寫(xiě)成這個(gè)樣子:

/*****************************************************************************/ push ebp mov ebp, esp db “example_1”, 0x00 db “HelloWorld”, 0x00 db “user32.dll”, 0x00 lea ebx, [ebp-24h] push ebx mov ebx, 0x7c801d7b call ebx // LoadLibraryA /*****************************************************************************/
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

因?yàn)槿齻€(gè)字符串為數(shù)據(jù),而不是指令,不可能夾在指令中間,這樣會(huì)讓CPU將數(shù)據(jù)當(dāng)做指令運(yùn)行,程序跑飛。因此,只能放在指令區(qū)域之外。但是,又必須放在代碼段中,因?yàn)镾hellcode只有指令,沒(méi)有數(shù)據(jù)段。因此,有了下面這種經(jīng)典的做法:將字符串定義放置到一條CALL指令之后,由于CALL指令會(huì)將返回地址壓棧,此時(shí)壓入棧中的地址就為第一個(gè)字符串的地址,從而,我們可以在此后的代碼中在棧上獲取該字符串的地址。如下結(jié)構(gòu):

/*****************************************************************************/ JMP short GetString RunMsgBox: ... GetString: CALL RunMsgBox DB “example_1” DB “HelloWorld” /*****************************************************************************/
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

這種結(jié)構(gòu)就充分說(shuō)明了指令和數(shù)據(jù)并不區(qū)分,本來(lái)CALL指令用來(lái)在棧上保存指令,結(jié)果現(xiàn)在被用來(lái)保存數(shù)據(jù)了。

下面就是利用上述結(jié)構(gòu)編寫(xiě)的匯編程序:

/*****************************************************************************/ // example_8 nasm下的匯編Shellcode SECTION .textBITS 32global _main_main: jmp short GetStringRunMsgBox: pop ebx push ebx ; "user32.dll" mov eax, 0x7c801d7b ; LoadLibraryA call eax xor eax,eax push eax lea ebx, [ebx+11] ; "example_1" push ebx lea ebx, [ebx+10] ; "HelloWorld" push ebx push eax mov ebx, 0x77d507ea ; MessageBoxA call ebx push eax mov ebx, 0x7c81cafa ; ExitProcess call ebx GetString: call RunMsgBox db "user32.dll", 0x00 db "example_1", 0x00 db "HelloWorld", 0x00 /*****************************************************************************/
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

RunMsgBox中第一句pop ebx就將“user32.dll”的首地址保存在了ebx,這里注意與棧不同,后面的ebx地址是加而不是減。使用命令:

nasm -f win32 example_8.asm

編譯為obj文件。然后使用VS的cl.exe,鏈接為exe:

cl example_8.obj libcmt.lib

運(yùn)行exe,成功:

?
圖34

下面我們?cè)贗mmunity Debugger來(lái)看看:?
?
圖35

這一段就是完整的代碼,可見(jiàn),字符串?dāng)?shù)據(jù)全部被反匯編為指令了,上圖中標(biāo)出了三個(gè)字符串的結(jié)尾符。

標(biāo)出了結(jié)尾符之后,問(wèn)題也就來(lái)了,是的,空字節(jié),又出現(xiàn)了空字節(jié),而且這次更不好處理,因?yàn)槲覀冎挥昧俗址氖椎刂贰榱瞬怀霈F(xiàn)空字節(jié),我們定義字符串的時(shí)候不能加0x00結(jié)束符,但是使用字符串的時(shí)候又需要該結(jié)束符,而且,這樣定義的字符串位于代碼段,代碼段是不可寫(xiě)的,也就是一旦定義,不可修改。所以,如果空字節(jié)會(huì)引起問(wèn)題,就不要這樣定義。使用直接壓棧的方法反而容易處理。

使用nasm有個(gè)好處,就是可以直接編譯為bin格式,即操作碼,例如:

nasm -f bin -o example_8.bin example_8.asm

用HexEdit打開(kāi)example_8.bin,如下:

?
圖36

這樣,可以簡(jiǎn)單的寫(xiě)個(gè)程序?qū)in文件寫(xiě)出為Shellcode,就不用再去Immunity Debugger一個(gè)字節(jié)一個(gè)字節(jié)的摳出來(lái)了。

總結(jié)

以上是生活随笔為你收集整理的栈溢出笔记1.5 换一个汇编工具的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。