Washi1337 / OldRod

An automated KoiVM disassembler and devirtualisation utility
GNU General Public License v3.0
345 stars 80 forks source link

System.NullReferenceException: Object reference not set to an instance of an object #69

Closed 0x410c closed 11 months ago

0x410c commented 11 months ago

Describe the bug Bug in devirtualisation of code

To Reproduce use attached binary and config

Expected behavior a devirtualised output

Additional context

14:41:02.769 [VMMethodDetection]: Not all VM exports were mapped to physical method definitions (56 out of 76 were mapped). Dummies will be added to the assembly for the remaining exports.
14:41:02.769 [Main]: Executing OpCode mapping resolution stage...
14:41:02.770 [MappingResolver]: Finding opcode handlers using custom constant mapping is unsupported.
14:41:02.770 [Main]: Executing VM code recovery stage...
14:41:02.778 [InferenceDisasm]: Started disassembling function_15EED...
14:41:02.811 [TUI]: Something went wrong! Try the latest version or report a bug at the repository.
14:41:02.814 [TUI]: System.NullReferenceException: Object reference not set to an instance of an object.
   at OldRod.Core.Emulation.InstructionEmulator.EmulateInstruction(ILInstruction instruction)
   at OldRod.Core.Disassembly.Inference.InstructionProcessor.InferJumpTargets(ILInstruction instruction)
   at OldRod.Core.Disassembly.Inference.InstructionProcessor.PerformFlowControl(VMFunction function, ILInstruction instruction, List`1 nextStates, ProgramState next)
   at OldRod.Core.Disassembly.Inference.InstructionProcessor.GetNextStates(VMFunction function, ProgramState currentState, ILInstruction instruction, UInt32 nextKey)
   at OldRod.Core.Disassembly.Inference.InferenceDisassembler.ContinueDisassembly(VMFunction function, IEnumerable`1 initialStates)
   at OldRod.Core.Disassembly.Inference.InferenceDisassembler.ContinueDisassemblyForFunction(VMFunction function)
   at OldRod.Core.Disassembly.Inference.InferenceDisassembler.DisassembleFunctionsImpl()
   at OldRod.Core.Disassembly.Inference.InferenceDisassembler.DisassembleFunctions()
   at OldRod.Pipeline.Stages.VMCodeRecovery.VMCodeRecoveryStage.Run(DevirtualisationContext context)
   at OldRod.Pipeline.Devirtualiser.RunPipeline(DevirtualisationContext context)
   at OldRod.Pipeline.Devirtualiser.Devirtualise(DevirtualisationOptions options)
   at OldRod.Program.Main(String[] args)
14:41:02.815 [TUI]: Process finished with 3 warnings and 1 errors.

dec.zip

Washi1337 commented 11 months ago

Modifications of KoiVM will always result in problems with either the disassembly or recompilation process.

This error stems from a few instructions not being decoded properly. Specifically, it is trying to emulate a CALL instruction. For binaries protected by vanilla KoiVM this should never happen (see InstructionEmulator).

This is indicative of either:

Double check your cross-references with the opcode handlers and your config.json. I also added some simple safety guards in the latest commit (56fc436807c46f94ffc1c790b9d8426dae7be047, build should appear on AppVeyor soon), that should at least produce some results, and should enable you to use --salvage and --dump-il and/or --dump-cfg to help debugging which of the two hypotheses is the case.

0x410c commented 11 months ago

im mostly sure that the call opcode is correct, i also rechecked, i am sure later is the case as if i even skip the first function there are more changes which deter devirtualisation

0x410c commented 11 months ago

i was wrong, there was an ambiguity in opcodes i found, as the opcode handlers of 2 opcodes are exactly same and oldrod assumes end of function when opcode is recieved. thanks, devirtualisation works great! thanks for the aweosme work!