SHARE
TWEET

CodeMon copy module bypass

ahcript Apr 15th, 2017 (edited) 18 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2. CodeMon copy module bypass
  3. Credit to mcrypt. http://mcrypt.hatenablog.com/
  4. */
  5.  
  6. /*=================== File: CodeMonL.hpp ===================*/
  7. #pragma once
  8.  
  9. #include <map>
  10.  
  11. typedef struct _MODULE_CONTEXT
  12. {
  13.     PVOID ImageBase[3];
  14.     PVOID BaseOfCode[3];
  15.     DWORD SizeOfImage;
  16.     PVOID OriginalImage;
  17.     WCHAR ImageName[MAX_PATH];
  18. }MODULE_CONTEXT, far *LPMODULE_CONTEXT, near *PMODULE_CONTEXT, MODULE_CTX, far *LPMODULE_CTX, near *PMODULE_CTX;
  19.  
  20. class CodeMonL
  21. {
  22. public:
  23.     CodeMonL();
  24.     ~CodeMonL();
  25.  
  26. publuc:
  27.     BOOL InitializeModuleContext(__in LPVOID lpBuffer, __in DWORD dwSize);
  28.     BOOL FindModuleContext(__in LPVOID lpBuffer, __out LPVOID* lppvTarget, __out LPVOID* lppvOriginal);
  29.     BOOL JmpToOriginalModule(__in LPVOID lpvTarget, __in LPVOID lpvOriginal);
  30.  
  31.     static CodeMonL *GetInstance()
  32.     {
  33.         static CodeMonL instance;
  34.         return &instance;
  35.     }
  36.  
  37. private:
  38.     BOOL SetModuleContext(__in LPVOID lpvOriginal, __in LPVOID lpvTarget, __in DWORD dwSize, __inout_opt MODULE_CONTEXT *pContext, __in DWORD dwBaseOfCodeOffset = 0x1000);
  39.     MODULE_CONTEXT m_mCTX[9];
  40. };
  41.  
  42. /*=================== File: CodeMonL.cpp ===================*/
  43. #include "stdafx.h"
  44.  
  45. #include "CodeMonL.hpp"
  46. #include "utils.hpp"
  47.  
  48. CodeMonL::CodeMonL()
  49. {
  50. }
  51. CodeMonL::~CodeMonL()
  52. {
  53. }
  54.  
  55. BOOL CodeMonL::SetModuleContext(__in LPVOID lpvOriginal, __in LPVOID lpvTarget, __in DWORD dwSize, __inout_opt MODULE_CONTEXT *pContext, __in DWORD dwBaseOfCode)
  56. {
  57.     int i = 0;
  58.  
  59.     if (!pContext->ImageBase[0])
  60.         i = 0;
  61.     else if (!pContext->ImageBase[1])
  62.         i = 1;
  63.     else if (!pContext->ImageBase[2])
  64.         i = 2;
  65.  
  66.     pContext->BaseOfCode[i] = (PBYTE)lpvTarget + dwBaseOfCode;
  67.     pContext->ImageBase[i]  = lpvTarget;
  68.     pContext->SizeOfImage   = dwSize;
  69.     pContext->OriginalImage = lpvOriginal;
  70.  
  71.     TCHAR szFilename[MAX_PATH];
  72.     GetModuleFileName((HMODULE)lpvOriginal, szFilename, MAX_PATH);
  73.     StringCchPrintf(pContext->ImageName, _countof(szFilename), _T("%s"), szFilename);
  74.  
  75.     return TRUE;
  76. }
  77.  
  78. BOOL CodeMonL::InitializeModuleContext(__in LPVOID lpBuffer, __in DWORD dwSize)
  79. {
  80.     if (lpBuffer == NULL || dwSize == NULL)
  81.         return FALSE;
  82.  
  83.     switch (dwSize)
  84.     {
  85.         case 0x0017B000: // ntdll
  86.         {
  87.             SetModuleContext(GetModuleHandle(L"NTDLL"), lpBuffer, dwSize, &m_mCTX[0]);
  88.             break;
  89.         }
  90.         case 0x0017E000: // kernelbase
  91.         {
  92.             SetModuleContext(GetModuleHandle(L"KERNELBASE"), lpBuffer, dwSize, &m_mCTX[1]);
  93.             break;
  94.         }
  95.         case 0x0005F000: // ws2_32
  96.         {
  97.             SetModuleContext(GetModuleHandle(L"WS2_32"), lpBuffer, dwSize, &m_mCTX[2]);
  98.             break;
  99.         }
  100.         case 0x000E0000: // kernel32
  101.         {
  102.             SetModuleContext(GetModuleHandle(L"KERNEL32"), lpBuffer, dwSize, &m_mCTX[3], 0x00010000);
  103.             break;
  104.         }
  105.         case 0x00024000: // winmm
  106.         {
  107.             SetModuleContext(GetModuleHandle(L"WINMM"), lpBuffer, dwSize, &m_mCTX[4]);
  108.             break;
  109.         }
  110.         case 0x00147000: // user32
  111.         {
  112.             SetModuleContext(GetModuleHandle(L"USER32"), lpBuffer, dwSize, &m_mCTX[5]);
  113.             break;
  114.         }
  115.         case 0x0014F000: // gdi32
  116.         {
  117.             SetModuleContext(GetModuleHandle(L"GDI32"), lpBuffer, dwSize, &m_mCTX[6]);
  118.             break;
  119.         }
  120.         case 0x001BD000: // combase
  121.         {
  122.             SetModuleContext(GetModuleHandle(L"COMBASE"), lpBuffer, dwSize, &m_mCTX[7]);
  123.             break;
  124.         }
  125.         case 0x00277000: // wininet
  126.         {
  127.             SetModuleContext(GetModuleHandle(L"WININET"), lpBuffer, dwSize, &m_mCTX[8]);
  128.             break;
  129.         }
  130.         default:
  131.         {
  132. #ifdef _DEBUG
  133.             if (dwSize >= 0x00010000)
  134.             {
  135.                 LogOutput(L"[%s] lpBuffer = %p, dwSize = %p \n", __FUNCTIONW__, lpBuffer, dwSize);
  136.             }
  137. #endif
  138.             return FALSE;
  139.         }
  140.     }
  141.  
  142.     return TRUE;
  143. }
  144.  
  145. BOOL CodeMonL::FindModuleContext(__in LPVOID lpBuffer, __out LPVOID* lppvTarget, __out LPVOID* lppvOriginal)
  146. {
  147.     if (!lpBuffer)
  148.         return FALSE;
  149.  
  150.     for (int i = 0; i < 9; i++)
  151.     {
  152.         // 3回コピーされるので 3
  153.         for (int j = 0; j < 3; j++)
  154.         {
  155.             if (lpBuffer != m_mCTX[i].BaseOfCode[j])
  156.                 continue;
  157.  
  158.             if (!m_mCTX[i].ImageBase[j])
  159.                 continue;
  160.  
  161.             *lppvTarget = m_mCTX[i].ImageBase[j];
  162.             *lppvOriginal = m_mCTX[i].OriginalImage;
  163.  
  164.             return TRUE;
  165.         }
  166.     }
  167.  
  168.     return FALSE;
  169. }
  170.  
  171. BOOL CodeMonL::JmpToOriginalModule(__in LPVOID lpvTarget, __in LPVOID lpvOriginal)
  172. {
  173.     if (!lpvModule || !lpvOriginal)
  174.         return FALSE;
  175.  
  176.     LPDWORD pName, pNameOriginal;
  177.     LPDWORD pFunc, pFuncOriginal;
  178.     LPWORD pOrdinal, pOrdinalOriginal;
  179.  
  180.     // Copy
  181.     IMAGE_NT_HEADERS32 *pNtHeaders = reinterpret_cast<IMAGE_NT_HEADERS32*>(reinterpret_cast<PBYTE>(lpvTarget) + PIMAGE_DOS_HEADER(lpvTarget)->e_lfanew);
  182.     IMAGE_EXPORT_DIRECTORY *pExports = reinterpret_cast<IMAGE_EXPORT_DIRECTORY*>(reinterpret_cast<PBYTE>(lpvTarget) + pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
  183.  
  184.     // Original
  185.     IMAGE_NT_HEADERS32 *pNtHeadersOriginal = reinterpret_cast<IMAGE_NT_HEADERS32*>(reinterpret_cast<PBYTE>(lpvOriginal) + PIMAGE_DOS_HEADER(lpvOriginal)->e_lfanew);
  186.     IMAGE_EXPORT_DIRECTORY *pExportsOriginal = reinterpret_cast<IMAGE_EXPORT_DIRECTORY*>(reinterpret_cast<PBYTE>(lpvOriginal) + pNtHeadersOriginal->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
  187.  
  188.     if (pNtHeaders && pExports
  189.         && pNtHeadersOriginal && pExportsOriginal)
  190.     {
  191.         // Copy
  192.         pName = reinterpret_cast<LPDWORD>(reinterpret_cast<PBYTE>(lpvTarget) + pExports->AddressOfNames);
  193.         pFunc = reinterpret_cast<LPDWORD>(reinterpret_cast<PBYTE>(lpvTarget) + pExports->AddressOfFunctions);
  194.         pOrdinal = reinterpret_cast<LPWORD>(reinterpret_cast<PBYTE>(lpvTarget) + pExports->AddressOfNameOrdinals);
  195.  
  196.         // Original
  197.         pNameOriginal = reinterpret_cast<LPDWORD>(reinterpret_cast<PBYTE>(lpvOriginal) + pExportsOriginal->AddressOfNames);
  198.         pFuncOriginal = reinterpret_cast<LPDWORD>(reinterpret_cast<PBYTE>(lpvOriginal) + pExportsOriginal->AddressOfFunctions);
  199.         pOrdinalOriginal = reinterpret_cast<LPWORD>(reinterpret_cast<PBYTE>(lpvOriginal) + pExportsOriginal->AddressOfNameOrdinals);
  200.  
  201.         // コピーされたDLLの各APIをオリジナルのDLLの各APIに飛ばす(jmp)
  202.         for (int i = 0; i < pExports->NumberOfNames; i++)
  203.         {
  204.             WORD w = pOrdinal[i];
  205.             WORD wo = pOrdinalOriginal[i];
  206.             LPVOID lpvFunction = reinterpret_cast<LPVOID>(reinterpret_cast<PBYTE>(lpvTarget) + pFunc[w]);
  207.             LPVOID lpvFuncOriginal = reinterpret_cast<LPVOID>(reinterpret_cast<PBYTE>(lpvOriginal) + pFuncOriginal[wo]);
  208.             LPSTR pszName = reinterpret_cast<LPSTR>(reinterpret_cast<PBYTE>(lpvOriginal) + pNameOriginal[i]);
  209.  
  210.             DetourFunction(TRUE, reinterpret_cast<LPVOID*>(&lpvFunction), lpvFuncOriginal);
  211.         }
  212.  
  213.         return TRUE;
  214.     }
  215.  
  216.     return FALSE;
  217. }
  218.  
  219. /*=================== File: Bypass.cpp ===================*/
  220.  
  221. VOID Detour_o_o()
  222. {
  223.     typedef LPVOID(WINAPI *pfnVirtualAlloc)(
  224.         _In_opt_ LPVOID lpAddress,
  225.         _In_     SIZE_T dwSize,
  226.         _In_     DWORD  flAllocationType,
  227.         _In_     DWORD  flProtect);
  228.  
  229.     typedef BOOL(WINAPI *pfnVirtualProtect)(
  230.         _In_  LPVOID lpAddress,
  231.         _In_  SIZE_T dwSize,
  232.         _In_  DWORD  flNewProtect,
  233.         _Out_ PDWORD lpflOldProtect);
  234.  
  235.     static pfnVirtualAlloc _VirtualAlloc =
  236.         reinterpret_cast<pfnVirtualAlloc>(GetProcAddress(GetModuleHandle(L"KERNELBASE.dll"), "VirtualAlloc"));
  237.     pfnVirtualAlloc VirtualAlloc_Hook = [](
  238.         _In_opt_ LPVOID lpAddress,
  239.         _In_     SIZE_T dwSize,
  240.         _In_     DWORD  flAllocationType,
  241.         _In_     DWORD  flProtect) -> LPVOID
  242.     {
  243.         LPVOID lpBuffer = _VirtualAlloc(lpAddress, dwSize, flAllocationType, flProtect);
  244.         if (lpBuffer)
  245.         {
  246.             CodeMonL::GetInstance()->InitializeModuleContext(lpBuffer, dwSize);
  247.         }
  248.  
  249.         return lpBuffer;
  250.     };
  251.  
  252.     static pfnVirtualProtect _VirtualProtect =
  253.         reinterpret_cast<pfnVirtualProtect>(GetProcAddress(GetModuleHandle(L"KERNELBASE.dll"), "VirtualProtect"));
  254.     pfnVirtualProtect VirtualProtect_Hook = [](
  255.         _In_  LPVOID lpAddress,
  256.         _In_  SIZE_T dwSize,
  257.         _In_  DWORD  flNewProtect,
  258.         _Out_ PDWORD lpflOldProtect) -> BOOL
  259.     {
  260.         CodeMonL *pCodeMonL = CodeMonL::GetInstance();
  261.         LPVOID lpvTarget, lpvOriginal;
  262.  
  263.         if (pCodeMonL->FindModuleContext(lpAddress, &lpvTarget, &lpvOriginal))
  264.             if (lpvTarget && lpvOriginal)
  265.                 pCodeMonL->JmpToOriginalModule(lpvTarget, lpvOriginal);
  266.  
  267.         return _VirtualProtect(lpAddress, dwSize, flNewProtect, lpflOldProtect);
  268.     };
  269.  
  270.     DetourFunction(TRUE, reinterpret_cast<LPVOID*>(&_VirtualAlloc), VirtualAlloc_Hook);
  271.     DetourFunction(TRUE, reinterpret_cast<LPVOID*>(&_VirtualProtect), VirtualProtect_Hook);
  272. }
RAW Paste Data
Top