寻求类中使用vector发生错误的解决办法?

nanfei01055 2008-07-22 05:27:37
在网上看到一篇关于HookAPI的文章,就依照着想做一个API拦截的功能,但在DLL的创建中遇到一个很棘手的问题,因为对C++了解不深,希望高手帮忙,代码如下:

CommonHeader.h
#define CALLCODE 0xE8
#ifndef COMMONHEADER_H
#define COMMONHEADER_H
#include <vector>
using namespace std;
typedef void(*CMAPIFUNC)(void);
// 关于API函数信息的结构
typedef struct _APIINFO
{
// 要拦截的API函数名
char szOrgApiName[100];
// 要拦截的API的地址
CMAPIFUNC lfOrgApiAddr;
// 我们要替换原来API的地址
CMAPIFUNC lfMyApiAddr;
// 要保存的原来API入口点的前5个字节
BYTE OrgApiBytes[5];
// 对进程内存的保护状态,调用VirtualProtect来改变对内存访问权限时得到的。
DWORD dwOldProtectFlag;
// 参数的个数
int ParamCount;
// 临界对象,为了互斥用,避免同时修改原始api的前5个字节
CRITICAL_SECTION cs;
// 是否已经HOOK了
BOOL bIsHooked;
}APIINFO;

// 用户需要使用的结构,通过这个结构来了解用户需要拦截的API的信息
typedef struct _HOOKAPIINFO
{
union
{
struct
{
// 我们要替换的API所在的DLL的名字
char szMyModuleName[100];
// 我们要替换原来API的函数名字
char szMyApiName[50];
} MyApi;
CMAPIFUNC lfMyApi;
};
// 要拦截的API所在DLL的名字
char szOrgModuleName[100];
// 要拦截的API的名字
char szOrgApiName[50];
// 参数的个数
int ParamCount;
// 提供MyAPI的方式
BOOL bMyApiType; // 如果是0代表提供地址,1代表使用模块名和函数名指定
} HOOKAPIINFO;

// 获得要拦截的API的信息函数指针
typedef vector<HOOKAPIINFO*>*(*GETHOOKAPIINFO)(void);
// 释放要拦截的API的信息函数指针
typedef void(*FREEHOOKAPIINFO)(void);
// 远程注入函数指针
typedef int (*INJECTDLL)(DWORD dwProcessId, LPTSTR lpDllName);

#endif

HookAPI.h
#include "CommonHeader.h"
//#include <Psapi.h>
#include <tlhelp32.h>
//#pragma comment(lib,"Psapi.lib")
// 通用替换函数指针声明
typedef void(*COMMONFUNC)(void);
/*
CHookApi类实现了Hook的核心功能
*/
class CHookApi
{
public:
// 构造函数
CHookApi(void);
// 析构函数
~CHookApi(void);
private:
// 自身路径
static char m_szDllPathName[MAX_PATH];
// 此容器包含所有要Hook的API信息(在类中使用的有效信息)
static vector<APIINFO*> m_vpApiInfo;
// 此容器包含所有要Hook的API信息(用户填写的信息)
vector<HOOKAPIINFO*>* m_vpHookApiInfo;
public:
// 使用远程线程注入的方法将我们的DLL注入到指定进程
static int WINAPI InjectDll(DWORD dwProcessId, LPTSTR lpDllName);
// 使用远程线程注入的方法将我们的DLL卸载
static int WINAPI EjectLib(DWORD dwProcessId, LPTSTR lpDllName);
protected:
// 通用替换函数,这是技术核心部分
static void CommonFunc(void);
private:
// 初始化函数
BOOL Init(void);
// 挂钩一个指定API的函数
BOOL HookOneApi(APIINFO* pai);
// 挂钩所有指定API的函数
BOOL HookAllApis(void);
// 取消挂钩一个指定API的函数
BOOL UnhookOneApi(APIINFO* pai);
// 取消挂钩所有指定API的函数
BOOL UnhookAllApis(void);
// 设置进程内存区域的存取权限
BOOL SetMemmoryAccess(APIINFO* pai,BOOL CanWritten);
// 修改/恢复指定API的前5个字节
BOOL SetCallMemmory(APIINFO* pai,BOOL bHook);
};

CHookApi::CHookApi(void){
//vector<APIINFO*>CHookApi::m_vpApiInfo;
}
void CHookApi::CommonFunc(void){
DWORD* pdwCall;// 保存被调用前压在栈中的返回地址,也就是Call XXXX 的地址
DWORD* pdwESP;// 保存ESP内容
DWORD* pdwParam; // 第一个参数的地址
DWORD dwParamSize; // 所有参数所占用的大小应该=4* dwParamCount
DWORD dwRt; // 保存返回值
DWORD dwRtAddr; // 我们的函数真正要返回的地址
PROCESS_INFORMATION *pPi;// 进程信息
// 得到栈中第一个参数的位置
_asm
{
mov EAX,[EBP+8]
mov [dwRtAddr],EAX
lea EAX,[EBP+4] // call XXXX所在的地址
mov [pdwCall],EAX
lea EAX, [EBP+12] // 第一个参数所在地址
mov [pdwParam],EAX
}
(*pdwCall) -= 5;
APIINFO* pai = NULL;
/*
vector是C++标准模板库中的部分内容,中文偶尔译作“容器”,但并不准确。它是一个多功能的,能够操作多种数据结构和算法的模板类和函数库。vector之所以被认为是一个容器,是因为它能够像容器一样存放各种类型的对象,简单地说,vector是一个能够存放任意类型的动态数组,能够增加和压缩数据。
简单的使用方法如下:
vector<int> test;//建立一个vector
test.pushback(1);//把1和2压入vector 这样test[0]就是1,test[1]就是2
test.pushback(2);
Iterator 在c++里是什么意思?
说白了就是一个类,该类的功能是可以遍历容器中的所有数据。当然各种容器有自己的遍历规则,就要求各类实现出可以遍历自己的类(iterator),我们看到的iterator名字是通过typedef 来取的别名而已。iterator类当然要重载所用到的运算符(如*,++,--,!=等),才能让我们直接用。
是一个内部类,它模拟指针,支持通过++和*来依次访问容器中的元素。
*/
//vector<APIINFO*> m_vpApiInfo;
vector<APIINFO*>::iterator it;

m_vpApiInfo.begin();
/*
for(it=m_vpApiInfo.begin();it!=m_vpApiInfo.end();it++)
{

}
*/


}

Linking...
Creating library Debug/HookAPI.lib and object Debug/HookAPI.exp
HookAPI.obj : error LNK2001: unresolved external symbol "private: static class std::vector<struct _APIINFO *,class std::allocator<struct _APIINFO *> > CHookApi::m_vpApiInfo" (?m_vpApiInfo@CHookApi@@0V?$vector@PAU_APIINFO@@V?$allocator@PAU_APIINFO@@@
std@@@std@@A)
Debug/HookAPI.dll : fatal error LNK1120: 1 unresolved externals
执行 link.exe 时出错.
Creating browse info file...

HookAPI.dll - 1 error(s), 0 warning(s)

执行到m_vpApiInfo.begin();句就错,去年后面的就可能编译通过
...全文
173 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
nanfei01055 2008-07-23
  • 打赏
  • 举报
回复
多谢4楼,接分
cppwin 2008-07-22
  • 打赏
  • 举报
回复
[Quote=引用楼主 nanfei01055 的帖子:]
static char m_szDllPathName[MAX_PATH];
static vector <APIINFO*> m_vpApiInfo;
[/Quote]

这两个 静态成员变量, 需要在cpp文件中 定义

char CHookApi::m_szDllPathName[MAX_PATH];
vector <APIINFO*> CHookApi::m_vpApiInfo;
stivenjia 2008-07-22
  • 打赏
  • 举报
回复
导出模板类首先需要导出模板参数之后逐一导出
scq2099yt 2008-07-22
  • 打赏
  • 举报
回复
已经够深入了
yjgx007 2008-07-22
  • 打赏
  • 举报
回复
clean -> rebuild all

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧