dump 使用小工具设计

 
/*
;配置文件格式
[hook_1]
dll=kernel32.dll
fun=GetModuleHandleA
min_addr=0x1000000
max_addr=0x2000000
*/

#include <tchar.h>
#include <windows.h>
#include <stdio.h>

#define MAX_HOOK_FUNCTION       100

typedef struct _HOOK_FUNCTION_LIST {
   TCHAR   szDllName[MAX_PATH];               // dll 路径
   CHAR   szFunctionName[MAX_PATH];       // 函数名
  
   ULONG   PointerToCode;                       // 函数入口
   BYTE   cOrgCode[5];                       // 函数入口的原始 5 个字节
   BYTE   cNewCode[5];                       // 函数入口 hooked 5 个字节
  
   // 当返回地址在下面两个值之间,就 pause
   ULONG   uMinReturnAddr; // 返回地址的最小值
   ULONG   uMaxReturnAddr; // 返回地址的最大值
} HOOK_FUNCTION_LIST, *PHOOK_FUNCTION_LIST;

HMODULE __hModule; // 模块实例
CHAR __szFullPath[MAX_PATH]; // 当前模块的完整路径
CHAR __szMsgText[0x100]; // 弹出消息的文本
HOOK_FUNCTION_LIST __HookFunctionList[MAX_HOOK_FUNCTION];
CRITICAL_SECTION __LockMessageBox;
HANDLE __hCurProcess;
ULONG __uTlsIndex;

#define _MY_STACK_SIZE       0x1000 // 应该够用了
VOID ClearHookFunctionList()
{
  
}

// 不进行堆栈溢出检查

PULONG GetMyStackBase()
{
   PULONG pStack = (PULONG)TlsGetValue(__uTlsIndex);
   if ( pStack == NULL )
   {
       pStack = (PULONG)VirtualAllocEx(__hCurProcess, NULL, _MY_STACK_SIZE * sizeof (ULONG), MEM_COMMIT, PAGE_READWRITE);
      
       ULONG uStackTop = _MY_STACK_SIZE - 1;
       pStack[uStackTop] = uStackTop;

       TlsSetValue(__uTlsIndex, pStack);
   }

   return pStack;
}

ULONG& GetMyStackTop()
{
   PULONG pStack = GetMyStackBase();
   return pStack[_MY_STACK_SIZE - 1];
}

ULONG PUSH_VALUE(ULONG uValue)
{
   PULONG pStack = GetMyStackBase();
   ULONG& uStackTop = GetMyStackTop();

   return (pStack[--uStackTop] = uValue);
}

ULONG POP_VALUE()
{
   PULONG pStack = GetMyStackBase();
   ULONG& uStackTop = GetMyStackTop();

   return pStack[uStackTop++];
}


VOID __cdecl /*禁止平栈*/ _pLeave_ProxyFunction(ULONG uDummyValue)
{  
   ULONG uReturnAddr = POP_VALUE();
   ULONG CalledFunction = POP_VALUE();

   PULONG pCurStack = &uDummyValue;
   pCurStack[2] = uReturnAddr; // 利用压入的值,改为返回到原始 code

   PHOOK_FUNCTION_LIST pHfl = __HookFunctionList;
   for ( int i = 0; i < MAX_HOOK_FUNCTION; i++ )
   {
       if ( CalledFunction == pHfl->PointerToCode )
       {
           DWORD dwTemp;

           WriteProcessMemory(__hCurProcess, (PVOID)CalledFunction, pHfl->cNewCode, 5, &dwTemp); // 重新 hook
           break;
       }

       pHfl++;
   }
}

ULONGLONG __declspec(naked) Leave_ProxyFunction()
{
   __asm
   {
       push   -1       // dummy value
       push   eax
       push   edx
       call   _pLeave_ProxyFunction
       pop       edx
       pop       eax
       ret
   }
}

VOID __fastcall Enter_ProxyFunction(
   PULONG pCurStack /* ecx 指向进入这个函数时的堆栈指针 */
   )
{
   /*
       pCurStack[0] = Function Address
       pCurStack[1] = Return Address
   */
   const ULONG CalledFunction = pCurStack[0];
   ULONG& uReturnAddr = pCurStack[1];
  
   PUSH_VALUE(CalledFunction);
   PUSH_VALUE(uReturnAddr);

   PHOOK_FUNCTION_LIST pHfl = __HookFunctionList;
   for ( int i = 0; i < MAX_HOOK_FUNCTION; i++ )
   {
       if ( CalledFunction == pHfl->PointerToCode )
       {
           DWORD dwTemp;
           WriteProcessMemory(__hCurProcess, (PVOID)CalledFunction, pHfl->cOrgCode, 5, &dwTemp); // 恢复被 hooked 函数
       }

       if ( (pHfl->uMinReturnAddr < uReturnAddr) && (uReturnAddr < pHfl->uMaxReturnAddr) )
       {
           EnterCriticalSection(&__LockMessageBox);
          
           wsprintf(__szMsgText, "函数 %s.%s 调用,返回地址是: 0x%08X!/n 祝你 Dump 成功!", pHfl->szDllName, pHfl->szFunctionName, uReturnAddr);
           MessageBox(NULL, __szMsgText, _T("提示"), MB_ICONSTOP | MB_DEFAULT_DESKTOP_ONLY);

           LeaveCriticalSection(&__LockMessageBox);
           break;
       }

       pHfl++;
   }

   uReturnAddr = (ULONG)Leave_ProxyFunction; // 修改返回地址
}

ULONG __declspec(naked) ProxyFunction()
{
   __asm
   {
       sub       dword ptr [esp], 5   // 得到函数入口地址
       mov       ecx, esp                   // 栈顶送入 Enter_ProxyFunction 参数
       call       Enter_ProxyFunction
       ret                                   // 转到原始函数
   }
}

ULONG HexStringTo(PCTSTR pszString)
{
   ULONG uResult = 0;

   while ( *pszString != 0 )
   {
       TCHAR c = *pszString;
      
       uResult <<= 4;
       if ( c >= _T('a') && c <= ('f') )
       {
           uResult += c - _T('a') + 10;
       }
       else if ( c >= _T('A') && c <= ('F') )
       {
           uResult += c - _T('A') + 10;
       }
       else if ( c >= _T('0') && c <= _T('9') )
       {
           uResult += c - _T('0');
       }
       else
       {
           uResult = 0;
       }

       pszString++;
   }

   return uResult;
}

VOID Initialize()
{
   __uTlsIndex = TlsAlloc();
   __hCurProcess = GetCurrentProcess();
   InitializeCriticalSection(&__LockMessageBox);
  
   //
   // 获取配置文件路径
   TCHAR szCfgPath[MAX_PATH];
   _tcsncpy(szCfgPath, __szFullPath, MAX_PATH);
   PTSTR p = _tcsrchr(szCfgPath, _T('.'));
   if ( p != NULL )
   {
       _tcscpy(p, _T(".ini"));
   }
  
   //
   // 重配置文件中读取数据,初始化 hook function list
   PHOOK_FUNCTION_LIST pHfl = __HookFunctionList;
   memset(pHfl, 0, sizeof (pHfl));

   for ( int i = 0; i < MAX_HOOK_FUNCTION; i++ )
   {
       TCHAR szMinAddr[50];
       TCHAR szMaxAddr[50];
       TCHAR szAppName[MAX_PATH];

       wsprintf(szAppName, _T("hook_%d"), i + 1);

       if (
           GetPrivateProfileString(szAppName, _T("dll"), _T(""), pHfl->szDllName, MAX_PATH, szCfgPath) == 0 ||
           GetPrivateProfileString(szAppName, _T("fun"), _T(""), pHfl->szFunctionName, MAX_PATH, szCfgPath) == 0 ||
           GetPrivateProfileString(szAppName, _T("min_addr"), _T(""), szMinAddr, MAX_PATH, szCfgPath) == 0 ||
           GetPrivateProfileString(szAppName, _T("max_addr"), _T(""), szMaxAddr, MAX_PATH, szCfgPath) == 0
           )
       {
           break;
       }

       pHfl->uMinReturnAddr = HexStringTo(szMinAddr);
       pHfl->uMaxReturnAddr = HexStringTo(szMaxAddr);
      
       pHfl++;
   }
  
   //
   // 被 hook 的函数最好不要有下列 api, 并且不支持 fastcall
   // LoadLibrary
   // GetProcAddress
   // WriteProcessMemory
   // EnterCriticalSection
   // LeaveCriticalSection
   // MessageBox
   // wsprintf
   pHfl = __HookFunctionList;
   for ( int j = 0; j < MAX_HOOK_FUNCTION; j++ )
   {      
       HMODULE hModule = LoadLibrary(pHfl->szDllName);
       if ( hModule != NULL )
       {
           pHfl->PointerToCode = (ULONG)GetProcAddress(hModule, pHfl->szFunctionName);
           if ( pHfl->PointerToCode != NULL )
           {
               DWORD dwTemp;
              
               // call xxxx
               pHfl->cNewCode[0] = 0xe8;
               *(PULONG32)(pHfl->cNewCode + 1) = (ULONG)ProxyFunction - (pHfl->PointerToCode + 5);
              
               ReadProcessMemory(__hCurProcess, (PVOID)pHfl->PointerToCode, pHfl->cOrgCode, 5, &dwTemp);
               WriteProcessMemory(__hCurProcess, (PVOID)pHfl->PointerToCode, pHfl->cNewCode, 5, &dwTemp);

               pHfl++;
           }
       }
   }
}

VOID UnInitialize()
{
   DeleteCriticalSection(&__LockMessageBox);
}

BOOL WINAPI DllMain(HMODULE hModule, DWORD dwReason, LPVOID p)
{
   if ( dwReason == DLL_PROCESS_ATTACH )
   {
       __hModule = hModule;

       GetModuleFileName(hModule, __szFullPath, MAX_PATH);

   //   __asm int 3
       Initialize();
   }
   else if ( dwReason == DLL_PROCESS_DETACH )
   {
       UnInitialize();
   }

   return TRUE;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值