radareorg / radare2

UNIX-like reverse engineering framework and command-line toolset
https://www.radare.org/
GNU Lesser General Public License v3.0
20.38k stars 2.97k forks source link

rabin2 -H does not show header of exe build with WatcomV2 wlink #19873

Open LowLevelMahn opened 2 years ago

LowLevelMahn commented 2 years ago

exe.asm

.model small
.stack 1deh

cseg segment 'CODE'   
  assume cs:cseg
start:        
  mov ax,4c00h
  int 21h
cseg ends

end start

https://github.com/open-watcom/open-watcom-v2/releases/tag/Current-build https://github.com/open-watcom/open-watcom-v2/releases/download/Current-build/open-watcom-2_0-c-win-x64.exe https://github.com/open-watcom/open-watcom-v2/releases/download/Current-build/open-watcom-2_0-c-linux-x64 no installation needed just unpack

open-watcom-2_0-c-win-x64\binnt64\wasm exe.asm open-watcom-2_0-c-win-x64\binnt64\wlink.exe name exe.exe system dos file exe.obj or open-watcom-2_0-c-win-x64\binnt64\wlink.exe name exe.exe format dos file exe.obj

radare2-5.6.6-w64\bin\rabin2.exe -H exe.exe

does show nothing - not even an error message

my own exe header dumper shows:

exe_header:
  signature: MZ
  bytes_in_last_block: 0x0025
  blocks_in_file: 0x0001
  num_relocs: 0x0000
  header_paragraphs: 0x0002
  min_extra_paragraphs: 0x0101
  max_extra_paragraphs: 0xffff
  ss:sp: 0x0001:0x1000
  checksum: 0x0000
  cs:ip: 0x0000:0x0000
  reloc_table_offset: 0x0020
  overlay_number: 0x0000

obj and exe file exe_loader.zip

Lazula commented 2 years ago

The current magic MZ detection doesn't work with non-PE binaries. It expects the full header MZ\0\0\0\0\0\0\0\0\0\0PE\0\0 \b, PE for MS Windows, but this compiler uses only MZ as the header. However, the MZ plugin still works. You can force rabin2 to use it with the -F mz option.

$ rabin2 -H exe.exe
$ rabin2 -F mz -H exe.exe
ii 37 32
[0000:0000]  Signature           MZ
[0000:0002]  BytesInLastBlock    0x0025
[0000:0004]  BlocksInFile        0x0001
[0000:0006]  NumRelocs           0x0000
[0000:0008]  HeaderParagraphs    0x0002
[0000:000a]  MinExtraParagraphs  0x0101
[0000:000c]  MaxExtraParagraphs  0xffff
[0000:000e]  InitialSs           0x0001
[0000:0010]  InitialSp           0x1000
[0000:0012]  Checksum            0x0000
[0000:0014]  InitialIp           0x0000
[0000:0016]  InitialCs           0x0000
[0000:0018]  RelocTableOffset    0x0020
[0000:001a]  OverlayNumber       0x0000

@trufae:

Resolving MZ alone to MS-DOS was removed in 2014.

$ git blame libr/magic/d/default/microsoft | grep ' 4[12])'
1d9955b2d41 libr/magic/d/default/microsoft (pancake           2014-10-22 00:56:11 +0200  41) #0 string  MZ              MS-DOS executable
1d9955b2d41 libr/magic/d/default/microsoft (pancake           2014-10-22 00:56:11 +0200  42) 0  string  MZ
$ git log -n1 1d9955b2d41
commit 1d9955b2d4168e763c72e151ff61c09926775017
Author: pancake <pancake@nopcode.org>
Date:   Wed Oct 22 00:56:11 2014 +0200

    Clean unnecessary MAGIC rules and optimize its search

    - Cleanup MAGIC database to avoid false positives,
    - Optimize magic search loop 6x faster /m

Thoughts? Just emit an error saying no headers were found and instructing the user to check plugins?

LowLevelMahn commented 2 years ago

The current magic MZ detection doesn't work with non-PE binaries. It expects the full header MZ\0\0\0\0\0\0\0\0\0\0PE\0\0 \b, PE for MS Windows, but this compiler uses only MZ as the header.

thanks for the info but it seems that the Header detection is still then not fully correct - or based on a size check

the same asm example linked with

  1. current UniLink v1.13 [beta] (build 3.09) (ftp://ftp.styx.cabel.net/pub/UniLink) --> exe_unilinker.zip

ulink.exe -Tde exe.obj (wich normaly produces a larger gap between header and relocation table)

shows the header with just -H

  1. Microsoft (R) Segmented Executable Linker Version 5.60.339 Dec 5 1994 - latest 16bit able -->exe_mslink.zip

shows also the header with just -H

  1. current OPTLINK (R) for Win32 Release 8.00.17 produces a exe where -H does NOT show header info

  2. TLink Version 7.1.30.1. Copyright (c) 1987 - latest 16bit from TASM 5.x package

shows also the header info with -H

Linker Headersize Space to relocation table Space to header end Image just -H works
wlink 28 bytes 00 00 00 00 5 bytes NO
ulink 28 bytes 55 6E 69 4C 69 6E 6B +29 null bytes 0 bytes 5 bytes YES
mslink 28 bytes 01 00 482 null bytes 5 bytes YES
optlink 28 bytes 00 00 00 00 5 bytes NO
tlink 28 bytes 01 00 FB 71 6A 72 +28 null bytes 450 null bytes 5 bytes YES

exe_unilinker.zip exe_mslink.zip exe_tlink.zip

trufae commented 2 years ago

You carload the file with r2 -F mz exe.exe. but it's indeed a bug that this is not handled properly probably because the PE plugin tries to handle it before the mz one and just returns error instead of redirecting the handling to the mz plugin.

About iH not printing anything, yes, I think it's fine to print an error when the plugin doesn't implement such callback

trufae commented 2 years ago

is this what you mean? https://github.com/radareorg/radare2/pull/19926

LowLevelMahn commented 2 years ago

is this what you mean? #19926

i think this will print an error message (can't test - waiting for next release) if there are no header fields found thats it definitily bettern then printing nothing :)

Lazula commented 2 years ago

works with r2 but not rabin2

$ r2 -q -c 'iH' ~/r2-files/issues/19873/exe.exe
No header fields found
$ rabin2 -H ~/r2-files/issues/19873/exe.exe
<no output>
trufae commented 2 years ago

done in rabin2 -H too. i'll drop the milestone because no hurry to implement that support for this short release. anyone feel free to do it. thanks for reporting