zoukankan      html  css  js  c++  java
  • Shellcoding教程:介绍ASM(译)

          网上看到一篇不错的介绍shellcode的入门文章,我就大致翻译一下,算是自己真正跨入二进制安全相关领域的学习吧。原文地址:http://www.primalsecurity.net/0x0-shellcoding-tutorial-introduction-to-asm/

          以下为翻译内容:(非逐句翻译)

          汇编代码介绍:

          汇编语言是一种为了方便与微处理器交互而设计的低级编程语言。该语言是与处理器系列相关联的,如Intel、ARM等。在理解汇编的时候,体系结构发挥了重要的作用,因为在32位和64位之间存在很大的不同。在这里我们主要集中到Linux下的Intel(IA-32)。

          今天我们看到的CPU寄存器为EAX、EBX、ECX和EDX。在最初设计时,这些寄存器拥有一般的功能。但是基于我们的目的,我们可以在每个时序存储任何我们喜欢的数据。这些寄存器的标准用法如下:

    EAX

    “累加器”通常用于算术运算

    EBX

    基址寄存器,作为数据指针

    ECX

    “计算器”,用于循环的索引

    EDX

    数据寄存器,充当一个I/O指针

          在后续文章中,我们会介绍其他一些寄存器。

          操作我们的寄存器:

          首先,我们会利用之前提到的寄存器创建一个基本的“hello world”的汇编语言脚本。要做到这一点,我们先创建一个名为“helloworld.asm”的新文件(可以取任何你想取的名字),然后在文本编辑器中创建‘.text’和‘.data’两个段,如下所示:

    
    section .text
    global _start       ;default entry point for linking
    
    _start:             ; entry point for commands
    
    section .data

          .data段我们将用于存储字符串(这可以用于变量等),.text段将创建ELF链接的入口,我们的指令用于操作寄存器设置我们的系统调用(多个),以及我们的指令给内核执行我们的系统调用。

          首先,我们需要使用define byte或者db把我们的字符串添加到.data段中:

    
    msg: db “Hello World!:,0x0a ; the string, followed by a new line character

          接下来,我们需要决定什么系统调用将用于我们的汇编指令。为了查看可用的系统调用,我们需要查看“uninstd_32.h”文件,一般存在于“/usr/include/i386-linux-gnu/asm/”或者可能在其他位置。我们可以打开这个文件查看可用的调用:

    48

          立即看到两个我们利用的系统调用,exit函数(#define __NR_exit 1)和write函数(#define __NR_write 4)。注意着两个系统调用号因为我们会在后面使用到。我们可以使用“man 2”来查看关于这些系统调用的细节。(例如:man 2 write):

    49

          查看man文件,看到我们需要使用多个字段,‘int fd’(字段描述符),‘const void *buf’(缓冲区),‘size_t count’(字符串大小)。在这个例子中,我们的字段描述符指示我们将要写入的位置(0代表标准输入,1代表标准输出,2代表标准错误)。在这里,我们的缓冲区,就是‘Hello World!’字符串,计数器就是缓冲区的长度。总括来说,我们有几下几点:

    • syscall:4;系统调用号代表我们的write命令
    • fd:1;字段描述符指示我们的字符串将被写到标准输出
    • *buf:msg;我们在.data段中创建的hello world字符串
    • count:13;我们缓冲区的长度12加上一个换行符

          现在,我们已经标识的必要的信息,我们可以开始操作寄存器了。要做到这一点,我们将使用Intel系统结构的寄存器操作的mov命令:

    
    mov [destination],

          我们将重复mov与四个字段的每一个,依次为EAX,EBX,ECX和EDX寄存器,后面再加上”int 0x80”命令来执行系统调用。

    
    section .text
    global _start       ;default entry point for linking
     
    _start:             ; entry point for commands
     
         ; use the write syscall to print 'Hello world!' to stdout
         mov eax, 4          ; move syscall 4(write) to the eax register
         mov ebx, 1          ; move field descriptor for stdout to ebx
         mov ecx, msg        ; move the memory address of our string to ecx
         mov edx, 13         ; move the length of the string to edx
         int 0x80       ; execute the syscall
     
    section .data
         msg: db “Hello world!”, 0x0a  ; the string, followed by a new line character

          现在,我们已经小心的编写了write系统调用。我们需要遵循相同的步骤,干净执行程序。要做到这一点,我们将使用前面提到的“exit”的系统调用.这一次,我们仅需要利用”int status“,下面的步骤用于exit系统调用后,你的代码将和下面类似:

    
    section .text
    global _start       ;default entry point for linking
     
    _start:             ; entry point for commands
     
         ; use the write syscall to print 'Hello world!' to stdout
         mov eax, 4          ; move syscall 4(write) to the eax register
         mov ebx, 1          ; move field descriptor for stdout to ebx
         mov ecx, msg        ; move the memory address of our string to ecx
         mov edx, 13         ; move the length of the string to edx
         int 0x80       ; execute the syscall
     
         ; use the exit syscall to exit the program with a status code of 0
         mov eax, 1          ; mov syscall 1(exit) to the eax register)
         mov ebx, 0          ; move status code to ebx
         int 0x80       ; execute the syscall
     
    section .data
         msg: db “Hello world!”, 0x0a  ; the string, followed by a new line character

          创建我们的可执行程序:

          现在,我们的汇编代码已经创建了,接下来将要把它编译称为目标文件,然后使用链接器创建我们的ELF可执行文件,我们使用如下的NASM命令来创建我们的目标文件:

    nasm -f elf32 -o <output object file> <input assembly file>

          现在我们有了一个成功的目标文件,我们可以使用ld来链接它,然后创建最后的执行文件。我们使用如下命令:

    ld -o <output file> <input object file>

          假设这种情况成功了,我们应该有了一个全功能的ELF可执行程序。现在,我们可以执行我们的文件,并且保证正确执行。

          附上NASM的下载地址:http://www.nasm.us/pub/nasm/releasebuilds/2.11.08/

  • 相关阅读:
    【CUDA开发】 Check failed: error == cudaSuccess (8 vs. 0) invalid device function
    【CUDA开发】 Check failed: error == cudaSuccess (8 vs. 0) invalid device function
    【神经网络与深度学习】【CUDA开发】服务器(多GPU)caffe安装和编译
    【神经网络与深度学习】【CUDA开发】服务器(多GPU)caffe安装和编译
    【神经网络与深度学习】Win10+VS2015 caffe环境搭建(极其详细)
    【神经网络与深度学习】Win10+VS2015 caffe环境搭建(极其详细)
    【OpenCV开发】OpenCV3后IPLimage转换成MAT的问题
    【OpenCV开发】OpenCV3后IPLimage转换成MAT的问题
    【VS开发】【视频开发】利用ffmpeg+opencv实现画中画
    【VS开发】【视频开发】利用ffmpeg+opencv实现画中画
  • 原文地址:https://www.cnblogs.com/hiccup/p/4487381.html
Copyright © 2011-2022 走看看