贴一段来自某度的介绍
在一个进程中,调用CreateThread或CreateRemoteThreadEx函数,在另一个进程内创建一个线程(因为不在同一个进程中,所以叫做远程线程)。创建的线程一般为Windows API函数LoadLibrary,来加载一个动态链接库(DLL),从而达到在另一个进程中运行自己所希望运行的代码的目的。
其实很简单
直接上代码
有两种注入方式一种是自己手写函数注入,将函数代码注入即可,还有一种是dll注入,dll注入就更加简单了,有两个例子大家看了就懂了。
手写代码注入
// Inject.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include<windows.h>
#include<iostream>
using namespace std;
DWORD loadAddr = 0;
//MessageBoxW地址
DWORD msgbox = 0;
//执行地址
char *exec = nullptr;
static DWORD WINAPI msgb(LPVOID param) {
//param为第一次分配首地址
//下面这段汇编代码是这个意思
/*
首先保存所有寄存器
将首地址放到eax寄存器
将首地址放到ecx寄存器
ecx加40为函数地址 ps int WINAPI MessageBox(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCaption,UINT uType);
首先push最后一个参数 uType
然后push lpCaption
然后lpText
然后hWnd
然后调用函数
恢复所有寄存器
*/
__asm {
pusha
mov eax,param
mov ecx,eax
add ecx,40
push 0
push eax
push eax
push 0
call [ecx]
popa
}
return 0;
}
WCHAR functionName[] = L"MessageBoxW";
int main()
{
//函数地址
msgbox = (DWORD)MessageBoxW;
//查找窗口
HWND sl_hwnd = FindWindowA(NULL, "扫雷");
//扫雷PID
DWORD sl_pid = 0;
//用来记录需要弹出的字符串及函数地址
char *textAndFunction = nullptr;
if (sl_hwnd) {
cout << "查找到扫雷窗口" << endl;
//获取进程pid
GetWindowThreadProcessId(sl_hwnd, &sl_pid);
//获取句柄
HANDLE sl_handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, sl_pid);
//在扫雷进程分配100字节
textAndFunction = (char*)VirtualAllocEx(sl_handle, NULL, 100, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (textAndFunction == nullptr) {
CloseHandle(sl_handle);
return -1;
}
cout << "已经申请100字节空间" << endl;
//写入函数名字
if (WriteProcessMemory(sl_handle, textAndFunction, (LPVOID)functionName, sizeof(functionName), NULL) == false) {
CloseHandle(sl_handle);
return -1;
}
//MessageBoxW函数地址
if (WriteProcessMemory(sl_handle, textAndFunction +40, (LPVOID)&msgbox, 4, NULL) == false) {
CloseHandle(sl_handle);
return -1;
}
//执行代码空间分配
exec = (char*)VirtualAllocEx(sl_handle, NULL, 1024, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (exec == nullptr) {
cout << "分配内存失败" << endl;
CloseHandle(sl_handle);
return -1;
}
//写入执行代码
if (WriteProcessMemory(sl_handle, exec, (LPVOID)&msgb, 1024, NULL) == false) {
cout << "写入内存失败" << endl;
CloseHandle(sl_handle);
return -1;
}
//输出地址
cout << "info" << " MessageBoxW address is " << hex<<msgbox << endl <<(DWORD)textAndFunction <<" "<<(DWORD)exec<< endl;;
//在扫雷中新建线程执行
HANDLE remoteHandle = CreateRemoteThread(sl_handle,NULL,0,(LPTHREAD_START_ROUTINE)exec,(LPVOID)textAndFunction,0,NULL);
if (remoteHandle == nullptr) {
cout << "开启远程线程失败,如果错误代码是5则是权限有问题,建议在winxp下使用" << endl;
int error = GetLastError();
cout << error << endl;
CloseHandle(sl_handle);
return -1;
}
system("pause");
}
return 0;
}
这里有个小细节需要注意一下
http://www.cnblogs.com/fanzhidongyzby/archive/2012/08/30/2664287.html
这个网站有讲解,就是需要设置一下
不然可能出现栈错误
效果如下图
还有一种dll注入代码也贴上去,大同小异,只是注入的时候传入LoadLibaryA即可,另外一个进程加载dll时候会自动执行case DLL_PROCESS_ATTACH:
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
MessageBoxA(NULL,"Hello","Hello",0);
MessageBoxA(NULL,"Hello","想干啥就干啥了",0);
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
后面这个效果如下
不过这种杀毒软件会站出来说你这个东西在做危险的动作,直接无视就好了
需要代码的直接留言即可