所有程序都可以转换为汇编吗?
假设我们有一个 exe,可以轻松地将其转换为程序集吗?软件作者有办法阻止/阻止这种情况吗?
Say we have an exe, can that be readily converted to assembly? Is there a way for software authors to prevent/obstruct this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
不可以。只有系统能够理解程序,它才能运行。如果它能理解,它可能是机器代码,可以直接转换为汇编代码。
你能做的就是尝试使用代码混淆方法,使反汇编的二进制文件尽可能难以理解。
编辑
:想要补充一点,当然,随着时间和足够的资源,有人最终会弄清楚如何阅读你的混淆代码。这是不可避免的。混淆的作用是让你的工作尽可能不方便地进行逆向工程,使其不值得花时间去追求它,所以只有那些非常想对其进行逆向工程的人才会这样做。
No. A program can only be run by your system if it can understand it; if it understands it, it probably is in machine code, which is directly convertable to assembly.
What you can do is to try to employ code obfuscation methods, so as to make the disassembled binary as hard to understand as possible.
http://en.wikibooks.org/wiki/X86_Disassembly/Code_Obfuscation
Edit: Would like to add that, of course, with time and enough resources, someone will eventually figure out how to read your obfuscated code. It's unavoidable. What obfuscation does is to make reverse engineering your work as inconvenient as possible, to make it not worth their time pursuing it, so only those who want to reverse engineer it badly will do so.
可执行文件被设计为由计算机处理器执行(因此得名)。汇编语言是计算机处理器执行的机器代码之上的一层。如果您的程序可以作为机器代码运行,那么它可以作为程序集读取。
您可能遇到这样的情况:一个专有的 C/C++ 编写的程序正在分发给客户。有些客户不怀好意,他们将程序反编译为汇编语言,更改一些指令(例如防止恶意使用程序的指令、无限期延长程序试用功能的指令),然后重新编译程序。
在这种情况下或类似的情况下,您必须意识到所有未执行的程序都只是磁盘上的数据。任何人都可以读取该数据并根据自己的喜好进行更改。如果这确实是一个问题,那么您将不得不想出另一种方法来保护您的程序:例如,将重要的逻辑委托给执行它并发回结果的 Web 服务。一个例子:谷歌的搜索算法在他们自己的网络服务器上运行 - 没有人确切知道它是如何工作的。
Executables are designed to be executed (hence the name) by computer processors. The assembly language is a layer on top of the machine-code that the computer processor executes. If your program can be run as machine-code, then it can be read as assembly.
You probably have a situation like this: A proprietary C/C++ written program is being distributed to clients. Some of the clients have less than honest intentions, they decompile the program to assembly, change some instructions (for example those that prevent malicious use of the program, extending the programs trial feature indefinitely), and then recompile the program.
In that case, or similar, you must realize that all programs when not executed are simply as data on the disk. Anyone can read that data and change it to their liking. If this really is a problem, you're going to have to come up with another way to protect your program: For example delegating the important logic to a webservice that executes it and sends back the results. An example of this: Googles' search algorithm which runs on their own webservers - no one knows exactly how it works.
一句话,不。就像您无法阻止某人阅读和分析您给他们的书一样。
In a word, no. Just like you can't prevent someone from reading and analyzing a book that you give them.
如果“转换”意味着编译,并且意味着编译为机器代码,是的,绝对如此。在任何机器上运行的每一位代码都作为机器代码运行。对于任何特定语言,答案会有所不同,具体取决于是否存在用于创建不需要该语言的运行时库的独立可执行文件的工具。
如果“转换”是指在程序集中手动编码,请参阅其他答案。我们不这样做,因为编写代码需要很长时间。
至于混淆,我在第一段中提到的转换/编译实际上对此不起作用。当您“编译”Java 或 C# 等内容时,源代码会被转换为许多指向运行时库的指针。这些指针可以轻松地进行逆向工程并重新生成原始代码。
If by "converted" you mean compiled, and by that you mean compiled to machine code, yes, absolutely. Every bit of code that runs on any box is running as machine code. For any particular language the answer varies based on whether tools exist to create a stand-alone executable that does not need the language's run-time libraries.
If by "converted" you mean manually coding it in Assembly, see the other answers. We don't do that because it takes a very long time to write the code.
As for obfuscation, the conversion/compilation I mention in the first paragraph does not really work for this. When you "compile" something like Java or C# the source is translated into a lot of pointers into the run-time libraries. Those pointers can easily be reverse engineered and the original code re-generated.
我认为到目前为止,马拉纳斯对此有最好的答案,但我想补充一点,我认为你可以在某些条件下反汇编该程序。首先这样想,如果它实际上是可执行的,意味着可以由处理器执行,那么您绝对可以以与处理器完全相同的方式解析该二进制文件,这意味着您可以解析每个位和字节并将其转换转换成人类可读的 ascii/汇编形式。如果程序可以执行,这总是可能的。
现在,如果您拥有的只是 .exe 文件,是否有一些东西可以阻止其工作,当然,很多东西和马拉纳斯答案都与其中一些相关,例如加密,以及如果该加密的密钥位于硬件或用户密码或 .exe 文件中未包含的内容,那么您可能无法弄清楚,游戏就结束了。
在编写反汇编程序的这些年里,我看到了不同的技巧,有时是有意的,有时不是。例如,如果您阅读 Michael Abrash 撰写的 Zen of Assembly,我似乎相信有关于 8088/86 中预取器的讨论,该讨论是区分一个处理器与另一个处理器的一种方式(记住这是在缓存之前),但也击败黑客。例如,您可以做的是让一条指令修改下一条指令,例如递增它。这将完美执行,因为第二条指令已被获取并位于管道中,因此修改后的指令仅在内存中,未修改的指令将被执行。当然,这需要是只运行一次的代码,因为该指令在内存中被修改。这样做的作用特别是阻止人们使用调试器单步执行代码,因为调试器会执行修改后的指令并崩溃或执行类似的操作。如果你的反汇编程序试图模拟程序并且没有考虑硬件再次工作的方式,你就会陷入困境。我还看到了使用说加载立即数为零的寄存器,然后是如果零则分支,这与无条件分支相同(假设寄存器确实不需要为零),后面跟着一些数据,这些数据将导致反汇编程序被绊倒。您需要使用可变字长指令集才能使其工作。对于人类来说,弄清楚发生了什么并手动调整反汇编过程以避免非指令的数据字并不困难,但对于自动化工具(不是模拟器)来说更困难。技巧的列表一直在不断...
最重要的是,如果您的程序可以由处理器执行,那么您绝对可以将机器代码转换回人类可读的汇编程序形式。是的,您可以做一些事情,特别是使用对于仅查看可执行文件的反汇编程序来说是秘密或不明显的硬件功能,这可以并且将会阻止反汇编。与任何安全措施一样,如果用户可以物理访问该东西,他们可能会击败它,如果他们有能力在硬件上运行程序,他们可能有能力击败你的安全措施并反汇编它。
I think maranas has the best answer to this so far but would add that I think you can disassemble the program, with some conditions. First think of it this way, if it is actually executable, meaning can be executed by a processor then absolutely you can parse through that binary in exactly the same way the processor can and that means you can parse through every bit and byte and turn that into a human readable form ascii/assembler. This is always possible if the program can be executed.
Now, are there things that can prevent that from working if all you have is the .exe file, sure, lots of things and maranas answer linked to some of them, for example encryption, and if the keys to that encryption are in hardware or a user password or something that is not included in the .exe file then you may not be able to figure it out and it is game over.
Over the years of writing disassemblers I have seen different tricks, sometimes intentional, sometimes not. For example if you read the Zen of Assembly by Michael Abrash I seem to believe there was a discussion about the prefetcher in the 8088/86 the discussion being a way to tell one processor from another (remember this was before caches), but also to defeat hackers. What you could do for example is have one instruction modify the next instruction, increment it lets say. This would execute perfectly because that second instruction had already been fetched and was in the pipe, so the modified instruction was only in memory, the unmodified instruction would get executed. Naturally this needed to be code that was only run once as that instruction was being modified in ram. What this did was in particular stop folks from single stepping through your code with a debugger, because the debugger would execute the modified instruction and crash or do something like that. And if your disassembler attempted to simulate the program and didnt account for the way the hardware works again you would be lead off into the weeds. I have also seen the use of say loading a register with an immediate of zero followed by a branch if zero, which is the same as an unconditional branch (assuming that register really didnt need to be zero), follow this by some data that will cause the disassembler to get tripped up. You need to be on a variable word length instruction set for this to work. Not difficult for a human to figure out what happened and hand adjust the disassembly process to avoid the data word that is not an instruction, but more difficult for an automated tool (that isnt a simulator). The list of tricks goes on and on...
The bottom line is if your program can be executed by a processor then yes absolutely you can convert the machine code back into a human readable assembler form. And yes there are things you can do, in particular using hardware features that are secret or not obvious to the disassembler looking only at the executable file, that can and will prevent disassembly. As with any security measure if the user has physical access to the thing they can probably defeat it, if they have the ability to run the program on hardware they likely have the ability to defeat your security measure and disassemble it.