windows环境中跨进程数据访问方法_第1页
windows环境中跨进程数据访问方法_第2页
windows环境中跨进程数据访问方法_第3页
windows环境中跨进程数据访问方法_第4页
windows环境中跨进程数据访问方法_第5页
已阅读5页,还剩8页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

windows环境中跨进程数据访问方法讨论windows环境中跨进程数据访问方法之讨论论文结构一、问题分析—4-4^一、技术万案三、 分步骤技术解析四、 遇到的问题和解决方法五、 结论六、 参考文献七、 代码附录本论文要解决的问题1、 将pjtPassWord.exe、Protector.dll和dinasaur.3D文件置于同一文件夹中,运行pjtPassWord.exe。在显示的界面上输入自己的学号,如110521101,必须是9位数字。点击下方“激活密码生成”按钮,用于激活密码计算。2、 系统自行根据输入的用户名按一定规律随机产生密码,1秒钟变化1次。3、 需要通过所学知识,编写适当代码,获取以*覆盖的密码,并将其写入到密码框之下的文本框中,点击“解除图形锁定”按钮,则可以看到系统中原本隐藏的一个新界面。4、 因密码变化周期为1秒,则用户所写代码的执行过程必须在1秒之内完成,否则无法解开锁定的图形。5、 解除锁定后,在内存中搜索连续的6个整型数据,分别对应x,y,z,h,p,r的值。将它们的值分别修改为550265043。之后双击图片,保存。.问题分析Windows是多任务的操作系统,任务即所说的进程。各进程的地址空间被分为用户空间和系统空间两部分,用户空间即进程的私有空间。此问题要做的就是如何在windows环境下读取其他进程的密码框内的文字。因为密码框内的文字是该进程的私有数据,所以不允许其他进程对其直接访问。但是因为本文本框内的文字1s变化一次,并且是通过sendmessage将其变化的内容发给主窗口下的子窗口,因此我们可以在主窗口的消息队列前挂接钩子,通过钩子函数对截获的信息做提前处理,然后再将消息给消息的目标窗口。解除图形解锁后,需要搜索本进程的内存中的六个连续的整型数据,然后对其分别进行修改。由于进程的地址空间是相互隔离的,所以必须通过API函数的协助才能访问其他进程中的数据,然后就是对内存进行搜索,找到符合条件的内存地址,然后对地址中的内容进行修改。.技术方案1.消息的截获因为是要跨进程数据访问,钩子函数负责的功能包括:截获发给第一个文本框的密码信息,然后将其写入到第二个文本框,最后还要自定义一个消息,模拟鼠标动作,使其点击Button按钮解锁。因此钩子函数必须能跨进程挂接,所以此钩子必须声明为全局钩子。因此此钩子函数必须定义在DLL中。2.内存搜索与修改Windows采用了分页机制来管理内存,每页的大小是4KB。也就是说windows是以4KB为单位来为应用程序分配内存的。所以可以按页来搜索目标内存,以提高搜索效率。因为搜索到符合条件的内存地址可能不止一个,所以需要在搜索到的地址中通过相应的验证方法进行过滤,直到最后的结果只有一个时,才是正确的我们要修改的地址。分步骤技术解析1.截获发送给第一个文本框的密码信息。Windows每隔一秒给文本框发送一个SetText的消息,此消息的密码信息储存在参数IParam,因此要在DLL中定义一个类型为WH_CALLWNDPROC的钩子,钩子的原型声明如下:HHOOKSetWindowsHookEx(WH_CALLWNDPROC,(HOOKPROC)HookPorc,hins,0)设置全局钩子,当系统任何一个进程调用SendMessage函数发送消息时,钩子函数被调用因为钩子函数是系统来自动调用的,因此要把钩子函数声明为CallBack函数,钩子函数声明的代码如下:LRESULTCALLBACKHookProc(intnCode,WPAPAMwParam,LPARAMlParam)钩子函数负责的功能有:截获lParam,然后将lparam写入到第二个文本框中,然后通过SendMessage模拟一个鼠标点击动作,所有这些事情都需要在一秒内完成,否则当第一个文本框的密码改变后,则无法解锁图形。2.将截获的密码写入到第二个文本框中获得第二个文本框的句柄,然后通过sendmessage发送一个类型为WM_SETTEXT的消息,其声明格式如下:SendMessage((void*)str[1],WM_SETTEXT,35,(LPARAM)Buffer);/给第二个文本框发送SETTEXT类型的消息3.用sendmessage模拟鼠标点击动作其格式如下:SendMessage((void*)str[2],BM_CLICK,0,0);//给第三个按钮发送BM_CLICK类型的消息所有这些事情要完成的关键是获得三个句柄值。得到三个句柄值。因为两个文本框和一个button按钮都是子窗口,所以先要找到其父窗口,我们已经知道其父窗口的标题为CrackMe-ByFanJingtao,所以只需要枚举父窗口,当窗口标题为CrackMe-ByFanJingtao时,再枚举子窗口,然后分获其句柄值。为此需要第一两个回调函数,boolCALLBACKEnumWindowsProc(HWNDhwnd,LPARAMlParam)枚举父窗口,boolCALLBACKEnumChildProc(HWNDhwnd,LPARAMlParam)枚举子窗口,并获得三个句柄值。搜索内存,将指定的值写入到指定的内存地址。boolwrite(){intarr[6];arr[0]=5;arr[1]=5;arr[2]=0;arr[3]=26;arr[4]=50;arr[5]=43;if(WriteProcessMemory(g_hProcess,(LPVOID)FirstAddress,arr,24,NULL))//将指定数据写入到内存之中returntrue;elsereturnfalse;}6.需要得到进程ID,然后得到打开此进程的句柄,然后利用这个句柄值对此进程的内存进行读写。那么应该怎样获取指定进程的ID呢?通过使用API函数CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0)给当前系统内执行的进程拍快照,获得一个进程列表,此API函数能够获得进程的ID,进程对应的可执行文件和创建该进程的进程ID等数据。然后使用Process32First和Process32Next函数遍历快照中记录的列表,通过此进程的可执行文件的名称对得到的进程列表进行过滤,通过任务管理器得知此进程的名称为:PjtPassWord.exe。得到此进程的ID后,还要取得该进程的句柄,对于一个已经存在的进程,只能使OpenProcess函数来取得这个进程的访问权限, 其格式如下:g_hProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,ID);其代码形式如下:BOOLGetProcessId(){PROCESSENTRY32pe32;HANDLEhProcessSnap =HANDLECreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);//给系统内所有的进程拍个快照if(hProcessSnap==INVALID_HANDLE_VALUE){ShowMessage("CreateToolhelp32Snapshot调用失败");returnfalse;}pe32.dwSize=sizeof(PROCESSENTRY32);//在使用这个结构前,先设置它的大小//遍历进程快照,轮流显示每个进程的信息BOOLbMore=Process32First(hProcessSnap,&pe32);while(bMore){if((String)pe32.szExeFile=="PjtPassWord.exe"){ID=pe32.th32ProcessID;CloseHandle(hProcessSnap);//清除掉snapshot对象g_hProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,ID);returntrue;}bMore=Process32Next(hProcessSnap,&pe32);}returnfalse;}读写需要找到的相应数据的基地址,为此只需要遍历搜索到的内存地址,判断六个连续的内存地址之间是否只差4个字节。如果存在,就将其基地址记下。读取进程内存的函数是:BOOLread(){while(1){RealAddress=0;if(ReadProcessMemory(g_hProcess,(LPCVOID)dwBase,arByte,4096,NULL)){for(inti=0;i<1024;i++){if(arByte[i]==3)AddressList[RealAddress++]=dwBase+4*i;//按页读取if(Decide())returntrue;elsedwBase+=4096;}elsedwBase+=4096;}}将指定地址写入到内存的函数是:boolwrite(){intarr[6];arr[0]=5;arr[1]=5;arr[2]=0;arr[3]=26;arr[4]=50;arr[5]=43;if(WriteProcessMemory(g_hProcess,(LPVOID)FirstAddress,arr,24,NULL))//将指定数据写入到内存之中returntrue;elsereturnfalse;}7.最后将DLL占用的资源释放FreeLibrary(handle);遇到的问题和解决方法问题一:怎样得到密码框中的密码?通过挂接钩子:HHOOKSetWindowsHookEx(WH_CALLWNDPROC,(HOOKPROC)HookPorc,hins,0)然后自定义一个消息:SendMessage((void*)str[1],WM_GETTEXT,35,(LPARAM)Buffer);即能得到*号下的密码值。问题二:怎样将密码值写入到第二个文本框?通过自定义一个消息:SendMessage((void*)str[1],WM_SETTEXT,35,(LPARAM)Buffer);即能将密码值写入到第二个文本框问题三:怎样自动点击按钮?通过自定义一个消息:SendMessage((void*)str[2],BM_CLICK,0,0);问题四:怎样搜索指定进程的内存?通过进程快照,对获取的进程快照进行遍历,将快照中的 (String)pe32.szExeFile与"PjtPassWord.exe,进行比较,如果相等,就获取其ID值,然后获取其进程句柄。然后调用API函数ReadProcessMemory(g_hProcess,(LPCVOID)dwBase,arByte,4096,NULL,因为要搜索连续存储的六个整数,所以需要有一个过滤条件,来确定可能符合条件的地址,为此我们不妨手动将x,y,z,h,p,r的值调整到一个值,然后只需要记录存储值为此值的地址。因为进程中是指定值的地址不一定只有x,y,z,h,p,rj因此需要进一步过滤,此过滤条件即为,在结果中有六个连续的整数地址:if(AddressList[i]+4==AddressList[i+1]&&AddressList[i+1]+4==AddressList[i+2]&&AddressList[i+2]+4==AddressList[i+3]&&AddressList[i+3]+4==AddressList[i+4]&&AddressList[i+4]+4==AddressList[i+5])这样之后,就能得到正确的基地址:FirstAddress=AddressList[i];//得到此段进程的首地址。问题五:怎样将指定值写入到内存?直接调用API函数WriteProcessMemory(g_hProcess,(LPVOID)FirstAddress,arr,24,NULL)其中参数的含义分别为:g_hProcess:指定进程的句柄(LPVOID)FirstAddress:写入的首地址arr:写入的指定值问题六:怎样将此进程的数据用于指定的进程发法师内存共享,若没有共享的内存,就调用API函数CreateFileMapping((HANDLE)DWORD(-1),NULL,PAGE_READWRITE,0,3*sizeof(int),"ShareMemory");来创建指定名称的共享内存,此函数返回共享内存的句柄,然后需要对共享内存中的数据进行设置,本问题是将在此进程中的句柄值给指定的进程使用,所以将本进程得到的句柄值设置成共享内存中的数据,为此需要得到指向共享内存的指针,声明一个int类型的指针,其代码如下:str=(int*)MapViewOfFile(MyHandle,FILE_MAP_ALL_ACCESS,0,0,3*sizeof(int));然后就是对指针进行赋值,其代码如下:extern"C"_declspec(dllexport)void_stdcallGet(int*get){for(inti=0;i<3;i++){str[i]=get[i];//得到第一‘二个文本框和第三个按钮的句柄值}}结论。获取的密码值为:06966F74-SB220HJA-00D8B4F1-00000007参考文献《Windows程序设计》(王艳萍编著,人民邮电出版社)代码附录DLL文件中:#pragmaargsusedHINSTANCEhins;//当前线程运行实例句柄HANDLEMyHandle;HHOOKhook=NULL;//接收钩子句柄int*str;#pragmaargsused//定义一个钩子回调函数LRESULTCALLBACKHookPorc(intnCode,WPARAMwParam,LPARAMlParam){〃将消息传给另一个钩子处理returnCallNextHookEx(hook,nCode,wParam,lParam);}〃定义挂接钩子的函数extern"C"_declspec(dllexport)void_stdcallHook(){if(hook==NULL){〃设置全局钩子,当系统任何一个进程调用SendMessage函数发送消息时,钩子函数被调用hook=SetWindowsHookEx(WH_CALLWNDPROC,(HOOKPROC)HookPorc,hins,0);}}//定义卸载钩子的函数extern"C"_declspec(dllexport)void_stdcallUnHook(){if(hook){〃卸载钩子UnhookWindowsHookEx(hook);}}//定义得到三个句柄的函数extern"C"_declspec(dllexport)void_stdcallGet(int*get){for(inti=0;i<3;i++){str[i]=get[i];//得到第一‘二个文本框和第三个按钮的句柄值}}voidStartShare(){MyHandle=CreateFileMapping((HANDLE)DWORD(-1),NULL,PAGE_READWRITE,0,3*sizeof(int),"ShareMemory");str=(int*)MapViewOfFile(MyHandle,FILE_MAP_ALL_ACCESS,0,0,3*sizeof(int));CharBuffer[35];//存储密码值//自定义消息SendMessage((void*)str[0],WM_GETTEXT,35,(LPARAM)Buffer);//给第一个文本框发送GETTEXT类型的消息SendMessage((void*)str[1],WM_SETTEXT,35,(LPARAM)Buffer);/给第二个文本框发送SETTEXT类型的消息SendMessage((void*)str[2],BM_CLICK,0,0);//给第三个按钮发送BM_CLICK类型的消息for(inti=0;i<3;i++){str[i]=0;//<句柄值置零,避免不断向其发送消息}voidStopShare(){UnmapViewOfFile(MyHandle);CloseHandle(MyHandle);}intWINAPIDllEntryPoint(HINSTANCEhinst,unsignedlongreason,void*lpReserved){ hins=hinst;//得到当前DLL的实例句柄值switch(reason){caseDLL_PROCESS_ATTACH:StartShare();//A口函数中调用此函数break;caseDLL_PROCESS_DETACH:StopShare();break;}return1;}主程序文件中:// #include<vcl.h>#pragmahdrstop#pragmahdrstop#include"jlxs1.h"#include"tlhelp32.h"#include"windows.h"// #pragmapackage(smart_init)#pragmaresource"*.dfm"HINSTANCEhinst=NULL;void(_stdcall*Hook)();//Hook函数声明void(_stdcall*UnHook)();//UnHook函数声明void(_stdcall*Write)(int*write);//Write函数声明intHandles[3];//用来存储三个句柄值intcount=0;HANDLEg_hProcess;DWORDID;DWORDAddressList[1024];//存放查找到的地址列表intRealAddress=0;//有效地址个数intarByte[1024];intdwBase=64*1024;DWORDFirstAddress;TForm1*Form1;// __fastcallTForm1::TForm1(TComponent*Owner):TForm(Owner){hinst=LoadLibrary("jlxsDLL.dll");Hook=(void(_stdcall*)())GetProcAddress(hinst,"Hook");UnHook=(void(_stdcall*)())GetProcAddress(hinst,"UnHook");Write=(void(_stdcall*)(int*))GetProcAddress(hinst,"Get");ShowMessage("变形之前,需先将x,y等六个数值改为相同的值");}// //枚举子窗口boolCALLBACKEnumChildProc(HWNDhwnd,LPARAMlParam){charBuffer[256];GetClassName(hwnd,Buffer,255);//调用API函数获得类名StringName=(String)Buffer;if(Name=="TSafeEdit")//用Spy++获得其类名称{Handles[0]=(int)hwnd;//将第一个文本框的句柄值存入数组count++;returntrue;}if(count==1){count++;returntrue;}if(count==2){Handles[2]=(int)hwnd;//将第二个文本框的句柄值存入到数组count++;returntrue;}if(count==3){Handles[1]=(int)hwnd;//将按钮的句柄值存入到数组count++;Write(Handles);Hook();returnfalse;}returntrue;}boolCALLBACKEnumWindowsProc(HWNDhwnd,LPARAMIParam){charBuffer[256];GetWindowText(hwnd,Buffer,255);/稠用API函数获取父窗口标题if((String)Buffer=="CrackMe-ByFanJingtao"){EnumChildWindows(hwnd,(WNDENUMPROC)EnumChildProc,0);returnfalse;}returntrue;}void__fastcallTForm1::btn1startClick(TObject*Sender){EnumWindows((WNDENUMPROC)EnumWindowsProc,0);//调用API函数枚举窗口}// void__fastcallTForm1::btn2unhookClick(TObject*Sender){UnHook();}// boolDecide(){for(inti=0;i<1024;i++){ 〃在当前进程内存中找到六个相等的整数值if(AddressList[i]+4==AddressList[i+1]&&AddressList[i+1]+4==AddressList[i+2]&&AddressList[i+2]+4==AddressList[i+3]&&AddressList[i+3]+4==AddressList[i+4]&&AddressList[i+4]+4==AddressList[i+5]){FirstAddress=AddressList[i];//得到此段进程的首地址returntrue;}elsereturnfalse;}returnfalse;}BOOLGetProcessId(){PROCESSENTRY32pe32;HANDLEhProcessSnap=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);//得到系统内所有进程的快照if(hProcessSnap==INVALID_HANDLE_VALUE){ShowMessage(-调用进程快照API函数失败");returnfalse;}pe32.dwSize=sizeof(PROCESSENTRY32);〃遍历进程快照,轮流显示每个进程的信息BOOLbMore=P

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论