本篇为译作,原文:Additional Exercises in Reverse Engineering

本系列上一篇:x86_64逆向工程简介


这是我(相当长时间以前的)x86_64逆向工程简介(即本系列上一篇文章)的续集。这篇文章快速过了一遍那些没有在该教程中提到的实用的逆向工程方法,并提供了许多练习来磨练您的技能。

CrackMe程序

您可以在GitHub上找到文中讨论的CrackMe程序。克隆这个存储库,并且在不查看源代码的情况下,使用make crackme01 ,make crackme02,……构建所有CrackMe。

工具和软件

这些CrackMe仅适用于Unix系统,我使用Linux编写本教程。您需要安装开发环境的基本知识——C编译器(gcc)、对象检查工具(objdumpobjcopyxxd)等等。本教程还将教您如何使用Radare2,这是一个先进的开源逆向工程工具包。在Debian派生的系统上,您应执行以下命令:

sudo apt install build-essential gcc xxd binutils

您可以在这里安装Radare2。

对于其他系统,通过对应系统的包管理器安装相应的包即可。

练习解答

crackme05.c

这个CrackMe非常类似于前一个教程中提供的那些,但更加模块化。它把成功和失败的情况封装成函数(用aaa分析然后afl列出函数),这两个函数打印出相应的字符串然后退出。

main函数中有一些对失败函数sym.fail的调用,每个次调用都源于不同的条件。只有通过所有的检查,执行流程才会达到0x880,其中RDI(函数的第一个参数)加载了输入字符串,然后调用sym.success

其中一些检查是很明显的的。例如,在0x7d7的代码处检查字符串长度必须正好是16:

call sym.imp.strnlen
cmp eax, 0x10
jne 0x850

但其他检查调用了函数check_with_mod,每次带有三个参数。例如在0x81a处:

lea rdi, [rbx + 8]
mov edx, 5
mov esi, 4
call sym.check_with_mod

这里RBX是argv[1],所以这实际上调用check_with_mod(argv[1] + 8, 5, 4)。第三个参数,这里是4,在所有调用中看起来是一样的,但第二个参数是会变化的。那么check_with_mod是在做什么的呢?

像之前一样,s sym.check_with_mod后跟pdf会给我们答案。它实际上是一个非常简单的函数,只有20个指令。它的核心是一个循环,它将输入字符串(参数1)中某些字节的值相加,相加字节的数量由第3个参数决定。在我们的例子中都是4个字节。

接下来函数执行整数除法idiv r8d。这个指令把RDX除以R8(第二个参数),商保存在RAX中,余数保存在EDX中。然后代码检查RDX为是否零,并把商丢弃,这是模运算

所以这段代码的迷雾被揭开,它是检查给定地址处的4个字节的和,是否可被给定值整除。回到main函数,我们可以看到有四个地方调用这个函数,需要分别满足那对应四个字节之和能整除3,4,5和4。

这还不够。程序还要求第2个字节为'B'和第0xd(13)字节为'Q'。

点击收藏 | 1 关注 | 1
  • 动动手指,沙发就是你的了!
登录 后跟帖