r77-rootkit icon indicating copy to clipboard operation
r77-rootkit copied to clipboard

behavior under antivirus

Open wineggdrop opened this issue 8 months ago • 6 comments
trafficstars

https://github.com/user-attachments/assets/b201c6b5-6c82-42ec-aca5-4daf3371632e

Kaspersky is running,console application acting weird,gui application performs normal.Not sure why

BTW,the CreatePublicNamePipe() function need to free some resource like the PSID valiable and etc Also,I am thinking that the injection from helper service process pooling(every 100 ms) and the NtResumeThread Injection are possibly running into race condition or even double injection if read/write process header at the same exact time.

wineggdrop avatar Mar 23 '25 19:03 wineggdrop

That's really weird...

Can you try to disable periodic process injection and see it this error persists? Then we could know whether or not this is a race condition:

//NewProcessListenerThread = NewProcessListener(NewProcessCallback);

Or if this makes no difference, try to disable the line above this one instead. It any of this fixes the issue, then tere is, indeed, a race condition that needs to be addressed.

Let me know about the result.

bytecode77 avatar Mar 25 '25 06:03 bytecode77

Disable the pooling injection result the same when Kaspersky is on,probably Kaspersky causes it.However,the race condition possibly would happen in chance,just in rare condition since detecting if process is hooked based on Read process memory call and no prevention from prohibiting more than one process calling ReadProcessMemory() at the same time on the same target at the same address

wineggdrop avatar Mar 25 '25 18:03 wineggdrop

Yes, in theory when a process is injected twice in the exact same moment, this condition could be satisfied, resulting in r77 loading twice.

// Do not write the signature, if this process already has an r77 signature.
if (*signaturePtr != R77_SIGNATURE && *signaturePtr != R77_SERVICE_SIGNATURE && *signaturePtr != R77_HELPER_SIGNATURE)
{
	DWORD oldProtect;
	if (VirtualProtectEx(GetCurrentProcess(), module, 512, PAGE_READWRITE, &oldProtect))
	{
		// The current process is now marked as injected and therefore, cannot be injected again.
		*signaturePtr = signature;

		// Write a function pointer that can be invoked using NtCreateThreadEx to detach the injected library gracefully.
		*(PDWORD64)&module[sizeof(IMAGE_DOS_HEADER) + 2] = (DWORD64)detachAddress;

		VirtualProtectEx(GetCurrentProcess(), module, 512, oldProtect, &oldProtect);
		result = TRUE;
	}
}

As undesired as this is, it is just as unlikely. Double injection is supported and usually happens with enough time in-between.

I suspect that the hooks of Kaspersky are interfering with the r77 hooks.

bytecode77 avatar Mar 27 '25 13:03 bytecode77

Yes, in theory when a process is injected twice in the exact same moment, this condition could be satisfied, resulting in r77 loading twice.

// Do not write the signature, if this process already has an r77 signature.
if (*signaturePtr != R77_SIGNATURE && *signaturePtr != R77_SERVICE_SIGNATURE && *signaturePtr != R77_HELPER_SIGNATURE)
{
	DWORD oldProtect;
	if (VirtualProtectEx(GetCurrentProcess(), module, 512, PAGE_READWRITE, &oldProtect))
	{
		// The current process is now marked as injected and therefore, cannot be injected again.
		*signaturePtr = signature;

		// Write a function pointer that can be invoked using NtCreateThreadEx to detach the injected library gracefully.
		*(PDWORD64)&module[sizeof(IMAGE_DOS_HEADER) + 2] = (DWORD64)detachAddress;

		VirtualProtectEx(GetCurrentProcess(), module, 512, oldProtect, &oldProtect);
		result = TRUE;
	}
}

As undesired as this is, it is just as unlikely. Double injection is supported and usually happens with enough time in-between.

I suspect that the hooks of Kaspersky are interfering with the r77 hooks.

I know it's unlikely caused by double injection which is possible in rare condition;however,the above code can only prevent from nesting hook since the header check after the dll data already injected into the target process,so double injection is still possible in theory,but no nesting hook.

wineggdrop avatar Mar 27 '25 18:03 wineggdrop

When the r77 DLL is injected but the header is already present, then DllMain returns false, and injection ends there. So, double injection really refers to installing the hooks multiple times, which of course is a recipe for desaster. That's possibly what you're observing with Kaspersky. I suspect that it installs some usermode hooks.

bytecode77 avatar Mar 27 '25 21:03 bytecode77

When the r77 DLL is injected but the header is already present, then DllMain returns false, and injection ends there. So, double injection really refers to installing the hooks multiple times, which of course is a recipe for desaster. That's possibly what you're observing with Kaspersky. I suspect that it installs some usermode hooks.

I just create a mutex with process Id as part of the mutex name to check if more than one process or thread is trying to do the injection at the same time by the return value of CreateMutex() and GetLastError()

wineggdrop avatar Mar 27 '25 22:03 wineggdrop