2024年3月24日发(作者:)

5#include "wow64ext.h"

6

7enum class InjectResult {

8 OK,

9 Error_OpenProcess,

10 Error_VirtualAllocEx,

11 Error_GetProcAddress,

12 Error_WriteProcessMemory,

13 Error_CreateRemoteThread

14};

15

16template

17class ScopeResource {

18 Res res;

19 Deleter deleter;

20 ScopeResource(const ScopeResource&) {}

21public:

22 Res get() const {

23 return this->res;

24 }

25 ScopeResource(Res res, Deleter deleter) : res(res), deleter(deleter) {}

26 ~ScopeResource() {

27 this->deleter(this->res);

28 }

29};

30

31InjectResult Wow64InjectWin64(DWORD dwProcessId, const std::wstring& filename)

32{

33 DWORD dwDesiredAccess = PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ;

34 auto closeProcessHandle = [](HANDLE hProcess) {

35 if(hProcess != NULL) CloseHandle(hProcess);

36 };

37 ScopeResource targetProcessHandle(OpenProcess(dwDesiredAccess, FALSE, dwProcessId), closeProcessHandle);

38 if(() == NULL) {

39 return InjectResult::Error_OpenProcess;

40 }

41 unsigned char injectCode[] = {

42 0x48, 0x89, 0x4c, 0x24, 0x08, // mov qword ptr [rsp+8],rcx

43 0x57, // push rdi

44 0x48, 0x83, 0xec, 0x20, // sub rsp,20h

45 0x48, 0x8b, 0xfc, // mov rdi,rsp

46 0xb9, 0x08, 0x00, 0x00, 0x00, // mov ecx,8

47 0xb8, 0xcc, 0xcc, 0xcc, 0xcc, // mov eac,0CCCCCCCCh

48 0xf3, 0xab, // rep stos dword ptr [rdi]

49 0x48, 0x8b, 0x4c, 0x24, 0x30, // mov rcx,qword ptr [__formal]

50 0x49, 0xb9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // mov r9,0

51 0x49, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // mov r8,0

52 0x48, 0xba, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // mov rdx,0

53 0x48, 0xb9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // mov rcx,0

54 0x48, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // mov rax,0

55 0xff, 0xd0, // call rax

56 0x48, 0xb9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // mov rcx,0

57 0x48, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // mov rax,0

58 0xff, 0xd0 // call rax

59 };

60

61 size_t parametersMemSize = sizeof(DWORD64) + sizeof(_UNICODE_STRING_T) + (() + 1) * sizeof(wchar_t);

62 auto freeInjectCodeMem = [&targetProcessHandle, &injectCode](DWORD64 address) {

63 if(address != 0) VirtualFreeEx64((), address, sizeof(injectCode), MEM_COMMIT | MEM_RESERVE);

64 };

65 ScopeResource injectCodeMem(VirtualAllocEx64((), NULL, sizeof(injectCode), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE), freeInjectCodeMe

66 auto freeParametersMem = [&targetProcessHandle, parametersMemSize](DWORD64 address) {

67 if(address != 0) VirtualFreeEx64((), address, parametersMemSize, MEM_COMMIT | MEM_RESERVE);

68 };

69 ScopeResource parametersMem(VirtualAllocEx64((), NULL, parametersMemSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE), freeParametersMem);

70 if (() == 0 || () == 0) {

71 return InjectResult::Error_VirtualAllocEx;

72 }

73 DWORD64 ntdll64 = GetModuleHandle64(L"");

74 DWORD64 ntdll_LdrLoadDll = GetProcAddress64(ntdll64, "LdrLoadDll");

75 DWORD64 ntdll_RtlExitUserThread = GetProcAddress64(ntdll64, "RtlExitUserThread");

76 DWORD64 ntdll_RtlCreateUserThread = GetProcAddress64(ntdll64, "RtlCreateUserThread");

77 if(ntdll_LdrLoadDll == 0 || ntdll_RtlExitUserThread == 0 || ntdll_RtlCreateUserThread == 0) {

78 return InjectResult::Error_GetProcAddress;

79 }

80 std::unique_ptr parameters(new unsigned char[parametersMemSize]);

81 std::memset((), 0, parametersMemSize);

82 _UNICODE_STRING_T* upath = reinterpret_cast<_UNICODE_STRING_T*>(() + sizeof(DWORD64));

83 upath->Length = () * sizeof(wchar_t);

84 upath->MaximumLength = (() + 1) * sizeof(wchar_t);

85 wchar_t* path = reinterpret_cast(() + sizeof(DWORD64) + sizeof(_UNICODE_STRING_T));

86 std::copy((), (), path);

87 upath->Buffer = () + sizeof(DWORD64) + sizeof(_UNICODE_STRING_T);

88

89 union {

90 DWORD64 from;

91 unsigned char to[8];

92 } cvt;

93

94 // r9

95 = ();

96 std::memcpy(injectCode + 32, , sizeof());

97

98 // r8

99 = () + sizeof(DWORD64);

100 std::memcpy(injectCode + 42, , sizeof());

101

102 // rax = LdrLoadDll

103 = ntdll_LdrLoadDll;

104 std::memcpy(injectCode + 72, , sizeof());

105

106 // rax = RtlExitUserThread

107 = ntdll_RtlExitUserThread;

108 std::memcpy(injectCode + 94, , sizeof());

109

110 if(FALSE == WriteProcessMemory64((), (), injectCode, sizeof(injectCode), NULL)

111 || FALSE == WriteProcessMemory64((), (), (), parametersMemSize, NULL)) {

112 return InjectResult::Error_WriteProcessMemory;

113 }

114

115 DWORD64 hRemoteThread = 0;

116 struct {

117 DWORD64 UniqueProcess;

118 DWORD64 UniqueThread;

119 } client_id;

120

121 X64Call(ntdll_RtlCreateUserThread, 10,

122 (DWORD64)(), // ProcessHandle

123 (DWORD64)NULL, // SecurityDescriptor

124 (DWORD64)FALSE, // CreateSuspended

125 (DWORD64)0, // StackZeroBits

126 (DWORD64)NULL, // StackReserved

127 (DWORD64)NULL, // StackCommit