NationalSecurityAgency / ghidra

Ghidra is a software reverse engineering (SRE) framework
https://www.nsa.gov/ghidra
Apache License 2.0
51.12k stars 5.82k forks source link

Ghidra (latest dev build) section address ranges don't seem to be accurate #4710

Closed RedOctober45 closed 1 year ago

RedOctober45 commented 1 year ago

Describe the bug I am using the latest Ghidra developer build as a workaround for the following issue: https://github.com/NationalSecurityAgency/ghidra/pull/4161

However, I am seeing an odd issue where the reported address range for the sections doesn't seem to be right. For example, when I import my DLL file I get an address range for the text section of: 0x00010000-0x012881ff

But when I do an objdump or look at the accompanying symbol table there is a text address range starting at: 0xDA00100. Confirming with others who work on this project, the correct starting address is indeed 0xDA00000 and I also checked this by doing a objdump on this file too. But I am unsure why Ghidra is reading a different range.

Interestingly, this is only seen for the files which I saw the error in issue#4161 linked above when I was using the release version.

To Reproduce I can't provide the file because it is proprietary, but I am looking for any ideas or suggestions on what the issue might be,

Expected behavior Before I ran into issue 4161 and using the release versions, the section address ranges were as expected and matched up.

Environment (please complete the following information):

Thanks

ryanmkurtz commented 1 year ago

Very hard to say without analyzing the sample. Would you be able to paste in the PE header up to including the section headers?

RedOctober45 commented 1 year ago

Very hard to say without analyzing the sample. Would you be able to paste in the PE header up to including the section headers?

Here are some screenshots I got from PE Explorer. I'll keep seeing what I can do with getting the code you asked for.

image image

ryanmkurtz commented 1 year ago

Could you post a screen shot of the Ghidra Memory Map? Could you also post a screen shot of the Ghidra Listing where the Section headers are expanded?

RedOctober45 commented 1 year ago

Could you post a screen shot of the Ghidra Memory Map? Could you also post a screen shot of the Ghidra Listing where the Section headers are expanded? image

    00010178 2e 74 65        IMAGE_SE
             78 74 00 
             00 00 18 
       00010178 2e 74 65 78 74  char[8]   ".text"                 Name          .text
                00 00 00
       00010180 18 29 ac 00     Misc                              Misc
       00010184 00 10 00 00     ibo32     FUN_00011000            VirtualAddress
       00010188 00 2a ac 00     ddw       AC2A00h                 SizeOfRawData
       0001018c 00 04 00 00     ddw       400h                    PointerToRaw
       00010190 00 00 00 00     ddw       0h                      PointerToRel
       00010194 00 00 00 00     ddw       0h                      PointerToLin
       00010198 00 00           dw        0h                      NumberOfRelo
       0001019a 00 00           dw        0h                      NumberOfLine
       0001019c 60 00 50 60     SectionF  IMAGE_SCN_CNT_CODE | I  Characterist
    000101a0 2e 64 61        IMAGE_SE
             74 61 00 
             00 00 d8 
       000101a0 2e 64 61 74 61  char[8]   ".data"                 Name          .data
                00 00 00
       000101a8 d8 06 01 00     Misc                              Misc
       000101ac 00 40 ac 00     ibo32     DAT_00ad4000            VirtualAddress
       000101b0 00 08 01 00     ddw       10800h                  SizeOfRawData
       000101b4 00 2e ac 00     ddw       AC2E00h                 PointerToRaw
       000101b8 00 00 00 00     ddw       0h                      PointerToRel
       000101bc 00 00 00 00     ddw       0h                      PointerToLin
       000101c0 00 00           dw        0h                      NumberOfRelo
       000101c2 00 00           dw        0h                      NumberOfLine
       000101c4 40 00 60 c0     SectionF  IMAGE_SCN_CNT_INITIALI  Characterist
    000101c8 2f 34 00        IMAGE_SE
             00 00 00 
             00 00 50 
       000101c8 2f 34 00 00 00  char[8]   "/4"                    Name          PersistentData
                00 00 00
       000101d0 50 96 00 00     Misc                              Misc
       000101d4 00 50 ad 00     ibo32     DAT_00ae5000            VirtualAddress
       000101d8 00 98 00 00     ddw       9800h                   SizeOfRawData
       000101dc 00 36 ad 00     ddw       AD3600h                 PointerToRaw
       000101e0 00 00 00 00     ddw       0h                      PointerToRel
       000101e4 00 00 00 00     ddw       0h                      PointerToLin
       000101e8 00 00           dw        0h                      NumberOfRelo
       000101ea 00 00           dw        0h                      NumberOfLine
       000101ec 40 00 60 c0     SectionF  IMAGE_SCN_CNT_INITIALI  Characterist
                         IMAGE_SECTION_HEADER_000101f0.SizeOfRawData     XREF[0,10]:  000ca348(R), 000ca41c(R), 
                         IMAGE_SECTION_HEADER_000101f0.PointerToRawData               000ca439(R), 000ca43f(W), 
                         IMAGE_SECTION_HEADER_000101f0.PointerToRelocat               000ca703(R), 
                                                                                      FUN_000cc000:000cc051(W), 
                                                                                      FUN_000cc090:000cc214(*), 
                                                                                      FUN_000cc090:000cc233(W), 
                                                                                      FUN_000cc090:000cc24b(W), 
                                                                                      008fea76(*)  
    000101f0 2e 72 64        IMAGE_SE
             61 74 61 
             00 00 18 
       000101f0 2e 72 64 61 74  char[8]   ".rdata"                Name          .rdata
                61 00 00
       000101f8 18 42 11 00     Misc                              Misc
       000101fc 00 f0 ad 00     ibo32     s_libgcc_s_dw2-1.dll_0  VirtualAddress = "libgcc_s_dw2-1.
       00010200 00 44 11 00     ddw       114400h                 SizeOfRawData                     XREF[6]:     000ca348(R), 000ca41c(R), 
                                                                                                                 000ca43f(W), 000ca703(R), 
                                                                                                                 FUN_000cc000:000cc051(W), 
                                                                                                                 FUN_000cc090:000cc233(W)  
       00010204 00 ce ad 00     ddw       ADCE00h                 PointerToRaw                      XREF[2]:     000ca439(R), 
                                                                                                                 FUN_000cc090:000cc24b(W)  
       00010208 00 00 00 00     ddw       0h                      PointerToRel                      XREF[2]:     FUN_000cc090:000cc214(*), 
                                                                                                                 008fea76(*)  
       0001020c 00 00 00 00     ddw       0h                      PointerToLin
       00010210 00 00           dw        0h                      NumberOfRelo
       00010212 00 00           dw        0h                      NumberOfLine
       00010214 40 00 60 40     SectionF  IMAGE_SCN_CNT_INITIALI  Characterist
    00010218 2f 31 39        IMAGE_SE
             00 00 00 
             00 00 d8 
       00010218 2f 31 39 00 00  char[8]   "/19"                   Name          .eh_frame
                00 00 00
       00010220 d8 4e 29 00     Misc                              Misc
       00010224 00 40 bf 00     ibo32     DAT_00c04000            VirtualAddress = 14h
       00010228 00 50 29 00     ddw       295000h                 SizeOfRawData
       0001022c 00 12 bf 00     ddw       BF1200h                 PointerToRaw
       00010230 00 00 00 00     ddw       0h                      PointerToRel
       00010234 00 00 00 00     ddw       0h                      PointerToLin
       00010238 00 00           dw        0h                      NumberOfRelo
       0001023a 00 00           dw        0h                      NumberOfLine
       0001023c 40 00 30 40     SectionF  IMAGE_SCN_CNT_INITIALI  Characterist
    00010240 2e 62 73        IMAGE_SE
             73 00 00 
             00 00 e0 
       00010240 2e 62 73 73 00  char[8]   ".bss"                  Name          .bss
                00 00 00
       00010248 e0 ab 37 00     Misc                              Misc
       0001024c 00 90 e8 00     ibo32     DAT_00e99000            VirtualAddress = ??
       00010250 00 00 00 00     ddw       0h                      SizeOfRawData
       00010254 00 00 00 00     ddw       0h                      PointerToRaw
       00010258 00 00 00 00     ddw       0h                      PointerToRel
       0001025c 00 00 00 00     ddw       0h                      PointerToLin
       00010260 00 00           dw        0h                      NumberOfRelo
       00010262 00 00           dw        0h                      NumberOfLine
       00010264 80 00 70 c0     SectionF  IMAGE_SCN_CNT_UNINITIA  Characterist
    00010268 2e 65 64        IMAGE_SE
             61 74 61 
             00 00 6b 
       00010268 2e 65 64 61 74  char[8]   ".edata"                Name          .edata
                61 00 00
       00010270 6b 59 00 00     Misc                              Misc
       00010274 00 40 20 01     ibo32     IMAGE_DIRECTORY_ENTRY_  VirtualAddress
       00010278 00 5a 00 00     ddw       5A00h                   SizeOfRawData
       0001027c 00 62 e8 00     ddw       E86200h                 PointerToRaw
       00010280 00 00 00 00     ddw       0h                      PointerToRel
       00010284 00 00 00 00     ddw       0h                      PointerToLin
       00010288 00 00           dw        0h                      NumberOfRelo
       0001028a 00 00           dw        0h                      NumberOfLine
       0001028c 40 00 30 40     SectionF  IMAGE_SCN_CNT_INITIALI  Characterist
    00010290 2e 69 64        IMAGE_SE
             61 74 61 
             00 00 f4 
       00010290 2e 69 64 61 74  char[8]   ".idata"                Name          .idata
                61 00 00
       00010298 f4 25 00 00     Misc                              Misc
       0001029c 00 a0 20 01     ibo32     DWORD_0121a000          VirtualAddress = 120A0C8h
       000102a0 00 26 00 00     ddw       2600h                   SizeOfRawData
       000102a4 00 bc e8 00     ddw       E8BC00h                 PointerToRaw
       000102a8 00 00 00 00     ddw       0h                      PointerToRel
       000102ac 00 00 00 00     ddw       0h                      PointerToLin
       000102b0 00 00           dw        0h                      NumberOfRelo
       000102b2 00 00           dw        0h                      NumberOfLine
       000102b4 40 00 30 c0     SectionF  IMAGE_SCN_CNT_INITIALI  Characterist
    000102b8 2e 43 52        IMAGE_SE
             54 00 00 
             00 00 18 
       000102b8 2e 43 52 54 00  char[8]   ".CRT"                  Name          .CRT
                00 00 00
       000102c0 18 00 00 00     Misc                              Misc
       000102c4 00 d0 20 01     ibo32     DAT_0121d000            VirtualAddress
       000102c8 00 02 00 00     ddw       200h                    SizeOfRawData
       000102cc 00 e2 e8 00     ddw       E8E200h                 PointerToRaw
       000102d0 00 00 00 00     ddw       0h                      PointerToRel
       000102d4 00 00 00 00     ddw       0h                      PointerToLin
       000102d8 00 00           dw        0h                      NumberOfRelo
       000102da 00 00           dw        0h                      NumberOfLine
       000102dc 40 00 30 c0     SectionF  IMAGE_SCN_CNT_INITIALI  Characterist
    000102e0 2e 74 6c        IMAGE_SE
             73 00 00 
             00 00 20 
       000102e0 2e 74 6c 73 00  char[8]   ".tls"                  Name          .tls
                00 00 00
       000102e8 20 00 00 00     Misc                              Misc
       000102ec 00 e0 20 01     ibo32     DAT_0121e000            VirtualAddress
       000102f0 00 02 00 00     ddw       200h                    SizeOfRawData
       000102f4 00 e4 e8 00     ddw       E8E400h                 PointerToRaw
       000102f8 00 00 00 00     ddw       0h                      PointerToRel
       000102fc 00 00 00 00     ddw       0h                      PointerToLin
       00010300 00 00           dw        0h                      NumberOfRelo
       00010302 00 00           dw        0h                      NumberOfLine
       00010304 40 00 30 c0     SectionF  IMAGE_SCN_CNT_INITIALI  Characterist
                         IMAGE_SECTION_HEADER_00010308.Misc              XREF[0,2]:   FUN_00437450:0043748b(*), 
                         IMAGE_SECTION_HEADER_00010308.PointerToLinenum               009b21d4(*)  
    00010308 2e 72 65        IMAGE_SE
             6c 6f 63 
             00 00 54 
       00010308 2e 72 65 6c 6f  char[8]   ".reloc"                Name          .reloc
                63 00 00
       00010310 54 8c 06 00     Misc                              Misc                              XREF[1]:     009b21d4(*)  
       00010314 00 f0 20 01     ibo32     DWORD_0121f000          VirtualAddress = 1000h
       00010318 00 8e 06 00     ddw       68E00h                  SizeOfRawData
       0001031c 00 e6 e8 00     ddw       E8E600h                 PointerToRaw
       00010320 00 00 00 00     ddw       0h                      PointerToRel
       00010324 00 00 00 00     ddw       0h                      PointerToLin                      XREF[0,1]:   FUN_00437450:0043748b(*)  
       00010328 00 00           dw        0h                      NumberOfRelo
       0001032a 00 00           dw        0h                      NumberOfLine
       0001032c 40 00 30 42     SectionF  IMAGE_SCN_CNT_INITIALI  Characterist
    00010330 2f 32 39        IMAGE_SE
             00 00 00 
             00 00 24 
       00010330 2f 32 39 00 00  char[8]   "/29"                   Name          .gnu_debuglink
                00 00 00
       00010338 24 00 00 00     Misc                              Misc
       0001033c 00 80 27 01     ibo32     s_libEmulateComms5580.  VirtualAddress = "libEmulateComms
       00010340 00 02 00 00     ddw       200h                    SizeOfRawData
       00010344 00 74 ef 00     ddw       EF7400h                 PointerToRaw
       00010348 00 00 00 00     ddw       0h                      PointerToRel
       0001034c 00 00 00 00     ddw       0h                      PointerToLin
       00010350 00 00           dw        0h                      NumberOfRelo
       00010352 00 00           dw        0h                      NumberOfLine
       00010354 40 00 30 42     SectionF  IMAGE_SCN_CNT_INITIALI  Characterist
    00010358 00              ??         00h
ryanmkurtz commented 1 year ago

It looks like since it is a 32-bit PE, we are reading the imagebase as an int, thinking it's bad that it's a negative number, and then forcing it to be 0x10000. I'll dig in deeper tonight but that is my initial thoughts. Are you getting a warning about a non-standard image base on import? When we output that warning, we force the imagebase to 0x10000.

RedOctober45 commented 1 year ago

It looks like since it is a 32-bit PE, we are reading the imagebase as an int, thinking it's bad that it's a negative number, and then forcing it to be 0x10000. I'll dig in deeper tonight but that is my initial thoughts. Are you getting a warning about a non-standard image base on import? When we output that warning, we force the imagebase to 0x10000.

Yeh, I see the following message before I click "ok" after I drag/drop the DLL into Ghidra to import but I don't see a warning anywhere else nor in the messages when the import is done.

image

ryanmkurtz commented 1 year ago

Ok, this is something we can work to improve. Is this just a normal userland DLL?

RedOctober45 commented 1 year ago

Ok, this is something we can work to improve. Is this just a normal userland DLL?

What do you mean?

ryanmkurtz commented 1 year ago

On 32-bit Windows virtual addresses above 0x80000000 are used by kernel space, as far as I know. I was wondering if this is kernel code vs userland code.

ryanmkurtz commented 1 year ago

I'm just trying to determine if this binary has any properties that would have caused it to have an imagebase >= 0x80000000, since that is something I guess we don't run into too often on 32-bit PE.

RedOctober45 commented 1 year ago

I'm just trying to determine if this binary has any properties that would have caused it to have an imagebase >= 0x80000000, since that is something I guess we don't run into too often on 32-bit PE.

Yeh, it is userland. The original base address use to be something like 0x5a000000 but it was shifted up due to some issue with ASLR in Windows causing problems with the executable that uses this DLL.

ryanmkurtz commented 1 year ago

What do you mean shifted up? You mean with the /BASE compiler flag?

ryanmkurtz commented 1 year ago

Also, for my own understanding, do you know what address it actually ends up at when loaded into memory?

RedOctober45 commented 1 year ago

It is set with --image-base (gcc compiler). I'd have to confirm directly but it should be loaded at that address. It was moved above the 3gb boundary to avoid conflicting with system libraries and it is a fixed address because there are persistency requirements meaning that when the program is restarted it expects to use the same memory locations. This program emulates an embedded control system in Windows so that is why it has that type of behavior.

ryanmkurtz commented 1 year ago

Ok, thank you. That explains everything nicely. Our team will have a discussion about how to prioritize supporting this type of PE.

ryanmkurtz commented 1 year ago

Looks like Visual Studio doesn't let you build with an imagebase >= 0x80000000 for 32-bit PE's. How are you building with gcc? Mingw?

RedOctober45 commented 1 year ago

Looks like Visual Studio doesn't let you build with an imagebase >= 0x80000000 for 32-bit PE's. How are you building with gcc? Mingw?

Yes, it is mingw.

ryanmkurtz commented 1 year ago

Ok, I was able to produce a rebased example to work with.

ryanmkurtz commented 1 year ago

Do you have any entries in the Ghidra relocation table for your binary? If so, are the original bytes for each entry based on the default image base or your custom image base?

RedOctober45 commented 1 year ago

Are you referring to the .reloc section? Yeh, looks like Ghidra is showing them at the default location too but starting at 0x0121f000, but the virtual address of the section is at 0xDB20F000 in the binary.

ryanmkurtz commented 1 year ago

I was referring more to Window -> Relocation Table in Ghidra. There is a column for original bytes. I was wondering if your original bytes were rebased properly in your PE from the start.

In the sample i produced which I based at 0xd0000000, the relocations still seem to be based at 0x40000. I am trying to determine if there is more I need to tell ld to do during the rebase or if your relocations look like that too.

RedOctober45 commented 1 year ago

Here's a screenshot from the top: image

ryanmkurtz commented 1 year ago

Thanks, that is very helpful. It looks like your binary has the correct relocations from the start, whereas mine doesn't for some reason. Would you be willing to share the command line arguments you are passing to gcc and ld so I can see exactly how you are rebasing the binary?

RedOctober45 commented 1 year ago

Here are some of the flags I got for the gcc and linker.

LINK_FLAGS: -Wl,--nxcompat -g3 -Wl,--exclude-all-symbols -Wl,--subsystem,windows,--dll,--image-base,0xDA000000 -Xlinker

GCC flags: -DARCH=nehalem -DBUILD_NOTE=\\"\\" -DCPU=generic -DDBG_PRINTS_ENABLED -DDIAGNOSTIC -DENABLE_DEBUG_SERVICES -DENABLE_DITS -DENABLE_SPY_OBJECT -DINTERNAL_DEVELOPMENT_BUILD -DMETRICS -DRSL=1 -DSLU_DEBUG -DUCS_ICE2 -DVB_CTRL -D__MSVCRT_VERSION__=0x0700 -g -O2 -fexceptions -fno-delete-null-pointer-checks -fno-ipa-sra -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-strict-aliasing -fno-strict-overflow -ggdb -m32 -march=nehalem -mtune=generic -mfpmath=sse -msse4.2 -fstack-protector-strong -Wall -Wextra -Wformat-security -Werror -fno-implement-inlines -fno-rtti -mno-ms-bitfields -std=c++14 -Weffc++ -Werror=effc++ -finstrument-functions

ryanmkurtz commented 1 year ago

Thanks!

ryanmkurtz commented 1 year ago

@RedOctober45 Would you mind trying the latest master branch to see if it suits your needs now?

RedOctober45 commented 1 year ago

@ryanmkurtz Yep, it looks good now. Thank you very much for your help!

ryanmkurtz commented 1 year ago

Excellent!