那么,计算机程序/可执行文件只是二进制数据(0 和 1)?
是的,比如图片、视频和其他数据。
当使用 OllyDbg 之类的反汇编程序查看时,它只是试图将那些 0 和 1 恢复为某种汇编(英特尔?)语言,并且输出大部分是正确的?
是的,在这种情况下,它总是正确的,因为在 16 位、32 位和 64 位中,mov al, 61h 总是组装到 0xB0 0x61(在 Intel 64 and IA-32 Architectures Software Developer's Manuals 和其他通常写为 B0 61 的地方)模式。注意0xB0 0x61 = 0b10110000 0b01100001。
您可以在第 2A 卷中找到不同指令的编码。例如这里是“B0+ rb MOV r8, imm8 E Valid Valid Move imm8 to r8”。在第 3-644 页。
其他指令有不同的含义取决于它们是在 16/32 还是 64 位模式下解释的。考虑一下这个短字节序列:66 83 C0 04 41 80 C0 05
在 16 位模式下,它们的意思是:
00000000 6683C004 add eax,byte +0x4
00000004 41 inc cx
00000005 80C005 add al,0x5
在 32 位模式下,它们的意思是:
00000000 6683C004 add ax,byte +0x4
00000004 41 inc ecx
00000005 80C005 add al,0x5
最后是 64 位模式:
00000000 6683C004 add ax,byte +0x4
00000004 4180C005 add r8b,0x5
因此,在不知道上下文的情况下,不能总是正确地反汇编指令(这甚至没有考虑到除了代码之外的其他内容可以驻留在文本段中,并且代码可以做一些令人讨厌的事情,例如动态生成代码或自行生成代码。修改)。
如果我的 SSD 上有这个 10110000 01100001 程序,并且我编写了一个 C#/PHP/wtvr 应用程序来读取文件的内容并将它们输出为位,我会看到这些确切的 10110000 01100001 数字吗?
是的,如果应用程序包含mov al, 61h 指令,则文件将包含字节0xB0 和0x61。
操作系统如何进行实际的“执行”?它如何告诉处理器“嘿,获取这些位并运行它们”?我可以直接在 C#/C++ 中这样做吗?
将代码加载到内存后(并且内存已正确设置权限),它可以跳转到或调用它并让它运行。即使操作系统只是另一个程序,您也必须意识到它是一个特殊程序,因为它首先到达处理器!它以特殊的主管(或管理程序)模式运行,允许它处理普通(用户)程序不允许的事情。就像设置 preemptive multitasking 一样,它可以确保自动生成流程。
第一个处理器还负责唤醒多核/多处理器机器上的其他内核/处理器。请参阅this SO 问题。
要调用您自己直接在 C++ 中加载的代码(我认为在 C# 中不使用不安全/本机代码是不可能的)需要特定于平台的技巧。对于 Windows,您可能想查看 VirtualProtect,在 linux 下查看 mprotect(2)。或者更实际地来自使用this process for Windows 或mmap(2) 映射的文件。