diff options
-rw-r--r-- | auto.png | bin | 0 -> 20879 bytes | |||
-rw-r--r-- | class.png | bin | 0 -> 66433 bytes | |||
-rw-r--r-- | hide-debug.png | bin | 0 -> 49899 bytes | |||
-rw-r--r-- | re.tex | 128 | ||||
-rw-r--r-- | strings.png | bin | 0 -> 215523 bytes |
5 files changed, 116 insertions, 12 deletions
diff --git a/auto.png b/auto.png Binary files differnew file mode 100644 index 0000000..5bbbea2 --- /dev/null +++ b/auto.png diff --git a/class.png b/class.png Binary files differnew file mode 100644 index 0000000..cac1f6d --- /dev/null +++ b/class.png diff --git a/hide-debug.png b/hide-debug.png Binary files differnew file mode 100644 index 0000000..7a5cbe4 --- /dev/null +++ b/hide-debug.png @@ -161,18 +161,49 @@ \end{itemize} \end{frame} -\begin{frame}{radare2常用命令和功能} +\begin{frame}{学习使用radare2} + 首先安装radare2.考虑到大多数发行版中radare2的版本太老,建议从GitHub获取源码后执行 sys/user.sh 安装。 + + radare2主要由命令行控制。学习radare2可以参考\uref{https://github.com/radare/radare2book}{radare2book}. + + 此外,radare2还有多个GUI前端实现,目前开发较活跃的是\uref{https://github.com/radareorg/cutter}{Cutter}.radare2还可以自身启动一个HTTP服务器,通过浏览器控制radare2. +\end{frame} + +\begin{frame}{radare2命令:分析} \begin{itemize} - \item 分析:a, af - \item 打印:p, x(即px) + \item 分析目标文件:aa, aaa, aaaa + \item 函数标记:af. 用于手动标记函数,在自动分析没分析出一个地址指向函数的时候使用。 \item 反汇编:pd, pdf, pi, pif - \item 工程:Ps - \item 注释:CC - \item 标记:f, afn + \item 打印:p, x(即px) \item 搜索:/ \item 交叉引用:axt - \item 类UNIX特性:重定向、管道和\~{}命令 + \end{itemize} +\end{frame} + +\begin{frame}{radare2命令:标记} + \begin{itemize} + \item 标记全局变量:f + \item 重命名函数:afn + \item 注释:CC + \item 工程:Ps. 为了在下次启动radare2时能使用以前的分析和标记信息,可以把当前的工作保存为工程。用 \textbf{r2 -p} 加载工程。工程文件为 \textit{\~{}/.local/share/radare2/projects/<proj>/rc},用 \textbf{r2 -i} 可以加载此文件。 + \end{itemize} +\end{frame} + +\begin{frame}{radare2二进制编辑} + 用radare2的\textit{-w}参数打开文件,或在radare2中执行\textit{oo+}命令,可以用可写的模式打开文件,此时可以对文件进行编辑。也可以执行\textit{r2 malloc://size}打开一个可读写的缓冲区。 + + \begin{itemize} + \item 写入一串十六进制表示的字符:wx + \item 写入汇编指令:wa + \item 保存缓冲区中内容至文件:wtf + \end{itemize} +\end{frame} + +\begin{frame}{radare2其他特性} + \begin{itemize} + \item 类UNIX特性:重定向、管道和类似grep的\~{}命令 \item 脚本 + \item 扩展:如反编译器r2dec,可以用radare2的包管理器r2pm安装 \end{itemize} \end{frame} @@ -220,7 +251,7 @@ 从\uref{北京大学学位论文库}{http://thesis.lib.pku.edu.cn/}下载的学位论文需要使用一个专用的PDF阅读器才能打开。 \begin{itemize} \item 对于有DRM的文档,不能打印,不能选择文档内容 - \item 限制文档的阅读期限(可能还有次数) + \item 阅读期限(可能还有阅读次数)限制 \end{itemize} \end{frame} @@ -229,7 +260,7 @@ PDF文件结构如下: \begin{itemize} - \item PDF文件头:一行 \textbf{\%PDF-x.y} 注释,通常再增加一行二进制注释 + \item PDF文件头:一行 \%PDF-x.y 注释,通常再增加一行二进制注释 \item 多个PDF对象 \item 交叉引用表 \item 文件结尾 @@ -240,25 +271,98 @@ 可以用文本编辑器打开PDF文件学习PDF文档的结构。 \end{frame} -\begin{frame}{从字符串中找出程序链接的库} - strings(1)可以打印出一个文件中可打印的字符串,radare2中的f命令也可以显示文件中的字符串。 +\begin{frame}{从字符串中寻找信息} + strings(1)可以打印出一个文件中可打印的字符串,但是无法显示UTF-16字符串。 + + 在radare2中先用aaa分析,在分析函数的过程中可以找到函数引用的数据,如果是字符串,则会进行标记。之后用f命令可以看到程序中被引用的字符串,包括UTF-16字符串。 +\end{frame} - 从程序中的assert语句泄漏的信息,可以推断程序静态链接的PDF库pdfium的3100版本。我们可以下一份pdfium的源码并检出chromium/3100分支。 +\begin{frame} + \begin{figure}[htbp] + \centering + \includegraphics[scale=0.23]{strings.png} + \end{figure} + + 从程序中的assert语句泄漏的信息,可以推断程序静态链接了PDF库pdfium的3100版本。我们可以下一份pdfium的源码并检出chromium/3100分支。 \end{frame} \begin{frame}{静态分析:标记函数} assert语句不但泄漏了源码路径,还有assert语句的行号和assert所断言的条件,因此可以很容易地找到assert语句对应的函数。 + 此外,还可以对比汇编和源码,找出汇编里面的函数调用对应的源码中的函数。在这个过程中,还可以找出哪些代码被修改过。最终,可以发现pdfium中的函数\textbf{CPDF\_Parser::SetEncryptHandler}被修改,由于这是解密相关的函数,可以推断里面调用了PDF DRM相关的解密过程。 \end{frame} \begin{frame}{调试:从程序执行路径中找关键函数} + 由于C++的虚函数是间接调用,r2的静态分析不能直接找到虚函数,也不能提供引用信息。此时可以借助调试器。 + + 在静态分析的过程中发现,程序中使用了\textbf{IsDebuggerPresent}这个API检测调试器,我们在x64dbg中隐藏调试器即可。 + + 跟踪此前提到被修改的\textbf{CPDF\_Parser::SetEncryptHandler}函数,可以发现在阅读器打开有DRM的PDF文件时,会调用位于0x0040b080(radare2中的地址,由于重定位,x64dbg中地址的高16位不同)的虚函数,因此我们可以对这个函数进行分析。 +\end{frame} + +\begin{frame}{隐藏调试器} + \begin{figure}[htbp] + \centering + \includegraphics[scale=1.3]{hide-debug.png} + \end{figure} \end{frame} \begin{frame}{调试:找到关键循环} + x64dbg的追踪工具可以自动执行步进/步过操作,通过使用自动步过功能,可以找到执行次数比较多的循环,这样的循环很可能和DRM的解密相关。 + + \begin{figure}[htbp] + \centering + \includegraphics[scale=2]{auto.png} + \end{figure} +\end{frame} + +\begin{frame}{静态分析:分析结构体成员位置} + 通过对比汇编和源代码,可以分析出一个结构体/类中每个成员的偏移地址。利用这个信息,可以更快地找到程序中哪些代码修改了我们关心的数据。 + + \begin{figure}[htbp] + \centering + \includegraphics{class.png} + \end{figure} + + 在这里,我们分析 \textbf{CPDF\_CryptoHandler::Init} 等函数,可以判断 \textbf{CPDF\_SecurityHandler} 类中加密密钥的偏移,再通过这个信息,可以找到哪些代码改写了加密密钥。 \end{frame} \begin{frame}{函数识别:通过特殊常数识别算法} + 在分析某些函数时,可以找到一些常数,通过它可以识别出使用的算法。 + + 在这个阅读器中,可以找到以下常数: + \begin{itemize} + \item 0x6a09e667,0xbb67ae85: SHA256 + \item 0x6c078965: MT19937 + \end{itemize} +\end{frame} + +\begin{frame}{在MuPDF中实现PDF文件的解密} + 在前面的分析中,我们可以发现阅读器打开有DRM的PDF时,用自身的加密处理函数算出一个密钥,解密过程则是使用PDF文档的标准解密过程,用算出来的密钥进行解密。 + + MuPDF是一个用C语言编写的简单高效的PDF阅读器和库,我们修改MuPDF使它能读取有DRM的文档。 + + 开始的时候,我用x64dbg在内存中提取计算出的解密密钥,然后硬编码至MuPDF,它可以打开相应的文档。 + + 在完全找出解密算法之后,在MuPDF中实现这个算法,然后测试,发现可以打开图书馆中有DRM的PDF文档,于是完成了DRM的破解。 + + 最终代码已上传至 \uref{https://git.wehack.space/mupdf/log/?h=xjc-rebase}{git.wehack.space}. \end{frame} +\section{总结} + +\frame{\tableofcontents[currentsection]} + +\begin{frame}{总结} + 现在我们已经初步地了解了逆向工程,并且看到了怎样使用这项技术破解简单的软件限制。 + + 如果你想更深入地了解逆向工程,提高自己的逆向水平,可以参加CTF竞赛,观看逆向工程相关的会议资料。 + \begin{itemize} + \item \uref{https://ctf-wiki.github.io/ctf-wiki/reverse/introduction/}{CTF Wiki: 软件逆向工程简介} + \item \uref{https://recon.cx/}{REcon} + \item \uref{https://www.defcon.org/}{DEF CON} + \item \uref{https://radare.org/con/}{r2con} + \end{itemize} +\end{frame} \end{document} diff --git a/strings.png b/strings.png Binary files differnew file mode 100644 index 0000000..f8708e6 --- /dev/null +++ b/strings.png |