本文介绍了执行从C二进制机器code的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这的我已成功地生产出只有528个字节的指令在大小的a.out(当GCC main.c中给了我8539个字节开始大文件)。

main.c中是:

  INT主(INT ARGC,字符** argv的){    返回42;
}

但我的a.out从这个汇编文件,而不是建:

main.s:

 ; tiny.asm
  BITS 64
  GLOBAL _start
  .text段
  _开始:
                MOV EAX,1
                MOV EBX,42
                INT 0x80的

 我@#补偿NASM -f ELF64 tiny.s
我@#补偿GCC -Wall -s -nostartfiles -nostdlib tiny.o
我@#补偿./a.out;回声$?
42
我@#补偿WC -c的a.out
528的a.out

因为我需要机器code我做的:

  objdump的-d的a.outa.out格式:文件格式ELF64,X86-64
.text段拆卸:00000000004000e0<的.text计算值:
  4000e0:B8 01 00 00 00 $ MOV为0x1,%eax中
  4000e5:BB 2A 00 00 00 $ MOV 0x2a,EBX%
  4000ea:CD 80 INT 0x80的$>#objdump的-hrt的a.outa.out格式:文件格式ELF64,X86-64部分:
IDX名称大小VMA LMA文件ALGN关闭
 0 .note.gnu.build-ID 00000024 00000000004000b0 00000000004000b0 000000b0 2 ** 2
                  内容ALLOC,LOAD,只读,DATA
 1的.text 0000000c 00000000004000e0 00000000004000e0 000000e0 2 ** 4
                  内容ALLOC,LOAD,只读,code
符号表:
无符号

文件是小端约定:

 我@#补偿-a rea​​delf的a.out
ELF头:
  魔术:7F 45 4C 46 02 01 01 00 00 00 00 00 00 00 00 00
  类别:ELF64
  数据:2的补,小尾数
  版本:1(电流)
  OS / ABI:UNIX - 系统V
  ABI版本:0
  类型:EXEC(可执行文件)
  机床:Advanced Micro Devices公司X86-64
  版本:为0x1
  入口地址:0x4000e0
  程序头开始:64(字节到文件)
  节头的开始:272(字节到文件)
  标志:为0x0
  这个头的大小:64(字节)
  程序头的尺寸:56(字节)
  程序头数:2
  节头的大小:64(字节)
  节头数:4
  节头字符串表指数:3

现在我想执行这个是这样的:

 的#include<&unistd.h中GT;
 //哪个版本(更多)是否正确?
 //这可能(???)涉及到字节序
字符code [] =\\ X01 \\ XB8 \\ X00 \\ X00 \\ XBB \\ X00 \\ X00 \\ X2A \\ X00 \\ X00 \\ X80 \\ XCD \\ X00
字符code_v1 [] =\\ XB8 \\ X01 \\ X00 \\ X00 \\ X00 \\ XBB \\ X2A \\ X00 \\ X00 \\ X00 \\ XCD \\ X80 \\ X00INT主(INT ARGC,字符** argv的)
{
/ *创建一个函数指针* /
INT(* FUNC)();
FUNC =(INT(*)())code;
(INT)(* FUNC)();返回0;
}

但是我得到分段错误。 我的问题是:这个文本栏目

  4000e0:B8 01 00 00 00 $ MOV为0x1,%eax中
  4000e5:BB 2A 00 00 00 $ MOV 0x2a,EBX%
  4000ea:CD 80 INT 0x80的$

(本机code)所有我真的需要吗我做的不对(字节序?),也许我只需要SIGSEGV以来以不同的方式来调用这个?


解决方案

我得到了这个工作。在code必须是标记为可执行code。做到这一点的方法之一是这个二进制机器code复制到可执行的缓冲区。

 的#include<&unistd.h中GT;
#包括LT&; SYS / mman.h>
#包括LT&;&string.h中GT;字符code [] = {0x55,0x48,0x89,0xe5,0x89,0x7d,0xFC有,0x48,
    0x89,0x75,0xf0,0xb8,0x2a,0x00,0x00,0x00,0xc9,0xc3,0x00};
/ *
 * 00000000004004b4<主> 55推%RBP
00000000004004b5<主+为0x1> 48 89 E5 MOV%RSP,RBP%
00000000004004b8<主+为0x4> 89 FC 7D MOV%EDI,-0x4(RBP%)
00000000004004bb<主+ 0x7的> 48 89 75 F0 MOV%RSI,-0x10(RBP%)
/NetBeansProjects/examples/tiny_c/tiny.c:15
    返回42;
00000000004004bf<主+ 0XB> B8 2A 00 00 00 $ MOV 0x2a,EAX%
/NetBeansProjects/examples/tiny_c/tiny.c:16
}
00000000004004c4<主+ 0×10> C9 leaveq
00000000004004c5<主+ 0×11> C3 retq
 * /
INT主(INT ARGC,字符** argv的)
{
    无效* BUF;  / *副本code到可执行的缓冲区* /
  BUF = MMAP(0,sizeof的(code),PROT_READ | PROT_WRITE | PROT_EXEC,
              MAP_PRIVATE | MAP_ANON,-1,0);
  的memcpy(BUF,code,sizeof的(code));  / *运行code * /
  INT I =((INT(*)(无效))BUF)();
  的printf(完成这件事返回:%D,我);
返回0;
}

这篇关于执行从C二进制机器code的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-01 23:05