如何实现函数替换呢?
在单元测试中,需要实现打桩函数,我现在一直没有想通怎么定义一个函数void Add_STUB( void *func, void* func_stub)
实现的功能要类似
#define func func_stub 呢?
程序代码:/******************************************************************
* Copyright (c) 2010, XX Technologies Co., Ltd.
* All rights reserved.
*
* 文件名称:testStub.cpp
* 摘 要: 函数打桩测试代码
*
* 取代版本:1.0
* 原作者 :zhong yunde
* 完成日期:2010年07月24日
*******************************************************************/
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include "stub.h"
#define UNICODE
#define _UNICODE
// 定义MessageBoxA函数原型
typedef int (WINAPI *PFNMESSAGEBOX)(HWND, LPCSTR, LPCSTR, UINT uType);
int WINAPI MessageBoxProxy(IN HWND hWnd, IN LPCSTR lpText, IN LPCSTR lpCaption, IN UINT uType);
unsigned * addr = (unsigned *)MessageBoxA; // 保存函数的入口地址
unsigned * myaddr = (unsigned *)MessageBoxProxy;
int main(void)
{
//OutputDebugString(_T("start !"));
MessageBoxA(NULL, " 原函数", "09HookDemo", 0);
AddStub(addr, myaddr); // 对 addr指向的函数进行打桩
//用于测试的API函数
MessageBoxA(NULL, "原函数", "09HookDemo", 0);
//ClearStub(myaddr, addr);
ClearStub(addr); // 进行清桩处理
MessageBoxA(NULL, "原函数", "09HookDemo", 0);
return 0;
}
int WINAPI MessageBoxProxy(IN HWND hWnd, IN LPCSTR lpText, IN LPCSTR lpCaption, IN UINT uType)
{
return ((PFNMESSAGEBOX)addr) (NULL, "stub", "Stub", 0); // 用地址调用一个API函数
}
目前实现了需要的代码,但对于清桩处理的函数ClearStub定义使用
程序代码:#include <stdio.h>
#define DB // 设置编译开关
void f()
{
printf("f\n");
}
void _f()
{
printf("_f\n");
}
#ifdef DB
#define f() _f()
#endif
int main(int argc, char *argv[])
{
f();
return 0;
}您上述的方法在程序中不能同时使用 f(); 和 _f();,每次只能根据编译开关DB决定是否进行整体转换
程序代码:以下是引用pangding在2010-7-25 00:38:22的发言:
为什么一定要一个函数来做这个?靠条件预处理可不可以?
类似下面这样的:
#ifdef DEBUG
#define func func_stub
#endif
然后在定义 func_stub 地方也可以用类似的条件处理包起来。
这样编译之前指定一下 DEBUG 这个宏,所有调用的地方就会变过去。
通过后,再编译的时候,会一且正常。而且桩函数根本不会被编译。
#include <stdio.h>
typedef struct class1_t
{
void dump(void) { printf("class1.\n"); }
} class1_t;
typedef struct class2_t
{
void dump(void) { printf("class2.\n"); }
} class2_t;
void test()
{
class1_t c1;
c1.dump();
}
int main( int ac, char **av )
{
class1_t c1;
class2_t c2;
c1.dump();
#define c1 c2
c1.dump();
test();
#undef c1
c1.dump();
return 0;
}发现使用宏定义后,对应间接调用方式无效(test();)!