ChatGPT解决这个技术问题 Extra ChatGPT

学习大会[关闭]

关闭。这个问题是基于意见的。它目前不接受答案。想改进这个问题?更新问题,以便可以通过编辑这篇文章用事实和引用来回答它。 5年前关闭。改进这个问题

我决定学习汇编语言。这样做的主要原因是能够理解反汇编代码,也许能够编写更有效的代码部分(例如,通过 c++),做一些类似代码洞穴的事情,等等。我看到有无数不同风格的汇编,那么,就我提到的目的而言,我应该如何开始呢?我应该学习什么样的组装?我想通过先做一些简单的程序(例如计算器)来学习,但目标本身就是要适应它,这样我才能理解显示的代码,例如,IDA Pro 显示的代码。

我正在使用 Windows(如果这有什么不同的话)。

编辑:所以,似乎每个人都指向 MASM。虽然我明白它具有高级功能,对汇编代码程序员来说都很好,但这不是我想要的。它似乎具有流行的反汇编程序(如 IDA)中未显示的 if、invoke 等指令。因此,如果可能的话,我想听听任何将 ASM 用于我所要求的目的(在 IDA 中阅读反汇编的 exe 代码)的人的意见,而不仅仅是“通用”汇编程序员。

编辑:好的。我已经在学习组装了。我正在学习 MASM,而不是使用对我来说无关紧要的高级东西。我现在正在做的是在 c++ 中尝试我在 __asm 指令上的代码,所以我可以比我必须使用 MASM 从头开始做所有事情更快地尝试一些事情。

是的,我也在读那个。但我会说,我的问题更“集中”。
如果您在 Windows 上,则目标(即处理器,以及指令集)是 x86 或 x86-64。除非您获得另一台机器或 MCU 板或使用仿真器。那么,我应该使用哪个汇编程序?或者你真的在问要定位什么架构?我个人喜欢 m68k 系列芯片上漂亮的正交指令集,唉,唉。
“它似乎有 if、invoke 等指令”——这些是宏(“MASM”中的“M”),即使汇编程序支持它们,您也不必使用它们。
给这个问题第 65 次投赞成票是一个艰难的决定,64 真是一个美丽的数字。 . .

O
Oded

我已经这样做了很多次,并继续这样做。在这种情况下,您的主要目标是阅读而不是编写汇编程序,我觉得这适用。

编写自己的反汇编程序。不是为了制造下一个最伟大的反汇编程序,这个完全是为你准备的。目标是学习指令集。无论我是在一个新平台上学习汇编程序,还是在我曾经知道的平台上记住汇编程序。从几行代码开始,例如添加寄存器,然后在反汇编二进制输出和在输入端添加越来越复杂的指令之间进行乒乓操作:

1)学习特定处理器的指令集

2)了解如何为所述处理器编写汇编代码的细微差别,以便您可以摆动每条指令中的每个操作码位

3)你比大多数使用该指令集谋生的工程师更好地学习指令集

在您的情况下,有几个问题,我通常建议从 ARM 指令集开始,今天出货的基于 ARM 的产品比任何其他产品都多(包括 x86 计算机)。但是您现在正在使用 ARM 并且不知道足够的汇编程序来编写启动代码或其他知道 ARM 的例程的可能性可能会或可能不会帮助您尝试做的事情。 ARM 优先的第二个也是更重要的原因是因为指令长度是固定大小且对齐的。作为你的第一个项目,反汇编像 x86 这样的可变长度指令可能是一场噩梦,这里的目标是学习指令集而不是创建一个研究项目。第三个 ARM 是一个做得很好的指令集,寄存器是平等的,没有个别的特殊细微差别。

所以你必须弄清楚你想从什么处理器开始。我建议先msp430或ARM,然后是ARM,然后是x86的混乱。无论是什么平台,任何值得使用的平台都有供应商免费提供的数据表或程序员参考手册,其中包括指令集以及操作码的编码(机器语言的位和字节)。为了了解编译器的功能以及如何编写编译器不必费力的代码,了解一些指令集并了解每个编译器在每次优化时如何在每个指令集上实现相同的高级代码是很好的环境。您不希望优化您的代码只是为了发现您已经使一个编译器/平台变得更好,但对于其他每个编译器/平台都变得更糟。

哦,用于反汇编可变长度指令集,而不是像使用 ARM 那样简单地从头开始并通过内存线性反汇编每四个字节字,或者像 msp430 那样每两个字节(msp430 具有可变长度指令,但您仍然可以通过如果您从中断向量表的入口点开始,则线性地通过内存)。对于可变长度,您希望根据向量表或有关处理器如何启动的知识找到一个入口点,并按照执行顺序跟踪代码。您必须完全解码每条指令才能知道使用了多少字节,然后如果该指令不是无条件分支,则假定该指令之后的下一个字节是另一条指令。您还必须存储所有可能的分支地址,并假设这些是更多指令的起始字节地址。有一次我成功了,我多次通过二进制文件。从入口点开始,我将该字节标记为指令的开始,然后通过内存线性解码,直到到达无条件分支。所有分支目标都被标记为指令的起始地址。我多次通过二进制文件,直到没有找到新的分支目标。如果在任何时候你发现一条 3 字节的指令,但由于某种原因你将第二个字节标记为指令的开头,你就有问题了。如果代码是由高级编译器生成的,除非编译器做坏事,否则这不应该发生,如果代码有手写的汇编程序(比如一个旧的街机游戏),很可能会有永远不会发生的条件分支比如 r0=0 如果不为零则跳转。您可能需要手动编辑这些二进制文件才能继续。对于我认为将在 x86 上的近期目标,我认为您不会有问题。

我推荐 gcc 工具,如果 x86 是您的目标,mingw32 是在 Windows 上使用 gcc 工具的简单方法。如果不是,mingw32 plus msys 是一个很好的平台,可以从 binutils 和 gcc 源代码生成交叉编译器(通常很容易)。 mingw32 与 cygwin 相比有一些优势,比如明显更快的程序,并且您避免了 cygwin dll 地狱。 gcc 和 binutils 将允许您用 C 或汇编程序编写并反汇编您的代码,并且有比您阅读的更多的网页向您展示如何执行这三个中的任何一个或全部。如果您要使用可变长度指令集执行此操作,我强烈建议您使用包含反汇编程序的工具集。例如,用于 x86 的第三方反汇编程序将是一个使用挑战,因为您永远不知道它是否已正确反汇编。其中一些也取决于操作系统,目标是将模块编译为二进制格式,其中包含来自数据的信息标记指令,以便反汇编程序可以完成更准确的工作。对于这个主要目标,您的另一个选择是拥有一个可以直接编译为汇编器以供您检查的工具,然后希望当它编译为二进制格式时,它会创建相同的指令。

对您的问题的简短(好吧,稍微短一点)的回答。编写反汇编程序来学习指令集。我会从 RISCy 和易于学习的东西开始,比如 ARM。一旦您知道了一个指令集,其他指令集就会变得更容易掌握,通常在几个小时内,通过第三个指令集,您几乎可以立即使用数据表/参考手册的语法开始编写代码。所有值得使用的处理器都有一个数据表或参考手册,其中描述了操作码的位和字节的指令。学习 ARM 之类的 RISC 处理器和 x86 之类的 CISC 足以感受其中的差异,例如必须通过寄存器来处理所有事情,或者能够在更少或没有寄存器的情况下直接在内存上执行操作。三个操作数指令与两个等。当您调整高级代码时,为多个处理器编译并比较输出。您将学到的最重要的事情是,无论编写的高级代码多么好,编译器的质量和所做的优化选择都会对实际指令产生巨大影响。我推荐 llvm 和 gcc(使用 binutils),它们都不会产生出色的代码,但它们是多平台和多目标的,并且都有优化器。两者都是免费的,您可以轻松地从各种目标处理器的源代码构建交叉编译器。


谢谢回复。但我什至不知道如何编写反汇编程序。
“编写你自己的反汇编程序” - 我同意,这是我学得最好的方式。 (“但我什至不知道如何编写反汇编程序”是怎么回事?)大声笑。
我跟你一起去!刚买了一个 MSP430 和一本关于它的书...... :)
我有一些 msp430 示例 github.com/dwelch67 以及一些用于试验的指令集模拟器,包括学习 asm 等。
我真的,真的很喜欢这个主意。
d
dey.shin

MASM32 开始,然后查看 FASM。但是你会玩 MASM 的。


我从 MASM 那里听说过。如果我没记错的话,它有很多“高级”功能,当我查看反汇编代码时我看不到这些功能。如果有意义的话,我想编写与大多数反汇编程序输出代码完全相同的东西。
这基本上就像编写操作码一样,这实际上没有任何意义。学习 MASM32 将帮助您了解代码在调试器中的外观。您可能还想查看 OllyDbg:ollydbg.de
你不懂组装。你需要理解它。操作码是一个数字。调试器将尝试根据指令解析操作码(有时很难)。您需要了解基本说明。学习 MASM 将帮助您做到这一点。无需多说。
您不必使用所有 MASM 功能,因为它们就在那里;如果你认为这样你会学到更多,你可以让事情变得像你想要的那样难以阅读。
MASM 的怪癖、错误和所谓的高级功能使汇编程序员(无论是初学者还是专家)都比我能想到的任何东西都更困惑。
k
kquinn

从高层次来看,您手动编写的程序集和编译器生成的程序集通常非常不同。当然,程序的内部结构会非常相似(毕竟编码 a = b + c 的方法只有这么多),但是当您尝试对某些东西进行逆向工程时,它们并不是问题。即使是简单的可执行文件,编译器也会添加 ton 的样板代码:上次我比较时,由 GCC 编译的“Hello World”大约是 4kB,而如果用手工编写的汇编大约是 100 字节。在 Windows 上情况更糟:上次我比较(诚然,这是上个世纪)我可以让我的 Windows 编译器生成的最小“Hello World”是 52kB!通常这个样板只执行一次,如果有的话,所以它不会对程序速度产生太大影响——就像我上面所说的,程序的核心,即花费大部分执行时间的部分,无论是编译还是手写。

归根结底,这意味着专家汇编程序员和专家反汇编程序是两个不同的专业。通常它们出现在同一个人身上,但它们确实是分开的,学习如何成为一名出色的汇编编码人员对学习逆向工程没有太大帮助。

您要做的是从 IntelAMD 中获取 IA-32 和 AMD64(两者一起介绍)架构手册,并查看有关指令和操作码的早期部分。也许阅读一两个关于汇编语言的教程,只是为了了解汇编语言的基础知识。然后获取一个您感兴趣的示例程序并对其进行反汇编:逐步检查其控制流并尝试了解它在做什么。看看你是否可以修补它来做其他事情。然后用另一个程序再试一次,并重复,直到你足够舒服,可以尝试实现更有用的目标。您可能对逆向工程社区制作的“crackmes”之类的东西感兴趣,这对于对逆向工程感兴趣的人来说是一个挑战,可以尝试并希望在此过程中学到一些东西。它们的难度范围从基本(从这里开始!)到不可能。

最重要的是,你只需要练习。与许多其他学科一样,通过逆向工程,熟能生巧……或者至少更好。


我知道当你用高级语言编译任何东西时,你会得到很多不需要的“垃圾”代码,它是直接在汇编中编码的。我也明白专家汇编程序员和专家反汇编程序之间存在差异。但几乎所有其他事情都可以这样说。
我担心的是,虽然理论上我可以阅读论文并理解它们的含义,但在我开始自己写东西之前,我不相信我会真正理解它。你说我可以从更改一小部分代码开始,但要做到这一点,我首先必须知道 IDA pro 使用什么样的汇编“风味”。
另外,MSVC++ 对内联汇编代码有什么用?马斯姆?
A
Alex Martelli

我将反对大多数答案,并推荐 Knuth 的 MIPS RISC 架构的 MMIX 变体。它不会像 x86 或 ARM 汇编语言那样实际有用(并不是说它们在当今大多数现实生活中的工作中都非常重要......;-),但它会为你解锁 Knuth 最新的魔力有史以来最伟大的关于对算法和数据结构的深入理解的杰作的版本——TAOCP,“计算机编程的艺术”。我引用的两个 URL 的链接是开始探索这种可能性的好方法!


C
Community

(我不了解你,但我对组装很兴奋)

您的电脑中已经安装了一个简单的组装试验工具。

转到“开始”菜单->“运行”,然后键入 debug

debug (command)

debug 是 DOS、MS-DOS、OS/2 和 Microsoft Windows(仅限 x86 版本,不是 x64)中的命令,它运行程序 debug.exe(或旧版本 DOS 中的 DEBUG.COM)。 Debug 可以充当汇编程序、反汇编程序或十六进制转储程序,允许用户交互式地检查内存内容(汇编语言、十六进制或 ASCII)、进行更改并有选择地执行 COM、EXE 和其他文件类型。它还有几个用于访问特定磁盘扇区、I/O 端口和内存地址的子命令。 MS-DOS 调试运行在 16 位进程级别,因此它仅限于 16 位计算机程序。 FreeDOS Debug 也有一个支持 32 位 DPMI 程序的“DEBUGX”版本。

教程:

调试指南

PC 程序如何工作:理解 x86 (Intel) 机器码

调试教程


如果您想了解在 IDA Pro(或 OllyDbg)中看到的代码,您需要了解编译后代码的结构。我推荐这本书Reversing: Secrets of Reverse Engineering

当我开始学习汇编时(15 年前),我用 debug 试验了几周。
请注意,debug 在基本机器级别上工作,没有高级汇编命令。

现在举一个简单的例子:

a 开始编写汇编代码 - 输入下面的程序 - 最后给 g 来运行它.

https://4.bp.blogspot.com/_6YQvmEwxFsw/SqORbWDROPI/AAAAAAAAAFg/nVj9cVQkL9o/s400/SOdebug.jpg


(如果 AH 寄存器设置为 2,则 INT 21 在屏幕上显示存储在 DL 寄存器中的 ASCII 字符 -- INT 20 终止程序)


我必须先按 ctrl-c,然后才能输入“g”。
@ericp,您不必按 ctrl-c。例如,您键入 a & [enter] 开始编写汇编代码。如果您按 [enter] 两次,您将退出汇编模式。 g & [enter] 运行它(默认偏移 100)。
它实际上会导致堆栈溢出还是只是将其写入屏幕?
@user,它只是写了这个网站的名字:-)
@JanusTroelsen 这些数字(53、74、61 等)是 'S' 't' 'a' 的 ASCII 代码......每个 Int21 调用一次打印一个字符!这就是为什么组装速度不快的原因:)
m
mblackwell8

我发现 Hacking: The Art of Exploitation 是进入这个主题的一种有趣且有用的方式......不能说我曾经直接使用过这些知识,但这真的不是我阅读它的原因。它让您对代码编译成的指令有更丰富的了解,这有时有助于理解更细微的错误。

不要被标题吓到。本书第一部分的大部分内容是埃里克·雷蒙德(Eric Raymond)所说的“黑客”:创造性的、令人惊讶的、几乎是偷偷摸摸地解决棘手问题的方法。我(也许你)对安全方面不太感兴趣。


J
Josh Haberman

我不会专注于尝试用汇编语言编写程序,至少一开始不会。如果您使用的是 x86(我假设您是,因为您使用的是 Windows),那么有很多奇怪的特殊情况,学习它是毫无意义的。例如,许多指令假定您正在对未明确命名的寄存器进行操作,而其他指令对某些寄存器起作用,但对其他寄存器不起作用。

我会充分了解您的预期架构,以便您了解基础知识,然后直接进入并尝试了解编译器的输出。用 the Intel manuals 武装自己,然后直接进入编译器的输出。将感兴趣的代码隔离成一个小函数,这样您就可以确保了解整个事情。

我认为基础是:

寄存器:有多少个,它们的名称是什么,它们的大小是多少?

操作数顺序:add eax,ebx 表示“将 ebx 添加到 eax 并将结果存储在 eax 中”。

FPU:学习浮点堆栈的基础知识以及如何与 fp 进行转换。

寻址模式:[base + offset * multiplier],但 multiplier 只能是 1、2 或 4(或者可能是 8?)

调用约定:如何将参数传递给函数?

很多时候编译器发出的结果会令人惊讶。弄清楚为什么编译器认为这是一个好主意是一个难题。它会教给你很多东西。

它也可能有助于用 Agner Fog's manuals 武装自己,尤其是清单一的说明。它会大致告诉您每条指令的成本是多少,尽管这在现代处理器上更难直接量化。但这将有助于解释为什么,例如,编译器会竭尽全力避免发出 idiv 指令。

我唯一的另一条建议是,当您有选择时,始终使用 Intel 语法而不是 AT&T。在这一点上,我曾经相当中立,直到有一天我意识到两者之间的某些指令完全不同(例如,AT&T 语法中的 movslq 是 Intel 语法中的 movsxd)。由于这些手册都是使用 Intel 语法编写的,所以请坚持下去。

祝你好运!


佚名

我开始学习 MIPS,它是一种非常紧凑的 32 位架构。这是一个精简的指令集,但这对于初学者来说很容易掌握。您仍然能够理解装配的工作原理,而不会被复杂性所淹没。您甚至可以下载一个不错的小 IDE,它可以让您编译 MIPS 代码:clicky 一旦掌握了它,我认为转向更复杂的架构会容易得多。至少我是这么想的:)此时你将掌握内存分配和管理、逻辑流程、调试、测试等方面的基本知识。


J
Jordan

使用调试的建议很有趣,可以用它来完成许多巧妙的技巧。但是,对于现代操作系统来说,学习 16 位汇编可能没那么有用。请考虑使用 ntsd.exe。它内置于 Windows XP 中(不幸的是,它在 Server 2003 及更高版本中被取消了),这使得它成为一个方便的学习工具,因为它是如此广泛可用。

也就是说,XP 中的原始版本存在许多错误。如果您真的想使用它(或 cdb 或 windbg,它们是具有相同命令语法和调试后端的本质不同的接口),您应该安装免费的 windows debugging tools 包。

该软件包中包含的 debugger.chm 文件在尝试找出异常语法时特别有用。

ntsd 的伟大之处在于您可以在附近的任何 XP 机器上弹出它并使用它来组装或拆卸。它是一个 /great/ X86 汇编学习工具。例如(使用 cdb,因为它在 dos 提示符中是内联的,其他方面是相同的):

(跳过符号错误,因为它们无关紧要——另外,我希望这种格式有效,这是我的第一篇文章)

C:\Documents and Settings\User>cdb calc

Microsoft (R) Windows Debugger Version 6.10.0003.233 X86
Copyright (c) Microsoft Corporation. All rights reserved.

CommandLine: calc
Symbol search path is: *** Invalid ***
Executable search path is:
ModLoad: 01000000 0101f000   calc.exe
ModLoad: 7c900000 7c9b2000   ntdll.dll
ModLoad: 7c800000 7c8f6000   C:\WINDOWS\system32\kernel32.dll
ModLoad: 7c9c0000 7d1d7000   C:\WINDOWS\system32\SHELL32.dll
ModLoad: 77dd0000 77e6b000   C:\WINDOWS\system32\ADVAPI32.dll
ModLoad: 77e70000 77f02000   C:\WINDOWS\system32\RPCRT4.dll
ModLoad: 77fe0000 77ff1000   C:\WINDOWS\system32\Secur32.dll
ModLoad: 77f10000 77f59000   C:\WINDOWS\system32\GDI32.dll
ModLoad: 7e410000 7e4a1000   C:\WINDOWS\system32\USER32.dll
ModLoad: 77c10000 77c68000   C:\WINDOWS\system32\msvcrt.dll
ModLoad: 77f60000 77fd6000   C:\WINDOWS\system32\SHLWAPI.dll
(f2c.208): Break instruction exception - code 80000003 (first chance)
eax=001a1eb4 ebx=7ffd6000 ecx=00000007 edx=00000080 esi=001a1f48 edi=001a1eb4
eip=7c90120e esp=0007fb20 ebp=0007fc94 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
ntdll!DbgBreakPoint:
7c90120e cc              int     3
0:000> r eax
eax=001a1eb4
0:000> r eax=0
0:000> a eip
7c90120e add eax,0x100
7c901213
0:000> u eip
ntdll!DbgBreakPoint:
7c90120e 0500010000      add     eax,100h
7c901213 c3              ret
7c901214 8bff            mov     edi,edi
7c901216 8b442404        mov     eax,dword ptr [esp+4]
7c90121a cc              int     3
7c90121b c20400          ret     4
ntdll!NtCurrentTeb:
7c90121e 64a118000000    mov     eax,dword ptr fs:[00000018h]
7c901224 c3              ret
0:000> t
eax=00000100 ebx=7ffd6000 ecx=00000007 edx=00000080 esi=001a1f48 edi=001a1eb4
eip=7c901213 esp=0007fb20 ebp=0007fc94 iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
ntdll!DbgUserBreakPoint+0x1:
7c901213 c3              ret
0:000>`

另外——当你在玩 IDA 时,一定要查看 Chris Eagle 的 IDA Pro Book(取消链接,因为 StackOverflow 不想让我在第一篇文章中发布两个以上的链接)。这是最好的参考。


为克里斯·伊格尔的书 +1。必须对 r00t 的 Sk3wl 投入一些爱;)
G
Glorfindel

我最近上了一门计算机系统课。其中一个主题是将装配作为与硬件进行通信的工具。

对我来说,如果不了解计算机系统如何工作的细节,组装知识就不会完整。理解这一点,就会对为什么在一个处理器架构上的汇编指令很好,但在另一种架构上却很糟糕的原因有了新的理解。

鉴于此,我倾向于推荐我的课本:

Computer Systems:A programmer's perspective

https://i.stack.imgur.com/rmS0W.jpg

它确实涵盖了 x86 汇编,但本书的范围远不止于此。它涵盖了处理器流水线和作为缓存的内存、虚拟内存系统等等。所有这些都会影响如何针对给定特征优化装配。


C
ChrisW

我认为您想学习 ASCII 化的操作码助记符(及其参数),它们由反汇编器输出,并且可以被汇编器理解(可用作输入)。

任何汇编程序(例如 MASM)都可以。

和/或读一本书对你来说可能会更好(有推荐的书,我不记得是哪一本书了)。


C
Community

您是否在 Windows 上进行其他开发工作?在哪个 IDE 上?如果是 VS,则不需要额外的 IDE 来读取反汇编代码:调试您的应用程序(或附加到外部应用程序),然后打开 disassembly window(在默认设置中,即 Alt+8)。像通过普通代码一样单步执行并观察内存/寄存器。您可能还希望保持一个寄存器窗口打开(默认为 Alt+5)。

英特尔免费提供 manuals,它提供了基本架构(寄存器、处理器单元等)的调查和完整的指令参考。随着架构的成熟和变得越来越复杂,“基本架构”手册的可读性越来越差。如果您可以使用旧版本,那么您可能会有一个更好的起点(即使是 P3 手册 - 他们更好地解释了相同基本执行环境)。

如果您愿意投资一本书,here 是不错的介绍性文字。在亚马逊上搜索“x86”,你会得到很多其他的。您可以从另一个问题 here 中获得其他几个方向。

最后,您可以从 reading some low-level 博客中获益良多。就我个人而言,这些字节大小的信息位最适合我。


J
James Anderson

这不一定会帮助您编写高效的代码!

i86 操作码或多或少是一种“遗留”格式,由于 Windows 和 Linux 的代码和可执行二进制文件的数量庞大,它仍然存在。

有点像古代学者用拉丁文写作,像伽利略这样讲意大利语的人会用拉丁文写作,他的论文可以被像哥白尼这样的波兰人理解。这仍然是最有效的交流方式,尽管 niether 尤其擅长拉丁语,而拉丁语是一种用于表达数学思想的垃圾语言。

因此,编译器默认生成 x86 代码,并且现代芯片读取 anceint Op 代码并将他们看到的内容转换为并行 RISC 指令,包括重新排序执行、推测执行、流水线等。此外,它们还充分利用了处理器的 32 或 64 个寄存器实际上有(与你在 x86 指令中看到的可怜的 8 相反。)

现在所有优化编译器都知道这是真正发生的事情,因此他们编写了他们知道芯片可以有效优化的 OP 代码序列——尽管其中一些序列对于大约 1990 年的 .asm 程序员来说看起来效率不高。

在某些时候,您需要接受编译器编写者数十万年的努力已经得到了回报,并且相信他们。

获得更高效运行时的最简单和最简单的方法是购买英特尔 C/C++ 编译器。他们有一个 efficeint 编译器的利基市场,而且他们的优势是能够向芯片设计人员询问内部发生的情况。


您的故事在某种程度上表明 CISC 处理器已在内部成为 RISC 处理器。我可能误解了,但这根本不是真的。可怜的8呢?现代处理器(例如,自 1999 年以来)包括更多:10 gpr:EAX-EFLAGS、80 位 FP0-FP7、64 位 MMX0-MMX7、128 位 XMM0-XMM7,段:CS-GS,特价:CR0-CR4 、DR0-DR7、TR3-TR7、GDTR、IDTR、LDTR、MSR 和 x86-64 上还有 R8-R15。并非所有这些都可以从 ring-3 访问,但大多数都被最近(2006 年后)的 GCC/VC++ 编译器使用。总共略多于“可怜的 8”;)。
m
mrduclaw

为了做你想做的事,我只是拿了 Intel Instruction Set Reference(可能不是我使用的确切的那个,但它看起来已经足够了)和我在 Visual Studio 中编写的一些简单程序,然后开始将它们扔到 IDAPro/Windbg 中。当我开发自己的程序时,crackmes 的软件很有帮助。

我假设您对程序如何在 Windows 上执行有一些基本的了解。但实际上,对于阅读汇编,只需要学习一些指令和这些指令的几种风格(例如,有一个跳转指令,跳转有一些风格,如 jump-if-equal、jump-if-ecx-is-zero , ETC)。一旦您学习了基本指令,就很容易掌握程序执行的要点。 IDA 的图形视图很有帮助,如果您使用 Windbg 跟踪程序,如果您不确定,很容易弄清楚指令在做什么。

玩了一会儿之后,我买了Hacker Disassembly Uncovered。一般来说,我远离标题中带有“黑客”一词的书籍,但我真的很喜欢这本书深入探讨了编译后的代码是如何被反汇编的。他还研究了编译器优化和一些有趣的效率问题。

这也完全取决于您希望能够理解该程序的深度。如果您正在对目标进行逆向工程以寻找漏洞,如果您正在编写漏洞利用代码或分析打包恶意软件的功能,您将需要更多的加速时间才能真正让事情顺利进行(尤其是对于更高级的恶意软件)。另一方面,如果你只是想改变你最喜欢的视频游戏中角色的等级,你应该在相对较短的时间内做得很好。


P
Paul Nathan

一种标准的教学汇编语言是 MIPS。您可以获得MIPS模拟器(spim)和各种教材。

就个人而言,我不是粉丝。我比较喜欢IA32。


MIPS 不错。 68000 也是,如果您学习 68000,您可以编写在 MAME 中运行的二进制文件。 :-)
G
G B

我个人最喜欢的是 NASM,主要是因为它是多平台的,它可以编译 MMX、SSE、64 位...

我开始用 gcc 编译一些简单的 C 源文件,并将汇编指令从 gcc 格式“转码”成 NASM 格式。然后您可以更改一小部分代码,并验证它带来的性能改进。

NASM 文档非常完整,我从不需要从书籍或其他来源中搜索信息。


m
mohit

您可能会发现一些对学习程序集有用的链接 - 源代码映射 -

Assembly And The Art Of Debugging

Debugging – Modifying Code At Runtime

希望你觉得这些有用。


B
Brian Lyttle

这里有很多很好的答案。低级编程、组装等在安全社区中很流行,因此一旦开始,就值得在那里寻找提示和技巧。他们甚至有一些不错的tutorials like this one on x86 assembly


E
EvilTeach

要真正达到您的目标,您可以考虑从您所在的 IDE 开始。通常是一个反汇编程序窗口,因此您可以单步执行代码。通常有某种视图可以让您查看寄存器并查看内存区域。

检查未优化的 c/c++ 代码将有助于建立一个链接到编译器为您的源代码生成的那种代码。一些编译器有某种 ASM 保留字,可让您在代码中插入机器指令。

我的建议是玩一会儿这些工具,弄湿你的脚,然后站起来?下?在您运行的任何平台上直接汇编代码。

那里有很多很棒的工具,但您可能会发现它更有趣,以避免一开始的陡峭学习曲线。


e
erik

我们学习了使用微控制器开发套件(摩托罗拉 HC12)和厚数据表的组装。


s
slf

我知道题外话,但由于您是 Windows 程序员,我不禁认为学习 MSIL 可能更合适和/或更好地利用您的时间。不,它不是汇编,但它可能在这个 .NET 时代更相关。


A
Adam Pierce

了解汇编对调试很有用,但我不会对使用它来优化代码感到太兴奋。如今,现代编译器通常在优化人类方面做得更好。


唔。您仍然可以自己拧出相当多的额外编码程序集,但是要击败编译器需要比以前更多的工作。
x
xorpd

您可以查看xorpd x86 Assembly video course。 (我写的)。课程本身是付费的,但练习是开源的,在 github 上。如果您有一些编程经验,我认为您应该能够只使用练习并理解所有内容。

请注意,该代码适用于 Windows 平台,并且是使用 Fasm assembler 编写的。课程和练习不包含任何高级结构,但是如果您愿意,可以使用 Fasm 创建非常复杂的宏。


关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅