我想反编译Linux.so
文件。
- 任何
.so
在基于 MS-Windows 的操作系统中反编译文件的工具? - 任何反编译
.so
文件的工具/方法?
我想反编译Linux.so
文件。
.so
在基于 MS-Windows 的操作系统中反编译文件的工具?.so
文件的工具/方法?正如 0xea 所说,该.so
文件只是常规的可执行文件,但以动态库样式打包。
我知道您专门询问了 MS-Windows 工具,但我将忽略这一点,因为 0xea 已经对此做出了答复。我将尝试解释如何使用 UNIX 工具来做到这一点。
第一步是提取此库中存在的所有函数的名称,以了解它的外观。我将使用/usr/lib/libao.so.4.0.0
(我在我的系统上使用的一个随机库,它足够小,可以作为一个例子)。
首先,运行readelf
它看看你在做什么:
#> readelf -a /usr/lib/libao.so.4.0.0
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: DYN (Shared object file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x1fb0
Start of program headers: 64 (bytes into file)
Start of section headers: 35392 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 56 (bytes)
Number of program headers: 6
Size of section headers: 64 (bytes)
Number of section headers: 29
Section header string table index: 28
[...lots of tables and other information...]
您可能会注意到readelf
检测到一个入口点。事实上,它确实对应于负责初始化内存以正确加载库的过程。但是,这对我们没有用。
查看 的其余输出readelf -a
,动态符号表 ( .dynsym
) 非常有用,因为它包含如下条目:
43: 00000000000038e0 1302 FUNC GLOBAL DEFAULT 13 ao_play@@LIBAO4_1.1.0
事实上,这个动态库中的每个函数都在这个列表中,你可以像这样简单地提取它:
#> readelf -a /usr/lib/libao.so.4.0.0 | grep LIBAO4_1.1.0 | grep FUNC
43: 00000000000038e0 1302 FUNC GLOBAL DEFAULT 13 ao_play@@LIBAO4_1.1.0
44: 0000000000003670 177 FUNC GLOBAL DEFAULT 13 ao_append_option@@LIBAO4_1.1.0
45: 00000000000040e0 70 FUNC GLOBAL DEFAULT 13 ao_driver_info@@LIBAO4_1.1.0
46: 0000000000002d40 2349 FUNC GLOBAL DEFAULT 13 ao_initialize@@LIBAO4_1.1.0
48: 0000000000003ef0 484 FUNC GLOBAL DEFAULT 13 ao_default_driver_id@@LIBAO4_1.1.0
49: 0000000000003e00 144 FUNC GLOBAL DEFAULT 13 ao_close@@LIBAO4_1.1.0
50: 0000000000005070 239 FUNC GLOBAL DEFAULT 13 ao_open_file@@LIBAO4_1.1.0
51: 0000000000005160 7 FUNC GLOBAL DEFAULT 13 ao_open_live@@LIBAO4_1.1.0
52: 0000000000003730 18 FUNC GLOBAL DEFAULT 13 ao_append_global_option@@LIBAO4_1.1.0
53: 0000000000003790 326 FUNC GLOBAL DEFAULT 13 ao_shutdown@@LIBAO4_1.1.0
54: 0000000000004130 16 FUNC GLOBAL DEFAULT 13 ao_driver_info_list@@LIBAO4_1.1.0
55: 0000000000003750 60 FUNC GLOBAL DEFAULT 13 ao_free_options@@LIBAO4_1.1.0
56: 0000000000004140 13 FUNC GLOBAL DEFAULT 13 ao_is_big_endian@@LIBAO4_1.1.0
57: 0000000000003e90 92 FUNC GLOBAL DEFAULT 13 ao_driver_id@@LIBAO4_1.1.0
你在这里得到的是函数的名称,这些函数的名称.so
加上它们在内存中的代码地址(第一列)。
请注意,您还可以使用以下方法获取此信息objdump
:
#> objdump -T /usr/lib/libao.so.4.0.0 | grep LIBAO4_1.1.0 | grep DF
00000000000038e0 g DF .text 0000000000000516 LIBAO4_1.1.0 ao_play
0000000000003670 g DF .text 00000000000000b1 LIBAO4_1.1.0 ao_append_option
00000000000040e0 g DF .text 0000000000000046 LIBAO4_1.1.0 ao_driver_info
0000000000002d40 g DF .text 000000000000092d LIBAO4_1.1.0 ao_initialize
0000000000003ef0 g DF .text 00000000000001e4 LIBAO4_1.1.0 ao_default_driver_id
0000000000003e00 g DF .text 0000000000000090 LIBAO4_1.1.0 ao_close
0000000000005070 g DF .text 00000000000000ef LIBAO4_1.1.0 ao_open_file
0000000000005160 g DF .text 0000000000000007 LIBAO4_1.1.0 ao_open_live
0000000000003730 g DF .text 0000000000000012 LIBAO4_1.1.0 ao_append_global_option
0000000000003790 g DF .text 0000000000000146 LIBAO4_1.1.0 ao_shutdown
0000000000004130 g DF .text 0000000000000010 LIBAO4_1.1.0 ao_driver_info_list
0000000000003750 g DF .text 000000000000003c LIBAO4_1.1.0 ao_free_options
0000000000004140 g DF .text 000000000000000d LIBAO4_1.1.0 ao_is_big_endian
0000000000003e90 g DF .text 000000000000005c LIBAO4_1.1.0 ao_driver_id
现在是使用的时候了objdump
(或者如果你能得到一个更高级的反汇编器)。给定函数列表及其在二进制文件中的地址,您可以简单地objdump
为每个函数运行,如下所示:
objdump -d /usr/lib/libao.so.4.0.0 --start-address=0x3730
请注意,由于objdump
使用线性扫描,拆卸可能不准确(请参见以下示例),并且您还必须自己决定何时结束。
#> objdump -d /usr/lib/libao.so.4.0.0 --start-address=0x3730
/usr/lib/libao.so.4.0.0: file format elf64-x86-64
Disassembly of section .text:
0000000000003730 <ao_append_global_option>:
3730: 48 89 f2 mov %rsi,%rdx
3733: 48 89 fe mov %rdi,%rsi
3736: 48 8d 3d cb 52 20 00 lea 0x2052cb(%rip),%rdi
373d: e9 4e e6 ff ff jmpq 1d90 <ao_append_option@plt>
3742: 66 66 66 66 66 2e 0f data32 data32 data32 data32 nopw %cs:0x0(%rax,%rax,1)
3749: 1f 84 00 00 00 00 00
0000000000003750 <ao_free_options>:
3750: 55 push %rbp
3751: 53 push %rbx
3752: 48 89 fb mov %rdi,%rbx
3755: 48 83 ec 08 sub $0x8,%rsp
3759: 48 85 ff test %rdi,%rdi
375c: 74 27 je 3785 <ao_free_options+0x35>
375e: 66 90 xchg %ax,%ax
3760: 48 8b 3b mov (%rbx),%rdi
3763: 48 8b 6b 10 mov 0x10(%rbx),%rbp
3767: e8 c4 e5 ff ff callq 1d30 <free@plt>
376c: 48 8b 7b 08 mov 0x8(%rbx),%rdi
3770: e8 bb e5 ff ff callq 1d30 <free@plt>
3775: 48 89 df mov %rbx,%rdi
3778: 48 89 eb mov %rbp,%rbx
377b: e8 b0 e5 ff ff callq 1d30 <free@plt>
[... clip ...]
而且,这就是全部(但是,获得比objdump
!更好的反汇编程序)。
Linux 共享对象文件也是 ELF!任何适用于“常规”ELF 文件的反编译器也适用于 SO 文件。
也就是说,您可以像往常一样使用 IDA Pro 来拆卸它们。如果您拥有带有 Hex-rays 反编译器的 IDA Pro 许可证,则可以使用它。如果你没有 Hex-rays,你可以试试ida-decompiler插件来得到一些结果。它是开源的,但远不如 Hex-rays 先进。
反汇编和反编译之间的区别在于,反汇编二进制代码将为您提供等效的汇编代码。另一方面,反编译意味着将原始汇编代码转换为高级语言(在本例中为 C)的过程。
反编译汇编代码并非易事,因为在汇编级别上丢失了更高级别代码的许多抽象。恢复这些抽象是困难的部分。
例如,您通常会丢失变量名称。
另一方面,将一些字节码反编译成更高级的语言,比如将 java 字节码反编译为 java,稍微容易一些,因为这些抽象中的许多都保留在字节码中。
用目前的工具自动反编译汇编代码并不完美,它的目的是作为敬仰的帮手。您还可以通过识别代码结构(如 for 循环、if 语句、开关等)手动将汇编代码反编译为高级语言。
如果反汇编没问题,您可以通过 seppel 使用 hteditor http://hte.sourceforge.net/
使用 samba 从 linux 机器复制 .so 文件
并将 so 文件提供给 hteditor
使用来自该死的小型 linux 的 libc.so.6 的示例
假设 samba 在 vm 中启动并运行,并且在 Windows 主机中创建了一个共享文件夹说 c:\sharedwithvm
from the linux machine
cp ../..../lib/libc.so.6 /mnt//sharedwithvm
in the windows machine
C:\>cd sharedwithvm
C:\sharedwithvm>dir /b
libc.so.6
C:\sharedwithvm>f:\hteditor\2022\ht-2.0.22-win32.exe libc.so.6
hteditor 将以十六进制视图打开
f6 select elf\image
f8 symbols type fo
60490 │ func │ fopen ▲
双击查看拆解
<.text> @00060490 push ebp
fopen+0
..... ! ;********************************************************
..... ! ; function fopen (global)
..... ! ;********************************************************
..... ! fopen: ;xref c189a7 c262da c74722
..... ! ;xref c93c74 c94cd5 cd23c4
..... ! ;xref cd3617 cd37c6 cd3a1a
..... ! ;xref cd7061 cd717f cd729f
..... ! ;xref ce50e3 ce67e6 ce7581
..... ! ;xref cef095 cf0302
..... ! push ebp
60491 ! mov ebp, esp
60493 ! sub esp, 18h
60496 ! mov [ebp-4], ebx
60499 ! mov eax, [ebp+0ch]
6049c ! call sub_15c8d
604a1 ! add ebx, offset_cab57
604a7 ! mov dword ptr [esp+8], 1
604af ! mov [esp+4], eax
604b3 ! mov eax, [ebp+8]