首页 > 编程问答 >C 和 Python 代码的函数的不同十六进制转储值

C 和 Python 代码的函数的不同十六进制转储值

时间:2024-08-05 16:36:36浏览次数:10  
标签:python c windows winapi dump

这是我的示例 C 代码,用于从 user32.dll 中转储 MessageBoxA

#include <windows.h>
#include <stdio.h>

void DumpFun(HANDLE process, LPVOID address, SIZE_T dump_size) {
    BYTE *buffer = (BYTE *)malloc(dump_size);
    if (buffer == NULL) {
        printf("Memory allocation failed\n");
        return;
    }

    SIZE_T bytes_read;
    if (ReadProcessMemory(process, address, buffer, dump_size, &bytes_read)) {
        printf("Dumping function bytes at address 0x%p:\n", address);
        for (SIZE_T i = 0; i < bytes_read; i++) {
            printf("%02X ", buffer[i]);
            if ((i + 1) % 16 == 0) printf("\n");
        }
        printf("\n");
    } else {
        printf("ReadProcessMemory failed with error %lu\n", GetLastError());
    }

    free(buffer);
}

int main() {
    HMODULE user32 = LoadLibraryA("user32.dll");
    if (!user32) {
        printf("Failed to load user32.dll\n");
        return 1;
    }

    FARPROC fun = GetProcAddress(user32, "MessageBoxA");
    if (!fun) {
        printf("Failed to get address of MessageBoxA\n");
        FreeLibrary(user32);
        return 1;
    }

    SIZE_T dump_size = 100;
    DumpFun(GetCurrentProcess(), fun, dump_size);
    FreeLibrary(user32);

    return 0;
}

这是输出:

Dumping function bytes at address 0x75C91600:
8B FF 55 8B EC 83 3D B4 6C CB 75 00 74 22 64 A1
18 00 00 00 BA FC 80 CB 75 8B 48 24 33 C0 F0 0F
B1 0A 85 C0 75 0A C7 05 20 6D CB 75 01 00 00 00
6A FF 6A 00 FF 75 14 FF 75 10 FF 75 0C FF 75 08
...

但是当我尝试使用此 python 代码时:

import ctypes
user32 = ctypes.WinDLL('user32.dll')
message_box_a = user32.MessageBoxA
message_box_a_addr = ctypes.cast(message_box_a, ctypes.c_void_p).value
print(f'Address of MessageBoxA: {hex(message_box_a_addr)}')
num_bytes = 100
buffer = (ctypes.c_ubyte * num_bytes)()
ctypes.memmove(buffer, message_box_a_addr, num_bytes)
byte_array = bytearray(buffer)
hex_bytes = ' '.join(f'{byte:02x}' for byte in byte_array)
print(f'Bytes of MessageBoxA: {hex_bytes}')

这是输出

Address of MessageBoxA: 0x7ffa2749a710
Bytes of MessageBoxA: 48 83 ec 38 45 33 db 44 39 1d 02 8c 03 00 74 2e 65 48 8b 04 25 30 00 00 00 4c 8b 50 48 33 c0 f0 4c 0f b1 15 78 97 03 00 4c 8b 15 79 97 03 00 41 8d 43 01 4c 0f 44 d0 4c 89 15 6a 97 03 00 83 4c 24 28 ff 66 44 89 5c 24 20 e8 e2 02 00 00 48 83 c4 38 c3 cc cc cc cc cc cc cc cc cc cc cc cc cc 48 83 ec 38

当我检查 user32.dll 时:


C 代码和 Python 代码都显示了 MessageBoxA 函数的内存转储,但它们之所以不同,是因为它们正在转储函数的不同方面:

  1. C 代码转储的是函数的 开头 ,更准确地说,是 GetProcAddress 返回的入口点。这个入口点通常包含一个短序言,后面是函数的实际代码。这就是在 C 代码输出中看到的序言:
8B FF 55 8B EC 83 3D ...

这些指令( 8B FF 55 8B EC )是典型的函数序言,用于设置堆栈帧并保存寄存器。

  1. Python 代码转储的是函数指针的值 ,该值被视为内存地址。这个地址指向包含函数代码的内存位置,但它 不一定是代码的开头 *。它可能是代码中一个稍后的点,尤其是在现代编译器和加载器中,它们出于性能或安全原因,可能会对代码进行重定位和优化。

这就是为什么在 Python 输出中看到的是不同的字节序列,它不以典型的函数序言开头:

48 83 ec 38 45 33 db ...

这些字节是 MessageBoxA 函数机器代码的一部分,但不是最开始的部分。

总结

  • 两种代码都显示了 MessageBoxA 函数的有效机器代码,但从不同的偏移量开始。
  • C 代码的输出更接近于函数在反汇编视图中的显示方式,因为它从入口点开始。
  • Python 代码的输出展示了函数代码在内存中的实际布局,这可能包括由于优化或重定位而导致的偏移。

为了使 Python 代码显示与 C 代码相同的初始字节,需要找到函数的实际入口点。这在一般情况下可能很困难,因为它需要解析 DLL 的结构和重定位表。

希望这能解释清楚!

标签:python,c,windows,winapi,dump
From: 78821190

相关文章

  • 是否有对数累积分布函数 (CDF) 和分位数函数的数值稳定的 Python 实现?
    我正在寻找以下函数的数值稳定实现。由于我的应用涉及t分布,所以我这里以t分布为例。LogCDF#NaivePythonimplementationofthefunctionIneedimportscipyimportnumpyasnpdeft_log_cdf(x,df):p=scipy.stats.t.cdf(x,df=df)returnnp.log(......
  • 如何将 *args 参数作为字符串传递给 Python 函数
    我正在使用pytubefix制作一个Youtube下载器。API允许我编写如下代码:YouTube(url).streams.filter(progressive=True)但是假设我有一个字符串存储在像args="progressive=True"这样的变量中,我如何使用args字符串来调用函数,就像......
  • 企业还会高薪招聘OCM证书获得者吗?
    从事Oracle数据库的人都知道,OCM证书的含金量比OCP证书的含金量要高很多,虽然OCM证书价值高,但由于考OCM的费用高、OCM技术难度大等等原因,OCM证书获得者比OCP证书获得者,人数少上很多。在很多情况下,公司仍会高薪招聘拥有OracleOCM证书的人员(下图为CUUG赵同学的OCM证书)。首先,......
  • tomcat10 springboot项目部署成功但springboot没有启动日志问题
    问题描述项目在tomcat8可以启动成功,请求也可以正常处理,在tomcat10上只有部署成功信息比如:deployWARDeploymentofwebapplicationarchive[/data1/WWW/webapps/XXX.war]hasfinishedin[127]ms,但是没有springboot启动的信息。该问题不属于springboot打包为war包不成......
  • Centos7 安装 Imc
    centos7安装imc注意:安装的时候必须选择图形化安装。即安装系统的时候,“软件选择”那块选择“带GUI的服务器”。关闭selinux和防火墙systemctlstopfirewalldsystemctldisablefirewalldsetenforce0sed-i"s/^SELINUX=enforcing/SELINUX=disabled/g"/etc/sysco......
  • 如何在linux系统上安装tomcat应用程序?
    1)首先查看安装包信息yuminfotomcatyuminfotomcat2)安装yum-yinstalltomcatyum-yinstalltomcat3)查看安装是否成功rpm-qtomcatrpm-qtomcat4)如果输出一下内容则代表安装成功tomcat-7.0.76-16.el7_9.noarch5)执行vi/etc/profile添加下列内容vi/etc......
  • 【Vitepress系列】-- 自定义组件及布局,配置tailwindcss、配置Markdown
    Vitepress自定义页面,以及配置tailwindcssvitepress中,除了使用一些配置项目,还可以通过写vue代码,来做一个定制化的UI。下面这个UI主页便是vue组件+tailwindcss做的一.自定义vitepress中,如果内置的home、doc、page不满足需求,还可以自己写vue代码进行自定义1.1自定义布......
  • centos下使用阿里云镜像安装docker
    环境:OS:Centos7步骤1:[[email protected]]#yuminstall-yyum-utilsdevice-mapper-persistent-datalvm2Loadedplugins:fastestmirror,langpacksLoadingmirrorspeedsfromcachedhostfileCouldnotretrievemirrorlisthttp://mirrorlist.centos.org/?......
  • Python Telegram Bot 从数据库获取数据时出错
    我正在开发用于管理企业用途任务的电报机器人。团队负责人注册他的公司并获得唯一的ID,然后可以分配任务。问题是,当团队负责人分配任务时,他可以使用/viewtasks访问它们。但是,当员工尝试查看任务时,它会打印出“错误。您尚未注册”。似乎无法检索与用户关联的company_id,即使......
  • DC-1靶机
    靶机下载下载后直接用vmware打开即可然后把靶机网络连接模式改为net,然后把攻击机也就是kail改为桥连或是net然后打开靶机停留在下面这个状态接下来你就可以开始渗透了第一步:找到靶机先扫一下网段(网段ifconfig看一下)nmap-sV10.204.11.0/24找到应该10.204.11.0是靶......