C语言编译逆向相关知识

1 如何将ccs2000生成的.out文件反汇编

可以使用Ti的工具链TMS320C3x/C4x/C5x/C6x Optimizing C/C++ compiler(OCC),其中包含了一个反汇编工具 dis2000.exe,可以将.out文件反汇编成汇编代码。

具体操作步骤如下:

  1. 打开命令行终端,进入到安装了OCC工具链的目录。
  2. 执行以下命令,将.out文件反汇编成.asm文件。
1
dis2000.exe filename.out filename.asm

其中,filename是.out文件的文件名(不包含扩展名)。

  1. 打开生成的.asm文件,即可查看反汇编后的汇编代码。

2 linux下gcc编译生成.out,.o,.a,.so文件

2.1 文件类型介绍

.out是可执行文件,相当于win上的exe

.o是编译中间目标文件,相当于win上的.obj

.a是静态库,多个.o链接得到,用于静态链接。

.so是共享库,用于动态链接,相当于win上.dll


2.2 out可执行文件生成

1
2
3
4
5
6
// main.cpp
#include <stdio.h>
int main() {
printf("hello world!\n");
return 0;
}

编译cpp:gcc main.cpp -o a.out

执行a.out:./a.out,结果会在终端中打印hello world!。


2.3 o目标文件生成

1
2
3
4
5
6
// hello.cpp
#include <stdio.h>

void hello() {
printf("hello!\n");
}

生成.o文件:gcc -c hello.cpp

执行命令后会得到hello.o文件,由于是中间文件,所以无法执行。


2.4 静态库生成

2.4.1 创建静态库

由.o文件创建静态库,静态库文件的命名规范是以lib为前缀,紧接着跟静态库名,扩展名为.a。

例如:我们将创建的静态库名为hello,则静态库文件名就是libhello.a。

生成.a文件:ar -cr libhello.a hello.o


2.4.2 调用静态库

1
2
3
4
5
6
7
// main.cpp
#include <stdio.h>
void hello();
int main() {
hello();
return 0;
}

编译main.cpp,静态链接libhello.a:gcc main.cpp libhello.a -o main.out


2.5 so共享库生成

2.5.1 创建so

由.o文件创建动态库文件,动态库文件命名规范和静态库文件命名规范类似,也是在动态库名前加前缀lib,但其文件扩展名为.so。

例如:我们将创建的动态库名为hello,则动态库文件名就是libhello.so。

生成so文件:gcc -shared -fPIC -o libhello.so hello.o

生成dll文件:gcc -shared -fPIC -o libhello.dll hello.o

我们执行时,发现报错hello.o:relocation R_x86_64_32 against '.rodata' can not be used when making a shared object;recompile with -fPIC ,这是因为在生成hello.o时,没有使用-fPIC选项,所以我们使用:gcc -c -fPIC hello.cpp,重新生成一下hello.o,再次执行生成so命令。


2.5.2 调用so

编译main.cpp:gcc -o main.exe main.cpp -L. -lhello(windows下需要dll而不是so文件),

如果在linux下执行:gcc -o main.out main.cpp -L. -lhello报错,是可能找不到动态库文件libhello.so,程序运行时,会在/usr/lib和/lib等目录中查找需要的动态库文件。若找到,则载入动态库,否则将提示类似找不到文件的错误。


3 IDA快速上手使用

3.1 启动IDA

只要启动 IDA,你都会看到一个初始欢迎界面,上面显示你的许可证信息摘要。初始屏幕消失后,IDA 将显示另一个对话框,为你进入桌面环境提供 3 种选项

New(新建)。选择 New 将启动一个标准的 File Open 对话框来选择将要分析的文件。根

据选择的文件,IDA 会显示另外一个或多个对话框,你可以选择特定的文件分析选项,

然后再加载、分析和显示该文件。

Go(运行)。Go 按钮终止加载过程,使 IDA 打开一个空白的工作区。这时,如果要打开

一个文件,可以将一个二进制文件直接拖放到 IDA 工作区,或者使用 File 菜单中的某个

选项打开该文件。

Previous(上一个)。使用 Previous 按钮可以打开其下“最近用过的文件”列表中的一个

文件。“最近用过的文件”列表中包含 IDA 的 Windows 注册表项的 History 子项中的值。


3.2 IDA文件加载

打开一个新文件时,会看到如图所示的加载对话框。

IDA 会生成一个可能的文件类型列表,并在对话框顶部显示这个列表。这个列表中将显示最适合处理选定文件的 IDA 加载器。IDA 通过执行 loaders 目录中的每一个文件加载器,来确定能够识别新文件的加载器,从而建立了这个列表。

如果 IDA 提供几个加载器,这时选择默认选项是一个不错的策略,除非你拥有推翻 IDA 决定的信息。

简言之:选默认

同样的,选默认。


3.3 IDA关闭数据库

任何时候你关闭一个数据库,无论你是完全关闭 IDA,还是切换到另一个数据库,IDA 都将

显示一个 Save database(保存数据库)对话框,如图

如果这是你初次保存一个新建的数据库,IDA 会用扩展名.idb 替换输入文件的扩展名,从而生成新数据库的文件名,例如,example.exe 会生成名为 example.idb 的数据库。如果输入文件没有扩展名,IDA 会将.idb 附加到输入文件名称后面,构成数据库名称,如 httpd 生成 httpd.idb。

下面简要说明可用的保存选项及其意义。

Don’t pack database(不打包数据库)。这个选项仅仅刷新对 4 个数据库组件文件所做的更改,在关闭桌面前并不创建 IDB 文件。在关闭数据库时,不建议使用这个选项。

Pack database(Store)[打包数据库(存储)]。选择 Store 选项会将 4 个数据库组件文件存到一个 IDB 文件中。之前的任何 IDB 不经确认即被覆盖。Store 选项不使用压缩。创建 IDB 文件后,4 个数据库组件文件即被删除。

Pack database(Deflate)[打包数据库(压缩)]。Deflate 选项等同于 Store 选项,其唯一的差别在于数据库组件文件被压缩到 IDB 归档文件中。

Collect garbage(收集垃圾)。如果请求垃圾收集,IDA 会在关闭数据库之前,从数据库中删除任何没有用的内存页面。在选择这个选项的同时,选择 Deflate 选项可创建尽可能小的 IDB 文件。通常,只有在磁盘空间不足时才选择这个选项。

DON’T SAVE the datebase(不保存数据库)。你可能会感到奇怪,怎么会有人不保存自己的工作呢!要知道,要想放弃你当前对数据库所做的更改(上次保存之后),使用这个选项是唯一的办法。选择这个选项时,IDA 会删除 4 个数据库组件文件,保留现有的未经修改的 IDB 文件。使用这个选项类似于在使用 IDA 时应用了撤销或还原功能。


3.4 IDA常用窗口简单介绍

函数窗口(Functions window)

左侧是函数窗口,会将程序中所有的函数显示出来

我们分析一道题目的时候一般是先从主函数开始

但是main一般不会显示出来,我们这时可以先搜索,用 Ctrl+F 快捷键

然后点击main,即可跳转到main函数里

汇编窗口(IDA View)

现在可见的是汇编窗口,展示的汇编代码,如图所示的是图形模式

我们可以按右键 选择 Text view 或者点击 空格键 进入文本模式

展示了一些地址和汇编代码

“十六进制窗口”(Hex View)

习惯讲是“十六进制窗口”,但将这个窗口称做“十六进制窗口”其实是一种误称,因为IDA十六进制窗口可以配置为显示各种格式,并可作为十六进制编辑器使用。默认情况下,十六进制窗口显示程序内容和列表的标准十六进制代码,每行显示16个字节,以及其对应的ASCII字符。和在反汇编窗口中一样,用户也可以同时打开几个十六进制窗口

导航栏

彩色的水平带是 IDA 的概况导航栏,也叫做导航带。导航带是被加载文件地址空间的线性视图。默认情况下,它会呈现二进制文件的整个地址范围。你可以右击导航带内任何位置

在导航带上,会有一个细小的当前位置指示符(默认为黄色)指向与当前反汇编窗口中显示的地址范围对应的导航带地址。将光标悬停在导航带的任何位置,IDA 会显示一个提示,指出其在二进制文件中的对应位置。

简单来说,点到哪里跳到哪里

而不同的颜色代表了不同的数据段,比如说data段,text段等

伪代码窗口(Pseudocode)

对着函数点F5即可弹出伪代码窗口

是将汇编语言,变成伪代码,即展示了一些类c代码

先简单介绍这么多窗口,其余窗口在实际用到时再介绍学习。

打开所有的函数窗口的方式

View > Open subviews > …

快捷键 / 一些操作的介绍

Shift+F12

可以打开字符串窗口(String window)

这个窗口展示了所有的字符串,我们可以在这里查找一些关键的字符串,我们也可以通过双击某一特殊字符串,弹到汇编窗口(IDA View)中该字符串对应的位置中去。

Ctrl+X(交叉引用)

我们可以通过这个操作,可以判断哪些函数引用了这个字符串或数据

点击ok,便会跳转到相应地方

G(跳转地址)

前面说过汇编窗口界面,左边是一些地址,右边是汇编代码

我们在浏览这些代码的过程中,往下往上翻页,可能找不到原来的地方了,或者有时候,你清楚地知道你想要导航的目的地址,但反汇编窗口中并没有可供双击导航的名称。这时我们就可以通过该操作跳转到相应的位置。

Alt+T(文本搜索)

IDA文本搜索相当于对反汇编列表窗口进行子字符串搜索。

它将搜索限制于仅查找完整的词,并且能够匹配反汇编行中的任何完整的词,包括操作码助记符或常量

选择Find all occurences(查找所有结果),IDA将在一个新的窗口中显示搜索结果,你可以根

据搜索条件轻松导航到任何一个匹配结果。

N(重命名)

对于一些函数名,我们可以改为方便我们理解的函数名

如果不小心改错了怎么办?

Ctrl+Z(撤回操作)

撤回到上一步

/ ( 注释操作)

在方框内添加注释,程序员必备,不多讲

我们下面用第二道题,reverse1来演示

这道题首先搜索main函数,没找到,怎么办呢?

我们用之前讲的查找字符串(shift+f12)

发现一些有用的信息

再根据我们之前讲的,定位,交叉引用,编译伪c代码,可以找到我们关键需要分析的地方

我们会发现在上述代码中,自带了一些注释,有时候会过多,可能会影响我们分析

\ (隐藏系统注释)
我们可以用这种方法隐藏干扰我们的一些自带的注释。

D (转换成数据形式)
我们在分析数据的时候,有时候需要这样做,将字符串转换成数据

A(转换成字符形式)
转换成字符串

C(转换成汇编代码)
转换成汇编代码

U (转成原始字符)
转换成最原始的状态

Shift+E (导出数据)
如果有想导出的数据,选中然后shift+e,选择你想导出的方式

便会导出

数据转化形式

我们在分析伪代码的时候,有时候要对一些数据进行类型转化

右键数据,可以产生如下选项

Hexadecimal 十六进制

Octal 八进制

Char 字符

Enum 枚举

至此,IDA一些常用的窗口与功能已经介绍完毕,未介绍的将在遇到实际应用场景时再行学习。


4 IDA反编译STM32 Hex\Bin文件成C代码

IDA是一款功能强大的反编译软件,经过摸索可将STM32的hex文件进行反汇编,操作步骤如下,首先下载IDA Pro软件,免安装。

IDA Pro下载链接:https://pan.baidu.com/s/15mlNh73Ga9zj9y3JN4kfaw 提取码:kkxi

如果文件为bin文件,可使用bin转hex工具转为hex格式,

BinToHex下载链接:https://pan.baidu.com/s/1X-ZPE1zaehf8tTEdMJtlrw 提取码:3djj


1、打开解压后目录下的idaq.exe可执行文件,点击[File]-[Open]看到如下界面。

2、打开hex文件弹出提示。

3、【Processor type】选择小端ARM,点击【set】保存。

4、按顺序点击图片中的1-2-3,设置好后点击ok关闭提示窗。

5、接下来将看到hex的文件内容,在CODE32下按d合并行。

6、右击第二行跳到程序起始处。

7、在跳转到的程序前面按c键。

8、反汇编完成,在CODE32处按F5键将生成类C伪代码,见第12步。

9、右击函数头选择【Graph view】可查看函数间调用关系。

10、查看函数调用关系。

11、在子函数中按【F5】键,生成反编译代码。

12、反编译后的CODE32函数,该函数前面是stm32中启动文件中的一些时钟初始化函数,main函数的入口在最后sub_8003076()中,双击该函数即可进入。

13、进入main函数中将看到如下一些具体功能实现代码,注意寄存器的配置都是对芯片的某个内存地址进行操作,变量也是对应某一个存储器地址。


5 使用IDA Pro、010 Editor反编译和修改so文件,轻松玩转逆向工程

当我们在做逆向工作时,总会遇到需要查看某个 so 文件的情况,甚至可能需要对其进行一些微小的修改。这时候,我们就需要来点反编译的魔法了。

当我们需要查看 so 源码时,可以使用 IDA Pro 工具对 so 文件进行反编译,然后就能阅读源码了。如果涉及到修改需求时,则可以先在 IDA Pro 工具里找到对应代码的汇编地址 ,然后使用 010 Editor 打开 so 文件,以汇编地址作为关键字进行查找,找多对应的代码,直接修改即可。

由于 010 Editor 工具里是以十六进制展示代码,所以修改时,需要特别注意,不要改错地方或者键入错误的内容,否则会导致 so 文件执行异常。

IDA Pro 下载地址:

Mac:https://www.macz.com/mac/734.html?id=NzY4OTYwJl8mMjcuMTg2LjEyNS40OQ==

Windows:https://soft.macxf.com/soft/2059.html?id=MjkzODQ%3D

010 Editor 下载地址:
https://www.sweetscape.com/download/010editor/


4.1 利用IDA Pro反编译so文件

如果你的so文件是32位的,双击ida启动软件,如果是64位的,双击ida64启动软件。

直接把 so 文件拖拽进来,点击 ok,就可以开始反编译了:

此时我们看到界面左侧有一个 Function name 的窗口,这里面会列出所有的函数名字,我们可以根据需要查看,也可以直接检索,检索的方式是点击右键,选择“Quick filter”,然后输入函数名字即可。

我搜索了一个名叫 fprintf 的函数:

然后双击第一个搜索结果,再双击下图红框圈出来的地方,即 sub_1D508:

进入 sub_1D508 后,直接按 F5 键,即可将其转化为 C 语言实现的伪代码,然后就可以正常阅读了:


4.2 利用 010 Editor 修改 so 文件

下面我们来实践下,修改代码中的某个值。比如我想修改刚刚代码中第 43 行的 return 返回值,将 2 改为 0。

修改方式是,先用鼠标选中需要修改的值 2 ,然后在页面底部查看它的地址: 1D592,我们需要记住这个地址。

此时,我们切换到 IDA View-A 界面,在里面查找到 1D592,右侧的 #2 就是我们需要修改的值。

我们同样用鼠标选中 #2,然后切换到 Hex View-1 窗口,查看其十六进制的表示:

我们看到对应的 02 20 也被选中了,02 就是我们要修改的值的十六进制表示。

我们把整个十六进制串拷贝一下,如红框圈起来所示:

然后用 010 Editor 打开 so 文件,用 ctrl+F 调出搜索框,粘贴刚刚拷贝的十六进制串,定位到对应的代码,然后将 02 改为 00

修改完后,修改后的值会显示为红色。此时记得点击 保存,然后可以关掉工具。

此时,我们使用 IDA Pro 再次打开 so 文件,找到刚刚的代码,发现 2 已经变成了 0。