Post

MalDevEdr

MalDevEdr

MalDevEdr

Console.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <Windows.h>
#include <stdio.h>

#include "Common.h"


// if injecting the dll into a cli process
// if not, then comment it:

#define TARGET_CLI_PROCESSES	

#ifndef TARGET_CLI_PROCESSES
#define TARGET_GUI_PROCESSES
#endif // !TARGET_CLI_PROCESSES




HANDLE		g_hConsole		= NULL;

// create a console screen to write to
HANDLE CreateOutputConsole() {

	if (g_hConsole != NULL){
		return g_hConsole;
	}

#ifdef TARGET_GUI_PROCESSES
	
	if (!FreeConsole()) {
		return NULL;
	}
	if (!AllocConsole()) {
		return NULL;
	}

#endif // TARGET_GUI_PROCESSES

	if ((g_hConsole = GetStdHandle(STD_OUTPUT_HANDLE)) == NULL) {
		return NULL;
	}

	return g_hConsole;
}






VOID ReportError(LPCSTR lpFunctionName, DWORD dwError) {

	PRINT("[!] \"%s\" Failed With Error : %d \n", lpFunctionName, dwError);
	MessageBoxA(NULL, "", "", MB_OK);
}




DllMain.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <Windows.h>
#include <stdio.h>
#include "Common.h"





BOOL APIENTRY DllMain (HMODULE hModule, DWORD dwReason, LPVOID lpReserved){


    HANDLE hThread = NULL;


    switch (dwReason)
    {
        case DLL_PROCESS_ATTACH: {
           hThread = CreateThread(NULL, NULL, &InstallTheHookviaMinHook, NULL, NULL, NULL); //install the hook
           if (hThread)
               CloseHandle(hThread);
           break;
        };

        case DLL_PROCESS_DETACH: {
            ProcessDetachRoutine(); // remove the hooks
            break;
        };
    }

    return TRUE;
}


Hook.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#include <Windows.h>
#include <stdio.h>

#include "MinHook.h"
#include "Common.h"


#ifdef _WIN64
#pragma comment(lib, "minhook.x64.lib")
#elif _WIN32
#pragma comment(lib, "minhook.x32.lib")
#endif




fnNtProtectVirtualMemory	g_NtProtectVirtualMemory	= NULL;	// original NtProtectVirtualMemory to call in the hook function
PVOID						pNtProtectVirtualMemory		= NULL;	// address of the NtProtectVirtualMemory function


// what will be executed instead of NtProtectVirtualMemory
NTSTATUS WINAPI Hooked_NtProtectVirtualMemory(
	HANDLE      ProcessHandle,
	PVOID*		BaseAddress,
	PULONG      NumberOfBytesToProtect,
	ULONG       NewAccessProtection,
	PULONG      OldAccessProtection
){


	PRINT("[#] NtProtectVirtualMemory At [ 0x%p ] Of Size [ %d ] \n", (PVOID)*BaseAddress, (unsigned int)*NumberOfBytesToProtect);
	
	// if PAGE_EXECUTE_READWRITE = dump memory + terminate
	if ((NewAccessProtection & PAGE_EXECUTE_READWRITE) == PAGE_EXECUTE_READWRITE) {
		PRINT("\t\t\t<<<!>>> [DETECTED] PAGE_EXECUTE_READWRITE [DETECTED] <<<!>>> \n");
		BlockExecution((PBYTE)*BaseAddress, (SIZE_T)*NumberOfBytesToProtect, TRUE);
	}

	// if PAGE_EXECUTE_READWRITE = dump memory + continue
	if ((NewAccessProtection & PAGE_EXECUTE_READ) == PAGE_EXECUTE_READ) {
		PRINT("\t\t\t<<<!>>> [DETECTED] PAGE_EXECUTE_READ [DETECTED] <<<!>>> \n");
		BlockExecution((PBYTE)*BaseAddress, (SIZE_T)*NumberOfBytesToProtect, FALSE);
	}

	// return the expected output
	return  g_NtProtectVirtualMemory(ProcessHandle, BaseAddress, NumberOfBytesToProtect, NewAccessProtection, OldAccessProtection);
}



// hooking NtProtectVirtualMemory using minhook library
BOOL InstallTheHookviaMinHook() {


	LONG	MinHookErr = MH_OK;

	pNtProtectVirtualMemory = GetProcAddress(GetModuleHandleW(TEXT("NTDLL.DLL")), "NtProtectVirtualMemory");

	if (CreateOutputConsole() == NULL) {
		MessageBoxA(NULL, "Failed To Allocate Console", "ERROR", MB_OK | MB_ICONERROR);
		return FALSE;
	}

	PRINT("\n\t\t\t <><><><><><>[ MALDEV ACAD EDR INJECTED ]<><><><><><> \n\n");


	if ((MinHookErr = MH_Initialize()) != MH_OK) {
		
		("MH_Initialize", MinHookErr);
		return FALSE;
	}

	if (((MinHookErr = MH_CreateHookApi(TEXT("NTDLL.DLL"), "NtProtectVirtualMemory", Hooked_NtProtectVirtualMemory, (LPVOID*)&g_NtProtectVirtualMemory) != MH_OK))) {
		ReportError("MH_CreateHookApi", MinHookErr);
		return FALSE;
	}

	if ((MinHookErr = MH_EnableHook(MH_ALL_HOOKS)) != MH_OK) {
		ReportError("MH_EnableHook", MinHookErr);
		return FALSE;
	}



	return TRUE;
}


// used to dump memory at `pAddress` of size `sSize`
// terminates the process if `Terminate` is true
VOID BlockExecution(PBYTE pAddress, SIZE_T sSize, BOOL Terminate) {

	PRINT("\n\t------------------------------------[ MEMORY DUMP ]------------------------------------\n\n");
	for (int i = 0; i < sSize; i++) {
		if (i % 16 == 0) {
			PRINT("\n\t\t");
		}
		PRINT(" %02X", pAddress[i]);
	}
	PRINT("\n\n\t------------------------------------[ MEMORY DUMP ]------------------------------------\n\n");

	if (Terminate){
		/*
		LONG	MinHookErr = MH_OK;

		if ((MinHookErr = MH_RemoveHook(pNtProtectVirtualMemory)) != MH_OK) {
			ReportError("MH_RemoveHook", MinHookErr);
		}
		*/
		MessageBoxA(NULL, "Terminating The Process ... ", "Maldev Edr", MB_OKCANCEL | MB_ICONERROR);
		ExitProcess(1);
	}
}



// unhooking the installed hook on NtProtectVirtualMemory
VOID ProcessDetachRoutine() {

	LONG	MinHookErr = MH_OK;

	if ((MinHookErr = MH_DisableHook(MH_ALL_HOOKS)) != MH_OK) {
		ReportError("MH_DisableHook", MinHookErr);
	}

	if ((MinHookErr = MH_Uninitialize()) != MH_OK) {
		ReportError("MH_Uninitialize", MinHookErr);
	}

}








This post is licensed under CC BY 4.0 by the author.