我想弄清楚一些CIL代码.但似乎这两个陈述做同样的事情(根据我读过的所有内容).
ldc.i4 33
和
ldc.i4.33
两者都应该"将int32加载到值为33的堆栈上".
它是否正确?为什么?我原以为这ldc.i4.33将"从局部变量索引33加载一个整数到堆栈".
我在哪里错了?
在我为特定于 x86 arch 的 Linux 编写一个小型反汇编程序的过程中,我遇到了一个小问题。这是关于强制前缀和重复前缀的。查看英特尔文档 [1],据说重复前缀是0xf2或0xf3,强制前缀是0x66、0xf2或0xf3。
有两条指令具有以下基本操作码:
crc32 -- f2 0f 38 f0 (这里,0xf2是强制前缀)
movbe -- 0f 38 f0
因此,只要计数器寄存器非零就必须重复的“movbe”指令的操作码应该是:
代表 movbe == f2 0f 38 f0
当我开始反汇编一条指令时,如果我看到字节0xf2,我如何知道它是crc32指令的强制前缀,而不是movbe指令的重复前缀,反之亦然?我应该将操作码模式“f2 0f 38 f0”与哪条指令相匹配?
我缺少什么?
[1] http://www.intel.com/design/intarch/manuals/243191.HTM
感谢和问候,
Hrishikesh Murali
我有32位操作码:FF 35 0E 20 40 00.有人知道一个好的OpCode表给出了答案吗?(我知道我可以使用反汇编程序,但我想知道,如何使用操作码表来确定它).我找到了这个网页,但有7个不同的解决方案FF.我没有得到它.
我想做汇编编译器。为此,我应该研究汇编操作码,所以我在网上找到了这个。当我测试用 NASM 编译一些代码时,如下所示:
add eax, eax
Run Code Online (Sandbox Code Playgroud)
它以二进制输出:
6601C0
其中 ADD 操作码是 00, 01, 02, 03, 04, 05。哪个操作码是正确的?我可以使用所有这些,还是应该使用 01(基于使用 NASM 编译的二进制文件)。
我正在编写自己的汇编程序并尝试对 ADC 指令进行编码,我对立即值有疑问,尤其是在将 8 位值添加到 AX 寄存器时。
添加 16 位值时:adc ax, 0xff33被编码为15 33 ff正确的。但是如果adc ax, 0x33被编码为会重要15 33 00吗?
Nasm 将83 d0 33其编码为显然是正确的,但我的方法也正确吗?
目前在我看来,我们拥有像“Push”这样的指令的唯一原因是用一条指令替换多个 MOV 和算术指令。
有没有更原始的指令不能完成的“PUSH”?
“PUSH”只是一个编译成多个机器代码指令的助记符吗?
使用 Turbo Assembler 和 Turbo Debugger 稍微玩了一下,我对操作码感到惊讶。更准确地说,我有一些组装好的二进制文件,Turbo Debugger 在其中反汇编了这个词
29 C3
Run Code Online (Sandbox Code Playgroud)
正确地sub bx, ax. 但是,Turbo Assembler 将完全相同的指令组装sub bx, ax到以下单词中
2B D8
Run Code Online (Sandbox Code Playgroud)
对此感到困惑,我发现这个参考文献指出从寄存器中减去寄存器可能确实以29和开头2B。是否真的可以用不同的操作码来表达完全相同的指令?如果是这样,那是为什么?是因为历史原因和兼容性吗?参考说明了操作码的不同操作数类型,它们只是sub bx, ax. 这是为了以后通过自修改代码或类似方式修补不同操作数的能力吗?此外,Turbo Assembler 是否有语法结构来选择一个操作码而不是另一个?
注意:我知道条件跳转类似je并且jz具有相同的操作码,因为它们具有相同的标志相关行为,并且不同的助记符用于反映同一操作的不同语义,但前者让我感到困惑。
我正在尝试编写一个带有.class文件的程序,并收集.class文件的所有方法以及每个方法的内容.这是我的代码
public class ClassReaderTest1 {
public static void main(String[] args) throws Exception{
InputStream in = new FileInputStream("*.class");
ClassReader reader = new ClassReader(in);
ClassNode classNode = new ClassNode();
reader.accept(classNode,0);
@SuppressWarnings("unchecked")
final List<MethodNode> methods = classNode.methods;
for(MethodNode m: methods){
InsnList inList = m.instructions;
System.out.println(m.name);
for(int i = 0; i< inList.size(); i++){
System.out.println(" " + Integer.toHexString(inList.get(i).getOpcode()));
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的输出
init>
ffffffff
ffffffff
19
b7
b1
ffffffff
main
ffffffff
ffffffff
b2
12
b6
ffffffff
ffffffff
3
36
ffffffff
ffffffff
b1
ffffffff
Run Code Online (Sandbox Code Playgroud)
最终我不想打印这些值,我只是希望能够在我的程序中引用它们(我正在尝试检查我是否得到了正确的值).我按预期得到方法,但方法的内容对我没有意义.我认为这些不是操作码; …
如何知道MIPS指令的操作码是Register,Imidiate还是Jump?鉴于本书中的这个表,但有没有办法定义操作码的格式?

我需要为一个漏洞利用演示制作一个跳转操作码.
我需要在跳转指令后跳转到大约200个字节.这太过分了jmp short.
如果我使用常规跳转生成操作码,jmp $200我会得到:
e9 fb 01 00 00
Run Code Online (Sandbox Code Playgroud)
这里的问题是操作码包含00,当将字符串传递给程序时,它被解释为字符串的结尾(因此我不能将完整的shellcode传递给它).
我认为我的方法被搞砸了,但后来我检查了手册,在第二行显然有一个"近似跳跃"需要2个字节(还有另一个需要4个字节,我上面显示的那个).这两个跳转都以相同的字节开头e9.
我如何通过e9 fb 01只接受两个字节参数的近跳转?如何阻止操作系统查找后的四个字节e9,即:e9 fb 01 90 90?