逆向工程

转自 https://www.zhihu.com/question/23999930

# 知乎用户 lslx

253 人赞同了该回答
作为一个老逆向工程师,有几句话想讲。
2010年就开始搞逆向了,那时候是windows平台,这两年搞起android了。首先逆向是个困难的工作,需要理论,也需要实践。
理论方面,必须清楚的认识逆向的本质是什么。放到更大的环境下来看,逆向从来不是最终目的,最终目的一般是要实现某个东西。
广义上,逆向不仅仅是调试二进制可执行格式,反汇编,破解。逆向是心理模型的建立过程,以及模型实现的底层细节的定位过程。
从理论上看,你为了理解系统,你读代码,无论是源码还是汇编,甚至二进制机械指令,都是一个逆向过程,其结果就是建立了一个模糊的心理模型,
用于理解系统的运作过程,然而系统代码是复杂的,庞大的,只凭脑力难以定位底层细节,需要借助工具,如反汇编器,调试器,模拟器。
有人认为学好了汇编语言,就相当于可以阅读任何闭源软件了,这显然是错误的思想,没有理论上的清晰认识,容易进入这个思维误区,
给定一个逆向的目标,不去搜索背景信息,已有成果,而是一头扎进汇编独自探索,是愚蠢的行为。因为人类的临时记忆是非常可怜的,
靠脑力仅能推演很短的代码量,通过纯汇编去推演高层逻辑,是人脑不可承受的,即便理论是可能的,但时间也是不可承受的。
所以推演必须要让cpu来执行,人脑只负责在特定的条件下让系统停下来,读取推演的结果。于是就有了调试器。
用了调试器,人脑只需判断并控制条件逼近底层细节,具体的就是操作软件,并结合条件断点来定位底层代码,这样在效率上比人肉调试器就有了质的提高。
而这种逆向模型,在很多时候仍然不够,因为它要求逆向者对软件高层概念对底层代码的映射有清晰深刻的理解,
也就是编译器如何把源码层的概念编译为底层代码的,比如高层的函数,语句,变量,如何变为底层的函数,汇编,内存地址的。
一般情况下,逆向者阅读汇编会直接反向映射为高层的函数语句变量等,但是也仅此而已,拥有源码的人根据函数名就知道这个函数是干嘛的,
而逆向者需要更多的信息才能知道,在仅依赖汇编的基础上,如何才能得知这段代码的功能呢,关注它的输入和输出,以及所调函数,
这决定了它的功能。在输入和输出上以及所调用函数的断点上抽取信息做判断,这是和琐碎的工作,是体力活,
于是面向调试器脚本的编程又将逆向推进一步。逆向能力随着逆向手段的增强而越来越强,软件保护的一方也在不断进步,
从开始的反调试,反反汇编,此阶段逆向与保护的能力基本持平,此消彼长,水平依赖于经验,后来发展到虚拟机保护,
保护的一方对逆向破解者造成对抗上的碾压。逆向者面对虚拟机保护一筹莫展,原来的知识体系仅能逆向虚拟机,对虚拟机指令无能为力,
并且没有现成的反汇编器可用,当其中混入了反调后(直接使用系统调用指令),常规逆向走入了死胡同,期待出现新的逆向手段。
终于基于模拟器的技术承担了这一重任,cpu模拟,全系统模拟,污点分析,程序切片技术,总的来说是面向模拟器分析的编程。
模拟器是天然规避反调试的,虚拟指令不用分析了,因为大部分情况我们不需要那种心理模型了。
这个对抗阶段,是多种技术方案并存的,因为门槛比较高,虚拟机保护基本是要花钱的,逆向破解也少有人能力足够来做。
目前这个层次的对抗是个神仙打架,大家围观的状态。
在实践上,你需要理解流行的寄存器机器,流行的操作系统,可执行文件格式,流行的工具,这四个东西的原理。总的来说分三大平台
windows,mac/ios,android。linux不算,因为开源,在实践上研究linux不叫逆向(虽然理论上是)。
这三大平台都(至少)支持intel,arm两种机器架构。
但就现实流行度来看,windows平台基本绑定了intel, mac/ios绑定了intel和arm,android绑定了arm/java。
可执行文件格式分别为pe,macho,elf,流行的工具
有的是平台特定的,有的是通用的,林林总总的很多,总的来说包括编译器,汇编器,调试器,模拟器,二进制分析对比工具,重量级集成式工具。
编译器包括:msvc,gcc,clang,javac
汇编器包括: 相当多的工具都具有汇编和反汇编功能
调试器包括:msvc,windbg,od,gdb,ida,xdbg64,lldb
模拟器或沙盒包括:qemu,bochs,unicorn,vapp
二进制分析对比工具:beyondcompare,010editor,binutils
重量级集成式工具:visualstudio,xcode, android studio,temu,panda,bap,angr,r2,
hook工具:开源detour,其他各类hook,
以上工具挂一漏万,实际上工具实在太多了,光熟悉工具都要耗费很多精力,经常的,你发现一个工具,然后研究使用,然后弃之如履,极少的视如珍宝。
特别提出的工具:visualstudio + visualgdb,其调试功能涵盖windows,android,linux,在理解开源代码方面非常有力。
开源与逆向何关?原因在于很多时候工具过于复杂,导致需要先理解工具,比如unicorn,bochs,甚至xdbg64,或者android的java虚拟机。
曾经有一股歪风,吹捧linux,鄙视windows,吹捧命令行,顺便鄙视可视化工具,实际上,命令行有命令行的优势,可视化有可视化的优势,
尤其是在集成开发调试上,集成开发调试工具上,最大限度的专注于相关信息的展示,以及减少操作,命令行在这方面是劣势,
命令行的优势在于快糙猛的拼凑功能代码,优势在于快速实现一个定制的补丁或功能。

特别喜欢的工具:unicorn,这是高级逆向的基石,为什么unicorn优于基于qemu的全系统模拟工具呢,
因为工具也在发展,并且全系统模拟牵涉了太多的组件和信息,很多时候一个缺陷让你没法用,或者要解决这个跟手头认为毫不相干的问题。
unicorn + softmmu,用来构建运行环境,这时候有个问题,就是你仍需要大量的平台底层知识来使它像真实环境那样来运行起来,
很多时候这是很考验技术深度的,事实上你可以用调试技术来动态的编程获得,前提是unicorn必须编译运行在目标平台上,
在windows,mac,linux上这是容易的,幸好,最近unicorn也能在android上运行了。

对于有志于逆向的新手,几句忠告:
1. 实践重于理论,好的理论会败给实践。
2. 集中精力在一个平台的一个小领域选个平台吧,win,或mac,或android,先找工作在说。因为东西太多了,学不完的。
3. 尽可能的理解工具原理,通过各种手段。
4. 可执行文件的加载执行过程是核心的知识,你需要一个加载器源码在调试器中把玩。
最后, 抱歉,我好像忽略了c/c++的编程能力,我假定你有2-3年的c/c++的编程编程经验,没有这个基础,劝你先别做逆向,先编程吧,c/c++是必须的。
编辑于 2020-05-17

# 知乎用户luping liu

184 人赞同了该回答
我学习了两年的逆向工程,前期主要从事windows 平台的漏洞分析与利用研究,后期进行了android平台下的逆向分析研究,
对windows平台下的逆向分析比较熟悉。针对如何学好逆向可以有以下几个方面可以参考:
1、具备基本的编程能力,如c、c++,c、c++作为很基础的语言,不要求精通,但是必须会写,写个小工具完全没有问题,
同时要对c++的类、继承、虚表虚函数等很熟悉,很多游戏都用c++开发,而且比较庞大,只有基础掌握好,才能更好的从汇编层来读懂代码,
很多时候我们看单条汇编指令时完全没有问题的,但是一旦组合起来就会完全不知所云了,通过必须对高级语言对应的汇编语言实现要掌握,
比如函数工作的原理,几种调用约定、参数传递方式以及返回值等都必须掌握,这方面网上很多资料。
最好能懂python,python作为一种脚本语言,可以用来开发许多逆向调试工具的插件,可以帮我们节省很多的体力活。
2、对windows系统知识比较了解,因为外挂会设计比较多的windows系统知识,因此要对windows底层要一定的掌握,
比如windows api,以及外观常用的注入、钩子技术还有windows系统的异常处理机制等,
可以到广海论坛学习外挂常用的较按键精灵、加速齿轮以及注入等同用知识,书籍可以可以参见《windows核心编程》,对底层知识了解越多,
分析外挂技术也越容易。
3、对逆向分析工具的熟练使用,我们平时工作中面对的是二进制可执行程序,要做外挂我们首先的分析目标程序,
因此对常用的调试工具windbg、ollydbg、静态分析工具ida一定要熟练使用。网上教程也比较多,可以到看雪论坛上利用相关的crackme练手学习。
4、掌握外壳原理和技巧,熟悉常见的加解密算法、反调试技巧,我们分析程序时经常会遇到很多加壳程序,
因此我们必须对外壳的原理和基本知识比较熟悉,熟练掌握同用的脱壳技巧,同时对各种反调试技巧也必须要很熟悉,在分析程序时,
一般会遇到很多加解密算法,因此必须要对各种加解密算法的特征有一定的快速识别能力,这样能更快得帮助我们分析目标程序的核心功能。
这方面可以参看《加密与解密》这本书,讲的非常好与详细。
以上就是基本的学习思路,逆向和外挂都涉及比较多的知识,学习的东西会比较多,而且周期会比较长,不过相信一句话天道酬勤,
只要努力就会有收获,其他方面如网络方面的知识也需要学习,希望这些能帮到楼主,我们学习逆向外挂技术,
目的是更多的去除各种外挂,为我们游戏爱好者更好的服务,而不是利用这些技术来破坏游戏的公平。
发布于 2014-11-06

# 知乎用户梨梨喵

174 人赞同了该回答
看题主的描述应该是想学外挂开发方面的吧,那我姑且把范围划到Windows下X86/X64的逆向与分析,提供一个入门学习的个人不完全的小意见:
1.学习C/C++语言与Windows下的32/64位汇编语言,大致学习掌握计算机组成,熟悉语言的各方面实现细节。了解程序特别是底层的运作机制,
因为在实战中你将面对的是文档几乎为0的底层汇编代码,了解它们是如何工作很重要。而且还有一点现在几乎所有的游戏底层都是用C++编写的。
2.光有语言的基础还要懂如何运用到实战中去,这里推荐一本书:REVERSING:逆向工程揭密。一开始可能面对一个大型的项目可能会力不从心,
比如现在不少游戏都有内核级的进程保护模块,而且代码量巨大,结构复杂。入门可以跟从书上的例子进行实践,或者在网上找些creakMe之类的先练练手。
渐渐熟悉之后再找一些大型的程序逐渐深入。
3.学会使用工具很重要,在逆向中广泛使用的工具如静态反汇编IDA pro和动态调试器OllyDbg还有内核调试winDbg等等,要熟悉它们的使用方式,
要懂得调试程序,掌握一些调试技巧,这方面资料在网络和书籍上都有很多。更进一步可以尝试编写些小插件辅助自己的分析。
4.多关注这方面的消息,比如国内的看雪论坛就有不少这方面的高手,也常常能见到这方面的分析讨论。同时最好能够广泛涉猎,
多了解相关的知识如加密解密,网络原理,内核编程,反调试和代码混淆等等的会大有裨益。另外逆向分析别人的游戏外挂有时会有惊奇发现哦,
比如发现种新的绕过方式,比如挖出个后面木马什么的然后反向社工爆菊什么哈哈哈。
手机码字,排版格式不太好,思路也不是很清晰,以后有时间修正。
编辑于 2014-06-02

# 知乎用户赫敏璋

学逆向和拉二胡、或者弹钢琴、甚至成为一个模范丈夫一样,天赋是有那么点作用的,但是最重要的是耐心。
你如果想尝试新人破解带来的快感,可以研究一下CheatEngine,尝试一下修改植物大战僵尸的阳光值。或者修改一下百度云的高速下载试用时间。
直接ce扫描就可以了。
假如你因此对逆向产生了兴趣,要深入学习逆向的话,可以参考下面的回复
语言基础:
C语言基础:用来编程入门,了解程序的基本结构,
我推荐,C primer plus大厚书,打好基础。
C++基础:游戏和软件很多是C++开发的,如果需要学习逆向,必须先了解正向编程。
汇编基础:王爽编程语言
逆向基础:看雪出版的加密解密
开始研究逆向:
C++反汇编与逆向分析技术揭秘 老钱的书,带你入门c++逆向
API基础:
windows程序设计 第5版 简单了解api,一开始肯定看的头晕,不必全看完
VC++入门:
vc++详解 孙鑫 入门VC++编程,了解程序执行流程,并为逆向打基础
实战:
现在可以开始逆向简单的程序了,或者去做游戏Hack
深入:下面的知识酌情学习
windows系统原理:windows下逆向的话,对系统应该有所了解
windows核心编程
深入解析windows操作系统
IDA分析工具:著名的逆向工具,以编程鼻祖阿达命名,此工具带你了解软件世界下的秘密
IDA Pro权威指南
IDA Pro代码破解揭秘
Windows PE格式:很多安全保护会在PE格式上做手脚
windows pe权威指南
Windows驱动:驱动并不高深,但是很多保护基于驱动,而且基于驱动可以做很多猥琐流的事情,
Windows驱动攻防:研究各种驱动可以做的常规和猥琐流攻防
汇编深入:
x64汇编,还有intel文档,因为windows程序是运行intel cpu指令之上,所以深入的话,必须有所了解
windows系统深入了解

很久之前的回复
俺这个菜比,来扯扯蛋,逆向想搞的好,首先最好得有windows应用层,开发的实战经验。系统理论也得打好。
学汇编可以搞好逆向? ,,,,伪命题。

你应该具备以下知识:
c/c++语言基础 x86和x64汇编,
windows系统理论:
参考:windows核心编程,深入解析windows系统,windows内核原理及实现等,,
应用层:
sdk(必学啊),mfc(没饭吃),.net(微软目前的主流,建议添加)等
Windows PE 驱动开发 Rootkit 软件调试: 比如ida,od,windbg 套接字网络编程 ...
这些书和资料你就去http://z.cn和jd买比较流行的吧,绝版了就去淘宝找买复印书的买盗版,
话说为啥要做黑客呢?
以上这些你比较用功花4、5年完成,,
然后你就面临一个坑爹的事实

这些只是基础啊,,,,,,,,,,
坑爹啊坑爹啊坑爹啊坑爹啊坑爹啊坑爹啊坑爹啊坑爹啊坑爹啊坑爹啊坑爹啊坑爹啊

去学习,实用的技术吧,,看雪,52pojie啦,
当然能赚钱的,技术,不是那么容易得到的,比如过某P啦,过某数字啦
想办法,搞到吧,能用钱最好

然后再没日没夜的过2、3年,,,,
差不多找到一份工作了,,,

为啥要走条路,,,,,,,,,,,,,,,

我是彩笔,,,,,,,,,,,,,,,,,,,,,,,,,

心情不错,再来补充点
有点c/c++基础,会使用msdn,
可以先研究按键模拟,,,自己写,mouse_event啥的前台,,
深入的话配合opencv,提高点击效率
或者配合java、kotlin,做一个安卓端的自动化小程序
再深入的话,使用readMemory和坐标转换做一个读取内存,按键点击的程序。
对于网页或者简单的android app逆向的话,直接fiddler抓包,逆向http协议,或者配合反编译工具,逆向一些加密的算法。
一个游戏hack没那么难,参考我是谁:没有绝对安全的系统 只要你有把锤子(不管是自己做的,还是捡的)打破游戏保护大门,
就可以开始研究游戏hack,为所欲为,提示:如何干掉win10驱动强制签名。
可以考虑参考android或者reactOS的源码

入道了,简单了解OD了,专门学不学汇编吧,直接CE,简单了解IDA,再学学找call,基址,最多2个月,,

fu过保护,驱动神马的,,,总之就是,各种猥琐,变态,流氓方法,,,

最好不要混QQ群,论坛,知乎,微博,这些东西,学会科学上网,老老实实闭门造车。
攻防是对应的,厂商的防御策略,检测手段,github上有很多开源的检测库,你可以自己做一个demo,然后给它加上反检测,然后隐藏自己进行攻击。
操作系统只要你有相关源码,有系统ring0权限,完全可以在两星期的试错后,写一些奇怪的代码,比如重建api,隐藏行为。
对于开发来说,不仅是hack工具,还有企业级和用户级软件,如果一开始采用分层设计,比如读写注入等底层操作为一层,然后是抽象层,然后是逻辑层。
这样可能起步比较慢,但是,越往后开发越快。而且基本可以无视每次底层变化对其他层的影响。这个只是软件工程的基本知识,
但是,发现很多程序员将各种代码像和面粉一样,混合在一起,越往后开发难度反而越大。
软件开发也好,逆向也好,不管你是来自985、专科、初中、小学、大城市、还是来自偏远农村、甚至身有残疾,只要你决定2年、5年、10年去做,一定会成功!
很多教程关于ce的讲解,入门知识都没有讲全。
比如,
veh调试模块(注入目录中的veh dll,然后使用异常断点)
point map功能
驱动调试模块
ReadMemory扫描模块。
断点发现什么在读取,什么在写入

另外,ce 还可以用来破解软件。

另外还有Reclass 工具可以花点时间学习
一个运行中的程序:进程。进程存在于内存中。可以通过扫描进程的内存块(快速查找)。像阅读一本书一样获取你需要的知识。

如果想做一些奇怪的修改,比如操作系统进程,进程链表,游戏进程等等。通过查看源码、反汇编源码、或者dump之后的数据。可以进行很多有趣的操作。

2021年1月15日 北京
很多过来人总是说必须先看过XX书,学习过XX原理,甚至,还要学XX数学,然后才可以学习逆向。还有人说做一个成品没有2、3个人以上不行。
但是,你也可以拿起CE或者其他扫描器(不被检测就行),找一个在线游戏或者单机游戏试一下。甚至,随着比较了解后,给单机游戏加一个vmp壳,
再进行同样的操作。
世界上的很多事情,比如恋爱,创业,并没有如同流水线一样的模式。想做,喜欢做,就努力去做。
至于缺少哪方面的知识,熬上几次夜之后,觉得有意思,可以再去补充。
另外,希望逆向只作为业余爱好,不要破坏游戏的平衡,愉快游戏


(完)