欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

[讨论]周末有点时间系列:让别人不能CALL我们的那些函数

[讨论]周末有点时间系列:让别人不能CALL我们的那些函数

这个话题,主要是因为跟朋友讨论一些小技术时,引发出来的,于是做了点笔记,不敢独享,故而发出来。
从线程入手就行了,不去使用可以被驱动拦截和监控的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;

}


实际使用的例子很简单,就不列举了~

求捐助,求投资,有意者欢迎联系

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途。
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功