ld在汇编并将.asm文件链接到64位可执行文件后找不到symbol start错误



我有一个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

相关内容

最新更新