兰州网站建设专家,单县建设局网站,电子商务网页设计与制作实训报告,深圳龙华建网站CreateRemoteThread和WriteProcessMemory技术
示例程序#xff1a;WinSpy
另一种注入代码到其他进程地址空间的方法是使用WriteProcessMemory API。这次你不用编写一个独立的DLL而是直接复制你的代码到远程进程#xff08;WriteProcessMemory#xff09;并用CreateRemoteT…CreateRemoteThread和WriteProcessMemory技术
示例程序WinSpy
另一种注入代码到其他进程地址空间的方法是使用WriteProcessMemory API。这次你不用编写一个独立的DLL而是直接复制你的代码到远程进程WriteProcessMemory并用CreateRemoteThread执行之。
让我们看一下CreateRemoteThread的声明 HANDLE CreateRemoteThread( HANDLE hProcess, // handle to process to create thread in LPSECURITY_ATTRIBUTES lpThreadAttributes, // pointer to security // attributes DWORD dwStackSize, // initial thread stack size, in bytes LPTHREAD_START_ROUTINE lpStartAddress, // pointer to thread // function LPVOID lpParameter, // argument for new thread DWORD dwCreationFlags, // creation flags LPDWORD lpThreadId // pointer to returned thread identifier ); 和CreateThread相比有一下不同 ●增加了hProcess参数。这是要在其中创建线程的进程的句柄。 ●CreateRemoteThread的lpStartAddress参数必须指向远程进程的地址空间中的函数。这个函数必须存在于远程进程中所以我们不能简单地传递一个本地ThreadFucn的地址我们必须把代码复制到远程进程。 ●同样lpParameter参数指向的数据也必须存在于远程进程中我们也必须复制它。 现在我们总结一下使用该技术的步骤 1 得到远程进程的HANDLEOpenProcess。 2 在远程进程中为要注入的数据分配内存VirtualAllocEx、 3 把初始化后的INJDATA结构复制到分配的内存中WriteProcessMemory。 4 在远程进程中为要注入的数据分配内存VirtualAllocEx。 5 把ThreadFunc复制到分配的内存中WriteProcessMemory。 6 用CreateRemoteThread启动远程的ThreadFunc。 7 等待远程线程的结束WaitForSingleObject。 8 从远程进程取回指执行结果ReadProcessMemory 或 GetExitCodeThread。 9 释放第2、4步分配的内存VirtualFreeEx。 10 关闭第6、1步打开打开的句柄。
另外编写ThreadFunc时必须遵守以下规则 1 ThreadFunc不能调用除kernel32.dll和user32.dll之外动态库中的API函数。只有kernel32.dll和user32.dll如果被加载可以保证在本地和目的进程中的加载地址是一样的。注意user32并不一定被所有的Win32进程加载参考附录A。如果你需要调用其他库中的函数在注入的代码中使用LoadLibrary和GetProcessAddress强制加载。如果由于某种原因你需要的动态库已经被映射进了目的进程你也可以使用GetMoudleHandle代替LoadLibrary。同样如果你想在ThreadFunc中调用你自己的函数那么就分别复制这些函数到远程进程并通过INJDATA把地址提供给ThreadFunc。
2 不要使用static字符串。把所有的字符串提供INJDATA传递。为什么编译器会把所有的静态字符串放在可执行文件的“.data”段而仅仅在代码中保留它们的引用即指针。这样远程进程中的ThreadFunc就会执行不存在的内存数据至少没有在它自己的内存空间中。
3 去掉编译器的/GZ编译选项。这个选项是默认的看附录B。 4 要么把ThreadFunc和AfterThreadFunc声明为static要么关闭编译器的“增量连接incremental linking”看附录C。 5 ThreadFunc中的局部变量总大小必须小于4k字节看附录D。注意当degug编译时这4k中大约有10个字节会被事先占用。 6 如果有多于3tch分支的case语句必须像下面这样分割开或用if-else if代替. case constant1: statement1; goto END; case constant2: statement2; goto END; case constant3: statement2; goto END; } case constant4: statement4; goto END; case constant5: statement5; goto END; case constant6: statement6; goto END; } END: 简单的CreateRemoteThread例程-初学者必看 // _remotethreaddemo.cpp : Defines the entry point for the console application. // Author:秋镇菜 #include stdafx.h #include windows.h // 定义一个代码结构,本例为一个对话框 struct MyData { char sz[ 64 ]; // 对话框显示内容 DWORD dwMessageBox; // 对话框的地址 }; // 远程线程的函数 DWORD __stdcall RMTFunc(MyData * pData) { typedef int (__stdcall * MMessageBox)(HWND,LPCTSTR,LPCTSTR,UINT); MMessageBox MsgBox (MMessageBox)pData - dwMessageBox; MsgBox(NULL, pData - sz, NULL, MB_OK); return 0 ; } int main( int argc, char * argv[]) { // 获得需要创建REMOTETHREAD的进程句柄 HWND hWnd FindWindow( notepad , NULL); // 以NOTEPAD为例 DWORD dwProcessId; ::GetWindowThreadProcessId(hWnd, dwProcessId); HANDLE hProcess OpenProcess( PROCESS_ALL_ACCESS, FALSE, dwProcessId); // 代码结构 MyData data; ZeroMemory( data, sizeof (MyData)); strcat(data.sz, 对话框的内容. ); HINSTANCE hUser LoadLibrary( user32.dll ); if ( ! hUser) { printf( Can not load library. ); return 0 ; } data.dwMessageBox (DWORD)GetProcAddress(hUser, MessageBoxA ); FreeLibrary(hUser); if ( ! data.dwMessageBox) return 0 ; // 分配空间 void * pRemoteThread VirtualAllocEx(hProcess, 0 , 1024 * 4 , MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); if ( ! pRemoteThread) return 0 ; if ( ! WriteProcessMemory(hProcess, pRemoteThread, RMTFunc, 1024 * 4 , 0 )) return 0 ; MyData * pData (MyData * )VirtualAllocEx(hProcess, 0 , sizeof (MyData), MEM_COMMIT, PAGE_READWRITE); if ( ! pData) return 0 ; if ( ! WriteProcessMemory(hProcess, pData, data, sizeof (MyData), 0 )) return 0 ; // 创建远程线程 HANDLE hThread CreateRemoteThread(hProcess, 0 , 0 , (LPTHREAD_START_ROUTINE)pRemoteThread, pData, 0 , 0 ); if ( ! hThread) { printf( 远程线程创建失败 ); return 0 ; } CloseHandle(hThread); VirtualFreeEx(hProcess, pRemoteThread, 1024 * 3 , MEM_RELEASE); VirtualFreeEx(hProcess, pData, sizeof (MyData), MEM_RELEASE); CloseHandle(hProcess); printf( Hello World! ); return 0 ; } 程序在windows xp下运行 弹出messagebox之后 只要点击确定宿主进程就会崩溃。 而且不止是messagebox调用其它的api函数也是一样请问这是什么原因有什么办法可以解决吗 -------------------------------------------------------- 编译成RELEASE版本就不会出错了,主要是DEBUG版本加了一个__chkesp的函数导致调用了非法地址