[英]Reverse engineering assembly code to C
有人可以為我提供幫助,幫助您拆卸下面的shell代碼(在注釋部分),並向我解釋最后一行代碼的作用嗎?
# include <stdlib .h>
# include <stdio .h>
# include <string .h>
const char code [] =
"\x31\xc0" /* Line 1: xorl %eax, %eax */
"\x50" /* Line 2: pushl %eax */
"\x68""// sh" /* Line 3: pushl $0x68732f2f */
"\x68""/bin" /* Line 4: pushl $0x6e69622f */
"\x89\xe3" /* Line 5: movl %esp, %ebx */
"\x50" /* Line 6: pushl %eax */
"\x53" /* Line 7: pushl %ebx */
"\x89\xe1" /* Line 8: movl %esp, %ecx */
"\x99" /* Line 9: cdq */
"\xb0\x0b" /* Line 10: movb $0x0b, %al */
"\xcd\x80" /* Line 11: int $0x80 */;
int main (int argc , char ** argv ) {
char buf [ sizeof ( code )];
strcpy (buf , code );
(( void (*)( )) buf )( ); /*I don't understand what this line is for*/
}
我讀了一些有關gdb的內容,但是在這種情況下我不知道如何使用它。
PS:我在x86-32 Ubuntu Linux機器上。
該代碼最有可能調用sys_execve()
內核函數
const char code [] =
"\x31\xc0" /* Line 1: xorl %eax, %eax */
"\x50" /* Line 2: pushl %eax */
"\x68""// sh" /* Line 3: pushl $0x68732f2f */
"\x68""/bin" /* Line 4: pushl $0x6e69622f */
"\x89\xe3" /* Line 5: movl %esp, %ebx */
"\x50" /* Line 6: pushl %eax */
"\x53" /* Line 7: pushl %ebx */
"\x89\xe1" /* Line 8: movl %esp, %ecx */
"\x99" /* Line 9: cdq */
"\xb0\x0b" /* Line 10: movb $0x0b, %al */
"\xcd\x80" /* Line 11: int $0x80 */;
sys_execve()
希望運行包含文件的字符串的寄存器。 sys_execve()
需要命令行參數 sys_execve()
函數是我們希望調用的函數 您已經有內聯代碼的匯編代碼,它在注釋中。 所以這部分有點令人困惑。
最后一條語句將buf
強制轉換為函數指針,然后調用代碼。 這是漏洞利用的實際用途。 (據我所知)它也是未定義的行為,並且在防止執行隨機內存區域的環境中不起作用。
C可以做到這一點,但是據我所知,沒有反向編譯器可以解決這個問題。
此代碼進行系統調用。 那就是int $0x80
是什么。 它前面的那一行說它是系統調用11。其余的指令為其設置了參數。
xorl %eax, %eax ; clear the 32-bit A register to 0
pushl %eax ; push 32-bit 0 on the stack
pushl $0x68732f2f ; push two 32-bit constants on the stack
pushl $0x6e69622f
movl %esp, %ebx ; copy the stack pointer into the 32-bit B register
pushl %eax ; push another 0
pushl %ebx ; push the stack pointer
movl %esp, %ecx ; copy the stack pointer into the 32-bit C register
cdq ; A already has 0. This also sets D to zero, 32-bit
movb $0x0b, %al ; move a constant 11 into the lower 8 bits of the A register
int $0x80 ; and do the system call
如果此代碼是為某些惡意目的而設計的,這不會令我感到驚訝。 這是一種將一些未知代碼引入程序並讓計算機執行它的方法。
程序集所做的是構建一個參數列表,以傳遞給操作系統調用以執行二進制文件( /bin/sh
)。
這兩行將/bin/sh
壓入堆棧。
pushl $0x68732f2f
pushl $0x6e69622f
這些行根據調用約定將指向/bin/sh
的指針放在參數寄存器中。
movl %esp, %ebx
pushl %eax
pushl %ebx
movl %esp, %ecx
cdq
該行將系統調用號11放置在寄存器中,作為中斷的參數。
movb $0x0b, %al
最后一行調用操作系統。
int $0x80
C代碼中的這一行只是將緩沖區強制轉換為函數指針,然后調用該函數。
(( void (*)( )) buf )( );
請注意,這曾經是利用軟件的常見方法,但是可以將類似的方法用於JIT編譯代碼。
我首先以為第3行和第4行正在設置/ bin / sh,但出於第二個想法,對於某些XI來說可能不是sh / bin / X。 實際上,// sh部分看起來幾乎像一個注釋?
我的直覺是,系統調用第11行是exec系統調用,而前面的幾行正在為exec調用設置args。
我冒昧地猜測您要謹慎運行此代碼;)
您可能要研究Hex-Rays拆裝器,它可以(某種程度上)將機器代碼/匯編器(兩者等效)轉換為C。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.