2017-06-09 09:15:10 jigongdajiang 阅读数 1163

转自:http://www.ithao123.cn/content-10909032.html

1、打开Finder ——>应用程序 ——> 实用工具——>终端

2、在命令行中输入如下命令(复制粘贴就好)

ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" < /dev/null 2> /dev/null

3、上述命令执行完毕后,输入如下命令

brew install nasm

4、将MAC重新启动,在终端中输入,查看最新版本

nasm -v

5、执行下面命令,查看支持的格式列表

nasm -hf




2016-03-22 09:37:16 youxiteehuu 阅读数 2527

我用的MAC系统版本是OS X EI Capitan 10.11.1


对于MAC系统nasm版本比较老,然而很多的第三方C开源库的编译要求的nasm版本会比较高,那我们怎么来安装或者更新Mac里的nasm呢,废话少说开始动手吧


1、打开Finder ——>应用程序 ——> 实用工具——>终端


2、在命令行中输入如下命令(复制粘贴就好)

ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" < /dev/null 2> /dev/null


3、上述命令执行完毕后,输入如下命令

brew install nasm

4、将MAC重新启动,在终端中输入

nasm -v

就可以看到最新版本的nasm啦,腻不腻害呀?


2016-06-10 23:16:20 jiangwei0512 阅读数 15981

nasm安装

首先需要安装nasm,不同版本的OS X可能没有装nasm,或者版本比较老。

安装的方法有几个:

可以在官网http://www.nasm.us/找到下载:

下载到的nasm可以直接运行。

也可以通过brew来安装nasm,它上面的版本也是比较新的。至于如何安装brew就不在这里介绍了。

 

示例代码

以下的示例代码来自wiki

global _start   ; 定义入口函数

section .data
  query_string        :  db    "Enter a character:  "
  query_string_len    :  equ   $ - query_string
  out_string          :  db    "You have input:  "
  out_string_len      :  equ   $ - out_string

section .bss
  in_char:			resw 4

section .text

_start:
  mov rax, 0x2000004         ; syscall需要用到的参数,表示write
  mov rdi, 1                 ; 表示stdout
  mov rsi, query_string      ; syscall调用回到rsi来获取字符
  mov rdx, query_string_len  ; 并到rdx获取长度
  syscall

  ; 读取字符
  mov rax, 0x2000003         ; syscall需要用到的参数,表示read
  mov rdi, 0                 ; 表示stdin
  mov rsi, in_char           ; 字符存储位置,在.bbs段
  mov rdx, 2                 ; 从内核缓存获取两个字节,一个给字符一个给回车
  syscall

  ; 打印输入的值
  mov rax, 0x2000004
  mov rdi, 1
  mov rsi, out_string
  mov rdx, out_string_len
  syscall

  mov rax, 0x2000004
  mov rdi, 1
  mov rsi, in_char
  mov rdx, 2                 ; 这里两个字节,因为第二个是回车
  syscall

  ; 退出syscall
  mov rax, 0x2000001         ; syscall需要用到的参数,表示退出syscall
  mov rdi, 0
  syscall

需要说明的几点:

1. global对外公开了函数的名称,这样ld时就可以指定它为入口函数;

2. syscall是内核调用函数,前面的mov指令都是用来提供参数的,在"syscall.h"中可以找到调用的具体作用(根据rax来确定);具体所有参数要怎么写,我也没有找到具体的说明...

关于syscall,在这里补充一些内容:

syscall指令使CPU从用户态跳转到了内核态,并执行内核态的代码(本例中就是控制台的读写操作)。

上述代码中的寄存器使用也是有规定的:首先rax用来确定内核态中需要执行的具体函数,这一部分在《深入理解Linux内核》一书的“系统调用”这一节中有讲到;其次,rdi、rsi、rdx等寄存器是用来传递内核态所执行的函数的参数的,在《nasmdoc.pdf》中的“Interfacing to 64-bit Programs(Unix)》一节中有如下的说明:

The first six integer arguments (from the left) are passed inRDI,RSI,RDX,RCX,R8, andR9, in that order.

与代码中的参数传递一致。

这里的参数规定也并不是nasm自己定的,而是因为mac 64位系统实现的ABI来决定的,具体可以参考《System V Application Binary Interface AMD64 Architecture Processor Supplement》,这个规范中的"Calling Conventions"一节中有如下的说明:

通过上面的说明,就可以基本理解例子中的代码了。

顺便说明下ABI是什么(摘自百度):

应用程序二进制接口 描述了应用程序和操作系统之间,一个应用和它的库之间,或者应用的组成部分之间的低级接口 。
ABI涵盖了各种细节,如:
数据类型的大小、布局和对齐;
调用约定(控制着函数的参数如何传送以及如何接受返回值),例如,是所有的参数都通过栈传递,还是部分参数通过寄存器传递;哪个寄存器用于哪个函数参数;通过栈传递的第一个函数参数是最先push到栈上还是最后;
系统调用的编码和一个应用如何向操作系统进行系统调用;
以及在一个完整的操作系统ABI中,目标文件的二进制格式、程序库等等。

另外,syscall.h中的参数并没有包含高字节中的2,原因在http://thexploit.com/secdev/mac-os-x-64-bit-assembly-system-calls/里面有说明,这里只摘抄一段:

Mac OS X or likely BSD has split up the system call numbers into several different “classes.” The upper order bits of the syscall number represent the class of the system call, in the case of write and exit, it’s SYSCALL_CLASS_UNIX and hence the upper order bits are 2! Thus, every Unix system call will be (0×2000000 + unix syscall #).

 

编译和运行

如下图所示:

这里需要了解nasm的编译时的一些参数。

比如-f用来指定编译环境,本机是mac x64的环境(就是这里的macho64,顺便说一句,这里的mach是一个操作系统内核,mac的系统是在此基础上开发的,所以是mach,而不是mac或者其它)。

在nasm编译器自带的nasmdoc.pdf手册中有更多的介绍。

也可以参考http://blog.csdn.net/jiangwei0512/article/details/51636602

 

2018-10-22 10:20:20 Zllvincent 阅读数 8654

一.方法1
到nasm 官网下载zip 文件解压后即可

二.方法2
终端运行:

ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" < /dev/null 2> /dev/null

运行完成后再运行:

brew install nasm

终端输入:nasm -v

在这里插入图片描述

至此,nasm 安装成功

2019-01-12 13:46:32 qq_43678568 阅读数 77
               
section .data    msg db 'This is a test', 10, 0    ; something stupid here    ft db 'addr is %x',10,0section .text    global _main    extern _printf    extern _exit_main:    push    rbp    mov     rbp, rsp           ;xor     al, al    mov     rdi, ft    ;lea rdi,[rel ft]    mov rsi,rdi    call    _printf ;xor rax,rax ;mov [rax],rax xor rdi,rdi call _exit    ;mov     rsp, rbp    ;pop     rbp    ret    

mac OS X 10.8.3:

nasm -f macho x.asm

gcc -o x x.o


会出现警告:

ld: warning: PIE disabled. Absolute addressing (perhaps -mdynamic-no-pic) not allowed in code signed PIE, but used in _main from a.o. To fix this warning, don't compile with -mdynamic-no-pic or link with -Wl,-no_pie

由于安全问题,解释如下:

所谓的PIE是指position independent executable,即地址无关exe,换句话说也就是生成的机器码中不能出现lea rax, some_symbol_name这样的绝对寻址,而只能以:lea rax, [rel some_symbol_name]这种形式出现,目的是为了提高安全性,这样OS可以以随机的地址加载exe。

采用相对地址定位即可:使用第16行指令代替。

x64 API接口有用的提示:

Mac OS X complies to the System V ABI - AMD64 Architecture Processor Supplement. It mandates that the fist 6 integer/pointer arguments are passed in RDIRSIRDXRCXR8 and R9, exactly in that order. The first 8 floating-point or vector arguments go into XMM0XMM1, ..., XMM7. Only after all the available registers are depleted or there are arguments that cannot fit in any of those registers (e.g. a 80-bit long double value) the stack is used. 64-bit pushes are performed using MOV (the QWORDvariant) and not PUSH. Simple return values are passed back in the RAX register. The caller must also provide stack space for the callee to save some of the registers.

printf is a special function because it takes variable number of arguments. When calling such functions RAX should be set to the number of floating-point arguments, passed in the vector registers. Also note that RIP-relative addressing is preferred for data that lies within 2 GiB of the code.


关于mac OS X系统调用号有用提示:

Mac OS X 64 bit Assembly System Calls

After reading about shellcode in Chapter 5 of Hacking: The Art of Exploitation, I wanted to go back through some of the examples and try them out. The first example was a simple Hello World program in Intel assembly. I followed along in the book and had no problems reproducing results on a 32 bit Linux VM using nasm with elf file format and ld for linking.

Then I decided I wanted to try something similar but with a little bit of a challenge: write a Mac OS X 64 bit “hello world” program using the new fast ‘syscall’ instruction instead of the software interrupt based (int 0×80) system call, this is where things got interesting.

First and foremost, the version of Nasm that comes with Mac OS X is a really old version. If you want to assemble macho64 code, you’ll need to download the lastest version.

nobody@nobody:~$ nasm -vNASM version 2.09.03 compiled on Oct 27 2010

I figured I could replace the extended registers with the 64 bit registers and the int 0×80 call with a syscall instruction so my first attempt was something like this

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
section .data
hello_world     db      "Hello World!", 0x0a
 
section .text
global _start
 
_start:
mov rax, 4              ; System call write = 4
mov rbx, 1              ; Write to standard out = 1
mov rcx, hello_world    ; The address of hello_world string
mov rdx, 14             ; The size to write
syscall                 ; Invoke the kernel
mov rax, 1              ; System call number for exit = 1
mov rbx, 0              ; Exit success = 0
syscall                 ; Invoke the kernel

After assembling and linking, I got this

nobody@nobody:~$ nasm -f macho64 helloworld.snobody@nobody:~$ ld helloworld.o ld: could not find entry point "start" (perhaps missing crt1.o) for inferred architecture x86_64

Apparently Mac OS X doesn’t use ‘_start’ for linking, instead it just uses ‘start’. After removing the underscore prefix from start, I was able to link but after running, I got this

nobody@nobody:~$ ./a.outBus error

I was pretty stumped at this point so I headed off to Google to figure out how I was supposed to use the ‘syscall’ instruction. After a bunch of confusion, I stumbled upon the documentation and realized that x86_64 uses entirely different registers for passing arguments. From the documentation:

The number of the syscall has to be passed in register rax.rdi - used to pass 1st argument to functionsrsi - used to pass 2nd argument to functionsrdx - used to pass 3rd argument to functionsrcx - used to pass 4th argument to functionsr8 - used to pass 5th argument to functionsr9 - used to pass 6th argument to functionsA system-call is done via the syscall instruction. The kernel destroys registers rcx and r11.

So I tweaked the code with this new information

...mov rax, 4              ; System call write = 4mov rdi, 1              ; Write to standard out = 1mov rsi, hello_world    ; The address of hello_world stringmov rdx, 14             ; The size to writesyscall                 ; Invoke the kernelmov rax, 1              ; System call number for exit = 1mov rdi, 0              ; Exit success = 0syscall                 ; Invoke the kernel...

And with high hopes that I’d see “Hello World!” on the console, I still got the exact same ‘Bus error’ after assembling and linking. Back to Google to see if others had tried a write syscall on Mac OS X. I found a few posts of people having success with the syscall number 0×2000004 so I thought I’d give it a try. Similarly, the exit syscall number was 0×2000001. I tweaked the code and BINGO! I was now able to see “Hello World” output on my console but I was seriously confused at this point; what was this magic number 0×200000 that is being added to the standard syscall numbers?

I looked in syscall.h to see if this was some sort of padding (for security?) I greped all of /usr/include for 0×2000000 with no hints what-so-ever. I looked into the Mach-o file format to see if it was related to that with no luck.

After about an hour and a half of looking, I spotted what I was looking for in ‘syscall_sw.h’

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
 * Syscall classes for 64-bit system call entry.
 * For 64-bit users, the 32-bit syscall number is partitioned
 * with the high-order bits representing the class and low-order
 * bits being the syscall number within that class.
 * The high-order 32-bits of the 64-bit syscall number are unused.
 * All system classes enter the kernel via the syscall instruction.
 *
 * These are not #ifdef'd for x86-64 because they might be used for
 * 32-bit someday and so the 64-bit comm page in a 32-bit kernel
 * can use them.
 */
#define SYSCALL_CLASS_SHIFT 24
#define SYSCALL_CLASS_MASK  (0xFF << SYSCALL_CLASS_SHIFT)
#define SYSCALL_NUMBER_MASK (~SYSCALL_CLASS_MASK)
 
#define SYSCALL_CLASS_NONE  0   /* Invalid */
#define SYSCALL_CLASS_MACH  1   /* Mach */ 
#define SYSCALL_CLASS_UNIX  2   /* Unix/BSD */
#define SYSCALL_CLASS_MDEP  3   /* Machine-dependent */
#define SYSCALL_CLASS_DIAG  4   /* Diagnostics */

Mac OS X or likely BSD has split up the system call numbers into several different “classes.” The upper order bits of the syscall number represent the class of the system call, in the case of write and exit, it’s SYSCALL_CLASS_UNIX and hence the upper order bits are 2! Thus, every Unix system call will be (0×2000000 + unix syscall #).

Armed with this information, here’s the final x86_64 Mach-o “Hello World”

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
section .data
hello_world     db      "Hello World!", 0x0a
 
section .text
global start
 
start:
mov rax, 0x2000004      ; System call write = 4
mov rdi, 1              ; Write to standard out = 1
mov rsi, hello_world    ; The address of hello_world string
mov rdx, 14             ; The size to write
syscall                 ; Invoke the kernel
mov rax, 0x2000001      ; System call number for exit = 1
mov rdi, 0              ; Exit success = 0
syscall                 ; Invoke the kernel
nobody@nobody:~$ nasm -f macho64 helloworld.snobody@nobody:~$ ld helloworld.o nobody@nobody:~$ ./a.outHello World!

总结如下:

因为mac OS X 10.8.3是64位系统,如果想要写汇编代码可有2种方式:

1 32位方式 macho32 ,但是要有32位的C库,你可以按照老的API ABI接口写程序,即

push xxx,push xxx,call xxx。

2 64位方式 macho64 ,使用新的64位ABI调用C库,或者你直接用syscall调用。

最后你可以用mac OS X自带的as汇编器来搞:

gcc -S -o x.s x.c

as -o x.o x.s

gcc -o x x.o


           

再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow

NASM

阅读数 2015

没有更多推荐了,返回首页