问题描述
我又回来了 - 感谢这里的好心人,尤其是@Jester 和@PeterCordes,我的四个目标平台中有三个正在运行.我有 Win 32 和 Win 64 工作,我有 OS X 64 工作,但我似乎无法使用 libc 库使 OS X 程序集在 32 位工作.
我可以使用系统调用(64 位)和 int 0x80(32 位)来做一个hello world"和其他事情,我可以让 _printf 在 64 位下工作,但我无法做到以 32 位工作.
理论上,我需要将参数压入堆栈,然后16字节对齐堆栈,但是我运行代码时出现了segmentation fault: 11 error.
8 节 .data910 hello db "Hello, world", 0x0a, 0x001112节.text1314 全局_main15 extern _printf, _exit1617 _主要:18推你好19 子 esp, 12 ;16 字节对齐堆栈20 调用_printf2122 添加 esp, 16 ;撤消堆栈对齐23 推 024 子 esp, 12 ;16 字节对齐堆栈25 调用_exit
我在没有堆栈对齐代码的情况下尝试过,但遇到了同样的错误.我在网上找到了各种示例,但我无法使它们工作,我什至使用 GCC 来输出 Intel 语法汇编程序,但我无法将其转换为 nasm.
我使用 nasm 是因为它适用于 Windows、OS X 和 Linux,所以我只需要学习一种汇编语法.
我意识到所有英特尔 Mac 都是 64 位的,但它们可以运行 32 位代码,所以我希望能够遵循并理解它.这一切都是为了帮助我对恶意软件进行逆向工程.
谢谢
函数总是在返回地址上方寻找它们的参数.如果您在推送某些内容后 sub esp, 12
,参数包含 12 字节的垃圾.
此外,12 是错误的空间量.ESP 是 16 字节对齐的之前调用
,根据 ABI,所以堆栈 args 的开始是 16 字节对齐的.但是 call
会推送一个返回地址,因此函数入口 ESP+4
和 ESP-12
是最近的对齐边界.
sub esp,12
在 main
的顶部会将堆栈对齐 16.但是你也做了另一个 push
,这也在 call
您的 2 个选项是 sub esp, 8
/push hello
或 sub esp,12
/mov dword [esp], hello
.
_main: ;ESP 是 16 字节对齐的 *before* 调用推送返回地址子 esp, 8 ;将 ESP 提高到对齐边界上方 4 个字节推你好;ESP 现在是 16 字节对齐的.调用_printfmov dword [esp], 0 ;推迟弹出堆栈呼叫 _exit;添加 esp, 4+8 ;弹出参数+填充.但退出不返回;返回.rodata 节;你不需要写这个字符串,所以把它放在rodata你好数据库你好,世界",0x0a,0x00
所有的 Intel Mac 都是 64 位的
不完全正确:第一代 Intel macs 使用 Intel Core CPU(基本上是 Pentium-M),而不是 Core2.如果他们等上一代,他们就永远不需要关心 32 位.
尽管在这一点上,我认为分发不能在仅 32 位 OS X 上运行的二进制文件被认为是安全的.
I'm back again - thanks to the kind folks here, especially @Jester and @PeterCordes, I have three out of my four target platforms working. I have Win 32 and Win 64 working, and I have OS X 64 working, but I can't seem to make OS X assembly work in 32-bit using the libc library.
I can do a "hello world" and other things using syscall (64-bit) and int 0x80 (32-bit), and I can make _printf work in 64-bit, but I can't manage to make it work in 32-bit.
In theory, I need to push the parameters onto the stack and then 16-byte align the stack, but I get a segmentation fault: 11 error when I run the code.
8 section .data
9
10 hello db "Hello, world", 0x0a, 0x00
11
12 section .text
13
14 global _main
15 extern _printf, _exit
16
17 _main:
18 push hello
19 sub esp, 12 ; 16-byte align stack
20 call _printf
21
22 add esp, 16 ; undo stack alignment
23 push 0
24 sub esp, 12 ; 16-byte align stack
25 call _exit
I've tried it without the stack aligning code and I get the same error. I've found various samples online and I could not make them work, and I've even done the trick with using GCC to output Intel-syntax assembler and I could not manage to translate it to nasm.
I'm using nasm because it works on Windows, OS X, and Linux, so that way I only need to learn one assembler syntax.
I realize that all the Intel Macs are 64-bit, but they can run 32-bit code so I want to be able to follow it and understand it. This is all aimed at helping me reverse-engineer malware.
Thanks
Functions always look for their arguments just above the return address. If you sub esp, 12
after pushing something, the args include 12 bytes of garbage.
Also, 12 is the wrong amount of space. ESP is 16-byte aligned before a call
, according to the ABI, so the start of the stack args is 16-byte aligned. But call
pushes a return address, so on entry to a function ESP+4
and ESP-12
are the nearest alignment boundaries.
sub esp,12
at the top of main
would align the stack by 16. But you doing another push
as well, which also moves ESP before call
Your 2 options are sub esp, 8
/ push hello
orsub esp,12
/ mov dword [esp], hello
.
_main: ; ESP was 16-byte aligned *before* call pushed a return address
sub esp, 8 ; get ESP to 4 bytes above an alignment boundary
push hello ; ESP is now 16-byte aligned.
call _printf
mov dword [esp], 0 ; defer popping the stack
call _exit
;add esp, 4+8 ; pop args+padding. But exit doesn't return
;ret
section .rodata ; You don't need to write this string, so put it in rodata
hello db "Hello, world", 0x0a, 0x00
Not strictly true: the very first gen Intel macs used Intel Core CPUs (basically Pentium-M), not Core2. If they'd waited one generation, they never would have needed to care much about 32bit.
Although at this point, I assume it's considered safe to distribute binaries that don't work on 32bit-only OS X.
这篇关于来自汇编程序的 os x 32 位 printf的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!