我有一个shell代码文件。然后使用ndisasm构建程序集代码。
ndisasm -b 64 shellcode > shellcode.asm
cat shellcode.asm | cut -c29->key.asm
我在key.asm文件中添加了2行
global_start:
_start:
$vi key.asm
global_start:
_start:
xor eax,eax
push rax
push qword 0x79237771
push qword 0x76772427
push qword 0x25747320
. . .
. . .
. . .
push qword 0x20757577
push rsp
pop rsi
mov edi,esi
mov edx,edi
cld
mov ecx,0x80
mov ebx,0x41
xor eax,eax
push rax
lodsb
xor eax,ebx
然后我组装并将其链接到64位可执行文件
$nasm -f elf64 -g -F stabs key.asm
$ld -o key key.o
它给了我一个警告
ld: warning: cannot find entry symbol _start; defaulting to 0000000000400080
我用gcc 测试过
gcc -o key key.o
我仍然得到一个错误几乎与第一个相同
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o: In
function `_start':
(.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status
当我跑步的时候/在我使用$ld NOT$gcc 后使用gdb密钥
$gdb -q ./key
$run
我得到一个分段故障
Starting program: /mnt/c/Users/owner/Documents/U
M/Computer_Security/ExtraCredit/key
Program received signal SIGSEGV, Segmentation fault.
0x000000000040013a in global_start ()
如果我在使用gcc运行后进行调试,那么由于退出状态,将找不到该文件
你能解释一下为什么会这样吗?我该如何解决这个问题?感谢
它会给我一个警告
ld: warning: cannot find entry symbol _start; defaulting to 0000000000400080
这实际上不是问题,只要您对以文本段开头为入口点(即外壳代码中的第一条指令)感到满意即可。
出现错误是因为您遗漏了global
关键字和_start
符号名称之间的空格。即使用global _start
,或者不用麻烦。您所做的定义了一个名为global_start
的标签,您可以从稍后的错误消息中看到。
由于使用mov edi,esi
而不是mov rdi, rsi
截断了堆栈地址,因此在lodsb
上出现segfault。如果你解决了这个问题,那么你就会从代码的末尾变成垃圾指令,因为你没有进行exit
系统调用。你已经在gdb中运行了,使用它吧!
我用gcc:
gcc -o key key.o
测试了它我仍然得到一个错误几乎与第一个相同
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o: In function `_start': (.text+0x20): undefined reference to `main'
不,这是一个完全不同的错误。如果您正确地导出了_start
,则可能会出现_start
定义冲突的错误(在您的代码和CRT启动文件之间)。
这个错误是crt1.o
中的_start
定义(由gcc提供)引用了main
,但您的代码没有提供main
。当您试图编译一个不定义main
的C或C++程序时,就会发生这种情况。
要与gcc链接,请使用-nostdlib
省略CRT启动文件和所有其他库。(即,链接与您手动使用ld
所做的非常相似。)
gcc -nostdlib -static key.o -o key # static executable: just your code
或者使用_start
在没有CRT启动文件的情况下动态链接。
gcc -nostdinc -no-pie key.o -o key
您可以从以这种方式链接的代码中调用libc函数,但只能在Linux或其他平台上,动态链接负责运行libc初始化函数。
如果静态链接libc,那么只有在第一次调用普通CRT启动代码所做的所有libc-init函数时,才能调用printf之类的函数。(此处不详细说明,因为此代码不使用libc)
您的代码是错误的。在全局和_start之间必须有一个空格。这是你的问题之一。
section .text
global _start
_start:
xor eax,eax
push rax
...
此外,要了解分段错误发生的原因,您必须对其进行调试。您可以查看执行分段错误的汇编指令。
x/5i $eip