挺简单的一个小玩意,可以通过ContinueCall去执行想要执行的函数,执行结束后会返回到指定的SavedContext。逆向分析的时候对ContinueCall或者NtContinue进行F8步过的话直接会跟丢,或者程序会挂掉。(这个思路没见有人说过啊,我估计这也是很鸡肋的东西,对反调试的帮助应该不算很大,也就发着玩玩了,大火看个乐)
不仅可以用GetSavedContext获取context,也可以自定义构造,那样的话就灵活更多了。
#include "ContinueCall.h"
/*内部函数*/
/*
* ContinueCallRoutine
* 功能 - 调用指定的函数并返回到指定的context
* 参数 - SavedContext:返回的context
* - TargetProc:指定函数
* - Params:参数指针
* - ParamSize:参数大小
* - Result:返回值缓冲区
*/
__declspec(naked) VOID ContinueCallRoutine(PCONTEXT SavedContext, PROC TargetProc, PVOID Params, SIZE_T ParamSize, PDWORD Result) {
__asm {
push ebp
mov ebp, esp
sub esp, ParamSize
mov edi, esp;
mov esi, Params;
mov ecx, ParamSize;
rep movsb;
mov eax, TargetProc;
call eax;
mov ebx, Result;
mov[ebx], eax;
}
NtContinue(SavedContext, TRUE);
}
/*
* GetEsp
* 功能 - 返回当前函数执行中的ESP
*/
__declspec(naked)ULONG GetEsp() {
__asm {
mov eax, esp;
add eax, 0x4;
ret
}
}
/*
* GetEip
* 功能 - 返回此函数的返回值
*/
__declspec(naked)ULONG GetEip() {
__asm {
mov eax, [esp];
ret
}
}
/*导出函数*/
/*
* NtContinue
* 功能 - 执行系统调用NtContinue
*/
ULONG WINAPI NtContinue(PCONTEXT ContextRecord, BOOLEAN TestAlert) {
static const PVOID addr = GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtContinue");
if (!addr) {
return FALSE;
}
__asm {
mov eax, [addr]
push[TestAlert]
push[ContextRecord]
call eax
}
return TRUE;
}
/*
* GetSavedContext
* 功能 - 获取此函数返回时的对应Context
* 参数 - SavedContext:保存获取的Context
*/
__declspec(naked) VOID WINAPI GetSavedContext(PCONTEXT SavedContext) {
__asm {
push ebp
mov ebp, esp
}
__asm {
push esi
push edi
}
SavedContext->ContextFlags = CONTEXT_ALL;
if (!GetThreadContext(GetCurrentThread(), SavedContext)) {
DEBUG_PRINT("GetThreadContext Failed\n");
goto END;
}
__asm {
pop edi
pop esi
mov eax, SavedContext
mov[eax + CONTEXT.Edi], edi;
mov[eax + CONTEXT.Esi], esi;
mov ebx, [ebp];
mov[eax + CONTEXT.Ebp], ebx;
mov ebx, [ebp + 0x4];
mov[eax + CONTEXT.Eip], ebx;
mov ebx, ebp;
add ebx, 0xc;
mov[eax + CONTEXT.Esp], ebx;
}
END:
__asm {
mov esp, ebp
pop ebp
ret 0x4
}
}
/*
* ContinueCall
* 功能 - 执行目标函数,执行结束后会返回到SavedContext
* 参数 - 其余:与ContinueCallRoutine相关
* - pFirst:此函数是否是第一次执行
*/
VOID WINAPI ContinueCall(PCONTEXT SavedContext, PROC TargetProc, PVOID Params, DWORD ParamNum, PDWORD Result, PBOOLEAN pFirst) {
CONTEXT NewContext;
CONTEXT Context;
PCONTEXT pSavedContext;
if (!SavedContext) {
GetSavedContext(&Context);
pSavedContext = &Context;
}
else {
pSavedContext = SavedContext;
}
if (!*pFirst) {
goto END;
}
*pFirst = FALSE;
memcpy(&NewContext, pSavedContext, sizeof(CONTEXT));
NewContext.Esp = (DWORD)GetEsp() - 0x400;
((PDWORD)NewContext.Esp)[0] = 0;
((PDWORD)NewContext.Esp)[1] = (DWORD)pSavedContext;
((PDWORD)NewContext.Esp)[2] = (DWORD)TargetProc;
((PDWORD)NewContext.Esp)[3] = (DWORD)Params;
((PDWORD)NewContext.Esp)[4] = (DWORD)ParamNum * sizeof(DWORD);
((PDWORD)NewContext.Esp)[5] = (DWORD)Result;
NewContext.Eip = (DWORD)ContinueCallRoutine;
NtContinue(&NewContext, TRUE);
END:
return;
}
测试例子1
int add(int a, int b) {
return a + b;
}
int main()
{
int a[2] = { 1,3 };
int result;
BOOLEAN bFirst = TRUE;
CONTEXT context;
GetSavedContext(&context);
printf("saved context end\n");
ContinueCall(&context, (PROC)add, a, 2, (PDWORD)&result, &bFirst);
printf("%d + %d = %d\n", a[0], a[1], result);
END:
system("pause");
return 0;
}
/*
输出结果:
saved context end
saved context end
1 + 3 = 4
*/
测试例子2
int a[2] = { 1,3 };
int result;
CONTEXT context;
BOOLEAN bFirst = TRUE;
int add(int a, int b) {
return a + b;
}
void func1() {
printf("func1 start\n");
ContinueCall(&context, (PROC)add, a, 2, (PDWORD)&result, &bFirst);
printf("func1 end\n");
}
void func2() {
printf("func2 start\n");
GetSavedContext(&context);
func1();
printf("func2 end\n");
}
int main()
{
func2();
printf("%d + %d = %d\n", a[0], a[1], result);
system("pause");
return 0;
}
/*
输出结果:
func2 start
func1 start
func1 start
func1 end
func2 end
1 + 3 = 4
*/
测试例子3
int a[2] = { 1,3 };
int result;
CONTEXT context;
BOOLEAN bFirst = TRUE;
int add(int a, int b) {
return a + b;
}
void func1() {
printf("func1 start\n");
ContinueCall(&context, (PROC)add, a, 2, (PDWORD)&result, &bFirst);
printf("func1 end\n");
}
void func2() {
printf("func2 start\n");
func1();
printf("func2 end\n");
}
int main()
{
GetSavedContext(&context);
if (bFirst) {
func2();
}
printf("%d + %d = %d\n", a[0], a[1], result);
system("pause");
return 0;
}
/*
输出结果:
func2 start
func1 start
1 + 3 = 4
*/
阿里云助力开发者!2核2G 3M带宽不限流量!6.18限时价,开
发者可享99元/年,续费同价!