News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Text to Speech access violation

Started by jj2007, December 17, 2018, 09:48:09 PM

Previous topic - Next topic

jj2007

Marinus posted a cute TTS example here five years ago. When playing with it, I noticed that it works fine as long as you don't debug it. The exception happens here (Win7-64):
InterlockedDecreme Ú$  8B4C24 04         mov ecx, [esp+4]                        ; KERNELBASE.InterlockedDecrement(guessed Arg1)
77666A98           ³.  B8 FFFFFFFF       mov eax, -1
77666A9D           ³.  F0:0FC101         lock xadd [ecx], eax
77666AA1           ³.  48                dec eax
77666AA2           À.  C2 0400           retn 4


Chasing the problem is a bit difficult because InterlockedDecrement gets called a Million times. Any idea if this is a bug, a feature, whatever?

P.S.: No crash in my XP VM (but the voice is awful). On Win10, it works fine in normal mode but crashes when debugging. And surprisingly, the voice is female and talks Italian. On my Italian Win7-64, the voice is male and talks English.

LiaoMi

Hi,

on my windows 10 enterprise everything works as it should, code can be debugged, only if you do not enter the system libraries, otherwise, the debugger interacts with system exceptions, and you get exceptions like yours, this can be corrected, you can add regions that exclude exception handling in the debugger program...  :t

jj2007

Thanks, I've tried (Olly 2.0) to add the InterlockedDecrement range, to ignore all access violations, nothing works :(

Siekmanski

Interesting phenomenon, maybe we can use it as an anti debug feature?
Creative coders use backward thinking techniques as a strategy.

jj2007

Yep, turn a bug into a feature :t

Still, I would like to understand what causes the exception... does anybody have ISpVoice::Speak code that does not trigger this exception when being debugged?

LiaoMi

Example
The following is an example to enumerate all the available voices registered under HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech\Voices.

// Declare local identifiers:
HRESULT                        hr = S_OK;
CComPtr<ISpObjectToken>        cpVoiceToken;
CComPtr<IEnumSpObjectTokens>   cpEnum;
CComPtr<ISpVoice>              cpVoice;
ULONG                          ulCount = 0;

// Create the SAPI voice.
hr = cpVoice.CoCreateInstance(CLSID_SpVoice);

if (SUCCEEDED (hr))
{
   // Enumerate the available voices.
   hr = SpEnumTokens(SPCAT_VOICES, NULL, NULL, &cpEnum;);
}

if (SUCCEEDED (hr))
{
   // Get the number of voices.
   hr = cpEnum->GetCount(&ulCount;);
}

// Obtain a list of available voice tokens, set
// the voice to the token, and call Speak.
while (SUCCEEDED(hr) && ulCount--)
{
   cpVoiceToken.Release();

   if (SUCCEEDED (hr))
   {
      hr = cpEnum->Next(1, &cpVoiceToken;, NULL);
   }

   if (SUCCEEDED (hr))
   {
      hr = cpVoice->SetVoice(cpVoiceToken);
   }

   if (SUCCEEDED (hr))
   {
      hr = cpVoice->Speak( L"How are you?", SPF_DEFAULT, NULL );
   }

}

if (SUCCEEDED (hr))
{
   // Do more stuff here.
}


Probably not all exceptions are added, x64dbg produce the same reaction?

TimoVJL

#6
For poasm:.486
.model flat, stdcall

extern stdcall _imp__CoInitialize@4 :proc
extern stdcall _imp__CoCreateInstance@20 :proc
extern stdcall _imp__CoUninitialize@0 :proc
extern stdcall _imp__ExitProcess@4 :proc

includelib kernel32.lib
includelib ole32.lib

GUID STRUCT
Data1 dd ?
Data2 dw ?
Data3 dw  ?
Data4 db 8 dup(?)
GUID ENDS

.data
CLSID_SpVoice  GUID {096749377h,03391h,011D2h,<09Eh,0E3h,000h,0C0h,04Fh,079h,073h,096h>}
IID_ISpVoice   GUID {06C44DF74h,072B9h,04992h,<0A1h,0ECh,0EFh,099h,06Eh,004h,022h,0D4h>}
msg dw 'H', 'e', 'l', 'l', 'o', 0

.code
_WinMainCRTStartup proc C
push ebp
mov ebp, esp
sub esp, 4h
mov dword ptr [ebp-4h], 0h
push 0h
call dword ptr [_imp__CoInitialize@4]
lea eax, [ebp-4h]
push eax
push offset IID_ISpVoice
push 17h
push 0h
push offset CLSID_SpVoice
call dword ptr [_imp__CoCreateInstance@20]
test eax, eax
jl L_57
push 0h
push 0h
push offset msg
push dword ptr [ebp-4h]
mov eax, dword ptr [ebp-4h]
mov eax, dword ptr [eax]
call dword ptr [eax+50h]
push dword ptr [ebp-4h]
mov eax, dword ptr [ebp-4h]
mov eax, dword ptr [eax]
call dword ptr [eax+8h]
mov dword ptr [ebp-4h], 0h
L_57:
call dword ptr [_imp__CoUninitialize@0]
push 0h
call dword ptr [_imp__ExitProcess@4]
mov esp, ebp
pop ebp
ret
_WinMainCRTStartup endp
end
Exceptions:Error code: (Win32) 0x6ba (1722) - The RPC server is unavailable.
Error code: (Win32) 0x71a (1818) - The remote procedure call was cancelled.
May the source be with you