Rantanen / ghidra-minidump-loader

Windows Minidump loader for Ghidra

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

EOF exception when reading minidump

sqrtroot opened this issue · comments

Super cool project, I'm trying to load a binary that at run time unpacks itself into a new part of memory. The dump file gets correctly analysed with rizin but this project throws an eof error:

EOF
java.io.IOException: EOF
	at net.jubjubnest.minidump.loader.MinidumpMemoryProvider.readBytes(MinidumpMemoryProvider.java:81)
	at net.jubjubnest.minidump.loader.MinidumpMemoryProvider.readByte(MinidumpMemoryProvider.java:67)
	at ghidra.app.util.bin.ByteProviderWrapper.readByte(ByteProviderWrapper.java:106)
	at ghidra.app.util.bin.ByteProviderInputStream.read(ByteProviderInputStream.java:37)
	at java.base/java.io.InputStream.read(InputStream.java:284)
	at ghidra.util.MonitoredInputStream.read(MonitoredInputStream.java:128)
	at db.ChainedBuffer.fill(ChainedBuffer.java:1212)
	at db.DBBuffer.fill(DBBuffer.java:162)
	at ghidra.program.database.mem.FileBytesAdapterV0.createBuffers(FileBytesAdapterV0.java:177)
	at ghidra.program.database.mem.FileBytesAdapterV0.createFileBytes(FileBytesAdapterV0.java:76)
	at ghidra.program.database.mem.MemoryMapDB.createFileBytes(MemoryMapDB.java:2167)
	at ghidra.app.util.MemoryBlockUtils.createFileBytes(MemoryBlockUtils.java:353)
	at ghidra.app.util.MemoryBlockUtils.createFileBytes(MemoryBlockUtils.java:335)
	at net.jubjubnest.minidump.contrib.opinion.PeLoader.loadImage(PeLoader.java:150)
	at net.jubjubnest.minidump.loader.MinidumpLoader.loadPeImage(MinidumpLoader.java:269)
	at net.jubjubnest.minidump.loader.MinidumpLoader.loadModules(MinidumpLoader.java:248)
	at net.jubjubnest.minidump.loader.MinidumpLoader.load(MinidumpLoader.java:136)
	at ghidra.app.util.opinion.AbstractLibrarySupportLoader.doLoad(AbstractLibrarySupportLoader.java:347)
	at ghidra.app.util.opinion.AbstractLibrarySupportLoader.loadProgram(AbstractLibrarySupportLoader.java:83)
	at ghidra.app.util.opinion.AbstractProgramLoader.load(AbstractProgramLoader.java:112)
	at ghidra.plugin.importer.ImporterUtilities.importSingleFile(ImporterUtilities.java:400)
	at ghidra.plugin.importer.ImporterDialog.lambda$okCallback$7(ImporterDialog.java:351)
	at ghidra.util.task.TaskBuilder$TaskBuilderTask.run(TaskBuilder.java:306)
	at ghidra.util.task.Task.monitoredRun(Task.java:124)
	at ghidra.util.task.TaskRunner.lambda$startTaskThread$0(TaskRunner.java:106)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
	at java.base/java.lang.Thread.run(Thread.java:832)

---------------------------------------------------
Build Date: 2021-Aug-04 1256 EDT
Ghidra Version: 10.0.2
Java Home: C:\Program Files\Java\jdk-15.0.1
JVM Version: Oracle Corporation 15.0.1
OS: Windows 10 10.0 amd64

Unfortunately I haven't had much tests cases with dumps of programs that do weird things. A quick look at that stack would indicate the PE image header is not present in the dump, but it's probably more likely that the loader just doesn't understand the dump and gets confused.

I haven't touched the code base for almost a year, but I wouldn't mind getting back to it. Is there any chance you could share the dump so I could take a look at it?

Sure thing, I've made the dump with process explorer it is from the 2nd level of the MalwareBytes crackme
lvl2-in_thread.zip

Seems there's a portion of the PE image memory missing from the dump itself. Looking at the dump in Visual Studio, it shows the kernel32.dll should be loaded in memory in address range 0x77310000..0x77400000, but the memory starting from 0x77311000 is missing:
image

This might be kind of expected. As PE images get loaded in memory, they align themselves, which might leave pieces of memory unused. Such unused memory pages may not exist in the system, thus they are omitted from the dump.

At the same time the Ghidra PE loader (which this minidump loader uses) expects the data to be contiguous.

I'll see if I can fake that by claiming the memory is just filled with zeros or something else.

Pushed new implementation for the memory provider that assumes all memory is present and initialized to zero if it isn't present in the minidump.

This allows loading the dump you shared. The PE loader realizes its mistake and doesn't end up loading the missing pages either. Instead it skips from the end of the 77310000..77311000 page to the start of the .text segment at 77320000:
image

Yes works perfectly, thanks for all the help :D