- 注册时间
- 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。
|
|