- 注册时间
- 2011-3-6
- 最后登录
- 1970-1-1
该用户从未签到
|
这个话题,主要是因为跟朋友讨论一些小技术时,引发出来的,于是做了点笔记,不敢独享,故而发出来。
从线程入手就行了,不去使用可以被驱动拦截和监控的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;
} |
|