本文由 简悦SimpRead 转码,原文地址 geekpradd.github.io
逆向工程是网络安全和品德黑客中最风趣的范畴之一。经过……
逆向工程是网络安全和品德黑客中最风趣的范畴之一。经过这篇文章,咱们将企图经过一步一步的方式来简化这一范畴的想法。咱们现在将重点关注简略的ELF Linux可履行文件,今后咱们还将研讨逆向工程的windows exe可履行文件和JVM的字节码等。所以,让咱们开端吧!
什么是逆向工程?
简略地说,逆向工程是指解构任何工程对象以弄清其内部机制的进程。一个比如是破解游戏,破解者有必要在他们的电脑上对游戏代码进行逆向工程,以便能够免费分发。
大多数非开放源码的软件都不提供源代码,而咱们只有编译后的可履行代码。咱们有必要在某种程度上从可履行代码中找出soruce的内容(或其子集)。这在一般情况下是不容易做到的,因为机器/汇编代码是十分复杂的,并且还添加了许多编译器的优化功用。
一般来说,提供给咱们的可履行文件或许不是二进制或汇编指令,也或许是任何虚拟机(比如说Java虚拟机)履行的渠道独立字节码的形式。但是,咱们在本教程中只看从C/C++代码生成的Linux可履行文件,因为这提供了该范畴的一个相当好的概述。但是,要做到这一点,咱们有必要了解根本的汇编。
x86汇编简介
x86汇编是由非ARM(Intel/AMD)处理器运用的汇编指令代码,大多数CTF问题将运用这种指令代码。产生的指令或许因操作系统而异,咱们将考虑linux的可履行文件(ELF格局)。在持续之前,请留意有各种不同的汇编语法,咱们将在本教程中运用英特尔汇编语法,尽管替代的AT&T语法也很常见。
与高档言语比较,汇编言语的结构十分少,而有必要依靠一些原始的操作。大多数汇编操作都产生在寄存器上,它是CPU上的特别内存方位,比直接拜访RAM要快得多,许多特别的值都存储在这儿。咱们先来看看这些寄存器和它们的命名规矩。
寄存器
寄存器能够被认为是CPU中的一个特别内存方位。有6个通用寄存器和2个特别寄存器可用。咱们能够在这些寄存器上进行全部或许的汇编操作,如加值、减值等。
这8个寄存器被命名为 “EAX, EBX, ECX, EDX, ESI, EDI, ESP, EBP”。
但是,假如你翻阅任何汇编代码,你会看到寄存器名称的各种改动。你能够用不同的方式来调用不同的寄存器。以上的命名方式能够让你拜访与每个寄存器相关的32位。现在在64位系统中,每个寄存器被分配了64位,能够经过运用RAX, RBX, RCX, RDX, RSI, RDI, RSP, RBP
的名称来调用。
同样,假如你只想得到16位,你能够用 “AX, BX, CX… “来称号它们,以此类推。要获得8位,你将运用`AL, BL, CL…’等等。下面的图能够更好地解释这个问题。
关于寄存器的更多细节,请看此链接通用寄存器能够用于计算,事实上,只有经过这些寄存器,你才干进行加减等操作。因而,假如你想把存储在两个不同内存方位的两个数字相加,你有必要把存储在那里的数值加载到寄存器中,然后进行操作,再把这些数值写到内存方位。咱们不会去研讨这些操作的详细细节,而是在下面快速总结一下。
还有一件重要的事情要留意,便是ESP和EBP
是用来存储仓库的内存方位的。ESP
指向仓库的顶部,EBP
(一般)指的是底部。因而,在仓库上声明变量相当于从ESP
和EBP
中加减值。请留意,你一般不需求知道详细的细节,但有一个含糊的概念就能够了。
还有几个FLAGS是由汇编运用的。把标志看成是一个特定的布尔变量,由汇编指令来设置。一些标志是零标志、符号标志等。咱们在逆向工程中主要需求零标志,因为这个标志被屡次用来确定操控流。
根本汇编操作
mov
操作
mov
操作是最简略的操作之一,它所做的便是移动数值(或赋值)。mov
的语法如下。
mov destination, source
假定我想在EAX
中设置数值12
,那么我将运转操作。
mov eax, 12
还有一件事需求了解,那便是撤销引证。假定寄存器ECX
中的值是0x6665f
,这是一个内存方位。因而,ECX'相似于一个指针。假如我想把存储在
0x6665f的值加载到
EAX`,我将运用以下命令。
mov eax, [ecx]
大括号[]
的功用相似于C/C++中的*
,它撤销对内存方位的界说并输出该方位的值。
add
操作
这是很简略的。考虑一下下面的汇编代码。
添加eax, ebx
这等同于:
eax = eax + ebx
sub
操作
这也是相似的。考虑一下下面的汇编代码。
sub eax, ebx
这就相当于
eax = eax - ebx
cmp
操作
这是一个十分有用的操作,用于比较数值。这个操作的成果能够和jump
操作结合起来,支配操控流。考虑一下下面的代码。
cmp ecx, 15h
jz 0x7eb
让咱们看看这是什么。cmp
命令比较给定的值,在本例中是存储在ecx
中的值和以十六进制给出的值21
。cmp
本质上是减去这两个值,并设置一些咱们之前谈到的FLAGS
。在这儿,假如两个值相等,那么减去的值将是 “0”,所以 “ZERO “标志将被设置。
下一条指令jz
代表 “越过零”。因而,假如零标志被设置,程序将跳转到由0x7eb
地址描述的代码方位(经过运用调试器能够很容易地看到)。因而,这相似于一个 “if “语句。
事实证明,咱们能够巧妙地运用这种命令来构建for
、while
和其他循环。咱们将在下一篇文章中进行介绍。假如咱们运用jz
,而不是jle
,那么假如满足ecx <= 15h
,就会产生跳跃。事实上,有许多这样的条件式能够用来模仿操控流。
push
和pop
。
这些对咱们来说其实并不重要。语法大多是这样的。
push/pop register
这个操作负责向仓库推送/平移数值。咱们不会经常运用它。
test
操作
这与cmp
相似,只是它计算二进制的AND
而不是减法。因而,假如给定的两个输入的二进制AND'是
0’,那么零标志被设置。
因而下面的`C’条件能够很容易地翻译成汇编。
if (eax == 0){
// do stuff
}
相应的程序集将是。
test eax, eax
jz location_to_do_stuff
lea
操作。
这是咱们将在这儿看到的最后一个操作。这与mov
相似,但不是仿制值,而是仿制地址。
lea eax, [ecx]
上面的代码将把存储在ecx
中的值(也便是地址)仿制到eax
中。请留意,mov
会仿制存储在ecx
中的地址的值。因而lea
加载的是地址而不是值。它代表了加载有效地址。
逆向工程的静态反汇编介绍。
到目前为止,现已看到了许多理论。现在让咱们来看看如何将其付诸实践!
咱们需求一个反汇编程序来获取和研讨汇编代码。现在让咱们运用一个静态反汇编程序。静态反汇编程序不允许咱们运转该文件,但它提供了一个规整的汇编代码反汇编分析。IDA是这方面的行业标准,从这儿下载并运转IDA的免费版本
一旦你安装了IDA Free,你就能够开端作业并分析代码了。让咱们用IDA处理这个CTFLearn挑战。
下载文件并将其加载到IDA中。持续点击下一步,不要改动任何选项(例如,让IDA决议它是一个ELF!)。你应该到达以下屏幕:!
假如你运转该文件,你会发现你需求输入一个针脚才干作业。假如你输入任何随机的输入,它将输出 “PIN Salah!” 很明显,咱们想找到PIN码,这就有了另一种或许性。
上面的分支显现了另一种或许性,你想得到 “PIN BENAR!”。观察一下,经过test
,咱们能够得到 “PIN Salah!”的唯一方法是EAX
的值为0。
所以当咱们输入过错的PIN码时,EAX
被设置为0。汇编中的call
意味着咱们正在调用一个函数。双击那里,看看cek
函数的代码是什么。
需求留意的一件事是,在逆向工程中,不要企图分析全部的东西,因为许多东西都是经过编译器生成的,或许很难了解。相反,要测验深化了解程序的运转结构。
现在咱们看到,在 “cek “的上层块产生的全部之后,有两条路线。一条路线是将eax
设置为1
,否则为0
。很明显,咱们想看的是当值被设置为1
时,因为只有这时针才是正确的。
分支是由jnz
决议的。这意味着 “假如不是零就越过”。因为咱们运用的是cmp
,这意味着只有当零标志被设置时,咱们才不会跳转(因而得到EAX
为1)。
什么时候设置零标志?只有当[rbp+var_4] == eax
时才会产生。但是上面两个movs
显现现在[rbp+var_4]
中的值与edi
中的值相同,而eax
中的值是在一个叫cs:valid
的东西中。
这个cs:valid
是什么?本来它只是IDA
给存储在二进制中的一些值起的一个姓名。假如咱们双击它,咱们会得到以下的值数据。
现在咱们还没有看到咱们的输入被贮存在哪里。成果发现它被存储在EDI
中。这在一般情况下是会改动的,但运用一个叫做动态反汇编程序(gdb)的东西,咱们能够弄清楚(咱们将在下一个教程中看到)。即使不知道这一点,咱们也能够猜想,输入被存储在EDI
中,正如咱们将看到的,这个猜想被证明是正确的。
因而,假如咱们的输入等于51615h
(用十六进制表示),咱们将在EAX
中得到1
,因而这一定是PIN码 将其转换为二进制,咱们得到333333
这个值。
让咱们输入这个值,看看这个值是否正确。
的确,咱们得到了 “PIN benar”! 这便是PIN,咱们用一些巧妙的拆解和调查技巧找到了PIN!
这就总结了这个问题。这实际上是比较简略的逆向工程问题之一,因为咱们只用一个静态反汇编程序就能够处理它。今后咱们会看到一些更复杂的问题,有必要运用其他东西如gdb
,radare2
等来处理。
本教程就到此为止。请随意运用IDA测验更多的问题,同时也要记得多用谷歌。了解汇编并不容易,一个人有必要经常用google来弄清楚每个操作的效果。就这样,祝你玩得开心,持续黑下去吧
www.deepl.com 翻译