Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
- /*
- CodeMon copy module bypass
- Credit to mcrypt. http://mcrypt.hatenablog.com/
- */
- /*=================== File: CodeMonL.hpp ===================*/
- #pragma once
- #include <map>
- typedef struct _MODULE_CONTEXT
- {
- PVOID ImageBase[3];
- PVOID BaseOfCode[3];
- DWORD SizeOfImage;
- PVOID OriginalImage;
- WCHAR ImageName[MAX_PATH];
- }MODULE_CONTEXT, far *LPMODULE_CONTEXT, near *PMODULE_CONTEXT, MODULE_CTX, far *LPMODULE_CTX, near *PMODULE_CTX;
- class CodeMonL
- {
- public:
- CodeMonL();
- ~CodeMonL();
- publuc:
- BOOL InitializeModuleContext(__in LPVOID lpBuffer, __in DWORD dwSize);
- BOOL FindModuleContext(__in LPVOID lpBuffer, __out LPVOID* lppvTarget, __out LPVOID* lppvOriginal);
- BOOL JmpToOriginalModule(__in LPVOID lpvTarget, __in LPVOID lpvOriginal);
- static CodeMonL *GetInstance()
- {
- static CodeMonL instance;
- return &instance;
- }
- private:
- BOOL SetModuleContext(__in LPVOID lpvOriginal, __in LPVOID lpvTarget, __in DWORD dwSize, __inout_opt MODULE_CONTEXT *pContext, __in DWORD dwBaseOfCodeOffset = 0x1000);
- MODULE_CONTEXT m_mCTX[9];
- };
- /*=================== File: CodeMonL.cpp ===================*/
- #include "stdafx.h"
- #include "CodeMonL.hpp"
- #include "utils.hpp"
- CodeMonL::CodeMonL()
- {
- }
- CodeMonL::~CodeMonL()
- {
- }
- BOOL CodeMonL::SetModuleContext(__in LPVOID lpvOriginal, __in LPVOID lpvTarget, __in DWORD dwSize, __inout_opt MODULE_CONTEXT *pContext, __in DWORD dwBaseOfCode)
- {
- int i = 0;
- if (!pContext->ImageBase[0])
- i = 0;
- else if (!pContext->ImageBase[1])
- i = 1;
- else if (!pContext->ImageBase[2])
- i = 2;
- pContext->BaseOfCode[i] = (PBYTE)lpvTarget + dwBaseOfCode;
- pContext->ImageBase[i] = lpvTarget;
- pContext->SizeOfImage = dwSize;
- pContext->OriginalImage = lpvOriginal;
- TCHAR szFilename[MAX_PATH];
- GetModuleFileName((HMODULE)lpvOriginal, szFilename, MAX_PATH);
- StringCchPrintf(pContext->ImageName, _countof(szFilename), _T("%s"), szFilename);
- return TRUE;
- }
- BOOL CodeMonL::InitializeModuleContext(__in LPVOID lpBuffer, __in DWORD dwSize)
- {
- if (lpBuffer == NULL || dwSize == NULL)
- return FALSE;
- switch (dwSize)
- {
- case 0x0017B000: // ntdll
- {
- SetModuleContext(GetModuleHandle(L"NTDLL"), lpBuffer, dwSize, &m_mCTX[0]);
- break;
- }
- case 0x0017E000: // kernelbase
- {
- SetModuleContext(GetModuleHandle(L"KERNELBASE"), lpBuffer, dwSize, &m_mCTX[1]);
- break;
- }
- case 0x0005F000: // ws2_32
- {
- SetModuleContext(GetModuleHandle(L"WS2_32"), lpBuffer, dwSize, &m_mCTX[2]);
- break;
- }
- case 0x000E0000: // kernel32
- {
- SetModuleContext(GetModuleHandle(L"KERNEL32"), lpBuffer, dwSize, &m_mCTX[3], 0x00010000);
- break;
- }
- case 0x00024000: // winmm
- {
- SetModuleContext(GetModuleHandle(L"WINMM"), lpBuffer, dwSize, &m_mCTX[4]);
- break;
- }
- case 0x00147000: // user32
- {
- SetModuleContext(GetModuleHandle(L"USER32"), lpBuffer, dwSize, &m_mCTX[5]);
- break;
- }
- case 0x0014F000: // gdi32
- {
- SetModuleContext(GetModuleHandle(L"GDI32"), lpBuffer, dwSize, &m_mCTX[6]);
- break;
- }
- case 0x001BD000: // combase
- {
- SetModuleContext(GetModuleHandle(L"COMBASE"), lpBuffer, dwSize, &m_mCTX[7]);
- break;
- }
- case 0x00277000: // wininet
- {
- SetModuleContext(GetModuleHandle(L"WININET"), lpBuffer, dwSize, &m_mCTX[8]);
- break;
- }
- default:
- {
- #ifdef _DEBUG
- if (dwSize >= 0x00010000)
- {
- LogOutput(L"[%s] lpBuffer = %p, dwSize = %p \n", __FUNCTIONW__, lpBuffer, dwSize);
- }
- #endif
- return FALSE;
- }
- }
- return TRUE;
- }
- BOOL CodeMonL::FindModuleContext(__in LPVOID lpBuffer, __out LPVOID* lppvTarget, __out LPVOID* lppvOriginal)
- {
- if (!lpBuffer)
- return FALSE;
- for (int i = 0; i < 9; i++)
- {
- // 3回コピーされるので 3
- for (int j = 0; j < 3; j++)
- {
- if (lpBuffer != m_mCTX[i].BaseOfCode[j])
- continue;
- if (!m_mCTX[i].ImageBase[j])
- continue;
- *lppvTarget = m_mCTX[i].ImageBase[j];
- *lppvOriginal = m_mCTX[i].OriginalImage;
- return TRUE;
- }
- }
- return FALSE;
- }
- BOOL CodeMonL::JmpToOriginalModule(__in LPVOID lpvTarget, __in LPVOID lpvOriginal)
- {
- if (!lpvModule || !lpvOriginal)
- return FALSE;
- LPDWORD pName, pNameOriginal;
- LPDWORD pFunc, pFuncOriginal;
- LPWORD pOrdinal, pOrdinalOriginal;
- // Copy
- IMAGE_NT_HEADERS32 *pNtHeaders = reinterpret_cast<IMAGE_NT_HEADERS32*>(reinterpret_cast<PBYTE>(lpvTarget) + PIMAGE_DOS_HEADER(lpvTarget)->e_lfanew);
- IMAGE_EXPORT_DIRECTORY *pExports = reinterpret_cast<IMAGE_EXPORT_DIRECTORY*>(reinterpret_cast<PBYTE>(lpvTarget) + pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
- // Original
- IMAGE_NT_HEADERS32 *pNtHeadersOriginal = reinterpret_cast<IMAGE_NT_HEADERS32*>(reinterpret_cast<PBYTE>(lpvOriginal) + PIMAGE_DOS_HEADER(lpvOriginal)->e_lfanew);
- IMAGE_EXPORT_DIRECTORY *pExportsOriginal = reinterpret_cast<IMAGE_EXPORT_DIRECTORY*>(reinterpret_cast<PBYTE>(lpvOriginal) + pNtHeadersOriginal->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
- if (pNtHeaders && pExports
- && pNtHeadersOriginal && pExportsOriginal)
- {
- // Copy
- pName = reinterpret_cast<LPDWORD>(reinterpret_cast<PBYTE>(lpvTarget) + pExports->AddressOfNames);
- pFunc = reinterpret_cast<LPDWORD>(reinterpret_cast<PBYTE>(lpvTarget) + pExports->AddressOfFunctions);
- pOrdinal = reinterpret_cast<LPWORD>(reinterpret_cast<PBYTE>(lpvTarget) + pExports->AddressOfNameOrdinals);
- // Original
- pNameOriginal = reinterpret_cast<LPDWORD>(reinterpret_cast<PBYTE>(lpvOriginal) + pExportsOriginal->AddressOfNames);
- pFuncOriginal = reinterpret_cast<LPDWORD>(reinterpret_cast<PBYTE>(lpvOriginal) + pExportsOriginal->AddressOfFunctions);
- pOrdinalOriginal = reinterpret_cast<LPWORD>(reinterpret_cast<PBYTE>(lpvOriginal) + pExportsOriginal->AddressOfNameOrdinals);
- // コピーされたDLLの各APIをオリジナルのDLLの各APIに飛ばす(jmp)
- for (int i = 0; i < pExports->NumberOfNames; i++)
- {
- WORD w = pOrdinal[i];
- WORD wo = pOrdinalOriginal[i];
- LPVOID lpvFunction = reinterpret_cast<LPVOID>(reinterpret_cast<PBYTE>(lpvTarget) + pFunc[w]);
- LPVOID lpvFuncOriginal = reinterpret_cast<LPVOID>(reinterpret_cast<PBYTE>(lpvOriginal) + pFuncOriginal[wo]);
- LPSTR pszName = reinterpret_cast<LPSTR>(reinterpret_cast<PBYTE>(lpvOriginal) + pNameOriginal[i]);
- DetourFunction(TRUE, reinterpret_cast<LPVOID*>(&lpvFunction), lpvFuncOriginal);
- }
- return TRUE;
- }
- return FALSE;
- }
- /*=================== File: Bypass.cpp ===================*/
- VOID Detour_o_o()
- {
- typedef LPVOID(WINAPI *pfnVirtualAlloc)(
- _In_opt_ LPVOID lpAddress,
- _In_ SIZE_T dwSize,
- _In_ DWORD flAllocationType,
- _In_ DWORD flProtect);
- typedef BOOL(WINAPI *pfnVirtualProtect)(
- _In_ LPVOID lpAddress,
- _In_ SIZE_T dwSize,
- _In_ DWORD flNewProtect,
- _Out_ PDWORD lpflOldProtect);
- static pfnVirtualAlloc _VirtualAlloc =
- reinterpret_cast<pfnVirtualAlloc>(GetProcAddress(GetModuleHandle(L"KERNELBASE.dll"), "VirtualAlloc"));
- pfnVirtualAlloc VirtualAlloc_Hook = [](
- _In_opt_ LPVOID lpAddress,
- _In_ SIZE_T dwSize,
- _In_ DWORD flAllocationType,
- _In_ DWORD flProtect) -> LPVOID
- {
- LPVOID lpBuffer = _VirtualAlloc(lpAddress, dwSize, flAllocationType, flProtect);
- if (lpBuffer)
- {
- CodeMonL::GetInstance()->InitializeModuleContext(lpBuffer, dwSize);
- }
- return lpBuffer;
- };
- static pfnVirtualProtect _VirtualProtect =
- reinterpret_cast<pfnVirtualProtect>(GetProcAddress(GetModuleHandle(L"KERNELBASE.dll"), "VirtualProtect"));
- pfnVirtualProtect VirtualProtect_Hook = [](
- _In_ LPVOID lpAddress,
- _In_ SIZE_T dwSize,
- _In_ DWORD flNewProtect,
- _Out_ PDWORD lpflOldProtect) -> BOOL
- {
- CodeMonL *pCodeMonL = CodeMonL::GetInstance();
- LPVOID lpvTarget, lpvOriginal;
- if (pCodeMonL->FindModuleContext(lpAddress, &lpvTarget, &lpvOriginal))
- if (lpvTarget && lpvOriginal)
- pCodeMonL->JmpToOriginalModule(lpvTarget, lpvOriginal);
- return _VirtualProtect(lpAddress, dwSize, flNewProtect, lpflOldProtect);
- };
- DetourFunction(TRUE, reinterpret_cast<LPVOID*>(&_VirtualAlloc), VirtualAlloc_Hook);
- DetourFunction(TRUE, reinterpret_cast<LPVOID*>(&_VirtualProtect), VirtualProtect_Hook);
- }
RAW Paste Data