我有一个shellcode文件。 然后使用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运行./key$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运行后进行调试,则由于退出状态
,将无法找到该文件你能解释一下为什么会这样吗?我该如何解决这个问题呢?感谢
答案 0 :(得分:2)
它给了我一个警告
ld: warning: cannot find entry symbol _start; defaulting to 0000000000400080
这实际上不是问题,只要你的入口点是文本段的开头(即shellcode中的第一条指令)就可以了。
您收到错误是因为您遗漏了global
关键字和_start
符号名称之间的空格。即使用global _start
,或者不要打扰。您所做的事情定义了一个名为global_start
的标签,您可以从后面的错误消息中看到。
您在lodsb
上进行了段错误,因为您使用mov edi,esi
而不是mov rdi, rsi
截断了堆栈地址。如果你修复了这个问题,那么你就会把代码的末尾放到垃圾指令中,因为你没有进行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起始文件之间)的冲突而出错。
此错误是_start
中的crt1.o
定义(由gcc提供)引用了main
,但您的代码未提供main
。当您尝试编译未定义main
的C或C ++程序时会发生这种情况。
要与gcc链接,请使用-nostdlib
省略CRT启动文件和所有其他库。 (即链接与您使用ld
手动完全一样。)
gcc -nostdlib -static key.o -o key # static executable: just your code
使用_start
gcc -nostdinc -no-pie key.o -o key
您可以从以这种方式链接的代码调用libc函数,但只能在Linux或其他动态链接负责运行libc初始化函数的平台上调用。
如果静态链接libc,如果首先调用普通CRT启动代码所执行的所有libc init函数,则只能调用printf等函数。 (此处不再详述,因为此代码不使用libc)
答案 1 :(得分:0)
你的代码错了。 global 和 _start 之间必须有空格。这是你的一个问题。
section .text
global _start
_start:
xor eax,eax
push rax
...
此外,为了解决分段错误发生的原因,您必须对其进行调试。您可以查看执行segfault的汇编指令。
x/5i $eip