GetCurrentProcess得到无效句柄。
屏幕取词,我在dll中调用GetCurrentProcess得到的返回值总是-1,而WriteProcessMemory每次都返回内存分配访问无效、错误代码998.
代码如下:
#include "stdafx.h"
#include "MouseGetWord.h"
#include <ImageHlp.h>
#include <TlHelp32.h>
#pragma comment(lib,"ImageHlp")
#pragma data_seg("ShareData")
HWND ghWnd=NULL;
HMODULE g_hExe = 0; // 当前进程模块句柄
int gi_MousePosX = 0;
int gi_MousePosY = 0;
UINT gu_TimerID = 0;
HWND gh_MouseWnd = NULL;
#pragma data_seg()
#pragma comment(linker,"/SECTION:ShareData,RWS")
#define WM_MOUSEINFO WM_USER + 100
HHOOK ghMouseHook=NULL;
HINSTANCE ghInstance=NULL;
VOID CALLBACK TimerFunc(HWND wHwnd,UINT uMsg,UINT dEvent,DWORD dwTime);
BOOL WINAPI Hook_TextOutA(HDC hdc, int nXStart, int nYStart, LPCSTR lpszString, int cbString);
VOID ModifyIATs(LPCSTR szDllName,PROC pfnOrg,PROC pfnNew);
//---------------------------------------------------------------------------
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
ghInstance = (HINSTANCE)hModule;
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
ModifyIATs("GDI32.dll",GetProcAddress(GetModuleHandle("GDI32.DLL"),
"TextOutA"),
(PROC)Hook_TextOutA);
break;
case DLL_PROCESS_DETACH:
ModifyIATs("GDI32.dll",(PROC)Hook_TextOutA,GetProcAddress(GetModuleHandle("GDI32.DLL"),"TextOutA"));
if (ghMouseHook != NULL)
{
UnhookWindowsHookEx(ghMouseHook);
ghMouseHook = NULL;
}
break;
}
return TRUE;
}
LRESULT CALLBACK MyHookProc(int aiCode ,WPARAM wParam,LPARAM lParam)
{
if(aiCode<0)
return CallNextHookEx(ghMouseHook,aiCode,wParam,lParam);
if(wParam==WM_MOUSEMOVE)
{
LPMOUSEHOOKSTRUCT lpMouse=(MOUSEHOOKSTRUCT *)lParam;
if(gu_TimerID != NULL)
{
KillTimer(NULL,gu_TimerID);
gu_TimerID = NULL;
}
gu_TimerID = SetTimer(NULL,0,500,(TIMERPROC)TimerFunc);
gh_MouseWnd = lpMouse->hwnd;
gi_MousePosX = lpMouse->pt.x;
gi_MousePosY = lpMouse->pt.y;
}
return CallNextHookEx(ghMouseHook,aiCode,wParam,lParam);
}
VOID CALLBACK TimerFunc(HWND wHwnd,UINT uMsg,UINT dEvent,DWORD dwTime)
{
KillTimer(NULL,gu_TimerID);
gu_TimerID = NULL;
POINT lp;
lp.x = gi_MousePosX;
lp.y = gi_MousePosY;
ScreenToClient(gh_MouseWnd,&lp);
RECT rect;
rect.left = gi_MousePosY - 1;
rect.right = gi_MousePosY + 1;
rect.top = gi_MousePosX - 1;
rect.bottom = gi_MousePosX +1;
InvalidateRect(gh_MouseWnd,&rect,TRUE);
}
extern "C" void SetWindowHandle(HWND ahWnd)
{
ghWnd = ahWnd;
}
extern "C" int StartGetWord()
{
ghMouseHook = SetWindowsHookEx(WH_MOUSE,(HOOKPROC)MyHookProc,ghInstance,0);
if(ghMouseHook == NULL)
return 1;
gu_TimerID = SetTimer(NULL,0,1000,(TIMERPROC)TimerFunc);
return 0;
}
extern "C" int StopGetWord()
{
if(ghMouseHook != NULL)
{
UnhookWindowsHookEx(ghMouseHook);
ghMouseHook = NULL;
}
if(gu_TimerID != NULL)
{
KillTimer(NULL,gu_TimerID);
gu_TimerID = NULL;
}
return 0;
}
VOID ModifyIAT(HMODULE hmodCaller,LPCSTR szDllName,PROC pfnOrg,PROC pfnNew)
{
PIMAGE_THUNK_DATA pITD;
char * lpTemp;
int liRet;
ULONG ulSize;
//对每一个用到的dll,在输入表中都用一个IMAGE_IMPORT_DESCRIPTOR类型的
//结构体保存该dll的信息
PIMAGE_IMPORT_DESCRIPTOR pIID;
//用ImageDirectoryEntryToData可以取得输入表中的第一项
//参数IMAGE_DIRECTORY_ENTRY_IMPORT指明要取得输入表,而不是其他表
pIID =(PIMAGE_IMPORT_DESCRIPTOR)ImageDirectoryEntryToData(hmodCaller,TRUE,IMAGE_DIRECTORY_ENTRY_IMPORT,&ulSize);
//如果pIID为NULL,表示该模块没有输入表,返回
if( !pIID )
return;
//IMAGE_IMPORT_DESCRIPTOR有一个Name的成员,该成员是dll名字的RVA
//hmodCaller实质是模块映射到进程空间中的基地址,通过将它转换为PBYTE类型,
//再加上Name这个RVA就可以得到这项IMAGE_IMPORT_DESCRIPTOR记录的dll的名字
//将这个名字与我们要挂接的dll的名字比较
//如果两个名字不同,则pIID++取下一项IMAGE_IMPORT_DESCRIPTOR
for(; pIID->Name; pIID++)
{
lpTemp = MakePtr(PSTR,hmodCaller,pIID->Name);
if( !lstrcmpiA( szDllName,lpTemp))
break;
}
//如果遍历完所有dll都没有找到我们要挂接的dll,则返回
if( !pIID->Name )
return;
//可以从一个dll中输入多个函数.对每一个输入的函数,用一个IMAGE_THUNK_DATA
//结构体保存它的信息.在IMAGE_IMPORT_DESCRIPTOR中,有一个FirstThunk成员记录着
//第一个IMAGE_THUNK_DATA(这个IMAGE_THUNK_DATA保存着第一个输入函数的信息)的RVA
//我们用与取得dll名字一样的方法(基址+RVA)取得这个IMAGE_THUNK_DATA
pITD = MakePtr(PIMAGE_THUNK_DATA,hmodCaller,pIID->FirstThunk);
//IMAGE_THUNK_DATA有一个ul成员,它是一个共同体.通过这个共同体的Function成员,我们
//可以得到输入函数在进程空间中的真实地址
//将这个真实地址和我们要挂接的函数的地址比较,如果相同,则修改
//否则pITD++取下一个输入函数的信息
for(; pITD->u1.Function ; pITD++)
{
PROC* ppfn = (PROC*)&pITD->u1.Function;
if( *ppfn == pfnOrg )
{
WriteProcessMemory(GetCurrentProcess(),ppfn,&pfnNew,sizeof(PROC),NULL);
return;
}
}
}
VOID ModifyIATs(LPCSTR szDllName,PROC pfnOrg,PROC pfnNew){
BOOL fOk = FALSE;
MODULEENTRY32 me32;
HANDLE hSnapshot;
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,GetCurrentProcessId());
me32.dwSize = sizeof( me32 );
//枚举当前进程的全部模块
for( fOk = Module32First( hSnapshot,&me32 ); fOk ; fOk = Module32Next(hSnapshot,&me32)){
if( me32.hModule != ghInstance ){
ModifyIAT(me32.hModule,szDllName,pfnOrg,pfnNew);
}
}
CloseHandle( hSnapshot );
}
BOOL WINAPI Hook_TextOutA(HDC hdc, int nXStart, int nYStart, LPCSTR lpszString, int cbString)
{
COPYDATASTRUCT MyCDS;
MyCDS.dwData = 0X002;
MyCDS.cbData = cbString;
MyCDS.lpData = (PVOID )lpszString;
::SendMessage(ghWnd,WM_COPYDATA,(WPARAM)WindowFromDC(hdc),(LPARAM)(LPVOID)&MyCDS);
return TextOutA(hdc,nXStart,nYStart,lpszString,cbString);
}