int __stdcall WINAPI MyFunc (LPVOID lpram)
{ RemoteParam *prp = (RemoteParam*)lpram;
PFN_MESSAGEBOX MY_MessageBox = (PFN_MESSAGEBOX)prp->dwMessageBox;
MY_MessageBox(NULL,prp->szMsg,prp->szMsg,0);
return 0;
}  void AfterMyFunc (void) 
{
}
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd )
{
///获得进程pid
HWND hStart = ::FindWindow ("Notepad",NULL); 
DWORD PID,TID;
///打开进程空间
TID = ::GetWindowThreadProcessId (hStart, &PID);HANDLE hProcess;
hProcess = OpenProcess(PROCESS_ALL_ACCESS,false,PID); 
///在目标进程中为需要插入的线程分配代码空间,并写入
DWORD cbCodeSize=((LPBYTE) AfterMyFunc - (LPBYTE) MyFunc);
PDWORD pCodeRemote = (PDWORD) VirtualAllocEx( hProcess, 0, cbCodeSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE );
WriteProcessMemory( hProcess, pCodeRemote, &MyFunc, cbCodeSize, NULL);
//将函数messagebox地址,还有用到的变量写到目标进程中
RemoteParam remoteData;
ZeroMemory(&remoteData, sizeof(RemoteParam));//填充结构体变量中的成员
HINSTANCE hUser32 = LoadLibrary("User32.dll");
remoteData.dwMessageBox = (DWORD)GetProcAddress(hUser32, "MessageBoxA");
strcat(remoteData.szMsg, "Hello\0");//为线程参数在宿主进程中开辟存储区域
RemoteParam* pRemoteParam = (RemoteParam*)VirtualAllocEx(
hProcess , 0, sizeof(RemoteParam), MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(hProcess,
            pRemoteParam, &remoteData, sizeof(remoteData), 0); ///在目标进程中启动线程
HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, 
(LPTHREAD_START_ROUTINE)pCodeRemote,pRemoteParam, 0 , NULL);
}程序在MyFunc函数中调用MessageBox并将MyFunc作为一个线程 ,插入到Notepad中,运行时MessageBox对话框可以正常显示,但一旦MessageBox返回,宿主进程就回出错,哪位朋友帮我看看哪里出了问题???

解决方案 »

  1.   

    这种问题通常是调用约定没写对。PFN_MESSAGEBOX的定义帖出来呢?
      

  2.   

    PFN_MESSAGEBOX定义为一个函数指针
    typedef int (* PFN_MESSAGEBOX)(HWND, LPCTSTR, LPCTSTR, DWORD);
      

  3.   

    typedef   int   (__stdcall *   PFN_MESSAGEBOX)(HWND,   LPCTSTR,   LPCTSTR,   DWORD);
      

  4.   

    刚才试了,加了__stdcall还是一样的问题啊
      

  5.   

    typedef   int    (__stdcall *   PFN_MESSAGEBOX)(HWND,   LPCTSTR,   LPCTSTR,   DWORD);
    =================================================================
    同意 Idle_ 由于参数调用规则不一致引起了堆栈错误,即函数可以正常调用(参数压栈正常),但返回时MESSAGEBOX已将参数堆栈释放掉,而使用typedef   int    (*   PFN_MESSAGEBOX)(HWND,   LPCTSTR,   LPCTSTR,   DWORD);则再次释放堆栈,造成错位,至此ret返回时跑到了错误的地址。
      

  6.   

    感谢vrace,做成RELEASE版本后问题解决.
    但不知道为何会出现这种情况??希望了解的朋友解释
      

  7.   

    你是在网上拷贝的这段代码吧,我试了debug也能不报错,你把你引用的头文件贴出来看看啊~~
      

  8.   

     不完全是拷贝的,有一部分是自己加的,引用的 头文件就是windows.h啊 ,没其他的.
      

  9.   

    1. 没有其它头文件么? 反正不能包含#include <iostream>, 否则会出现你说的错误.. 我原来试过...
    2. DWORD cbCodeSize=((LPBYTE) AfterMyFunc - (LPBYTE) MyFunc);
       会不会是你这里申请内存大小太小的问题? 尝试把这里大小改大点看看..比如4096
    3. int __stdcall WINAPI MyFunc (LPVOID lpram) 
       在这里__stdcall = WINAPI ,你干吗要申明两次? int __stdcall MyFunc (LPVOID lpram)就可以了..
      

  10.   

    DWORD   cbCodeSize=((LPBYTE)   AfterMyFunc   -   (LPBYTE)   MyFunc); 改成4096后问题解决
    谢谢,马上给分