foundryzero / llef

LLEF is a plugin for LLDB to make it more useful for RE and VR

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Fix x86-ELF debugging support from x86_64 FreeBSD

therealdreg opened this issue · comments

commented

image

image

its not working well for a 32 bit process :\

  1. registers should be: eax, ebx...
  2. stack should be 4 byte align
  3. disasm is wrong (64 bit), sould be i386

Also worth mentioning that for a program in pure assembly, disassembly is not ideal. It would be ideal to be able to configure the number of instructions and whether I want to see the opcodes...

Something like:

image


btw, @stephen-f0 Thanks for doing this project... LLDB has always been a pain in the *ss...

Hi @therealdreg,

Thanks for raising the issue. That's an interesting edge case and great to hear you are (attempting) to use LLEF!

I have just clarified that debugging i386 targets on x86_64 Linux hosts works as expected (all the LLEF context is in i386) So I believe this issue is specific to *BSD hosts. In slower time I'll setup a FreeBSD host for myself and give it a good poke. I'm fairly confident however this is likely to be an actual LLDB issue as we rely entirely on their API for architecture selection and register retrieval.

What happens is you run the native LLDB command register read on that same binary do you get back i386 registers or x64?

As for customising the disassembly output I've just completed a feature currently in PR #29 which adds in support for settings - this forms some of the ground work towards a longer term goal of having a much more user-customisable experience.

commented
lldb) register read
General Purpose Registers:
       rax = 0x0000000000000000
       rbx = 0x00000000ffffdff0
       rcx = 0x0000000000000000
       rdx = 0x0000000000000000
       rdi = 0x0000000000000000
       rsi = 0x0000000000000000
       rbp = 0x0000000000000000
       rsp = 0x00000000ffffd674
        r8 = 0x0000000000000000
        r9 = 0x0000000000000000
       r10 = 0x0000000000000000
       r11 = 0x0000000000000000
       r12 = 0x0000000000000000
       r13 = 0x0000000000000000
       r14 = 0x0000000000000000
       r15 = 0x0000000000000000
       rip = 0x0000000008048089
    rflags = 0x0000000000000202
        cs = 0x0000000000000033
        fs = 0x0013
        gs = 0x001b
        ss = 0x000000000000003b
        ds = 0x003b
        es = 0x003b
commented

here my dirty tricks for lldb:

image

https://github.com/therealdreg/lldb_reversing

Awesome thanks - Looks like LLDB is doing it wrong hence why LLEF is doing it wrong :)

I expect we'll be able to support a "force architecture" mode or something. Come to think of it I believe I've seen some poor architecture selection for certain MIPS targets as well that this might resolve.

commented

Awesome, thx for your support. I linked this project in my repo :D

I got setup with a FreeBSD instance and could replicate your exact issue. Ideally this should be fixed in LLDB but it seems like LLDB on FreeBSD is still quite fragile anyway. I've put up a quick WIP PoC which allows forcing architectures on this branch:

https://github.com/foundryzero/llef/tree/feature/force-arch

Once you've launched you can use the new force_arch setting to force it to i386:

llefsettings set force_arch i386

In the current implementation I've only fixed up the register output - the stack etc are still using whatever LLDB is providing (i.e. x86_64). If you get a moment please give it a try and let us know your thoughts.

commented

The register is wrong, you should show "rip / pc"

The stack and disas is wrong

image

we need force the 32 bit code, something like:

di -b -c 10 -A i386 -s $pc
  • Keep in mind that if we don't force the number of lines in a pure ASM program, we will only be able to see one instruction and this is not usable... (-c 10)
  • Additionally, showing the opcodes in the instructions is essential for me.

And for stack something like:

memory read -s 4 -c 10 -l 1 -f x $sp

helloworld.asm

section .data
    msg     db      'Hello Dreg from 32 bit code FreeBSD!!', 0Ah
    hbytes	equ	$-msg

section .text
    global _start

_start:
    ; sys_write
    push dword hbytes
    push dword msg
    push dword 1
    mov eax, 4
    push eax ; garbage... freebsd call convention...
    int 0x80

    ; sys_exit
    push 0
    mov eax, 1
    push eax ; garbage...
    int 0x80

build.sh

#!/usr/bin/env bash
rm -rf helloworld hellworld.o && nasm -f elf helloworld.asm && ld -m elf_i386_fbsd -o helloworld -s helloworld.o

@stephen-f0 comment updated! take a look :D