I would like to decompile the Linux
- Any tool to decompile
.sofiles in MS-Windows based operating system ?
- Any tools/methods to decompile
Reverse Engineering Stack Exchange is a question and answer site for researchers and developers who explore the principles of a system through analysis of its structure, function, and operation. It only takes a minute to sign up.Sign up to join this community
As 0xea said, the
.so file are just regular executable files but packed in a dynamic library style.
I know that you asked specifically about MS-Windows tools, but I will ignore this as 0xea already replied about that. I will try to explain how to do it with UNIX tools.
A first step will be to extract the name of all the functions that are present in this library to know what it is looking like. I will use
/usr/lib/libao.so.4.0.0 (a random library I took on my system which is small enough to be taken as an example).
readelf on it to see a bit what you are on:
#> 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...]
You may notice that
readelf detected an entrypoint. In fact, it does correspond to the procedure in charge of initializing the memory to get the library properly loaded. But, it is of no use for us.
Looking at the rest of the output of
readelf -a, the dynamic symbol table (
.dynsym) is quite informative because it contains entries like this:
43: 00000000000038e0 1302 FUNC GLOBAL DEFAULT 13 ao_play@@LIBAO4_1.1.0
In fact, every function from this dynamic library is in this list and you can extract it simply like this:
#> 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
What you get here, is the names of the functions which are in the
.so plus the address of their code in the memory (first column).
Note that you can also get this information by using
objdump like this:
#> 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
It is time now to use
objdump (or a more advanced disassembler if you can get one). Given the list of functions and their address in the binary, you can simply run
objdump for each function like this:
objdump -d /usr/lib/libao.so.4.0.0 --start-address=0x3730
Note that, as
objdump use linear sweep, the disassembly may not be exact (see the following example) and, you also will have to decide by yourself when it ends.
#> 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 ...]
And, that's about all (but, get a better disassembler than
Linux shared object files are ELFs too! Any decompiler that works on "regular" ELF files will work for SO files too.
That said, you can use IDA Pro to disassemble them as usual. If you have IDA Pro licence with Hex-rays decompiler, you can use that. If you don't have Hex-rays, you can try ida-decompiler plugin to get some results. It's open source, but is far less advanced than Hex-rays.
The distinction between disassembling and decompiling is that disassembling the binary code will give you the assembly equivalent. Decompiling on the other hand implies the process of converting the raw assembly code into a higher level language (in this case C).
Decompiling assembly code is not an easy task, as many abstractions that higher level code has are lost on the assembly level. Recovering those abstractions is the difficult part.
For example, you usually lose variable names.
On the other hand, decompiling some bytecode into a higher language, like java bytecode to java, is somewhat easier because many of these abstractions are preserved in the bytecode.
Automatic decompilation of assembly code with current tools isn't perfect, it's meant to serve as a helper in revering. You can also manualy decompile assembly code to higher language by recognizing code constructs (like for loops, if statements, switches and similar).
you can use hteditor by seppel if disassembly is ok http://hte.sourceforge.net/
copy the .so file from linux machine with say samba
and feed the so file to hteditor
a sample using libc.so.6 from a damn small linux
assuming samba is up and running in vm and a shared folder in windows host is created
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 will open with hex view
f6 select elf\image f8 symbols type fo 60490 │ func │ fopen ▲
double click to view the disassembly
<.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]