protection region is long after VMProtectEnd tag and got unsupported instruction "db"

Issues related to VMProtect
Post Reply
yangxi
Posts: 6
Joined: Mon Oct 12, 2020 9:24 am

protection region is long after VMProtectEnd tag and got unsupported instruction "db"

Post by yangxi »

When I run VMProtect on the function below (either located by tags or by map file), it claims an error of unsupported instruction "db D6".

This is part of the source code:

Code: Select all

int MyClass::operator() (int, int, int64)
{
    VMProtectBeginUltra( "MyClassCallbackProtection" );
    const int status = atomic_read_from_some_position();
    if (status == 0) return 0;
    
    do
    {
    	parse_some_json();
        if (!check_some_state()) break;
        if (!check_other_state()) break;
        if (!check_last_state()) break;
        ...... many stuffs ......
        at_last_set_some_atomic();
    } while (false)
    
    compare_exchange_some_global_atomic_from_1_to_0();
    VMProtectEnd();
    return 1;
}
This is the part around beginning of protected code, exactly starts at VMProtectBeginUltra:

Code: Select all

008B7CA4 FF15 F0C48E00	call dword ptr [008EC4F0] → VMProtectSDK32.dll!VMProtectBeginUltra
008B7CAA 33C0	xor eax, eax
008B7CAC F0:0FC107	lock xadd [edi], eax
008B7CB0 33C9	xor ecx, ecx
008B7CB2 83C0 08	add eax, 08
008B7CB5 F0:0FC108	lock xadd [eax], ecx
008B7CB9 85C9	test ecx, ecx
008B7CBB 75 07	jnz 008B7CC4 ↓
008B7CBD 33C0	xor eax, eax
008B7CBF E9 69530000	jmp 008BD02D ↓
008B7CC4 8D81 38FFFFFF	lea eax, [ecx-000000C8]
This is the part around and after VMProtectEnd. Specifically, massive codes are inclucded after the end tag, and even after the function last return, and there has many stuffs that not look like instructions:

Code: Select all

008BD015 8BC8	mov ecx, eax
008BD017 33D2	xor edx, edx
008BD019 B8 01000000	mov eax, 00000001
008BD01E F0:0FB111	lock cmpxchg [ecx], edx
008BD022 FF15 F4C48E00	call dword ptr [008EC4F4] → VMProtectSDK32.dll!VMProtectEnd
008BD04A E8 5888FBFF	call 008758A7 → _abort
008BD04F 90	nop
008BD050 9D	popfd
008BD051 808B 00A47F8B 00	or byte ptr [ebx-74805C00], 00
008BD058 7F 7F	jnle 008BD0D9 ↓
008BD05A 8B00	mov eax, [eax]
008BD05C 1380 8B00CB80	adc eax, [eax-7F34FF75]
008BD062 8B00	mov eax, [eax]
008BD064 3282 8B00EE7F	xor al, [edx+7FEE008B]
008BD06A 8B00	mov eax, [eax]
008BD06C 8381 8B000482 8B	add dword ptr [ecx-7DFBFF75], -75
008BD073 006F 80	add [edi-80], ch
008BD076 8B00	mov eax, [eax]
008BD078 B1 81	mov cl, 81
008BD07A 8B00	mov eax, [eax]
008BD07C 27	daa
008BD07D 818B 0055818B 004AD08B	or dword ptr [ebx-747EAB00], 8BD04A00
008BD087 00F9	add cl, bh
008BD089 808B 00C97F8B 00	or byte ptr [ebx-74803700], 00
008BD090 D6	db D6
008BD0A0 0E848B00	dd 008B840E Case
008BD0A4 FA828B00	dd 008B82FA Case
008BD0A8 CC828B00	dd 008B82CC Case
008BD0AC 84838B00	dd 008B8384 Case
008BD0B0 3C848B00	dd 008B843C Case
008BD0B4 9A858B00	dd 008B859A Case
008BD0B8 56838B00	dd 008B8356 Case
008BD0BC F4848B00	dd 008B84F4 Case
008BD0C0 78858B00	dd 008B8578 Case
008BD0C4 E0838B00	dd 008B83E0 Case
008BD0C8 22858B00	dd 008B8522 Case
008BD0CC 98848B00	dd 008B8498 Case
008BD0D0 C6848B00	dd 008B84C6 Case
008BD0D4 4AD08B00	dd 008BD04A Case
008BD0D9 848B 0028838B	test [ebx-747CD800], cl
008BD0DF 004D 85	add [ebp-7B], cl
008BD0E2 8B00	mov eax, [eax]
008BD0E4 9E	sahf
008BD0E5 828B 00B2838B 00	or byte ptr [ebx-747C4E00], 00
008BD0EC 70 82	jo 008BD070 ↑
008BD0EE 8B00	mov eax, [eax]
008BD0F0 50	push eax
008BD0F1 888B 003C878B	mov [ebx-7478C400], cl
008BD0F7 000E	add [esi], cl
008BD0F9 878B 00C6878B	xchg [ebx-74783A00], ecx
008BD0FF 007E 88	add [esi-78], bh
008BD102 8B00	mov eax, [eax]
008BD104 EE	out dx, al
008BD105 898B 0098878B	mov [ebx-74786800], ecx
008BD10B 0036	add [esi], dh
008BD10D 898B 00C0898B	mov [ebx-74764000], ecx
008BD113 0022	add [edx], ah
008BD115 888B 0064898B	mov [ebx-74769C00], cl
008BD11B 00DA	add dl, bl
008BD11D 888B 0008898B	mov [ebx-7476F800], cl
008BD123 004A D0	add [edx-30], cl
008BD126 8B00	mov eax, [eax]
008BD128 AC	lodsb
008BD129 888B 006A878B	mov [ebx-74789600], cl
008BD12F 0092 898B00E9	add [edx-16FF7477], dl
008BD135 868B 00F4878B	xchg [ebx-74780C00], cl
008BD13B 00C4	add ah, al
008BD13D 868B 00C18B8B	xchg [ebx-74743F00], cl
008BD143 00B6 8A8B0088	add [esi-77FF7476], dh
008BD149 8A8B 00378B8B	mov cl, [ebx-7474C900]
008BD14F 00EF	add bh, ch
008BD151 8B8B 00298D8B	mov ecx, [ebx-7472D700]
008BD157 0009	add [ecx], cl
008BD159 8B8B 009E8C8B	mov ecx, [ebx-74736200]
008BD15F 0007	add [edi], al
008BD161 8D8B 00938B8B	lea ecx, [ebx-74746D00]
008BD167 00C3	add bl, al
008BD169 8C8B 004B8C8B	mov [ebx-7473B500], cs
008BD16F 0079 8C	add [ecx-74], bh
008BD172 8B00	mov eax, [eax]
008BD174 4A	dec edx
008BD175 D08B 001D8C8B	ror byte ptr [ebx-7473E300], 01
008BD17B 00DB	add bl, bl
008BD17D 8A8B 00E58C8B	mov cl, [ebx-74731B00]
008BD183 005A 8A	add [edx-76], bl
008BD186 8B00	mov eax, [eax]
008BD188 65:8B8B 002C8A8B	mov ecx, gs:[ebx-7475D400]
008BD18F 0031	add [ecx], dh
008BD191 92	xchg edx, eax
008BD192 8B00	mov eax, [eax]
008BD194 1D 918B00EF	sbb eax, EF008B91
008BD199 90	nop
008BD19A 8B00	mov eax, [eax]
008BD19C A7	cmpsd
008BD19D 91	xchg ecx, eax
008BD19E 8B00	mov eax, [eax]
008BD1A0 5F	pop edi
008BD1A1 92	xchg edx, eax
008BD1A2 8B00	mov eax, [eax]
008BD1A4 CF	iretd
008BD1E0 A2958B00	dd 008B95A2 Case
008BD1E4 97948B00	dd 008B9497 Case

...... massive lines of "Case"

008BD68C 1FCC8B00	dd 008BCC1F Case
035DBD40 22059319	dd 19930522 Magic
035DBD44 8E010000	dd 0000018E MaxState
035DBD48 64BD5D03	dd 035DBD64 UnwindMapEntry
035DBD4C 00000000	dd 00000000 TryBlocks
035DBD50 00000000	dd 00000000 TryBlockMapEntry
035DBD54 00000000	dd 00000000 IPMapEntries
035DBD58 00000000	dd 00000000 IPtoStateMap
035DBD5C 00000000	dd 00000000 ESTypeList
035DBD60 01000000	dd 00000001 Flags
035DBD64 FFFFFFFF	dd FFFFFFFF ToState
035DBD68 1C598E00	dd 008E591C Action
035DBD6C FFFFFFFF	dd FFFFFFFF ToState
035DBD70 27598E00	dd 008E5927 Action

...... massive lines of "ToState" and "Action"

035DC9CC 18010000	dd 00000118 ToState
035DC9D0 4E548E00	dd 008E544E Action
Admin
Site Admin
Posts: 2566
Joined: Mon Aug 21, 2006 8:19 pm
Location: Russia, E-burg
Contact:

Re: protection region is long after VMProtectEnd tag and got unsupported instruction "db"

Post by Admin »

Could you show the code of "_abort"? (008BD04A E8 5888FBFF call 008758A7 → _abort)
yangxi
Posts: 6
Joined: Mon Oct 12, 2020 9:24 am

Re: protection region is long after VMProtectEnd tag and got unsupported instruction "db"

Post by yangxi »

Admin wrote:Could you show the code of "_abort"? (008BD04A E8 5888FBFF call 008758A7 → _abort)
I recompiled the binary, the overall structure remains the same and it raises the same error, only the detailed address has slightly changed. Below are contents of _abort function:

Code: Select all

008759B7 E8 C17F0100	call 0088D97D → ___acrt_get_sigabrt_handler
008759BC 85C0	test eax, eax
008759BE 74 08	jz 008759C8 ↓
008759C0 6A 16	push 16
008759C2 E8 0D800100	call 0088D9D4 → _raise
008759C7 59	pop ecx
008759C8 F605 A0967603 02	test byte ptr [037696A0], 02
008759CF 74 22	jz 008759F3 ↓
008759D1 6A 17	push 17
008759D3 FF15 B8C08E00	call dword ptr [008EC0B8] → KERNEL32.dll!IsProcessorFeaturePresent
008759D9 85C0	test eax, eax
008759DB 74 05	jz 008759E2 ↓
008759DD 6A 07	push 07
008759DF 59	pop ecx
008759E0 CD 29	int 29
008759E2 6A 01	push 01
008759E4 68 15000040	push 40000015
008759E9 6A 03	push 03
008759EB E8 42FDFFFF	call 00875732 → ___acrt_call_reportfault
008759F0 83C4 0C	add esp, 0C
008759F3 6A 03	push 03
008759F5 E8 48350100	call 00888F42 → __exit
008759FA CC	int 03
Admin
Site Admin
Posts: 2566
Joined: Mon Aug 21, 2006 8:19 pm
Location: Russia, E-burg
Contact:

Re: protection region is long after VMProtectEnd tag and got unsupported instruction "db"

Post by Admin »

This problem occurs when VMProtect disassembles code after "call _abort". "_abort" is NORETURN function (it works like JMP) but VMProtect doesn't know about it.

The address "008BD04A" is catch/finnaly entry point (referenced from the "Action" field), so VMProtect started to disassemle the code from this address

Code: Select all

008BD022 FF15 F4C48E00   call dword ptr [008EC4F4] → VMProtectSDK32.dll!VMProtectEnd
... // there is no code between 008BD04A and 008BD022
008BD04A E8 5888FBFF   call 008758A7 → _abort
yangxi
Posts: 6
Joined: Mon Oct 12, 2020 9:24 am

Re: protection region is long after VMProtectEnd tag and got unsupported instruction "db"

Post by yangxi »

Admin wrote:This problem occurs when VMProtect disassembles code after "call _abort". "_abort" is NORETURN function (it works like JMP) but VMProtect doesn't know about it.

The address "008BD04A" is catch/finnaly entry point (referenced from the "Action" field), so VMProtect started to disassemle the code from this address

Code: Select all

008BD022 FF15 F4C48E00   call dword ptr [008EC4F4] → VMProtectSDK32.dll!VMProtectEnd
... // there is no code between 008BD04A and 008BD022
008BD04A E8 5888FBFF   call 008758A7 → _abort
The switch table and abort() is expanded from a inline function called inside protected region. This is much out of my imagination, as the call to inline function is at the front part of protected region, but the resultant call to abort() is even after the protection mark.

Nevertheless, is that means I shall not contain any abort() call in the finally generated code in protected region, or even the whole function containing protected region (as the actual location of abort() call may varied by optimizer)?

Or is there any way to make VMProtect work properly on that condition? I know VMProtect has a script system but never used it, does the script system allow such kind of fine-tuning?
Admin
Site Admin
Posts: 2566
Joined: Mon Aug 21, 2006 8:19 pm
Location: Russia, E-burg
Contact:

Re: protection region is long after VMProtectEnd tag and got unsupported instruction "db"

Post by Admin »

We are going to add the automatic detection of NORETURN functions in the next version.
Post Reply