Exemple #1
0
BOOL engine_UnHookFunctionInProcess(HANDLE hProcess,LPSTR lpModuleName,LPSTR lpFunctionName,LPVOID lpOldFunctionAddress,DWORD dwFunctionSize)
{
	LPVOID lpModule=NULL;
	LPVOID lpFunction=NULL;
	MEMORY_BASIC_INFORMATION mbi;
	CHAR   lpLocalStub[MAX_FUNC_LEN*2];
	DWORD  dwFree=0;
	DWORD  dwBytesWritten;
	
	// Get module address
	lpModule=(LPVOID)engine_GetRemoteModuleHandle(hProcess,lpModuleName);
	if (!lpModule)
		return FALSE;
		
	// Get function address
	lpFunction=engine_GetRemoteProcAddress(hProcess,lpModule,lpFunctionName);
	if (!lpFunction)
		return FALSE;

	// Get info about the function address
	if (!NT_SUCCESS(SafeNtQueryVirtualMemory(hProcess,lpFunction,MemoryBasicInformation,&mbi,sizeof(mbi),NULL)))
		return FALSE;

	// Flush instruction cache
	NtFlushInstructionCache(hProcess,mbi.BaseAddress,mbi.RegionSize);

	// Change the protection for the region
	if (!NT_SUCCESS(NtProtectVirtualMemory(hProcess,&mbi.BaseAddress,&mbi.RegionSize,PAGE_EXECUTE_READWRITE,&mbi.Protect)))
		return FALSE;

	// Read old functions instructions
	if (!NT_SUCCESS(SafeNtReadVirtualMemory(hProcess,lpOldFunctionAddress,lpLocalStub,dwFunctionSize,NULL)))
	{
		// restore protection
		NtProtectVirtualMemory(hProcess,&mbi.BaseAddress,&mbi.RegionSize,mbi.Protect,NULL);
		return FALSE;
	}

	// Restore original function
	if (!NT_SUCCESS(NtWriteVirtualMemory(hProcess,lpFunction,lpLocalStub,dwFunctionSize,&dwBytesWritten)))
	{
		// restore protection
		NtProtectVirtualMemory(hProcess,&mbi.BaseAddress,&mbi.RegionSize,mbi.Protect,NULL);
		return FALSE;
	}

	// Free stub memory
	NtFreeVirtualMemory(hProcess,&lpOldFunctionAddress,&dwFree,MEM_RELEASE);

	// Restore protection
	NtProtectVirtualMemory(hProcess,&mbi.BaseAddress,&mbi.RegionSize,mbi.Protect,NULL);

	return TRUE;
}
Exemple #2
0
/*
 * @implemented
 */
BOOL
WINAPI
FlushInstructionCache(HANDLE hProcess,
                      LPCVOID lpBaseAddress,
                      SIZE_T dwSize)
{
    NTSTATUS Status;

    Status = NtFlushInstructionCache(hProcess,
                                     (PVOID)lpBaseAddress,
                                     dwSize);
    if (!NT_SUCCESS(Status))
    {
        SetLastErrorByStatus(Status);
        return FALSE;
    }

    return TRUE;
}
Exemple #3
0
LPVOID engine_HookFunctionInProcess(HANDLE hProcess,LPSTR lpModuleName,LPSTR lpFunctionName,LPVOID lpHookFunctionAddress,PDWORD pdwHookFunctionSize,LPVOID* lpFunctionAddress,INT iRndJmp)
{
	LPVOID lpModule=NULL;
	LPVOID lpFunction=NULL;
	MEMORY_BASIC_INFORMATION mbi;
	CHAR  lpTmpFunction[MAX_FUNC_LEN*2];
	CHAR  lpLocalStub[MAX_FUNC_LEN*3];
	CHAR  lpLocalFunc[MAX_FUNC_LEN*3];
	DWORD dwBytesRead;
	DWORD dwReadLen=0;
	DWORD dwExistingJMP=0;
	DWORD dwStubSize;
	DWORD dwFree=0;
	DWORD dwBytesWritten;
	DWORD dwOldProtect;

	LPVOID lpRemoteStub=NULL;
	INT   iFuncLen;
	PBYTE pReadAddress;
	NTSTATUS ntStatus;

	// Get module address
	lpModule=(LPVOID)engine_GetRemoteModuleHandle(hProcess,lpModuleName);
	if (!lpModule)
		return NULL;
		
	// Get function address
	lpFunction=engine_GetRemoteProcAddress(hProcess,lpModule,lpFunctionName);
	if (!lpFunction)
		return NULL;

	// Get info about the function address
	if (!NT_SUCCESS(SafeNtQueryVirtualMemory(hProcess,lpFunction,MemoryBasicInformation,&mbi,sizeof(mbi),NULL)))
		return NULL;

	// Flush instruction cache
	NtFlushInstructionCache(hProcess,mbi.BaseAddress,mbi.RegionSize);

	// Change the protection for the region
	if (!NT_SUCCESS(NtProtectVirtualMemory(hProcess,&mbi.BaseAddress,&mbi.RegionSize,PAGE_EXECUTE_READWRITE,&mbi.Protect)))
		return NULL;

	// Fill stub buffer with nops
	RtlFillMemory(lpLocalStub,MAX_FUNC_LEN*3,NOP);

	// Read MAX_FUNC_LEN instruction(s) from the function into our function buffer
	if (!NT_SUCCESS(SafeNtReadVirtualMemory(hProcess,lpFunction,lpTmpFunction,MAX_FUNC_LEN*2,&dwBytesRead)))
	{
		NtProtectVirtualMemory(hProcess,&mbi.BaseAddress,&mbi.RegionSize,mbi.Protect,NULL);
		return NULL;
	}

	pReadAddress=(PBYTE)lpTmpFunction;

	// check if first opcode in the function is a another jump
	if (*pReadAddress==LONG_JMP_OPCODE)
	{
		// get relative address
		memcpy(&dwExistingJMP,pReadAddress+1,4);
		// get absolute address
		dwExistingJMP=(DWORD)lpFunction+dwExistingJMP;
		// readlen
		dwReadLen=jtJmpTable[RELATIVE_JMP].iCodeSize

		engine_BuildJMPBuffer((CHAR*)lpLocalStub,((DWORD)lpRemoteStub+dwReadLen)-dwExistingJMP,RELATIVE_JMP);

		NtProtectVirtualMemory(hProcess,&mbi.BaseAddress,&mbi.RegionSize,mbi.Protect,NULL);
		return NULL;
	}

	// Get the length of the first instruction(s)
	// This part is done by Z0MBiE's LDE32 v1.05
	iFuncLen=disasm_main(pReadAddress); // get first instruction length
	while (iFuncLen!=-1 && dwReadLen<(DWORD)jtJmpTable[iRndJmp].iCodeSize)
	{
		dwReadLen+=iFuncLen;
		pReadAddress+=iFuncLen;
		iFuncLen=disasm_main(pReadAddress); // next instruction length
	}

	// API code is too short or too long too hook this way (for now ;))
	if (dwReadLen<(DWORD)jtJmpTable[iRndJmp].iCodeSize||dwReadLen>MAX_FUNC_LEN*2)
	{
		NtProtectVirtualMemory(hProcess,&mbi.BaseAddress,&mbi.RegionSize,mbi.Protect,NULL);
		return NULL;
	}

	// Read the first instruction(s) from the function into our stub buffer
	if (!NT_SUCCESS(SafeNtReadVirtualMemory(hProcess,lpFunction,lpLocalStub,dwReadLen,&dwBytesRead)))
	{	
		NtProtectVirtualMemory(hProcess,&mbi.BaseAddress,&mbi.RegionSize,mbi.Protect,NULL);
		return NULL;
	}

	// Allocate space with read/write access for our "stub"
	// note: always use a relative jump for our stub -> RELATIVE_JMP

	dwStubSize=dwReadLen+jtJmpTable[RELATIVE_JMP].iCodeSize;
	if (!NT_SUCCESS(NtAllocateVirtualMemory(hProcess,&lpRemoteStub,0,&dwStubSize,MEM_COMMIT|MEM_TOP_DOWN,PAGE_READWRITE)))
	{	
		NtProtectVirtualMemory(hProcess,&mbi.BaseAddress,&mbi.RegionSize,mbi.Protect,NULL);
		return NULL;
	}

	// Check
	if (dwStubSize<dwReadLen+jtJmpTable[RELATIVE_JMP].iCodeSize)
	{
		NtProtectVirtualMemory(hProcess,&mbi.BaseAddress,&mbi.RegionSize,mbi.Protect,NULL);
		
		// Free allocated buffer
		NtFreeVirtualMemory(hProcess,&lpRemoteStub,&dwFree,MEM_RELEASE);
		return NULL;
	}

	engine_BuildJMPBuffer((CHAR*)lpLocalStub+dwReadLen,jtJmpTable[RELATIVE_JMP].jcStub((DWORD)lpFunction+dwReadLen,(DWORD)lpRemoteStub,dwReadLen+jtJmpTable[RELATIVE_JMP].iCodeSize),RELATIVE_JMP);

	// Copy the "stub" buffer to process memory
	if (!NT_SUCCESS(NtWriteVirtualMemory(hProcess,lpRemoteStub,lpLocalStub,dwReadLen+jtJmpTable[RELATIVE_JMP].iCodeSize,&dwBytesWritten)))
	{
		NtProtectVirtualMemory(hProcess,&mbi.BaseAddress,&mbi.RegionSize,mbi.Protect,NULL);
		
		// Free allocated buffer
		NtFreeVirtualMemory(hProcess,&lpRemoteStub,&dwFree,MEM_RELEASE);
		return NULL;
	}

	// Check
	if (dwBytesWritten<dwReadLen+jtJmpTable[RELATIVE_JMP].iCodeSize)
	{
		NtProtectVirtualMemory(hProcess,&mbi.BaseAddress,&mbi.RegionSize,mbi.Protect,NULL);
		
		// Free allocated buffer
		NtFreeVirtualMemory(hProcess,&lpRemoteStub,&dwFree,MEM_RELEASE);
		return NULL;
	}
	
	// change access
	if (!NT_SUCCESS(NtProtectVirtualMemory(hProcess,&lpRemoteStub,&dwStubSize,PAGE_EXECUTE_READ,&dwOldProtect)))
	{
		NtProtectVirtualMemory(hProcess,&mbi.BaseAddress,&mbi.RegionSize,mbi.Protect,NULL);
		
		// Free allocated buffer
		NtFreeVirtualMemory(hProcess,&lpRemoteStub,&dwFree,MEM_RELEASE);
		return NULL;
	}
		
	// Fill it with NOP
	RtlFillMemory(lpLocalFunc,MAX_FUNC_LEN*3,NOP);

	// Prepare jmpcode
	engine_BuildJMPBuffer((CHAR*)lpLocalFunc,jtJmpTable[iRndJmp].jcFunc((DWORD)lpHookFunctionAddress,(DWORD)lpFunction,(DWORD)jtJmpTable[iRndJmp].iCodeSize),iRndJmp);
	
	ntStatus=NtWriteVirtualMemory(hProcess,lpFunction,lpLocalFunc,dwReadLen,&dwBytesWritten);
		
	// Check that we really wrote our jmpcode completely
	if (!NT_SUCCESS(ntStatus) || dwBytesWritten!=dwReadLen)
	{
		// Try to fix stuff
		if (dwBytesWritten)
			NtWriteVirtualMemory(hProcess,lpFunction,lpRemoteStub,dwBytesWritten,&dwBytesWritten);

		NtProtectVirtualMemory(hProcess,&mbi.BaseAddress,&mbi.RegionSize,mbi.Protect,NULL);
		
		// Free allocated buffer
		NtFreeVirtualMemory(hProcess,&lpRemoteStub,&dwFree,MEM_RELEASE);
		return NULL;
	}
	
	// Restore protection
	NtProtectVirtualMemory(hProcess,&mbi.BaseAddress,&mbi.RegionSize,mbi.Protect,NULL);

	// Save size of read function length
	if (pdwHookFunctionSize) *pdwHookFunctionSize=dwReadLen;
	// Save address of function
	if (lpFunctionAddress) *lpFunctionAddress=lpFunction;

	return lpRemoteStub;
}