本文由 简悦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…’等等。下面的图能够更好地解释这个问题。

[Hack翻译]逆向工程简介

关于寄存器的更多细节,请看此链接通用寄存器能够用于计算,事实上,只有经过这些寄存器,你才干进行加减等操作。因而,假如你想把存储在两个不同内存方位的两个数字相加,你有必要把存储在那里的数值加载到寄存器中,然后进行操作,再把这些数值写到内存方位。咱们不会去研讨这些操作的详细细节,而是在下面快速总结一下。

还有一件重要的事情要留意,便是ESP和EBP是用来存储仓库的内存方位的。ESP指向仓库的顶部,EBP(一般)指的是底部。因而,在仓库上声明变量相当于从ESPEBP中加减值。请留意,你一般不需求知道详细的细节,但有一个含糊的概念就能够了。

还有几个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中的值和以十六进制给出的值21cmp本质上是减去这两个值,并设置一些咱们之前谈到的FLAGS。在这儿,假如两个值相等,那么减去的值将是 “0”,所以 “ZERO “标志将被设置。

下一条指令jz代表 “越过零”。因而,假如零标志被设置,程序将跳转到由0x7eb地址描述的代码方位(经过运用调试器能够很容易地看到)。因而,这相似于一个 “if “语句。

事实证明,咱们能够巧妙地运用这种命令来构建forwhile和其他循环。咱们将在下一篇文章中进行介绍。假如咱们运用jz,而不是jle,那么假如满足ecx <= 15h,就会产生跳跃。事实上,有许多这样的条件式能够用来模仿操控流。

pushpop

这些对咱们来说其实并不重要。语法大多是这样的。

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函数的代码是什么。

[Hack翻译]逆向工程简介

需求留意的一件事是,在逆向工程中,不要企图分析全部的东西,因为许多东西都是经过编译器生成的,或许很难了解。相反,要测验深化了解程序的运转结构。

现在咱们看到,在 “cek “的上层块产生的全部之后,有两条路线。一条路线是将eax设置为1,否则为0。很明显,咱们想看的是当值被设置为1时,因为只有这时针才是正确的。

分支是由jnz决议的。这意味着 “假如不是零就越过”。因为咱们运用的是cmp,这意味着只有当零标志被设置时,咱们才不会跳转(因而得到EAX为1)。

什么时候设置零标志?只有当[rbp+var_4] == eax时才会产生。但是上面两个movs显现现在[rbp+var_4]中的值与edi中的值相同,而eax中的值是在一个叫cs:valid的东西中。

这个cs:valid是什么?本来它只是IDA给存储在二进制中的一些值起的一个姓名。假如咱们双击它,咱们会得到以下的值数据。

[Hack翻译]逆向工程简介

现在咱们还没有看到咱们的输入被贮存在哪里。成果发现它被存储在EDI中。这在一般情况下是会改动的,但运用一个叫做动态反汇编程序(gdb)的东西,咱们能够弄清楚(咱们将在下一个教程中看到)。即使不知道这一点,咱们也能够猜想,输入被存储在EDI中,正如咱们将看到的,这个猜想被证明是正确的。

因而,假如咱们的输入等于51615h(用十六进制表示),咱们将在EAX中得到1,因而这一定是PIN码 将其转换为二进制,咱们得到333333这个值。

让咱们输入这个值,看看这个值是否正确。

[Hack翻译]逆向工程简介

的确,咱们得到了 “PIN benar”! 这便是PIN,咱们用一些巧妙的拆解和调查技巧找到了PIN!

这就总结了这个问题。这实际上是比较简略的逆向工程问题之一,因为咱们只用一个静态反汇编程序就能够处理它。今后咱们会看到一些更复杂的问题,有必要运用其他东西如gdbradare2等来处理。

本教程就到此为止。请随意运用IDA测验更多的问题,同时也要记得多用谷歌。了解汇编并不容易,一个人有必要经常用google来弄清楚每个操作的效果。就这样,祝你玩得开心,持续黑下去吧


www.deepl.com 翻译