Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/130.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 了解如何手动发出处理器指令_C++_Linux_Assembly - Fatal编程技术网

C++ 了解如何手动发出处理器指令

C++ 了解如何手动发出处理器指令,c++,linux,assembly,C++,Linux,Assembly,我在读一篇关于如何构造的文章,作者基本上使用了以下代码: // Processor instructions for: // mov eax, 0 // ret unsigned char code[] = {0xb8, 0x00, 0x00, 0x00, 0x00, 0xc3}; void *mem = mmap(NULL, sizeof(code), PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE, -1, 0);

我在读一篇关于如何构造的文章,作者基本上使用了以下代码:

// Processor instructions for:
//   mov eax, 0   
//   ret 
unsigned char code[] = {0xb8, 0x00, 0x00, 0x00, 0x00, 0xc3};

void *mem = mmap(NULL, sizeof(code), PROT_WRITE | PROT_EXEC,
    MAP_ANON | MAP_PRIVATE, -1, 0);  

memcpy(mem, code, sizeof(code));

int (*func)() = mem;   
return func();
除了他知道如何手动将汇编指令映射到数字代码之外,我对代码了解得很透彻。为了理解这一点,我需要学习什么?

参考文献()介绍了装配指令如何映射到实际机器代码上。当然,这将在CPU/环境之间进行-例如,上述操作在ARM系统上不起作用


或者,可以从现有生成的输出(如汇编程序的输出)复制这些值。

您可以使用许多库来编写JIT。将帮助您发出机器代码指令(在x86上),将一些抽象指令集(或抽象语法树)转换为机器代码


记录处理器(在长文档中)。因为你可能需要阅读上千页。

我是文章作者,希望你喜欢

为了构建这些价值观,我基本上做到了

$ cat test.S
  .intel_syntax noprefix
  mov eax, 0
  ret
$ gcc -c -o test.o test.S
$ objdump -d -M intel test.o

test.o:     file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <.text>:
   0:   b8 00 00 00 00          mov    eax,0x0
   5:   c3                      ret
$cat test.S
.intel_语法noprefix
mov-eax,0
ret
$gcc-c-o测试.o测试.S
$objdump-d-M intel test.o
test.o:文件格式elf64-x86-64
第节的分解。正文:
0000000000000000 :
0:B800 mov eax,0x0
5:c3 ret

您可以在左栏中看到指令的字节。除非你有很好的理由,否则我不建议你深入研究指令编码。它们非常复杂,汇编程序非常擅长生成这些东西。在这个层次上还有很多其他的东西需要学习,这将更好地利用你的大脑能量。阅读有一个良好的开端。

这让我朝着正确的方向前进。我在这里找到了一个列表:。我唯一不明白的是,MOV(0xB8)似乎是第一条指令的开始,而它似乎是第二条指令的结束(RET:0xC3)。@sircodesalot不同的指令,如
MOV
有不同的模式(例如立即?寄存器?内存?),并采用不同的参数(即
eax
0
)。另一方面,
ret
只有一种简单的无参数形式,这就是为什么它与
mov
输出相比显得如此小(一个字节)的原因,后者还必须对所有其他数据进行编码。我想我需要继续研究计算机体系结构。谢谢因此,我已经对此进行了足够多的实验,以探索它是如何工作的,以及如何发出我自己的代码(非常棒,非常棒的文章)等等。有一件事我有一个问题,在文章中你提到,
我们希望避免映射任何可写和可执行的内存。我想我从一个较高的层面上想知道:(1)风险是什么,(2)你如何正确地设置它?再次感谢,我喜欢你的文章@sircodesalot:风险在于,成功利用缓冲区溢出的人可以将自己的可执行指令写入该内存,然后跳转到该内存。基本上它是另一种攻击的载体。避免这种情况的方法是首先映射内存rw,然后像我在这段代码中所做的那样将映射更改为rx:很高兴你喜欢这篇文章!