Why does the SVL Admin Service inject into processes?

By Stephen Kellett
12 June, 2024

Why does the SVL Admin Service inject into processes?

We were recently asked this question by a customer because their security team was concerned that this behaviour was unexpected and might be malicious.

In this article I’m going to describe every Software Verify process that injects into another process and explain why it is doing that.

Summary

Before I do that, here’s the summary:

  • We inject into other processes mainly to set environment variables that will allow .Net and .Net Core processes to load our .Net profiler. 
  • We inject into other processes mainly to delete environment variables that will allow .Net and .Net Core processes to load our .Net profiler.
  • We inject into other processes sometimes to attach to a native process to allow profiling of that process. This is the Inject into running process… option on the Launch menu.
  • We can also eject a DLL from a target process.

Setting Environment Variables

We set environment variables in a target process – used to set .Net Profiler environment variables.

  • We allocate some memory in the target process and setup the environment variables values we want to set.
  • We then create a remote thread in the target process and call the SetEnvironmentVariable() function (found in kernel32.dll in the target process) with a pointer to the memory setup previously.

Deleting Environment Variables

We delete environment variables in a target process – used to reset .Net Profiler environment variables.

  • We allocate some memory in the target process and setup the environment variables values we want to delete.
  • We then create a remote thread in the target process and call the SetEnvironmentVariable() function (found in kernel32.dll in the target process) with a pointer to the memory setup previously.

Injecting a DLL into a target process

We inject Software Verify DLLs into a target process – used to attach to processes that are already running.

    • We create a remote thread in the target process.
    • The thread loads the Software Verify DLL we want loaded.
    • The thread calls the function we want called in that DLL. There are two use cases for this.

Injecting a profiler into an application that is about to start

This is the Launch Application… option on the Launch menu.

We start the target application in a suspended state, then modify the entry point code to run our code that will load the native profiler before any other code gets executed. This allows us to monitor more of your application’s behaviour than any other method. It is also more reliable and doesn’t suffer from the risk of deadlocks that Injecting a profiler into a running application has.

Note that for this method we do not create a remote thread, it is not required.

The function called is “startProfiler” or “startProfilerEx”.

The DLL that will be injected depends on the software tool being used.

Bug Validator svlBugValidatorStub.dll
Coverage Validator x86 svlCoverageValidatorStub.dll
Coverage Validator x64 svlCoverageValidatorStub_x64.dll
Memory Validator x86 svlMemoryValidatorStub.dll
Memory Validator x64 svlMemoryValidatorStub_x64.dll
Performance Validator x86 svlPerformanceValidatorStub.dll
Performance Validator x64 svlPerformanceValidatorStub_x64.dll
Thread Validator x86 svlThreadValidatorStub.dll
Thread Validator x64 svlThreadValidatorStub_x64.dll

Injecting a profiler into a running application

This is the Inject into running process… option on the Launch menu.

There is a risk of deadlock with this method because it is impossible to know the state of locks and critical sections that are already active before you inject to a running application (not the same as attaching a debugger to a running application – the debugger is a separate process). We do note in the software documentation that you should always prefer Launch Application to Inject into running process.

The function called is “startProfiler” or “startProfilerEx”.

The DLL that will be injected depends on the software tool being used.

Bug Validator svlBugValidatorStub.dll
Coverage Validator x86 svlCoverageValidatorStub.dll
Coverage Validator x64 svlCoverageValidatorStub_x64.dll
Memory Validator x86 svlMemoryValidatorStub.dll
Memory Validator x64 svlMemoryValidatorStub_x64.dll
Performance Validator x86 svlPerformanceValidatorStub.dll
Performance Validator x64 svlPerformanceValidatorStub_x64.dll
Thread Validator x86 svlThreadValidatorStub.dll
Thread Validator x64 svlThreadValidatorStub_x64.dll

Injecting a DLL that sets some environment variables

Injecting a DLL that sets some environment variables via the DllMain() function.

There is no risk of deadlock injecting these DLLs, they do so little work you can’t trigger that sort of problem.

The DLL unloads immediately because once the environment variables are set it has no more work to do. 

Bug Validator svlBvSetEnv.dll
Coverage Validator x86 svlCvSetEnv.dll
Coverage Validator x64 svlCvSetEnv_x64.dll
Memory Validator x86 svlMvSetEnv.dll
Memory Validator x64 svlMvSetEnv_x64.dll
Performance Validator x86 svlPvSetEnv.dll
Performance Validator x64 svlPvSetEnv_x64.dll
Thread Validator x86 svlTvSetEnv.dll
Thread Validator x64 svlTvSetEnv_x64.dll

The above are used when working with ASP.Net. The processes injected into are:

mmc.exe Applications
cmd.exe Applications
explorer.exe Applications
inetinfo.exe Internet Information Server
services.exe Services
svchost.exe Services

The reasons these processes are injected into is because these are the processes that may launch other processes, and those processes inherit their environment variables from the process launching them.

The applications that may initiate this are:

  • bugValidator.exe
  • coverageValidator.exe
  • coverageValidator_x64.exe
  • memoryValidator.exe
  • memoryValidator_x64.exe
  • performanceValidator.exe
  • performanceValidator_x64.exe
  • threadValidator.exe
  • threadValidator_x64.exe

The services that may initiate this are:

  • svlAdminService.exe via svlInject.exe
  • svlAdminService.exe via svlInject_x64.exe
  • svlAdminService_x64.exe via svlInject.exe
  • svlAdminService_x64.exe via svlInject_x64.exe

These may also be called indirectly via the resetDotNetProfiler.exe tool which will reset all .Net Profiler environment variables.

Why do Bug Validator and Thread Validator set .Net profiler environment variables when these profilers only profile native code?

The reason for this is mixed mode .Net processes that execute both .Net and native code. If BV and TV are to profile the native code in these mixed mode processes we still need to load a .Net profiler into these processes so that the native profiling code can be loaded into the target process.

Why do x86 processes inject into x64 processes?

The reason for this is that on 64 bit systems it is most likely that a 64 bit process will start a 32 bit process that may be the target for the software tool you are using. We need to set the .Net profiling environment variables appropriately for that task. This is why svlAdminService.exe calls svlInject_x64.exe to inject 64 bit DLLs into 64 bit target processes.

Ejecting a DLL into a target process

We remove Software Verify DLLs from a target process – used to remove DLLs from a process that we have previously inject into a process.

  • We create a remote thread in the target process then call FreeLibrary() with the base address of the DLL in the target process.

Conclusion

Some of Software Verify’s software tools inject DLLs into other processes.

This is done to manage .Net Profiler environment variables, or to profile already running native applications when instructed to do so by the user of the software.

There is nothing malicious about this behaviour. It is by design, and is necessary for the correct functioning of the software when working with .Net, .Net Core and debugging applications that are already running.

 

Fully functional, free for 30 days