Closed RedOctober45 closed 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?
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.
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?
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?
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
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.
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 be0x10000
. 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 to0x10000.
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.
Ok, this is something we can work to improve. Is this just a normal userland DLL?
Ok, this is something we can work to improve. Is this just a normal userland DLL?
What do you mean?
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.
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.
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.
What do you mean shifted up? You mean with the /BASE
compiler flag?
Also, for my own understanding, do you know what address it actually ends up at when loaded into memory?
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.
Ok, thank you. That explains everything nicely. Our team will have a discussion about how to prioritize supporting this type of PE.
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?
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.
Ok, I was able to produce a rebased example to work with.
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?
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.
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.
Here's a screenshot from the top:
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?
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
Thanks!
@RedOctober45 Would you mind trying the latest master
branch to see if it suits your needs now?
@ryanmkurtz Yep, it looks good now. Thank you very much for your help!
Excellent!
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