Beispiel #1
0
DWORD64 WoW64dm::LoadLibrary64( const wchar_t* path )
{
    BOOL isWOW = FALSE;
    IsWow64Process(_hProcess, &isWOW);

    // Inject into x64
    if(isWOW == FALSE)
    {
        DWORD64 memptr = 0;

        VirtualAllocEx64(memptr, 0x1000, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);

        if(memptr != 0)
        {
            DWORD size = 0;

            DWORD64 hKernel32 = GetModuleHandle64(L"Kernel32.dll", &size);
            DWORD64 pLoadLib  = GetProcAddress64(hKernel32, size, "LoadLibraryW");

            if(pLoadLib != 0 && WriteProcessMemory64(memptr, (LPVOID)path, (wcslen(path) + 1)*sizeof(wchar_t), 0) == STATUS_SUCCESS)
            {
                DWORD64 status = 0;

                if(CreateRemoteThread64(pLoadLib, memptr, status, true) != FALSE && status == STATUS_SUCCESS)
                {
                    VirtualFreeEx64(memptr, 0x1000, MEM_RELEASE);
                    return status;
                }
            }

            VirtualFreeEx64(memptr, 0x1000, MEM_FREE);
        }

        return FALSE;
    }
    // Inject into WOW64
    else
    {
        return LoadLibraryRemoteWOW64(path);
    }
}
Beispiel #2
0
	bool injectdll_x64(const PROCESS_INFORMATION& pi, const std::wstring& dll) {
		static unsigned char sc[] = {
			0x9c,                                                                   // pushfq
			0x50,                                                                   // push rax
			0x51,                                                                   // push rcx
			0x52,                                                                   // push rdx
			0x53,                                                                   // push rbx
			0x55,                                                                   // push rbp
			0x56,                                                                   // push rsi
			0x57,                                                                   // push rdi
			0x41, 0x50,                                                             // push r8
			0x41, 0x51,                                                             // push r9
			0x41, 0x52,                                                             // push r10
			0x41, 0x53,                                                             // push r11
			0x41, 0x54,                                                             // push r12
			0x41, 0x55,                                                             // push r13
			0x41, 0x56,                                                             // push r14
			0x41, 0x57,                                                             // push r15
			0x48, 0x83, 0xEC, 0x28,                                                 // sub rsp, 0x28
			0x49, 0xB9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,             // mov  r9, 0  // DllHandle
			0x49, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,             // mov  r8, 0  // DllPath
			0x48, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,             // mov  rax,0  // LdrLoadDll
			0x48, 0x31,                                                             // xor  rcx,rcx
			0xC9, 0x48,                                                             // xor  rdx,rdx
			0xFF, 0xD0,                                                             // call rax   LdrLoadDll
			0x48, 0x83, 0xC4, 0x28,                                                 // add rsp, 0x28
			0x41, 0x5F,                                                             // pop r15
			0x41, 0x5E,                                                             // pop r14
			0x41, 0x5D,                                                             // pop r13
			0x41, 0x5C,                                                             // pop r12
			0x41, 0x5B,                                                             // pop r11
			0x41, 0x5A,                                                             // pop r10
			0x41, 0x59,                                                             // pop r9
			0x41, 0x58,                                                             // pop r8
			0x5F,                                                                   // pop rdi
			0x5E,                                                                   // pop rsi
			0x5D,                                                                   // pop rbp
			0x5B,                                                                   // pop rbx
			0x5A,                                                                   // pop rdx
			0x59,                                                                   // pop rcx
			0x58,                                                                   // pop rax
			0x9D,                                                                   // popfq
			0xFF, 0x25, 0x00, 0x00, 0x00, 0x00,                                     // jmp offset
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00                          // rip
		};
		
		InitWow64ext();
		DWORD64 pfLoadLibrary = (DWORD64)GetProcAddress64(GetModuleHandle64(L"ntdll.dll"), "LdrLoadDll");
		if (!pfLoadLibrary) {
			return false;
		}

		struct UNICODE_STRING {
			USHORT    Length;
			USHORT    MaximumLength;
			DWORD64   Buffer;
		};
		SIZE_T memsize = sizeof(DWORD64) + sizeof(UNICODE_STRING) + (dll.size() + 1) * sizeof(wchar_t);
		DWORD64 memory = VirtualAllocEx64(pi.hProcess, NULL, memsize, MEM_COMMIT, PAGE_READWRITE);
		if (!memory) {
			return false;
		}
		DWORD64 shellcode = VirtualAllocEx64(pi.hProcess, NULL, sizeof(sc), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
		if (!shellcode) {
			return false;
		}

		UNICODE_STRING us;
		us.Length = (USHORT)(dll.size() * sizeof(wchar_t));
		us.MaximumLength = us.Length + sizeof(wchar_t);
		us.Buffer = memory + sizeof(UNICODE_STRING);

		SIZE_T written = 0;
		BOOL ok = FALSE;
		ok = WriteProcessMemory64(pi.hProcess, memory, &us, sizeof(UNICODE_STRING), &written);
		if (!ok || written != sizeof(UNICODE_STRING)) {
			return false;
		}
		ok = WriteProcessMemory64(pi.hProcess, us.Buffer, (void*)dll.data(), us.MaximumLength, &written);
		if (!ok || written != us.MaximumLength) {
			return false;
		}

		_CONTEXT64 ctx = { 0 };
		ctx.ContextFlags = CONTEXT_CONTROL;
		if (!GetThreadContext64(pi.hThread, &ctx)) {
			return false;
		}

		DWORD64 handle = us.Buffer + us.MaximumLength;
		memcpy(sc + 30, &handle, sizeof(handle));
		memcpy(sc + 40, &memory, sizeof(memory));
		memcpy(sc + 50, &pfLoadLibrary, sizeof(pfLoadLibrary));
		memcpy(sc + 98, &ctx.Rip, sizeof(ctx.Rip));
		ok = WriteProcessMemory64(pi.hProcess, shellcode, &sc, sizeof(sc), &written);
		if (!ok || written != sizeof(sc)) {
			return false;
		}

		ctx.ContextFlags = CONTEXT_CONTROL;
		ctx.Rip = shellcode;
		if (!SetThreadContext64(pi.hThread, &ctx)) {
			return false;
		}
		return true;
	}
Beispiel #3
0
/*
    Memory layout. 
    Function additionally writes Activation Context pointer into TEB for RtlQueryInformationActivationContext.

    ------------------------------------------------------------------------------------
    |  Return handle  |   UNICODE_STRING   |  dll path  |  padding  | executable code  | 
    ------------------------------------------------------------------------------------
*/
DWORD64 WoW64dm::LoadLibraryRemoteWOW64( const wchar_t* path )
{
    DWORD64 memptr = 0;
    int idx = 0;
    _UNICODE_STRING_T<DWORD64> upath = {0};

    VirtualAllocEx64(memptr, 0x1000, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);

    if(memptr != 0)
    {
        DWORD size = 0;
        DWORD64 hNtdll = GetModuleHandle64(L"ntdll.dll", &size);
        DWORD64 pfnLdrLoadDll = GetProcAddress64(hNtdll, size, "LdrLoadDll");

        upath.Length        = wcslen(path) * sizeof(wchar_t);
        upath.MaximumLength = upath.Length;
        upath.Buffer        = memptr + 0x100;
        DWORD64 codeAddr    = memptr + 0xA00;

        uint8_t code[] = 
        { 
            // Enter x64 mode
            0x6A, 0x33, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x83, 0x04, 0x24, 0x05, 0xCB,         

            0x65, 0x48, 0x8B, 0x04, 0x25, 0x30, 0x00, 0x00, 0x00,           // mov rax, gs:[30]
            0x48, 0xBA, 0xEF, 0xBE, 0xAD, 0xDE, 0xEF, 0xBE, 0xAD, 0xDE,     // movabs rdx, memptr + 0x700
            0x48, 0x89, 0x90, 0xC8, 0x02, 0x00, 0x00,                       // mov QWORD PTR [rax + 0x2c8],rdx
            0x48, 0x89, 0xE5,                                               // mov rbp, rsp
            0x48, 0x83, 0xE4, 0xF0,                                         // and rsp, 0xfffffffffffffff0
            0x48, 0x83, 0xEC, 0x28,                                         // sub rsp, 0x30
            0x48, 0x31, 0xC9,                                               // xor rcx, rcx
            0x48, 0x31, 0xD2,                                               // xor rdx, rdx
            0x49, 0xB8, 0xEF, 0xBE, 0xAD, 0xDE, 0xEF, 0xBE, 0xAD, 0xDE,     // movabs r8, &upath                        
            0x49, 0xB9, 0xEF, 0xBE, 0xAD, 0xDE, 0xEF, 0xBE, 0xAD, 0xDE,     // movabs r9, &memptr
            0x48, 0xB8, 0xEF, 0xBE, 0xAD, 0xDE, 0xEF, 0xBE, 0xAD, 0xDE,     // movabs rax, LdrLoadDll
            //0xCC, 
            0xFF, 0xD0,                                                     // call rax
            0x48, 0x89, 0xEC,                                               // mov rsp, rbp

            // Leave x64 mode
            0xE8, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x44, 0x24, 0x04, 0x23, 0x00, 0x00, 0x00, 0x83, 0x04, 0x24, 0x0D, 0xCB, 
            0xC2, 0x04, 0x00    // retn 0x4
        };

        DWORD64 patch[] = { memptr + 0x700, memptr + 0x10, memptr, pfnLdrLoadDll };

        // Patch immediate memory values
        for(uint8_t* ptr = code; ptr < (code + sizeof(code) - 8); ptr++)
        {
            if(*(DWORD64*)ptr == (DWORD64)0xDEADBEEFDEADBEEF)
            {
                *(DWORD64*)ptr = patch[idx];
                idx++;
            }
        }

        if(WriteProcessMemory64(memptr + 0x10, &upath, sizeof(upath), 0) == STATUS_SUCCESS &&
           WriteProcessMemory64(upath.Buffer, (LPVOID)path, upath.Length + sizeof(wchar_t), 0) == STATUS_SUCCESS &&
           WriteProcessMemory64(codeAddr, code, sizeof(code), 0) == STATUS_SUCCESS)
        {
            DWORD64 status = 0;

            if(CreateRemoteThread64(codeAddr, 0, status, true) != FALSE && (status & 0xFFFFFFFF) == STATUS_SUCCESS)
            {
                DWORD64 module = 0;

                ReadProcessMemory64(memptr, &module, sizeof(module), 0);
                VirtualFreeEx64(memptr, 0x1000, MEM_RELEASE);

                return module;
            }
        }

        VirtualFreeEx64(memptr, 0x1000, MEM_FREE);
    }        

    return 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;
}