예제 #1
0
BOOL InitializeW64oWoW64()
{

	void * lvpNtdll = GetModuleBase64( L"ntdll.dll" );
	UNICODE_STRING64 sUnicodeString;
	__int8 * lvpKernelBaseBase;
	__int8 * lvpKernel32Base;
	PLDR_DATA_TABLE_ENTRY64 lpsKernel32Ldr;
	PLDR_DATA_TABLE_ENTRY64 lpsKernelBaseLdr;

	sFunctions.LdrGetKnownDllSectionHandle = GetProcAddress64( lvpNtdll, 
		"LdrGetKnownDllSectionHandle" );
	sFunctions.NtFreeVirtualMemory = GetProcAddress64( lvpNtdll, 
		"NtFreeVirtualMemory" );
	sFunctions.NtMapViewOfSection = GetProcAddress64( lvpNtdll, 
		"NtMapViewOfSection" );
	sFunctions.NtUnmapViewOfSection = GetProcAddress64( lvpNtdll, 
		"NtUnmapViewOfSection" );

	if( FreeKnownDllPage( L"kernel32.dll" ) == FALSE) return FALSE;
	if( FreeKnownDllPage( L"user32.dll" ) == FALSE ) return FALSE;

	sUnicodeString.Length = 0x18;
	sUnicodeString.MaximumLength = 0x1a;
	sUnicodeString.Buffer = (DWORD64)L"kernel32.dll";
	if( X64Call( GetProcAddress64( lvpNtdll, "LdrLoadDll" ), 4, 
		(DWORD64)0, 
		(DWORD64)0, 
		(DWORD64)&sUnicodeString, 
		(DWORD64)&lvpKernel32Base ) != NULL ) {
			PrintLastError();
			return FALSE;
	}

	lvpKernelBaseBase = (__int8 *)GetModuleBase64( L"KERNELBASE.dll");
	X64Call( ( lvpKernelBaseBase + (int)GetModule64EntryRVA( lvpKernelBaseBase ) ), 
		3, 
		(DWORD64)lvpKernelBaseBase, 
		(DWORD64)DLL_PROCESS_ATTACH, 
		(DWORD64)0 );

	X64Call( ( lvpKernel32Base + (int)GetModule64EntryRVA( lvpKernel32Base ) ), 
		3, 
		(DWORD64)lvpKernel32Base, 
		(DWORD64)DLL_PROCESS_ATTACH, 
		(DWORD64)0 );

	lpsKernel32Ldr = GetModule64LdrTable( L"kernel32.dll" );
	lpsKernel32Ldr->LoadCount = 0xffff;
	lpsKernel32Ldr->Flags += LDRP_ENTRY_PROCESSED | LDRP_PROCESS_ATTACH_CALLED;

	lpsKernelBaseLdr = GetModule64LdrTable( L"KERNELBASE.dll" );
	lpsKernelBaseLdr->LoadCount = 0xffff;
	lpsKernelBaseLdr->Flags += LDRP_ENTRY_PROCESSED | LDRP_PROCESS_ATTACH_CALLED;

	return TRUE;
}
예제 #2
0
extern __declspec(dllexport) void * LoadLibrary64A( char * lpcLibraryName )
{
	if( sFunctions.LoadLibraryA == NULL ) {
		sFunctions.LoadLibraryA = 
			GetProcAddress64( GetModuleBase64( L"kernel32.dll" ), "LoadLibraryA" );
	}
	return (void *)X64Call( sFunctions.LoadLibraryA, 1, (DWORD64)lpcLibraryName );
}
예제 #3
0
	DWORD64 Wow64Local::LoadLibrary64(const wchar_t* path) {
		_UNICODE_STRING_T<DWORD64> upath = {0};
		DWORD64 hModule = 0;
		DWORD64 pfnLdrLoad = GetProcAddress64(GetNTDLL64(), "LdrLoadDll");
		upath.Length = (WORD)wcslen(path) * sizeof(wchar_t);
		upath.MaximumLength = (WORD)upath.Length;
		upath.Buffer = (DWORD64)path;
		X64Call(pfnLdrLoad, NULL, 0, &upath, &hModule);
		return hModule;
	};
예제 #4
0
BOOL FreeKnownDllPage( wchar_t * lpwzKnownDllName )
{
	DWORD64 hSection = 0;
	DWORD64 lvpBaseAddress = 0;
	DWORD64 lvpRealBaseAddress = 0;
	DWORD64 stViewSize = 0;
	DWORD64 stRegionSize = 0;
	PTEB64 psTeb;
	X64Call( sFunctions.LdrGetKnownDllSectionHandle, 3, 
		(DWORD64)lpwzKnownDllName, 
		(DWORD64)0, 
		(DWORD64)&hSection );

	psTeb = NtTeb64();
	psTeb->NtTib.ArbitraryUserPointer = (DWORD64)lpwzKnownDllName;

	X64Call( sFunctions.NtMapViewOfSection, 10, 
		(DWORD64)hSection, 
		(DWORD64)-1, 
		(DWORD64)&lvpBaseAddress, 
		(DWORD64)0, 
		(DWORD64)0, 
		(DWORD64)0, 
		(DWORD64)&stViewSize, 
		(DWORD64)ViewUnmap, 
		(DWORD64)0, 
		(DWORD64)PAGE_READONLY );

	lvpRealBaseAddress = 
		(DWORD64)GetModule64PEBaseAddress( (void *)lvpBaseAddress );

	X64Call( sFunctions.NtFreeVirtualMemory, 4, 
		(DWORD64)-1, 
		(DWORD64)&lvpRealBaseAddress, 
		(DWORD64)&stRegionSize, 
		(DWORD64)MEM_RELEASE );

	X64Call( sFunctions.NtUnmapViewOfSection, 2, (DWORD64)-1, 
		(DWORD64)lvpBaseAddress );
	return TRUE;
}
예제 #5
0
extern "C" SIZE_T __cdecl VirtualQueryEx64(HANDLE hProcess, DWORD64 lpAddress, MEMORY_BASIC_INFORMATION64* lpBuffer, SIZE_T dwLength)
{
    static DWORD64 ntqvm = 0;
    if (0 == ntqvm)
    {
        ntqvm = GetProcAddress64(getNTDLL64(), "NtQueryVirtualMemory");
        if (0 == ntqvm)
            return 0;
    }
    DWORD64 ret = 0;
    DWORD64 status = X64Call(ntqvm, 6, (DWORD64)hProcess, lpAddress, (DWORD64)0, (DWORD64)lpBuffer, (DWORD64)dwLength, (DWORD64)&ret);
	if (STATUS_SUCCESS != status)
		SetLastErrorFromX64Call(status);
	return (SIZE_T)ret;
}
예제 #6
0
	DWORD64 Wow64Local::GetProcAddress64(DWORD64 hModule, const char* funcName) {
		if(0 == _LdrGetProcedureAddress) {
			_LdrGetProcedureAddress = GetLdrGetProcedureAddress();
			if(0 == _LdrGetProcedureAddress)
				return 0;
		}
		// It's actually an ANSI string
		_UNICODE_STRING_T<DWORD64> fName = {0};
		fName.Buffer = (DWORD64)funcName;
		fName.Length = (WORD)strlen(funcName);
		fName.MaximumLength = fName.Length + 1;
		DWORD64 funcRet = 0;
		X64Call(_LdrGetProcedureAddress, hModule, &fName, 0, &funcRet);
		return funcRet;
	}
예제 #7
0
extern "C" BOOL __cdecl SetThreadContext64(HANDLE hThread, _CONTEXT64_2* lpContext)
{
    static DWORD64 stc = 0;
    if (0 == stc)
    {
        stc = GetProcAddress64(getNTDLL64(), "NtSetContextThread");
        if (0 == stc)
            return 0;
    }
    DWORD64 ret = X64Call(stc, 2, (DWORD64)hThread, (DWORD64)lpContext);
	if (STATUS_SUCCESS != ret)
	{
		SetLastErrorFromX64Call(ret);
		return FALSE;
	}
    else
        return TRUE;
}
예제 #8
0
extern "C" DWORD64 __cdecl GetProcAddress64(DWORD64 hModule, char* funcName)
{
    static DWORD64 _LdrGetProcedureAddress = 0;
    if (0 == _LdrGetProcedureAddress)
    {
        _LdrGetProcedureAddress = getLdrGetProcedureAddress();
        if (0 == _LdrGetProcedureAddress)
            return 0;
    }

    _UNICODE_STRING_T<DWORD64> fName = { 0 };
    fName.Buffer = (DWORD64)funcName;
    fName.Length = (WORD)strlen(funcName);
    fName.MaximumLength = fName.Length + 1;
    DWORD64 funcRet = 0;
    X64Call(_LdrGetProcedureAddress, 4, (DWORD64)hModule, (DWORD64)&fName, (DWORD64)0, (DWORD64)&funcRet);
    return funcRet;
}
예제 #9
0
extern "C" BOOL __cdecl VirtualProtectEx64(HANDLE hProcess, DWORD64 lpAddress, SIZE_T dwSize, DWORD flNewProtect, DWORD* lpflOldProtect)
{
    static DWORD64 ntpvm = 0;
    if (0 == ntpvm)
    {
        ntpvm = GetProcAddress64(getNTDLL64(), "NtProtectVirtualMemory");
        if (0 == ntpvm)
            return 0;
    }

    DWORD64 tmpAddr = lpAddress;
    DWORD64 tmpSize = dwSize;
    DWORD64 ret = X64Call(ntpvm, 5, (DWORD64)hProcess, (DWORD64)&tmpAddr, (DWORD64)&tmpSize, (DWORD64)flNewProtect, (DWORD64)lpflOldProtect);
	if (STATUS_SUCCESS != ret)
	{
		SetLastErrorFromX64Call(ret);
		return FALSE;
	}
    else
        return TRUE;
}
예제 #10
0
extern "C" BOOL __cdecl VirtualFreeEx64(HANDLE hProcess, DWORD64 lpAddress, SIZE_T dwSize, DWORD dwFreeType)
{
    static DWORD64 ntfvm = 0;
    if (0 == ntfvm)
    {
        ntfvm = GetProcAddress64(getNTDLL64(), "NtFreeVirtualMemory");
        if (0 == ntfvm)
            return 0;
    }

    DWORD64 tmpAddr = lpAddress;
    DWORD64 tmpSize = dwSize;
    DWORD64 ret = X64Call(ntfvm, 4, (DWORD64)hProcess, (DWORD64)&tmpAddr, (DWORD64)&tmpSize, (DWORD64)dwFreeType);
	if (STATUS_SUCCESS != ret)
	{
		SetLastErrorFromX64Call(ret);
		return FALSE;
	}
    else
        return TRUE;
}
예제 #11
0
extern "C" DWORD64 __cdecl VirtualAllocEx64(HANDLE hProcess, DWORD64 lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect)
{
    static DWORD64 ntavm = 0;
    if (0 == ntavm)
    {
        ntavm = GetProcAddress64(getNTDLL64(), "NtAllocateVirtualMemory");
        if (0 == ntavm)
            return 0;
    }

    DWORD64 tmpAddr = lpAddress;
    DWORD64 tmpSize = dwSize;
    DWORD64 ret = X64Call(ntavm, 6, (DWORD64)hProcess, (DWORD64)&tmpAddr, (DWORD64)0, (DWORD64)&tmpSize, (DWORD64)flAllocationType, (DWORD64)flProtect);
	if (STATUS_SUCCESS != ret)
	{
		SetLastErrorFromX64Call(ret);
		return FALSE;
	}
    else
        return tmpAddr;
}
예제 #12
0
extern "C" BOOL __cdecl WriteProcessMemory64(HANDLE hProcess, DWORD64 lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T *lpNumberOfBytesWritten)
{
    static DWORD64 nrvm = 0;
    if (0 == nrvm)
    {
        nrvm = GetProcAddress64(getNTDLL64(), "NtWriteVirtualMemory");
        if (0 == nrvm)
            return 0;
    }
    DWORD64 numOfBytes = lpNumberOfBytesWritten ? *lpNumberOfBytesWritten : 0;
    DWORD64 ret = X64Call(nrvm, 5, (DWORD64)hProcess, lpBaseAddress, (DWORD64)lpBuffer, (DWORD64)nSize, (DWORD64)&numOfBytes);
	if (STATUS_SUCCESS != ret)
	{
		SetLastErrorFromX64Call(ret);
		return FALSE;
	}
    else
    {
        if (lpNumberOfBytesWritten)
            *lpNumberOfBytesWritten = (SIZE_T)numOfBytes;
        return TRUE;
    }
}
예제 #13
0
static INJECT_RESULT Win32Inject64(DWORD dwProcessID, const wchar_t* dllFilePath)
{
	int path_length = std::wcslen(dllFilePath);
	HANDLE hTargetProcess = ::OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, FALSE, dwProcessID);
	if (hTargetProcess == NULL) {
		return INJECT_FAIL_OPENPROCESS;
	}

	int alloc_size = sizeof(DWORD64);
	alloc_size += sizeof(_UNICODE_STRING_T<DWORD64>);
	alloc_size += (path_length + 1) * sizeof(wchar_t);

	DWORD64 lpVirtualMemExec = VirtualAllocEx64(hTargetProcess, NULL, sizeof(exec_code), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
	DWORD64 lpVirtualMemParameters = VirtualAllocEx64(hTargetProcess, NULL, alloc_size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
	if(lpVirtualMemExec == NULL || lpVirtualMemParameters == NULL) {
		if(lpVirtualMemExec != NULL) {
			VirtualFreeEx64(hTargetProcess, lpVirtualMemExec, sizeof(exec_code), MEM_RESERVE | MEM_COMMIT);
		}
		if(lpVirtualMemParameters != NULL) {
			VirtualFreeEx64(hTargetProcess, lpVirtualMemParameters, alloc_size, MEM_RESERVE | MEM_COMMIT);
		}
		::CloseHandle(hTargetProcess);
		return INJECT_FAIL_VIRTUALALLOC;
	}
	DWORD64 ntdll64 = GetModuleHandle64(L"ntdll.dll");
	DWORD64 ntdll_LdrLoadDll = GetProcAddress64(ntdll64, "LdrLoadDll");
	DWORD64 ntdll_RtlExitUserThread = GetProcAddress64(ntdll64, "RtlExitUserThread");
	DWORD64 ntdll_RtlCreateUserThread = GetProcAddress64(ntdll64, "RtlCreateUserThread");
	if(ntdll_LdrLoadDll == 0 || ntdll_RtlExitUserThread == 0 || ntdll_RtlCreateUserThread == 0) {
		VirtualFreeEx64(hTargetProcess, lpVirtualMemExec, sizeof(exec_code), MEM_RESERVE | MEM_COMMIT);
		VirtualFreeEx64(hTargetProcess, lpVirtualMemParameters, alloc_size, MEM_RESERVE | MEM_COMMIT);
		::CloseHandle(hTargetProcess);
		return INJECT_FAIL_GETPROCADDRESS;
	}

	unsigned char* parameters = new unsigned char[alloc_size];
	std::memset(parameters, 0, alloc_size);
	_UNICODE_STRING_T<DWORD64>* upath = reinterpret_cast<_UNICODE_STRING_T<DWORD64>*>(parameters + sizeof(DWORD64));
	upath->Length = (path_length) * sizeof(wchar_t);
	upath->MaximumLength = (path_length + 1) * sizeof(wchar_t);
	wchar_t* path = reinterpret_cast<wchar_t*>(parameters + sizeof(DWORD64) + sizeof(_UNICODE_STRING_T<DWORD64>));
	std::wcscpy(path, dllFilePath);
	upath->Buffer = lpVirtualMemParameters + sizeof(DWORD64) + sizeof(_UNICODE_STRING_T<DWORD64>);

	unsigned char exec_code_copy[sizeof(exec_code)];
	std::memcpy(exec_code_copy, exec_code, sizeof(exec_code_copy));
	union {
		DWORD64 dw64;
		unsigned char bytes[8];
	} cvt;
	// arg4
	cvt.dw64 = lpVirtualMemParameters;
	std::memcpy(exec_code_copy + 2 + PrefixCodeLength, cvt.bytes, sizeof(cvt.bytes));
	// arg3
	cvt.dw64 = lpVirtualMemParameters + sizeof(DWORD64);
	std::memcpy(exec_code_copy + 12 + PrefixCodeLength, cvt.bytes, sizeof(cvt.bytes));

	// rax = LdrLoadDll
	cvt.dw64 = ntdll_LdrLoadDll;
	std::memcpy(exec_code_copy + 42 + PrefixCodeLength, cvt.bytes, sizeof(cvt.bytes));

	// rax = RtlExitUserThread
	cvt.dw64 = ntdll_RtlExitUserThread;
	std::memcpy(exec_code_copy + 64 + PrefixCodeLength, cvt.bytes, sizeof(cvt.bytes));
	if(FALSE == WriteProcessMemory64(hTargetProcess, lpVirtualMemExec, exec_code_copy, sizeof(exec_code), NULL)
		|| FALSE == WriteProcessMemory64(hTargetProcess, lpVirtualMemParameters, parameters, alloc_size, NULL)) {
		VirtualFreeEx64(hTargetProcess, lpVirtualMemExec, sizeof(exec_code), MEM_RESERVE | MEM_COMMIT);
		VirtualFreeEx64(hTargetProcess, lpVirtualMemParameters, alloc_size, MEM_RESERVE | MEM_COMMIT);
		::CloseHandle(hTargetProcess);
		delete[] parameters;
		return INJECT_FAIL_WRITEPROCESSMEMERY;
	}
	DWORD64 hRemoteThread = 0;
	struct {
	  DWORD64 UniqueProcess;
	  DWORD64 UniqueThread;
	} client_id;

	X64Call(ntdll_RtlCreateUserThread, 10, 
		(DWORD64)hTargetProcess, // ProcessHandle
		(DWORD64)NULL, // SecurityDescriptor
		(DWORD64)FALSE, // CreateSuspended
		(DWORD64)0, // StackZeroBits
		(DWORD64)NULL, // StackReserved
		(DWORD64)NULL, // StackCommit
		lpVirtualMemExec, // StartAddress
		(DWORD64)NULL, // StartParameter
		(DWORD64)&hRemoteThread, // ThreadHandle
		(DWORD64)&client_id // ClientID
		);
	INJECT_RESULT result = INJECT_OK;
	if(hRemoteThread == 0) {
		result = INJECT_FAIL_CREATEREMOTETHREAD;
	}
	else {
		::WaitForSingleObject((HANDLE)hRemoteThread, 3000);
	}
	VirtualFreeEx64(hTargetProcess, lpVirtualMemExec, sizeof(exec_code), MEM_RESERVE | MEM_COMMIT);
	VirtualFreeEx64(hTargetProcess, lpVirtualMemParameters, alloc_size, MEM_RESERVE | MEM_COMMIT);
	::CloseHandle(hTargetProcess);
	delete[] parameters;
	return result;
}