远程线程的注入 PE的修正

 ​

 

从github上下载了ReflectiverLoader认真学习了一下 在代码中得到一些心得和自己的想法,都按步骤写到了代码中,现在分享给大家,如有错,望大家指正

其中需要注入的dll和解析, 内存RVA与 文件RVA的转换代码(汇编与c++的都有)和解析,shellcode的汇编附到最后的链接中 

 

 一.这是用到的shellocode

作用:经调试得出他是为了解决x86下运行x64 的问题(windbg可以看到是通过远跳转到x64下执行)

 



1


2


3


4


5


6


7


8


9


10


11


12


13


14


15


16


17


18


19


20


21


22


23


24


25




​static BYTE __ExecutexX64[] ​​​​=​​ ​​"\x55\x89\xE5\x56\x57\x8B\x75\x08\x8B\x4D\x0C\xE8\x00\x00\x00\x00"​


​"\x58\x83\xC0\x25\x83\xEC\x08\x89\xE2\xC7\x42\x04\x33\x00\x00\x00"​


​"\x89\x02\xE8\x09\x00\x00\x00\x83\xC4\x14\x5F\x5E\x5D\xC2\x08\x00"​


​"\x8B\x3C\x24\xFF\x2A\x48\x31\xC0\x57\xFF\xD6\x5F\x50\xC7\x44\x24"​


​"\x04\x23\x00\x00\x00\x89\x3C\x24\xFF\x2C\x24"​​​​;​


 


​static BYTE __FunctionX64[] ​​​​=​​ ​​"\xFC\x48\x89\xCE\x48\x89\xE7\x48\x83\xE4\xF0\xE8\xC8\x00\x00\x00"​


​"\x41\x51\x41\x50\x52\x51\x56\x48\x31\xD2\x65\x48\x8B\x52\x60\x48"​


​"\x8B\x52\x18\x48\x8B\x52\x20\x48\x8B\x72\x50\x48\x0F\xB7\x4A\x4A"​


​"\x4D\x31\xC9\x48\x31\xC0\xAC\x3C\x61\x7C\x02\x2C\x20\x41\xC1\xC9"​


​"\x0D\x41\x01\xC1\xE2\xED\x52\x41\x51\x48\x8B\x52\x20\x8B\x42\x3C"​


​"\x48\x01\xD0\x66\x81\x78\x18\x0B\x02\x75\x72\x8B\x80\x88\x00\x00"​


​"\x00\x48\x85\xC0\x74\x67\x48\x01\xD0\x50\x8B\x48\x18\x44\x8B\x40"​


​"\x20\x49\x01\xD0\xE3\x56\x48\xFF\xC9\x41\x8B\x34\x88\x48\x01\xD6"​


​"\x4D\x31\xC9\x48\x31\xC0\xAC\x41\xC1\xC9\x0D\x41\x01\xC1\x38\xE0"​


​"\x75\xF1\x4C\x03\x4C\x24\x08\x45\x39\xD1\x75\xD8\x58\x44\x8B\x40"​


​"\x24\x49\x01\xD0\x66\x41\x8B\x0C\x48\x44\x8B\x40\x1C\x49\x01\xD0"​


​"\x41\x8B\x04\x88\x48\x01\xD0\x41\x58\x41\x58\x5E\x59\x5A\x41\x58"​


​"\x41\x59\x41\x5A\x48\x83\xEC\x20\x41\x52\xFF\xE0\x58\x41\x59\x5A"​


​"\x48\x8B\x12\xE9\x4F\xFF\xFF\xFF\x5D\x4D\x31\xC9\x41\x51\x48\x8D"​


​"\x46\x18\x50\xFF\x76\x10\xFF\x76\x08\x41\x51\x41\x51\x49\xB8\x01"​


​"\x00\x00\x00\x00\x00\x00\x00\x48\x31\xD2\x48\x8B\x0E\x41\xBA\xC8"​


​"\x38\xA4\x40\xFF\xD5\x48\x85\xC0\x74\x0C\x48\xB8\x00\x00\x00\x00"​


​"\x00\x00\x00\x00\xEB\x0A\x48\xB8\x01\x00\x00\x00\x00\x00\x00\x00"​


​"\x48\x83\xC4\x50\x48\x89\xFC\xC3"​​​​;​



 


二.用到的结构体 宏定义和哈希值(利用MakeHanValue计算就行,代码中有小注释)

 

 



1


2


3


4


5


6


7


8


9


10


11


12


13


14


15


16


17


18


19


20


21


22


23


24


25


26


27


28


29


30


31


32


33


34


35


36


37


38


39


40


41


42


43


44




​#define MYFUNCTION_HASH     0x6654bba6 // hash of "MyFunction"​


​enum {​


​UNKNOWN,​


​X86,​


​X64​


​};​


 


 


​#define DEREFERENCE   (Value) *(UINT_PTR *)(Value)​


​#define DEREFERENCE_64(Value) *(DWORD64 *)(Value)​


​#define DEREFERENCE_32(Value) *(DWORD *)(Value)​


​#define DEREFERENCE_16(Value) *(WORD *)(Value)​


​#define DEREFERENCE_8 (Value) *(BYTE *)(Value)​


 


​typedef ​​​​BOOL​​ ​​(WINAPI ​​​​*​​​​LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);​


 


​typedef ​​​​BOOL​​​​(WINAPI​​​​*​​ ​​LPFN_FUNCTIONX64)(DWORD ParameterData);​


​typedef DWORD(WINAPI​​​​*​​ ​​LPFN_EXECUTEX64)(LPFN_FUNCTIONX64 FunctionX64, DWORD ParameterData);​


 


​typedef struct _WOW64CONTEXT_​


​{​


​union​


​{​


​HANDLE ProcessHandle;​


​BYTE   Padding[​​​​8​​​​];​


​}u1;​


 


​union​


​{​


​LPVOID ThreadProcedure;​


​BYTE   Padding[​​​​8​​​​];​


​}u2;​


 


​union​


​{​


​LPVOID ParameterData;​


​BYTE   Padding[​​​​8​​​​];​


​}u3;​


​union​


​{​


​HANDLE ThreadHandle;​


​BYTE   Padding[​​​​8​​​​];​


​}u4;​


​} WOW64CONTEXT, ​​​​*​​​​LPWOW64CONTEXT;​



 


 

 

三.主函数的解析

 



1


2


3


4


5


6


7


8


9


10


11


12


13


14


15


16


17


18


19


20


21


22


23


24


25


26


27


28


29


30


31


32


33


34


35


36


37


38


39


40


41


42


43


44


45


46


47


48


49


50


51


52


53


54


55


56


57


58


59


60


61


62


63


64


65


66


67


68


69


70


71


72


73


74


75


76


77


78


79


80


81


82


83


84


85


86


87


88




​int​​ ​​main()​


​{​


​HANDLE FileHandle ​​​​=​​ ​​NULL;​


​ULONG  FileLength ​​​​=​​ ​​0​​​​;​


​LPVOID FileData ​​​​=​​ ​​NULL;​


​ULONG  ReturnLength ​​​​=​​ ​​0​​​​;​


​HANDLE ProcessHandle ​​​​=​​ ​​NULL;​


​HANDLE RemoteThreadHandle ​​​​=​​ ​​NULL;​


​DWORD  ExitCode ​​​​=​​ ​​0​​​​;​


​if​​ ​​(EnableSeDebugPrivilege(L​​​​"SeDebugPrivilege"​​​​, TRUE) ​​​​=​​​​=​​ ​​FALSE)​


​{​


​return​​ ​​0​​​​;​


​}​


​DWORD ProcessID ​​​​=​​ ​​0​​​​;​


​printf(​​​​"Input ProcessID:\r\n"​​​​);​


​scanf(​​​​"%d"​​​​, &ProcessID);​


​#ifdef_WIN64​


​char​​​​*​​ ​​DllFullPath ​​​​=​​ ​​"ReflectiveLoader.dll"​​​​;​


​#else​


​char​​​​*​​ ​​DllFullPath ​​​​=​​ ​​"ReflectiveLoader.dll"​​​​;​


​#endif​


​/​​​​/​​​​1.​​​​打开文件​


​FileHandle ​​​​=​​ ​​CreateFileA(DllFullPath, GENERIC_READ, ​​​​0​​​​, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);​


​if​​ ​​(FileHandle ​​​​=​​​​=​​ ​​INVALID_HANDLE_VALUE)​


​{​


​printf(​​​​"CreateFileA() Error\r\n"​​​​);​


​goto Exit;​


​}​


​/​​​​/​​​​2.​​​​获得大小​


​FileLength ​​​​=​​ ​​GetFileSize(FileHandle, NULL);​


​if​​ ​​(FileLength ​​​​=​​​​=​​ ​​INVALID_FILE_SIZE || FileLength ​​​​=​​​​=​​ ​​0​​​​)​


​{​


​printf(​​​​"GetFileSize() Error\r\n"​​​​);​


​goto Exit;​


​}​


​/​​​​/​​​​3.​​​​申请堆内存​


​FileData ​​​​=​​ ​​HeapAlloc(GetProcessHeap(), ​​​​0​​​​, FileLength);​


​if​​ ​​(!FileData)​


​{​


​printf(​​​​"HeapAlloc() Error\r\n"​​​​);​


​goto Exit;​


​}​


​/​​​​/​​​​4.​​​​读内存​


​if​​ ​​(ReadFile(FileHandle, FileData, FileLength, &ReturnLength, NULL) ​​​​=​​​​=​​ ​​FALSE)​


​{​


​printf(​​​​"HeapAlloc() Error\r\n"​​​​);​


​goto Exit;​


​}​


​/​​​​/​​​​以下是对目标进行操作​


​/​​​​/​​​​5.​​​​打开目标进程​


​ProcessHandle ​​​​=​​ ​​OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ,​


​FALSE, ProcessID);​


​if​​ ​​(!ProcessHandle)​


​{​


​printf(​​​​"OpenProcess() Error\r\n"​​​​);​


​goto Exit;​


​}​


​/​​​​/​​​​6.​​​​加载动态库​


​RemoteThreadHandle ​​​​=​​ ​​LoadRemoteLibrary(ProcessHandle, FileData, FileLength, NULL,MYFUNCTION_HASH,(LPVOID)​​​​"911"​​​​,strlen(​​​​"911"​​​​)​​​​+​​​​1​​​​);​


​if​​ ​​(!RemoteThreadHandle)​


​{​


​printf(​​​​"LoadRemoteLibrary() Error\r\n"​​​​);​


​goto Exit;​


​}​


​printf(​​​​"LoadRemoteLibrary() Success\r\n"​​​​);​


​/​​​​/​​​​7.​​​​远程线程等待注入​


​WaitForSingleObject(RemoteThreadHandle, INFINITE);​


​if​​ ​​(!GetExitCodeThread(RemoteThreadHandle, &ExitCode))​


​printf(​​​​"Input AnyKey To Exit\r\n"​​​​);​


​getchar();​


​/​​​​/​​​​8.​​​​释放内存​


​Exit:​


​if​​ ​​(FileData)​


​{​


​HeapFree(GetProcessHeap(), ​​​​0​​​​, FileData);​


​}​


​if​​ ​​(FileHandle!​​​​=​​​​NULL)​


​{​


​CloseHandle(FileHandle);​


​FileHandle ​​​​=​​ ​​NULL;​


​}​


​if​​ ​​(ProcessHandle)​


​{​


​CloseHandle(ProcessHandle);​


​ProcessHandle ​​​​=​​ ​​NULL;​


​}​


​return​​ ​​0​​​​;​


​}​




 


 

四. LoadRemoteLibrary的解读(其中三种获得目标体系结构的方法 我记入了笔记)

 

 



1


2


3


4


5


6


7


8


9


10


11


12


13


14


15


16


17


18


19


20


21


22


23


24


25


26


27


28


29


30


31


32


33


34


35


36


37


38


39


40


41


42


43


44


45


46


47


48


49


50


51


52


53


54


55


56


57


58


59


60


61


62


63


64


65


66


67


68


69


70


71


72


73


74


75


76


77


78


79


80


81


82


83


84


85


86


87


88


89


90


91


92


93


94


95


96


97


98


99


100


101


102


103


104


105


106


107


108


109


110


111


112


113


114


115


116


117


118


119


120


121


122


123


124


125


126


127


128


129


130


131


132


133


134


135


136


137


138


139


140


141


142


143


144


145


146


147


148


149


150


151


152


153


154


155


156


157


158


159


160


161


162


163


164


165




​HANDLEWINAPI LoadRemoteLibrary(​


​HANDLEProcessHandle,​


​LPVOIDFileData,   ​​​​/​​​​/​​​​Dll文件数据​


​DWORDFileLength,​


​LPVOIDParameterData,​


​DWORDFunctionHash,​​​​/​​​​/​​​​函数哈希值​


​LPVOIDUserData,​


​DWORDUserDataLength)​


​{​


​HANDLE RemoteThreadHandle ​​​​=​​ ​​NULL;​


​DWORD  RemoteThreadID ​​​​=​​ ​​0​​​​;​


​DWORD TargetArchitecture ​​​​=​​ ​​X86; ​​​​/​​​​/​​​​目标体系结构​


​DWORD DllArchitecture ​​​​=​​ ​​UNKNOWN;​


​#ifdefined(_WIN64)​


​DWORD CurrentArchitecture ​​​​=​​ ​​X64;​


​#elifdefined(_WIN32)​


​DWORD CurrentArchitecture​​​​=​​​​X86​


​#else​


​#endif​


​__try​


​{​


​do​


​{​


​if​​ ​​(!ProcessHandle || !FileData || !FileLength)​


​{​


​break​​​​;​


​}​


​/​​​​/​​​​第一幕​


​/​​​​/​​ ​​1.​​​​获得目标进程的Architecture 进程通过内核获得体系结构​


​HMODULE KernelModuleBase ​​​​=​​ ​​LoadLibraryA(​​​​"kernel32.dll"​​​​);​


​if​​ ​​(!KernelModuleBase)​


​break​​​​;​


​__IsWow64Process ​​​​=​​ ​​(LPFN_ISWOW64PROCESS)GetProcAddress(KernelModuleBase, ​​​​"IsWow64Process"​​​​);​


​FreeLibrary(KernelModuleBase);​


​if​​ ​​(__IsWow64Process)​


​{​


​BOOL​​ ​​IsOK;​


​if​​ ​​(!__IsWow64Process(ProcessHandle, &IsOK));​


​{​


​break​​​​;​


​}​


​if​​ ​​(IsOK)​


​{​


​TargetArchitecture ​​​​=​​ ​​X86;​


​}​


​else​


​{​


​/​​​​/​​​​通过系统判断​​​​32​​​​位与​​​​64​​​​位​


​SYSTEM_INFO SystemInfo ​​​​=​​ ​​{ ​​​​0​​ ​​};​


​GetNativeSystemInfo(&SystemInfo);​


​if​​ ​​(SystemInfo.wProcessorArchitecture ​​​​=​​​​=​​ ​​PROCESSOR_ARCHITECTURE_AMD64)​


​TargetArchitecture ​​​​=​​ ​​X64;​


​elseif (SystemInfo.wProcessorArchitecture ​​​​=​​​​=​​ ​​PROCESSOR_ARCHITECTURE_INTEL)​


​TargetArchitecture ​​​​=​​ ​​X86;​


​else​


​break​​​​;​


​}​


​}​


​/​​​​/​​ ​​2.​​​​通过PE获得获得Dll的Architecture​


​/​​​​/​​​​MZ头​​​​+​​​​e_lfanew​​​​=​​​​NT头​


​PIMAGE_NT_HEADERS ImageNtHeaders ​​​​=​​ ​​(PIMAGE_NT_HEADERS)(((PUINT8)FileData) ​​​​+​​ ​​((PIMAGE_DOS_HEADER)FileData)​​​​-​​​​>e_lfanew);​


​if​​ ​​(ImageNtHeaders​​​​-​​​​>OptionalHeader.Magic ​​​​=​​​​=​​ ​​IMAGE_NT_OPTIONAL_HDR32_MAGIC) ​​​​/​​​​/​​ ​​PE32​


​DllArchitecture ​​​​=​​ ​​X86;​


​elseif (ImageNtHeaders​​​​-​​​​>OptionalHeader.Magic ​​​​=​​​​=​​ ​​IMAGE_NT_OPTIONAL_HDR64_MAGIC) ​​​​/​​​​/​​ ​​PE64​


​DllArchitecture ​​​​=​​ ​​X64;​


​/​​​​/​​ ​​3.​​​​判断DLL和目标进程是否是相同的架构??​


​if​​ ​​(DllArchitecture !​​​​=​​ ​​TargetArchitecture)​


​{​


​printf(​​​​"Must Be Same Architecture\r\n"​​​​);​


​break​​​​;​


​}​


​/​​​​/​​​​第二幕​


​/​​​​/​​​​1.​​​​再次检查动态库的装入​


​/​​​​/​​ ​​check ​​​​if​​ ​​the library has a ReflectiveLoader...​


​DWORD ReflectiveLoaderOffset ​​​​=​​ ​​GetReflectiveLoaderOffset(FileData);​


​if​​ ​​(!ReflectiveLoaderOffset)​


​{​


​printf(​​​​"Could Not Get ReflectiveLoader Offset\r\n"​​​​);​


​break​​​​;​


​}​


​DWORD RemoteBufferLength ​​​​=​​ ​​FileLength​


​+​​ ​​UserDataLength​


​+​​ ​​64​​​​; ​​​​/​​​​/​​ ​​shellcode ​​​​buffer​


​/​​​​/​​ ​​2.alloc​​ ​​memory (RWX) ​​​​in​​ ​​the host process ​​​​for​​ ​​the image...​


​LPVOID RemoteBufferData ​​​​=​​ ​​VirtualAllocEx(ProcessHandle, NULL, RemoteBufferLength, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);​


​if​​ ​​(!RemoteBufferData)​


​{​


​break​​​​;​


​}​


​printf(​​​​"VirtualAllocEx() Success\r\n"​​​​);​


​/​​​​/​​​​3.1​​ ​​write the image into the host process...将图像写入主进程。​


​/​​​​/​​​​RemoteBufferData 指向写入数据的指定进程中的基地址的指针​


​if​​ ​​(!WriteProcessMemory(ProcessHandle, RemoteBufferData, FileData, FileLength, NULL))​


​break​​​​;​


​/​​​​/​​​​基地址​​​​+​​​​偏移​


​ULONG_PTR ReflectiveLoader ​​​​=​​ ​​(ULONG_PTR)RemoteBufferData ​​​​+​​ ​​ReflectiveLoaderOffset;​


​/​​​​/​​​​3.2​​ ​​write our userdata blob into the host process​


​ULONG_PTR RemoteUserData ​​​​=​​ ​​(ULONG_PTR)RemoteBufferData ​​​​+​​ ​​FileLength;​


​if​​ ​​(!WriteProcessMemory(ProcessHandle, (LPVOID)RemoteUserData, UserData, UserDataLength, NULL))​


​break​​​​;​


​/​​​​/​​​​3.3​​​​写shellcode​


​ULONG_PTR RemoteShellCode ​​​​=​​ ​​RemoteUserData ​​​​+​​ ​​UserDataLength;​


​BYTE Bootstrap[​​​​64​​​​] ​​​​=​​ ​​{ ​​​​0​​ ​​};​


​DWORD BootstrapLength ​​​​=​​ ​​CreateBootstrap(​


​Bootstrap,​


​64​​​​,​


​TargetArchitecture,​


​(ULONG_PTR)ParameterData,​


​(ULONG_PTR)RemoteBufferData,​


​FunctionHash,​


​RemoteUserData,​


​UserDataLength,​


​ReflectiveLoader);​


​if​​ ​​(BootstrapLength <​​​​=​​ ​​0​​​​)​


​{​


​break​​​​;​


​}​


​printf(​​​​"%p\r\n"​​​​, RemoteShellCode);​


​getchar();​


​if​​ ​​(!WriteProcessMemory(ProcessHandle, (LPVOID)RemoteShellCode, Bootstrap, BootstrapLength, NULL))​


​break​​​​;​


​printf(​​​​"Wrote ShellCode Success\r\n"​​​​);​


​/​​​​*​


​此处的写入图​


​RemoteBufferData[FileData的基地址]​


​写入FileData​


​RemoteUserData[UserData的基地址]​


​写入UserData​


​RemoteShellCode​


​写入Bootstrap​


​*​​​​/​


​/​​​​/​​​​确保我们的更改是马上写的​


​FlushInstructionCache(ProcessHandle, RemoteBufferData, RemoteBufferLength);​


​printf(​​​​"%p\r\n"​​​​, RemoteShellCode);​


​getchar();​


​getchar();​


​/​​​​/​​​​第三幕 判断主体与客体的位 并且创建线程执行​


​/​​​​/​​ ​​目标​​​​64​​  ​​当前​​​​32​


​if​​ ​​(CurrentArchitecture ​​​​=​​​​=​​ ​​X86 && TargetArchitecture ​​​​=​​​​=​​ ​​X64)​


​{​


​Wow64CreateRemoteThread(ProcessHandle, (LPVOID)RemoteShellCode, ParameterData, &RemoteThreadHandle);​


​ResumeThread(RemoteThreadHandle);​


​}​


​else​


​{​


​/​​​​/​​​​目标​​​​32​​  ​​当前​​​​32​


​/​​​​/​​​​目标​​​​64​​  ​​当前​​​​64​


​/​​​​/​​​​目标​​​​32​​  ​​当前​​​​64​


​RemoteThreadHandle ​​​​=​​ ​​CreateRemoteThread(ProcessHandle, NULL, ​​​​1024​​ ​​*​​ ​​1024​​​​,​


​(LPTHREAD_START_ROUTINE)RemoteShellCode, ParameterData,​


​(DWORD)NULL, &RemoteThreadID);​


​/​​​​*​​​​lpStartAddress [​​​​in​​​​]指向由线程执行的类型为LPTHREAD_START_ROUTINE的应用程序​


​定义函数的指针,并表示远程进程中线程的起始地址。该功能必须存在于远程进程中。​


​lpParameter [​​​​in​​​​]​


​指向要传递给线程函数的变量的指针。​


​*​​​​/​


​}​


​} ​​​​while​​ ​​(​​​​0​​​​);​


​}​


​__except (EXCEPTION_EXECUTE_HANDLER)​


​{​


​RemoteThreadHandle ​​​​=​​ ​​NULL;​


​}​


​return​​ ​​RemoteThreadHandle;​


​}​



 


 

 

 

五.  Wow64CreateRemoteThread解读

 



1


2


3


4


5


6


7


8


9


10


11


12


13


14


15


16


17


18


19


20


21


22


23


24


25


26


27


28


29


30


31


32


33


34


35


36


37


38


39


40


41


42


43


44


45


46


47


48


49


50


51


52


53


54


55


56


57


58


59


60


61


62


63


64


65


66


67


68


69


70


71


72


73


74


75




​DWORD Wow64CreateRemoteThread(HANDLEProcessHandle, LPVOIDThreadProcedure, LPVOIDParameterData, HANDLE ​​​​*​​ ​​ThreadHandle)​


​{​


​DWORD Result ​​​​=​​ ​​ERROR_SUCCESS;​


​LPFN_EXECUTEX64  ExecuteX64 ​​​​=​​ ​​NULL;​


​LPFN_FUNCTIONX64 FunctionX64 ​​​​=​​ ​​NULL;​


​WOW64CONTEXT​​​​*​​  ​​Wow64Context ​​​​=​​ ​​NULL;​


​OSVERSIONINFO  OsVersionInfo ​​​​=​​ ​​{ ​​​​0​​ ​​};​


​do​


​{​


​/​​​​/​​​​第一幕 判断系统是否合适​


​OsVersionInfo.dwOSVersionInfoSize ​​​​=​​ ​​sizeof(OSVERSIONINFO);​


​if​​ ​​(!GetVersionEx(&OsVersionInfo))​


​{​


​printf(​​​​"GetVersionEx() Error\r\n"​​​​);​


​break​​​​;​


​}​


​/​​​​/​​ ​​filter​​ ​​out Windows ​​​​2003​


​if​​ ​​(OsVersionInfo.dwMajorVersion ​​​​=​​​​=​​ ​​5​​ ​​&& OsVersionInfo.dwMinorVersion ​​​​=​​​​=​​ ​​2​​​​)​


​{​


​printf(​​​​"Is 2003 Error\r\n"​​​​);​


​break​​​​;​


​}​


​/​​​​/​​​​第二幕​


​/​​​​/​​​​1.​​​​分别为ExecuteX64,FunctionX64申请shellcode大小的内存兵赋值​


​/​​​​*​​​​shellcode经过调试得出是通过远跳转到​​​​64​​​​位进程中执行 惭愧 瞎调了一遍还没有掌握调试方法 有点难。。。​​​​*​​​​/​


​ExecuteX64 ​​​​=​​ ​​(LPFN_EXECUTEX64)VirtualAlloc(NULL, sizeof(__ExecutexX64), MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);​


​if​​ ​​(!ExecuteX64)​


​{​


​printf(​​​​"VirtualAlloc() Error\r\n"​​​​);​


​break​​​​;​


​}​


​FunctionX64 ​​​​=​​ ​​(LPFN_FUNCTIONX64)VirtualAlloc(NULL, sizeof(__FunctionX64) ​​​​+​​ ​​sizeof(WOW64CONTEXT), MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);​


​if​​ ​​(!FunctionX64)​


​{​


​printf(​​​​"VirtualAlloc() Error\r\n"​​​​);​


​break​​​​;​


​}​


​/​​​​/​​ ​​copy over the wow64​​​​-​​​​>x64 stub​


​memcpy(ExecuteX64, &__ExecutexX64, sizeof(__ExecutexX64));​


​/​​​​/​​ ​​copy over the native x64 function​


​memcpy(FunctionX64, &__FunctionX64, sizeof(__FunctionX64));​


​/​​​​/​​​​2.​​​​设置上下背景文​


​Wow64Context ​​​​=​​ ​​(WOW64CONTEXT ​​​​*​​​​)((BYTE ​​​​*​​​​)FunctionX64 ​​​​+​​ ​​sizeof(__FunctionX64));​


​Wow64Context​​​​-​​​​>u1.ProcessHandle   ​​​​=​​ ​​ProcessHandle;   ​​​​/​​​​/​​​​目标进程句柄​


​Wow64Context​​​​-​​​​>u2.ThreadProcedure ​​​​=​​ ​​ThreadProcedure;​


​Wow64Context​​​​-​​​​>u3.ParameterData   ​​​​=​​ ​​ParameterData;​


​Wow64Context​​​​-​​​​>u4.ThreadHandle    ​​​​=​​ ​​NULL;​


​/​​​​/​​​​3.​​​​执行该代码的环境是​​​​32​​​​位​


​if​​ ​​(!ExecuteX64(FunctionX64, (DWORD)Wow64Context))  ​


​{​


​printf(​​​​"ExecuteX64() Error\r\n"​​​​);​


​break​​​​;​


​}​


​/​​​​/​​​​作为一个标识​


​if​​ ​​(!Wow64Context​​​​-​​​​>u4.ThreadHandle)​


​{​


​printf(​​​​"ThreadHandle Is NULL\r\n"​​​​);​


​break​​​​;​


​}​


​/​​​​/​​ ​​4.​​​​成功! 从上下文中抓取新的线程句柄​


​*​​​​ThreadHandle ​​​​=​​ ​​Wow64Context​​​​-​​​​>u4.ThreadHandle;​


​} ​​​​while​​ ​​(​​​​0​​​​);​


​/​​​​/​​​​5.​​​​退出​


​if​​ ​​(ExecuteX64)​


​{​


​VirtualFree(ExecuteX64, ​​​​0​​​​, MEM_RELEASE);​


​ExecuteX64 ​​​​=​​ ​​NULL;​


​}​


​if​​ ​​(FunctionX64)​


​{​


​VirtualFree(FunctionX64, ​​​​0​​​​, MEM_RELEASE);​


​FunctionX64 ​​​​=​​ ​​NULL;​


​}​


​return​​ ​​Result;​


​}​



 


========== End