mirror of
https://github.com/rapid7/metasploit-payloads
synced 2025-03-18 15:14:10 +01:00
Land #302, Add universal unhooking call to meterpreter server
Merge branch 'land-302' into upstream-master
This commit is contained in:
commit
6431374acf
c/meterpreter
source/extensions/unhook
workspace
197
c/meterpreter/source/extensions/unhook/apisetmap.c
Normal file
197
c/meterpreter/source/extensions/unhook/apisetmap.c
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
* Author: Jeff Tang <jtang@cylance.com>
|
||||||
|
* Copyright (c) 2017 Cylance Inc. All rights reserved. *
|
||||||
|
* *
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification, *
|
||||||
|
* are permitted provided that the following conditions are met: *
|
||||||
|
* *
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this *
|
||||||
|
* list of conditions and the following disclaimer. *
|
||||||
|
* *
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice, *
|
||||||
|
* this list of conditions and the following disclaimer in the documentation and/or *
|
||||||
|
* other materials provided with the distribution. *
|
||||||
|
* *
|
||||||
|
* 3. Neither the name of the copyright holder nor the names of its contributors *
|
||||||
|
* may be used to endorse or promote products derived from this software without *
|
||||||
|
* specific prior written permission. *
|
||||||
|
* *
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND *
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED *
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR *
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES *
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; *
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON *
|
||||||
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
|
||||||
|
* *
|
||||||
|
*************************************************************************************/
|
||||||
|
#include "apisetmap.h"
|
||||||
|
|
||||||
|
_PPEB GetProcessEnvironmentBlock()
|
||||||
|
{
|
||||||
|
ULONG_PTR pPeb;
|
||||||
|
#ifdef _WIN64
|
||||||
|
pPeb = __readgsqword(0x60);
|
||||||
|
#else
|
||||||
|
#ifdef WIN_ARM
|
||||||
|
pPeb = *(DWORD *)( (BYTE *)_MoveFromCoprocessor( 15, 0, 13, 0, 2 ) + 0x30 );
|
||||||
|
#else _WIN32
|
||||||
|
pPeb = __readfsdword(0x30);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
return (_PPEB)pPeb;
|
||||||
|
}
|
||||||
|
|
||||||
|
PLDR_DATA_TABLE_ENTRY GetInMemoryOrderModuleList()
|
||||||
|
{
|
||||||
|
return (PLDR_DATA_TABLE_ENTRY)GetProcessEnvironmentBlock()->pLdr->InMemoryOrderModuleList.Flink;
|
||||||
|
}
|
||||||
|
|
||||||
|
PWCHAR GetRedirectedName(const PWSTR wszImportingModule, const PWSTR wszVirtualModule, SIZE_T* stSize)
|
||||||
|
{
|
||||||
|
PAPI_SET_NAMESPACE_ARRAY_V2 pApiSetMap;
|
||||||
|
pApiSetMap = (PAPI_SET_NAMESPACE_ARRAY_V2)GetProcessEnvironmentBlock()->pFreeList;
|
||||||
|
*stSize = 0;
|
||||||
|
|
||||||
|
if (pApiSetMap->Version == 6)
|
||||||
|
return GetRedirectedName_V6(wszImportingModule, wszVirtualModule, stSize);
|
||||||
|
else if (pApiSetMap->Version == 4)
|
||||||
|
return GetRedirectedName_V4(wszImportingModule, wszVirtualModule, stSize);
|
||||||
|
else if (pApiSetMap->Version == 2)
|
||||||
|
return GetRedirectedName_V2(wszImportingModule, wszVirtualModule, stSize);
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
PWCHAR GetRedirectedName_V6(const PWSTR wszImportingModule, const PWSTR wszVirtualModule, SIZE_T* stSize)
|
||||||
|
{
|
||||||
|
PAPI_SET_NAMESPACE_ARRAY_V6 pApiSetMap;
|
||||||
|
PAPI_SET_NAMESPACE_ENTRY_V6 pApiEntry;
|
||||||
|
PAPI_SET_VALUE_ENTRY_V6 pApiValue;
|
||||||
|
PAPI_SET_VALUE_ENTRY_V6 pApiArray;
|
||||||
|
DWORD dwEntryCount;
|
||||||
|
LONG dwSetCount;
|
||||||
|
PWSTR wsEntry;
|
||||||
|
PWSTR wsName;
|
||||||
|
PWSTR wsValue;
|
||||||
|
|
||||||
|
pApiSetMap = (PAPI_SET_NAMESPACE_ARRAY_V6)GetProcessEnvironmentBlock()->pFreeList;
|
||||||
|
|
||||||
|
// Loop through each entry in the ApiSetMap to find the matching redirected module entry
|
||||||
|
for (dwEntryCount = 0; dwEntryCount < pApiSetMap->Count; dwEntryCount++)
|
||||||
|
{
|
||||||
|
pApiEntry = &pApiSetMap->Array[dwEntryCount];
|
||||||
|
wsEntry = (PWSTR)((PCHAR)pApiSetMap + pApiEntry->NameOffset);
|
||||||
|
|
||||||
|
// Skip this entry if it does not match
|
||||||
|
if (_wcsnicmp(wsEntry, wszVirtualModule, pApiEntry->NameLength / 2) != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
pApiArray = (PAPI_SET_VALUE_ENTRY_V6)((PCHAR)pApiSetMap + pApiEntry->DataOffset);
|
||||||
|
|
||||||
|
// Loop through each value entry from the end and find where the importing module matches the ``Name`` entry
|
||||||
|
// If the ``Name`` entry is empty, it is the default entry @ index = 0
|
||||||
|
for (dwSetCount = pApiEntry->Count-1; dwSetCount >= 0; dwSetCount--)
|
||||||
|
{
|
||||||
|
// pApiValue = (PAPI_SET_VALUE_ENTRY_V6)((PCHAR)pApiSetMap + pApiEntry->DataOffset + (dwSetCount * sizeof(API_SET_VALUE_ENTRY_V6)));
|
||||||
|
pApiValue = &pApiArray[dwSetCount];
|
||||||
|
wsName = (PWSTR)((PCHAR)pApiSetMap + pApiValue->NameOffset);
|
||||||
|
wsValue = (PWSTR)((PCHAR)pApiSetMap + pApiValue->ValueOffset);
|
||||||
|
|
||||||
|
if (pApiValue->NameLength == 0 || _wcsnicmp(wsName, wszImportingModule, pApiValue->NameLength / 2) == 0)
|
||||||
|
{
|
||||||
|
*stSize = pApiValue->ValueLength / 2;
|
||||||
|
return wsValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PWCHAR GetRedirectedName_V4(const PWSTR wszImportingModule, const PWSTR wszVirtualModule, SIZE_T* stSize)
|
||||||
|
{
|
||||||
|
PAPI_SET_NAMESPACE_ARRAY_V4 pApiSetMap;
|
||||||
|
PAPI_SET_NAMESPACE_ENTRY_V4 pApiEntry;
|
||||||
|
PAPI_SET_VALUE_ARRAY_V4 pApiArray;
|
||||||
|
PAPI_SET_VALUE_ENTRY_V4 pApiValue;
|
||||||
|
DWORD dwEntryCount;
|
||||||
|
LONG dwSetCount;
|
||||||
|
PWSTR wsEntry;
|
||||||
|
PWSTR wsName;
|
||||||
|
PWSTR wsValue;
|
||||||
|
PWSTR wszShortVirtualModule;
|
||||||
|
|
||||||
|
pApiSetMap = (PAPI_SET_NAMESPACE_ARRAY_V4)GetProcessEnvironmentBlock()->pFreeList;
|
||||||
|
wszShortVirtualModule = (PWSTR)((PWCHAR)wszVirtualModule + 4);
|
||||||
|
|
||||||
|
for (dwEntryCount = 0; dwEntryCount < pApiSetMap->Count; dwEntryCount++)
|
||||||
|
{
|
||||||
|
pApiEntry = &pApiSetMap->Array[dwEntryCount];
|
||||||
|
wsEntry = (PWSTR)((PCHAR)pApiSetMap + pApiEntry->NameOffset);
|
||||||
|
|
||||||
|
if (_wcsnicmp(wsEntry, wszShortVirtualModule, pApiEntry->NameLength / 2) != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
pApiArray = (PAPI_SET_VALUE_ARRAY_V4)((PCHAR)pApiSetMap + pApiEntry->DataOffset);
|
||||||
|
|
||||||
|
for (dwSetCount = pApiArray->Count-1; dwSetCount >= 0; dwSetCount--)
|
||||||
|
{
|
||||||
|
pApiValue = &pApiArray->Array[dwSetCount];
|
||||||
|
wsName = (PWSTR)((PCHAR)pApiSetMap + pApiValue->NameOffset);
|
||||||
|
wsValue = (PWSTR)((PCHAR)pApiSetMap + pApiValue->ValueOffset);
|
||||||
|
|
||||||
|
if (pApiValue->NameLength == 0 || _wcsnicmp(wsName, wszImportingModule, pApiValue->NameLength / 2) == 0)
|
||||||
|
{
|
||||||
|
*stSize = pApiValue->ValueLength / 2;
|
||||||
|
return wsValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
PWCHAR GetRedirectedName_V2(const PWSTR wszImportingModule, const PWSTR wszVirtualModule, SIZE_T* stSize)
|
||||||
|
{
|
||||||
|
PAPI_SET_NAMESPACE_ARRAY_V2 pApiSetMap;
|
||||||
|
PAPI_SET_NAMESPACE_ENTRY_V2 pApiEntry;
|
||||||
|
PAPI_SET_VALUE_ARRAY_V2 pApiArray;
|
||||||
|
PAPI_SET_VALUE_ENTRY_V2 pApiValue;
|
||||||
|
DWORD dwEntryCount;
|
||||||
|
LONG dwSetCount;
|
||||||
|
PWSTR wsEntry;
|
||||||
|
PWSTR wsName;
|
||||||
|
PWSTR wsValue;
|
||||||
|
PWSTR wszShortVirtualModule;
|
||||||
|
|
||||||
|
pApiSetMap = (PAPI_SET_NAMESPACE_ARRAY_V2)GetProcessEnvironmentBlock()->pFreeList;
|
||||||
|
wszShortVirtualModule = (PWSTR)((PWCHAR)wszVirtualModule + 4);
|
||||||
|
|
||||||
|
for (dwEntryCount = 0; dwEntryCount < pApiSetMap->Count; dwEntryCount++)
|
||||||
|
{
|
||||||
|
pApiEntry = &pApiSetMap->Array[dwEntryCount];
|
||||||
|
wsEntry = (PWSTR)((PCHAR)pApiSetMap + pApiEntry->NameOffset);
|
||||||
|
|
||||||
|
if (_wcsnicmp(wsEntry, wszShortVirtualModule, pApiEntry->NameLength / 2) != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
pApiArray = (PAPI_SET_VALUE_ARRAY_V2)((PCHAR)pApiSetMap + pApiEntry->DataOffset);
|
||||||
|
|
||||||
|
for (dwSetCount = pApiArray->Count-1; dwSetCount >= 0; dwSetCount--)
|
||||||
|
{
|
||||||
|
pApiValue = &pApiArray->Array[dwSetCount];
|
||||||
|
wsName = (PWSTR)((PCHAR)pApiSetMap + pApiValue->NameOffset);
|
||||||
|
wsValue = (PWSTR)((PCHAR)pApiSetMap + pApiValue->ValueOffset);
|
||||||
|
|
||||||
|
if (pApiValue->NameLength == 0 || _wcsnicmp(wsName, wszImportingModule, pApiValue->NameLength / 2) == 0)
|
||||||
|
{
|
||||||
|
*stSize = pApiValue->ValueLength / 2;
|
||||||
|
return wsValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
152
c/meterpreter/source/extensions/unhook/apisetmap.h
Normal file
152
c/meterpreter/source/extensions/unhook/apisetmap.h
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
* Author: Jeff Tang <jtang@cylance.com>
|
||||||
|
* Copyright (c) 2017 Cylance Inc. All rights reserved. *
|
||||||
|
* *
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification, *
|
||||||
|
* are permitted provided that the following conditions are met: *
|
||||||
|
* *
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this *
|
||||||
|
* list of conditions and the following disclaimer. *
|
||||||
|
* *
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice, *
|
||||||
|
* this list of conditions and the following disclaimer in the documentation and/or *
|
||||||
|
* other materials provided with the distribution. *
|
||||||
|
* *
|
||||||
|
* 3. Neither the name of the copyright holder nor the names of its contributors *
|
||||||
|
* may be used to endorse or promote products derived from this software without *
|
||||||
|
* specific prior written permission. *
|
||||||
|
* *
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND *
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED *
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR *
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES *
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; *
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON *
|
||||||
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
|
||||||
|
* *
|
||||||
|
*************************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef _APISETMAP_H_
|
||||||
|
#define _APISETMAP_H_
|
||||||
|
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#include <windows.h>
|
||||||
|
#include "../../ReflectiveDLLInjection/dll/src/ReflectiveLoader.h"
|
||||||
|
|
||||||
|
|
||||||
|
_PPEB GetProcessEnvironmentBlock();
|
||||||
|
PLDR_DATA_TABLE_ENTRY GetInMemoryOrderModuleList();
|
||||||
|
|
||||||
|
// Win 10
|
||||||
|
typedef struct _API_SET_VALUE_ENTRY_V6
|
||||||
|
{
|
||||||
|
ULONG Flags;
|
||||||
|
ULONG NameOffset;
|
||||||
|
ULONG NameLength;
|
||||||
|
ULONG ValueOffset;
|
||||||
|
ULONG ValueLength;
|
||||||
|
} API_SET_VALUE_ENTRY_V6, *PAPI_SET_VALUE_ENTRY_V6;
|
||||||
|
|
||||||
|
typedef struct _API_SET_NAMESPACE_HASH_ENTRY_V6
|
||||||
|
{
|
||||||
|
ULONG Hash;
|
||||||
|
ULONG Index;
|
||||||
|
} API_SET_NAMESPACE_HASH_ENTRY_V6, *PAPI_SET_NAMESPACE_HASH_ENTRY_V6;
|
||||||
|
|
||||||
|
typedef struct _API_SET_NAMESPACE_ENTRY_V6
|
||||||
|
{
|
||||||
|
ULONG Flags;
|
||||||
|
ULONG NameOffset;
|
||||||
|
ULONG Size;
|
||||||
|
ULONG NameLength;
|
||||||
|
ULONG DataOffset;
|
||||||
|
ULONG Count;
|
||||||
|
} API_SET_NAMESPACE_ENTRY_V6, *PAPI_SET_NAMESPACE_ENTRY_V6;
|
||||||
|
|
||||||
|
typedef struct _API_SET_NAMESPACE_ARRAY_V6
|
||||||
|
{
|
||||||
|
ULONG Version;
|
||||||
|
ULONG Size;
|
||||||
|
ULONG Flags;
|
||||||
|
ULONG Count;
|
||||||
|
ULONG DataOffset;
|
||||||
|
ULONG HashOffset;
|
||||||
|
ULONG Multiplier;
|
||||||
|
API_SET_NAMESPACE_ENTRY_V6 Array[ANYSIZE_ARRAY];
|
||||||
|
} API_SET_NAMESPACE_ARRAY_V6, *PAPI_SET_NAMESPACE_ARRAY_V6;
|
||||||
|
|
||||||
|
// Windows 8.1
|
||||||
|
typedef struct _API_SET_VALUE_ENTRY_V4
|
||||||
|
{
|
||||||
|
ULONG Flags;
|
||||||
|
ULONG NameOffset;
|
||||||
|
ULONG NameLength;
|
||||||
|
ULONG ValueOffset;
|
||||||
|
ULONG ValueLength;
|
||||||
|
} API_SET_VALUE_ENTRY_V4, *PAPI_SET_VALUE_ENTRY_V4;
|
||||||
|
|
||||||
|
typedef struct _API_SET_VALUE_ARRAY_V4
|
||||||
|
{
|
||||||
|
ULONG Flags;
|
||||||
|
ULONG Count;
|
||||||
|
API_SET_VALUE_ENTRY_V4 Array[ANYSIZE_ARRAY];
|
||||||
|
} API_SET_VALUE_ARRAY_V4, *PAPI_SET_VALUE_ARRAY_V4;
|
||||||
|
|
||||||
|
typedef struct _API_SET_NAMESPACE_ENTRY_V4
|
||||||
|
{
|
||||||
|
ULONG Flags;
|
||||||
|
ULONG NameOffset;
|
||||||
|
ULONG NameLength;
|
||||||
|
ULONG AliasOffset;
|
||||||
|
ULONG AliasLength;
|
||||||
|
ULONG DataOffset;
|
||||||
|
} API_SET_NAMESPACE_ENTRY_V4, *PAPI_SET_NAMESPACE_ENTRY_V4;
|
||||||
|
|
||||||
|
typedef struct _API_SET_NAMESPACE_ARRAY_V4
|
||||||
|
{
|
||||||
|
ULONG Version;
|
||||||
|
ULONG Size;
|
||||||
|
ULONG Flags;
|
||||||
|
ULONG Count;
|
||||||
|
API_SET_NAMESPACE_ENTRY_V4 Array[ANYSIZE_ARRAY];
|
||||||
|
} API_SET_NAMESPACE_ARRAY_V4, *PAPI_SET_NAMESPACE_ARRAY_V4;
|
||||||
|
|
||||||
|
// Windows 7/8
|
||||||
|
typedef struct _API_SET_VALUE_ENTRY_V2
|
||||||
|
{
|
||||||
|
ULONG NameOffset;
|
||||||
|
ULONG NameLength;
|
||||||
|
ULONG ValueOffset;
|
||||||
|
ULONG ValueLength;
|
||||||
|
} API_SET_VALUE_ENTRY_V2, *PAPI_SET_VALUE_ENTRY_V2;
|
||||||
|
|
||||||
|
typedef struct _API_SET_VALUE_ARRAY_V2
|
||||||
|
{
|
||||||
|
ULONG Count;
|
||||||
|
API_SET_VALUE_ENTRY_V2 Array[ANYSIZE_ARRAY];
|
||||||
|
} API_SET_VALUE_ARRAY_V2, *PAPI_SET_VALUE_ARRAY_V2;
|
||||||
|
|
||||||
|
typedef struct _API_SET_NAMESPACE_ENTRY_V2
|
||||||
|
{
|
||||||
|
ULONG NameOffset;
|
||||||
|
ULONG NameLength;
|
||||||
|
ULONG DataOffset;
|
||||||
|
} API_SET_NAMESPACE_ENTRY_V2, *PAPI_SET_NAMESPACE_ENTRY_V2;
|
||||||
|
|
||||||
|
typedef struct _API_SET_NAMESPACE_ARRAY_V2
|
||||||
|
{
|
||||||
|
ULONG Version;
|
||||||
|
ULONG Count;
|
||||||
|
API_SET_NAMESPACE_ENTRY_V2 Array[ANYSIZE_ARRAY];
|
||||||
|
} API_SET_NAMESPACE_ARRAY_V2, *PAPI_SET_NAMESPACE_ARRAY_V2;
|
||||||
|
|
||||||
|
PWCHAR GetRedirectedName(const PWSTR wszImportingModule, const PWSTR wszVirtualModule, SIZE_T* stSize);
|
||||||
|
PWCHAR GetRedirectedName_V6(const PWSTR wszImportingModule, const PWSTR wszVirtualModule, SIZE_T* stSize);
|
||||||
|
PWCHAR GetRedirectedName_V4(const PWSTR wszImportingModule, const PWSTR wszVirtualModule, SIZE_T* stSize);
|
||||||
|
PWCHAR GetRedirectedName_V2(const PWSTR wszImportingModule, const PWSTR wszVirtualModule, SIZE_T* stSize);
|
||||||
|
|
||||||
|
#endif // _APISETMAP_H_
|
515
c/meterpreter/source/extensions/unhook/refresh.c
Normal file
515
c/meterpreter/source/extensions/unhook/refresh.c
Normal file
@ -0,0 +1,515 @@
|
|||||||
|
#include "refresh.h"
|
||||||
|
#include "apisetmap.h"
|
||||||
|
#include "../../common/common.h"
|
||||||
|
#include "../../ReflectiveDLLInjection/dll/src/ReflectiveLoader.h"
|
||||||
|
|
||||||
|
void RefreshPE()
|
||||||
|
{
|
||||||
|
HMODULE hModule;
|
||||||
|
PWSTR wszFullDllName;
|
||||||
|
PWSTR wszBaseDllName;
|
||||||
|
ULONG_PTR pDllBase;
|
||||||
|
|
||||||
|
PLDR_DATA_TABLE_ENTRY pLdteHead = NULL;
|
||||||
|
PLDR_DATA_TABLE_ENTRY pLdteCurrent = NULL;
|
||||||
|
|
||||||
|
dprintf("[REFRESH] Running DLLRefresher");
|
||||||
|
|
||||||
|
pLdteHead = GetInMemoryOrderModuleList();
|
||||||
|
pLdteCurrent = pLdteHead;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (pLdteCurrent->FullDllName.Length > 2)
|
||||||
|
{
|
||||||
|
wszFullDllName = pLdteCurrent->FullDllName.pBuffer;
|
||||||
|
wszBaseDllName = pLdteCurrent->BaseDllName.pBuffer;
|
||||||
|
pDllBase = (ULONG_PTR)pLdteCurrent->DllBase;
|
||||||
|
|
||||||
|
dprintf("[REFRESH] Refreshing DLL: %S", wszFullDllName);
|
||||||
|
|
||||||
|
hModule = CustomLoadLibrary(wszFullDllName, wszBaseDllName, pDllBase);
|
||||||
|
|
||||||
|
if (hModule)
|
||||||
|
{
|
||||||
|
ScanAndFixModule((PCHAR)hModule, (PCHAR)pDllBase, wszBaseDllName);
|
||||||
|
VirtualFree(hModule, 0, MEM_RELEASE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pLdteCurrent = (PLDR_DATA_TABLE_ENTRY)pLdteCurrent->InMemoryOrderModuleList.Flink;
|
||||||
|
} while (pLdteCurrent != pLdteHead);
|
||||||
|
}
|
||||||
|
|
||||||
|
HMODULE CustomLoadLibrary(const PWCHAR wszFullDllName, const PWCHAR wszBaseDllName, ULONG_PTR pDllBase)
|
||||||
|
{
|
||||||
|
// File handles
|
||||||
|
HANDLE hFile = INVALID_HANDLE_VALUE;
|
||||||
|
HANDLE hMap = NULL;
|
||||||
|
PCHAR pFile = NULL;
|
||||||
|
|
||||||
|
// PE headers
|
||||||
|
PIMAGE_DOS_HEADER pDosHeader;
|
||||||
|
PIMAGE_NT_HEADERS pNtHeader;
|
||||||
|
PIMAGE_SECTION_HEADER pSectionHeader;
|
||||||
|
|
||||||
|
// Library
|
||||||
|
PCHAR pLibraryAddr = NULL;
|
||||||
|
DWORD dwIdx;
|
||||||
|
|
||||||
|
// Relocation
|
||||||
|
PIMAGE_DATA_DIRECTORY pDataDir;
|
||||||
|
PIMAGE_BASE_RELOCATION pBaseReloc;
|
||||||
|
ULONG_PTR pReloc;
|
||||||
|
DWORD dwNumRelocs;
|
||||||
|
ULONG_PTR pInitialImageBase;
|
||||||
|
PIMAGE_RELOC pImageReloc;
|
||||||
|
|
||||||
|
// Import
|
||||||
|
PIMAGE_IMPORT_DESCRIPTOR pImportDesc;
|
||||||
|
PCHAR szDllName;
|
||||||
|
SIZE_T stDllName;
|
||||||
|
PWSTR wszDllName = NULL;
|
||||||
|
PWCHAR wsRedir = NULL;
|
||||||
|
PWSTR wszRedirName = NULL;
|
||||||
|
SIZE_T stRedirName;
|
||||||
|
SIZE_T stSize;
|
||||||
|
|
||||||
|
HMODULE hModule;
|
||||||
|
PIMAGE_THUNK_DATA pThunkData;
|
||||||
|
FARPROC* pIatEntry;
|
||||||
|
|
||||||
|
// clr.dll hotpatches itself at runtime for performance reasons, so skip it
|
||||||
|
if (wcscmp(L"clr.dll", wszBaseDllName) == 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
dprintf("[REFRESH] Opening file: %S", wszFullDllName);
|
||||||
|
|
||||||
|
// ----
|
||||||
|
// Step 1: Map the file into memory
|
||||||
|
// ----
|
||||||
|
|
||||||
|
hFile = CreateFileW(wszFullDllName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
|
if (hFile == INVALID_HANDLE_VALUE)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
hMap = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
|
||||||
|
if (hMap == NULL)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
pFile = (PCHAR)MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0);
|
||||||
|
if (pFile == NULL)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
// ----
|
||||||
|
// Step 2: Parse the file headers and load it into memory
|
||||||
|
// ----
|
||||||
|
pDosHeader = (PIMAGE_DOS_HEADER)pFile;
|
||||||
|
pNtHeader = (PIMAGE_NT_HEADERS)(pFile + pDosHeader->e_lfanew);
|
||||||
|
|
||||||
|
// allocate memory to copy DLL into
|
||||||
|
dprintf("[REFRESH] Allocating memory for library");
|
||||||
|
pLibraryAddr = (PCHAR)VirtualAlloc(NULL, pNtHeader->OptionalHeader.SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
|
||||||
|
|
||||||
|
// copy header
|
||||||
|
dprintf("[REFRESH] Copying PE header into memory");
|
||||||
|
memcpy(pLibraryAddr, pFile, pNtHeader->OptionalHeader.SizeOfHeaders);
|
||||||
|
|
||||||
|
// copy sections
|
||||||
|
dprintf("[REFRESH] Copying PE sections into memory");
|
||||||
|
pSectionHeader = (PIMAGE_SECTION_HEADER)(pFile + pDosHeader->e_lfanew + sizeof(IMAGE_NT_HEADERS));
|
||||||
|
for (dwIdx = 0; dwIdx < pNtHeader->FileHeader.NumberOfSections; dwIdx++)
|
||||||
|
{
|
||||||
|
memcpy(pLibraryAddr + pSectionHeader[dwIdx].VirtualAddress,
|
||||||
|
pFile + pSectionHeader[dwIdx].PointerToRawData,
|
||||||
|
pSectionHeader[dwIdx].SizeOfRawData);
|
||||||
|
}
|
||||||
|
|
||||||
|
// update our pointers to the loaded image
|
||||||
|
pDosHeader = (PIMAGE_DOS_HEADER)pLibraryAddr;
|
||||||
|
pNtHeader = (PIMAGE_NT_HEADERS)(pLibraryAddr + pDosHeader->e_lfanew);
|
||||||
|
|
||||||
|
// ----
|
||||||
|
// Step 3: Calculate relocations
|
||||||
|
// ----
|
||||||
|
dprintf("[REFRESH] Calculating file relocations");
|
||||||
|
|
||||||
|
pDataDir = &pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
|
||||||
|
pInitialImageBase = pNtHeader->OptionalHeader.ImageBase;
|
||||||
|
// set the ImageBase to the already loaded module's base
|
||||||
|
pNtHeader->OptionalHeader.ImageBase = pDllBase;
|
||||||
|
|
||||||
|
// check if their are any relocations present
|
||||||
|
if (pDataDir->Size)
|
||||||
|
{
|
||||||
|
// calculate the address of the first IMAGE_BASE_RELOCATION entry
|
||||||
|
pBaseReloc = (PIMAGE_BASE_RELOCATION)(pLibraryAddr + pDataDir->VirtualAddress);
|
||||||
|
|
||||||
|
// iterate through each relocation entry
|
||||||
|
while ((PCHAR)pBaseReloc < (pLibraryAddr + pDataDir->VirtualAddress + pDataDir->Size) && pBaseReloc->SizeOfBlock)
|
||||||
|
{
|
||||||
|
// the VA for this relocation block
|
||||||
|
pReloc = (ULONG_PTR)(pLibraryAddr + pBaseReloc->VirtualAddress);
|
||||||
|
|
||||||
|
// number of entries in this relocation block
|
||||||
|
dwNumRelocs = (pBaseReloc->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(IMAGE_RELOC);
|
||||||
|
|
||||||
|
// first entry in the current relocation block
|
||||||
|
pImageReloc = (PIMAGE_RELOC)((PCHAR)pBaseReloc + sizeof(IMAGE_BASE_RELOCATION));
|
||||||
|
|
||||||
|
// iterate through each entry in the relocation block
|
||||||
|
while (dwNumRelocs--)
|
||||||
|
{
|
||||||
|
// perform the relocation, skipping IMAGE_REL_BASED_ABSOLUTE as required.
|
||||||
|
// we subtract the initial ImageBase and add in the original dll base
|
||||||
|
if (pImageReloc->type == IMAGE_REL_BASED_DIR64)
|
||||||
|
{
|
||||||
|
*(ULONG_PTR *)(pReloc + pImageReloc->offset) -= pInitialImageBase;
|
||||||
|
*(ULONG_PTR *)(pReloc + pImageReloc->offset) += pDllBase;
|
||||||
|
}
|
||||||
|
else if (pImageReloc->type == IMAGE_REL_BASED_HIGHLOW)
|
||||||
|
{
|
||||||
|
*(DWORD *)(pReloc + pImageReloc->offset) -= (DWORD)pInitialImageBase;
|
||||||
|
*(DWORD *)(pReloc + pImageReloc->offset) += (DWORD)pDllBase;
|
||||||
|
}
|
||||||
|
else if (pImageReloc->type == IMAGE_REL_BASED_HIGH)
|
||||||
|
{
|
||||||
|
*(WORD *)(pReloc + pImageReloc->offset) -= HIWORD(pInitialImageBase);
|
||||||
|
*(WORD *)(pReloc + pImageReloc->offset) += HIWORD(pDllBase);
|
||||||
|
}
|
||||||
|
else if (pImageReloc->type == IMAGE_REL_BASED_LOW)
|
||||||
|
{
|
||||||
|
*(WORD *)(pReloc + pImageReloc->offset) -= LOWORD(pInitialImageBase);
|
||||||
|
*(WORD *)(pReloc + pImageReloc->offset) += LOWORD(pDllBase);
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the next entry in the current relocation block
|
||||||
|
pImageReloc = (PIMAGE_RELOC)((PCHAR)pImageReloc + sizeof(IMAGE_RELOC));
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the next entry in the relocation directory
|
||||||
|
pBaseReloc = (PIMAGE_BASE_RELOCATION)((PCHAR)pBaseReloc + pBaseReloc->SizeOfBlock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----
|
||||||
|
// Step 4: Update import table
|
||||||
|
// ----
|
||||||
|
dprintf("[REFRESH] Resolving Import Address Table (IAT) ");
|
||||||
|
|
||||||
|
pDataDir = &pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
|
||||||
|
if (pDataDir->Size)
|
||||||
|
{
|
||||||
|
pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)(pLibraryAddr + pDataDir->VirtualAddress);
|
||||||
|
|
||||||
|
while (pImportDesc->Characteristics)
|
||||||
|
{
|
||||||
|
hModule = NULL;
|
||||||
|
wszDllName = NULL;
|
||||||
|
szDllName = (PCHAR)(pLibraryAddr + pImportDesc->Name);
|
||||||
|
stDllName = strnlen(szDllName, MAX_PATH);
|
||||||
|
wszDllName = (PWSTR)calloc(stDllName + 1, sizeof(WCHAR));
|
||||||
|
|
||||||
|
if (wszDllName == NULL)
|
||||||
|
goto next_import;
|
||||||
|
|
||||||
|
mbstowcs_s(&stSize, wszDllName, stDllName + 1, szDllName, stDllName);
|
||||||
|
|
||||||
|
dprintf("[REFRESH] Loading library: %S", wszDllName);
|
||||||
|
|
||||||
|
// If the DLL starts with api- or ext-, resolve the redirected name and load it
|
||||||
|
if (_wcsnicmp(wszDllName, L"api-", 4) == 0 || _wcsnicmp(wszDllName, L"ext-", 4) == 0)
|
||||||
|
{
|
||||||
|
// wsRedir is not null terminated
|
||||||
|
wsRedir = GetRedirectedName(wszBaseDllName, wszDllName, &stRedirName);
|
||||||
|
if (wsRedir)
|
||||||
|
{
|
||||||
|
// Free the original wszDllName and allocate a new buffer for the redirected dll name
|
||||||
|
free(wszDllName);
|
||||||
|
wszDllName = (PWSTR)calloc(stRedirName + 1, sizeof(WCHAR));
|
||||||
|
if (wszDllName == NULL)
|
||||||
|
goto next_import;
|
||||||
|
|
||||||
|
memcpy(wszDllName, wsRedir, stRedirName * sizeof(WCHAR));
|
||||||
|
dprintf("[REFRESH] Redirected library: %S", wszDllName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load the module
|
||||||
|
hModule = CustomGetModuleHandleW(wszDllName);
|
||||||
|
|
||||||
|
// Ignore libraries that fail to load
|
||||||
|
if (hModule == NULL)
|
||||||
|
goto next_import;
|
||||||
|
|
||||||
|
if (pImportDesc->OriginalFirstThunk)
|
||||||
|
pThunkData = (PIMAGE_THUNK_DATA)(pLibraryAddr + pImportDesc->OriginalFirstThunk);
|
||||||
|
else
|
||||||
|
pThunkData = (PIMAGE_THUNK_DATA)(pLibraryAddr + pImportDesc->FirstThunk);
|
||||||
|
|
||||||
|
pIatEntry = (FARPROC*)(pLibraryAddr + pImportDesc->FirstThunk);
|
||||||
|
|
||||||
|
// loop through each thunk and resolve the import
|
||||||
|
for(; DEREF(pThunkData); pThunkData++, pIatEntry++)
|
||||||
|
{
|
||||||
|
if (IMAGE_SNAP_BY_ORDINAL(pThunkData->u1.Ordinal))
|
||||||
|
*pIatEntry = CustomGetProcAddressEx(hModule, (PCHAR)IMAGE_ORDINAL(pThunkData->u1.Ordinal), wszDllName);
|
||||||
|
else
|
||||||
|
*pIatEntry = CustomGetProcAddressEx(hModule, ((PIMAGE_IMPORT_BY_NAME)(pLibraryAddr + DEREF(pThunkData)))->Name, wszDllName);
|
||||||
|
}
|
||||||
|
|
||||||
|
next_import:
|
||||||
|
if (wszDllName != NULL)
|
||||||
|
{
|
||||||
|
free(wszDllName);
|
||||||
|
wszDllName = NULL;
|
||||||
|
}
|
||||||
|
pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)((PCHAR)pImportDesc + sizeof(IMAGE_IMPORT_DESCRIPTOR));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if (pFile != NULL)
|
||||||
|
UnmapViewOfFile(pFile);
|
||||||
|
if (hMap != NULL)
|
||||||
|
CloseHandle(hMap);
|
||||||
|
if (hFile != INVALID_HANDLE_VALUE)
|
||||||
|
CloseHandle(hFile);
|
||||||
|
|
||||||
|
return (HMODULE) pLibraryAddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
HMODULE CustomGetModuleHandleW(const PWSTR wszModule)
|
||||||
|
{
|
||||||
|
HMODULE hModule = NULL;
|
||||||
|
PLDR_DATA_TABLE_ENTRY pLdteHead = NULL;
|
||||||
|
PLDR_DATA_TABLE_ENTRY pLdteCurrent = NULL;
|
||||||
|
|
||||||
|
dprintf("[REFRESH] Searching for loaded module: %S", wszModule);
|
||||||
|
|
||||||
|
pLdteCurrent = pLdteHead = GetInMemoryOrderModuleList();
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (pLdteCurrent->FullDllName.Length > 2 &&
|
||||||
|
_wcsnicmp(wszModule, pLdteCurrent->BaseDllName.pBuffer, pLdteCurrent->BaseDllName.Length / 2) == 0)
|
||||||
|
{
|
||||||
|
return ((HMODULE)pLdteCurrent->DllBase);
|
||||||
|
}
|
||||||
|
pLdteCurrent = (PLDR_DATA_TABLE_ENTRY)pLdteCurrent->InMemoryOrderModuleList.Flink;
|
||||||
|
} while (pLdteCurrent != pLdteHead);
|
||||||
|
|
||||||
|
return LoadLibraryW(wszModule);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID ScanAndFixModule(PCHAR pKnown, PCHAR pSuspect, PWCHAR wszBaseDllName)
|
||||||
|
{
|
||||||
|
// PE headers
|
||||||
|
PIMAGE_DOS_HEADER pDosHeader;
|
||||||
|
PIMAGE_NT_HEADERS pNtHeader;
|
||||||
|
PIMAGE_SECTION_HEADER pSectionHeader;
|
||||||
|
|
||||||
|
DWORD dwIdx;
|
||||||
|
|
||||||
|
dprintf("[REFRESH] Scanning module: %S", wszBaseDllName);
|
||||||
|
|
||||||
|
pDosHeader = (PIMAGE_DOS_HEADER)pKnown;
|
||||||
|
pNtHeader = (PIMAGE_NT_HEADERS)(pKnown + pDosHeader->e_lfanew);
|
||||||
|
|
||||||
|
// Scan PE header
|
||||||
|
ScanAndFixSection("Header", pKnown, pSuspect, pNtHeader->OptionalHeader.SizeOfHeaders);
|
||||||
|
|
||||||
|
// Scan each section
|
||||||
|
pSectionHeader = (PIMAGE_SECTION_HEADER)(pKnown + pDosHeader->e_lfanew + sizeof(IMAGE_NT_HEADERS));
|
||||||
|
for (dwIdx = 0; dwIdx < pNtHeader->FileHeader.NumberOfSections; dwIdx++)
|
||||||
|
{
|
||||||
|
if (pSectionHeader[dwIdx].Characteristics & IMAGE_SCN_MEM_WRITE)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (wcscmp(wszBaseDllName, L"clr.dll") == 0 && strcmp(pSectionHeader[dwIdx].Name, ".text") == 0)
|
||||||
|
{
|
||||||
|
ScanAndFixSection((PCHAR)pSectionHeader[dwIdx].Name, pKnown + pSectionHeader[dwIdx].VirtualAddress,
|
||||||
|
pSuspect + pSectionHeader[dwIdx].VirtualAddress, pSectionHeader[dwIdx].Misc.VirtualSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID ScanAndFixSection(PCHAR szSectionName, PCHAR pKnown, PCHAR pSuspect, size_t stLength)
|
||||||
|
{
|
||||||
|
DWORD ddOldProtect;
|
||||||
|
|
||||||
|
if (memcmp(pKnown, pSuspect, stLength) != 0)
|
||||||
|
{
|
||||||
|
dprintf("[REFRESH] Found modification in: %s", szSectionName);
|
||||||
|
|
||||||
|
if (!VirtualProtect(pSuspect, stLength, PAGE_EXECUTE_READWRITE, &ddOldProtect))
|
||||||
|
return;
|
||||||
|
|
||||||
|
dprintf("[REFRESH] Copying known good section into memory.");
|
||||||
|
memcpy(pSuspect, pKnown, stLength);
|
||||||
|
|
||||||
|
if (!VirtualProtect(pSuspect, stLength, ddOldProtect, &ddOldProtect))
|
||||||
|
dprintf("[REFRESH] Unable to reset memory permissions");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// This code is modified from Stephen Fewer's GetProcAddress implementation
|
||||||
|
//===============================================================================================//
|
||||||
|
// Copyright (c) 2013, Stephen Fewer of Harmony Security (www.harmonysecurity.com)
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without modification, are permitted
|
||||||
|
// provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
// conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// * Redistributions in binary form must reproduce the above copyright notice, this list of
|
||||||
|
// conditions and the following disclaimer in the documentation and/or other materials provided
|
||||||
|
// with the distribution.
|
||||||
|
//
|
||||||
|
// * Neither the name of Harmony Security nor the names of its contributors may be used to
|
||||||
|
// endorse or promote products derived from this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
|
||||||
|
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||||
|
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//===============================================================================================//
|
||||||
|
FARPROC WINAPI CustomGetProcAddressEx(HMODULE hModule, const PCHAR lpProcName, PWSTR wszOriginalModule)
|
||||||
|
{
|
||||||
|
UINT_PTR uiLibraryAddress = 0;
|
||||||
|
UINT_PTR uiAddressArray = 0;
|
||||||
|
UINT_PTR uiNameArray = 0;
|
||||||
|
UINT_PTR uiNameOrdinals = 0;
|
||||||
|
UINT_PTR uiFuncVA = 0;
|
||||||
|
PCHAR cpExportedFunctionName;
|
||||||
|
PCHAR szFwdDesc;
|
||||||
|
PCHAR szRedirFunc;
|
||||||
|
PWSTR wszDllName;
|
||||||
|
SIZE_T stDllName;
|
||||||
|
PWCHAR wsRedir;
|
||||||
|
PWSTR wszRedirName = NULL;
|
||||||
|
SIZE_T stRedirName;
|
||||||
|
|
||||||
|
HMODULE hFwdModule;
|
||||||
|
PIMAGE_NT_HEADERS pNtHeaders = NULL;
|
||||||
|
PIMAGE_DATA_DIRECTORY pDataDirectory = NULL;
|
||||||
|
PIMAGE_EXPORT_DIRECTORY pExportDirectory = NULL;
|
||||||
|
FARPROC fpResult = NULL;
|
||||||
|
DWORD dwCounter;
|
||||||
|
|
||||||
|
if (hModule == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// a module handle is really its base address
|
||||||
|
uiLibraryAddress = (UINT_PTR)hModule;
|
||||||
|
|
||||||
|
// get the VA of the modules NT Header
|
||||||
|
pNtHeaders = (PIMAGE_NT_HEADERS)(uiLibraryAddress + ((PIMAGE_DOS_HEADER)uiLibraryAddress)->e_lfanew);
|
||||||
|
|
||||||
|
pDataDirectory = (PIMAGE_DATA_DIRECTORY)&pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
|
||||||
|
|
||||||
|
// get the VA of the export directory
|
||||||
|
pExportDirectory = (PIMAGE_EXPORT_DIRECTORY)(uiLibraryAddress + pDataDirectory->VirtualAddress);
|
||||||
|
|
||||||
|
// get the VA for the array of addresses
|
||||||
|
uiAddressArray = (uiLibraryAddress + pExportDirectory->AddressOfFunctions);
|
||||||
|
|
||||||
|
// get the VA for the array of name pointers
|
||||||
|
uiNameArray = (uiLibraryAddress + pExportDirectory->AddressOfNames);
|
||||||
|
|
||||||
|
// get the VA for the array of name ordinals
|
||||||
|
uiNameOrdinals = (uiLibraryAddress + pExportDirectory->AddressOfNameOrdinals);
|
||||||
|
|
||||||
|
// test if we are importing by name or by ordinal...
|
||||||
|
#pragma warning(suppress: 4311)
|
||||||
|
if (((DWORD)lpProcName & 0xFFFF0000) == 0x00000000)
|
||||||
|
{
|
||||||
|
// import by ordinal...
|
||||||
|
|
||||||
|
// use the import ordinal (- export ordinal base) as an index into the array of addresses
|
||||||
|
#pragma warning(suppress: 4311)
|
||||||
|
uiAddressArray += ((IMAGE_ORDINAL((DWORD)lpProcName) - pExportDirectory->Base) * sizeof(DWORD));
|
||||||
|
|
||||||
|
// resolve the address for this imported function
|
||||||
|
fpResult = (FARPROC)(uiLibraryAddress + DEREF_32(uiAddressArray));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// import by name...
|
||||||
|
dwCounter = pExportDirectory->NumberOfNames;
|
||||||
|
while (dwCounter--)
|
||||||
|
{
|
||||||
|
cpExportedFunctionName = (PCHAR)(uiLibraryAddress + DEREF_32(uiNameArray));
|
||||||
|
|
||||||
|
// test if we have a match...
|
||||||
|
if (strcmp(cpExportedFunctionName, lpProcName) == 0)
|
||||||
|
{
|
||||||
|
// use the functions name ordinal as an index into the array of name pointers
|
||||||
|
uiAddressArray += (DEREF_16(uiNameOrdinals) * sizeof(DWORD));
|
||||||
|
uiFuncVA = DEREF_32(uiAddressArray);
|
||||||
|
|
||||||
|
// check for redirected exports
|
||||||
|
if (pDataDirectory->VirtualAddress <= uiFuncVA && uiFuncVA < (pDataDirectory->VirtualAddress + pDataDirectory->Size))
|
||||||
|
{
|
||||||
|
szFwdDesc = (PCHAR)(uiLibraryAddress + uiFuncVA);
|
||||||
|
|
||||||
|
// Find the first character after "."
|
||||||
|
szRedirFunc = strstr(szFwdDesc, ".") + 1;
|
||||||
|
stDllName = (SIZE_T)(szRedirFunc - szFwdDesc);
|
||||||
|
|
||||||
|
// Allocate enough space to append "dll"
|
||||||
|
wszDllName = (PWSTR)calloc(stDllName + 3 + 1, sizeof(WCHAR));
|
||||||
|
if (wszDllName == NULL)
|
||||||
|
break;
|
||||||
|
|
||||||
|
mbstowcs_s(NULL, wszDllName, stDllName + 1, szFwdDesc, stDllName);
|
||||||
|
memcpy(wszDllName + stDllName, L"dll", 3 * sizeof(WCHAR));
|
||||||
|
|
||||||
|
// check for a redirected module name
|
||||||
|
if (_wcsnicmp(wszDllName, L"api-", 4) == 0 || _wcsnicmp(wszDllName, L"ext-", 4) == 0)
|
||||||
|
{
|
||||||
|
wsRedir = GetRedirectedName(wszOriginalModule, wszDllName, &stRedirName);
|
||||||
|
if (wsRedir)
|
||||||
|
{
|
||||||
|
// Free the original buffer and allocate a new one for the redirected dll name
|
||||||
|
free(wszDllName);
|
||||||
|
|
||||||
|
wszDllName = (PWSTR)calloc(stRedirName + 1, sizeof(WCHAR));
|
||||||
|
if (wszDllName == NULL)
|
||||||
|
break;
|
||||||
|
|
||||||
|
memcpy(wszDllName, wsRedir, stRedirName * sizeof(WCHAR));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hFwdModule = GetModuleHandleW(wszDllName);
|
||||||
|
fpResult = CustomGetProcAddressEx(hFwdModule, szRedirFunc, wszDllName);
|
||||||
|
free(wszDllName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// calculate the virtual address for the function
|
||||||
|
fpResult = (FARPROC)(uiLibraryAddress + uiFuncVA);
|
||||||
|
}
|
||||||
|
|
||||||
|
// finish...
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the next exported function name
|
||||||
|
uiNameArray += sizeof(DWORD);
|
||||||
|
|
||||||
|
// get the next exported function name ordinal
|
||||||
|
uiNameOrdinals += sizeof(WORD);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fpResult;
|
||||||
|
}
|
19
c/meterpreter/source/extensions/unhook/refresh.h
Normal file
19
c/meterpreter/source/extensions/unhook/refresh.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
#define OUTPUTDBGA(str) OutputDebugStringA(str);
|
||||||
|
#define OUTPUTDBGW(str) OutputDebugStringW(str);
|
||||||
|
#else
|
||||||
|
#define OUTPUTDBGA(str)
|
||||||
|
#define OUTPUTDBGW(str)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void RefreshPE();
|
||||||
|
HMODULE CustomLoadLibrary(const PWCHAR wszFullDllName, const PWCHAR wszBaseDllName, ULONG_PTR pDllBase);
|
||||||
|
HMODULE CustomGetModuleHandleW(const PWSTR wszModule);
|
||||||
|
FARPROC WINAPI CustomGetProcAddressEx(HMODULE hModule, const PCHAR lpProcName, PWSTR wszOriginalModule);
|
||||||
|
VOID ScanAndFixModule(PCHAR pKnown, PCHAR pSuspect, PWCHAR wszBaseDllName);
|
||||||
|
VOID ScanAndFixSection(PCHAR szSectionName, PCHAR pKnown, PCHAR pSuspect, size_t stLength);
|
64
c/meterpreter/source/extensions/unhook/unhook.c
Normal file
64
c/meterpreter/source/extensions/unhook/unhook.c
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
/*!
|
||||||
|
* @file unhook.c
|
||||||
|
* @brief Entry point and intialisation functionality for the unhook extention.
|
||||||
|
*/
|
||||||
|
#include "../../common/common.h"
|
||||||
|
|
||||||
|
#include "../../DelayLoadMetSrv/DelayLoadMetSrv.h"
|
||||||
|
// include the Reflectiveloader() function, we end up linking back to the metsrv.dll's Init function
|
||||||
|
// but this doesnt matter as we wont ever call DLL_METASPLOIT_ATTACH as that is only used by the
|
||||||
|
// second stage reflective dll inject payload and not the metsrv itself when it loads extensions.
|
||||||
|
#include "../../ReflectiveDLLInjection/dll/src/ReflectiveLoader.c"
|
||||||
|
|
||||||
|
#include "unhook.h"
|
||||||
|
#include "refresh.h"
|
||||||
|
|
||||||
|
DWORD unhook_pe(Remote *remote, Packet *packet);
|
||||||
|
|
||||||
|
// this sets the delay load hook function, see DelayLoadMetSrv.h
|
||||||
|
EnableDelayLoadMetSrv();
|
||||||
|
|
||||||
|
Command customCommands[] =
|
||||||
|
{
|
||||||
|
// custom commands go here
|
||||||
|
COMMAND_REQ("unhook_pe", unhook_pe),
|
||||||
|
|
||||||
|
COMMAND_TERMINATOR
|
||||||
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Initialize the server extension
|
||||||
|
*/
|
||||||
|
DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
|
||||||
|
{
|
||||||
|
hMetSrv = remote->met_srv;
|
||||||
|
|
||||||
|
command_register_all(customCommands);
|
||||||
|
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Deinitialize the server extension
|
||||||
|
*/
|
||||||
|
DWORD __declspec(dllexport) DeinitServerExtension(Remote *remote)
|
||||||
|
{
|
||||||
|
command_deregister_all(customCommands);
|
||||||
|
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DWORD unhook_pe(Remote *remote, Packet *packet)
|
||||||
|
{
|
||||||
|
Packet *response = packet_create_response(packet);
|
||||||
|
DWORD result = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
RefreshPE();
|
||||||
|
|
||||||
|
packet_add_tlv_uint(response, TLV_TYPE_UNHOOK_RESPONSE, ERROR_SUCCESS);
|
||||||
|
packet_transmit_response(result, remote, response);
|
||||||
|
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
|
||||||
|
}
|
13
c/meterpreter/source/extensions/unhook/unhook.h
Normal file
13
c/meterpreter/source/extensions/unhook/unhook.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
/*!
|
||||||
|
* @file bare.h
|
||||||
|
* @brief Entry point and intialisation declrations for the bare extention.
|
||||||
|
*/
|
||||||
|
#ifndef _METERPRETER_SOURCE_EXTENSION_UNHOOK_UNHOOK_H
|
||||||
|
#define _METERPRETER_SOURCE_EXTENSION_UNHOOK_UNHOOK_H
|
||||||
|
|
||||||
|
#define TLV_TYPE_EXTENSION_UNHOOK 0
|
||||||
|
|
||||||
|
// Custom TLVs go here
|
||||||
|
#define TLV_TYPE_UNHOOK_RESPONSE MAKE_CUSTOM_TLV(TLV_META_TYPE_UINT, TLV_TYPE_EXTENSION_UNHOOK, TLV_EXTENSIONS + 1)
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,304 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="r7_release|Win32">
|
||||||
|
<Configuration>r7_release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="r7_release|x64">
|
||||||
|
<Configuration>r7_release</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|x64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>{561E26D9-7E79-4EF4-8AA2-A770F81568A7}</ProjectGuid>
|
||||||
|
<RootNamespace>ext_server_unhook</RootNamespace>
|
||||||
|
<Keyword>Win32Proj</Keyword>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
|
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||||
|
<PlatformToolset>v120_xp</PlatformToolset>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='r7_release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
|
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||||
|
<PlatformToolset>v120_xp</PlatformToolset>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
|
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||||
|
<PlatformToolset>v120_xp</PlatformToolset>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='r7_release|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
|
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||||
|
<PlatformToolset>v120_xp</PlatformToolset>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup>
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
|
||||||
|
<OutDir>$(Configuration)\$(Platform)\</OutDir>
|
||||||
|
<IntDir>$(Configuration)\$(Platform)\</IntDir>
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
<GenerateManifest>false</GenerateManifest>
|
||||||
|
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
<CodeAnalysisRules />
|
||||||
|
<CodeAnalysisRuleAssemblies />
|
||||||
|
<TargetName>$(ProjectName).$(PlatformShortName)</TargetName>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<Optimization>MinSpace</Optimization>
|
||||||
|
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
||||||
|
<IntrinsicFunctions>false</IntrinsicFunctions>
|
||||||
|
<AdditionalIncludeDirectories>..\..\source\ReflectiveDLLInjection\common;..\..\source\extensions\unhook;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;EXT_SERVER_UNHOOK_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<StringPooling>true</StringPooling>
|
||||||
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
|
<FunctionLevelLinking>false</FunctionLevelLinking>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<AssemblerListingLocation>$(OutDir)\</AssemblerListingLocation>
|
||||||
|
<ObjectFileName>$(OutDir)\</ObjectFileName>
|
||||||
|
<ProgramDataBaseFileName>$(OutDir)\</ProgramDataBaseFileName>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
|
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||||
|
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
|
||||||
|
<TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<AdditionalDependencies>backcompat.lib;Netapi32.lib;Mpr.lib;metsrv.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<AdditionalLibraryDirectories>..\backcompat\$(Configuration);..\metsrv\$(Configuration)\$(Platform);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||||
|
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
|
||||||
|
<IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
|
||||||
|
<DelayLoadDLLs>metsrv.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
|
||||||
|
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||||
|
<GenerateMapFile>true</GenerateMapFile>
|
||||||
|
<MapFileName>$(OutDir)\ext_server_unhook.map</MapFileName>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<OptimizeReferences>
|
||||||
|
</OptimizeReferences>
|
||||||
|
<EnableCOMDATFolding>
|
||||||
|
</EnableCOMDATFolding>
|
||||||
|
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||||
|
<DataExecutionPrevention>
|
||||||
|
</DataExecutionPrevention>
|
||||||
|
<ImportLibrary>$(OutDir)\ext_server_unhook.lib</ImportLibrary>
|
||||||
|
<TargetMachine>MachineX86</TargetMachine>
|
||||||
|
<Profile>false</Profile>
|
||||||
|
<MinimumRequiredVersion>5.02</MinimumRequiredVersion>
|
||||||
|
</Link>
|
||||||
|
<PostBuildEvent>
|
||||||
|
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" > NUL
|
||||||
|
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY
|
||||||
|
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\"
|
||||||
|
:COPY
|
||||||
|
copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformShortName)\"</Command>
|
||||||
|
</PostBuildEvent>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='r7_release|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<Optimization>MinSpace</Optimization>
|
||||||
|
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
||||||
|
<IntrinsicFunctions>false</IntrinsicFunctions>
|
||||||
|
<AdditionalIncludeDirectories>..\..\source\ReflectiveDLLInjection\common;..\..\source\extensions\unhook;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;EXT_SERVER_UNHOOK_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<StringPooling>true</StringPooling>
|
||||||
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
|
<FunctionLevelLinking>false</FunctionLevelLinking>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<AssemblerListingLocation>$(OutDir)\</AssemblerListingLocation>
|
||||||
|
<ObjectFileName>$(OutDir)\</ObjectFileName>
|
||||||
|
<ProgramDataBaseFileName>$(OutDir)\</ProgramDataBaseFileName>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
|
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||||
|
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
|
||||||
|
<TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<AdditionalDependencies>backcompat.lib;Netapi32.lib;Mpr.lib;metsrv.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<AdditionalLibraryDirectories>..\backcompat\$(Configuration);..\metsrv\$(Configuration)\$(Platform);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||||
|
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
|
||||||
|
<IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
|
||||||
|
<DelayLoadDLLs>metsrv.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
|
||||||
|
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||||
|
<GenerateMapFile>true</GenerateMapFile>
|
||||||
|
<MapFileName>$(OutDir)\ext_server_unhook.map</MapFileName>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<OptimizeReferences>
|
||||||
|
</OptimizeReferences>
|
||||||
|
<EnableCOMDATFolding>
|
||||||
|
</EnableCOMDATFolding>
|
||||||
|
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||||
|
<DataExecutionPrevention>
|
||||||
|
</DataExecutionPrevention>
|
||||||
|
<ImportLibrary>$(OutDir)\ext_server_unhook.lib</ImportLibrary>
|
||||||
|
<TargetMachine>MachineX86</TargetMachine>
|
||||||
|
<Profile>false</Profile>
|
||||||
|
<MinimumRequiredVersion>5.02</MinimumRequiredVersion>
|
||||||
|
</Link>
|
||||||
|
<PostBuildEvent>
|
||||||
|
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" > NUL
|
||||||
|
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY
|
||||||
|
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\"
|
||||||
|
:COPY
|
||||||
|
copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformShortName)\"</Command>
|
||||||
|
</PostBuildEvent>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<Midl>
|
||||||
|
<TargetEnvironment>X64</TargetEnvironment>
|
||||||
|
</Midl>
|
||||||
|
<ClCompile>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
||||||
|
<IntrinsicFunctions>false</IntrinsicFunctions>
|
||||||
|
<AdditionalIncludeDirectories>..\..\source\ReflectiveDLLInjection\common;..\..\source\extensions\unhook;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;EXT_SERVER_UNHOOK_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<StringPooling>true</StringPooling>
|
||||||
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
|
<FunctionLevelLinking>false</FunctionLevelLinking>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<AssemblerListingLocation>$(OutDir)\</AssemblerListingLocation>
|
||||||
|
<ObjectFileName>$(OutDir)\</ObjectFileName>
|
||||||
|
<ProgramDataBaseFileName>$(OutDir)\</ProgramDataBaseFileName>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
|
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||||
|
<TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<AdditionalDependencies>Netapi32.lib;Mpr.lib;metsrv.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<AdditionalLibraryDirectories>..\metsrv\$(Configuration)\$(Platform);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||||
|
<DelayLoadDLLs>metsrv.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
|
||||||
|
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||||
|
<GenerateMapFile>true</GenerateMapFile>
|
||||||
|
<MapFileName>$(OutDir)\ext_server_unhook.map</MapFileName>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<OptimizeReferences>
|
||||||
|
</OptimizeReferences>
|
||||||
|
<EnableCOMDATFolding>
|
||||||
|
</EnableCOMDATFolding>
|
||||||
|
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||||
|
<DataExecutionPrevention>
|
||||||
|
</DataExecutionPrevention>
|
||||||
|
<ImportLibrary>$(OutDir)\ext_server_unhook.lib</ImportLibrary>
|
||||||
|
<TargetMachine>MachineX64</TargetMachine>
|
||||||
|
<Profile>false</Profile>
|
||||||
|
</Link>
|
||||||
|
<PostBuildEvent>
|
||||||
|
<Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" > NUL
|
||||||
|
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY
|
||||||
|
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\"
|
||||||
|
:COPY
|
||||||
|
copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformShortName)\"</Command>
|
||||||
|
</PostBuildEvent>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='r7_release|x64'">
|
||||||
|
<Midl>
|
||||||
|
<TargetEnvironment>X64</TargetEnvironment>
|
||||||
|
</Midl>
|
||||||
|
<ClCompile>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
||||||
|
<IntrinsicFunctions>false</IntrinsicFunctions>
|
||||||
|
<AdditionalIncludeDirectories>..\..\source\ReflectiveDLLInjection\common;..\..\source\extensions\unhook;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;EXT_SERVER_UNHOOK_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<StringPooling>true</StringPooling>
|
||||||
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
|
<FunctionLevelLinking>false</FunctionLevelLinking>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<AssemblerListingLocation>$(OutDir)\</AssemblerListingLocation>
|
||||||
|
<ObjectFileName>$(OutDir)\</ObjectFileName>
|
||||||
|
<ProgramDataBaseFileName>$(OutDir)\</ProgramDataBaseFileName>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
|
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||||
|
<TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<AdditionalDependencies>Netapi32.lib;Mpr.lib;metsrv.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<AdditionalLibraryDirectories>..\metsrv\$(Configuration)\$(Platform);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||||
|
<DelayLoadDLLs>metsrv.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
|
||||||
|
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||||
|
<GenerateMapFile>true</GenerateMapFile>
|
||||||
|
<MapFileName>$(OutDir)\ext_server_unhook.map</MapFileName>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<OptimizeReferences>
|
||||||
|
</OptimizeReferences>
|
||||||
|
<EnableCOMDATFolding>
|
||||||
|
</EnableCOMDATFolding>
|
||||||
|
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||||
|
<DataExecutionPrevention>
|
||||||
|
</DataExecutionPrevention>
|
||||||
|
<ImportLibrary>$(OutDir)\ext_server_unhook.lib</ImportLibrary>
|
||||||
|
<TargetMachine>MachineX64</TargetMachine>
|
||||||
|
<Profile>false</Profile>
|
||||||
|
</Link>
|
||||||
|
<PostBuildEvent>
|
||||||
|
<Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" > NUL
|
||||||
|
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY
|
||||||
|
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\"
|
||||||
|
:COPY
|
||||||
|
copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformShortName)\"</Command>
|
||||||
|
</PostBuildEvent>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\..\source\extensions\unhook\apisetmap.c" />
|
||||||
|
<ClCompile Include="..\..\source\extensions\unhook\refresh.c" />
|
||||||
|
<ClCompile Include="..\..\source\extensions\unhook\unhook.c" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="..\..\source\extensions\unhook\apisetmap.h" />
|
||||||
|
<ClInclude Include="..\..\source\extensions\unhook\refresh.h" />
|
||||||
|
<ClInclude Include="..\..\source\extensions\unhook\unhook.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\backcompat\backcompat.vcxproj">
|
||||||
|
<Project>{c6fb3275-9067-4bba-9206-0a720d2bc64f}</Project>
|
||||||
|
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||||
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\common\common.vcxproj">
|
||||||
|
<Project>{9e4de963-873f-4525-a7d0-ce34edbbdcca}</Project>
|
||||||
|
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||||
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\metsrv\metsrv.vcxproj">
|
||||||
|
<Project>{37e24f8f-1bd9-490b-8cd2-4768b89e5eab}</Project>
|
||||||
|
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||||
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\ReflectiveDLLInjection\ReflectiveDLLInjection.vcxproj">
|
||||||
|
<Project>{72f0246a-a38d-4547-9057-46020e8e503d}</Project>
|
||||||
|
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
@ -41,6 +41,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ext_server_winpmem", "ext_s
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ext_server_peinjector", "ext_server_peinjector\ext_server_peinjector.vcxproj", "{2A4FDCA0-A620-4E98-AF05-2B2F227F5166}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ext_server_peinjector", "ext_server_peinjector\ext_server_peinjector.vcxproj", "{2A4FDCA0-A620-4E98-AF05-2B2F227F5166}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ext_server_unhook", "ext_server_unhook\ext_server_unhook.vcxproj", "{561E26D9-7E79-4EF4-8AA2-A770F81568A7}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
r7_release|Win32 = r7_release|Win32
|
r7_release|Win32 = r7_release|Win32
|
||||||
@ -199,6 +201,14 @@ Global
|
|||||||
{2A4FDCA0-A620-4E98-AF05-2B2F227F5166}.Release|Win32.Build.0 = Release|Win32
|
{2A4FDCA0-A620-4E98-AF05-2B2F227F5166}.Release|Win32.Build.0 = Release|Win32
|
||||||
{2A4FDCA0-A620-4E98-AF05-2B2F227F5166}.Release|x64.ActiveCfg = Release|x64
|
{2A4FDCA0-A620-4E98-AF05-2B2F227F5166}.Release|x64.ActiveCfg = Release|x64
|
||||||
{2A4FDCA0-A620-4E98-AF05-2B2F227F5166}.Release|x64.Build.0 = Release|x64
|
{2A4FDCA0-A620-4E98-AF05-2B2F227F5166}.Release|x64.Build.0 = Release|x64
|
||||||
|
{561E26D9-7E79-4EF4-8AA2-A770F81568A7}.r7_release|Win32.ActiveCfg = r7_release|Win32
|
||||||
|
{561E26D9-7E79-4EF4-8AA2-A770F81568A7}.r7_release|Win32.Build.0 = r7_release|Win32
|
||||||
|
{561E26D9-7E79-4EF4-8AA2-A770F81568A7}.r7_release|x64.ActiveCfg = r7_release|x64
|
||||||
|
{561E26D9-7E79-4EF4-8AA2-A770F81568A7}.r7_release|x64.Build.0 = r7_release|x64
|
||||||
|
{561E26D9-7E79-4EF4-8AA2-A770F81568A7}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{561E26D9-7E79-4EF4-8AA2-A770F81568A7}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{561E26D9-7E79-4EF4-8AA2-A770F81568A7}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{561E26D9-7E79-4EF4-8AA2-A770F81568A7}.Release|x64.Build.0 = Release|x64
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
Loading…
x
Reference in New Issue
Block a user