看流星社区

 找回密码
 注册账号
查看: 2586|回复: 0

让别人不能CALL我们的那些函数

[复制链接]

该用户从未签到

发表于 2013-3-27 10:11:42 | 显示全部楼层 |阅读模式
这个话题,主要是因为跟朋友讨论一些小技术时,引发出来的,于是做了点笔记,不敢独享,故而发出来。
从线程入手就行了,不去使用可以被驱动拦截和监控的ZwSetInfomationThread和ZwQueryInformationThread而使用只操作用户层内存的三个函数:
RtlPushFrame
RtlGetFrame
RtlPopFrame
完全定义形态:
typedef  VOID (NTAPI *T_RtlPushFrame)(
  PTEB_ACTIVE_FRAME Frame
  );
typedef PTEB_ACTIVE_FRAME (NTAPI *T_RtlGetFrame)(
  VOID
  );

typedef VOID (NTAPI *T_RtlPopFrame)(
  PTEB_ACTIVE_FRAME Frame
  );


其中PTEB_ACTIVE_FRAME的定义(通过windbg可以获得):
typedef struct TEB_ACTIVE_FRAME_CONTEXT
{
  /* 0x000 */ ULONG   Flags;
  /* 0x004 */ PSTR    FrameName;

} TEB_ACTIVE_FRAME_CONTEXT, *PTEB_ACTIVE_FRAME_CONTEXT;

typedef struct TEB_ACTIVE_FRAME
{
  /* 0x000 */ ULONG                       Context;  // Flags;
  /* 0x004 */ struct TEB_ACTIVE_FRAME    *Previous;
  /* 0x008 */ PTEB_ACTIVE_FRAME_CONTEXT   pContext;
} TEB_ACTIVE_FRAME, *PTEB_ACTIVE_FRAME;


具体的封装应用的逻辑:
一个自己的创建线程的封装(自己的线程除了系统给的第一个之外都是自己建立的)。
一个通用的检测函数,在某些关键函数(比如发包前的加密的函数,某个重要操作的函数)里加入调用检测函数(当然要适当使用VMP这类高强度的壳的SDK保护好自己的这套逻辑才好)。
封装一个设置给主线程和某些不明线程的使用的设置标识的函数。
封装一个用于清理的函数。


详情参看如下代码:

首先是头文件部分:
#pragma once
#include <windows.h>
#include <winternl.h>
#include <ntstatus.h>
typedef struct TEB_ACTIVE_FRAME_CONTEXT
{
  /* 0x000 */ ULONG   Flags;
  /* 0x004 */ PSTR    FrameName;

} TEB_ACTIVE_FRAME_CONTEXT, *PTEB_ACTIVE_FRAME_CONTEXT;

typedef struct TEB_ACTIVE_FRAME
{
  /* 0x000 */ ULONG                       Context;  // Flags;
  /* 0x004 */ struct TEB_ACTIVE_FRAME    *Previous;
  /* 0x008 */  PTEB_ACTIVE_FRAME_CONTEXT   pContext;
} TEB_ACTIVE_FRAME, *PTEB_ACTIVE_FRAME;
typedef struct _THREADPARAM_
{
  PVOID Context;
  LPTHREAD_START_ROUTINE Routine;
}THREADPARAM,*PTHREADPARAM;
struct _OWN_THREAD_CONTEXT_ : public TEB_ACTIVE_FRAME
{
  DWORD dwThreadId;
  struct _OWN_THREAD_CONTEXT_ *Own;
};
typedef  VOID (NTAPI *T_RtlPushFrame)(
  PTEB_ACTIVE_FRAME Frame
  );
typedef PTEB_ACTIVE_FRAME (NTAPI *T_RtlGetFrame)(
  VOID
  );

typedef VOID (NTAPI *T_RtlPopFrame)(
  PTEB_ACTIVE_FRAME Frame
  );
#define OWN_THREAD_FLAGS ULONG('MJMJ')
VOID SetOwnThread();//设置当前线程标志
BOOL IsOwnThread();//检测当前线程是否有标志,无标志返回FALSE有返回TRUE
VOID CleanUpOwnThread();//对当前线程清空标志
BOOL _CreateThreadEx(LPTHREAD_START_ROUTINE lpThreadRoutine,LPVOID lparam,PHANDLE pThreadHandle,PDWORD pThreadId);//创建新线程封装函数


接着实现逻辑的函数代码:

代码:
T_RtlPushFrame fRtlPushFrame=NULL;
T_RtlGetFrame fRtlGetFrame=NULL;
T_RtlPopFrame fRtlPopFrame=NULL;
#define OWN_THREAD_FLAGS ULONG('MJMJ')
BOOL InitOwnThread()
{
  HMODULE hNtdll = GetModuleHandle(TEXT("ntdll.dll"));
  if (!fRtlGetFrame)
  {
    if(!(fRtlGetFrame = (T_RtlGetFrame)GetProcAddress(hNtdll,"RtlGetFrame"))) return FALSE;
  }
  if (!fRtlPopFrame)
  {
    if(!(fRtlPopFrame = (T_RtlPopFrame)GetProcAddress(hNtdll,"RtlPopFrame"))) return FALSE;
  }
  if (!fRtlPushFrame)
  {
    if(!(pRtlPushFrame = (T_RtlPushFrame)GetProcAddress(hNtdll,"RtlPushFrame"))) return FALSE;
  }
  return TRUE;
}
VOID SetOwnThread()
{
  _OWN_THREAD_CONTEXT_ *pContext = new _OWN_THREAD_CONTEXT_;
  if (pContext)
  {
    RtlZeroMemory(pContext,sizeof(_OWN_THREAD_CONTEXT_));
    pContext->Context = OWN_THREAD_FLAGS;
    pContext->dwThreadId = GetCurrentThreadId();
    pContext->Own = pContext;
    fRtlPushFrame(pContext);
  }
}
VOID CleanUpOwnThread()
{
  PTEB_ACTIVE_FRAME Frame;
  if (!InitOwnThread())
  {
    return ;
  }
  Frame = fRtlGetFrame();
  while (Frame != NULL && Frame->Context != OWN_THREAD_FLAGS)
    Frame = Frame->Previous;
  if (Frame)
  {
    _OWN_THREAD_CONTEXT_ *pCtx = (_OWN_THREAD_CONTEXT_ *)Frame;
    pCtx = pCtx->Own;
    fRtlPopFrame(Frame);
    delete pCtx;
  }
  return ;
}
DWORD WINAPI _ThreadRoutineEx(LPVOID lparam)
{
  DWORD dwRet= 0;
  PTHREADPARAM pThread;
  SetOwnThread();
  pThread = (PTHREADPARAM)lparam;
  if (pThread&&pThread->Routine)
  {
     dwRet = pThread->Routine(pThread->Context);
  }
  CleanUpOwnThread();
  return dwRet;
}

BOOL _CreateThreadEx(LPTHREAD_START_ROUTINE lpThreadRoutine,LPVOID lparam,PHANDLE pThreadHandle,PDWORD pThreadId)
{
  HANDLE hThread;
  PTHREADPARAM threadparam;
  if (!InitOwnThread())
  {
    return FALSE;
  }
  threadparam = new THREADPARAM;
  if (threadparam)
  {
    RtlZeroMemory(threadparam,sizeof(THREADPARAM));
    threadparam->Routine = lpThreadRoutine;
    threadparam->Context = lparam;
    hThread = CreateThread(NULL,0,_ThreadRoutineEx,threadparam,0,pThreadId);
    if (pThreadHandle)
    {
      *pThreadHandle = hThread;
    }
    if (hThread)
    {
      return TRUE;
    }
  }
  return FALSE;
}
BOOL IsOwnThread()
{
  PTEB_ACTIVE_FRAME Frame;
  if (!InitOwnThread())
  {
    return FALSE;
  }
  Frame = fRtlGetFrame();
  while (Frame != NULL && Frame->Context != OWN_THREAD_FLAGS)
    Frame = Frame->Previous;
  if (Frame)
  {
    _OWN_THREAD_CONTEXT_ *pContext = (_OWN_THREAD_CONTEXT_ *)Frame;
    if (pContext->dwThreadId==GetCurrentThreadId())
    {
      return TRUE;
    }
  }
  return FALSE;
}
点击按钮快速添加回复内容: 支持 高兴 激动 给力 加油 苦寻 生气 回帖 路过 感恩
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

小黑屋|手机版|Archiver|看流星社区 |网站地图

GMT+8, 2024-4-19 22:54

Powered by Kanliuxing X3.4

© 2010-2019 kanliuxing.com

快速回复 返回顶部 返回列表