- 注册时间
 - 2010-7-27
 
- 最后登录
 - 2017-5-30
 
- 在线时间
 - 3 小时
 
 
 
 
 
编程入门 
  
	- 魔鬼币
 - 565 
 
 
 
 | 
 
 
    大家都知道如果我们知道了一个游戏中的某一个函数,如选怪函数,我们只需要调用该函数就可以实现选怪这个操作了,而不需要通过传递按键的方式。这里我们不讨论如何去找这个函数,我只想说说怎么通过自己的进程去调用其他进程中的函数的方法。 
    
    其实这个有3中方法:    
  (1)Windows 钩子,把你的代码放到一个DLL中;然后用 windows 钩子把它映射到远程进程。    
  (2)CreateRemoteThread 和LoadLibrary 技术,把你的代码放到一个DLL中;然后用 CreateRemoteThread 和 LoadLibrary 把它映射到远程进程。    
  (3)CreateRemoteThread 和 WriteProcessmemory 技术,不用DLL,直接复制你的代码到远程进程(使用WriteProcessMemory)并且用CreateRemoteThread执行之。    
 
    我先说说第二个方法。    
    ※CreateRemoteThread 和LoadLibrary 技术。    
    首先,我们做一个试验。我们先创建一个窗体项目(VC或者VB都可以)Project1,窗体上面放2个textbox(文本输入框),一个为普通类型 text1,另一个为password类型text2。我们再创建一个项目(可执行就行)Project2。在Project2中写入如下代码:   
    char szText[256];   
    WPARAM wParam = sizeof(szText);   
    LPARAM lParam = (LPARAM)szText;   
    memset (szText, 0, sizeof(szText));   
    HWND handle2 = (HWND)0x40FAA;//注1   
    SendMessage(handle2, WM_GETTEXT, wParam, lParam);//获得句柄是handle2的控件的文本值   
    cout<<szText;   
    注1:这里为Project1中textbox的句柄,可以通过SPY++或者自己遍历子窗体的方式获得,这里不详细说明。   
 
    我们首先将text1(普通类型的textbox)的句柄赋给handle2,运行Project1,在text1上输入:123456;运行Project2,我们可以获得结果123456。关闭Project1和Project2。   
    我们再将text2(password类型的textbox)的句柄赋给handle2,运行Project1,在text2上输入:123456,运行Project2,我们得到的结果是空。   
    通过这个试验,我们可以发现,外部进程使用sendmessage的gettext不能获取密码框中的文本。msdn中说,只有本进程才可以通过sendmessage的gettext方式获取本进程的密码框内容。   
    因此,这里我将介绍使用CreateRemoteThread 和LoadLibrary 技术将sendmessage这个方法注入到目标进程Project1中获取text2密码框中的内容。   
    首先建立一个mfc dll文件,"testDLL.dll".在dllmain函数中写入如下代码:   
    char szText[256];   
    WPARAM wParam = sizeof(szText);   
    LPARAM lParam = (LPARAM)szText;   
    memset (szText, 0, sizeof(szText));   
    HWND handle2 = (HWND)0x40FAA;//这里handle2为text2的句柄   
    SendMessage(handle2, WM_GETTEXT, wParam, lParam);   
    MessageBox(0,szText,"",0);   
 
将编译生成的testDLL.dll文件放到C盘根目录下。   
 
    然后随便创建一个可执行项目,这里是个控制台项目:   
#include <windows.h>   
#include <winbase.h>   
#include <iostream.h>   
void main()   
{   
    HANDLE hThread;   
    char    szLibPath[]= "c:\\testDLL.dll"; //自己写的dll的绝对路径    
    void*  pLibRemote;    
    DWORD  hLibModule;      
    HMODULE hKernel32 = ::GetModuleHandle("Kernel32");   
    HWND mhwnd = (HWND)0x70Fc6;   
    HANDLE hProcess;   
    DWORD threadid;   
    GetWindowThreadProcessId(mhwnd,&threadid);   
    hProcess = OpenProcess(PROCESS_ALL_ACCESS,false,threadid);   
    //在远程进程中为szLibPath分配内存   
    pLibRemote = ::VirtualAllocEx( hProcess, NULL, sizeof(szLibPath),   
                                  MEM_COMMIT,PAGE_READWRITE );   
    //写szLibPath到分配的内存   
    ::WriteProcessMemory( hProcess, pLibRemote, (void*)szLibPath,   
        sizeof(szLibPath), NULL );   
    //加载"textDLL.dll"到远程进程(CreateRemoteThread 和LoadLibrary 技术)   
    hThread = ::CreateRemoteThread( hProcess, NULL, 0,   
        (LPTHREAD_START_ROUTINE) ::GetProcAddress( hKernel32,"LoadLibraryA" ),   
        pLibRemote, 0, NULL );   
    ::WaitForSingleObject( hThread, INFINITE );   
    //取得DLL的基址   
    ::GetExitCodeThread( hThread, &hLibModule );   
    //关闭线程和释放内存   
    ::CloseHandle( hThread );   
    ::VirtualFreeEx( hProcess, pLibRemote, sizeof(szLibPath), MEM_RELEASE );   
    //建立远程线程卸载DLL   
    hThread = ::CreateRemoteThread( hProcess, NULL, 0,   
        (LPTHREAD_START_ROUTINE) ::GetProcAddress( hKernel32, "FreeLibrary" ),(void*)hLibModule, 0, NULL );   
    //关闭线程和释放内存   
    ::WaitForSingleObject( hThread, INFINITE );   
    ::CloseHandle( hThread );   
}    
    运行Project1,在text2中输入123456,运行上面的代码,弹出对话框,显示123456。 
 |   
 
 
 
 |