sha0coder/scemu

Linux User Mode Adventure

Opened this issue · 2 comments

@sha0coder and I have weird, silly, sick, twisted idea from aarch64 Apple M1/M2 Mac to be able to "cross compile" to x86_64-apple-darwin Rust triple and then see how far we can get running Linux User Mode kernel ELF

https://en.wikipedia.org/wiki/User-mode_Linux

https://www.kernel.org/doc/html/v5.9/virt/uml/user_mode_linux.html

Obviously we don't expect this to actually work very far but... it'll be interesting to see how close we can get/where it will fail.

MacBook-Air:scemu brandon 2023-07-24 17:01:26 $ ./target/x86_64-apple-darwin/debug/scemu -f '/Users/brandon/Downloads/linux-user-mode/linux-6.2.2-uml-vmlinux'
use -vv to see the assembly code emulated, and -v to see the messages
initializing regs
loading memory maps
Loaded nsi.dll
        4 sections  base addr 0x776c0000
        created pe32 map for section `.text` at 0x776c1000 size: 5624
        created pe32 map for section `.data` at 0x776c3000 size: 16
        created pe32 map for section `.rsrc` at 0x776c4000 size: 1008
        created pe32 map for section `.reloc` at 0x776c5000 size: 88
elf64 detected.
loading map elf64 0x0 sz:0
loading map elf64.interp 0x600002a8 sz:28
loading map elf64.init.text 0x60001000 sz:104002
loading map elf64.gnu.hash 0x6001b000 sz:1228
loading map elf64.dynsym 0x6001b4d0 sz:3456
loading map elf64.dynstr 0x6001c250 sz:1336
loading map elf64.gnu.version 0x6001c788 sz:288
loading map elf64.gnu.version_r 0x6001c8a8 sz:256
loading map elf64.rela.got 0x6001c9a8 sz:48
loading map elf64.rela.bss 0x6001c9d8 sz:48
loading map elf64.rela.plt 0x6001ca08 sz:3336
loading map elf64.init 0x6001d710 sz:23
loading map elf64.plt 0x6001d730 sz:2240
loading map code 0x6001dff0 sz:3534864
loading map elf64.syscall_stub 0x6037d000 sz:246
loading map elf64.fini 0x6037d0f8 sz:9
loading map elf64.rodata 0x6037e000 sz:876192
loading map elf64.eh_frame_hdr 0x60453ea0 sz:149524
loading map elf64__ksymtab 0x604786b8 sz:74448
loading map elf64__ksymtab_gpl 0x6048a988 sz:42168
loading map elf64__ksymtab_strings 0x60494e40 sz:86019
loading map elf64__param 0x604a9e48 sz:2200
loading map elf64__modver 0x604aa6e0 sz:72
loading map elf64.notes 0x604aa728 sz:116
loading map elf64__ex_table 0x604ab000 sz:48
loading map elf64.uml.setup.init 0x604ab030 sz:240
loading map elf64.uml.help.init 0x604ab120 sz:184
loading map elf64.uml.postsetup.init 0x604ab1d8 sz:8
loading map elf64.init.setup 0x604ab1e0 sz:2256
loading map elf64.data..percpu 0x604ac000 sz:0
loading map elf64.initcall.init 0x604ac000 sz:1808
loading map elf64.con_initcall.init 0x604ac710 sz:8
loading map elf64.uml.exitcall 0x604ac718 sz:72
loading map elf64.altinstructions 0x604ac760 sz:72
loading map elf64.altinstr_replacement 0x604ac7a8 sz:15
loading map elf64.init_array 0x604ac7b8 sz:8
loading map elf64init.data 0x604ad000 sz:46400
loading map elf64.data 0x604b8540 sz:309248
loading map elf64.eh_frame 0x60503d40 sz:652764
loading map elf64.dynamic 0x605a3320 sz:496
loading map elf64.got 0x605a3510 sz:1152
loading map elf64.bss 0x605a39c0 sz:170964
loading map elf64.debug_aranges 0x0 sz:56096
loading map elf64.debug_info 0x0 sz:49673760
loading map elf64.debug_abbrev 0x0 sz:1727486
loading map elf64.debug_line 0x0 sz:6710949
loading map elf64.debug_str 0x0 sz:1390110
loading map elf64.debug_loc 0x0 sz:13190828
loading map elf64.debug_ranges 0x0 sz:3700832
loading map elf64.comment 0x0 sz:39
loading map elf64.symtab 0x0 sz:1013112
loading map elf64.strtab 0x0 sz:758203
loading map elf64.shstrtab 0x0 sz:552
thread 'main' panicked at 'range start index 1610729190 out of range for slice of length 84138344', /Users/brandon/.cargo/registry/src/index.crates.io-6f17d22bba15001f/libscemu-0.12.9/src/emu/elf64.rs:185:43
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
MacBook-Air:scemu brandon 2023-07-24 17:01:28 $ 

UML emulation, interesting, good opportunity to improve algorithms.

uml is dynamic-linked which is not supported for now, one option is compile it statically.
For emulating UML is necessary to implement dynamic-linking and crafting the GOT I'm working on it.
It's like the IAT binding of windows but the linux relocations.

Ok the strtab sometimes is vaddr instead of file offset, fixed.

~/s/scemu ❯❯❯ target/release/scemu -f '/home/sha0/Downloads/Telegram Desktop/uml/linux-user-mode/linux-6.2.2-uml-vmlinux' -6 -vv -c 11
initializing regs
loading memory maps
elf64 detected.
loading map elf64 0x0 sz:0
loading map elf64.interp 0x600002a8 sz:28
loading map elf64.init.text 0x60001000 sz:104002
loading map elf64.gnu.hash 0x6001b000 sz:1228
loading map elf64.dynsym 0x6001b4d0 sz:3456
loading map elf64.dynstr 0x6001c250 sz:1336
loading map elf64.gnu.version 0x6001c788 sz:288
loading map elf64.gnu.version_r 0x6001c8a8 sz:256
loading map elf64.rela.got 0x6001c9a8 sz:48
loading map elf64.rela.bss 0x6001c9d8 sz:48
loading map elf64.rela.plt 0x6001ca08 sz:3336
loading map elf64.init 0x6001d710 sz:23
loading map elf64.plt 0x6001d730 sz:2240
loading map code 0x6001dff0 sz:3534864
loading map elf64.syscall_stub 0x6037d000 sz:246
loading map elf64.fini 0x6037d0f8 sz:9
loading map elf64.rodata 0x6037e000 sz:876192
loading map elf64.eh_frame_hdr 0x60453ea0 sz:149524
loading map elf64__ksymtab 0x604786b8 sz:74448
loading map elf64__ksymtab_gpl 0x6048a988 sz:42168
loading map elf64__ksymtab_strings 0x60494e40 sz:86019
loading map elf64__param 0x604a9e48 sz:2200
loading map elf64__modver 0x604aa6e0 sz:72
loading map elf64.notes 0x604aa728 sz:116
loading map elf64__ex_table 0x604ab000 sz:48
loading map elf64.uml.setup.init 0x604ab030 sz:240
loading map elf64.uml.help.init 0x604ab120 sz:184
loading map elf64.uml.postsetup.init 0x604ab1d8 sz:8
loading map elf64.init.setup 0x604ab1e0 sz:2256
loading map elf64.data..percpu 0x604ac000 sz:0
loading map elf64.initcall.init 0x604ac000 sz:1808
loading map elf64.con_initcall.init 0x604ac710 sz:8
loading map elf64.uml.exitcall 0x604ac718 sz:72
loading map elf64.altinstructions 0x604ac760 sz:72
loading map elf64.altinstr_replacement 0x604ac7a8 sz:15
loading map elf64.init_array 0x604ac7b8 sz:8
loading map elf64init.data 0x604ad000 sz:46400
loading map elf64.data 0x604b8540 sz:309248
loading map elf64.eh_frame 0x60503d40 sz:652764
loading map elf64.dynamic 0x605a3320 sz:496
loading map elf64.got 0x605a3510 sz:1152
loading map elf64.bss 0x605a39c0 sz:170964
loading map elf64.debug_aranges 0x0 sz:56096
loading map elf64.debug_info 0x0 sz:49673760
loading map elf64.debug_abbrev 0x0 sz:1727486
loading map elf64.debug_line 0x0 sz:6710949
loading map elf64.debug_str 0x0 sz:1390110
loading map elf64.debug_loc 0x0 sz:13190828
loading map elf64.debug_ranges 0x0 sz:3700832
loading map elf64.comment 0x0 sz:39
loading map elf64.symtab 0x0 sz:1013112
loading map elf64.strtab 0x0 sz:758203
loading map elf64.shstrtab 0x0 sz:552
lib: libutil.so.1
lib: librt.so.1
lib: libpthread.so.0
lib: libc.so.6
dynamic library libutil.so.1
loading map libutil.so.1 0x0 sz:0
loading map libutil.so.1.note.gnu.build-id 0x238 sz:36
loading map libutil.so.1.note.ABI-tag 0x25c sz:32
loading map libutil.so.1.gnu.hash 0x280 sz:92
loading map libutil.so.1.dynsym 0x2e0 sz:1008
loading map libutil.so.1.dynstr 0x6d0 sz:438
loading map libutil.so.1.gnu.version 0x886 sz:84
loading map libutil.so.1.gnu.version_d 0x8e0 sz:56
loading map libutil.so.1.gnu.version_r 0x918 sz:64
loading map libutil.so.1.rela.dyn 0x958 sz:192
loading map libutil.so.1.rela.plt 0xa18 sz:696
loading map libutil.so.1.init 0x1000 sz:23
loading map libutil.so.1.plt 0x1020 sz:480
loading map libutil.so.1.plt.got 0x1200 sz:8
loading map libutil.so.1.text 0x1210 sz:2440
loading map libutil.so.1.fini 0x1b98 sz:9
loading map libutil.so.1.rodata 0x2000 sz:34
loading map libutil.so.1.eh_frame_hdr 0x2024 sz:92
loading map libutil.so.1.eh_frame 0x2080 sz:592
loading map libutil.so.1.hash 0x22d0 sz:472
loading map libutil.so.1.init_array 0x3db8 sz:8
loading map libutil.so.1.fini_array 0x3dc0 sz:8
loading map libutil.so.1.dynamic 0x3dc8 sz:528
loading map libutil.so.1.got 0x3fd8 sz:40
loading map libutil.so.1.got.plt 0x4000 sz:256
loading map libutil.so.1.data 0x4100 sz:8
loading map libutil.so.1.bss 0x4108 sz:8
loading map libutil.so.1.gnu_debuglink 0x0 sz:52
loading map libutil.so.1.shstrtab 0x0 sz:260
dynamic library librt.so.1
loading map librt.so.1 0x0 sz:0
loading map librt.so.1.note.gnu.build-id 0x238 sz:36
loading map librt.so.1.note.ABI-tag 0x25c sz:32
loading map librt.so.1.gnu.hash 0x280 sz:560
loading map librt.so.1.dynsym 0x4b0 sz:2592
loading map librt.so.1.dynstr 0xed0 sz:1365
loading map librt.so.1.gnu.version 0x1426 sz:216
loading map librt.so.1.gnu.version_d 0x1500 sz:200
loading map librt.so.1.gnu.version_r 0x15c8 sz:160
loading map librt.so.1.rela.dyn 0x1668 sz:240
loading map librt.so.1.rela.plt 0x1758 sz:1320
loading map librt.so.1.init 0x2000 sz:23
loading map librt.so.1.plt 0x2020 sz:896
loading map librt.so.1.plt.got 0x23a0 sz:8
loading map librt.so.1.text 0x23b0 sz:12796
loading map librt.so.1__libc_freeres_fn 0x55b0 sz:61
loading map librt.so.1.fini 0x55f0 sz:9
loading map librt.so.1.rodata 0x6000 sz:855
loading map librt.so.1.eh_frame_hdr 0x6358 sz:556
loading map librt.so.1.eh_frame 0x6588 sz:2560
loading map librt.so.1.gcc_except_table 0x6f88 sz:23
loading map librt.so.1.hash 0x6fa0 sz:1244
loading map librt.so.1.init_array 0x8d90 sz:8
loading map librt.so.1.fini_array 0x8d98 sz:8
loading map librt.so.1__libc_subfreeres 0x8da0 sz:8
loading map librt.so.1.dynamic 0x8da8 sz:560
loading map librt.so.1.got 0x8fd8 sz:40
loading map librt.so.1.got.plt 0x9000 sz:464
loading map librt.so.1.data 0x91e0 sz:140
loading map librt.so.1.bss 0x9280 sz:2400
loading map librt.so.1.gnu_debuglink 0x0 sz:52
loading map librt.so.1.shstrtab 0x0 sz:314
dynamic library libpthread.so.0
loading map libpthread.so.0 0x0 sz:0
loading map libpthread.so.0.note.gnu.build-id 0x2a8 sz:36
loading map libpthread.so.0.note.ABI-tag 0x2cc sz:32
loading map libpthread.so.0.gnu.hash 0x2f0 sz:3372
loading map libpthread.so.0.dynsym 0x1020 sz:8664
loading map libpthread.so.0.dynstr 0x31f8 sz:5393
loading map libpthread.so.0.gnu.version 0x470a sz:722
loading map libpthread.so.0.gnu.version_d 0x49e0 sz:488
loading map libpthread.so.0.gnu.version_r 0x4bc8 sz:160
loading map libpthread.so.0.rela.dyn 0x4c68 sz:1416
loading map libpthread.so.0.rela.plt 0x51f0 sz:2040
loading map libpthread.so.0.init 0x6000 sz:14
loading map libpthread.so.0.plt 0x6010 sz:1376
loading map libpthread.so.0.plt.got 0x6570 sz:8
loading map libpthread.so.0.text 0x6580 sz:60193
loading map libpthread.so.0.fini 0x150a4 sz:9
loading map libpthread.so.0.rodata 0x16000 sz:4598
loading map libpthread.so.0.interp 0x17200 sz:28
loading map libpthread.so.0.eh_frame_hdr 0x1721c sz:2388
loading map libpthread.so.0.eh_frame 0x17b70 sz:11248
loading map libpthread.so.0.hash 0x1a760 sz:4212
loading map libpthread.so.0.init_array 0x1cc08 sz:16
loading map libpthread.so.0.fini_array 0x1cc18 sz:8
loading map libpthread.so.0.data.rel.ro 0x1cc20 sz:336
loading map libpthread.so.0.dynamic 0x1cd70 sz:560
loading map libpthread.so.0.got 0x1cfa0 sz:72
loading map libpthread.so.0.got.plt 0x1d000 sz:704
loading map libpthread.so.0.data 0x1d2c0 sz:80
loading map libpthread.so.0.bss 0x1d320 sz:16720
loading map libpthread.so.0.gnu.warning.pthread_attr_getstackaddr 0x0 sz:82
loading map libpthread.so.0.gnu.warning.pthread_attr_setstackaddr 0x0 sz:82
loading map libpthread.so.0.gnu_debuglink 0x0 sz:52
loading map libpthread.so.0.symtab 0x0 sz:17952
loading map libpthread.so.0.strtab 0x0 sz:13229
loading map libpthread.so.0.shstrtab 0x0 sz:375
dynamic library libc.so.6
loading map libc.so.6 0x0 sz:0
loading map libc.so.6.note.gnu.build-id 0x2e0 sz:36
loading map libc.so.6.note.ABI-tag 0x304 sz:32
loading map libc.so.6.gnu.hash 0x328 sz:15540
loading map libc.so.6.dynsym 0x3fe0 sz:56880
loading map libc.so.6.dynstr 0x11e10 sz:24769
loading map libc.so.6.gnu.version 0x17ed2 sz:4740
loading map libc.so.6.gnu.version_d 0x19158 sz:1136
loading map libc.so.6.gnu.version_r 0x195c8 sz:48
loading map libc.so.6.rela.dyn 0x195f8 sz:31272
loading map libc.so.6.rela.plt 0x21020 sz:1128
loading map libc.so.6.plt 0x22000 sz:768
loading map libc.so.6.plt.got 0x22300 sz:32
loading map libc.so.6.text 0x22320 sz:1408281
loading map libc.so.6__libc_freeres_fn 0x17a040 sz:3660
loading map libc.so.6.rodata 0x17b000 sz:149064
loading map libc.so.6.interp 0x19f650 sz:28
loading map libc.so.6.eh_frame_hdr 0x19f66c sz:25676
loading map libc.so.6.eh_frame 0x1a5ab8 sz:131624
loading map libc.so.6.gcc_except_table 0x1c5ce0 sz:1051
loading map libc.so.6.hash 0x1c6100 sz:13556
loading map libc.so.6.tdata 0x1ca768 sz:16
loading map libc.so.6.tbss 0x1ca778 sz:128
loading map libc.so.6.init_array 0x1ca778 sz:16
loading map libc.so.6__libc_subfreeres 0x1ca788 sz:240
loading map libc.so.6__libc_atexit 0x1ca878 sz:8
loading map libc.so.6__libc_IO_vtables 0x1ca880 sz:3432
loading map libc.so.6.data.rel.ro 0x1cb600 sz:9600
loading map libc.so.6.dynamic 0x1cdb80 sz:480
loading map libc.so.6.got 0x1cdd60 sz:664
loading map libc.so.6.got.plt 0x1ce000 sz:400
loading map libc.so.6.data 0x1ce1a0 sz:5632
loading map libc.so.6.bss 0x1cf7a0 sz:16096
loading map libc.so.6.gnu.warning.sigstack 0x0 sz:77
loading map libc.so.6.gnu.warning.sigreturn 0x0 sz:50
loading map libc.so.6.gnu.warning.siggetmask 0x0 sz:57
loading map libc.so.6.gnu.warning.tmpnam 0x0 sz:55
loading map libc.so.6.gnu.warning.tmpnam_r 0x0 sz:57
loading map libc.so.6.gnu.warning.tempnam 0x0 sz:56
loading map libc.so.6.gnu.warning.sys_errlist 0x0 sz:68
loading map libc.so.6.gnu.warning.sys_nerr 0x0 sz:65
loading map libc.so.6.gnu.warning.gets 0x0 sz:57
loading map libc.so.6.gnu.warning.getpw 0x0 sz:58
loading map libc.so.6.gnu.warning.re_max_failures 0x0 sz:61
loading map libc.so.6.gnu.warning.lchmod 0x0 sz:47
loading map libc.so.6.gnu.warning.getwd 0x0 sz:122
loading map libc.so.6.gnu.warning.sstk 0x0 sz:45
loading map libc.so.6.gnu.warning.revoke 0x0 sz:47
loading map libc.so.6.gnu.warning.mktemp 0x0 sz:68
loading map libc.so.6.gnu.warning.gtty 0x0 sz:45
loading map libc.so.6.gnu.warning.stty 0x0 sz:45
loading map libc.so.6.gnu.warning.chflags 0x0 sz:48
loading map libc.so.6.gnu.warning.fchflags 0x0 sz:49
loading map libc.so.6.gnu.warning.__compat_bdflush 0x0 sz:57
loading map libc.so.6.gnu.warning.__gets_chk 0x0 sz:57
loading map libc.so.6.gnu.warning.inet6_option_space 0x0 sz:60
loading map libc.so.6.gnu.warning.inet6_option_init 0x0 sz:59
loading map libc.so.6.gnu.warning.inet6_option_append 0x0 sz:61
loading map libc.so.6.gnu.warning.inet6_option_alloc 0x0 sz:60
loading map libc.so.6.gnu.warning.inet6_option_next 0x0 sz:59
loading map libc.so.6.gnu.warning.inet6_option_find 0x0 sz:59
loading map libc.so.6.gnu.warning.setlogin 0x0 sz:49
loading map libc.so.6.gnu_debuglink 0x0 sz:52
loading map libc.so.6.shstrtab 0x0 sz:1043
 ----- emulation -----
1 0x6001dff0: xor   ebp,ebp
2 0x6001dff2: mov   r9,rdx
3 0x6001dff5: pop   rsi ;0x1 
4 0x6001dff6: mov   rdx,rsp
5 0x6001dff9: and   rsp,0FFFFFFFFFFFFFFF0h
6 0x6001dffd: push  rax ;0x0 
7 0x6001dffe: push  rsp ;0x7fffffffe268 
8 0x6001dfff: mov   r8,6036F8B0h
9 0x6001e006: mov   rcx,6036F850h
10 0x6001e00d: mov   rdi,60004436h
-------
11 0x6001e014: call  qword ptr [605A3988h]
--- console ---
=>mn
address=>0x605A3988
map: elf64.got 0x605a3510-0x605a3990 (1152)

GOT is not yet crafted, i have to learn more to implement it.