summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--auto.pngbin0 -> 20879 bytes
-rw-r--r--class.pngbin0 -> 66433 bytes
-rw-r--r--hide-debug.pngbin0 -> 49899 bytes
-rw-r--r--re.tex128
-rw-r--r--strings.pngbin0 -> 215523 bytes
5 files changed, 116 insertions, 12 deletions
diff --git a/auto.png b/auto.png
new file mode 100644
index 0000000..5bbbea2
--- /dev/null
+++ b/auto.png
Binary files differ
diff --git a/class.png b/class.png
new file mode 100644
index 0000000..cac1f6d
--- /dev/null
+++ b/class.png
Binary files differ
diff --git a/hide-debug.png b/hide-debug.png
new file mode 100644
index 0000000..7a5cbe4
--- /dev/null
+++ b/hide-debug.png
Binary files differ
diff --git a/re.tex b/re.tex
index 4329e2d..625f893 100644
--- a/re.tex
+++ b/re.tex
@@ -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
new file mode 100644
index 0000000..f8708e6
--- /dev/null
+++ b/strings.png
Binary files differ