Author Topic: Detailed error reporting  (Read 13728 times)

Offline TightCoderEx

  • Full Member
  • **
  • Posts: 103
Detailed error reporting
« on: July 02, 2012, 09:55:10 PM »
This is the test application and I just picked 208 out of the blue, because I knew it would cause an error.  I've done the test bed listing like this so you can see the correlation between error reporting and actual code.
Code: [Select]
_start
  4001c0: c8 94 00 00          enter  0x94,0x0
  4001c4: b0 ff                mov    al,0xff
  4001c6: e8 f5 00 00 00        call   InitFrame
  4001cb: b0 d0                mov    al,0xd0         io_getevents (I knew this would cause an error)
  4001cd: 0f 05                syscall
  4001cf: 77 0a                ja     Exit
  4001d1: bf c0 01 40 00        mov    edi,0x4001c0
  4001d6: e8 e5 fe ff ff        call   FmtErr

.Exit
  4001db: c9                    leave 
  4001dc: b0 3c                mov    al,0x3c
  4001de: 0f 05                syscall

This will produce an output like this and all values are in hex. Only errors that aren't trapped by application will show like this and the detail is of more meaning to developer than user.

  Error [ 16 ] in 4001C0 + D

     = EINVAL > Invalid argument

      [A] Abort
      [R] Retry
      (I) Ignore:
      [ ]
<---- Operator enters selection here

This algo is peculiar to the way I do things and the offset make sense because I'll either convert that value in GDB or look for the entry point in the object listing

Main.o:     file format elf64-x86-64

Disassembly of section .text:

0000000000000000 <_start>:
   0:   c8 94 00 00             enter  0x94,0x0
   4:   b0 ff                   mov    al,0xff
   6:   e8 00 00 00 00          call   b <_start+0xb>
   b:   b0 d0                   mov    al,0xd0
   d:   0f 05                   syscall
   f:   77 0a                   ja     1b <_start.Exit>
  11:   bf 00 00 00 00          mov    edi,0x0
  16:   e8 00 00 00 00          call   1b <_start.Exit>

000000000000001b <_start.Exit>:
  1b:   c9                      leave 
  1c:   b0 3c                   mov    al,0x3c
  1e:   0f 05                   syscall


Code: [Select]
  00: 53                    push   rbx
  01: c8 80 00 00          enter  0x80, 0x0
 
  Stack must be populated with data so string can be constructed with these details
 
  #5: Pointer to description string of error
  #4: How long is the description string
  #3: Offset within function where error occured
  #2: Callers entry point ( Can be referenced against a symbol table )
  #1: Error code:
 
  05: 48 f7 d8              neg    rax Abs value of error
  08: 49 89 c0              mov    r8, rax
  0b: ff c8                dec    eax
  0d: c1 e0 02              shl    eax, 0x2
  10: 05 00 00 00 00        add    eax, PNTRS
  15: 48 89 c6              mov    rsi, rax
  18: ad                    lods   eax, [rsi]
  19: 50                    push   rax #5 Length of description
  1a: 67 2b 06              sub    eax, [esi]
  1d: f7 d8                neg    eax
  1f: 50                    push   rax #4 Address of description
 
  Now we need calculate where from the entry point of callers routine, error occured by
  searching backward for 05 and then if byte pointed to by RDI is 0F, we know we're at syscall
 
  20: 57                    push   rdi
  21: 48 8b 7d 10          mov    rdi, [rbp+0x10]
  25: 48 83 ef 06          sub    rdi, 0x6
  29: b0 05                mov    al, 0x5
  2b: 48 31 c9              xor    rcx, rcx
  2e: b1 ff                mov    cl, 0xff Should be closer than 256 bytes back.
 
  30: fd                    std   
  31: f2 ae                repnz scasb
  33: fc                    cld   
  34: 67 80 3f 0f          cmp    [edi], 0xf
  38: 74 10                je     4a
  3a: 09 c9                or     ecx, ecx
  3c: 75 f2                jne    30
 
  Programmer has done something wrong with calling sequence, because you shouldn't be calling
  this procedure more than 256 bytes from SYSCALL.
 
  3e: bf f0 ff ff ff        mov    edi, 0xfffffff0
  43: 48 31 c0              xor    rax, rax
  46: b0 3c                mov    al, 0x3c
  48: 0f 05                syscall
 
   
  4a: 2b 3c 24              sub    edi, [rsp]
  4d: 48 87 3c 24          xchg   [rsp], rdi #3 Offset in callers pace
  51: 57                    push   rdi #2 Callers function entry point
   
  52: 41 50                push   r8 Local copy procedure trashes error #
 
  Now we can begin moving these string segments and each time NULL is encountered this is
  where one value will be poped from stack and put in that position
 
   FmtStr db '  Error [ ', 0
  db ' ] in ', 0
  db ' + ', 0
  db 10, 10, 9, '  = ', 0, 10
 
  Last db 10, 9, 9, '[A] Abort '
  db 10, 9, 9, '[R] Retry '
  db 10, 9, 9, '[I] Ignore:'
  db 10, 9, 9, '[ ]', 8, 8, 0
  FmtStrSz equ $ - Last
 
  54: be 00 00 00 00        mov    esi, FmtStr
  59: 48 8d 7d 80          lea    rdi, [rbp-0x80] Destination buffer on stack
  5d: bb 00 00 00 00        mov    ebx, 0x0
  62: b9 03 00 00 00        mov    ecx, 0x3
 
  Move first four segments
 
  67: ff d3                call   rbx Copy to destination
  69: 58                    pop    rax Get next value
  6a: e8 00 00 00 00        call   I2A Convert to hex value
  6f: 48 ff cf              dec    rdi Bounce back over NULL
  72: e2 f3                loop   67
 
  74: ff d3                call   rbx
  76: 59                    pop    rcx Length of decription string
  77: 48 87 34 24          xchg   [rsp], rsi
  7b: f3 a4                rep movsb Move description string
  7d: 5e                    pop    rsi
  7e: b9 31 00 00 00        mov    ecx, 0x31
  83: f3 a4                rep movsb Move everything from Last->FmtStrSz
 
  Prompt string is completely constructed and ready to show on screen
 
  85: 48 8d 75 80          lea    rsi, [rbp-0x80]
  89: 56                    push   rsi
  8a: e8 00 00 00 00        call   Show Display constructed string
  8f: 48 83 c4 08          add    rsp, 0x8
 
  Get single key response from operator in non-canonical mode
 
  93: e8 00 00 00 00        call   Ask Get operators selection
  98: 24 5f                and    al, 0x5f Convert to uppercase
  9a: 3c 41                cmp    al, 0x41 Was selection "A"
  9c: 75 08                jne    a6
 
  Operator chose Abort, bail from app
 
  9e: 48 83 cf ff          or     rdi, 0xffffffffffffffff
  a2: b0 3c                mov    al, 0x3c
  a4: 0f 05                syscall
 
  Here we test for "I" or "R", it must be one or else just keep cycling
   
  a6: 3c 49                cmp    al, 0x49 Was selection "I"
  a8: 74 06                je     b0 ZR = 1 ignore error
 
  aa: 3c 52                cmp    al, 0x52 Was selection "R"
  ac: 75 e5                jne    93 Do again if none of A, I or R
 
  ae: fe c0                inc    al ZR = 0 retry function
 
  We are done
 
  b0: c9                    leave 
  b1: 5b                    pop    rbx
  b2: c3                    ret

  Local subroutine to copy source -> destination until NULL
   
  b3: aa                    stosb
  b4: ac                    lodsb 
  b5: 3c 00                cmp    al, 0x0
  b7: 75 fa                jne    b3
  b9: c3                    ret