Initial Image bytes - windbg

If I debug an asm file with Windbg the image is loaded at a location in memory, in my case its 00400000. If I dump the data from 00400000 I can see my assembly code is loaded in the image file at and offset of 10000 from this address and not at 00400000.
Here's the dump for the start of the image.
00400000 -> 00905a4d 00000003 00000004 0000ffff
00400010 -> 000000b8 00000000 00000040 00000000
00400020 -> 00000000 00000000 00000000 00000000
00400030 -> 00000000 00000000 00000000 000000c0
So, my question is what is this header at the start of the image and what is it used for? It looks like all images have this header.
Thanks in advance.

What you have posted looks like a PE header in 32 bit format:
0:000> dd 00400000
00400000 00905a4d 00000003 00000004 0000ffff
00400010 000000b8 00000000 00000040 00000000
00400020 00000000 00000000 00000000 00000000
00400030 00000000 00000000 00000000 00000080
If you dump it as bytes, it will show the ASCII characters along with it and you can easily recognize the "MZ" header.
0:000> db 00400000
00400000 4d 5a 90 00 03 00 00 00-04 00 00 00 ff ff 00 00 MZ..............
00400010 b8 00 00 00 00 00 00 00-40 00 00 00 00 00 00 00 ........#.......
00400020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
00400030 00 00 00 00 00 00 00 00-00 00 00 00 80 00 00 00 ................
You can use the !dh command to decode it:
0:000> !dh 00400000
File Type: EXECUTABLE IMAGE
FILE HEADER VALUES
14C machine (i386)
3 number of sections
5911398E time date stamp Mon May 8 20:37:50 2017
0 file pointer to symbol table
0 number of symbols
E0 size of optional header
22 characteristics
Executable
App can handle >2gb addresses
[...]
If you don't want to use WinDbg, there's Stud_PE where you can load an executable and it will analyze it for you.

Related

View managed stack from a full memory dump

My managed process is suspected to have caused a BSOD at a client site. I received a full memory dump (i.e.: including kernel, physical pages only) - but still am not able to inspect my process' stacks.
After switching to my process context -
.process /p /r <MyProcAddress>
I see only -
1: kd> k
# ChildEBP RetAddr
00 b56e3b70 81f2aa5d nt!KeBugCheckEx+0x1e
01 b56e3b94 81e7b68d nt!PspCatchCriticalBreak+0x71
02 b56e3bc4 81e6dfd1 nt!PspTerminateAllThreads+0x2d
03 b56e3bf8 8d48159a nt!NtTerminateProcess+0xcd
WARNING: Stack unwind information not available. Following frames may be wrong.
04 b56e3c24 81c845e4 klif+0x7559a
05 b56e3c24 77da6bb4 nt!KiSystemServicePostCall
06 0262f34c 00220065 ntdll!KiFastSystemCallRet
07 0262f390 003e0022 0x220065
08 0262f394 0073003c 0x3e0022
09 0262f398 00730079 0x73003c
0a 0262f39c 006e003a 0x730079
0b 0262f3a0 006d0061 0x6e003a
0c 0262f3a4 00200065 0x6d0061
0d 0262f3a8 00610076 0x200065
0e 0262f3ac 0075006c 0x610076
0f 0262f3b0 003d0065 0x75006c
10 0262f3b4 00770022 0x3d0065
11 0262f3b8 006e0069 0x770022
12 0262f3bc 006f0077 0x6e0069
13 0262f3c0 00640072 0x6f0077
14 0262f3c4 00200022 0x640072
...
Which is natural for managed process. SOS extension does not work for kernel dumps.
Is there anything I can do to view the throwing managed stack? It was previously said to be 'much more difficult', but hopefully not impossible.
PS.
I'm aware of the presence of Kaspersky driver kilf.sys in the stack, and this is my personal suspect. But the question is more general - hopefully there's a way to understand what my process was doing at the time.
the stack as you posted is not correct
it appears to be overwritten or is a result of some other artefact
with such a stack details you will have a hard time deciphering
anything useful at all
the contents of stack converted to a printable range in english looks like this
Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
00000000 00 3E 00 22 00 22 00 65 00 73 00 3C 00 3E 00 22 .>.".".e.s.<.>."
00000010 00 73 00 79 00 73 00 3C 00 6E 00 3A 00 73 00 79 .s.y.s.<.n.:.s.y
00000020 00 6D 00 61 00 6E 00 3A 00 20 00 65 00 6D 00 61 .m.a.n.:. .e.m.a
00000030 00 61 00 76 00 20 00 65 00 75 00 6C 00 61 00 76 .a.v. .e.u.l.a.v
00000040 00 3D 00 65 00 75 00 6C 00 77 00 22 00 3D 00 65 .=.e.u.l.w.".=.e
00000050 00 6E 00 69 00 77 00 22 00 6F 00 77 00 6E 00 69 .n.i.w.".o.w.n.i
00000060 00 64 00 72 00 6F 00 77 00 20 00 22 00 64 00 72 .d.r.o.w. .".d.r
try !analyze -v and see what is the bsod analysis results

WinDbg: How do I get the message displayed in a Word dialog from a core dump?

I'm doing some Office automation with MS Word from a C# application, and I'm finding that Word sometimes hangs. I can't reproduce the hang in a developer environment, so I'm hoping I can diagnose exactly why Word is hanging by taking a core dump and then analyzing it using WinDbg.
If I run kb, I get this stack trace (I've left off everything after the warning as it's probably irrelevant):
ChildEBP RetAddr Args to Child
003bc94c 762ed846 00037b72 00000008 00000000 user32!NtUserWaitMessage+0x15
003bc988 762eda5c 00047b12 00037b72 00000008 user32!DialogBox2+0x222
003bc9b4 762ed98a 59870000 0089aa30 00037b72 user32!InternalDialogBox+0xe5
003bc9d4 762ed70e 59870000 0089aa30 00037b72 user32!DialogBoxIndirectParamAorW+0x37
003bc9f4 59acdf5e 59870000 0089aa30 00037b72 user32!DialogBoxIndirectParamW+0x1b
WARNING: Stack unwind information not available. Following frames may be wrong.
So this seems to indicate that Word is hanging because it's showing a dialog box. How can I get the contents of that dialog box?
If I look at the memory at address 0089aa30, I see this:
........................3....
.M.i.c.r.o.s.o.f.t. .W.o.r.d.
........T.a.h.o.m.a..........
....P#.!.*...........O.K.....
...........PW.!.*...........&
.H.e.l.p..................P..
.............................
....P+...r.......M.S.O.U.N.I.
S.T.A.T...W.o.r.d. .c.a.n.n.o
.t. .o.p.e.n. .t.h.e. .e.x.i.
s.t.i.n.g. .f.i.l.e..... .(.N
.o.r.m.a.l.)................#
..+.........M.S.O.U.N.I.S.T.A
.T...2.0.0.5.2.1.............
So to me this says that the message in the dialog is "Word cannot open the existing file (Normal)".
Am I on the right track? Am I looking at the right bit of memory?
Is there any way to get the exact memory address of the message? (I feel like I'm guessing a bit, because the above message just happens to be close by in memory to a parameter to DialogBoxIndirectParam.) I have looked at the MSDN docs for DialogBoxIndirectParam, hoping to figure out exactly where in memory I should expect to see the dialog's message, but didn't get very far.
Edit: After seeing blabb's (absolutely incredible) answer, I have attempted to perform the same steps in WinDbg for my MS Word core dump. Here's the output:
0:000> ub 762ed98a
user32!DialogBoxIndirectParamAorW+0x1f:
762ed972 83c801 or eax,1
762ed975 50 push eax
762ed976 ff7518 push dword ptr [ebp+18h]
762ed979 ff7514 push dword ptr [ebp+14h]
762ed97c ff7510 push dword ptr [ebp+10h]
762ed97f ff750c push dword ptr [ebp+0Ch]
762ed982 ff7508 push dword ptr [ebp+8]
762ed985 e809000000 call user32!InternalDialogBox (762ed993)
0:000> .frame /r 2
02 003bc9b4 762ed98a user32!InternalDialogBox+0xe5
eax=00000000 ebx=00037b72 ecx=00000000 edx=00000000 esi=003bc97c edi=003bc918
eip=762eda5c esp=003bc990 ebp=003bc9b4 iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
user32!InternalDialogBox+0xe5:
762eda5c 5f pop edi
0:000> dc /c 1 003bc990 l8
003bc990 00047b12 .{..
003bc994 00037b72 r{..
003bc998 00000008 ....
003bc99c 00000000 ....
003bc9a0 00000000 ....
003bc9a4 00037b72 r{..
003bc9a8 003bcb98 ..;.
003bc9ac 00000000 ....
I know I'm looking at the wrong bit of memory (i.e. the address I'm passing to dc is incorrect), but I don't know why. I used ".frame /r 2" to fetch the address of esp, what did I do wrong?
The InternalDialogBox Api Takes Six Arguments
C:\>cdb -c ".fnent user32!InternalDialogbox;q" cdb | grep Params
Params: 0n6 (0x18 bytes)
you can try deciphering this call by doing a backward disassembly on the return address on stack
0:000> kb 1
# ChildEBP RetAddr Args to Child
00 0017fad8 778be0d5 77860000 001ec4f0 00000000 USER32!InternalDialogBox
0:000> ub #$ra
USER32!SoftModalMessageBox+0x66d:
778be0b8 e87c48fdff call USER32!MessageBeep (77892939)
778be0bd 56 push esi
778be0be 53 push ebx
778be0bf 6848d68b77 push offset USER32!MB_DlgProc (778bd648)
778be0c4 ff75ac push dword ptr [ebp-54h]
778be0c7 ff75e4 push dword ptr [ebp-1Ch]
778be0ca ff35d0908c77 push dword ptr [USER32!hmodUser (778c90d0)]
778be0d0 e8a059fdff call USER32!InternalDialogBox (77893a75)
in a crash dump you can substitute address instead of register or you can
do .frame /r {frame number} to fetch the address of esp
0:000> dc /c 1 #esp l8
0017fadc 778be0d5 ...w
0017fae0 77860000 ...w
0017fae4 001ec4f0 ....
0017fae8 00000000 ....
0017faec 778bd648 H..w
0017faf0 0017fcd8 ....
0017faf4 00000000 ....
0017faf8 00000001 ....
1) The first argument is hModUser a global variable
2) The fourth argument is a DialogProc callback that is documented
3) 3rd and 6th argument are NULL
the second argument consits of an array of DLGTEMPLATE followed by DLGITEMTEMPLATE structure read the document for the format of this variable sized array
the fifth argument is MSGBOXPARAMS structure
a sample dump and deciphering the dump for the variable sized array as follows
0:000> db 1ec4f0 l f8
001ec4f0 c5 01 c8 80 00 00 00 00-02 00 1a 01 9b 00 a7 00 ................
001ec500 3e 00 00 00 00 00 54 00-68 00 69 00 73 00 20 00 >.....T.h.i.s. .
001ec510 69 00 73 00 20 00 4d 00-79 00 20 00 43 00 61 00 i.s. .M.y. .C.a.
001ec520 70 00 74 00 69 00 6f 00-6e 00 20 00 46 00 6f 00 p.t.i.o.n. .F.o.
001ec530 72 00 20 00 32 00 30 00-31 00 35 00 20 00 43 00 r. .2.0.1.5. .C.
001ec540 6f 00 6d 00 6d 00 75 00-6e 00 69 00 74 00 79 00 o.m.m.u.n.i.t.y.
001ec550 20 00 76 00 73 00 00 00-ff 7f 00 00 01 00 03 50 .v.s..........P
001ec560 00 00 00 00 71 00 2a 00-32 00 0e 00 01 00 ff ff ....q.*.2.......
001ec570 80 00 4f 00 4b 00 00 00-00 00 00 00 80 20 02 50 ..O.K........ .P
001ec580 00 00 00 00 07 00 0e 00-8c 00 09 00 ff ff ff ff ................
001ec590 82 00 54 00 68 00 69 00-73 00 20 00 69 00 73 00 ..T.h.i.s. .i.s.
001ec5a0 20 00 6d 00 79 00 20 00-66 00 69 00 72 00 73 00 .m.y. .f.i.r.s.
001ec5b0 74 00 20 00 54 00 65 00-73 00 74 00 20 00 77 00 t. .T.e.s.t. .w.
001ec5c0 69 00 74 00 68 00 20 00-32 00 30 00 31 00 35 00 i.t.h. .2.0.1.5.
001ec5d0 20 00 63 00 6f 00 6d 00-6d 00 75 00 6e 00 69 00 .c.o.m.m.u.n.i.
001ec5e0 74 00 79 00 00 00 00 00 t.y.....
0:000> dt ConsoleApplication1!DLGTEMPLATE 1ec4f0
+0x000 style : 0x80c801c5
+0x004 dwExtendedStyle : 0
+0x008 cdit : 2
+0x00a x : 0x11a
+0x00c y : 0x9b
+0x00e cx : 0xa7
+0x010 cy : 0x3e
0:000> du 1ec504
001ec504 ""
0:000> du 1ec506
001ec506 "This is My Caption For 2015 Comm"
001ec546 "unity vs"
0:000> dt ConsoleApplication1!DLGITEMTEMPLATE 1ec55c
+0x000 style : 0x50030001
+0x004 dwExtendedStyle : 0
+0x008 x : 0x71
+0x00a y : 0x2a
+0x00c cx : 0x32
+0x00e cy : 0xe
+0x010 id : 1
0:000> $$ 80 is a predfined button and the text is OK
0:000> dt ConsoleApplication1!DLGITEMTEMPLATE 1ec57c
+0x000 style : 0x50022080
+0x004 dwExtendedStyle : 0
+0x008 x : 7
+0x00a y : 0xe
+0x00c cx : 0x8c
+0x00e cy : 9
+0x010 id : 0xffff
0:000> $$ 82 is a predfined static text and the text is
0:000> du 1ec592
001ec592 "This is my first Test with 2015 "
001ec5d2 "community"
here is a MSGBOXPARAMSW dump
0:000> dt ConsoleApplication1!MSGBOXPARAMSW 0017fcd8
+0x000 cbSize : 0x28
+0x004 hwndOwner : (null)
+0x008 hInstance : (null)
+0x00c lpszText : 0x01172150 "This is my first Test with 2015 community"
+0x010 lpszCaption : 0x011720f8 "This is My Caption For 2015 Community vs"
+0x014 dwStyle : 0
+0x018 lpszIcon : (null)
+0x01c dwContextHelpId : 0
+0x020 lpfnMsgBoxCallback : (null)
+0x024 dwLanguageId : 0
EDIT
created a dump from taskmanager and loaded it
0:000> .shell -ci "version" grep DMP
Full memory user mini dump: C:\Users\HP\Desktop\cons.DMP
command line: 'windbg -z cons.DMP' Debugger Process 0x17CC
.shell: Process exited
just to be sure resetting the context record
0:000> .cxr
Resetting default scope
dumping stacktrace 9the frame of interest is not at top here)
0:000> kb 5
# ChildEBP RetAddr Args to Child
00 0028f6fc 778766c9 7789382a 00000000 00000000 ntdll!KiFastSystemCallRet
01 0028f700 7789382a 00000000 00000000 00000000 user32!NtUserWaitMessage+0xc
02 0028f734 77893b27 00aa0350 00000000 00000000 user32!DialogBox2+0x207
03 0028f758 778be0d5 77860000 002f63f0 00000000 user32!InternalDialogBox+0xcb
04 0028f7fc 778be659 00000000 69d52104 69d52108 user32!SoftModalMessageBox+0x68a
overriding local context for frame number of interest
0:000> .frame /c /r 04
04 0028f7fc 778be659 user32!SoftModalMessageBox+0x68a
eax=00000001 ebx=0028f958 ecx=0028f458 edx=77ad70f4 esi=005fab18 edi=00000001
eip=778be0d5 esp=0028f760 ebp=0028f7fc iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
user32!SoftModalMessageBox+0x68a:
778be0d5 8945e8 mov dword ptr [ebp-18h],eax ss:0023:0028f7e4=00000000
checking esp you can use esp as it is instead of groping for address
0:000> dc /c 1 #esp l 8
0028f760 77860000 ...w
0028f764 002f63f0 .c/.
0028f768 00000000 ....
0028f76c 778bd648 H..w
0028f770 0028f958 X.(.
0028f774 00000000 ....
0028f778 00000001 ....
0028f77c 0028f958 X.(.
dumping DLGTEMPLATE second arg
0:000> db 2f63f0 lf8
002f63f0 c5 01 c8 80 00 00 00 00-02 00 1a 01 9b 00 a7 00 ................
002f6400 3e 00 00 00 00 00 54 00-68 00 69 00 73 00 20 00 >.....T.h.i.s. .
002f6410 69 00 73 00 20 00 4d 00-79 00 20 00 43 00 61 00 i.s. .M.y. .C.a.
002f6420 70 00 74 00 69 00 6f 00-6e 00 20 00 46 00 6f 00 p.t.i.o.n. .F.o.
002f6430 72 00 20 00 32 00 30 00-31 00 35 00 20 00 43 00 r. .2.0.1.5. .C.
002f6440 6f 00 6d 00 6d 00 75 00-6e 00 69 00 74 00 79 00 o.m.m.u.n.i.t.y.
002f6450 20 00 76 00 73 00 00 00-ff 7f 00 00 01 00 03 50 .v.s..........P
002f6460 00 00 00 00 71 00 2a 00-32 00 0e 00 01 00 ff ff ....q.*.2.......
002f6470 80 00 4f 00 4b 00 00 00-00 00 00 00 80 20 02 50 ..O.K........ .P
002f6480 00 00 00 00 07 00 0e 00-8c 00 09 00 ff ff ff ff ................
002f6490 82 00 54 00 68 00 69 00-73 00 20 00 69 00 73 00 ..T.h.i.s. .i.s.
002f64a0 20 00 6d 00 79 00 20 00-66 00 69 00 72 00 73 00 .m.y. .f.i.r.s.
002f64b0 74 00 20 00 54 00 65 00-73 00 74 00 20 00 77 00 t. .T.e.s.t. .w.
002f64c0 69 00 74 00 68 00 20 00-32 00 30 00 31 00 35 00 i.t.h. .2.0.1.5.
002f64d0 20 00 63 00 6f 00 6d 00-6d 00 75 00 6e 00 69 00 .c.o.m.m.u.n.i.
002f64e0 74 00 79 00 00 00 00 00 t.y.....
typeinfo (you need proper private pdb or hack load a binary which you compiled into address space or add the DLGTEMPLATE struct into the official pdb for user32 from ms ( i thought i had a post explaining this in se but i cant seem to find) ill link it later if i find it or sitesearch google for how to add typeinfo to pdb in site:woodmann.com
0:000> dt cons!DLGTEMPLATE poi(#esp+4)
+0x000 style : 0x80c801c5
+0x004 dwExtendedStyle : 0
+0x008 cdit : 2
+0x00a x : 0n282
+0x00c y : 0n155
+0x00e cx : 0n167
+0x010 cy : 0n62
0:000> du poi(#esp+4)+16
002f6406 "This is My Caption For 2015 Comm"
002f6446 "unity vs"
edit 2 this is for a live session in dump mode you need to modify a pdb as you cant use execution commands
we are in a live dbg session we can use step commands which arent available in dmp mode
0:000> .tlist -c -v
0n3324 Msgbox.exe
Session: 1 User: HP-PC\HP Command Line: Msgbox.exe
lets search for some typeinfo we need
0:000> dt *!*DLGTEMPLATE*
0:000> $$ no the thype info is not available
0:000> $$ we know ole32.dll has it
0:000> $$ so lets hack load it
allocate some memory
0:000> .dvalloc 1000
Allocated 1000 bytes starting at 00020000
save the current eip
0:000> ? #eip
Evaluate expression: 2008221094 = 77b305a6
embed the modulename string at some address in the allocated memory
0:000> ea 20100 "ole32.dll"
0:000> db 20100 l20
00020100 6f 6c 65 33 32 2e 64 6c-6c 00 00 00 00 00 00 00 ole32.dll.......
00020110 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
Assemble a LoadLibraryA call inline
0:000> a 20000
00020000 push 20100
push 20100
00020005 call kernel32!LoadLibraryA
call kernel32!LoadLibraryA
0002000a
change eip to the detour address
0:000> r eip = 20000
single step to load a dll into the address space
0:000> p
eax=00000000 ebx=00000000 ecx=0026f80c edx=77ad70f4 esi=fffffffe edi=00000000
eip=00020005 esp=0026f824 ebp=0026f854 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
00020005 e852395877 call kernel32!LoadLibraryA (775a395c)
0:000> p
ModLoad: 77930000 77a8c000 C:\Windows\system32\ole32.dll
ModLoad: 75ee0000 75f81000 C:\Windows\system32\RPCRT4.dll
ModLoad: 77530000 7754f000 C:\Windows\system32\IMM32.DLL
ModLoad: 76030000 760fc000 C:\Windows\system32\MSCTF.dll
eax=77930000 ebx=00000000 ecx=77ae6570 edx=002b0174 esi=fffffffe edi=00000000
eip=0002000a esp=0026f828 ebp=0026f854 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
0002000a 0000 add byte ptr [eax],al ds:0023:77930000=4d
reset eip back
0:000> r eip = 77b305a6
we research the typeinfo and bingo we have it
0:000> dt *!*DLGTEMPLATE*
ole32!LPDLGTEMPLATEA
ole32!LPDLGTEMPLATE
ole32!LPDLGTEMPLATEW
ole32!LPCDLGTEMPLATE
ole32!LPCDLGTEMPLATEA
ole32!LPCDLGTEMPLATEW
ole32!DLGTEMPLATE
ole32!DLGTEMPLATE

What are the three 255's before the image in a monochrome .bmp?

I'm trying to figure out bitmap formatting for a project I'm working on, but there's one thing I don't really get. In this .bmp:
00000000 42 4d aa 00 00 00 00 00 00 00 82 00 00 00 6c 00 |BM............l.|
00000010 00 00 0a 00 00 00 0a 00 00 00 01 00 01 00 00 00 |................|
00000020 00 00 28 00 00 00 13 0b 00 00 13 0b 00 00 02 00 |..(.............|
00000030 00 00 02 00 00 00 42 47 52 73 00 00 00 00 00 00 |......BGRs......|
00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000060 00 00 00 00 00 00 00 00 00 00 02 00 00 00 00 00 |................|
00000070 00 00 00 00 00 00 00 00 00 00 ff ff ff 00 00 00 |................|
00000080 00 00 ff c0 00 00 ff c0 00 00 ff c0 00 00 ff c0 |................|
*
000000a0 00 00 ff c0 00 00 aa 80 00 00 |..........|
000000aa
what are the three 256's at offset 122 (line 7). I assume they're some sort of color indicators, but I'm not sure.
This is the image I'm using.
The top part of your hex dump is a "BITMAPINFO structure" (https://msdn.microsoft.com/en-us/library/dd183375(v=vs.85).aspx). This is immediately followed by a color index array bmiColors (although its length may be 0, and you should check this in the BITMAPINFO data).
Although some say that
[t]hough seemingly a simple format, it is complicated by its many different versions, lack of an official specification, lack of any version control process, and ambiguities and contradictions in the documentation.
(http://fileformats.archiveteam.org/wiki/BMP)
you don't actually need to understand each single byte. The various structures either have a fixed size (the initial BITMAPFILEHEADER for example), or have their length as its first value.
A line by line annotation of most well-documented parts:
-------- BITMAPFILEHEADER
00000000 42 4d file type identifier
00000002 aa 00 00 00 size in bytes of the entire file
00000006 00 00 (reserved and must be 0)
00000008 00 00 (reserved and must be 0)
0000000A 82 00 00 00 offset from the beginning of the BITMAPFILEHEADER structure to the bitmap bits
-------- BITMAPINFOHEADER
0000000E 6c 00 00 00 BITMAPINFOHEADER structure size
00000012 0a 00 00 00 image width in pixels
00000016 0a 00 00 00 image height in pixels
0000001A 01 00 number of planes
0000001C 01 00 number of bits per pixel
0000001E 00 00 00 00 compression
00000022 28 00 00 00 size in bytes of image data
00000026 13 0b 00 00 horizontal resolution in pixels-per-meter
0000002A 13 0b 00 00 vertical resolution in pixels-per-meter
0000002E 02 00 00 00 number of colors in the color table that are actually used by the bitmap
00000032 02 00 00 00 number of color indexes that are required ("important")
........ badly documented stuff ........
00000036 42 47 52 73 00 00 00 00 00 00
00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00000060 00 00 00 00 00 00 00 00 00 00 02 00 00 00 00 00
00000070 00 00 00 00 00 00 00 00 00 00
-------- end of BITMAPINFOHEADER
-------- bmiColors array
0000007A ff ff ff 00 color table entry #0
0000007E 00 00 00 00 color table entry #1
-------- Image data
00000082 ff c0 00 00 ff c0 00 00 ff c0 00 00 ff c0
000000a0 00 00 ff c0 00 00 aa 80 00 00
The "number of bits per pixel" at 0000001C is 1:
"1 = The bitmap is monochrome, and the bmiColors member of BITMAPINFO contains two entries. Each bit in the bitmap array represents a pixel. If the bit is clear, the pixel is displayed with the color of the first entry in the bmiColors table; if the bit is set, the pixel has the color of the second entry in the table."
(https://msdn.microsoft.com/en-us/library/dd183376(v=vs.85).aspx)
and the number of colors in the array is reported to be 2. So the bmiColors array contains 2 elements in Microsoft's RGBQUAD format, with values in the odd order Blue, Green, Red, and Reserved.
In short: in your image, a pixel value of 0 (a 0 bit in a monochrome image) is FFFFFF: white, and a pixel value of 1 is 000000: black.

Can I trick libc (GLIBC_2.13) into loading a symbol it doesn't have (from GLIBC_2.15)?

In my attempt to get "Steam for Linux" working on Debian, I've run into an issue. libcef (Chromium Embedded Framework) works fine with GLIBC_2.13 (which eglibc on Debian testing can provide), but requires one pesky little extra function from GLIBC_2.15 (which eglibc can't provide):
$ readelf -s libcef.so | grep -E "#GLIBC_2\.1[4567]"
1037: 00000000 0 FUNC GLOBAL DEFAULT UND __fdelt_chk#GLIBC_2.15 (49)
2733: 00000000 0 FUNC GLOBAL DEFAULT UND __fdelt_chk##GLIBC_2.15
My plan of attack here was to LD_PRELOAD a shim library that provides just these functions. This doesn't seem to work. I really want to avoid installing GLIBC_2.17 (since it is in Debian experimental; even Debian sid still has GLIBC_2.13).
This is what I've tried.
fdelt_chk.c is basically stolen from the GNU C library:
#include <sys/select.h>
# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
# define _strong_alias(name, aliasname) \
extern __typeof (name) aliasname __attribute__ ((alias (#name)));
unsigned long int
__fdelt_chk (unsigned long int d)
{
if (d >= FD_SETSIZE)
__chk_fail ();
return d / __NFDBITS;
}
strong_alias (__fdelt_chk, __fdelt_warn)
My Versions script looks as follows:
GLIBC_2.15 {
__fdelt_chk; __fdelt_warn;
};
I then build the library as follows:
$ gcc -m32 -c -fPIC fdelt_chk.c -o fdelt_chk.o
$ gcc -m32 -shared -nostartfiles -Wl,-s -Wl,--version-script Versions -o fdelt_chk.so fdelt_chk.o
However, if I then run Steam (with a bunch of extra stuff to get it working in the first place), the loader still refuses to find the symbol:
% LD_LIBRARY_PATH="/home/tinctorius/.local/share/Steam/ubuntu12_32" LD_PRELOAD=./fdelt_chk.so:./steamui.so ./steam
./steam: /lib/i386-linux-gnu/i686/cmov/libc.so.6: version `GLIBC_2.15' not found (required by /home/tinctorius/.local/share/Steam/ubuntu12_32/libcef.so)
However, the version symbol is also provided by the .so I just built:
% readelf -s fdelt_chk.so
Symbol table '.dynsym' contains 8 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 00000000 0 FUNC GLOBAL DEFAULT UND __chk_fail#GLIBC_2.3.4 (3)
2: 0000146c 0 NOTYPE GLOBAL DEFAULT ABS _edata
3: 0000146c 0 NOTYPE GLOBAL DEFAULT ABS _end
4: 00000310 44 FUNC GLOBAL DEFAULT 11 __fdelt_warn##GLIBC_2.15
5: 00000310 44 FUNC GLOBAL DEFAULT 11 __fdelt_chk##GLIBC_2.15
6: 00000000 0 OBJECT GLOBAL DEFAULT ABS GLIBC_2.15
7: 0000146c 0 NOTYPE GLOBAL DEFAULT ABS __bss_start
At this point, I don't know what I can do to trick the loader (who?) into choosing my symbols. Am I going in the right direction at all?
I ran into this same problem, though not with Steam. What I was trying to run wanted 2.15 for fdelt_chk while my system had 2.14. I found a solution for simple cases like ours where we can easily provide our own implementation for the missing functionality.
I started out from your attempted solution of implementing the functionality and LD_PRELOADing it. Using LD_DEBUG=all (as suggested by osgx) showed that the linker was still looking for 2.15, so just having the right symbol wasn't enough and there was some other versioning mechanism somewhere. I noticed that objdump -p and readelf -V both showed references to 2.15, so I looked up documentation on ELF and found information on version requirements.
So my new goal was to transform references to 2.15 into references to something else. It seemed reasonable that I could just overwrite structures that referred to 2.15 with the structures that referred to some lower version, like 2.1. In the end, after some trial and error, I found just editing the right Elfxx_Vernaux(es?) in .gnu.version_r was sufficient, but caveat hacker, I guess.
The .gnu.version_r section is a list of 16-byte Elfxx_Verneeds and 16-byte Elfxx_Vernauxes. Each Elfxx_Verneed entry is followed by the associated Elfxx_Vernauxes. As far as I could tell, vn_file is actually how many associated Elfxx_Vernauxes there are, even though the docs say number of associated verneed array entries. It might just be a misunderstanding on my part, though.
So, to start off making the edits, let's look at some of the info from readelf -V. I snipped out parts we don't care about.
$ readelf -V mybinary
<snip stuff before .gnu.version_r>
Version needs section '.gnu.version_r' contains 5 entries:
Addr: 0x00000000000021ac Offset: 0x0021ac Link: 4 (.dynstr)
<snip libraries that don't refer to GLIBC_2.15>
0x00c0: Version: 1 File: libc.so.6 Cnt: 10
0x00d0: Name: GLIBC_2.3 Flags: none Version: 19
0x00e0: Name: GLIBC_2.7 Flags: none Version: 16
0x00f0: Name: GLIBC_2.2 Flags: none Version: 15
0x0100: Name: GLIBC_2.2.4 Flags: none Version: 14
0x0110: Name: GLIBC_2.1.3 Flags: none Version: 13
0x0120: Name: GLIBC_2.15 Flags: none Version: 12
0x0130: Name: GLIBC_2.4 Flags: none Version: 10
0x0140: Name: GLIBC_2.1 Flags: none Version: 9
0x0150: Name: GLIBC_2.3.4 Flags: none Version: 4
0x0160: Name: GLIBC_2.0 Flags: none Version: 2
From this we see that the section starts at 0x21ac. Each file listed will have a Elfxx_Verneed followed by an Elfxx_Vernaux for each of the subentries (like GLIBC_2.3). I assume the order of the info in the output will always match the order in the file since readelf is just dumping the structures. Here's my entire .gnu.version_r section.
000021A0 01 00 02 00
000021B0 A3 0C 00 00 10 00 00 00 30 00 00 00 11 69 69 0D
000021C0 00 00 11 00 32 0D 00 00 10 00 00 00 10 69 69 0D
000021D0 00 00 0B 00 3C 0D 00 00 00 00 00 00 01 00 02 00
000021E0 BE 0C 00 00 10 00 00 00 30 00 00 00 13 69 69 0D
000021F0 00 00 08 00 46 0D 00 00 10 00 00 00 10 69 69 0D
00002200 00 00 07 00 3C 0D 00 00 00 00 00 00 01 00 02 00
00002210 99 0C 00 00 10 00 00 00 30 00 00 00 11 69 69 0D
00002220 00 00 06 00 32 0D 00 00 10 00 00 00 10 69 69 0D
00002230 00 00 05 00 3C 0D 00 00 00 00 00 00 01 00 02 00
00002240 AE 0C 00 00 10 00 00 00 30 00 00 00 11 69 69 0D
00002250 00 00 12 00 32 0D 00 00 10 00 00 00 10 69 69 0D
00002260 00 00 03 00 3C 0D 00 00 00 00 00 00 01 00 0A 00
00002270 FF 0C 00 00 10 00 00 00 00 00 00 00 13 69 69 0D
00002280 00 00 13 00 46 0D 00 00 10 00 00 00 17 69 69 0D
00002290 00 00 10 00 50 0D 00 00 10 00 00 00 12 69 69 0D
000022A0 00 00 0F 00 5A 0D 00 00 10 00 00 00 74 1A 69 09
000022B0 00 00 0E 00 64 0D 00 00 10 00 00 00 73 1F 69 09
000022C0 00 00 0D 00 70 0D 00 00 10 00 00 00 95 91 96 06
000022D0 00 00 0C 00 7C 0D 00 00 10 00 00 00 14 69 69 0D
000022E0 00 00 0A 00 87 0D 00 00 10 00 00 00 11 69 69 0D
000022F0 00 00 09 00 32 0D 00 00 10 00 00 00 74 19 69 09
00002300 00 00 04 00 91 0D 00 00 10 00 00 00 10 69 69 0D
00002310 00 00 02 00 3C 0D 00 00 00 00 00 00
To briefly talk about the structure here, it starts out with an Elfxx_Verneed. As per the docs, we can see there will be 2 Elfxx_Vernauxes, one offset 16 bytes, and the next Elfxx_Verneed is offset 48 bytes. These offsets are from the start of the current structure. It looks like technically the associated Elfxx_Vernauxes might not be adjacent after the current Elfxx_Verneed but it was actually so in all the files I poked around in.
From this we can find the file we want (libc.so.6) in a few different ways. Cross reference the string (which I won't get into), find the Elfxx_Verneed with a count of 0A 00 (10, matching our readelf output above), or find the last Elfxx_Verneed since it's the last one readelf output. In any case, the right one for my file is at 0x226C. Its first Elfxx_Vernaux starts at 0x227C.
We want to find the Elfxx_Vernaux with a version of 0C 00 (12, again matching our readelf output above). We see the Elfxx_Vernaux that matches is at 0x22CC and the entire structure is 95 91 96 06 00 00 0C 00 7C 0D 00 00 10 00 00 00. We'll be overwriting the first 12 bytes so as to leave the offset alone. We're only modifying the data, not moving around the structures, after all.
To pick the data to overwrite with, we just copy it from a different Elfxx_Vernaux for a version of glibc we can satisfy. I picked one for 2.1, which is at 0x22EC in my file, with the data 11 69 69 0D 00 00 09 00 32 0D 00 00 10 00 00 00. So take the first 12 bytes from this and overwrite the first 12 bytes above, and that's it for the hex editing.
Of course, you might have multiple references to deal with. Your program might have multiple binaries to edit.
At this point, our program still won't run. But instead of being told something like GLIBC_2.15 not found it should complain about missing __fdelt_chk. Now we do the shim and LD_PRELOADing described in the question, except instead of versioning our implementation as 2.15, we use the version we picked while hex editing. At this point the program should run.
This method depends on being able to provide an implementation for whatever's missing. Our __fdelt_chk is extremely simple but I don't doubt that in some cases providing an implementation could be more difficult than just upgrading the system's libc instead.
For what it's worth, the __fdelt_chk function is related to the FORTIFY_SOURCE feature which was added in glibc 2.15. It enables compile-time and run-time checking for buffer overflows.
If you were able to recompile with the following CFLAGS added, it would build a backwards compatible binary without the extra checking:
-U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=0

How to solve "Error 13 while loading file" when using Qemu?

I write the following bytes into a file named disk.img
FA 8D 36 1B 7C E8 01 00 F4 AC 3C 00 74 0C B4 0E
BB 07 00 B9 01 00 CD 10 EB EF C3 4D 61 79 20 74
68 65 20 66 6F 72 63 65 20 62 65 20 77 69 74 68
20 79 6F 75 21 0D 0A 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
..enough zero to make the size of file 512bytes.
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 AA
The above bytes are proper instructions and magic number that should work when loading into the boot sector. But after I executed "qemu-X86_64 disk.img", error happens.
Error -13 while loading disk.img
Does anyone know how to solve the problem or what is the reason that might lead to this error?
Thank you!
I don't know if you can fill an image with just anything and expect it to work just because you have 55 AA in the correct place. Since you seem to be writing a bootloader make sure your code thinks it is executing at the correct place. It should be in offset 0x7C00 (if I remember this correctly, double check that). You set it by writing the line [org 0x7C00] at the top of your assembly file.
Also I'm not sure you can have only a 512 byte file. Try to make the disk image bigger than that using something like dd if=/dev/zero of=disk.img bs=512 count=2000 and then just copy your bootloader to the first part of the disk using dd again.
Also, you should use the -hda or -fda tags, so it would be qemu -hda disk.img. -hda means hard drive image, and -fda means floppy disk image.