From bf348a2d2576f625fec6cf8891836a40e0050a70 Mon Sep 17 00:00:00 2001 From: hasherezade Date: Mon, 1 Feb 2021 09:29:44 +0100 Subject: [PATCH 1/9] [FEATURE] Realign the input PE (raw == virtual) during conversion --- pe2shc/main.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/pe2shc/main.cpp b/pe2shc/main.cpp index b7cb294..57ae5d0 100644 --- a/pe2shc/main.cpp +++ b/pe2shc/main.cpp @@ -58,7 +58,7 @@ bool has_tls_callbacks(BYTE *my_exe, size_t exe_size) { IMAGE_DATA_DIRECTORY* tls_dir = peconv::get_directory_entry(my_exe, IMAGE_DIRECTORY_ENTRY_TLS); if (!tls_dir) return false; - + IMAGE_TLS_DIRECTORY* tls = peconv::get_type_directory((HMODULE)my_exe, IMAGE_DIRECTORY_ENTRY_TLS); if (!tls) return false; @@ -164,7 +164,7 @@ int main(int argc, char *argv[]) } size_t exe_size = 0; - BYTE *my_exe = peconv::load_file(in_path.c_str(), exe_size); + BYTE *my_exe = peconv::load_pe_module(in_path.c_str(), exe_size, false, false); if (!my_exe) { std::cout << "[-] Could not read the input file!" << std::endl; return -1; @@ -178,7 +178,10 @@ int main(int argc, char *argv[]) peconv::free_file(my_exe); return -3; } - if (peconv::dump_to_file(out_str.c_str(), ext_buf, ext_size)) { + // remap pe to raw == virtual, so that remapping on load will not be required + peconv::t_pe_dump_mode dump_mode = peconv::PE_DUMP_REALIGN; + ULONGLONG current_base = peconv::get_image_base(ext_buf); + if (peconv::dump_pe(out_str.c_str(), ext_buf, ext_size, current_base, dump_mode)) { std::cout << "[+] Saved as: " << out_str << std::endl; } else { @@ -186,5 +189,5 @@ int main(int argc, char *argv[]) } peconv::free_file(my_exe); peconv::free_aligned(ext_buf); - return 0; + return 0; } From 7704a2c9579954a9f3cae9026fb85e2e8a551372 Mon Sep 17 00:00:00 2001 From: hasherezade Date: Tue, 2 Feb 2021 03:02:08 +0100 Subject: [PATCH 2/9] [FEATURE] Remove PE mapping from the 32bit stub --- hldr32/hldr32.asm | 39 +++------------------------------------ 1 file changed, 3 insertions(+), 36 deletions(-) diff --git a/hldr32/hldr32.asm b/hldr32/hldr32.asm index a00c899..2272e47 100644 --- a/hldr32/hldr32.asm +++ b/hldr32/hldr32.asm @@ -84,49 +84,16 @@ crc_skip: jnz walk_names ;----------------------------------------------------------------------------- -;allocate memory for mapping +;save the pointers to the PE structure ;----------------------------------------------------------------------------- mov esi, dword [esp + krncrcstk_size + 20h + 4] mov ebp, dword [esi + lfanew] add ebp, esi - mov ch, (MEM_COMMIT | MEM_RESERVE) >> 8 - push PAGE_EXECUTE_READWRITE - push ecx - push dword [ebp + _IMAGE_NT_HEADERS.nthOptionalHeader + _IMAGE_OPTIONAL_HEADER.ohSizeOfImage] - push 0 - call dword [esp + 10h + krncrcstk.kVirtualAlloc] - push eax - mov ebx, esp - -;----------------------------------------------------------------------------- -;map MZ header, NT Header, FileHeader, OptionalHeader, all section headers... -;----------------------------------------------------------------------------- - mov ecx, dword [ebp + _IMAGE_NT_HEADERS.nthOptionalHeader + _IMAGE_OPTIONAL_HEADER.ohSizeOfHeaders] - mov edi, eax push esi - rep movsb - pop esi - -;----------------------------------------------------------------------------- -;map sections data -;----------------------------------------------------------------------------- - - mov cx, word [ebp + _IMAGE_NT_HEADERS.nthFileHeader + _IMAGE_FILE_HEADER.fhSizeOfOptionalHeader] - lea edx, dword [ebp + ecx + _IMAGE_NT_HEADERS.nthOptionalHeader] - mov cx, word [ebp + _IMAGE_NT_HEADERS.nthFileHeader + _IMAGE_FILE_HEADER.fhNumberOfSections] - xchg edi, eax - -map_section: - pushad - add esi, dword [edx + _IMAGE_SECTION_HEADER.shPointerToRawData] - add edi, dword [edx + _IMAGE_SECTION_HEADER.shVirtualAddress] - mov ecx, dword [edx + _IMAGE_SECTION_HEADER.shSizeOfRawData] - rep movsb - popad - add edx, _IMAGE_SECTION_HEADER_size - loop map_section + mov ebx, esp + mov edi, esi ;----------------------------------------------------------------------------- ;import DLL From 50ee2576c002d872dc3480a724ee0cdbfd3e69fb Mon Sep 17 00:00:00 2001 From: hasherezade Date: Tue, 2 Feb 2021 03:05:31 +0100 Subject: [PATCH 3/9] [FEATURE] Removed flushing cache in 32 bit stub --- hldr32/hldr32.asm | 5 ----- 1 file changed, 5 deletions(-) diff --git a/hldr32/hldr32.asm b/hldr32/hldr32.asm index 2272e47..1dac3e6 100644 --- a/hldr32/hldr32.asm +++ b/hldr32/hldr32.asm @@ -209,11 +209,6 @@ reloc_abs: ;----------------------------------------------------------------------------- xor ecx, ecx - push ecx - push ecx - dec ecx - push ecx - call dword [ebx + mapstk_size + krncrcstk.kFlushInstructionCache] mov eax, dword [ebp + _IMAGE_NT_HEADERS.nthOptionalHeader + _IMAGE_OPTIONAL_HEADER.ohAddressOfEntryPoint] add eax, dword [ebx] call eax From c24cc623c14b28df0b77158a72e0dcffbbdaccb1 Mon Sep 17 00:00:00 2001 From: hasherezade Date: Tue, 2 Feb 2021 04:04:50 +0100 Subject: [PATCH 4/9] [FEATURE][tests] Added apps for testing --- tests/CMakeLists.txt | 2 + tests/dpc_test/CMakeLists.txt | 17 ++++++++ tests/dpc_test/main.cpp | 16 +++++++ tests/injector/CMakeLists.txt | 19 ++++++++ tests/injector/main.cpp | 45 +++++++++++++++++++ tests/injector/util.cpp | 81 +++++++++++++++++++++++++++++++++++ tests/injector/util.h | 15 +++++++ tests/test_case1/main.cpp | 1 + 8 files changed, 196 insertions(+) create mode 100644 tests/dpc_test/CMakeLists.txt create mode 100644 tests/dpc_test/main.cpp create mode 100644 tests/injector/CMakeLists.txt create mode 100644 tests/injector/main.cpp create mode 100644 tests/injector/util.cpp create mode 100644 tests/injector/util.h diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 277be8c..04538c7 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -5,6 +5,8 @@ set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT") #add the application that will be used for tests: add_subdirectory ( test_case1 ) +add_subdirectory ( dpc_test ) +add_subdirectory ( injector ) enable_testing() diff --git a/tests/dpc_test/CMakeLists.txt b/tests/dpc_test/CMakeLists.txt new file mode 100644 index 0000000..e8a521f --- /dev/null +++ b/tests/dpc_test/CMakeLists.txt @@ -0,0 +1,17 @@ +cmake_minimum_required (VERSION 2.8) +project (dpc_test) + +set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT") + +set (srcs + main.cpp +) + +set (hdrs +) + +add_executable ( ${PROJECT_NAME} ${hdrs} ${srcs}) + +if(PE2SHC_BUILD_TESTING) + INSTALL( TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX} COMPONENT ${PROJECT_NAME} ) +endif() diff --git a/tests/dpc_test/main.cpp b/tests/dpc_test/main.cpp new file mode 100644 index 0000000..ae4db2b --- /dev/null +++ b/tests/dpc_test/main.cpp @@ -0,0 +1,16 @@ +#include +#include + +int main() +{ + PROCESS_MITIGATION_DYNAMIC_CODE_POLICY dcp = {}; + dcp.ProhibitDynamicCode = 1; + SetProcessMitigationPolicy(ProcessDynamicCodePolicy, &dcp, sizeof(dcp)); + + std::cout << "PROCESS_MITIGATION_DYNAMIC_CODE_POLICY enabled...\n"; + while (true) + { + Sleep(6000); + } + return 0; +} diff --git a/tests/injector/CMakeLists.txt b/tests/injector/CMakeLists.txt new file mode 100644 index 0000000..26ca244 --- /dev/null +++ b/tests/injector/CMakeLists.txt @@ -0,0 +1,19 @@ +cmake_minimum_required (VERSION 2.8) +project (injector) + +set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT") + +set (srcs + main.cpp + util.cpp +) + +set (hdrs + util.h +) + +add_executable ( ${PROJECT_NAME} ${hdrs} ${srcs}) + +if(PE2SHC_BUILD_TESTING) + INSTALL( TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX} COMPONENT ${PROJECT_NAME} ) +endif() diff --git a/tests/injector/main.cpp b/tests/injector/main.cpp new file mode 100644 index 0000000..4808ac7 --- /dev/null +++ b/tests/injector/main.cpp @@ -0,0 +1,45 @@ +#include +#include +#include "util.h" + +int main(int argc, char *argv[]) +{ + if (argc < 2) { + std::cout << "Args: \n"; + return 0; + } + + char *path = argv[1]; + int pid = atoi(argv[2]); + size_t shc_size = 0; + BYTE *shellcode = util::load_file(path, shc_size); + if (!shellcode) { + std::cerr << "Could not load the shellcode file\n"; + return -1; + } + std::cout << "Injecting to: " << pid << "\n"; + HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid); + if (hProcess == NULL) { + std::cerr << "[ERROR] Could not open process : " << std::hex << GetLastError() << std::endl; + return -1; + } + LPVOID remote_buf = VirtualAllocEx(hProcess, NULL, shc_size, (MEM_RESERVE | MEM_COMMIT), PAGE_EXECUTE_READWRITE); + if (remote_buf == NULL) { + std::cerr << "[ERROR] Could not allocate a remote buffer : " << std::hex << GetLastError() << std::endl; + return -1; + } + if (!WriteProcessMemory(hProcess, remote_buf, shellcode, shc_size, NULL)) { + std::cerr << "[ERROR] WriteProcessMemory failed, status : " << std::hex << GetLastError() << std::endl; + return -1; + } + HANDLE hMyThread = NULL; + DWORD threadId = 0; + if ((hMyThread = CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)remote_buf, NULL, 0, &threadId)) == NULL) { + std::cerr << "[ERROR] CreateRemoteThread failed, status : " << std::hex << GetLastError() << std::endl; + return -1; + } + std::cout << "Injected, created Thread, id = " << threadId << "\n"; + CloseHandle(hMyThread); + CloseHandle(hProcess); + return 0; +} diff --git a/tests/injector/util.cpp b/tests/injector/util.cpp new file mode 100644 index 0000000..7d373d0 --- /dev/null +++ b/tests/injector/util.cpp @@ -0,0 +1,81 @@ +#include "util.h" +#include + +BYTE* util::alloc_aligned(size_t buffer_size, DWORD protect, ULONGLONG desired_base) +{ + if (!buffer_size) return NULL; + + BYTE* buf = (BYTE*)VirtualAlloc((LPVOID)desired_base, buffer_size, MEM_COMMIT | MEM_RESERVE, protect); + return buf; +} + +bool util::free_aligned(BYTE* buffer) +{ + if (buffer == nullptr) return true; + if (!VirtualFree(buffer, 0, MEM_RELEASE)) { +#ifdef _DEBUG + std::cerr << "Releasing failed" << std::endl; +#endif + return false; + } + return true; +} + +BYTE* util::load_file(IN const char *filename, OUT size_t &read_size) +{ + HANDLE file = CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); + if (file == INVALID_HANDLE_VALUE) { +#ifdef _DEBUG + std::cerr << "Could not open file!" << std::endl; +#endif + return nullptr; + } + HANDLE mapping = CreateFileMapping(file, 0, PAGE_READONLY, 0, 0, 0); + if (!mapping) { +#ifdef _DEBUG + std::cerr << "Could not create mapping!" << std::endl; +#endif + CloseHandle(file); + return nullptr; + } + BYTE *dllRawData = (BYTE*)MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, 0); + if (!dllRawData) { +#ifdef _DEBUG + std::cerr << "Could not map view of file" << std::endl; +#endif + CloseHandle(mapping); + CloseHandle(file); + return nullptr; + } + size_t r_size = GetFileSize(file, 0); + if (read_size != 0 && read_size <= r_size) { + r_size = read_size; + } + if (IsBadReadPtr(dllRawData, r_size)) { + std::cerr << "[-] Mapping of " << filename << " is invalid!" << std::endl; + UnmapViewOfFile(dllRawData); + CloseHandle(mapping); + CloseHandle(file); + return nullptr; + } + BYTE* localCopyAddress = alloc_aligned(r_size, PAGE_READWRITE); + if (localCopyAddress != nullptr) { + memcpy(localCopyAddress, dllRawData, r_size); + read_size = r_size; + } + else { + read_size = 0; +#ifdef _DEBUG + std::cerr << "Could not allocate memory in the current process" << std::endl; +#endif + } + UnmapViewOfFile(dllRawData); + CloseHandle(mapping); + CloseHandle(file); + return localCopyAddress; +} + +void util::free_file(BYTE* buffer) +{ + free_aligned(buffer); +} diff --git a/tests/injector/util.h b/tests/injector/util.h new file mode 100644 index 0000000..2d01a47 --- /dev/null +++ b/tests/injector/util.h @@ -0,0 +1,15 @@ +#pragma once + +#include + + +namespace util { + + BYTE* alloc_aligned(size_t buffer_size, DWORD protect, ULONGLONG desired_base=0); + + bool free_aligned(BYTE* buffer); + + BYTE* load_file(IN const char *filename, OUT size_t &read_size); + + void free_file(BYTE* buffer); +} diff --git a/tests/test_case1/main.cpp b/tests/test_case1/main.cpp index addb03b..77b4d07 100644 --- a/tests/test_case1/main.cpp +++ b/tests/test_case1/main.cpp @@ -17,6 +17,7 @@ int main() if (get_date() == 1337) { std::cout << "Test passed!\n"; } + MessageBoxW(0, L"Hello World!", L"Demo!", MB_OK); std::cout << "Test Case 1 finished\n"; return 0; } From dfd23ea6f01290b9ee09a8fc2bdb49b13f7ae3c7 Mon Sep 17 00:00:00 2001 From: hasherezade Date: Tue, 2 Feb 2021 04:11:48 +0100 Subject: [PATCH 5/9] [FEATURE][tests] Make DPC test display its own PID --- tests/dpc_test/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/dpc_test/main.cpp b/tests/dpc_test/main.cpp index ae4db2b..2d7d020 100644 --- a/tests/dpc_test/main.cpp +++ b/tests/dpc_test/main.cpp @@ -6,7 +6,7 @@ int main() PROCESS_MITIGATION_DYNAMIC_CODE_POLICY dcp = {}; dcp.ProhibitDynamicCode = 1; SetProcessMitigationPolicy(ProcessDynamicCodePolicy, &dcp, sizeof(dcp)); - + std::cout << "PID: " << std::dec << GetCurrentProcessId() << "\n"; std::cout << "PROCESS_MITIGATION_DYNAMIC_CODE_POLICY enabled...\n"; while (true) { From 2b40d4f2f3c6925c1cdd1e77374c03c635883cf0 Mon Sep 17 00:00:00 2001 From: hasherezade Date: Tue, 2 Feb 2021 04:28:11 +0100 Subject: [PATCH 6/9] [FEATURE] Remove remapping and flushing in 64 bit stub --- hldr64/hldr64.asm | 48 ++++------------------------------------------- 1 file changed, 4 insertions(+), 44 deletions(-) diff --git a/hldr64/hldr64.asm b/hldr64/hldr64.asm index ac49c0d..3f75bf7 100644 --- a/hldr64/hldr64.asm +++ b/hldr64/hldr64.asm @@ -104,51 +104,15 @@ crc_skip: and rsp, -10h ;align on 16-byte boundary ;----------------------------------------------------------------------------- -;allocate memory for mapping +;save the pointers to the PE structure ;----------------------------------------------------------------------------- mov rsi, qword [rbx + mapstk_size + krncrcstk_size + regstksize + 8] mov ebp, dword [rsi + lfanew] add rbp, rsi - push PAGE_EXECUTE_READWRITE - pop r9 - mov r8d, MEM_COMMIT | MEM_RESERVE - mov edx, dword [rbp + _IMAGE_NT_HEADERS.nthOptionalHeader + _IMAGE_OPTIONAL_HEADER.ohSizeOfImage] - call qword [rbx + mapstk_size + krncrcstk.kVirtualAlloc] - mov qword [rbx], rax - -;----------------------------------------------------------------------------- -;map MZ header, NT Header, FileHeader, OptionalHeader, all section headers... -;----------------------------------------------------------------------------- - - mov ecx, dword [rbp + _IMAGE_NT_HEADERS.nthOptionalHeader + _IMAGE_OPTIONAL_HEADER.ohSizeOfHeaders] - push rax - pop rdi - push rsi - rep movsb - pop rsi - -;----------------------------------------------------------------------------- -;map sections data -;----------------------------------------------------------------------------- - - mov cx, word [rbp + _IMAGE_NT_HEADERS.nthFileHeader + _IMAGE_FILE_HEADER.fhSizeOfOptionalHeader] - lea rdx, qword [rbp + rcx + _IMAGE_NT_HEADERS.nthOptionalHeader] - mov cx, word [rbp + _IMAGE_NT_HEADERS.nthFileHeader + _IMAGE_FILE_HEADER.fhNumberOfSections] - -map_section: - push rcx - push rsi - mov ecx, dword [rdx + _IMAGE_SECTION_HEADER.shPointerToRawData] - add rsi, rcx - mov edi, dword [rdx + _IMAGE_SECTION_HEADER.shVirtualAddress] - add rdi, rax - mov ecx, dword [rdx + _IMAGE_SECTION_HEADER.shSizeOfRawData] - rep movsb - pop rsi - pop rcx - add rdx, _IMAGE_SECTION_HEADER_size - loop map_section + mov rax, rsi + mov qword [rbx], rsi + mov rdi, rsi ;----------------------------------------------------------------------------- ;import DLL @@ -240,10 +204,6 @@ reloc_finished: ;call entrypoint ;----------------------------------------------------------------------------- - xor r8, r8 - xor edx, edx - or ecx, -1 - call qword [rbx + mapstk_size + krncrcstk.kFlushInstructionCache] mov eax, dword [rbp + _IMAGE_NT_HEADERS.nthOptionalHeader + _IMAGE_OPTIONAL_HEADER.ohAddressOfEntryPoint] add rax, qword [rbx] call rax From 34e93e435085e29d01dae28bf2c68df1e0cb0fd3 Mon Sep 17 00:00:00 2001 From: hasherezade Date: Tue, 2 Feb 2021 04:36:24 +0100 Subject: [PATCH 7/9] [BUGFIX][tests] Fixed arguments check --- tests/injector/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/injector/main.cpp b/tests/injector/main.cpp index 4808ac7..51ccc9a 100644 --- a/tests/injector/main.cpp +++ b/tests/injector/main.cpp @@ -4,7 +4,7 @@ int main(int argc, char *argv[]) { - if (argc < 2) { + if (argc < 3) { std::cout << "Args: \n"; return 0; } From c2367d23e105c95e7bab561503288b084e204cef Mon Sep 17 00:00:00 2001 From: hasherezade Date: Tue, 2 Feb 2021 04:49:19 +0100 Subject: [PATCH 8/9] [REFACT] Removed unused functions from the stubs --- hldr32/hldr32.asm | 2 -- hldr32/hldr32.inc | 2 -- hldr64/hldr64.asm | 4 +--- hldr64/hldr64.inc | 2 -- 4 files changed, 1 insertion(+), 9 deletions(-) diff --git a/hldr32/hldr32.asm b/hldr32/hldr32.asm index 1dac3e6..87f0aba 100644 --- a/hldr32/hldr32.asm +++ b/hldr32/hldr32.asm @@ -22,10 +22,8 @@ hldr_begin: ;API CRC table, null terminated ;----------------------------------------------------------------------------- - dd 0E9258E7Ah ;FlushInstructionCache dd 0C97C1FFFh ;GetProcAddress dd 03FC1BD8Dh ;LoadLibraryA - dd 009CE0D4Ah ;VirtualAlloc db 0 ;----------------------------------------------------------------------------- diff --git a/hldr32/hldr32.inc b/hldr32/hldr32.inc index c2c18dc..e8f8036 100644 --- a/hldr32/hldr32.inc +++ b/hldr32/hldr32.inc @@ -24,10 +24,8 @@ struc mapstk endstruc struc krncrcstk -.kVirtualAlloc: resd 1 .kLoadLibraryA: resd 1 .kGetProcAddress: resd 1 -.kFlushInstructionCache: resd 1 endstruc struc _IMAGE_FILE_HEADER diff --git a/hldr64/hldr64.asm b/hldr64/hldr64.asm index 3f75bf7..333e71c 100644 --- a/hldr64/hldr64.asm +++ b/hldr64/hldr64.asm @@ -29,10 +29,9 @@ regstksize equ 30h lodsq mov rbp, qword [rax + mDllBase] call parse_exports - dd 0E9258E7Ah ;FlushInstructionCache + dd 0C97C1FFFh ;GetProcAddress dd 03FC1BD8Dh ;LoadLibraryA - dd 009CE0D4Ah ;VirtualAlloc db 0 ;----------------------------------------------------------------------------- @@ -203,7 +202,6 @@ reloc_finished: ;----------------------------------------------------------------------------- ;call entrypoint ;----------------------------------------------------------------------------- - mov eax, dword [rbp + _IMAGE_NT_HEADERS.nthOptionalHeader + _IMAGE_OPTIONAL_HEADER.ohAddressOfEntryPoint] add rax, qword [rbx] call rax diff --git a/hldr64/hldr64.inc b/hldr64/hldr64.inc index c2736c2..3a6c624 100644 --- a/hldr64/hldr64.inc +++ b/hldr64/hldr64.inc @@ -26,10 +26,8 @@ struc mapstk endstruc struc krncrcstk -.kVirtualAlloc: resq 1 .kLoadLibraryA: resq 1 .kGetProcAddress: resq 1 -.kFlushInstructionCache: resq 1 endstruc struc _IMAGE_FILE_HEADER From 2200c020d3b2a6c1a7ff052dde85da88245d4487 Mon Sep 17 00:00:00 2001 From: hasherezade Date: Tue, 2 Feb 2021 04:50:24 +0100 Subject: [PATCH 9/9] [FEATURE] Replaced the stubs with the new versions --- pe2shc/stub32.bin | Bin 350 -> 283 bytes pe2shc/stub64.bin | Bin 436 -> 358 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/pe2shc/stub32.bin b/pe2shc/stub32.bin index f0631c55d9bbf8be1925ccce707d5853792d32c4..f07d36a29de6e3a2fc62e5a4da641f8ea5a34ef4 100644 GIT binary patch delta 101 zcmV-r0Gj{a0-FMm6buOf0093Ve94Wy!9S5GQ6emhZae|?R*B<@_h7Mri!3RH?Q}Z< z{fkWu<1_;cQU6l}kTxQU7&N zY5@OKBoI)E19B7tdJKz75c8yAgTg4{?qIQi zi!3RH?Q}Z<{fkWu<1_;cQU6m2k&`3=43W4%Dk4HcInjUBVFOPD1AhcLN(6twG09O; WNm2h(5Q{}90|WoijbjvH!UO=tnn0=m diff --git a/pe2shc/stub64.bin b/pe2shc/stub64.bin index de936cf7ea81c1883e5f5db1132ed1d9dc57ab6e..5f3edc2c140bcf8d8d8937dbbb543715757c29f0 100644 GIT binary patch delta 102 zcmV-s0Ga=^1LgvdA`A%t0093Ve94Wy!9S5UX%JY8Zahc<^+<{ENQpB@iT9D}8UYZK z1pzn#7?VB$JTD&q!vDfKR|J2}0ntbS*Ex-}0001gy^BRCNCN}^&`6DAAVFC{SV3H0 IUR%Nl0JcIUzyJUM delta 225 zcmV<703QG50<;5=A`}q-004T9CF%bke94Wy!9Pk3&Iyq&X@6*oZahc<^=d#tSwXk} zFaQ9HRZ#y^5J-swi%nEeUsm&^US^9;6iAI!4H#yNO$Jd`i%Jwo0nUqh3`haTi%Jml zq+VG_gTg4{0U(k4JUS`=!vDfKR|J2}0ntbS*Ex-}0001gy-hK|G17y{|Nm1c bi$y3%0|WoiNR4AKL0LgqL0n&6TfztcN^e+2