无法使用ld - Mac OS X链接目标文件

tut*_*ike 3 c assembly shellcode

/*********
exit.asm
*/

[SECTION .text]

global _start


_start:
xor eax, eax
xor ebx, ebx
mov al, 1
int 0x80

//****************************
Run Code Online (Sandbox Code Playgroud)

首先,我使用nasm -f elf exit.asm生成目标文件.

然后我在我的Mac OS X 10.7上运行了以下"ld"命令,它有这些输出和警告,我试图在我的32位linux机器上运行它,一切都很顺利,请你解释为什么不会链接器在我的Mac上运行?

谢谢!

Alfred says: ld -o exiter exit.o
ld: warning: -arch not specified
ld: warning: -macosx_version_min not specified, assuming 10.7
ld: warning: ignoring file exit.o, file was built for unsupported file format ( 0x7f 0x45      0x4c 0x46 0x 1 0x 1 0x 1 0x 0 0x 0 0x 0 0x 0 0x 0 0x 0 0x 0 0x 0 0x 0 ) which is not the   architecture being linked (x86_64): exit.o
Undefined symbols for architecture x86_64:
  "start", referenced from:
    implicit entry/start for main executable
ld: symbol(s) not found for inferred architecture x86_64
Run Code Online (Sandbox Code Playgroud)

在我指定我的拱门和版本之后,我得到了:

Alfred says: ld -arch x86_64 -macosx_version_min 10.7 -o exiter exit.o
ld: warning: ignoring file exit.o, file was built for unsupported file format ( 0x7f 0x45     0x4c 0x46 0x 1 0x 1 0x 1 0x 0 0x 0 0x 0 0x 0 0x 0 0x 0 0x 0 0x 0 0x 0 ) which is not the   architecture being linked (x86_64): exit.o
 Undefined symbols for architecture x86_64:
 "start", referenced from:
    implicit entry/start for main executable
 ld: symbol(s) not found for architecture x86_64
Run Code Online (Sandbox Code Playgroud)

sco*_*ttt 6

获取程序链接是很容易的部分:

  • 更改_startstart
  • $ nasm -f macho exit.asm
  • $ ld -arch i386 -o exiter exit.o

问题是,exit.asm呼吁在i386的Linux exit()系统调用(EAX = 1),程序将按预期在OS X与零个状态退出

系统调用

一个系统调用是内核的请求.与之exit()不同sqrt(),它必须向其实现中具有更高权限的软件组件发出请求,因为它终止正在运行的程序.应用无法自行创建或终止进程.系统调用为应用程序提供了一种让内核代表他们执行操作的方法.

制作系统调用是这样的:

  • 应用程序通过将数据放入CPU寄存器(或寄存器指向的存储器)来描述他们想要执行的操作,例如
    • 该值1EAX是系统调用号exit.
    • 该值0EBX(EBX被清零xor)是第一个参数到系统调用,退出状态.
  • 应用程序发出一条指令,使控件转移到内核,例如
    • int 80 在i386上
    • sycall 在x86-64上
    • svc 在ARMv7上的Thumb模式下
  • 内核检查请求并决定执行或拒绝它.
  • 内核将控制权转移回app,返回值在商定的位置,例如i386上的EAX.

Linux和OS X都void exit(int)为C程序提供了一个函数,但是没有就如何向内核描述这个请求的细节达成一致.代码exit.asm_exit()函数的实现处于同一级别libc.

即使在运行Linux的不同体系结构之间,系统调用号和调用约定也不同.例如,在x86-64 Linux上,exit(0)更常见的是这样发出:

xor rdi, rdi
mov al, 60
syscall
Run Code Online (Sandbox Code Playgroud)

您可以通过拆解看到这个_exit/lib64/libc.so.6.

我们不能从libc调用exit()而不是吗?

您可以.但你必须将程序与libc.链接exit.asm上面的区别是:

$ cc -m32 -nostdlib exit.o -o exiter
Run Code Online (Sandbox Code Playgroud)

出口libc.asm

extern exit
global main
main:
push 0
call exit
Run Code Online (Sandbox Code Playgroud)

必须与以下内容联系:

$ cc -m32 exit-libc.o -o exit-libc
Run Code Online (Sandbox Code Playgroud)

试试这个,看一下文件大小.


Car*_*rum 5

Mac OS X 不使用 ELF,因此您需要生成一个 Mach-O 对象以在该系统上链接。在我的机器上nasm似乎只支持 32 位输出,因此您在链接时也需要匹配该体系结构。

我还必须更改_startstart才能链接到它。

这是您的代码的一个工作示例:

$ cat exit.asm 
[SECTION .text]

global start

start:
xor eax, eax
xor ebx, ebx
mov al, 1
int 0x80
$ nasm -f macho exit.asm 
$ ld -arch i386 -macosx_version_min 10.7  -o exiter exit.o 
$ ./exiter 
$ echo $?
236
Run Code Online (Sandbox Code Playgroud)

请注意,该程序可能无法在 Mac OS X 上执行您想要的操作,因为它不像 Linux 那样执行系统调用。