Why does Avira consider "CoCreateInstance()" function as a malware? - c++

I have created c++ console application using visual studio 2017 which is extract .zip file. But, when I run application.exe file, Avira antivirus detects my exe as a malware.
I found CoCreateInstance(CLSID_Shell, NULL, CLSCTX_INPROC_SERVER, IID_IShellDispatch, (void **)&pISD) function where actual Avira create problem.
Why does Avira consider CoCreateInstance(CLSID_Shell, NULL, CLSCTX_INPROC_SERVER, IID_IShellDispatch, (void **)&pISD) function as a malware?
My Function:
bool Utils::Unzip2Folder(BSTR lpZipFile, BSTR lpFolder)
{
IShellDispatch *pISD;
Folder *pZippedFile = 0L;
Folder *pDestination = 0L;
long FilesCount = 0;
IDispatch* pItem = 0L;
FolderItems *pFilesInside = 0L;
VARIANT Options, OutFolder, InZipFile, Item;
CoInitialize(NULL);
__try {
if (CoCreateInstance(CLSID_Shell, NULL, CLSCTX_INPROC_SERVER, IID_IShellDispatch, (void **)&pISD) != S_OK)
return 1;
InZipFile.vt = VT_BSTR;
InZipFile.bstrVal = lpZipFile;
pISD->NameSpace(InZipFile, &pZippedFile);
if (!pZippedFile)
{
pISD->Release();
return 1;
}
OutFolder.vt = VT_BSTR;
OutFolder.bstrVal = lpFolder;
pISD->NameSpace(OutFolder, &pDestination);
if (!pDestination)
{
pZippedFile->Release();
pISD->Release();
return 1;
}
pZippedFile->Items(&pFilesInside);
if (!pFilesInside)
{
pDestination->Release();
pZippedFile->Release();
pISD->Release();
return 1;
}
pFilesInside->get_Count(&FilesCount);
if (FilesCount < 1)
{
pFilesInside->Release();
pDestination->Release();
pZippedFile->Release();
pISD->Release();
return 0;
}
pFilesInside->QueryInterface(IID_IDispatch, (void**)&pItem);
Item.vt = VT_DISPATCH;
Item.pdispVal = pItem;
Options.vt = VT_I4;
Options.lVal = 1024 | 512 | 16 | 4;//http://msdn.microsoft.com/en-us/library/bb787866(VS.85).aspx
bool retval = pDestination->CopyHere(Item, Options) == S_OK;
pItem->Release(); pItem = 0L;
pFilesInside->Release(); pFilesInside = 0L;
pDestination->Release(); pDestination = 0L;
pZippedFile->Release(); pZippedFile = 0L;
pISD->Release(); pISD = 0L;
return retval;
}
__finally
{
CoUninitialize();
}
}

There is no real good answer. Why AV systems detect some files as false positives.
Most of this false positives are based on some heuristic.
Small programs seam to be more problematic than larger ones.
Programs with less dependencies to other DLLs seams to be more problematic than complex EXE with dependencies.
Some mixes of API functions seem to be more problematic tahn other. Usage of more complex API functions and UI seem to be less problematic.
Signed executable are less risky for such heuristic traos in AV systems.
A lot of programs (and signatures of companies) are internally white listed. Your program is unknown.
This function is surely not the only API function you use. Check Depends and you find more!
Just add your exe path to the exclusion list of Avira... in the development phase of small tools I had to do this more than once.
Final tipp: Ask Avira and send them you file. They may change there heuristic pattern match so this is no longer a false positive.
I had this effects with Avira serval times.

Related

CLR host doesn't execute WPF applications but it does WinForms

I made a code very similar to https://code.msdn.microsoft.com/windowsdesktop/CppHostCLR-e6581ee0. The difference between both is that I'm loading the executable from memory while he's doing it from file. The other difference is that he calls some random method while I want to call Main method.
My goal is to be something like .NET Reactor's native loader.
The code works fine with Console Apps and WinForms. The only issue is that it won't load WPF applications and more specifically it fails on this line: pMethodInfo->Invoke_3(v2, p2, &v); with hr = 0x80131604 (COR_E_TARGETINVOCATION). The WPF project was created in VS 2019 and the targeting architecture (x86) and .NET Framework (4.0) match with loader's.
In the image below the Main function of the WPF application is present. I have literally no idea why it might be causing TargetInvocation.
Code here:
int LoadAssembly(LPVOID bytes, DWORD size)
{
HRESULT hr;
ICLRMetaHost* pMetaHost = NULL;
ICLRRuntimeInfo* pRuntimeInfo = NULL;
ICorRuntimeHost* pCorRuntimeHost = NULL;
IUnknownPtr UnkAppDomain = NULL;
_AppDomainPtr AppDomain = NULL;
_AssemblyPtr pAssembly = NULL;
_MethodInfoPtr pMethodInfo = NULL;
SAFEARRAY* params = NULL;
SAFEARRAY* sa = NULL;
bool bSuccess = false;
while (!bSuccess)
{
// STAThread
CoInitialize(NULL);
// Load and start the .NET runtime.
hr = CLRCreateInstance(CLSID_CLRMetaHost, IID_PPV_ARGS(&pMetaHost));
if (FAILED(hr))
break;
// Get the ICLRRuntimeInfo corresponding to a particular CLR version. It
// supersedes CorBindToRuntimeEx with STARTUP_LOADER_SAFEMODE.
hr = pMetaHost->GetRuntime(L"v4.0.30319", IID_PPV_ARGS(&pRuntimeInfo));
if (FAILED(hr))
break;
// Check if the specified runtime can be loaded into the process. This
// method will take into account other runtimes that may already be
// loaded into the process and set pbLoadable to TRUE if this runtime can
// be loaded in an in-process side-by-side fashion.
BOOL fLoadable;
hr = pRuntimeInfo->IsLoadable(&fLoadable);
if (FAILED(hr) || !fLoadable)
break;
// Load the CLR into the current process and return a runtime interface
// pointer. ICorRuntimeHost and ICLRRuntimeHost are the two CLR hosting
// interfaces supported by CLR 4.0. Here we demo the ICorRuntimeHost
// interface that was provided in .NET v1.x, and is compatible with all
// .NET Frameworks.
hr = pRuntimeInfo->GetInterface(CLSID_CorRuntimeHost, IID_PPV_ARGS(&pCorRuntimeHost));
if (FAILED(hr))
break;
// Start the CLR
hr = pCorRuntimeHost->Start();
if (FAILED(hr))
break;
// Get a pointer to the default AppDomain in the CLR
hr = pCorRuntimeHost->GetDefaultDomain(&UnkAppDomain);
if (FAILED(hr))
break;
hr = UnkAppDomain->QueryInterface(IID_PPV_ARGS(&AppDomain));
if (FAILED(hr))
break;
SAFEARRAYBOUND sab[1];
sab[0].lLbound = 0;
sab[0].cElements = size;
sa = SafeArrayCreate(VT_UI1, 1, sab);
if (!sa)
break;
void* sa_raw;
hr = SafeArrayAccessData(sa, &sa_raw);
if (FAILED(hr))
break;
memcpy(sa_raw, bytes, size);
SafeArrayUnaccessData(sa);
hr = AppDomain->Load_3(sa, &pAssembly);
if (FAILED(hr))
break;
hr = pAssembly->get_EntryPoint(&pMethodInfo);
if (FAILED(hr))
break;
SAFEARRAY* mtd_params;
hr = pMethodInfo->GetParameters(&mtd_params);
if (FAILED(hr))
break;
SAFEARRAY* p2;
if (mtd_params->rgsabound->cElements != 0)
{
INT argc;
WCHAR** _argv = CommandLineToArgvW(GetCommandLineW(), &argc);
params = SafeArrayCreateVector(VT_BSTR, 0, argc);
if (!params)
break;
for (int i = 0; i < argc; i++)
{
long lIndex = i;
hr = SafeArrayPutElement(params, &lIndex, SysAllocString(_argv[i]));
if (FAILED(hr))
break;
}
p2 = SafeArrayCreateVector(VT_VARIANT, 0, 1);
LONG l2 = 0;
VARIANT vp2;
vp2.vt = VT_ARRAY | VT_BSTR;
vp2.parray = params;
hr = SafeArrayPutElement(p2, &l2, &vp2);
if (FAILED(hr))
break;
}
else
{
SAFEARRAYBOUND sabc[1];
sabc[0].cElements = 0;
sabc[0].lLbound = 0;
p2 = SafeArrayCreate(VT_VARIANT, 1, sabc);
}
VARIANT v;
VARIANT v2;
VariantInit(&v);
VariantInit(&v2);
hr = pMethodInfo->Invoke_3(v2, p2, &v);
VariantClear(&v);
VariantClear(&v2);
if (FAILED(hr))
break;
bSuccess = true;
}
if (pMetaHost)
pMetaHost->Release();
if (pRuntimeInfo)
pRuntimeInfo->Release();
if (pCorRuntimeHost)
{
// Please note that after a call to Stop, the CLR cannot be
// reinitialized into the same process. This step is usually not
// necessary. You can leave the .NET runtime loaded in your process.
pCorRuntimeHost->Stop();
pCorRuntimeHost->Release();
}
if (sa)
SafeArrayDestroy(sa);
if (params)
SafeArrayDestroy(params);
return hr;
}
Edit:
I tried to load a WPF application from C# using System.Reflection and it didn't work. There is the code which nearly the same as my C++ one except that the C++ one fixes the arguments:
byte[] data = File.ReadAllBytes("Test2.exe");
Assembly assembly = Assembly.Load(data);
assembly.EntryPoint.Invoke(null, new object[0]);
This is the same error I received in C++'s code except that I'm not quite sure how to check for the Inner Exceptions there.
I did some research and I realized that I have to change ResourceAssembly as they did here: Load WPF application from the memory. The new code looked like this:
byte[] data = File.ReadAllBytes("Test2.exe");
Assembly assembly = Assembly.Load(data);
Type type = typeof(Application);
FieldInfo field = type.GetField("_resourceAssembly", BindingFlags.NonPublic | BindingFlags.Static);
field.SetValue(null, assembly);
Type helper = typeof(BaseUriHelper);
PropertyInfo property = helper.GetProperty("ResourceAssembly", BindingFlags.NonPublic | BindingFlags.Static);
property.SetValue(null, assembly, null);
assembly.EntryPoint.Invoke(null, new object[0]);
The result was that the code loaded the WPF application. Now, the question is how can I do that in my C++ code? Seems like nobody dealt with that issue. The only solution I found was by loading the file from disk and not memory - http://sbytestream.pythonanywhere.com/blog/clr-hosting.

IShellDispatch NameSpace-call fails, don't know why

First time working with COM from C++, been using C# and Delphi before.
So here's the code
HRESULT Result;
Result = CoInitialize(nullptr);
if (!SUCCEEDED(Result))
return Result;
IShellDispatch* API;
Result = CoCreateInstance(CLSID_Shell, nullptr, CLSCTX_INPROC_SERVER, IID_IShellDispatch, (void **)&API);
if ((!SUCCEEDED(Result)) || (nullptr == API))
goto Cleanup;
VARIANT Source1, Source2, Destination, Options;
VariantInit(&Destination);
Destination.vt = VT_BSTR;
Destination.bstrVal = SysAllocString(OutFile.c_str());
Folder* PDestination;
Result = API->NameSpace(Destination, &PDestination);
if (!SUCCEEDED(Result))
goto Cleanup;
VariantInit(&Source1);
VariantInit(&Source2);
Source1.vt = VT_BSTR;
Source2.vt = VT_BSTR;
Source1.bstrVal = SysAllocString(InFile1.c_str());
Source2.bstrVal = SysAllocString(InFile2.c_str());
VariantInit(&Options);
Options.vt = VT_I4;
Options.lVal = FOF_NO_UI;
PDestination->CopyHere(Source1, Options);
Sleep(1000);
PDestination->CopyHere(Source2, Options);
Sleep(1000);
PDestination->Release();
API->Release();
Cleanup:
CoUninitialize();
return Result;
OutFile, InFile1 and InFile2 are of type wstring as the program is (mostly) C++. I've managed to create an empty ZIP file, that's not the issue. The issue is that I get an exception claiming that PDestination is nullptr.
If it helps, the variants themselves seems to work. Inspecting them in the debugger yields the paths I provided. I've noticed though how the NameSpace-call returns an S_FALSE. Does anyone know what I can do about that?
Using a library doesn't exactly work, it's corporate code and there's some truly draconian rules when it comes to linking external code so using the Windows API is the easiest way.

CoCreateInstance creates empty IBaseFilter for CLSID_WavDest

I am trying to record .wav by using directshow framework in C++ Visual Studio 2010 project. I am following WAV file section of this guide: https://msdn.microsoft.com/en-us/library/windows/desktop/dd375005(v=vs.85).aspx
I have built WavDest.dll, added it to registry, found it in the registry, it can be added as filter in Graphedit. I had unresolved external symbol error for _CLSID_WavDest but had fixed it by including InitGuid.h in my StdAfx.h and by linking the WavDest.lib.
Now I get no errors, program doesn't crash, but I get 0 byte wav file.
Section of code:
res = AddFilterByCLSID(dshow_dev->m_pGraph, CLSID_WavDest, (IBaseFilter **)&dshow_dev->m_pWaveDest, L"WavDest");
res = AddFilterByCLSID(dshow_dev->m_pGraph, CLSID_FileWriter, (IBaseFilter **)&dshow_dev->m_pWaveWriter, L"File Writer");
res = dshow_dev->m_pWaveWriter->QueryInterface(IID_IFileSinkFilter, (void**)&dshow_dev->m_pFileSink);
res = dshow_dev->m_pFileSink->SetFileName(L"D:\\test.wav", NULL);
res = ConnectFilters(dshow_dev->m_pGraph, dshow_dev->m_pCaptureSourceAudio, dshow_dev->m_pWaveDest);
res = ConnectFilters(dshow_dev->m_pGraph, dshow_dev->m_pWaveDest, dshow_dev->m_pWaveWriter);
AddFilterByCLSID for CLSID_WavDest returns S_OK but dshow_dev->m_pWaveDest has following values: -
[CWavDestFilter] {m_cbWavData=0x00000000 m_cbHeader=0x00000000 } CWavDestFilter
.
Therefore, ConnectFilters for m_pWaveDest returns E_Fail and no audio is recorded.
I have tried this with both Debug and Release versions of WavDest.dll registered (first Debug, then unreg Debug and reg Release).
I have checked everything other in code, graph (dshow_dev->m_pGraph) runs fine for video preview and writing AVI file (with audio).
I am sure that that I did something wrong with WavDest integration but I don't know what.
Any help is appreciated.
It was my mistake after all. I have replaced
assert(pResult != NULL);
in this function
// Match a pin by pin direction and connection state.
HRESULT MatchPin(IPin *pPin, PIN_DIRECTION direction, BOOL bShouldBeConnected, BOOL *pResult)
{
assert(pResult != NULL);
BOOL bMatch = FALSE;
BOOL bIsConnected = FALSE;
HRESULT hr = IsPinConnected(pPin, &bIsConnected);
if (SUCCEEDED(hr))
{
if (bIsConnected == bShouldBeConnected)
{
hr = IsPinDirection(pPin, direction, &bMatch);
}
}
if (SUCCEEDED(hr))
{
*pResult = bMatch;
}
return hr;
}
with
if(pResult == NULL);
{
HRESULT hr = E_FAIL;
return hr;
}

ClrRuntimeHost->Start not functioning as expected

So I've create a project that uses a CLRRunTimeHost to suprise suprise host a managed library.
However I've run into a problem. When I run this it works absolutely fine with no hiccups, however after distributing it to a few people the error reports started to flow in. After around 11 hours just today I've figured out the source to be this. The entire function passes through fine, however, upon the last check or
hr = pClrRuntimeHost->Start();
It fails and doesn't start. I've talked and guided all of the people that are using it through library installs etc. and none can get it to work, I even gave the source to a close friend that has VS2015 installed and he fell victim to the same error.
Here's the full function:
ICLRRuntimeHost* StartCLR(LPCWSTR dotNetVersion)
{
HRESULT hr;
ICLRMetaHost* pClrMetaHost = NULL;
ICLRRuntimeInfo* pClrRuntimeInfo = NULL;
ICLRRuntimeHost* pClrRuntimeHost = NULL;
// Get the CLRMetaHost that tells us about .NET on this machine
hr = CLRCreateInstance(CLSID_CLRMetaHost, IID_ICLRMetaHost, (LPVOID*)&pClrMetaHost);
if (hr == S_OK)
{
// Get the runtime information for the particular version of .NET
hr = pClrMetaHost->GetRuntime(dotNetVersion, IID_PPV_ARGS(&pClrRuntimeInfo));
if (hr == S_OK)
{
// Check if the specified runtime can be loaded into the process. This
// method will take into account other runtimes that may already be
// loaded into the process and set pbLoadable to TRUE if this runtime can
// be loaded in an in-process side-by-side fashion.
BOOL fLoadable;
hr = pClrRuntimeInfo->IsLoadable(&fLoadable);
if ((hr == S_OK) && fLoadable)
{
// Load the CLR into the current process and return a runtime interface
// pointer.
hr = pClrRuntimeInfo->GetInterface(CLSID_CLRRuntimeHost,
IID_PPV_ARGS(&pClrRuntimeHost));
if (hr == S_OK)
{
// Start it. This is okay to call even if the CLR is already running
hr = pClrRuntimeHost->Start();
if (hr == S_OK)
{
// Success!
return pClrRuntimeHost;
}
}
}
}
}
// Cleanup if failed
if (pClrRuntimeHost)
{
pClrRuntimeHost->Release();
pClrRuntimeHost = NULL;
}
if (pClrRuntimeInfo)
{
pClrRuntimeInfo->Release();
pClrRuntimeInfo = NULL;
}
if (pClrMetaHost)
{
pClrMetaHost->Release();
pClrMetaHost = NULL;
}
return NULL;
}
And I'm calling it like this:
ICLRRuntimeHost* pClr = StartCLR(L"v4.0.30319");

How to globally mute and unmute sound in Vista and 7, and to get a mute state?

I'm using the old good Mixer API right now, but it does not work as expected on Windows Vista & 7 in the normal, not in XP compatibility mode. It mutes the sound for the current app only, but I need a global (hardware) mute. How to rearch the goal? Is there any way to code this w/o COM interfaces and strange calls, in pure C/C++?
The audio stack was significantly rewritten for Vista. Per-application volume and mute control was indeed one of the new features. Strange calls will be required to use the IAudioEndpointVolume interface.
I recently dealt with this same issue. We have a Windows application that uses the sound system for alarms. We cannot abide the user muting the sound system inadvertently. Here is how I was able to use the interface suggested above to address this issue:
During initialization I added a function to initialize a member of type IAudioEndpointVolume. It was a bit tricky and the help wasn't as helpful as it could be. Here's how to do it:
/****************************************************************************
** Initialize the Audio Endpoint (Only for post XP systems)
****************************************************************************/
void CMuteWatchdog::InitAudioEndPoint(void)
{
HRESULT hr;
IMMDeviceEnumerator * pDevEnum;
IMMDevice * pDev;
const CLSID CLSID_MMDeviceEnumerator = __uuidof(MMDeviceEnumerator);
const IID IID_IMMDeviceEnumerator = __uuidof(IMMDeviceEnumerator);
hr = CoCreateInstance(CLSID_MMDeviceEnumerator, NULL,
CLSCTX_ALL, IID_IMMDeviceEnumerator,
(void**)&pDevEnum);
m_pIaudEndPt = NULL;
if(hr == S_OK)
{
hr = pDevEnum->GetDefaultAudioEndpoint(eRender, eConsole, &pDev);
if(hr == S_OK)
{
DWORD dwClsCtx;
const IID iidAEV = __uuidof(IAudioEndpointVolume);
dwClsCtx = 0;
hr = pDev->Activate(iidAEV, dwClsCtx, NULL, (void**) &m_pIaudEndPt);
if(hr == S_OK)
{
// Everything is groovy.
}
else
{
m_pIaudEndPt = NULL; // Might mean it's running on XP or something. Don't use.
}
pDev->Release();
}
pDevEnum->Release();
}
}
...
About once per second I added a simple call to the following:
////////////////////////////////////////////////////////////////////////
// Watchdog function for mute.
void CMuteWatchdog::GuardMute(void)
{
if(m_pIaudEndPt)
{
BOOL bMute;
HRESULT hr;
bMute = FALSE;
hr = m_pIaudEndPt->GetMute(&bMute);
if(hr == S_OK)
{
if(bMute)
{
m_pIaudEndPt->SetMute(FALSE, NULL);
}
}
}
}
Finally, when the program exits just remember to release the allocated resource.
////////////////////////////////////////////////////////////////////////
// De-initialize the watchdog
void CMuteWatchdog::OnClose(void)
{
if(m_pIaudEndPt)
{
m_pIaudEndPt->Release();
m_pIaudEndPt = NULL;
}
}