Closed karthick-gururaj closed 5 years ago
no, this binary format is not supported by r2's RBin yet. do y ou have documentation about it?
All the QNX bins ive seen before were basically ELFs.. what's the name of this executable format? can you provide magic signatures for them too?
On 5 Jan 2019, at 15:18, karthick-gururaj notifications@github.com wrote:
Work environment
Questions Answers OS/arch/bits Windows 10 / x86 / 64 File format of the file being disassembled QNX Executable format Architecture/bits of the file x86/32 (386) r2 -v full output radare2 3.1.3 6 @ windows-x86-32 git.3.1.3-5-gdf4c9f0 commit: df4c9f0 https://github.com/radare/radare2/commit/df4c9f09ba6fe07a30b55a5c40c5bbdb7bddf087 build: Tue 12/04/2018__21:40:59.09 Expected behavior
radare2 should decode the format to figure out where code blocks are and then disassemble the code blocks. The attached zip https://github.com/radare/radare2/files/2729570/simple_test.zip has reference disassembly files.
Actual behavior
Disassembly starts from the very first byte - possibly because the format is not recognized.
Hexdump of first few bytes of the executable file header is (question marks indicate the bytes that differ between 3 executables that were inspected):
00000000: 0000 3800 0000 9001 1600 8201 0000 0000 ..8............. 00000010: 0100 0100 0100 0000 0000 0000 0000 ???? ..............?? 00000020: 0000 0080 0000 0010 0000 00a0 0000 0000 ................ 00000030: 0000 0000 0000 ???? 0020 ???? 0000 ???? ......??. ??..?? The hexdump of first few bytes of the actual executable being disassembled:
00000000: 0000 3800 0000 9001 1600 8201 0000 0000 ..8............. 00000010: 0100 0100 0100 0000 0000 0000 0000 1c02 ................ 00000020: 0000 0080 0000 0010 0000 00a0 0000 0000 ................ 00000030: 0000 0000 0000 c306 0020 1001 0000 0200 ......... ...... The disassembly produced by radare2 is (for debug/test.x in attached zip https://github.com/radare/radare2/files/2729570/simple_test.zip):
0x00000000 0000 add byte [eax], al 0x00000002 3800 cmp byte [eax], al 0x00000004 0000 add byte [eax], al 0x00000006 90 nop 0x00000007 0116 add dword [esi], edx 0x00000009 008201000000 add byte [edx + 1], al 0x0000000f 0001 add byte [ecx], al 0x00000011 0001 add byte [ecx], al 0x00000013 0001 add byte [ecx], al 0x00000015 0000 add byte [eax], al 0x00000017 0000 add byte [eax], al 0x00000019 0000 add byte [eax], al 0x0000001b 0000 add byte [eax], al 0x0000001d 001c02 add byte [edx + eax], bl 0x00000020 0000 add byte [eax], al 0x00000022 008000000010 add byte [eax + 0x10000000], al 0x00000028 0000 add byte [eax], al 0x0000002a 00a000000000 add byte [eax], ah 0x00000030 0000 add byte [eax], al 0x00000032 0000 add byte [eax], al 0x00000034 0000 add byte [eax], al 0x00000036 c3 ret 0x00000037 06 push es 0x00000038 0020 add byte [eax], ah 0x0000003a 1001 adc byte [ecx], al 0x0000003c 0000 add byte [eax], al 0x0000003e 0200 add al, byte [eax] 0x00000040 fc cld 0x00000041 0000 add byte [eax], al Steps to reproduce the behavior
The attached zip https://github.com/radare/radare2/files/2729570/simple_test.zip has the following files:
test.c -> the C source file I'm using to compile debug/ contains objects compiled in debug mode (with -g option) and no_debug/ contains objects compiled without -g option Inside debug and no_debug folders, test.o -> object file, test.x -> final executable. Disassembly (test.S) and linker map (test.x.map) files are also included for reference. Compare the reference disassembly to what is produced by radare2:
cmd> radare2 test.x [0x00000000]> pd $r — You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/radare/radare2/issues/12664, or mute the thread https://github.com/notifications/unsubscribe-auth/AA3-lgoHs0-P5OW97H29WCWHMK4zLCGzks5vALQ1gaJpZM4ZxHqv.
The format is referred to as "QNX Executable format" and is not ELF. I had posted a question on the Open Watcom compiler group (the tool chain I'm using) on understanding the format better and got few hints. Documentation is limited - I found just one that had some potentially useful information - http://watcom.markoverholser.com/manuals/current/cguide.pdf (the parent folder has other tool chain manuals)
The format is as per the header file bld/watcom/h/exeqnx.h:
The file is a list of records of type lmf_record. The very first record is decoded from the first 6 bytes (which can be treated as the magic signature):
0x00 -> lmf_record::rec_type (0 means LMF_HEADER_REC)
0x00 -> lmf_record::reserved
0x0038 -> lmf_record::data_nbytes (size of data record that follows, lmf_header in this case)
0000 -> lmf_record::spare
The next 0x0038
(56) bytes are of type lmf_header
:
0x0190 -> lmf_header::version
0x0016 -> lmf_header::cflags
0x0182 -> lmf_header::cpu (can be: 86,186,286,386,486 etc. 0x0182 = 386 decimal)
0x0000 -> lmf_header::fpu (can be: 0, 87,287,387)
0x0000 -> lmf_header::code_index (segment of code start)
0x0001 -> lmf_header::stack_index (segment to put the stack)
0x0001 -> lmf_header::heap_index (segment to start DS at.)
0x0001 -> lmf_header::argv_index (segment to put argv & environment.)
0x0000 -> lmf_header::spare2[0] (must be zero)
0x0000 -> lmf_header::spare2[1] (must be zero)
0x0000 -> lmf_header::spare2[2] (must be zero)
0x0000 -> lmf_header::spare2[3] (must be zero)
0x0000021c -> lmf_header::code_offset (starting offset of code.)
0x00008000 -> lmf_header::stack_nbytes (stack size)
0x00001000 -> lmf_header::heap_nbytes (initial size of heap (optional).)
0x0000a000 -> lmf_header::image_base (starting address of image)
0x00000000 -> lmf_header::spare3[0]
0x00000000 -> lmf_header::spare3[1]
Does this information help?
Thanks that's enough tos tart! is there any other tool that supports this file format ? maybe a fork of binutils?
Any other resource is welcome, also do you plan to contribute to this or it is fine for you to wait until someone else gets some spare time to care about it?
--pancake
On 5 Jan 2019, at 16:38, karthick-gururaj notifications@github.com wrote:
The format is referred to as "QNX Executable format" and is not ELF. I had posted a question on the Open Watcom compiler group https://groups.google.com/forum/#!topic/openwatcom.contributors/ipm6pi92e14 (the tool chain I'm using) on understanding the format better and got few hints. Documentation is limited - I found just one that had some potentially useful information - http://watcom.markoverholser.com/manuals/current/cguide.pdf http://watcom.markoverholser.com/manuals/current/cguide.pdf (the parent http://watcom.markoverholser.com/manuals/current folder has other tool chain manuals)
The format is as per the header file bld/watcom/h/exeqnx.h https://github.com/open-watcom/open-watcom-v2/blob/master/bld/watcom/h/exeqnx.h:
The file is a list of records of type lmf_record https://github.com/open-watcom/open-watcom-v2/blob/master/bld/watcom/h/exeqnx.h#L62. The very first record is decoded from the first 6 bytes (which can be treated as the magic signature):
0x00 -> lmf_record::rec_type (0 means LMF_HEADER_REC) 0x00 -> lmf_record::reserved 0x0038 -> lmf_record::data_nbytes (size of data record that follows, lmf_header in this case) 0000 -> lmf_record::spare The next 0x0038 (56) bytes are of type lmf_header:
0x0190 -> lmf_header::version 0x0016 -> lmf_header::cflags 0x0182 -> lmf_header::cpu (can be: 86,186,286,386,486 etc. 0x0182 = 386 decimal) 0x0000 -> lmf_header::fpu (can be: 0, 87,287,387) 0x0000 -> lmf_header::code_index (segment of code start) 0x0001 -> lmf_header::stack_index (segment to put the stack) 0x0001 -> lmf_header::heap_index (segment to start DS at.) 0x0001 -> lmf_header::argv_index (segment to put argv & environment.) 0x0000 -> lmf_header::spare2[0] (must be zero) 0x0000 -> lmf_header::spare2[1] (must be zero) 0x0000 -> lmf_header::spare2[2] (must be zero) 0x0000 -> lmf_header::spare2[3] (must be zero) 0x0000021c -> lmf_header::code_offset (starting offset of code.) 0x00008000 -> lmf_header::stack_nbytes (stack size) 0x00001000 -> lmf_header::heap_nbytes (initial size of heap (optional).) 0x0000a000 -> lmf_header::image_base (starting address of image) 0x00000000 -> lmf_header::spare3[0] 0x00000000 -> lmf_header::spare3[1] Does this information help?
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/radare/radare2/issues/12664#issuecomment-451665415, or mute the thread https://github.com/notifications/unsubscribe-auth/AA3-lvfsfkPXGRpjlEdtJqYHM8y32h-7ks5vAMbogaJpZM4ZxHqv.
I'm not aware of any other tool that supports this format other than Watcom toolchain.
I'm not sure if I'll be able to contribute significant effort right now :( But if someone else does pick this up, I can pitch in. Can you point me someplace in code that I can look at to see how to add support for a new file format? I'll pursue that at my own pace, and see how far I can proceed.
Radare2 has one of the nerdiest interfaces I have seen in recent times - thanks for all the good work!
I will try to find some time to implement that. Shouldnt take more than an hour. But full complete support will require more time and samples.
On 6 Jan 2019, at 13:12, Maijin notifications@github.com wrote:
See https://radare.gitbooks.io/radare2book/content/plugins/dev-bin.html
— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or mute the thread.
Thanks! I'll test the changes and feedback.
I'm noting down a one more source that I studied - that could be helpful.
wdump
is a tool that dumps meta-data of the QNX executable. Output of running wdump
on the debug/test.x
is as below:
Open Watcom Executable Image Dump Utility Version 1.9
Portions Copyright (c) 1984-2002 Sybase, Inc. All Rights Reserved.
Source code is available under the Sybase Open Watcom Public License.
See http://www.openwatcom.org/ for details.
QNX EXE Header
==============================================================================
version number = 0190H
cflags = 0016H
cpu (86, 186, 286, 386, 486) = 0182H
fpu (0, 87, 287, 287) = 0000H
selector of code start address = 0000H
selector where to put the stack = 0001H
selector to put heap = 0001H
selector where to put argv and environment = 0001H
zero = 0000H
zero = 0000H
zero = 0000H
zero = 0000H
code offset = 0000021CH
stack size in bytes = 00008000H
initial near heap size in bytes = 00001000H
image base = 0000A000H
zero = 00000000H
zero = 00000000H
flags = 32BIT PRIV_MASK FLAT
segments = type:size
type 0==read/write, 1==read-only, 2==execute/read, 3==execute-only
2:00006C3 0:0000110
Data Table 1
==============================================================================
segment index = 0001H
offset = 00000000H
size = 00F6H
Read/Write end
==============================================================================
verify = D5F5H signature = A079CBDDH
Data Table 2
==============================================================================
segment index = 0000H
offset = 00000000H
size = 06C3H
The source file of wdump
is useful reference, the function Dmp_qnx_head
is the entry point.
There is also a loader bld/wl/c/loadqnx.c - which could also be helpful.
Hey, I could start working on this if no one else is. It will take some time but I'll do it as fast as I can.
Sure :) no hurry, feel free to ask anything you need
On 14 Feb 2019, at 01:58, Deepak Chethan notifications@github.com wrote:
Hey, I could start working on this if no one else is. It will take some time but I'll do it as fast as I can.
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/radare/radare2/issues/12664#issuecomment-463440290, or mute the thread https://github.com/notifications/unsubscribe-auth/AA3-ls1KU8yemzamJfPhBser8a4f1yN-ks5vNLTCgaJpZM4ZxHqv.
@karthick-gururaj can you please check and tell me if I should do any modifications?
This can be closed
Work environment
Expected behavior
radare2 should decode the format to figure out where code blocks are and then disassemble the code blocks. The attached zip has reference disassembly files.
Actual behavior
Disassembly starts from the very first byte - possibly because the format is not recognized.
Hexdump of first few bytes of the executable file header is (question marks indicate the bytes that differ between 3 executables that were inspected):
The hexdump of first few bytes of the actual executable being disassembled:
The disassembly produced by radare2 is (for
debug/test.x
in attached zip):Steps to reproduce the behavior
The attached zip has the following files:
test.c
-> the C source file I'm using to compiledebug/
contains objects compiled in debug mode (with -g option) andno_debug/
contains objects compiled without -g optiondebug
andno_debug
folders,test.o
-> object file,test.x
-> final executable. Disassembly (test.S
) and linker map (test.x.map
) files are also included for reference.Compare the reference disassembly to what is produced by radare2: