- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv) {
char buff[15];
int auth = 0;
printf("\nEnter password: ");
gets(buff);
if (strcmp(buff, "password") != 0) {
printf("\nAccess denied\n");
} else {
auth = 1;
}
if (auth) {
printf("\nAccess granted\n");
}
return 0;
}
这段代码需要16个字节(用户输入的字符)才能在x86上溢出auth
并打印“Access granted”。在 x64 上,需要 29 个字节才能执行相同的操作。为什么是这样?似乎我的变量之间有一些填充,或者它们之间有其他东西的地址。我不相信这是阴影空间的影响(这是否也适用于 *nix?),因为只保留前 32 个字节 https://en.wikipedia.org/wiki/X86_calling_conventions#Microsoft_x64_calling_convention
请注意,我没有通过任何优化来编译它以避免寄存器内部的东西。
我在 OS X 上使用 GCC 6.2.0。这是 x86 版本的程序集输出:
.cstring
LC0:
.ascii "\12Enter password: \0"
LC1:
.ascii "password\0"
LC2:
.ascii "\12Access denied\0"
LC3:
.ascii "\12Access granted\0"
.text
.globl _main
_main:
LFB1:
pushl %ebp
LCFI0:
movl %esp, %ebp
LCFI1:
pushl %ebx
subl $36, %esp
LCFI2:
call ___x86.get_pc_thunk.bx
L1$pb:
movl $0, -12(%ebp)
subl $12, %esp
leal LC0-L1$pb(%ebx), %eax
pushl %eax
call _printf
addl $16, %esp
subl $12, %esp
leal -27(%ebp), %eax
pushl %eax
call _gets
addl $16, %esp
subl $8, %esp
leal LC1-L1$pb(%ebx), %eax
pushl %eax
leal -27(%ebp), %eax
pushl %eax
call _strcmp
addl $16, %esp
testl %eax, %eax
je L2
subl $12, %esp
leal LC2-L1$pb(%ebx), %eax
pushl %eax
call _puts
addl $16, %esp
jmp L3
L2:
movl $1, -12(%ebp)
L3:
cmpl $0, -12(%ebp)
je L4
subl $12, %esp
leal LC3-L1$pb(%ebx), %eax
pushl %eax
call _puts
addl $16, %esp
L4:
movl $0, %eax
movl -4(%ebp), %ebx
leave
LCFI3:
ret
LFE1:
.section __TEXT,__textcoal_nt,coalesced,pure_instructions
.weak_definition ___x86.get_pc_thunk.bx
.private_extern ___x86.get_pc_thunk.bx
___x86.get_pc_thunk.bx:
LFB2:
movl (%esp), %ebx
ret
LFE2:
.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
EH_frame1:
.set L$set$0,LECIE1-LSCIE1
.long L$set$0
LSCIE1:
.long 0
.byte 0x1
.ascii "zR\0"
.byte 0x1
.byte 0x7c
.byte 0x8
.byte 0x1
.byte 0x10
.byte 0xc
.byte 0x5
.byte 0x4
.byte 0x88
.byte 0x1
.align 2
LECIE1:
LSFDE1:
.set L$set$1,LEFDE1-LASFDE1
.long L$set$1
LASFDE1:
.long LASFDE1-EH_frame1
.long LFB1-.
.set L$set$2,LFE1-LFB1
.long L$set$2
.byte 0
.byte 0x4
.set L$set$3,LCFI0-LFB1
.long L$set$3
.byte 0xe
.byte 0x8
.byte 0x84
.byte 0x2
.byte 0x4
.set L$set$4,LCFI1-LCFI0
.long L$set$4
.byte 0xd
.byte 0x4
.byte 0x4
.set L$set$5,LCFI2-LCFI1
.long L$set$5
.byte 0x83
.byte 0x3
.byte 0x4
.set L$set$6,LCFI3-LCFI2
.long L$set$6
.byte 0xc4
.byte 0xc3
.byte 0xc
.byte 0x5
.byte 0x4
.align 2
LEFDE1:
LSFDE3:
.set L$set$7,LEFDE3-LASFDE3
.long L$set$7
LASFDE3:
.long LASFDE3-EH_frame1
.long LFB2-.
.set L$set$8,LFE2-LFB2
.long L$set$8
.byte 0
.align 2
LEFDE3:
.subsections_via_symbols
对于 x64 版本:
.cstring
LC0:
.ascii "\12Enter password: \0"
LC1:
.ascii "password\0"
LC2:
.ascii "\12Access denied\0"
LC3:
.ascii "\12Access granted\0"
.text
.globl _main
_main:
LFB1:
pushq %rbp
LCFI0:
movq %rsp, %rbp
LCFI1:
subq $48, %rsp
movl %edi, -36(%rbp)
movq %rsi, -48(%rbp)
movl $0, -4(%rbp)
leaq LC0(%rip), %rdi
movl $0, %eax
call _printf
leaq -32(%rbp), %rax
movq %rax, %rdi
call _gets
leaq -32(%rbp), %rax
leaq LC1(%rip), %rsi
movq %rax, %rdi
call _strcmp
testl %eax, %eax
je L2
leaq LC2(%rip), %rdi
call _puts
jmp L3
L2:
movl $1, -4(%rbp)
L3:
cmpl $0, -4(%rbp)
je L4
leaq LC3(%rip), %rdi
call _puts
L4:
movl $0, %eax
leave
LCFI2:
ret
LFE1:
.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
EH_frame1:
.set L$set$0,LECIE1-LSCIE1
.long L$set$0
LSCIE1:
.long 0
.byte 0x1
.ascii "zR\0"
.byte 0x1
.byte 0x78
.byte 0x10
.byte 0x1
.byte 0x10
.byte 0xc
.byte 0x7
.byte 0x8
.byte 0x90
.byte 0x1
.align 3
LECIE1:
LSFDE1:
.set L$set$1,LEFDE1-LASFDE1
.long L$set$1
LASFDE1:
.long LASFDE1-EH_frame1
.quad LFB1-.
.set L$set$2,LFE1-LFB1
.quad L$set$2
.byte 0
.byte 0x4
.set L$set$3,LCFI0-LFB1
.long L$set$3
.byte 0xe
.byte 0x10
.byte 0x86
.byte 0x2
.byte 0x4
.set L$set$4,LCFI1-LCFI0
.long L$set$4
.byte 0xd
.byte 0x6
.byte 0x4
.set L$set$5,LCFI2-LCFI1
.long L$set$5
.byte 0xc
.byte 0x7
.byte 0x8
.align 3
LEFDE1:
.subsections_via_symbols
最佳答案
我又在考虑这个问题,想起了我在聊天中发给你的编译器标志:
-mpreferred-stack-boundary=num
特别是以下段落:
Attempt to keep the stack boundary aligned to a 2 raised to num byte boundary. If -mpreferred-stack-boundary is not specified, the default is 4 (16 bytes or 128 bits).
Warning: When generating code for the x86-64 architecture with SSE extensions disabled, -mpreferred-stack-boundary=3 can be used to keep the stack boundary aligned to 8 byte boundary. Since x86-64 ABI require 16 byte stack alignment, this is ABI incompatible and intended to be used in controlled environment where stack space is important limitation.
因此,15 字节的数组将需要 16 字节的堆栈槽以将其保存在堆栈边界内。
int auth
,假设一个 4 字节的 int
,也需要一个 16 字节的堆栈槽来遵守 gcc
的堆栈边界标志.用gdb
调试程序,我注意到int auth
地址是BSP-0x04
。 BSP-0x04
到 BSP-0x10
正在填充,因此适合堆栈槽。因此,要溢出缓冲区直到到达 int auth
,您需要 15 个字节(缓冲区大小)+ 1 个字节(缓冲区填充)+ 12 个字节(int auth
填充)+ 1 个字节到达 int
。
最后,我跟你提过,我在调试时发现了数组和 int
之间的地址。这可能是内存中残留的一些垃圾:由于程序不关心 int
之前的额外 12 个字节,它可能不会清理它,它可能被用来存储一些内存指针。
下面是 x64 代码程序堆栈的表示。
-------------------------------------------- ------
保存的 RBP
---------------------------------------------- ---- 新的 RBP = 0x7FFFFFFFFDD10
授权
---------------------------------------------- ---- RBP - 0x04 = 0x7FFFFFFFDD0C
auth 12 字节填充
---------------------------------------------- ---- RBP - 0x10 = 0x7FFFFFFFFDD00
buff 1 字节填充
---------------------------------------------- ---- RBP - 0x11 = 0x7FFFFFFFDCFF
增益
---------------------------------------------- ---- RBP - 0x20 = 0x7FFFFFFFDCF0
EDI 的值(value)
---------------------------------------------- ---- RBP - 0x24 = 0x7FFFFFFFDCEC
RSI 值
---------------------------------------------- ---- RBP - 0x30 = 0x7FFFFFFFDCE0 栈顶
关于c - 缓冲区溢出在 x86 上需要 16 个字节,但在 x64 上需要 29 个字节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41537314/
我有一个 div(蓝色框),它在父元素(红色框)内的页面上绝对定位,我需要将 overflow-y 设置为隐藏,以便它强制 Y 轴上的溢出内容切掉了,但我希望任何溢出-x 的内容都可见。 HTML:
请参阅以下帖子以获取突出显示我的问题和可能的解决方案的图片: CSS overflow-y:visible, overflow-x:scroll 但是,当您实际移动滚动条时,此策略会中断。在建议的实现
我在搜索中看到过几个类似的问题,但要么没有正确回答问题,要么没有给出答案。所以,我再问一次。 .parent { overflow-y:scroll; overflow-x:visible; wid
我读过这个CSS overflow-x hidden and overflow-y visible (以及很多其他帖子)但我无法在我的具体情况下使用它。 我正在使用 slick-slider并想添加下
我有以下 Spark 作业,试图将所有内容保留在内存中: val myOutRDD = myInRDD.flatMap { fp => val tuple2List: ListBuffer[(St
我有疑问 两个16位的值加上最大值,16位机会不会溢出? 我会详细说明 unsigned short a; unsigned short b; unsigned long c; c=(unsigne
我有这个 HTML 和 CSS,但“溢出:隐藏”标签在 Firefox 中不起作用。这让我感到难过...有人知道为什么它不起作用吗?是因为A标签不支持overflow标签吗? #page_sideba
我正在开发一个程序,用于在 C++ 中分解非常大的数字(20 位或更多),并且正在使用 GMP 来处理溢出问题。我的程序对于大约 10 位或更少的数字运行良好,但是当我向它抛出一个 15 位数字时,它
我创建了一个 Canvas ,并在其中放置了一个StackPanel。 StackPanel是水平的,它接受缩略图图像的列表。 Canvas 具有固定的大小。当我放置的缩略图多于Canvas宽度不能容
当 g_array_append_val() 时会发生什么或 GLib 中的其他附加/前置函数之一,使 GArray 的长度大于 guint (unsigned int) 所能容纳的长度? 文档对此没
overflow-x:hidden 和 overflow:hidden; 有什么区别? 我所知道的是overflow-x:hidden;禁用水平滚动,但当我使用它时,它不仅仅适用于 Firefox,所
我们正在运行 Solr 来索引大量数据,但遇到了一个非常有趣的问题,我无法在任何地方找到任何帮助。 似乎 Solr 使用带符号的 32 位整数来计算索引中当前的文档数。我们刚刚达到了这个数字,我们的
这是我的查询: 从相似性中选择 COUNT(*),其中 T1Similarity = 0 或 T2Similarity = 0 结果如下: Msg 8115, Level 16, State 2, L
int main(void) { char x1 = 0x81; char x2 = 0x1; int a, b; a = x1
我有一个 div,其中的内容通过查询的 append() 定期附加到它。随着内容越来越长,最终会溢出div。我不希望在溢出时出现滚动条,但仍然让内容向上滚动以显示下面的新内容。 这可能吗?当我使用 o
我为 UITextField 创建了一个简单的子类,它按预期工作。我遇到的唯一问题是当文本值变得太大时,它会溢出到清除按钮中。 我似乎无法找到如何仅更改文本的右侧以具有一些填充而不与清除按钮相交的方法
我想要一个包括下拉菜单的粘性导航栏。但是,当我将鼠标悬停在它上面时,下拉菜单没有显示。 如果我删除 overflow: hidden;在无序列表中,当我向下滚动时,导航栏设法保持在顶部,但是导航栏是不
我正在研究一些按钮。我想要一个翻转状态,我在一个 div 的图像中有这个,溢出:隐藏以隐藏不活动的状态。它有时有效,但有时看起来像这样: 最奇怪的是,当我尝试使用 Chrome Web Inspect
基本上,我正在尝试创建一个六边形形状,它内部有一个圆圈,圆圈的多余部分应该被隐藏。演示:https://codepen.io/AskSaikatSinha/pen/jwXNPJ?editors=110
这似乎是一个相当常见且不那么奇特的用例,但我以前没有遇到过。我设置了一支笔,但无法在那里复制它,我正在努力找出原因。 Demo Pen 左侧边栏有一个用于元素列表的自定义滚动窗口,但是虽然设置 ove
我是一名优秀的程序员,十分优秀!