使用detours库hook windows API 程序经常崩溃

王金水 2015-04-12 08:40:47
用detours库 hook 了智能卡的库文件 winscard.dll 假装只能卡存在,读卡 写卡,都是我来返回数据,现在通过读卡的ocx控件,可以用,但是不稳定,IE总会崩溃,尤其是我再读卡写卡完,ocx退出之后崩溃的几率就特别高,有时是内存不能read,有时时IE出现问题,需要关闭。 我自己分析,可能是我自己重写的读卡函数有问题。
请大家给点建议,说说ocx退出时发生了什么,或者看看我的代码写的有什么问题,下面我贴上主要代码,可能有点乱,请大家见谅


PVOID g_pOldSCardEstablishContext=NULL;
PVOID g_pOldSCardListReadersA=NULL;
PVOID g_pOldSCardConnectA=NULL;
PVOID g_pOldSCardTransmit=NULL;
PVOID g_pOldSCardDisconnect=NULL;
PVOID g_pOldSCardReleaseContext=NULL;
const char str[]="WMNIKEY Smart Card Reader USB 011";


typedef LONG (WINAPI *PfuncSCardEstablishContext)(
_In_ DWORD dwScope,
_In_ LPCVOID pvReserved1,
_In_ LPCVOID pvReserved2,
_Out_ LPSCARDCONTEXT phContext
);

typedef LONG (WINAPI *PfuncSCardListReadersA)(
_In_ SCARDCONTEXT hContext,
_In_opt_ LPCTSTR mszGroups,
_Out_ LPTSTR mszReaders,
_Inout_ LPDWORD pcchReaders);

typedef LONG (WINAPI *PfuncSCardConnectA)(
_In_ SCARDCONTEXT hContext,
_In_ LPCTSTR szReader,
_In_ DWORD dwShareMode,
_In_ DWORD dwPreferredProtocols,
_Out_ LPSCARDHANDLE phCard,
_Out_ LPDWORD pdwActiveProtocol);

typedef LONG (WINAPI *PfuncSCardTransmit)(
_In_ SCARDHANDLE hCard,
_In_ LPCSCARD_IO_REQUEST pioSendPci,
_In_ LPCBYTE pbSendBuffer,
_In_ DWORD cbSendLength,
_Inout_opt_ LPSCARD_IO_REQUEST pioRecvPci,
_Out_ LPBYTE pbRecvBuffer,
_Inout_ LPDWORD pcbRecvLength);

typedef LONG (WINAPI *PfuncSCardDisconnect)(
_In_ SCARDHANDLE hCard,
_In_ DWORD dwDisposition);

typedef LONG (WINAPI *PfuncSCardReleaseContext)(
_In_ SCARDCONTEXT hContext);

acl::redis_string GetData(acl::string addr,char* key,acl::string buff){
acl::acl_cpp_init();
acl::redis_client client(addr.c_str(), 60, 30);
acl::redis_string string_operation(&client);
string_operation.get(key,buff);
char* c = buff.c_str();

return string_operation;
}

int hexcharToInt(char c)
{
if (c >= '0' && c <= '9') return (c - '0');
if (c >= 'A' && c <= 'F') return (c - 'A' + 10);
if (c >= 'a' && c <= 'f') return (c - 'a' + 10);
return 0;
}

void hexstringToBytes(char* hexstring,char* bytes,int hexlength)
{
for (int i=0 ; i <hexlength ; i+=2) {
bytes[i/2] = (char) ((hexcharToInt(hexstring[i]) << 4)| hexcharToInt(hexstring[i+1]));
}
}


void bytesToHexstring(char* bytes,int bytelength,char *hexstring,int hexstrlength)
{
char str2[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
for (int i=0,j=0;i<bytelength,j<hexstrlength;i++,j++)
{
int b;
b = 0x0f&(bytes[i]>>4);
char s1 = str2[b];
hexstring[j] = s1;
b = 0x0f & bytes[i];
char s2 = str2[b];
j++;
hexstring[j] = s2;
}
}

LONG WINAPI ZwNewSCardEstablishContext(
_In_ DWORD dwScope,
_In_ LPCVOID pvReserved1,
_In_ LPCVOID pvReserved2,
_Out_ LPSCARDCONTEXT phContext)
{
*phContext = 3439394816;
LONG result = SCARD_S_SUCCESS;
return result;
}

LONG WINAPI ZwNewSCardListReadersA(
_In_ SCARDCONTEXT hContext,
_In_opt_ LPCTSTR mszGroups,
_Out_ LPTSTR mszReaders,
_Inout_ LPDWORD pcchReaders)
{
*pcchReaders = 33L;
if(mszReaders!=NULL){
memcpy(mszReaders,str,strlen(str)-2);
*(mszReaders+strlen(str)-2) = 0;
}

return SCARD_S_SUCCESS ;
}

LONG WINAPI ZwNewSCardConnectA(
_In_ SCARDCONTEXT hContext,
_In_ LPCTSTR szReader,
_In_ DWORD dwShareMode,
_In_ DWORD dwPreferredProtocols,
_Out_ LPSCARDHANDLE phCard,
_Out_ LPDWORD pdwActiveProtocol)
{
*phCard = 3926065152;
*pdwActiveProtocol = 1;
return SCARD_S_SUCCESS;
}



LONG WINAPI ZwNewSCardTransmit(
_In_ SCARDHANDLE hCard,
_In_ LPCSCARD_IO_REQUEST pioSendPci,
_In_ LPCBYTE pbSendBuffer,
_In_ DWORD cbSendLength,
_Inout_opt_ LPSCARD_IO_REQUEST pioRecvPci,
_Out_ LPBYTE pbRecvBuffer,
_Inout_ LPDWORD pcbRecvLength)
{
//校验是否白卡(IMSI)
//A0A40000023F00 返回9F开头表示成功
//A0A40000027F20 返回9F开头表示成功
//A0A40000026F07 返回9F开头表示成功
//A0B0000009 需要返回FFFFFFFFFFFFFFFFFF9000 所有的F表示是白卡 9000表示成功

//读卡命令
//A0A40000023F00
//A0A40000022FE2
//A0B000000A

//写卡命令
//A0A40000023F00 返回9F开头表示成功;
//A0A40000027F10 返回9F开头表示成功;
//A0A40000026F42 返回9F开头表示成功;
/*A0DC010428FFFF FFFFFFFFFFFFFF FFFFFFFDFFFFFF FFFFFFFFFFFFFF FFFF0891683110 700205F0FFFFFF FFFFFF,9000*/
/*A0F4000012084906104415806890084906104415806890*/
if(cbSendLength == 7){
char seven[2] = {0x9f, 0x17};
memcpy(pbRecvBuffer,seven,2);
*pcbRecvLength = 2;
}
if(cbSendLength == 5){
char five[5];
memcpy(five,pbSendBuffer,5);
if(five[4]==0x09){
char recv[12] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x90, 0x00};
memcpy(pbRecvBuffer,recv,11);
*pcbRecvLength = 11;
}
if(five[4] == 0x0A){
acl::string buf;
acl::string addr("127.0.0.1:6379");
acl::acl_cpp_init();
acl::redis_client client(addr.c_str(), 60, 30);
acl::redis_string string_operation(&client);
bool re = string_operation.get("iccid",buf);
char recv[12];
hexstringToBytes(buf.c_str(),recv,20);
recv[10] = 0x90;
recv[11] = 0x00;
memcpy(pbRecvBuffer,recv,12);
*pcbRecvLength = 12;
}
}
if(cbSendLength == 45){
char f45[45];
memcpy(f45,pbSendBuffer,45);
char recv[2] = {0x90, 0x00};
memcpy(pbRecvBuffer,recv,2);
*pcbRecvLength = 2;
}
if(cbSendLength == 23){
char f23[23];
memcpy(f23,pbSendBuffer,23);
char s47[47];
bytesToHexstring(f23,23,s47,47);
s47[46] = '\0';
acl::string addr("127.0.0.1:6379");
acl::acl_cpp_init();
acl::redis_client client(addr.c_str(), 60, 30);
acl::redis_string string_operation(&client);
bool re = string_operation.set("imsi",s47);
char recv[2] = {0x90, 0x00};
memcpy(pbRecvBuffer,recv,2);
*pcbRecvLength = 2;
}
return SCARD_S_SUCCESS;
}

LONG WINAPI ZwNewSCardDisconnect(
_In_ SCARDHANDLE hCard,
_In_ DWORD dwDisposition)
{
return SCARD_S_SUCCESS;
}

LONG WINAPI ZwNewSCardReleaseContext(
_In_ SCARDCONTEXT hContext)
{
return SCARD_S_SUCCESS;
}

//共享代码段
#pragma data_seg("THISISHOOKAPISHARED")

HHOOK g_hMessageHook=0;
DWORD currentHm=0;
DWORD hmArray[1024] = {0};
int acSize = 0; //hmArray 当前大小
BOOL hookState = FALSE;
BOOL g_bStopHook=FALSE;
BOOL g_bHookInstalled=FALSE;
#pragma data_seg()
#pragma comment(linker, "/section:THISISHOOKAPISHARED,RWS")


BOOL CheckHModul(DWORD hModule){
for(int i=0;i<acSize+1;i++){
if(hmArray[i]==hModule) return TRUE;
}
return FALSE;
}

BOOL APIENTRY SetHook()
{
//如果已经安装就return
if(CheckHModul(currentHm))return TRUE;
//输出到控制台
cout<<"let't us install hook of winscard.dll"<<endl;
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
g_pOldSCardEstablishContext=DetourFindFunction("WinSCard.dll","SCardEstablishContext");
g_pOldSCardListReadersA=DetourFindFunction("WinSCard.dll","SCardListReadersA");
g_pOldSCardConnectA=DetourFindFunction("WinSCard.dll","SCardConnectA");
g_pOldSCardTransmit=DetourFindFunction("WinSCard.dll","SCardTransmit");
g_pOldSCardDisconnect=DetourFindFunction("WinSCard.dll","SCardDisconnect");
g_pOldSCardReleaseContext=DetourFindFunction("WinSCard.dll","SCardReleaseContext");
DetourAttach(&g_pOldSCardEstablishContext,ZwNewSCardEstablishContext);
DetourAttach(&g_pOldSCardListReadersA,ZwNewSCardListReadersA);
DetourAttach(&g_pOldSCardConnectA,ZwNewSCardConnectA);
DetourAttach(&g_pOldSCardTransmit,ZwNewSCardTransmit);
DetourAttach(&g_pOldSCardDisconnect,ZwNewSCardDisconnect);
DetourAttach(&g_pOldSCardReleaseContext,ZwNewSCardReleaseContext);
LONG ret=DetourTransactionCommit();
hmArray[acSize] = currentHm;
acSize+=1;
//g_bHookInstalled=TRUE;
return g_bHookInstalled;
}


BOOL APIENTRY DropHook()
{
//如果已经卸载就return
if(!g_bHookInstalled)return TRUE;

//输出控制台
cout<<"let't us drop hook of winscard.dll"<<endl;
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach(&g_pOldSCardEstablishContext,ZwNewSCardEstablishContext);
DetourDetach(&g_pOldSCardListReadersA,ZwNewSCardListReadersA);
DetourDetach(&g_pOldSCardConnectA,ZwNewSCardConnectA);
DetourDetach(&g_pOldSCardTransmit,ZwNewSCardTransmit);
DetourDetach(&g_pOldSCardDisconnect,ZwNewSCardDisconnect);
DetourDetach(&g_pOldSCardReleaseContext,ZwNewSCardReleaseContext);
LONG ret=DetourTransactionCommit();
g_bHookInstalled=FALSE;
return ret==NO_ERROR;
}

//查找函数地址
HMODULE WINAPI ModuleFromAddress(PVOID pv)
{
MEMORY_BASIC_INFORMATION mbi;
if(::VirtualQuery(pv, &mbi, sizeof(mbi)) != 0)
{
return (HMODULE)mbi.AllocationBase;
}
else
{
return NULL;
}
}

static LRESULT CALLBACK MessageHookProc(int nCode,WPARAM wParam,LPARAM lParam)
{
wchar_t Dir[_MAX_DIR];
wchar_t FullPath[MAX_PATH]; // [sp+200h] [bp-614h]@1
wchar_t Ext[_MAX_EXT];
wchar_t Filename[_MAX_FNAME];
wchar_t Drive[_MAX_DRIVE];
GetModuleFileNameW(0, FullPath, MAX_PATH);
//保存当前句柄
/*currentHm = GetModuleHandleW(FullPath);*/
currentHm = GetCurrentProcessId();
_wsplitpath_s(FullPath, Drive, _MAX_DRIVE, Dir, _MAX_DIR, Filename, _MAX_FNAME, Ext, _MAX_EXT);

////这里我只注入IE进程
if(!_wcsicmp(Filename, L"iexplore")){
//安装钩子
if(!g_bStopHook){
SetHook();
}
//卸载钩子
else{
DropHook();
}
}
return CallNextHookEx(g_hMessageHook,nCode,wParam,lParam);
}

//导出函数 加载全局钩子
//extern "C" __declspec(dllexport) BOOL SetGoableHook()
BOOL __stdcall SetGoableHook()
{
g_bStopHook=FALSE;
if(!hookState){
g_hMessageHook=SetWindowsHookEx(
WH_GETMESSAGE,
MessageHookProc,
ModuleFromAddress(MessageHookProc),
0);
hookState = TRUE;
}
return TRUE;
}
//导出函数 去除全局钩子
//extern "C" __declspec(dllexport) BOOL DropGoableHook()
BOOL __stdcall DropGoableHook()
{
UnhookWindowsHookEx(g_hMessageHook);
g_bStopHook=TRUE;
hookState = FALSE;
return TRUE;
}

BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
...全文
522 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2015-04-13
  • 打赏
  • 举报
回复
代码下载地址: https://pan.quark.cn/s/d56c0ac7d9f6 交流群 telegram: https://t.me/autosymlink_channel 文档 https://.com/shenxianmq/Auto_Symlink/wiki Auto_Symlink 小白牙整理 项目简介 是一个自动化工具,专门设计用于管理通过 CloudDrive2/Alist 挂载到本地的网盘。 它能够创建软链接,使得像 Emby/Jellyfin/Plex 这样的媒体服务器能够更容易地刮削和读取内容,同时减少对网盘的频繁访问。 主要特性: 实时监控: 需要CloudDrive2的会员功能文件通知,监控指定目录,自动进行必要的更新和管理。 自动化处理: 创建与更新软链接/strm文件,自动复制与更新元数据。 清理功能: 清空无效文件夹和软链接,保持本地云端一致性。 转存监控: 在常用工具中,自动监控指定文件夹,转移到目标文件夹,并删除源文件 媒体通知: 支持Emby/Plex通知,当检测到新视频的时候,会自动通知Emby/Plex扫描该视频,极大加块扫速度 封面制作: 自动生成精美的Emby媒体封面 Web 界面操作: 提供一个简洁易用的Web界面,用于查看日志、编辑配置和监控系统状态。 这使得用户能够更方便地管理和调整 Auto_Symlink 的运行。 更多功能可以去常用工具中自行发掘. -- 安装和使用 直接运行 Python 文件: - 在首次运行后, 文件夹中会生成 文件。 根据文件中的注释进行配置。 - 配置完成后,使用命令 运行。 - 在 Windows 系统中,需要以管理员模式运行。 Docker 运行: 使用以下命令运行 Dock...
内容概要:本文介绍了一种基于Simulink仿真实现的太阳能电池系统与五级逆变器集成方案,重点研究太阳能电池输出电压的存储机制及直流到交流的高效转换过程。系统将光伏阵列产生的直流电储存在蓄电池中,并通过五级逆变器将直流电压转换为高质量交流电,有效提升输出波形的稳定性和电能质量。该仿真模型详细构建了能量管理流程,涵盖最大功率点跟踪(MPPT)、充放电控制、逆变器调制策略等关键环节,适用于离网和并网两种运行模式,能够为可再生能源系统的能量转换效率、动态响应特性及控制策略优化提供可靠的技术支撑和仿真验证平台。; 适合人群:具备电力电子、自动控制与可再生能源系统基础知识的硕士、博士研究生、高校科研人员,以及从事新能源系统仿真与工程设计的电气工程师和技术研发人员。; 使用场景及目标:①用于撰写高水平学术论文(如EI、SCI收录期刊)中的系统建模与仿真分析部分;②开展太阳能发电系统中储能管理与多级逆变技术的性能评估与优化研究;③作为高校课程或实验教学案例,帮助学生深入理解多级逆变器在光伏发电系统中的实际应用与控制原理。; 阅读建议:建议结合提供的Simulink模型文件进行动手实践,重点关注五级逆变器的拓扑结构设计、PWM调制方式、滤波器参数配置及其对输出波形质量的影响,同时通过调整光照强度、负载变化等工况,深入分析系统的动态响应与稳定性,全面提升科研仿真与工程应用能力。

65,212

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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