这个问题是该问题的后续问题。
要设置此问题的上下文,请考虑无空编程。这是一种将指令序列(shellcode)伪装成字符串的技术。在C编程语言中,字节0标志着字符串的结束,因此指令序列必须设计为不包含任何此类字节,否则它将被滥用的字符串操作函数截断。
IA32 和 x86-64 指令集,其可变长度指令没有特定的对齐方式,允许任务 B 的指令在执行任务 A 的现有指令流内的偏移处进行解码。该技术已在个人计算的早期(20 世纪 80 年代)为了节省空间。
从第一条指令内的偏移量开始在代码中嵌入代码的技术是否已被用作欺骗防病毒检测的一种方法?它有名字吗?如果有用并且已经使用过,有什么例子吗?如果攻击者一开始就编写代码,那么任务 A 以一种表面上无害的方式不执行任何操作就足够了,这可能会留下足够的余地来执行任务 B 想要执行的任何操作。
我想做汇编编译器。为此,我应该研究汇编操作码,所以我在网上找到了这个。当我测试用 NASM 编译一些代码时,如下所示:
add eax, eax
Run Code Online (Sandbox Code Playgroud)
它以二进制输出:
6601C0
其中 ADD 操作码是 00, 01, 02, 03, 04, 05。哪个操作码是正确的?我可以使用所有这些,还是应该使用 01(基于使用 NASM 编译的二进制文件)。
我熟悉 r/m8、r/m16、imm16 等,但如何编码 m16:16、m16:32 和 m16:64?这些在 JMP 和 CALL 指令中......
m16:16 是地址位置吗?或者它就像一个直接地址?任何帮助将不胜感激!
我很好奇如果我把db 0x41这个.text部分放在它通常所属的地方,而不是放在.data它通常所属的地方,会发生什么。它会出现段错误,但到底为什么呢?
下面的代码是在 Mint 19.1 中使用 和 进行编译、链接和执行nasm的ld。
无段错误:
global _start
section .data
db 0x41
section .text
_start:
mov rax, 60 ; Exit(0) syscall
xor rdi, rdi
syscall
Run Code Online (Sandbox Code Playgroud)
段错误:
global _start
section .text
_start:
db 0x41
mov rax, 60 ; Exit(0) syscall
xor rdi, rdi
syscall
Run Code Online (Sandbox Code Playgroud)
我使用以下命令来组装、链接和运行它:
global _start
section .data
db 0x41
section .text
_start:
mov rax, 60 ; Exit(0) syscall
xor rdi, rdi
syscall
Run Code Online (Sandbox Code Playgroud) 我正在编写自己的汇编程序并尝试对 ADC 指令进行编码,我对立即值有疑问,尤其是在将 8 位值添加到 AX 寄存器时。
添加 16 位值时:adc ax, 0xff33被编码为15 33 ff正确的。但是如果adc ax, 0x33被编码为会重要15 33 00吗?
Nasm 将83 d0 33其编码为显然是正确的,但我的方法也正确吗?
我知道 8086 有一个 BIU 和一个 EU,这有助于处理器的流水线化。BIU 有一个 6 字节预取队列,用于提取指令指针指向的地址后面的字节。现在,当要执行的指令是跳转到另一个位置的指令时,预取的所有 6 个字节会发生什么情况?它们会被冲掉然后重新加载吗?(这会破坏处理器的流水线效率,不是吗?)
小工具:
pushad
ret
Run Code Online (Sandbox Code Playgroud)
在合法程序中,来自某个 DLL 对我来说毫无意义。
假设 DLL 是合法的,如何通过自动搜索找到小工具?使用函数的示例可能会有所帮助。
当我实现一个程序时,我发现我的程序在 g++ 或 clang++ 中从 切换-g到时表现不同-O2。
简化的代码是:
#include <cstdint>
#include <iostream>
class A {
public:
explicit A(const int64_t &zero_);
const int64_t& zero;
};
A::A(const int64_t &zero_):
zero(zero_) {
std::cout << "zero=" << zero << std::endl;
}
int main() {
A st(0);
size_t p;
std::cin >> p;
std::cout << "zero=" << st.zero << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
假设标准输入为 1,并且异常输出(在最后一行中)为零 = 0,因为该变量zero是一个常量引用。
使用 编译时g++ -g -o b.o b.cc,程序运行正常。
但是,当用 编译时g++ -O2 -o b.o b.cc,输出是 …
我正在使用网站learncpp.com学习 C++ 。第 0.5 章指出编译器的目的是将人类可读的源代码转换为机器可读的机器代码,由 1 和 0 组成。
\n我编写了一个简短的 hello-world 程序并用于g++ hello-world.cpp编译它(我使用的是 macOS)。结果是a.out。它确实打印“Hello World”很好,但是,当我尝试在 vim/less/Atom/... 中查看时a.out,我没有看到 1 和 0',而是看到很多这样的内容:
H\xef\xbf\xbdE\xef\xbf\xbdH\xef\xbf\xbd\xef\xbf\xbdX\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbdH\xef\xbf\xbdE\xef\xbf\xbdH\xef\xbf\xbd}\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbdH\xef\xbf\xbd\xef\xbf\xbdX\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbdH9\xef\xbf\xbd\xef\xbf\xbd\nRun Code Online (Sandbox Code Playgroud)\n为什么内容a.out不只是机器代码所期望的 1 和 0?
我已经编码了 5 年多了,现在想远离 IDE,尝试一个没有 IDE 的项目。我有开始所需的东西(我认为),一个 HelloWorld.cpp 文件,打开的 Windows 命令提示符并安装了 Clang。
现在我有了这些东西,我的问题是 - 我需要在命令提示符中输入什么才能使 Clang 获取 HelloWorld.cpp 文件中的 C++ 代码并将其编译成包含 的单独文件assembly code,然后使 Clang 获取我的汇编代码并将其汇编成一个包含 的单独文件object code,然后最后让 Clang 获取我的目标代码并将其链接machine code到一个包含?的单独文件中。
最终意味着最后我将有 4 个文件,一个包含 C++ 代码,一个包含汇编代码,一个包含目标代码,最后一个包含机器代码。所有这一切的要点是能够在运行包含机器代码的文件之前读取和理解流程的每个阶段。
作为第一次离开 IDE 世界的人,我发现 Clang 官方文档非常混乱,无法找到我的问题的直接答案。
machine-code ×10
assembly ×7
x86 ×5
c++ ×3
opcode ×2
x86-64 ×2
antivirus ×1
clang ×1
compilation ×1
dll ×1
memory-leaks ×1
nasm ×1
obfuscation ×1
object-code ×1
optimization ×1
x86-16 ×1