使用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;
}
...全文
375 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2015-04-13
  • 打赏
  • 举报
回复

64,662

社区成员

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

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