代码注入在 Vista 或 Win7 上不起作用?
所以我不得不让两个朋友在他们的 Vista 和 Windows 上测试可执行文件。 Win7操作系统。注入的代码都没有执行(即使以管理员身份运行),但控制台打开/关闭。通过 WriteProcessMemory
和 CreateRemoteThread
进行代码注入在 Vista 或 Win7 上仍然有效吗?
代码
在 Visual Studio 2008 上使用 /RTCu 进行编译,以防止在 Windows XP 上远程线程终止后进程崩溃。
CodeInjector.h
#ifndef CODEINJECTOR_H
#define CODEINJECTOR_H
typedef HANDLE(WINAPI *GETPROC)();
typedef HMODULE(WINAPI *PLOADLIBRARYA)(const char *dll);
typedef LPVOID(WINAPI *PGETPROCADDRESS)(HMODULE mod, const char *func);
typedef int (WINAPI *FNMESSAGEBOX)(HWND, LPCSTR, LPCSTR, UINT);
typedef struct _IAT {
PLOADLIBRARYA pLoadLibraryA;
PGETPROCADDRESS pGetProcAddress;
FNMESSAGEBOX fnMessageBox;
} IAT;
typedef struct _DATA {
void *szData[256];
} DATA;
typedef struct _FNARGS {
LPVOID pIat;
LPVOID pData;
} FNARGS;
#endif /* CODEINJECTOR_H */
CodeInjector.cpp
#include "stdafx.h"
#include <iostream>
#include <string>
#include <windows.h>
#include "CodeInjector.h"
using namespace std;
HANDLE getHandleByName(const char* nameWnd)
{
HWND hWnd = FindWindowA(0, nameWnd);
if (hWnd == 0) {
std::cerr << "Cannot find window" << std::endl;
} else {
DWORD pId;
GetWindowThreadProcessId(hWnd, &pId);
HANDLE hToken;
TOKEN_PRIVILEGES tkp;
if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tkp.Privileges[0].Luid);
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hToken, 0, &tkp, sizeof (tkp), NULL, NULL);
}
HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pId);
if (!hProc) {
std::cerr << "Cannot open process: " << GetLastError() << std::endl;
} else {
return hProc;
}cout << hProc;
getchar();
}
return false;
}
static DWORD WINAPI ThreadFunc(FNARGS *info)
{
if (info == NULL || info->pIat == NULL || info->pData == NULL) {
return 0;
}
IAT *iat = (IAT *)info->pIat;
DATA *data = (DATA *)info->pData;
iat->fnMessageBox(NULL, (char*)data->szData[1], (char*)data->szData[0], MB_OK);
return 0;
}
static void ThreadFuncEnd() {}
int main(int argc, char** argv)
{
HANDLE hProc = getHandleByName("Calculator");
DWORD CodeSize = (DWORD) & ThreadFuncEnd - (DWORD) & ThreadFunc;
IAT hIAT;
DWORD hLibModule;
HMODULE hKernel = LoadLibraryA("kernel32.dll");
HMODULE hUser32 = LoadLibraryA("user32.dll");
hIAT.pLoadLibraryA = (PLOADLIBRARYA)GetProcAddress(hKernel, "LoadLibraryA");
hIAT.pGetProcAddress = (PGETPROCADDRESS)GetProcAddress(hKernel, "GetProcAddress");
hIAT.fnMessageBox = (FNMESSAGEBOX)GetProcAddress(hUser32, "MessageBoxA");
LPVOID hIATMemAddr = VirtualAllocEx(hProc, NULL, sizeof (IAT), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(hProc, hIATMemAddr, (LPVOID) & hIAT, sizeof (IAT), NULL);
DATA hData;
LPVOID hDataMemAddr = VirtualAllocEx(hProc, NULL, sizeof (DATA), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
hData.szData[0] = VirtualAllocEx(hProc, NULL, 64, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
hData.szData[1] = VirtualAllocEx(hProc, NULL, 64, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
hData.szData[2] = VirtualAllocEx(hProc, NULL, 64, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
hData.szData[3] = VirtualAllocEx(hProc, NULL, 64, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
char tmp[64];
strcpy(tmp, "Caption");
WriteProcessMemory(hProc, hData.szData[0], (LPVOID) & tmp, sizeof (tmp), NULL);
strcpy(tmp, "Message");
WriteProcessMemory(hProc, hData.szData[1], (LPVOID) & tmp, sizeof (tmp), NULL);
WriteProcessMemory(hProc, hDataMemAddr, (LPVOID) &hData, sizeof (DATA), NULL);
FNARGS tInfo;
tInfo.pIat = hIATMemAddr;
tInfo.pData = hDataMemAddr;
LPVOID hInfoMemAddr = VirtualAllocEx(hProc, NULL, sizeof (FNARGS), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(hProc, hInfoMemAddr, (LPVOID) & tInfo, sizeof (FNARGS), NULL);
LPVOID CodeMemAddr = VirtualAllocEx(hProc, NULL, CodeSize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(hProc, CodeMemAddr, (LPVOID) & ThreadFunc, CodeSize, NULL);
HANDLE hRemoteThread = CreateRemoteThread(hProc, NULL, 0, (LPTHREAD_START_ROUTINE)CodeMemAddr, hInfoMemAddr, 0, NULL);
WaitForSingleObject(hRemoteThread, INFINITE);
GetExitCodeThread(hRemoteThread, &hLibModule);
CloseHandle(hProc);
return 0;
}
So I had to two friends test the executable on their Vista & Win7 operating systems. Neither had the injected code executed (even when Run as Administrator) but the console open/closed. Does code injection via WriteProcessMemory
and CreateRemoteThread
still work on Vista or Win7?
The Code
Compiled using /RTCu on Visual Studio 2008 to prevent process crashing while on Windows XP after the remote thread terminates.
CodeInjector.h
#ifndef CODEINJECTOR_H
#define CODEINJECTOR_H
typedef HANDLE(WINAPI *GETPROC)();
typedef HMODULE(WINAPI *PLOADLIBRARYA)(const char *dll);
typedef LPVOID(WINAPI *PGETPROCADDRESS)(HMODULE mod, const char *func);
typedef int (WINAPI *FNMESSAGEBOX)(HWND, LPCSTR, LPCSTR, UINT);
typedef struct _IAT {
PLOADLIBRARYA pLoadLibraryA;
PGETPROCADDRESS pGetProcAddress;
FNMESSAGEBOX fnMessageBox;
} IAT;
typedef struct _DATA {
void *szData[256];
} DATA;
typedef struct _FNARGS {
LPVOID pIat;
LPVOID pData;
} FNARGS;
#endif /* CODEINJECTOR_H */
CodeInjector.cpp
#include "stdafx.h"
#include <iostream>
#include <string>
#include <windows.h>
#include "CodeInjector.h"
using namespace std;
HANDLE getHandleByName(const char* nameWnd)
{
HWND hWnd = FindWindowA(0, nameWnd);
if (hWnd == 0) {
std::cerr << "Cannot find window" << std::endl;
} else {
DWORD pId;
GetWindowThreadProcessId(hWnd, &pId);
HANDLE hToken;
TOKEN_PRIVILEGES tkp;
if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tkp.Privileges[0].Luid);
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hToken, 0, &tkp, sizeof (tkp), NULL, NULL);
}
HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pId);
if (!hProc) {
std::cerr << "Cannot open process: " << GetLastError() << std::endl;
} else {
return hProc;
}cout << hProc;
getchar();
}
return false;
}
static DWORD WINAPI ThreadFunc(FNARGS *info)
{
if (info == NULL || info->pIat == NULL || info->pData == NULL) {
return 0;
}
IAT *iat = (IAT *)info->pIat;
DATA *data = (DATA *)info->pData;
iat->fnMessageBox(NULL, (char*)data->szData[1], (char*)data->szData[0], MB_OK);
return 0;
}
static void ThreadFuncEnd() {}
int main(int argc, char** argv)
{
HANDLE hProc = getHandleByName("Calculator");
DWORD CodeSize = (DWORD) & ThreadFuncEnd - (DWORD) & ThreadFunc;
IAT hIAT;
DWORD hLibModule;
HMODULE hKernel = LoadLibraryA("kernel32.dll");
HMODULE hUser32 = LoadLibraryA("user32.dll");
hIAT.pLoadLibraryA = (PLOADLIBRARYA)GetProcAddress(hKernel, "LoadLibraryA");
hIAT.pGetProcAddress = (PGETPROCADDRESS)GetProcAddress(hKernel, "GetProcAddress");
hIAT.fnMessageBox = (FNMESSAGEBOX)GetProcAddress(hUser32, "MessageBoxA");
LPVOID hIATMemAddr = VirtualAllocEx(hProc, NULL, sizeof (IAT), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(hProc, hIATMemAddr, (LPVOID) & hIAT, sizeof (IAT), NULL);
DATA hData;
LPVOID hDataMemAddr = VirtualAllocEx(hProc, NULL, sizeof (DATA), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
hData.szData[0] = VirtualAllocEx(hProc, NULL, 64, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
hData.szData[1] = VirtualAllocEx(hProc, NULL, 64, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
hData.szData[2] = VirtualAllocEx(hProc, NULL, 64, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
hData.szData[3] = VirtualAllocEx(hProc, NULL, 64, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
char tmp[64];
strcpy(tmp, "Caption");
WriteProcessMemory(hProc, hData.szData[0], (LPVOID) & tmp, sizeof (tmp), NULL);
strcpy(tmp, "Message");
WriteProcessMemory(hProc, hData.szData[1], (LPVOID) & tmp, sizeof (tmp), NULL);
WriteProcessMemory(hProc, hDataMemAddr, (LPVOID) &hData, sizeof (DATA), NULL);
FNARGS tInfo;
tInfo.pIat = hIATMemAddr;
tInfo.pData = hDataMemAddr;
LPVOID hInfoMemAddr = VirtualAllocEx(hProc, NULL, sizeof (FNARGS), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(hProc, hInfoMemAddr, (LPVOID) & tInfo, sizeof (FNARGS), NULL);
LPVOID CodeMemAddr = VirtualAllocEx(hProc, NULL, CodeSize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(hProc, CodeMemAddr, (LPVOID) & ThreadFunc, CodeSize, NULL);
HANDLE hRemoteThread = CreateRemoteThread(hProc, NULL, 0, (LPTHREAD_START_ROUTINE)CodeMemAddr, hInfoMemAddr, 0, NULL);
WaitForSingleObject(hRemoteThread, INFINITE);
GetExitCodeThread(hRemoteThread, &hLibModule);
CloseHandle(hProc);
return 0;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
并不意外。 Vista 和 Windows 7 增强了安全性。许多恶意软件使用代码注入作为绕过 Windows XP 安全机制的步骤之一,我很高兴看到 Microsoft 修复了此问题。
Not really a surprise. Vista and Windows 7 have increased security. Lots of malware used Code Injection as one of the steps to bypass security mechanisms on Windows XP, and I'm glad to see Microsoft fixed this.