.so
文件。是否可以在基于MS-Windows的操作系统中反编译
.so
文件的任何工具? br /> #1 楼
正如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 q4312078qx8,%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
更好的反汇编程序!)。评论
很好的解释:)
– BlueBerry-Vignesh4303
13年8月23日在4:33
#2 楼
Linux共享对象文件也是ELF!任何适用于“常规” ELF文件的反编译器也适用于SO文件。也就是说,您可以像往常一样使用IDA Pro拆卸它们。如果您拥有带有Hex-rays反编译器的IDA Pro许可证,则可以使用它。如果您没有Hex-ray,可以尝试使用ida-decompiler插件来获得一些结果。它是开源的,但远没有Hex-ray先进。
反汇编和反编译之间的区别在于,反汇编二进制代码将使您获得等效的汇编代码。另一方面,反编译意味着将原始汇编代码转换为更高级别的语言(在本例中为C)的过程。
反汇编代码并不是一件容易的事,因为许多抽象需要更高级别的代码在装配级别丢失了。恢复这些抽象是困难的部分。
例如,您通常会丢失变量名。
另一方面,将某些字节码反编译为高级语言(如将Java字节码转换为Java)则较为容易,因为其中许多抽象都保留在字节码中。
使用当前工具对汇编代码进行自动反汇编并不是完美的,它可以作为崇敬的助手。您还可以通过识别代码构造(例如用于循环,if语句,开关等)来手动将汇编代码反编译为高级语言。
#3 楼
如果可以反汇编,则可以通过seppel使用hteditor。 >然后将so文件提供给hteditor从该死的小型linux使用libc.so.6的示例
假设samba在vm中已启动并正在运行,并且在创建Windows主机
说
c:\sharedwithvm
from the linux machine
in the windows machine
C:\>cd sharedwithvm
C:\sharedwithvm>dir /b
libc.so.6
C:\sharedwithvm>f:\hteditor22\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]
评论
区分SO文件和常规ELF的任何特殊原因?