关于注入

VirtualRookit 2010-01-27 03:31:54
#include <windows.h>
#include <iostream>
using namespace std;
//事先必须先单独测试该函数的长度,还有必须static 属性才是真正的函数地址
//否则只是 jmp 真正函数地址: 这一句代码的地址而已
//release下只有加static编译器才不会优化成普通代码,而当成一函数处理
static DWORD WINAPI ThreadProc(LPVOID lpParameter);
typedef HMODULE (WINAPI *LPLoadLibrary)(LPCSTR);
typedef FARPROC (WINAPI *LPGetProcAddress)(HMODULE, LPCSTR);
typedef int (WINAPI *LPMessageBox)(HWND, LPCSTR, LPCSTR, UINT);
//....
//如上这边可以列下线程所要用的api函数指针
struct para
{
LPLoadLibrary lploadlibrary;
LPGetProcAddress lpgetprocaddress;
char dllname[10][0xff];
char funname[10][0xff];
char strname[10][0xff];
};
void ShowError();
void main()
{
HWND hwnd;
DWORD PID;
HANDLE hProcess;
hwnd = ::FindWindowEx(NULL, NULL, "CalcFrame", "计算器");
if (hwnd == NULL)
{
ShowError();
::ExitProcess(0xff);
}
::GetWindowThreadProcessId(hwnd, &PID); //不必判断返回值
hProcess = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID);
if (hProcess == NULL)
{
ShowError();
::ExitProcess(0xff);
}

//构造传进去的参数
struct para parabuff;
memset(¶buff, 0, sizeof(struct para));
parabuff.lploadlibrary = (LPLoadLibrary)::GetProcAddress(::GetModuleHandle("kernel32.dll"), "LoadLibraryA");
parabuff.lpgetprocaddress = (LPGetProcAddress)::GetProcAddress(::GetModuleHandle("kernel32.dll"), "GetProcAddress");
memcpy(parabuff.dllname[0], "kernel32.dll", 0xff);
memcpy(parabuff.dllname[1], "user32.dll", 0xff );
memcpy(parabuff.dllname[2], "ws2_32.dll", 0xff);
memcpy(parabuff.funname[0], "MessageBoxA", 0xff);
memcpy(parabuff.funname[1], "GetModuleHandleA", 0xff);
memcpy(parabuff.strname[0], "欢迎使用远程线程", 0xff);
memcpy(parabuff.strname[1], "远程线程:", 0xff);
//....上面还可以列出要用到的*.dll与API

//申请参数结构空间
LPVOID databuff = ::VirtualAllocEx(hProcess, NULL, sizeof(struct para), MEM_COMMIT, PAGE_READWRITE);
if (databuff == NULL)
{
ShowError();
::ExitProcess(0xff);
}

if (!::WriteProcessMemory(hProcess, databuff, ¶buff, sizeof(parabuff), NULL ))
{
ShowError();
::VirtualFreeEx(hProcess, databuff, 0, MEM_RELEASE);
::ExitProcess(0xff);
}

//代码长度是查出汇编文件查看出来的
LPVOID codebuff = ::VirtualAllocEx(hProcess, NULL, 0xff, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (codebuff == NULL)
{
ShowError();
::ExitProcess(0xff);
}
if (!::WriteProcessMemory(hProcess, codebuff, ThreadProc, 0xff, NULL ))
{
ShowError();
::VirtualFreeEx(hProcess, codebuff, 0, MEM_RELEASE);
::ExitProcess(0xff);
}
HANDLE hThread;
hThread = ::CreateRemoteThread(hProcess, //进程句柄
NULL, //安全属性
0, //堆栈大小
(LPTHREAD_START_ROUTINE)codebuff,
databuff, //参数
0, //创建标志
NULL); //线程ID
if (hThread == NULL)
{
ShowError();
::VirtualFreeEx(hProcess, codebuff, 0, MEM_RELEASE);
::ExitProcess(0xff);
}

if (::WaitForSingleObject(hThread, INFINITE) == WAIT_FAILED)
{
ShowError();
::VirtualFreeEx(hProcess, codebuff, 0, MEM_RELEASE);
::ExitProcess(0xff);
}
DWORD status;
if (!::GetExitCodeThread(hThread, &status))
{
ShowError(); //函数失败
::VirtualFreeEx(hProcess, codebuff, 0, MEM_RELEASE);
::ExitProcess(0xff);
}
else
{
cout < < "线程退出码:" < < hex < < status < < endl; //dll.dll在目标进程中的地址
}
if (!::CloseHandle(hThread))
{
ShowError();
::VirtualFreeEx(hProcess, codebuff, 0, MEM_RELEASE);
::ExitProcess(0xff);
}
//释放目标进程申请的内存空间(MEM_RELEASE完全释放dwSize参数必须为0)
if (!::VirtualFreeEx(hProcess, databuff, 0, MEM_RELEASE))
{
ShowError();
::ExitProcess(0xff);
}
if (!::VirtualFreeEx(hProcess, codebuff, 0, MEM_RELEASE))
{
ShowError();
::ExitProcess(0xff);
}
}
//线程函数中不能调用任何API(kernel32.dll除外)及普通函数,
//(但kernel32.dll的API却不会),系统将kernel32.dll加载到每个进程相同的地址空间中,但其它
//*.dll导出的API系统可能会载到不同的空间中所以不能直接用其它*.dll里的API
DWORD WINAPI ThreadProc(LPVOID lpParameter)
{
struct para *parabuff = (struct para *)lpParameter;
LPLoadLibrary lpLoadLibrary = parabuff->lploadlibrary;
LPGetProcAddress lpGetProcAddress = parabuff->lpgetprocaddress;

HMODULE hUser = lpLoadLibrary(parabuff->dllname[1]);
LPMessageBox lpMessageBox = (LPMessageBox)lpGetProcAddress(hUser, parabuff->funname[0]);
lpMessageBox(NULL, parabuff->strname[0], parabuff->strname[1], MB_OK);
return 0;
}
void ShowError()
{
LPTSTR lpMsgBuf;
::FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
::GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&lpMsgBuf,
0,
NULL);
::MessageBox(NULL, lpMsgBuf, NULL, MB_OK | MB_ICONSTOP);
::LocalFree(lpMsgBuf);//释放操作系统开辟的缓冲区地址
}

//以上为完整代码.运行环境VS2008 + windows7 + Release +多字节(字符集)
//程序运行时目标程序崩溃,调试停在mov edi,edi;这一句(还没进入线程),然后单步执行直到线程结束都是正确的
//所以私下估计是在线程初始化时出的错,但不知道错在哪
//为什么?,请真正高手运行并确定bug后再教教小弟(没动手没发言权)
...全文
112 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
VirtualRookit 2010-01-27
  • 打赏
  • 举报
回复
后来我稍微改了下:基本上大部分进程都可以注入成功,但如下calc.exe还有一些少数进程仍是那样问题。。
代码如下:
#include <windows.h>
#include <iostream>
using namespace std;
//事先必须先单独测试该函数的长度,还有必须static 属性才是真正的函数地址
//否则只是[__jmp __FunName@n]: 这一句代码的地址而已
//release下只有加static编译器才不会优化成普通代码,而当成一函数处理
static DWORD WINAPI ThreadProc(LPVOID lpParameter);
typedef HMODULE (WINAPI *LPLoadLibrary)(LPCSTR);
typedef FARPROC (WINAPI *LPGetProcAddress)(HMODULE, LPCSTR);
typedef int (WINAPI *LPMessageBox)(HWND, LPCSTR, LPCSTR, UINT);
//....
//如上这边可以列下线程所要用的api函数指针
struct para
{
LPLoadLibrary lploadlibrary;
LPGetProcAddress lpgetprocaddress;
char dllname[10][0xff];
char funname[10][0xff];
char strname[10][0xff];
};
void ShowError();
void main()
{
DWORD PID;
HANDLE hProcess;
cout << "输入目标进程PID:"; //大部分进程能成功注入,但少部分进程会崩溃
cin >> PID;
hProcess = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID);
if (hProcess == NULL)
{
ShowError();
::ExitProcess(0xff);
}
//构造传进去的参数
struct para parabuff;
memset(¶buff, 0, sizeof(struct para));
parabuff.lploadlibrary = (LPLoadLibrary)::GetProcAddress(::GetModuleHandle("kernel32.dll"), "LoadLibraryA");
parabuff.lpgetprocaddress = (LPGetProcAddress)::GetProcAddress(::GetModuleHandle("kernel32.dll"), "GetProcAddress");
memcpy(parabuff.dllname[0], "kernel32.dll", 0xff);
memcpy(parabuff.dllname[1], "user32.dll", 0xff );
memcpy(parabuff.dllname[2], "ws2_32.dll", 0xff);
memcpy(parabuff.funname[0], "MessageBoxA", 0xff);
memcpy(parabuff.funname[1], "GetModuleHandleA", 0xff);
memcpy(parabuff.strname[0], "欢迎使用远程线程", 0xff);
memcpy(parabuff.strname[1], "远程线程:", 0xff);
//....上面还可以列出要用到的*.dll与API

//申请参数结构空间
LPVOID databuff = ::VirtualAllocEx(hProcess, NULL, sizeof(struct para), MEM_COMMIT, PAGE_READWRITE);
if (databuff == NULL)
{
ShowError();
::ExitProcess(0xff);
}

if (!::WriteProcessMemory(hProcess, databuff, ¶buff, sizeof(parabuff), NULL ))
{
ShowError();
::VirtualFreeEx(hProcess, databuff, 0, MEM_RELEASE);
::ExitProcess(0xff);
}

//代码长度是查出汇编文件查看出来的
LPVOID codebuff = ::VirtualAllocEx(hProcess, NULL, 0xff, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (codebuff == NULL)
{
ShowError();
::VirtualFreeEx(hProcess, databuff, 0, MEM_RELEASE);
::ExitProcess(0xff);
}
if (!::WriteProcessMemory(hProcess, codebuff, ThreadProc, 0xff, NULL ))
{
ShowError();
::VirtualFreeEx(hProcess, databuff, 0, MEM_RELEASE);
::VirtualFreeEx(hProcess, codebuff, 0, MEM_RELEASE);
::ExitProcess(0xff);
}
HANDLE hThread;
hThread = ::CreateRemoteThread(hProcess, //进程句柄
NULL, //安全属性
0, //堆栈大小
(LPTHREAD_START_ROUTINE)codebuff,
databuff, //参数
0, //创建标志
NULL); //线程ID
if (hThread == NULL)
{
ShowError();
::VirtualFreeEx(hProcess, databuff, 0, MEM_RELEASE);
::VirtualFreeEx(hProcess, codebuff, 0, MEM_RELEASE);
::ExitProcess(0xff);
}

if (::WaitForSingleObject(hThread, INFINITE) == WAIT_FAILED)
{
ShowError();
::VirtualFreeEx(hProcess, databuff, 0, MEM_RELEASE);
::VirtualFreeEx(hProcess, codebuff, 0, MEM_RELEASE);
::ExitProcess(0xff);
}
DWORD status;
if (!::GetExitCodeThread(hThread, &status))
{
ShowError(); //函数失败
::VirtualFreeEx(hProcess, databuff, 0, MEM_RELEASE);
::VirtualFreeEx(hProcess, codebuff, 0, MEM_RELEASE);
::ExitProcess(0xff);
}
else
{
cout << "线程退出码:"<< hex << status << endl; //dll.dll在目标进程中的地址
}
if (!::CloseHandle(hThread))
{
ShowError();
::VirtualFreeEx(hProcess, databuff, 0, MEM_RELEASE);
::VirtualFreeEx(hProcess, codebuff, 0, MEM_RELEASE);
::ExitProcess(0xff);
}
//释放目标进程申请的内存空间(MEM_RELEASE完全释放dwSize参数必须为0)
if (!::VirtualFreeEx(hProcess, databuff, 0, MEM_RELEASE))
{
ShowError();
::VirtualFreeEx(hProcess, codebuff, 0, MEM_RELEASE);
::ExitProcess(0xff);
}
if (!::VirtualFreeEx(hProcess, codebuff, 0, MEM_RELEASE))
{
ShowError();
::ExitProcess(0xff);
}
}
//线程函数中不能调用任何API(kernel32.dll除外)及普通函数,
//(但kernel32.dll的API却不会),系统将kernel32.dll加载到每个进程相同的地址空间中,但其它
//*.dll导出的API系统可能会载到不同的空间中所以不能直接用其它*.dll里的API
DWORD WINAPI ThreadProc(LPVOID lpParameter)
{
struct para *parabuff = (struct para *)lpParameter;
LPLoadLibrary lpLoadLibrary = parabuff->lploadlibrary;
LPGetProcAddress lpGetProcAddress = parabuff->lpgetprocaddress;

HMODULE hUser = lpLoadLibrary(parabuff->dllname[1]);
LPMessageBox lpMessageBox = (LPMessageBox)lpGetProcAddress(hUser, parabuff->funname[0]);
lpMessageBox(NULL, parabuff->strname[0], parabuff->strname[1], MB_OK);
return 0xabcd;
}
void ShowError()
{
LPTSTR lpMsgBuf;
::FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
::GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&lpMsgBuf,
0,
NULL);
::MessageBox(NULL, lpMsgBuf, NULL, MB_OK | MB_ICONSTOP);
::LocalFree(lpMsgBuf);//释放操作系统开辟的缓冲区地址
}
VirtualRookit 2010-01-27
  • 打赏
  • 举报
回复
我这上面代码只需注释掉线程函数里面的:
//LPMessageBox lpMessageBox = (LPMessageBox)lpGetProcAddress(hUser, parabuff->funname[0]);
//lpMessageBox(NULL, parabuff->strname[0], parabuff->strname[1], MB_OK);

就一切都是正常的。。真是奇怪,我想是线程初始化的时候出状况,但不知道为什么,我真的很想知道。。。
  • 打赏
  • 举报
回复
呃。帮顶!
clhposs 2010-01-27
  • 打赏
  • 举报
回复
嗯。。。我也研究过,如果直接写入函数的话,有很多限制。
你可以参考一个我写的。。
对了 一定要注意。代码不能在debug模式编译,因此会产生很多调试代码。。。


/************************************************************************/
/* 无DLL注入,由于编译器优化可能导致错误,因此请用Relase优化 */
/* 2009年12月10日 */
/* By Poss */
/************************************************************************/

#include <windows.h>
#include <TLHELP32.H>
#include "resource.h"

struct ProcessMsg
{
HANDLE (WINAPI *MyCreateToolhelp32Snapshot)(DWORD,DWORD); //创建系统快照
BOOL (WINAPI *MyProcess32First)(HANDLE, LPPROCESSENTRY32); //枚举进程
BOOL (WINAPI *MyProcess32Next)(HANDLE, LPPROCESSENTRY32);
UINT (WINAPI *MyWinExec)(LPCSTR, UINT); //启动程序,郁闷,他没有ASCII
VOID (WINAPI *MySleep)(DWORD); //暂停
int (WINAPI *MyMessageBox)(HWND, LPCTSTR, LPCTSTR, UINT); //消息框
int (WINAPI *MyComperString)(LPCTSTR, LPCTSTR); //比较字符串

char szFilePath[MAX_PATH];
TCHAR szFileName[MAX_PATH];
HANDLE hSnapshot;
bool isRun;
PROCESSENTRY32W pe32;
};

DWORD WINAPI ThreadProc(LPVOID lpParam)
{
struct ProcessMsg *msg = (struct ProcessMsg*)lpParam;

// msg->pe32.dwSize = sizeof(msg->pe32);

while (true)
{

msg->isRun = true;
msg->hSnapshot = msg->MyCreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
msg->MyProcess32First(msg->hSnapshot, &msg->pe32);

do
{
// msg->MyMessageBox(NULL, msg->pe32.szExeFile, msg->szFileName, MB_OK);
if (!msg->MyComperString(msg->szFileName, msg->pe32.szExeFile))
{
msg->isRun = false;
}
msg->MySleep(100);
} while(msg->MyProcess32Next(msg->hSnapshot, &msg->pe32));
if (msg->isRun)
{
// msg->MyMessageBox(NULL, NULL, NULL, 0);
msg->MyWinExec(msg->szFilePath, SW_SHOWNORMAL);
}
msg->MySleep(1000);
}
return 0;
}

BOOL EnablePriv()
{
HANDLE hToken;
if ( OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,&hToken) )
{
TOKEN_PRIVILEGES tkp;

LookupPrivilegeValue( NULL,SE_DEBUG_NAME,&tkp.Privileges[0].Luid );//修改进程权限
tkp.PrivilegeCount=1;
tkp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges( hToken,FALSE,&tkp,sizeof tkp,NULL,NULL );//通知系统修改进程权限

return( (GetLastError()==ERROR_SUCCESS) );
}
return TRUE;
}

DWORD GetProcessID(TCHAR *szProcess)
{
EnablePriv();
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
PROCESSENTRY32 pe32;

pe32.dwSize = sizeof(pe32);
Process32First(hSnapshot, &pe32);

do
{
if (!wcsicmp(szProcess, pe32.szExeFile))
{
return pe32.th32ProcessID;
}
} while(Process32Next(hSnapshot, &pe32));

return 0;
}

HANDLE GetProcessHandle(TCHAR *szProcess)
{
DWORD dwProcess = GetProcessID(szProcess);

if (dwProcess == 0)
{
return NULL;
}

HANDLE hProcess = OpenProcess(PROCESS_CREATE_THREAD|PROCESS_VM_WRITE|PROCESS_VM_OPERATION, FALSE, dwProcess);

return hProcess;
}

void SetFunAddress(struct ProcessMsg *msg)
{
HMODULE hKernel32 = GetModuleHandle(TEXT("Kernel32.dll"));

(FARPROC&)msg->MyCreateToolhelp32Snapshot = GetProcAddress(hKernel32, "CreateToolhelp32Snapshot");
(FARPROC&)msg->MyProcess32First = GetProcAddress(hKernel32, "Process32FirstW");
(FARPROC&)msg->MyProcess32Next = GetProcAddress(hKernel32, "Process32NextW");
(FARPROC&)msg->MySleep = GetProcAddress(hKernel32, "Sleep");
(FARPROC&)msg->MyWinExec = GetProcAddress(hKernel32, "WinExec");
(FARPROC&)msg->MyComperString = GetProcAddress(hKernel32, "lstrcmp");
(FARPROC&)msg->MyMessageBox = GetProcAddress(GetModuleHandle(TEXT("User32.dll")), "MessageBoxW");
GetModuleFileNameA(GetModuleHandle(NULL), msg->szFilePath, MAX_PATH);
lstrcpy(msg->szFileName, TEXT("CreateRemoteThread.exe"));
msg->pe32.dwSize = sizeof(PROCESSENTRY32W);
}

bool InsertThread(TCHAR *szProcess)
{
HANDLE hProcess = GetProcessHandle(szProcess);

if (hProcess == NULL)
{
return false;
}

struct ProcessMsg msg;
SetFunAddress(&msg);

DWORD dwSize = sizeof(msg);
LPVOID lpParam = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT, PAGE_READWRITE);

if (lpParam == NULL)
{
CloseHandle(hProcess);
return false;
}

DWORD dwWrite;
if (!WriteProcessMemory(hProcess, lpParam, &msg, dwSize, &dwWrite))
{
VirtualFreeEx(hProcess, lpParam, dwSize, MEM_DECOMMIT);
CloseHandle(hProcess);
return false;
}

/*函数大小。除汇编外,其他语言设置这个十分麻烦,因此我这架设一个比较大的内容*/
DWORD dwThread = 1024 * 4;
LPVOID lpThread = VirtualAllocEx(hProcess, NULL, dwThread, MEM_COMMIT, PAGE_EXECUTE_READWRITE);

if (lpThread == NULL)
{
VirtualFreeEx(hProcess, lpParam, dwSize, MEM_DECOMMIT);
CloseHandle(hProcess);
return false;
}

if (!WriteProcessMemory(hProcess, lpThread, ThreadProc, dwThread, &dwWrite))
{
VirtualFreeEx(hProcess, lpParam, dwSize, MEM_DECOMMIT);
VirtualFreeEx(hProcess, lpThread, dwThread, MEM_DECOMMIT);
CloseHandle(hProcess);
return false;
}

CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)lpThread, lpParam, 0, 0);

return true;
}

INT_PTR CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDC_BTN_BEGIN:
if (BN_CLICKED == HIWORD(wParam))
{
TCHAR szProcess[MAX_PATH];
GetDlgItemText(hwndDlg, IDC_EDIT_PROCESS, szProcess, MAX_PATH);
InsertThread(szProcess);
}
return true;
}
return true;
case WM_INITDIALOG:
return true;
case WM_CLOSE:
EndDialog(hwndDlg, 0);
return true;
}

return false;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG), NULL, (DLGPROC)DialogProc);

return 0;
}

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧