If your Olly is crashing when loading executable protected by VMProtect, you most likely have outdated dbghelp.dll somewhere on your path. Grab the latest version from Microsoft and put it in the Olly folder.
Well, that might be enough to work around the issue that I had - but I still wanted to know what's causing the crash.
Cause of the problem
If you try to debug Olly with another Olly, you'll see the Access Violation happening somewhere in dbghelp.dll:
Log data, item 0 Address=6D529B91 Message=Access violation when reading [C4983C3E]
6D529B8E 8B55 F4 MOV EDX,DWORD PTR SS:[EBP-C] 6D529B91 66:833C42 00 CMP WORD PTR DS:[EDX+EAX*2],0 6D529B96 75 07 JNZ SHORT DBGHELP.6D529B9F
Check register values in Olly:
EAX 00000000 <---------------- ECX 00000001 EDX C4983C3E <---------------- EBX 0458A390 ESP 0018A450 EBP 0018AC94 ESI 045EE7E8 EDI 045EF738 EIP 6D529B91 DBGHELP.6D529B91
For some reason, value in EDX is garbage and therefore access violation happens.
Call stack doesn't tell us much:
Call stack of main thread Procedure / arguments Called from Name from PDB DBGHELP.6D52997D DBGHELP.6D52ACFD LoadExportSymbols(struct _MODULE_ENTRY *, struct _IMGHLP_DEBUG_DATA *) DBGHELP.6D52A755 DBGHELP.6D52B035 load(char *, DWORD) DBGHELP.6D52ADB8 DBGHELP.6D5264B2 InternalLoadModule(char *, char *FullPath, char *Str1, unsigned __int64, unsigned __int32, void *, struct _DBGHELP_MODLOAD_DATA *, unsigned __int32) DBGHELP.SymLoadModuleEx DBGHELP.6D526502 DBGHELP.SymLoadModule64 DBGHELP.6D526522 DBGHELP.SymLoadModule OLLYDBG.00491502
And same piece of code in IDA doesn't help much either:
.text:6D529B8E loop_check_something: ; CODE XREF: LoadExportSymbols(_MODULE_ENTRY *,_IMGHLP_DEBUG_DATA *)+225j .text:6D529B8E mov edx, [ebp+ptrAllocatedMemory] .text:6D529B91 cmp word ptr [edx+eax*2], 0 ; <---------------- .text:6D529B96 jnz short loc_6D529B9F .text:6D529B98 add [ebp+var_10], 10h .text:6D529B9C inc [ebp+arg_4] .text:6D529B9F .text:6D529B9F loc_6D529B9F: ; CODE XREF: LoadExportSymbols(_MODULE_ENTRY *,_IMGHLP_DEBUG_DATA *)+219j .text:6D529B9F inc eax .text:6D529BA0 cmp eax, ecx .text:6D529BA2 jb short loop_check_something
So, it's debugging time! Set breakpoint to start of LoadExportSymbols, then set hardware breakpoint on write to address [ebp+ptrAllocatedMemory].
First hit is initialization of variable with 0:
.text:6D529986 xor ecx, ecx .text:6D529988 test byte ptr dword_6D57F438+1, 4 .text:6D52998F mov [ebp+ptrAllocatedMemory], ecx
Second hit stores the address of allocated memory:
.text:6D529AA7 call _pMemAlloc@4 ; pMemAlloc(x) .text:6D529AAC xor ecx, ecx .text:6D529AAE cmp eax, ecx .text:6D529AB0 mov [ebp+ptrAllocatedMemory], eax .text:6D529AB3 jz loc_6D529D56
And third time is a charm:
.text:6D529AF5 lea edx, [ebp+exportFunctionName] ; 0018A45C .text:6D529AFB sub edx, eax ; EDX = FBAD009A .text:6D529AFD .text:6D529AFD loop_strcpy_overflows: ; CODE XREF: LoadExportSymbols(_MODULE_ENTRY *,_IMGHLP_DEBUG_DATA *)+188j .text:6D529AFD mov cl, [eax] .text:6D529AFF mov [edx+eax], cl ; <---------------- .text:6D529B02 inc eax .text:6D529B03 test cl, cl .text:6D529B05 jnz short loop_strcpy_overflows
Good folks at Microsoft have left us with a nice buffer overflow. exportFunctionName is defined as byte array of size 2048 bytes. Any exported function name longer than that will cause stack overflow and (possibly) subsequent crash.
010Editor with PETemplate confirms that the export name is indeed very long (3100 chars):
From what I can tell, it's a similar (but not the same) bug to what was described by j00ru at http://j00ru.vexillium.org/?p=405 (see "PE Image Fuzzing (environment + process)")
Stay safe!
P.S Here's an example file, if you want to test your Olly: https://forum.tuts4you.com/topic/38963-vmprotect-professional-v-309-custom-protection/
P.P.S. CFF Explorer, HIEW and IDA do not show us any exports in this example file - but that's a matter of another story..