有很多很棒的资源学习汇编语言,但它们似乎都没有详细介绍如何将汇编助记符转换为原始二进制指令。
#1 楼
如果您想详细了解指令编码,则需要学习英特尔®64和IA-32架构软件开发人员手册第2卷(指令集参考,A-Z)。请注意,英特尔IA-32和AMD64是非常复杂的指令集,并且要挂钩一个并非专门设计为通过注入跳转来挂钩的功能,您将遇到许多不同的指令。不能保证该功能甚至设置了堆栈框架。有一些库可以为您进行反汇编和挂钩,例如Microsoft Research的Detours。
评论
谢谢!那似乎正是我要的东西。 Detours几乎与我所做的相同,但我出于教育目的重新发明了轮子。
–亨利·海基宁(Henry Heikkinen)
2013年3月19日23:47
小心一点,Detours EULA并不是人们所说的自由主义者。我知道到处都有它被引用,但是它附带的许可证使它在很多方面都失去了资格。
– 0xC0000022L♦
13年4月1日在1:36
#2 楼
您可以使用反汇编程序从二进制操作码转换为汇编代码。例如,ndisam
命令可以执行此操作。如果您具有以下二进制操作码(十六进制视图)的文件):
31C0FFC0C3
用
ndisasm
拆开它时,您将得到以下输出:00000000 31C0 xor ax,ax
00000002 FFC0 inc ax
00000004 C3 ret
第一列是文件偏移量,第二列是二进制操作码,最后一行是汇编代码。
然后您可以获取第二列并获取其字符串长度并除以2并且您将具有以字节为单位的指令长度。
评论
尽管这解释了如何在命令行上手动进行操作,但我认为对于在运行时挂接任意代码的实用程序库,这不是一种合适的方法。如果ndisasm可作为库使用,则可能可以使用,但是您应该将其添加到答案中。
– Jix
13年3月19日在20:02
基本上,我已经使用了udis86和opdis库。两者都工作得很好,并且(iirc)将每个指令的长度公开为struct成员,而不必解析asm输出。
– Sean B.
2013年3月19日在20:17
@SeanB。快速浏览udis86,我可以看到它已经移至github。
–提洛
13年3月19日在20:22
#3 楼
很多人都提到了英特尔手册,这是非常宝贵的参考,但内容很多。我建议您查看此OSDev Wiki页面,以了解如何在更简单的级别上对指令进行编码。对于所有实际的指令长度查找问题,我建议您使用反汇编程序。
函数挂钩是一个有趣的挑战。这个MSDN博客很好地解释了一些困难。根据要求,可能更可取的是使用操作系统的调试功能将其附加到进程,“破坏”函数的功能,并在单独的进程中实现挂钩。
评论
看起来很棒。谢谢!
–亨利·海基宁(Henry Heikkinen)
13年3月20日在12:22
#4 楼
这篇CodeProject文章是x86指令格式的高级概述(带图表!)。阅读此书后,更详细的参考将更有意义。由于多年向后兼容的发展,x86指令格式非常复杂,具有各种可选的前缀和与指令相关的字段,所以计算指令长度有点棘手。如果您想要强大的功能,建议您改用现有软件,而不要自己动手开发。但是理解这些概念当然会很有帮助。
#5 楼
指令解码的基本原理可以在软件开发人员的处理器手册中找到。汇编程序作者需要知道这一点,因此这里的信息才是。对于Intel来说,这是在第2A卷的开头(我想我走了,因为他们将所有手册都塞进了PDF中)。有一个大表,用于定义如何对前缀进行编码,对操作码进行编码以及对操作数进行编码。这不是最简单的阅读,但是在那里...评论
嗯,那是什么时候?甚至就在几周前,它们都被很好地分成了单独的PDF文件...
– 0xC0000022L♦
13年4月1日在1:35
#6 楼
IA-32英特尔®架构软件开发人员手册第1卷。 2令人发指的荣耀。#7 楼
您可以使用顶点库来分解说明您要查找的地址的指令。它可以为您确定指令的长度(以字节为单位),然后可以在代码中使用它。http://www.capstone-engine.org/
评论
除了您可以使用反汇编程序为您完成这项工作外,我看不到它与逆向工程有何关系。此博客条目应与运行时的挂钩函数有些相关:blogs.msdn.com/b/oldnewthing/archive/2011/09/21/10214405.aspx
不幸的是,根据我的经验,答案是“以一种非常恐怖和任意的方式”。祝你好运:)
到目前为止,我最喜欢的教程是:c-jump.com/CIS77/CPU/x86/lecture.html并没有涵盖所有内容,但是是一个不错的开始。