可以看到我们的输入变成了如下汇编指令:
我们可以选择Options->General,把Number of opcode bytes (non-graph)的值调大。
会发现每条汇编指令都对应着长短不一的一串16进制数。
对汇编有一定了解的读者应该知道,这些16进制数串叫做opcode。opcode是由最多6个域组成的,和汇编指令存在对应关系的机器码。或者说可以认为汇编指令是opcode的“别名”。易于人类阅读的汇编语言指令,如xor ecx, ecx等,实际上就是被汇编器根据opcode与汇编指令的替换规则替换成16进制数串,再与其他数据经过组合处理,最后变成01字符串被CPU识别并执行的。
当然,IDA之类的反汇编器也是使用替换规则将16进制串处理成汇编代码的。所以我们可以直接构造合法的16进制串组成的opcode串,即ShellCode,使系统得以识别并执行,完成我们想要的功能。关于opcode六个域的组成及其他深入知识此处不再赘述,感兴趣的读者可以在Intel官网获取开发者手册或其他地方查阅资料进行了解并尝试查表阅读机器码或者手写ShellCode。
系统调用
我们继续执行这段代码,可以发现EAX, EBX, ECX, EDX四个寄存器被先后清零,EAX被赋值为0Xb,ECX入栈,“/bin//sh”字符串入栈,并将其首地址赋给了EBX,最后执行完int 80h,IDA弹出了一个warning窗口显示got SIGTRAP signal。