📜
PENETRATION NOTE
  • About
    • Readme
  • 收集信息
    • IP和端口信息
      • ASN
      • NMAP使用
      • 工具
      • 历史IP
    • 域名信息
      • CDN是否存在
      • 绕过CDN
      • DNS历史记录
      • SSL证书信息
      • Whois信息
    • 子域名检查
    • 网站架构和指纹识别
    • 人员信息
    • 其他信息
  • 初始访问
    • Web服务突破
      • 前端
      • SQL注入
        • 判断注入
        • 数据库类型识别
        • MSSQL
        • MYSQL
        • Oracle
        • PostgreSQL
        • SQLite
        • DB2
        • SQLMAP
      • XSS
      • CSRF
      • SSRF
      • XML
      • Xpath注入
      • SSTI
      • 命令执行
      • 命令注入
      • Fuzz目录
      • CmdHijack
      • 数据库
      • PHPstudy后门
      • PHP包含下载读取
      • PHP FPM之RCE
      • PHPMyAdmin利用
      • 绕过WAF
      • DNSLOG
      • IIS写权限
    • 未授权访问
      • hadoop
      • memcache
      • mongo
      • Redis
      • zookeeper
      • activemq
      • docker
      • elastic
      • jboss
      • VNC
      • Weblogic
      • Zabbix
      • CouchDB
      • Jenkins
      • Solr
    • 一些Bypass
      • Linux绕过disable_function
      • Open_basedir绕过
      • Windows系统组件com绕过
      • 常规函数绕过
      • 蚁剑绕过
      • cgi启动方式
      • ImageMagick组件绕过
    • 鱼叉式攻击
      • 钓鱼邮件
      • 钓鱼连接
      • 第三方鱼叉
    • 近源攻击
      • WI-FI破解
      • 无线干扰
      • 钓鱼网络
      • 克隆卡
      • 蓝牙
      • BadUSB
    • MySQL不登陆执行命令
    • MySQL开启外联
    • MySQL连接读取文件
    • MSSQL&Agent之Job上线
    • TomcatAjp之LFI&RCE
  • 防御规避
    • C#源码免杀
      • 直接编译
      • 加密处理
      • CSC+InstallUtil
      • XOR和AES编码
    • Powershell免杀
      • 直接生成
      • 行为检测
      • 分块免杀
      • 拆分+C编译
      • CobaltStrike+Powershell免杀
      • obfuscation
      • Out-EncryptedScript
      • PyFuscation
      • Xencrypt
      • Invoke-Shellcode
    • Python源码免杀
      • pyinstaller加载C代码编译
      • pyinstaller加载py代码编译
      • 加载器分离
      • Base64编码+Pyinstaller打包
    • MSF+shellcode免杀
      • nps_payload
      • 编码器
      • c和c++源码免杀
    • 加载器免杀
      • shellcode_launcher
      • SSI加载
    • GreatSCT
    • hanzoInjection
    • InstallUtil
    • MSBuilt
    • MSF捆绑
    • Mshta
    • Phantom-Evasion
    • RC4
    • Ruby
    • Shellter
    • the backdoor factory
    • Veil
    • zirikatu
    • 捆绑器
    • avet
    • carboncopy
    • c代码加载图片马
    • DLL劫持
    • Evasion模块
    • Golang
  • 权限提升
    • Windows提权
      • RDP&Firewall
        • RDP连接记录
        • 注册表开启
        • 注入点开启
        • MSF开启
        • wmic开启
        • 防火墙
        • 爆破RDP
        • 多用户登陆
        • 删除痕迹
      • impactet工具包
      • Windows exploit suggester
      • Searchsploit
      • watson
      • 激活guest
      • MSF
      • 本机文件和脚本
      • BypassUAC
      • AppLocker
      • PowerUp
      • Powerup AlwaysInstallElevated
      • AlwaysInstallElevated提权
      • MSSQL
      • MYSQL udf
      • PrintNightmare
      • HiveNightmare
      • Wesng
      • CVE-2020-1472
      • DNS组到DomainAdmin
      • SeImpersonatePrivilege
      • SpoolFool
      • Trusted Service Paths
      • Vulnerable Services
      • Whitelist白名单
      • 令牌窃取
      • 密码窃取
      • 弱注册表权限
      • RottenPotato
      • JuicyPotato
      • RoguePotato
      • EFSPotato
      • Runas
      • SamAccountSpoofing
      • SeBackupPrivilege
      • DLL劫持
      • WSL子系统
      • 不安全的GUI应用程序
      • 从administrator到system
      • 打印机漏洞
      • 服务中的不正确权限
      • 环境变量优先
      • 恢复服务帐户的权限
      • 弱权限的PATH目录
      • 特权文件写入
      • 未引用的服务路径
    • Linux提权
      • MYSQL Linux Root
      • 可写文件提权
      • Sudo提权
      • 查找辅助信息
      • 查找可能泄露的密码
      • 环境变量提权
      • 漏洞提权
      • 通配符提权
      • 一些检测工具
      • MYSQL漏洞
      • LD_Preload提权
      • Linux Exploit Suggester
      • LinuxSUID提权
      • Linux计划任务
      • Lxd提权
  • 文件操作
    • 传输
      • php
      • powershell
      • py
      • scp
      • vbs
      • wget
      • bitsadmin
      • certutil
      • curl
      • ftp
      • js
      • nc
      • perl
    • 创建
    • Windows查找文件
    • Linux查找文件
    • 查找可写目录
    • 解压
    • 压缩
  • 内网和域
    • 信息搜集
      • Windows安全标识符SID
      • 临时HTTP服务架设
      • Cmd
      • Wmi
      • Powershell基础操作
      • Powerview
      • Linux
      • ADDomain
      • BloodHoundAD
    • 端口映射和转发
      • iptables
      • lcx
      • msf
      • netsh
      • ssf
      • ssh
      • Ligolo
      • chisel
    • 命令与控制
      • Metasploit
        • 常规使用
        • 细节使用
        • meterpreter
        • 模块
        • 与cs和empire交互
      • CobaltStrike
        • 安装
        • 部署
        • 连接
        • 监听
        • 模块
        • 交互
        • 攻击模块
        • 视图模块
        • Beacon
        • 钓鱼邮件
        • 隔离网络
        • 权限维持
        • 代理
        • Malleable C2
        • 部署VPN
        • 横向移动
        • 加载脚本
        • 克隆
        • 浏览器劫持
        • 与msf和empire交互
        • 上线提醒
        • office宏
      • Empire
        • 安装
        • 生成
        • 监听
        • 模块
        • 连接靶机及其他操作
        • 权限提升
        • 横向移动
        • 后门
        • 与cs和msf交互
        • Empire_Word
      • 下载并执行
      • DNS TXT Command
      • Dropbox
      • Gmail
      • Jsrat
      • koadic
      • Openssl
      • Powershell
      • SILENTTRINITY
      • telegram
      • 反弹shell
      • 交互式shell
      • browser
      • crackmap
      • 工具
      • dnscat
  • HASH操作
    • mimikatz
      • mimikatz
      • mimipenguin
      • Powershell_Bypass
      • Procdump64+mimikatz
      • SqlDumper+mimikatz
      • 调用mimikatz远程抓取
      • 横向批量抓HASH
      • 绕过卡巴斯基
      • 远程LSASS进程转储 Physmem2profit
      • Cisco_Jabber转储lsass
      • dotnet2.0
      • dotnet4.0Msbuild
      • Dumpert
      • JScript
    • 域HASH提取
      • NTDSDumpex
      • Ntdsutil
      • Powersploit
      • Vssadmin
      • Wmivssadmin
      • impacket工具包
      • mimikatz
      • MSF
      • esentutl
      • Nishang脚本
    • 缓存HASH获取
      • Quarks pwdump
      • 注册表
      • Ninjacopy
    • 获取其他密码
      • foxmail
      • navicat
      • seatbelt
      • securecrt
      • vncpass
      • chrome
      • firefox
    • 破解工具
      • medusa
      • hydra
    • GoogleColab破解HASH
    • Invoke Dcsync
    • laZagne
    • MSF
    • QuarksPwDump
    • 开启Wdigest
    • 密码策略
    • 密码破解网站
    • Empire
    • Getpass
  • 横向移动
    • 探测存活主机
      • For+Ping命令查询存活主机
      • NbtScan
      • NetDiscover
      • NMAP
      • rp scan
      • 代理nmap扫描
      • 内外网资产对应
      • MSF
    • 探测服务&端口
      • 常见端口
      • MSF
      • Nc
      • Powershell
      • PTScan
      • SMB
      • CobaltStrike+K8Aggressor
      • Linux_Samba服务
      • Masscan
    • 执行命令&IPC&计划任务
      • AT
      • IPC
      • Schtasks
      • Wmic
    • 代理
      • goproxy
      • shadowsocks
      • sock4a
      • socks5
      • socks5web
      • ssf
      • ssh
      • 代理软件
      • chisel
      • earthworm
      • revsocks
      • Gost
      • gotohttp
      • rustdesk
      • frp
    • NTLM中继和中间人攻击
      • Ntlmrelayx+资源受限委派
      • Responder/LLMNR毒害
      • DNS Poisonning
      • MS08-068 NTLM反射
      • RemotePotato0
      • SMB签名禁用和IPv4
      • SMB签名禁用和IPv6
      • WebDav中继
      • 捕获和破解Net NTLMv1和NTLMv1哈希
      • CVE-2019-1040
      • CVE-2019-1384
    • ActiveDirectory的ACL和ACE
      • GenericAll
      • GenericWrite
      • WriteDACL
      • WriteOwner
      • 读取GMSA密码
      • 读取LAPS密码
      • 强制更改密码
    • ActiveDirectory证书服务
      • ESC1-配置错误的证书模板
      • ESC2-配置错误的证书模板
      • ESC3-配置错误的注册代理模板
      • ESC4-访问控制漏洞
      • ESC6-EDITF_ATTRIBUTESUBJECTALTNAME2
      • ESC7-易受攻击的证书颁发机构访问控制
      • ESC8-ADCS中继攻击
      • Pass-The-Certificate
      • 查找证书服务器
      • 经过认证的CVE-2022-26923
    • DCOM-Exploitation
      • DCOM
      • 通过MMC应用程序类进行DCOM
      • 通过Office进行DCOM
      • 通过ShellBrowserWindow进行DCOM
      • 通过ShellExecute进行DCOM
    • Kerberoasting
      • 申请票据
      • 破解密码
      • 导出票据
      • SPN发现
      • GetUserSPNs
      • 重写票据
    • MSF添加路由
    • Ngrok内网穿透
    • PASS-THE-HASH
    • PASS-THE-TICKET
    • PASS-THE-KEY
    • 组策略对象GPO
    • WinRM无文件执行
    • 方程式内网不产生session
    • 隔离主机payload
    • 攻击MSSQL数据库
    • 攻击MySQL数据库
    • 共享
    • 获取保存的RDP密码
    • 快速定位域管理登过的机器
    • 添加域管命令
    • ASEPRoasting
    • CVE-2019-0708
    • GPP-Password
    • MS08_067
    • MS17_010
    • MSF管道监听
    • 账户委派
    • 资源受限委派
    • 域内爆破
    • 危险的内置组使用
    • 域与域
    • kerberos青铜比特攻击CVE-2020-17049
    • kerberos无约束委派
    • kerberos约束委派
    • 基于kerberos资源的约束委派
    • PrivExchange攻击
    • PXE启动映像攻击
    • RODC-只读域控制器入侵
    • WSUS部署
    • SCCM部署
  • 权限维持
    • Windows
      • 关闭防病毒软件
      • 启动文件夹
      • DLL劫持计划任务
      • DLL注入
      • DSRM+注册表ACL后门
      • Empire
      • Guest激活
      • HookPasswordChangeNotify
      • Invoke ADSBackdoor
      • Invoke Tasks后门&权限维持
      • Kerberoasting后门
      • Metsvc
      • MOF
      • Shadow-Credentials
      • ADS&JavaScript
      • ADS隐藏webshell
      • Bitadmin
      • CLR Injection
      • COM OBJECT hijacking
      • DCShadow&SIDHistory
      • DCSync后门
      • DLL代理劫持右键
      • DLL劫持
      • Persistence
      • RID劫持
      • rootkit
      • RPC后门
      • S4U2Self后门
      • Skeleton Key万能钥匙
      • Squibledoo
      • Windows FAX DLL Injection
      • WinRM端口复用
      • WMIC事件订阅
      • WMI Persistence
      • 创建服务
      • 登录初始化
      • MSSQL后门
      • Netsh Helper DLL
      • NPPSpy记录密码
      • NSSM
      • Password Filter DLL
      • 添加签名
      • 通过控制面板加载项维持权限
      • 通过自定义.net垃圾回收机制进行DLL注入
      • 唯一IP访问
      • 影子用户
      • 映像劫持
      • 注入SSP被动收集密码
      • 基于域策略文件权限后门
      • 计划任务
      • 进程注入
      • 使用AMSI扫描接口维持权限
      • 受限委派后门
    • Linux
      • apt后门
      • bash rc
      • Kbeast_rootkit
      • Linux cron后门
      • OpenSSH后门
      • Reptile
      • SSHD后门
      • SSH wrapper后门
      • SSH公私钥登录
      • Strace记录ssh密码
      • SUID Shell
      • 进程注入
      • 文件处理
      • 用户启动文件
      • 启动项服务后门
      • 后门驱动程序
      • IPTables端口复用
    • web服务&中间件
      • Java
      • Nginx
      • Apache
      • IIS
  • 赏金技巧
    • TOP系列
      • Top25LFI参数
      • Top25RCE参数
      • Top25ssrf
      • Top25重定向dorks
    • 一行命令
      • 一条正则命令获取私钥或密码
      • 使用grep快速去除垃圾数据
    • 字典
      • 从站点生成字典
      • 来自github的字典
      • 已泄露的密码整理出的字典
      • loT高频率账户密码
      • 查找git和svn的字典
    • 403 bypass
    • CMS
    • favico信息
    • Github
    • git和svn
    • sql注入检测
    • 参数污染
    • 测试是否存在heartbleed漏洞
    • 命令注入Bypass
    • 配置错误的云存储桶
    • 通过.json的信息泄露
    • 未认证的ElasticsearchDB
    • 子域名接管
    • 2FA双因子认证绕过
    • 绕过登录限制
  • 云安全
    • GCP
      • 初始访问
      • 枚举
      • 权限维持
      • 特权升级和横向移动
    • AWS
      • AWS的服务
      • 工具
      • 初始访问
      • 枚举
      • 权限提升
      • 权限维持
      • 将EBS卷挂载到EC2Linux
      • 禁用CloudTrail
      • 使用AMI映像复制EC2
      • 通过API密钥获得AWS控制台访问权限
      • 通过混淆Cloudtrail日志和GuardDuty来掩盖踪迹
      • Golden SAML Attack
      • InstanceConnect 将SSH密钥推送到EC2实例
      • Lambda 提取函数的代码
      • Shadow Copy attack
      • SSM 命令执行
      • 动态数据库
    • Azure
      • 侦察工具
      • 枚举
      • 钓鱼
      • 非法同意
      • 向所有EnterpriseApplications添加凭据
      • 为AzureWeb应用程序生成SSH
      • Azure存储Blob
      • Pass-The-PRT
      • Pass-The-Certificate
      • Intunes管理
      • 动态组成员资格
      • Administrative Unit
      • 部署模板
      • 应用程序代理
      • 条件访问
      • 令牌
      • 自动化runbook
      • 虚拟机runCommand
      • KeyVault
      • AzureAD
      • AzureAD连接
    • Aliyun
      • osskey
    • Docker
      • 未授权API
      • 权限维持
      • 逃逸
    • kubernetes
      • 未授权API
      • 枚举
      • 权限提升
      • 定时任务
    • 工具
  • Redteam红队
    • Web类
      • web程序漏洞
      • 编辑器漏洞
      • 默认密码
      • wso2
      • 从LFI到RCE
      • 深x服
      • 天r信
      • 邮件地址payload
      • Web server日志分析命令
    • 免杀技巧
      • cshot远程shellcode
      • Pezor免杀
      • 内存中解码shellcode绕过av
      • 一些可尝试绕过白名单的执行
      • 在Windows Server 2016和2019中绕过WindowsDefender
      • 绕过安全狗脚本
      • 360白名单
      • Bypass AMSI
    • Bypass技巧
      • Bypass mod_security
      • 绕过lsa protection
    • 系统类
      • ImportDLLInjection 通过修改内存中的PE头来注入DLL的另一种方法
      • 动态调用进程注入逻辑
      • 父进程破坏
      • 进程挖空(MitreT1055.012)
      • 使用WindowsDefender下载文件
      • 通过挂起EventLog服务线程禁用Windows事件日志
      • 隐藏windows服务
      • 远程解压文件
由 GitBook 提供支持
在本页

这有帮助吗?

  1. Redteam红队
  2. 系统类

ImportDLLInjection 通过修改内存中的PE头来注入DLL的另一种方法

将修改新创建进程内存中的 PE 标头,以将我们自己的 DLL 添加到导入描述符列表中
1 使用带有 CREATE_SUSPENDED 标志的 CreateProcess 创建目标 EXE 进程的挂起实例。
2 计算目标EXE的基地址,使用NtQueryInformationProcess读取目标进程的PEB地址,使用ReadProcessMemory读取ImageBaseAddress字段值。
3 使用 ReadProcessMemory 从目标进程读取主 PE 头(IMAGE_NT_HEADERS)。
4 为以后存储未修改的 IMAGE_NT_HEADERS 结构的副本。
5 在 PE 头 (ImageNtHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]) 内的导入描述符列表中添加一个额外的 DLL 条目。还需要在目标进程中分配模块路径、导入查找表和导入地址表。导入表将包括一个条目:序数 #1。
6 使用WriteProcessMemory 将更新的PE 头写回目标进程。
7 使用 ResumeThread 恢复目标进程的执行。
8 循环使用ReadProcessMemory 读取注入DLL 的新导入地址表。等到目标进程更新了单个导入(序数 #1)的地址。
9 DLL 现在已经被注入到目标进程中。释放任何临时内存并从第 4 步恢复原始 PE 标头。
#include <stdio.h>
#include <windows.h>

DWORD (WINAPI *NtQueryInformationProcess)(HANDLE ProcessHandle, DWORD ProcessInformationClass, PVOID ProcessInformation, DWORD ProcessInformationLength, DWORD *ReturnLength);

struct PROCESS_BASIC_INFORMATION
{
	DWORD ExitStatus;
	void *PebBaseAddress;
	DWORD AffinityMask;
	DWORD BasePriority;
	DWORD UniqueProcessId;
	DWORD InheritedFromUniqueProcessId;
};

DWORD LaunchTargetProcess(char *pExePath, HANDLE *phProcess, HANDLE *phProcessMainThread)
{
	PROCESS_INFORMATION ProcessInfo;
	STARTUPINFO StartupInfo;

	// initialise startup data
	memset((void*)&StartupInfo, 0, sizeof(StartupInfo));
	StartupInfo.cb = sizeof(StartupInfo);

	printf("Launching target process...\n");

	// create target process (suspended)
	memset((void*)&ProcessInfo, 0, sizeof(ProcessInfo));
	if(CreateProcess(NULL, pExePath, NULL, NULL, 0, CREATE_SUSPENDED, NULL, NULL, &StartupInfo, &ProcessInfo) == 0)
	{
		return 1;
	}

	// store handles
	*phProcess = ProcessInfo.hProcess;
	*phProcessMainThread = ProcessInfo.hThread;

	return 0;
}

DWORD InjectDll(HANDLE hProcess, HANDLE hProcessMainThread, char *pDllPath)
{
	IMAGE_DOS_HEADER ImageDosHeader;
	IMAGE_NT_HEADERS ImageNtHeader;
	IMAGE_NT_HEADERS ImageNtHeader_Original;
	PROCESS_BASIC_INFORMATION ProcessBasicInfo;
	DWORD dwExeBaseAddrPebPtr = 0;
	DWORD dwExeBaseAddr = 0;
	DWORD dwNtHeaderAddr = 0;
	DWORD dwDllPathLength = 0;
	void *pRemoteAlloc_DllPath = NULL;
	void *pRemoteAlloc_ImportLookupTable = NULL;
	void *pRemoteAlloc_ImportAddressTable = NULL;
	void *pRemoteAlloc_NewImportDescriptorList = NULL;
	DWORD dwImportLookupTable[2];
	DWORD dwExistingImportDescriptorEntryCount = 0;
	DWORD dwNewImportDescriptorEntryCount = 0;
	BYTE *pNewImportDescriptorList = NULL;
	IMAGE_IMPORT_DESCRIPTOR NewDllImportDescriptors[2];
	DWORD dwExistingImportDescriptorAddr = 0;
	BYTE *pCopyImportDescriptorDataPtr = NULL;
	DWORD dwNewImportDescriptorListDataLength = 0;
	DWORD dwOriginalProtection = 0;
	DWORD dwOriginalProtection2 = 0;
	DWORD dwCurrentImportAddressTable[2];

	printf("Reading image base address from PEB...\n");

	// get process info
	memset(&ProcessBasicInfo, 0, sizeof(ProcessBasicInfo));
	if(NtQueryInformationProcess(hProcess, 0, &ProcessBasicInfo, sizeof(ProcessBasicInfo), NULL) != 0)
	{
		return 1;
	}

	// get target exe base address from PEB
	dwExeBaseAddrPebPtr = (DWORD)ProcessBasicInfo.PebBaseAddress + 8;
	if(ReadProcessMemory(hProcess, (void*)dwExeBaseAddrPebPtr, (void*)&dwExeBaseAddr, sizeof(DWORD), NULL) == 0)
	{
		return 1;
	}

	printf("Reading PE headers...\n");

	// read PE header from target process
	memset((void*)&ImageDosHeader, 0, sizeof(ImageDosHeader));
	if(ReadProcessMemory(hProcess, (void*)dwExeBaseAddr, (void*)&ImageDosHeader, sizeof(ImageDosHeader), NULL) == 0)
	{
		return 1;
	}

	// read NT header from target process
	dwNtHeaderAddr = dwExeBaseAddr + ImageDosHeader.e_lfanew;
	memset((void*)&ImageNtHeader, 0, sizeof(ImageNtHeader));
	if(ReadProcessMemory(hProcess, (void*)dwNtHeaderAddr, (void*)&ImageNtHeader, sizeof(ImageNtHeader), NULL) == 0)
	{
		return 1;
	}

	// save a copy of the original NT header
	memcpy((void*)&ImageNtHeader_Original, (void*)&ImageNtHeader, sizeof(ImageNtHeader_Original));

	// calculate dll path length
	dwDllPathLength = strlen(pDllPath) + 1;

	// allocate buffer for the dll path in the remote process
	pRemoteAlloc_DllPath = VirtualAllocEx(hProcess, NULL, dwDllPathLength, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
	if(pRemoteAlloc_DllPath == NULL)
	{
		return 1;
	}

	// write dll path to remote process buffer
	if(WriteProcessMemory(hProcess, (void*)pRemoteAlloc_DllPath, pDllPath, dwDllPathLength, NULL) == 0)
	{
		return 1;
	}

	// set import lookup table values (import ordinal #1)
	dwImportLookupTable[0] = 0x80000001;
	dwImportLookupTable[1] = 0;

	// allocate buffer for the new import lookup table in the remote process
	pRemoteAlloc_ImportLookupTable = VirtualAllocEx(hProcess, NULL, sizeof(dwImportLookupTable), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
	if(pRemoteAlloc_ImportLookupTable == NULL)
	{
		return 1;
	}

	// write import lookup table to remote process buffer
	if(WriteProcessMemory(hProcess, (void*)pRemoteAlloc_ImportLookupTable, (void*)dwImportLookupTable, sizeof(dwImportLookupTable), NULL) == 0)
	{
		return 1;
	}

	// allocate buffer for the new import address table in the remote process
	pRemoteAlloc_ImportAddressTable = VirtualAllocEx(hProcess, NULL, sizeof(dwImportLookupTable), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
	if(pRemoteAlloc_ImportAddressTable == NULL)
	{
		return 1;
	}

	// write import address table to remote process buffer (initially the same values as the import lookup table)
	if(WriteProcessMemory(hProcess, (void*)pRemoteAlloc_ImportAddressTable, (void*)dwImportLookupTable, sizeof(dwImportLookupTable), NULL) == 0)
	{
		return 1;
	}

	// set import descriptor values for injected dll
	NewDllImportDescriptors[0].OriginalFirstThunk = (DWORD)pRemoteAlloc_ImportLookupTable - dwExeBaseAddr;
	NewDllImportDescriptors[0].TimeDateStamp = 0;
	NewDllImportDescriptors[0].ForwarderChain = 0;
	NewDllImportDescriptors[0].Name = (DWORD)pRemoteAlloc_DllPath - dwExeBaseAddr;
	NewDllImportDescriptors[0].FirstThunk = (DWORD)pRemoteAlloc_ImportAddressTable - dwExeBaseAddr;

	// end of import descriptor chain
	NewDllImportDescriptors[1].OriginalFirstThunk = 0;
	NewDllImportDescriptors[1].TimeDateStamp = 0;
	NewDllImportDescriptors[1].ForwarderChain = 0;
	NewDllImportDescriptors[1].Name = 0;
	NewDllImportDescriptors[1].FirstThunk = 0;

	// calculate existing number of imported dll modules
	dwExistingImportDescriptorEntryCount = ImageNtHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size / sizeof(IMAGE_IMPORT_DESCRIPTOR);

	if(dwExistingImportDescriptorEntryCount == 0)
	{
		// the target process doesn't have any imported dll entries - this is highly unusual but not impossible
		dwNewImportDescriptorEntryCount = 2;
	}
	else
	{
		// add one extra dll entry
		dwNewImportDescriptorEntryCount = dwExistingImportDescriptorEntryCount + 1;
	}

	// allocate new import description list (local)
	dwNewImportDescriptorListDataLength = dwNewImportDescriptorEntryCount * sizeof(IMAGE_IMPORT_DESCRIPTOR);
	pNewImportDescriptorList = (BYTE*)malloc(dwNewImportDescriptorListDataLength);
	if(pNewImportDescriptorList == NULL)
	{
		return 1;
	}

	if(dwExistingImportDescriptorEntryCount != 0)
	{
		// read existing import descriptor entries
		dwExistingImportDescriptorAddr = dwExeBaseAddr + ImageNtHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
		if(ReadProcessMemory(hProcess, (void*)dwExistingImportDescriptorAddr, pNewImportDescriptorList, dwExistingImportDescriptorEntryCount * sizeof(IMAGE_IMPORT_DESCRIPTOR), NULL) == 0)
		{
			free(pNewImportDescriptorList);
			return 1;
		}
	}

	// copy the new dll import (and terminator entry) to the end of the list
	pCopyImportDescriptorDataPtr = pNewImportDescriptorList + dwNewImportDescriptorListDataLength - sizeof(NewDllImportDescriptors);
	memcpy(pCopyImportDescriptorDataPtr, (void*)NewDllImportDescriptors, sizeof(NewDllImportDescriptors));

	// allocate buffer for the new import descriptor list in the remote process
	pRemoteAlloc_NewImportDescriptorList = VirtualAllocEx(hProcess, NULL, dwNewImportDescriptorListDataLength, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
	if(pRemoteAlloc_NewImportDescriptorList == NULL)
	{
		free(pNewImportDescriptorList);
		return 1;
	}

	// write new import descriptor list to remote process buffer
	if(WriteProcessMemory(hProcess, (void*)pRemoteAlloc_NewImportDescriptorList, pNewImportDescriptorList, dwNewImportDescriptorListDataLength, NULL) == 0)
	{
		free(pNewImportDescriptorList);
		return 1;
	}

	// free local import descriptor list buffer
	free(pNewImportDescriptorList);

	printf("Updating PE headers...\n");

	// change the import descriptor address in the remote NT header to point to the new list
	ImageNtHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = (DWORD)pRemoteAlloc_NewImportDescriptorList - dwExeBaseAddr;
	ImageNtHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size = dwNewImportDescriptorListDataLength;

	// make NT header writable
	if(VirtualProtectEx(hProcess, (LPVOID)dwNtHeaderAddr, sizeof(ImageNtHeader), PAGE_EXECUTE_READWRITE, &dwOriginalProtection) == 0)
	{
		return 1;
	}

	// write updated NT header to remote process
	if(WriteProcessMemory(hProcess, (void*)dwNtHeaderAddr, (void*)&ImageNtHeader, sizeof(ImageNtHeader), NULL) == 0)
	{
		return 1;
	}

	printf("Resuming process...\n");

	// resume target process execution
	ResumeThread(hProcessMainThread);

	printf("Waiting for target DLL...\n");

	// wait for the target process to load the DLL
	for(;;)
	{
		// read the IAT table for the injected DLL
		memset((void*)dwCurrentImportAddressTable, 0, sizeof(dwCurrentImportAddressTable));
		if(ReadProcessMemory(hProcess, (void*)pRemoteAlloc_ImportAddressTable, (void*)dwCurrentImportAddressTable, sizeof(dwCurrentImportAddressTable), NULL) == 0)
		{
			return 1;
		}

		// check if the IAT table has been processed
		if(dwCurrentImportAddressTable[0] == dwImportLookupTable[0])
		{
			// IAT table for injected DLL not yet processed - try again in 100ms
			Sleep(100);

			continue;
		}

		// DLL has been loaded by target process
		break;
	}

	printf("Restoring original PE headers...\n");

	// restore original NT headers in target process
	if(WriteProcessMemory(hProcess, (void*)dwNtHeaderAddr, (void*)&ImageNtHeader_Original, sizeof(ImageNtHeader), NULL) == 0)
	{
		return 1;
	}

	// restore original protection value for remote NT headers
	if(VirtualProtectEx(hProcess, (LPVOID)dwNtHeaderAddr, sizeof(ImageNtHeader), dwOriginalProtection, &dwOriginalProtection2) == 0)
	{
		return 1;
	}

	// free temporary memory in remote process
	VirtualFreeEx(hProcess, pRemoteAlloc_DllPath, 0, MEM_RELEASE);
	VirtualFreeEx(hProcess, pRemoteAlloc_ImportLookupTable, 0, MEM_RELEASE);
	VirtualFreeEx(hProcess, pRemoteAlloc_ImportAddressTable, 0, MEM_RELEASE);
	VirtualFreeEx(hProcess, pRemoteAlloc_NewImportDescriptorList, 0, MEM_RELEASE);

	return 0;
}

int main(int argc, char *argv[])
{
	HANDLE hProcess = NULL;
	HANDLE hProcessMainThread = NULL;
	char *pExePath = NULL;
	char *pInjectDllPath = NULL;
	char szInjectDllFullPath[512];

	printf("ImportDLLInjection - www.x86matthew.com\n\n");

	if(argc != 3)
	{
		printf("Usage: %s [exe_path] [inject_dll_path]\n\n", argv[0]);

		return 1;
	}

	// get params
	pExePath = argv[1];
	pInjectDllPath = argv[2];

	// get full path from dll filename
	memset(szInjectDllFullPath, 0, sizeof(szInjectDllFullPath));
	if(GetFullPathName(pInjectDllPath, sizeof(szInjectDllFullPath) - 1, szInjectDllFullPath, NULL) == 0)
	{
		printf("Invalid DLL path\n");

		return 1;
	}

	// get NtQueryInformationProcess function ptr
	NtQueryInformationProcess = (unsigned long (__stdcall *)(void *,unsigned long,void *,unsigned long,unsigned long *))GetProcAddress(GetModuleHandle("ntdll.dll"), "NtQueryInformationProcess");
	if(NtQueryInformationProcess == NULL)
	{
		printf("Failed to find NtQueryInformationProcess function\n");

		return 1;
	}

	// launch target process
	if(LaunchTargetProcess(pExePath, &hProcess, &hProcessMainThread) != 0)
	{
		printf("Failed to launch target process\n");

		return 1;
	}

	// inject DLL into target process
	if(InjectDll(hProcess, hProcessMainThread, szInjectDllFullPath) != 0)
	{
		printf("Failed to inject DLL\n");

		// error
		TerminateProcess(hProcess, 0);
		CloseHandle(hProcessMainThread);
		CloseHandle(hProcess);

		return 1;
	}

	printf("Finished\n");

	// close handles
	CloseHandle(hProcessMainThread);
	CloseHandle(hProcess);

	return 0;
}
演示dll
#include <stdio.h>
#include <windows.h>

// a blank exported function - this will be ordinal #1
__declspec(dllexport) void __cdecl ExportedFunction(void)
{
}

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
{
	if(fdwReason == DLL_PROCESS_ATTACH)
	{
		// display a message box
		MessageBox(NULL, "MessageBox from injected DLL", "www.x86matthew.com", MB_OK);
	}

    return 1;
}
上一页系统类下一页动态调用进程注入逻辑

最后更新于3年前

这有帮助吗?