阅读:2049回复:13
VtoolsD中的PELDR_GetModuleHandle干吗用的?为什么不能取user32.dll的地址? |
|
沙发#
发布于:2002-04-20 09:14
没98,不能帮你试了。你仔细查查是不是程序的问题
|
|
板凳#
发布于:2002-04-22 08:15
我的现象是这样的, 用PELDR_GetModuleHandle能取到user32.dll的地址,接着用PELDR_GetProcessAddress取道了MessageBoxA的地址,在VC中用DeviceIOControl的方法使VXD用函数指针调用MessageBoxA,但弹出的不是大家熟悉的消息框,而是整个屏幕变成蓝屏,并显示了消息框的内容。这是为什么?
|
|
地板#
发布于:2002-04-22 09:51
Ring0 -> Ring3 and return Ring0.
How to return Ring0? |
|
|
地下室#
发布于:2002-04-22 09:59
呵呵,你在0环程序里调3环代码,当然会蓝屏啦。By the way,98中用户界面代码最终都是16位的,更不行了。
你到底想做什么呀?0环程序显示对话框有二法: EVENTHANDLE __stdcall dSHELL_Message( VMHANDLE hVM, DWORD Flags, CONST CHAR * Message, CONST CHAR * Caption, CONST VOID * Callback, CONST VOID * Refdata, PSHELLMessage_THUNK pThunk ); DWORD SHELL_SYSMODAL_Message( VMHANDLE hVM, DWORD Flags, CONST CHAR * Message, CONST CHAR * Caption ); 前者是一个白框对话框 后者产生你熟悉的蓝屏(整个屏幕就是对话框,呵呵) |
|
5楼#
发布于:2002-04-22 10:10
0环程序调环3上的代码也不是完全不行(当然不是说call之后就Ring0->Ring3了,这是硬件上禁止的,你必须用near call,Ring3代码就运行在Ring0上),不过你得保证Ring3代码在Ring0运行时的安全性。一般代码都是不行的,更别说98的16位代码了。NT上有些函数可以,比如一些Rtl*函数。
|
|
6楼#
发布于:2002-04-22 11:02
首先感谢pjf,我用修改中断描述表的方法已经实现RING0调运RING3代码,我这次写VXD是为了动态替换API函数,我发现了一个这样的现象,在VXD中搜索USER32.DLL的输出表,将MessageBoxA的地址改成我的MyMsgBox地址并保存,在MyMsgBox中用固定参数调用MessageBoxA,在VC中用DeviceIOControl控制替换和恢复。替换后别的程序调用MessageBox时弹出的是MyMsgBox,但按确定后出现异常提示,如果说RING0不能调用消息框,但消息框确实正常出现了,只是退出时不正常,接着用DeviceIOControl恢复又一切正常。这是为什么?会不会和堆栈有关系?
|
|
7楼#
发布于:2002-04-22 13:13
|
|
8楼#
发布于:2002-04-22 13:30
(点错鼠标了...)
噢,你仅仅是修改了MessageBox的入口地址,并未在Ring0调用它,而是别的Ring3程序在调它呀。你的MyMsgBox是不是用的标准C调用啊?是的话把它改为__stdcall;若是汇编写的返回时用ret n good luck |
|
9楼#
发布于:2002-04-22 13:43
我将相关程序列在这儿:
DWORD MyDevice::OnW32DeviceIoControl(PIOCTLPARAMS pDIOCParams) { DWORD * pDWORD; switch( pDIOCParams->dioc_IOCtlCode ) { case DIOC_OPEN: gOldProc = 0; gLibAddress = 0; gpMsg = 0; return DEVIOCTL_NOERROR; case DIOC_CLOSEHANDLE: return DEVIOCTL_NOERROR; case 1://替换 if( pDIOCParams->dioc_InBuf && pDIOCParams->dioc_cbInBuf >= 8 ) { pDWORD = (DWORD *)pDIOCParams->dioc_InBuf; gLibAddress = pDWORD[0]; gNewProc = (DWORD )MyMessageBox; gpMsg = (MSGBOX )MyHookApi( \"MessageBoxA\", gNewProc); if( pDIOCParams->dioc_bytesret ) *pDIOCParams->dioc_bytesret = (DWORD )gpMsg; } else { if( pDIOCParams->dioc_bytesret ) *pDIOCParams->dioc_bytesret = 2; } return DEVIOCTL_NOERROR; case 2://恢复 if( gpMsg ) MyHookApi( \"MessageBoxA\", (DWORD )gpMsg); if( pDIOCParams->dioc_bytesret ) *pDIOCParams->dioc_bytesret = 0x22; return DEVIOCTL_NOERROR; default: return 1; } } typedef int (*MSGBOX)(HWND hWnd, LPCTSTR text, LPCTSTR caption, UINT type); MSGBOX gpMsg; int __stdcall MyMessageBox(HWND hWnd, LPCTSTR text, LPCTSTR caption, UINT type) { if( gpMsg ) return gpMsg( hWnd, text, \"my messagebox\", type); return 0; } 其中MyHookApi是根据PE格式搜索函数输出表 我试了试,加不加__stdcall都一样,都能弹出正常的消息框,就是按确定就异常,若在MyMessageBox直接return 0则不出现异常。 |
|
10楼#
发布于:2002-04-22 14:29
兄弟,我是叫你在这里加:
typedef int (__stdcall *MSGBOX)(HWND hWnd, LPCTSTR text, LPCTSTR caption, UINT type); 因为API是__stdcall,你原来的程序调用之后又用了add esp,16指令,将stack破坏了。你应申明一下,告诉编译器 |
|
11楼#
发布于:2002-04-22 14:32
int __stdcall MyMessageBox(HWND hWnd, LPCTSTR text, LPCTSTR caption, UINT type)
这里的__stdcall保留 |
|
12楼#
发布于:2002-04-22 14:40
非常感谢pjf兄弟,我一直就怀疑是堆栈的问题,也试过加WINAPI修饰,现在搞定了,在MyMessageBox 和 *MSGBOX之前都应该加,缺一不可。给你20分,略表感谢。
|
|
13楼#
发布于:2002-04-22 16:22
谢了,呵呵
|
|