-
Notifications
You must be signed in to change notification settings - Fork 0
/
addresshunter.h
241 lines (218 loc) · 7.13 KB
/
addresshunter.h
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
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
#include <windows.h>
#include <inttypes.h>
#define DEREF( name )*(UINT_PTR *)(name)
#define DEREF_64( name )*(DWORD64 *)(name)
#define DEREF_32( name )*(DWORD *)(name)
#define DEREF_16( name )*(WORD *)(name)
#define DEREF_8( name )*(BYTE *)(name)
#define KERNEL32DLL_HASH 0x6A4ABC5B
//redefine UNICODE_STR struct
typedef struct _UNICODE_STR
{
USHORT Length;
USHORT MaximumLength;
PWSTR pBuffer;
} UNICODE_STR, *PUNICODE_STR;
//redefine PEB_LDR_DATA struct
typedef struct _PEB_LDR_DATA
{
DWORD dwLength;
DWORD dwInitialized;
LPVOID lpSsHandle;
LIST_ENTRY InLoadOrderModuleList;
LIST_ENTRY InMemoryOrderModuleList;
LIST_ENTRY InInitializationOrderModuleList;
LPVOID lpEntryInProgress;
} PEB_LDR_DATA, * PPEB_LDR_DATA;
//redefine LDR_DATA_TABLE_ENTRY struct
typedef struct _LDR_DATA_TABLE_ENTRY
{
LIST_ENTRY InMemoryOrderModuleList;
LIST_ENTRY InInitializationOrderModuleList;
PVOID DllBase;
PVOID EntryPoint;
ULONG SizeOfImage;
UNICODE_STR FullDllName;
UNICODE_STR BaseDllName;
ULONG Flags;
SHORT LoadCount;
SHORT TlsIndex;
LIST_ENTRY HashTableEntry;
ULONG TimeDateStamp;
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
//redefine PEB_FREE_BLOCK struct
typedef struct _PEB_FREE_BLOCK
{
struct _PEB_FREE_BLOCK * pNext;
DWORD dwSize;
} PEB_FREE_BLOCK, * PPEB_FREE_BLOCK;
//redefine PEB struct
typedef struct __PEB
{
BYTE bInheritedAddressSpace;
BYTE bReadImageFileExecOptions;
BYTE bBeingDebugged;
BYTE bSpareBool;
LPVOID lpMutant;
LPVOID lpImageBaseAddress;
PPEB_LDR_DATA pLdr;
LPVOID lpProcessParameters;
LPVOID lpSubSystemData;
LPVOID lpProcessHeap;
PRTL_CRITICAL_SECTION pFastPebLock;
LPVOID lpFastPebLockRoutine;
LPVOID lpFastPebUnlockRoutine;
DWORD dwEnvironmentUpdateCount;
LPVOID lpKernelCallbackTable;
DWORD dwSystemReserved;
DWORD dwAtlThunkSListPtr32;
PPEB_FREE_BLOCK pFreeList;
DWORD dwTlsExpansionCounter;
LPVOID lpTlsBitmap;
DWORD dwTlsBitmapBits[2];
LPVOID lpReadOnlySharedMemoryBase;
LPVOID lpReadOnlySharedMemoryHeap;
LPVOID lpReadOnlyStaticServerData;
LPVOID lpAnsiCodePageData;
LPVOID lpOemCodePageData;
LPVOID lpUnicodeCaseTableData;
DWORD dwNumberOfProcessors;
DWORD dwNtGlobalFlag;
LARGE_INTEGER liCriticalSectionTimeout;
DWORD dwHeapSegmentReserve;
DWORD dwHeapSegmentCommit;
DWORD dwHeapDeCommitTotalFreeThreshold;
DWORD dwHeapDeCommitFreeBlockThreshold;
DWORD dwNumberOfHeaps;
DWORD dwMaximumNumberOfHeaps;
LPVOID lpProcessHeaps;
LPVOID lpGdiSharedHandleTable;
LPVOID lpProcessStarterHelper;
DWORD dwGdiDCAttributeList;
LPVOID lpLoaderLock;
DWORD dwOSMajorVersion;
DWORD dwOSMinorVersion;
WORD wOSBuildNumber;
WORD wOSCSDVersion;
DWORD dwOSPlatformId;
DWORD dwImageSubsystem;
DWORD dwImageSubsystemMajorVersion;
DWORD dwImageSubsystemMinorVersion;
DWORD dwImageProcessAffinityMask;
DWORD dwGdiHandleBuffer[34];
LPVOID lpPostProcessInitRoutine;
LPVOID lpTlsExpansionBitmap;
DWORD dwTlsExpansionBitmapBits[32];
DWORD dwSessionId;
ULARGE_INTEGER liAppCompatFlags;
ULARGE_INTEGER liAppCompatFlagsUser;
LPVOID lppShimData;
LPVOID lpAppCompatInfo;
UNICODE_STR usCSDVersion;
LPVOID lpActivationContextData;
LPVOID lpProcessAssemblyStorageMap;
LPVOID lpSystemDefaultActivationContextData;
LPVOID lpSystemAssemblyStorageMap;
DWORD dwMinimumStackCommit;
} _PEB, * _PPEB;
// main hashing function for ror13
__forceinline DWORD ror13( DWORD d )
{
return _rotr( d, 13 );
}
__forceinline DWORD hash( char * c )
{
register DWORD h = 0;
do
{
h = ror13( h );
h += *c;
} while( *++c );
return h;
}
// function to fetch the base address of kernel32.dll from the Process Environment Block
UINT64 GetKernel32() {
ULONG_PTR kernel32dll, val1, val2, val3;
USHORT usCounter;
// kernel32.dll is at 0x60 offset and __readgsqword is compiler intrinsic,
// so we don't need to extract it's symbol
kernel32dll = __readgsqword( 0x60 );
kernel32dll = (ULONG_PTR)((_PPEB)kernel32dll)->pLdr;
val1 = (ULONG_PTR)((PPEB_LDR_DATA)kernel32dll)->InMemoryOrderModuleList.Flink;
while( val1 ) {
val2 = (ULONG_PTR)((PLDR_DATA_TABLE_ENTRY)val1)->BaseDllName.pBuffer;
usCounter = ((PLDR_DATA_TABLE_ENTRY)val1)->BaseDllName.Length;
val3 = 0;
//calculate the hash of kernel32.dll
do {
val3 = ror13( (DWORD)val3 );
if( *((BYTE *)val2) >= 'a' )
val3 += *((BYTE *)val2) - 0x20;
else
val3 += *((BYTE *)val2);
val2++;
} while( --usCounter );
// compare the hash kernel32.dll
if( (DWORD)val3 == KERNEL32DLL_HASH ) {
//return kernel32.dll if found
kernel32dll = (ULONG_PTR)((PLDR_DATA_TABLE_ENTRY)val1)->DllBase;
return kernel32dll;
}
val1 = DEREF( val1 );
}
return 0;
}
// custom strcmp function since this function will be called by GetSymbolAddress
// which means we have to call strcmp before loading msvcrt.dll
// so we are writing our own my_strcmp so that we don't have to play with egg or chicken dilemma
int my_strcmp (const char *p1, const char *p2) {
const unsigned char *s1 = (const unsigned char *) p1;
const unsigned char *s2 = (const unsigned char *) p2;
unsigned char c1, c2;
do {
c1 = (unsigned char) *s1++;
c2 = (unsigned char) *s2++;
if (c1 == '\0') {
return c1 - c2;
}
}
while (c1 == c2);
return c1 - c2;
}
UINT64 GetSymbolAddress( HANDLE hModule, LPCSTR lpProcName ) {
UINT64 dllAddress = (UINT64)hModule,
symbolAddress = 0,
exportedAddressTable = 0,
namePointerTable = 0,
ordinalTable = 0;
if( hModule == NULL ) {
return 0;
}
PIMAGE_NT_HEADERS ntHeaders = NULL;
PIMAGE_DATA_DIRECTORY dataDirectory = NULL;
PIMAGE_EXPORT_DIRECTORY exportDirectory = NULL;
ntHeaders = (PIMAGE_NT_HEADERS)(dllAddress + ((PIMAGE_DOS_HEADER)dllAddress)->e_lfanew);
dataDirectory = (PIMAGE_DATA_DIRECTORY)&ntHeaders->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT ];
exportDirectory = (PIMAGE_EXPORT_DIRECTORY)( dllAddress + dataDirectory->VirtualAddress );
exportedAddressTable = ( dllAddress + exportDirectory->AddressOfFunctions );
namePointerTable = ( dllAddress + exportDirectory->AddressOfNames );
ordinalTable = ( dllAddress + exportDirectory->AddressOfNameOrdinals );
if (((UINT64)lpProcName & 0xFFFF0000 ) == 0x00000000) {
exportedAddressTable += ( ( IMAGE_ORDINAL( (UINT64)lpProcName ) - exportDirectory->Base ) * sizeof(DWORD) );
symbolAddress = (UINT64)( dllAddress + DEREF_32(exportedAddressTable) );
}
else {
DWORD dwCounter = exportDirectory->NumberOfNames;
while( dwCounter-- ) {
char * cpExportedFunctionName = (char *)(dllAddress + DEREF_32( namePointerTable ));
if( my_strcmp( cpExportedFunctionName, lpProcName ) == 0 ) {
exportedAddressTable += ( DEREF_16( ordinalTable ) * sizeof(DWORD) );
symbolAddress = (UINT64)(dllAddress + DEREF_32( exportedAddressTable ));
break;
}
namePointerTable += sizeof(DWORD);
ordinalTable += sizeof(WORD);
}
}
return symbolAddress;
}