Skip to content

Commit

Permalink
Merge branch 'dpc_fix' ( Issue #19 )
Browse files Browse the repository at this point in the history
  • Loading branch information
hasherezade committed Feb 2, 2021
2 parents 575c9d2 + 2200c02 commit 635cf25
Show file tree
Hide file tree
Showing 15 changed files with 211 additions and 98 deletions.
46 changes: 3 additions & 43 deletions hldr32/hldr32.asm
Original file line number Diff line number Diff line change
Expand Up @@ -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

;-----------------------------------------------------------------------------
Expand Down Expand Up @@ -84,49 +82,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
Expand Down Expand Up @@ -242,11 +207,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
Expand Down
2 changes: 0 additions & 2 deletions hldr32/hldr32.inc
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
52 changes: 5 additions & 47 deletions hldr64/hldr64.asm
Original file line number Diff line number Diff line change
Expand Up @@ -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

;-----------------------------------------------------------------------------
Expand Down Expand Up @@ -104,51 +103,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
Expand Down Expand Up @@ -239,11 +202,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
Expand Down
2 changes: 0 additions & 2 deletions hldr64/hldr64.inc
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
11 changes: 7 additions & 4 deletions pe2shc/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<IMAGE_TLS_DIRECTORY>((HMODULE)my_exe, IMAGE_DIRECTORY_ENTRY_TLS);
if (!tls) return false;

Expand Down Expand Up @@ -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;
Expand All @@ -178,13 +178,16 @@ 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 {
std::cout << "[-] Failed to save the output!" << std::endl;
}
peconv::free_file(my_exe);
peconv::free_aligned(ext_buf);
return 0;
return 0;
}
Binary file modified pe2shc/stub32.bin
Binary file not shown.
Binary file modified pe2shc/stub64.bin
Binary file not shown.
2 changes: 2 additions & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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()

Expand Down
17 changes: 17 additions & 0 deletions tests/dpc_test/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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()
16 changes: 16 additions & 0 deletions tests/dpc_test/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#include <iostream>
#include <Windows.h>

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)
{
Sleep(6000);
}
return 0;
}
19 changes: 19 additions & 0 deletions tests/injector/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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()
45 changes: 45 additions & 0 deletions tests/injector/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#include <iostream>
#include <Windows.h>
#include "util.h"

int main(int argc, char *argv[])
{
if (argc < 3) {
std::cout << "Args: <shellcode> <target pid>\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;
}
Loading

0 comments on commit 635cf25

Please sign in to comment.