Saturday, 24 July 2021

Linux virtual machine emulator - for assembly programming

http://3zanders.co.uk/2017/10/13/writing-a-bootloader/

Uses NASM and QEMU to write a bootloader.



https://qemu-project.gitlab.io/qemu/system/gdb.html

https://www.bitdegree.org/learn/gdb-debugger#running-the-program-slowly

To use Qemu with GDB use -s and -S. This set it listening at port 1234 and halt the VM until gdb connects.

qemu-system-i386 -s -S -drive file=./boot.bin,cache=none,format=raw

In GDB

connect to qemu

target remote localhost:1234 

  1. Use info reg to display all the CPU registers.
  2. Use x/10i $eip to display the code at the PC position.
  3. Use set architecture i8086 to dump 16 bit code. 
  4. set tdesc filename target.xml
  5. x/10i $cs*16+$eip to dump the next 10 lines of code at the PC position
  6. stepi

https://visualgdb.com/gdbreference/commands/x

To see the disassembled line

gdb) show disassemble-next-line
Debugger's willingness to use disassemble-next-line is off.
(gdb) set disassemble-next-line on
then si



Machine boots

info reg - show registers

cs = 0xf000 (1048560) 

ip = 0xfff0

pc = (cs * 16) + ip

      = F0000 + FFF0

       = FFFF0 (1048560)

This is 16 bytes from BIOS top (at 1048575 or 0xFFFFF)

https://www.programmersought.com/article/33296090366/



Inspecting the program at FFFF0:

x/16b 0xffff0

xffff0: 0xea 0x5b 0xe0 0x00 0xf0   0x30 0x36 0x2f

0xffff8: 0x32 0x33 0x2f 0x39 0x39 0x00 0xfc 0x00

or looking at the instructions
x/2i 0xffff0
0xffff0: ljmp   $0x3630,$0xf000e05b

which shows that 0xEA is JMP
https://www.felixcloutier.com/x86/jmp

However the interetation is a bug because the VM is running in real mode and GDB does not handle it properly, even though we set architecture i8086
https://stackoverflow.com/questions/59078290/memory-addressing-in-x86-real-mode?noredirect=1&lq=1

So we must download the target 

set tdesc filename target.xml

Now running it again gives

   0xffff0: ljmp $0xf000,$0xe05b 0xffff5: xor %dh,0x322f 0xffff9: xor (%bx),%bp 0xffffb: cmp %di,(%bx,%di) 0xffffd: add %bh,%ah 0xfffff: add %al,(%bx,%si) 0x100001: add %al,(%bx,%si) 0x100003: add %al,(%bx,%si) 0x100005: add %al,(%bx,%si) 0x100007: add %al,(%bx,%si)

Now gives us

(0xf000 x 16) + 0xe05b = F0000 + 0xe05b = FE05B = (1040475)


This jumps us to FE05B
This is 1FA4 (8100) bytes from BIOS top (at 1048575 or 0xFFFFF)

Run stepi (execute instruction)

  0xfe05b: cmpl   $0x0,%cs:0x62c8

   0xfe062: jne    0xfd0b0

   0xfe066: xor    %dx,%dx

   0xfe068: mov    %dx,%ss

   0xfe06a: mov    $0x7000,%esp

   0xfe070: mov    $0xf07c4,%edx

   0xfe076: jmp    0xfcf24

   0xfe079: push   %ebp

   0xfe07b: push   %edi

   0xfe07d: push   %esi




Reference for x386:

http://ref.x86asm.net/coder32.html

Visual chart on the Opcodes: https://i.stack.imgur.com/VTxd0.jpg


Good Reference to the opcodes




No comments:

Post a Comment