├── corrupt.PNG ├── test ├── stack_example ├── stack_example_llvm ├── stack_example_protect.o ├── stack_example.c ├── stack_example.ll ├── stack_example_protect.ll ├── stack_example_gcc.s └── stack_example_llvm.s ├── disassemble_code.png ├── CMakeLists.txt ├── SSPPass ├── CMakeLists.txt ├── StackDoubleProtector.h └── StackDoubleProtector.cpp └── README.md /corrupt.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bin2415/llvm-stack-guard/HEAD/corrupt.PNG -------------------------------------------------------------------------------- /test/stack_example: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bin2415/llvm-stack-guard/HEAD/test/stack_example -------------------------------------------------------------------------------- /disassemble_code.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bin2415/llvm-stack-guard/HEAD/disassemble_code.png -------------------------------------------------------------------------------- /test/stack_example_llvm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bin2415/llvm-stack-guard/HEAD/test/stack_example_llvm -------------------------------------------------------------------------------- /test/stack_example_protect.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bin2415/llvm-stack-guard/HEAD/test/stack_example_protect.o -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.1) 2 | 3 | find_package(LLVM REQUIRED CONFIG) 4 | list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_DIR}") 5 | include(AddLLVM) 6 | add_definitions(${LLVM_DEFINITIONS}) 7 | include_directories(${LLVM_INCLUDE_DIRS}) 8 | link_directories(${LLVM_LIBRARY_DIRS}) 9 | 10 | add_subdirectory(SSPPass) # Use your pass name here. 11 | -------------------------------------------------------------------------------- /test/stack_example.c: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | > File Name: stack_example.c 3 | > Author: binpang 4 | > Mail: 5 | > Created Time: 2017年07月13日 星期四 19时12分59秒 6 | ************************************************************************/ 7 | 8 | #include 9 | #include 10 | void success() {puts("You have already controlled it.");} 11 | 12 | void vulnerable(){ 13 | char s[12]; 14 | gets(s); 15 | puts(s); 16 | return; 17 | } 18 | int main(int argc, char **argv){ 19 | vulnerable(); 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /SSPPass/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(SSPPass MODULE 2 | # List your source files here. 3 | StackDoubleProtector.cpp 4 | ) 5 | 6 | # Use C++11 to compile our pass (i.e., supply -std=c++11). 7 | target_compile_features(SSPPass PRIVATE cxx_range_for cxx_auto_type) 8 | 9 | # LLVM is (typically) built with no C++ RTTI. We need to match that; 10 | # otherwise, we'll get linker errors about missing RTTI data. 11 | set_target_properties(SSPPass PROPERTIES 12 | COMPILE_FLAGS "-fno-rtti" 13 | ) 14 | 15 | # Get proper shared-library behavior (where symbols are not necessarily 16 | # resolved when the shared library is linked) on OS X. 17 | if(APPLE) 18 | set_target_properties(SSPPass PROPERTIES 19 | LINK_FLAGS "-undefined dynamic_lookup" 20 | ) 21 | endif(APPLE) 22 | -------------------------------------------------------------------------------- /SSPPass/StackDoubleProtector.h: -------------------------------------------------------------------------------- 1 | #ifndef LLVM_CODEGEN_STACKDOUBLEPROTECTOR_H 2 | #define LLVM_CODEGEN_STACKDOUBLEPROTECTOR_H 3 | 4 | #include "llvm/ADT/SmallPtrSet.h" 5 | #include "llvm/ADT/Triple.h" 6 | #include "llvm/IR/Instructions.h" 7 | #include "llvm/IR/ValueMap.h" 8 | #include "llvm/Pass.h" 9 | #include "llvm/PassAnalysisSupport.h" 10 | 11 | namespace llvm { 12 | class BasicBlock; 13 | class DominatorTree; 14 | class Function; 15 | class Instruction; 16 | class Module; 17 | class TargetLowingBase; 18 | class TargetMachine; 19 | class Type; 20 | 21 | class StackDoubleProtector : public FunctionPass { 22 | 23 | private: 24 | const TargetMachine *TM = nullptr; 25 | 26 | //TIL-targetLoweringBase 27 | //const TargetLoweringBase *TLI = nullptr; 28 | 29 | Triple trip; 30 | 31 | Function *F; 32 | Module *M; 33 | 34 | DominatorTree *DT; 35 | 36 | unsigned SSPBufferSize = 0; 37 | 38 | //将代码插入到Pass中,首先将stackguard存进stack中, 39 | //其次在return地址之前将存的stackguard与TLS中的stackguard进行比较 40 | bool InsertStackDoubleProtectors(); 41 | 42 | //产生随机化的数并将数放入到fs:0x28中去 43 | void randomCananyMemory(); 44 | 45 | //如果遇到fork函数,则需要将TLS中的stackguard更新 46 | bool changeStackGuard(); 47 | 48 | BasicBlock *CreateFailBB(); 49 | 50 | public: 51 | static char ID; 52 | StackDoubleProtector() : FunctionPass(ID), SSPBufferSize(8) { 53 | } 54 | 55 | void getAnalysisUsage(AnalysisUsage &AU) const override; 56 | 57 | bool runOnFunction(Function &Fn) override; 58 | 59 | 60 | }; 61 | } 62 | 63 | 64 | #endif 65 | 66 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Simplified LLVM StackProtector 2 | 3 | This is a simplified llvm Stackprotector which can only run on the x86_64 machine, if you want to build this project on your own machine, you can follow the following steps: 4 | 5 | 1. You should make sure that llvm is properly built on your machine. The tuotorial can be found from the [link](http://llvm.org/docs/CMake.html#quick-start) 6 | 7 | 2. First, clone the git repository into your workspace 8 | ``` 9 | git clone https://github.com/bin2415/llvm-stack-guard.git 10 | ``` 11 | 12 | 3. Second, mkdir a dirtory named build and cmake in it 13 | ``` 14 | mkdir build && cd ./build 15 | cmake ../ 16 | make 17 | ``` 18 | 4. Then, you can find a .so file in /build/SSPPass/ 19 | 20 | 5. In test folder, you can find the test file named stack_example.c 21 | 22 | 6. Compile it through clang 23 | ``` 24 | clang -S -emit-llvm -o stack_example.ll stack_example.c 25 | ``` 26 | 27 | 7. Use the pass to protect stack. 28 | ``` 29 | opt -load ../build/SSPPass/libSSPass.so -SSPPass stack_example.ll -S -o stack_example_protect.ll 30 | ``` 31 | 32 | 8. Use the llc tool to generate .o file 33 | ``` 34 | llc -filetype=obj stack_example_protect.ll -o stack_example_protect.o 35 | ``` 36 | 37 | 9. Use clang to generate a binary file 38 | ``` 39 | clang -o stack_example_llvm stack_example_protect.o 40 | ``` 41 | 42 | 10. Run the example file and input 111111111111111111111111 to corrupt the program 43 | ``` 44 | ./stack_example_llvm 45 | 111111111111111111111111111111111 46 | ``` 47 | And the result is shown as belows: 48 | 49 | ![corrupt](corrupt.PNG) 50 | 51 | 11. You can disassemble the binary to find code that implement the stack smashing protect 52 | ``` 53 | objdump -S stack_example_llvm > stack_example_llvm.s 54 | vi stack_example_llvm.s 55 | ``` 56 | 57 | ![disassemble code](disassemble_code.png) 58 | 59 | Enjoy doing it! -------------------------------------------------------------------------------- /test/stack_example.ll: -------------------------------------------------------------------------------- 1 | ; ModuleID = 'stack_example.c' 2 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" 3 | target triple = "x86_64-pc-linux-gnu" 4 | 5 | @.str = private unnamed_addr constant [32 x i8] c"You have already controlled it.\00", align 1 6 | 7 | ; Function Attrs: nounwind uwtable 8 | define void @success() #0 { 9 | %1 = call i32 @puts(i8* getelementptr inbounds ([32 x i8], [32 x i8]* @.str, i32 0, i32 0)) 10 | ret void 11 | } 12 | 13 | declare i32 @puts(i8*) #1 14 | 15 | ; Function Attrs: nounwind uwtable 16 | define void @vulnerable() #0 { 17 | %s = alloca [12 x i8], align 1 18 | %1 = getelementptr inbounds [12 x i8], [12 x i8]* %s, i32 0, i32 0 19 | %2 = call i32 (i8*, ...) bitcast (i32 (...)* @gets to i32 (i8*, ...)*)(i8* %1) 20 | %3 = getelementptr inbounds [12 x i8], [12 x i8]* %s, i32 0, i32 0 21 | %4 = call i32 @puts(i8* %3) 22 | ret void 23 | } 24 | 25 | declare i32 @gets(...) #1 26 | 27 | ; Function Attrs: nounwind uwtable 28 | define i32 @main(i32 %argc, i8** %argv) #0 { 29 | %1 = alloca i32, align 4 30 | %2 = alloca i32, align 4 31 | %3 = alloca i8**, align 8 32 | store i32 0, i32* %1, align 4 33 | store i32 %argc, i32* %2, align 4 34 | store i8** %argv, i8*** %3, align 8 35 | call void @vulnerable() 36 | ret i32 0 37 | } 38 | 39 | attributes #0 = { nounwind uwtable "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" } 40 | attributes #1 = { "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" } 41 | 42 | !llvm.ident = !{!0} 43 | 44 | !0 = !{!"clang version 3.8.0-2ubuntu4 (tags/RELEASE_380/final)"} 45 | -------------------------------------------------------------------------------- /test/stack_example_protect.ll: -------------------------------------------------------------------------------- 1 | ; ModuleID = 'stack_example.ll' 2 | source_filename = "stack_example.ll" 3 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" 4 | target triple = "x86_64-pc-linux-gnu" 5 | 6 | @.str = private unnamed_addr constant [32 x i8] c"You have already controlled it.\00", align 1 7 | 8 | ; Function Attrs: nounwind uwtable 9 | define void @success() #0 { 10 | %StackDoubleGuard = alloca i8* 11 | %stackDoubleGuard = load volatile i8*, i8* addrspace(257)* inttoptr (i32 40 to i8* addrspace(257)*) 12 | store volatile i8* %stackDoubleGuard, i8** %StackDoubleGuard 13 | %1 = call i32 @puts(i8* getelementptr inbounds ([32 x i8], [32 x i8]* @.str, i32 0, i32 0)) 14 | %stackDoubleGuard1 = load volatile i8*, i8* addrspace(257)* inttoptr (i32 40 to i8* addrspace(257)*) 15 | %2 = load volatile i8*, i8** %StackDoubleGuard 16 | %3 = icmp eq i8* %stackDoubleGuard1, %2 17 | br i1 %3, label %SP_double_return, label %CallStackDoublecheckFailBlk 18 | 19 | SP_double_return: ; preds = %0 20 | ret void 21 | 22 | CallStackDoublecheckFailBlk: ; preds = %0 23 | call void @__stack_chk_fail() 24 | unreachable 25 | } 26 | 27 | declare i32 @puts(i8*) #1 28 | 29 | ; Function Attrs: nounwind uwtable 30 | define void @vulnerable() #0 { 31 | %StackDoubleGuard = alloca i8* 32 | %stackDoubleGuard = load volatile i8*, i8* addrspace(257)* inttoptr (i32 40 to i8* addrspace(257)*) 33 | store volatile i8* %stackDoubleGuard, i8** %StackDoubleGuard 34 | %s = alloca [12 x i8], align 1 35 | %1 = getelementptr inbounds [12 x i8], [12 x i8]* %s, i32 0, i32 0 36 | %2 = call i32 (i8*, ...) bitcast (i32 (...)* @gets to i32 (i8*, ...)*)(i8* %1) 37 | %3 = getelementptr inbounds [12 x i8], [12 x i8]* %s, i32 0, i32 0 38 | %4 = call i32 @puts(i8* %3) 39 | %stackDoubleGuard1 = load volatile i8*, i8* addrspace(257)* inttoptr (i32 40 to i8* addrspace(257)*) 40 | %5 = load volatile i8*, i8** %StackDoubleGuard 41 | %6 = icmp eq i8* %stackDoubleGuard1, %5 42 | br i1 %6, label %SP_double_return, label %CallStackDoublecheckFailBlk 43 | 44 | SP_double_return: ; preds = %0 45 | ret void 46 | 47 | CallStackDoublecheckFailBlk: ; preds = %0 48 | call void @__stack_chk_fail() 49 | unreachable 50 | } 51 | 52 | declare i32 @gets(...) #1 53 | 54 | ; Function Attrs: nounwind uwtable 55 | define i32 @main(i32 %argc, i8** %argv) #0 { 56 | %1 = alloca i32, align 4 57 | %2 = alloca i32, align 4 58 | %3 = alloca i8**, align 8 59 | store i32 0, i32* %1, align 4 60 | store i32 %argc, i32* %2, align 4 61 | store i8** %argv, i8*** %3, align 8 62 | call void @vulnerable() 63 | ret i32 0 64 | } 65 | 66 | declare void @__stack_chk_fail() 67 | 68 | attributes #0 = { nounwind uwtable "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" } 69 | attributes #1 = { "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" } 70 | 71 | !llvm.ident = !{!0} 72 | 73 | !0 = !{!"clang version 3.8.0-2ubuntu4 (tags/RELEASE_380/final)"} 74 | -------------------------------------------------------------------------------- /SSPPass/StackDoubleProtector.cpp: -------------------------------------------------------------------------------- 1 | #include "StackDoubleProtector.h" 2 | #include "llvm/ADT/SmallPtrSet.h" 3 | #include "llvm/ADT/Statistic.h" 4 | #include "llvm/Analysis/BranchProbabilityInfo.h" 5 | #include "llvm/Analysis/EHPersonalities.h" 6 | #include "llvm/Analysis/OptimizationDiagnosticInfo.h" 7 | #include "llvm/CodeGen/Passes.h" 8 | #include "llvm/CodeGen/TargetPassConfig.h" 9 | #include "llvm/IR/Attributes.h" 10 | #include "llvm/IR/BasicBlock.h" 11 | #include "llvm/IR/Constants.h" 12 | #include "llvm/IR/DataLayout.h" 13 | #include "llvm/IR/DebugInfo.h" 14 | #include "llvm/IR/DebugLoc.h" 15 | #include "llvm/IR/DerivedTypes.h" 16 | #include "llvm/IR/Dominators.h" 17 | #include "llvm/IR/Function.h" 18 | #include "llvm/IR/IRBuilder.h" 19 | #include "llvm/IR/Instruction.h" 20 | #include "llvm/IR/Instructions.h" 21 | #include "llvm/IR/Intrinsics.h" 22 | #include "llvm/IR/MDBuilder.h" 23 | #include "llvm/IR/Module.h" 24 | #include "llvm/IR/Type.h" 25 | #include "llvm/IR/User.h" 26 | #include "llvm/Pass.h" 27 | #include "llvm/Support/Casting.h" 28 | #include "llvm/Support/CommandLine.h" 29 | #include "llvm/Target/TargetLowering.h" 30 | #include "llvm/Target/TargetMachine.h" 31 | #include "llvm/Target/TargetOptions.h" 32 | #include "llvm/Target/TargetSubtargetInfo.h" 33 | #include 34 | 35 | using namespace llvm; 36 | 37 | #define DEBUG_TYPE "stack-double-protector" 38 | 39 | char StackDoubleProtector::ID = 0; 40 | 41 | void StackDoubleProtector::getAnalysisUsage(AnalysisUsage &AU) const { 42 | AU.addRequired(); 43 | AU.addPreserved(); 44 | } 45 | 46 | //Address为257表示在用户模式下的fs段寄存器 47 | static Constant* SegmentOffsetStack(IRBuilder<> &IRB, unsigned Offset, unsigned AddressSpace) { 48 | return ConstantExpr::getIntToPtr( 49 | ConstantInt::get(Type::getInt32Ty(IRB.getContext()), Offset), 50 | Type::getInt8PtrTy(IRB.getContext())->getPointerTo(AddressSpace) 51 | ); 52 | } 53 | static Value* getTheStackGuardValue(IRBuilder<> &IRB) { 54 | return SegmentOffsetStack(IRB, 0x28, 257); 55 | } 56 | static bool CreateDoublePrologue(Function* F, Module *M, ReturnInst *RI, AllocaInst *&AI) { 57 | IRBuilder<> B(&F->getEntryBlock().front()); 58 | PointerType *PtrTy = Type::getInt8PtrTy(RI->getContext()); 59 | AI = B.CreateAlloca(PtrTy, nullptr, "StackDoubleGuard"); 60 | Value* DoubleGuard = getTheStackGuardValue(B); 61 | Value* loadedDoubleGuard = B.CreateLoad(DoubleGuard, true, "stackDoubleGuard"); 62 | //将canany值存进allocaInst中去 63 | errs() << "stack protector store\n"; 64 | B.CreateStore(loadedDoubleGuard, AI, true); 65 | return true; 66 | } 67 | 68 | void StackDoubleProtector::randomCananyMemory() { 69 | IRBuilder<> B(&F->getEntryBlock().front()); 70 | Value* cananyMemory = getTheStackGuardValue(B); 71 | unsigned random = std::rand(); 72 | ConstantInt *canany = ConstantInt::get(Type::getInt32Ty(F->getContext()), random, false); 73 | errs() << "Random Protector store\n"; 74 | errs() << canany->getType() << ","; 75 | errs() << cast(cananyMemory->getType())->getElementType() << "\n"; 76 | B.CreateStore(canany, cananyMemory, true); 77 | } 78 | bool StackDoubleProtector::runOnFunction(Function &Fn) { 79 | F = &Fn; 80 | M = F->getParent(); 81 | DominatorTreeWrapperPass *DTWP = getAnalysisIfAvailable(); 82 | DT = DTWP ? &DTWP->getDomTree() : nullptr; 83 | TM = &getAnalysis().getTM(); 84 | trip = TM->getTargetTriple(); 85 | //TLI = TM->getSubtargetImpl(Fn)->getTargetLowering(); 86 | 87 | if (!F->getName().equals("main")) { //一开始随机化canany 88 | InsertStackDoubleProtectors(); 89 | } 90 | 91 | return true; 92 | } 93 | 94 | bool StackDoubleProtector::InsertStackDoubleProtectors() { 95 | AllocaInst *AI = nullptr; 96 | 97 | for (Function::iterator I = F->begin(), E = F->end(); I != E;) { 98 | BasicBlock* BB = &*I++; 99 | ReturnInst *RI = dyn_cast(BB->getTerminator()); 100 | if (!RI) 101 | continue; 102 | CreateDoublePrologue(F, M, RI, AI); //将canany保存进栈中 103 | BasicBlock *FailBB = CreateFailBB(); 104 | BasicBlock *NewBB = BB->splitBasicBlock(RI->getIterator(), "SP_double_return"); 105 | 106 | if (DT && DT->isReachableFromEntry(BB)) { 107 | DT->addNewBlock(NewBB, BB); 108 | DT->addNewBlock(FailBB, BB); 109 | } 110 | BB->getTerminator()->eraseFromParent(); //将以前的return指令转移到新的basicblock中 111 | 112 | NewBB->moveAfter(BB); 113 | IRBuilder<> B(BB); 114 | Value* stackGuard = getTheStackGuardValue(B); 115 | Value* loadedStackGuard = B.CreateLoad(stackGuard, true, "stackDoubleGuard"); 116 | LoadInst* loadedValue = B.CreateLoad(AI, true); 117 | Value *Cmp = B.CreateICmpEQ(loadedStackGuard, loadedValue); 118 | B.CreateCondBr(Cmp, NewBB, FailBB); 119 | } 120 | return true; 121 | } 122 | 123 | BasicBlock *StackDoubleProtector::CreateFailBB() { 124 | LLVMContext &Context = F->getContext(); 125 | BasicBlock *FailBB = BasicBlock::Create(Context, "CallStackDoublecheckFailBlk", F); 126 | IRBuilder<> B(FailBB); 127 | //B.SetCurrentDebugLocation(DebugLoc::get(0, 0, F->getSubprogram)); 128 | Constant *StackChkFail = M->getOrInsertFunction("__stack_chk_fail", Type::getVoidTy(Context)); 129 | 130 | B.CreateCall(StackChkFail, {}); 131 | B.CreateUnreachable(); 132 | return FailBB; 133 | } 134 | 135 | //char StackDoubleProtector::ID = 0; 136 | static RegisterPass X("SSPPass", "Stack Double Protector", false, false); 137 | -------------------------------------------------------------------------------- /test/stack_example_gcc.s: -------------------------------------------------------------------------------- 1 | 2 | stack_example: 文件格式 elf64-x86-64 3 | 4 | 5 | Disassembly of section .init: 6 | 7 | 0000000000400460 <_init>: 8 | 400460: 48 83 ec 08 sub $0x8,%rsp 9 | 400464: 48 8b 05 8d 0b 20 00 mov 0x200b8d(%rip),%rax # 600ff8 <_DYNAMIC+0x1d0> 10 | 40046b: 48 85 c0 test %rax,%rax 11 | 40046e: 74 05 je 400475 <_init+0x15> 12 | 400470: e8 5b 00 00 00 callq 4004d0 13 | 400475: 48 83 c4 08 add $0x8,%rsp 14 | 400479: c3 retq 15 | 16 | Disassembly of section .plt: 17 | 18 | 0000000000400480 : 19 | 400480: ff 35 82 0b 20 00 pushq 0x200b82(%rip) # 601008 <_GLOBAL_OFFSET_TABLE_+0x8> 20 | 400486: ff 25 84 0b 20 00 jmpq *0x200b84(%rip) # 601010 <_GLOBAL_OFFSET_TABLE_+0x10> 21 | 40048c: 0f 1f 40 00 nopl 0x0(%rax) 22 | 23 | 0000000000400490 : 24 | 400490: ff 25 82 0b 20 00 jmpq *0x200b82(%rip) # 601018 <_GLOBAL_OFFSET_TABLE_+0x18> 25 | 400496: 68 00 00 00 00 pushq $0x0 26 | 40049b: e9 e0 ff ff ff jmpq 400480 <_init+0x20> 27 | 28 | 00000000004004a0 <__stack_chk_fail@plt>: 29 | 4004a0: ff 25 7a 0b 20 00 jmpq *0x200b7a(%rip) # 601020 <_GLOBAL_OFFSET_TABLE_+0x20> 30 | 4004a6: 68 01 00 00 00 pushq $0x1 31 | 4004ab: e9 d0 ff ff ff jmpq 400480 <_init+0x20> 32 | 33 | 00000000004004b0 <__libc_start_main@plt>: 34 | 4004b0: ff 25 72 0b 20 00 jmpq *0x200b72(%rip) # 601028 <_GLOBAL_OFFSET_TABLE_+0x28> 35 | 4004b6: 68 02 00 00 00 pushq $0x2 36 | 4004bb: e9 c0 ff ff ff jmpq 400480 <_init+0x20> 37 | 38 | 00000000004004c0 : 39 | 4004c0: ff 25 6a 0b 20 00 jmpq *0x200b6a(%rip) # 601030 <_GLOBAL_OFFSET_TABLE_+0x30> 40 | 4004c6: 68 03 00 00 00 pushq $0x3 41 | 4004cb: e9 b0 ff ff ff jmpq 400480 <_init+0x20> 42 | 43 | Disassembly of section .plt.got: 44 | 45 | 00000000004004d0 <.plt.got>: 46 | 4004d0: ff 25 22 0b 20 00 jmpq *0x200b22(%rip) # 600ff8 <_DYNAMIC+0x1d0> 47 | 4004d6: 66 90 xchg %ax,%ax 48 | 49 | Disassembly of section .text: 50 | 51 | 00000000004004e0 <_start>: 52 | 4004e0: 31 ed xor %ebp,%ebp 53 | 4004e2: 49 89 d1 mov %rdx,%r9 54 | 4004e5: 5e pop %rsi 55 | 4004e6: 48 89 e2 mov %rsp,%rdx 56 | 4004e9: 48 83 e4 f0 and $0xfffffffffffffff0,%rsp 57 | 4004ed: 50 push %rax 58 | 4004ee: 54 push %rsp 59 | 4004ef: 49 c7 c0 d0 06 40 00 mov $0x4006d0,%r8 60 | 4004f6: 48 c7 c1 60 06 40 00 mov $0x400660,%rcx 61 | 4004fd: 48 c7 c7 32 06 40 00 mov $0x400632,%rdi 62 | 400504: e8 a7 ff ff ff callq 4004b0 <__libc_start_main@plt> 63 | 400509: f4 hlt 64 | 40050a: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1) 65 | 66 | 0000000000400510 : 67 | 400510: b8 4f 10 60 00 mov $0x60104f,%eax 68 | 400515: 55 push %rbp 69 | 400516: 48 2d 48 10 60 00 sub $0x601048,%rax 70 | 40051c: 48 83 f8 0e cmp $0xe,%rax 71 | 400520: 48 89 e5 mov %rsp,%rbp 72 | 400523: 76 1b jbe 400540 73 | 400525: b8 00 00 00 00 mov $0x0,%eax 74 | 40052a: 48 85 c0 test %rax,%rax 75 | 40052d: 74 11 je 400540 76 | 40052f: 5d pop %rbp 77 | 400530: bf 48 10 60 00 mov $0x601048,%edi 78 | 400535: ff e0 jmpq *%rax 79 | 400537: 66 0f 1f 84 00 00 00 nopw 0x0(%rax,%rax,1) 80 | 40053e: 00 00 81 | 400540: 5d pop %rbp 82 | 400541: c3 retq 83 | 400542: 0f 1f 40 00 nopl 0x0(%rax) 84 | 400546: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1) 85 | 40054d: 00 00 00 86 | 87 | 0000000000400550 : 88 | 400550: be 48 10 60 00 mov $0x601048,%esi 89 | 400555: 55 push %rbp 90 | 400556: 48 81 ee 48 10 60 00 sub $0x601048,%rsi 91 | 40055d: 48 c1 fe 03 sar $0x3,%rsi 92 | 400561: 48 89 e5 mov %rsp,%rbp 93 | 400564: 48 89 f0 mov %rsi,%rax 94 | 400567: 48 c1 e8 3f shr $0x3f,%rax 95 | 40056b: 48 01 c6 add %rax,%rsi 96 | 40056e: 48 d1 fe sar %rsi 97 | 400571: 74 15 je 400588 98 | 400573: b8 00 00 00 00 mov $0x0,%eax 99 | 400578: 48 85 c0 test %rax,%rax 100 | 40057b: 74 0b je 400588 101 | 40057d: 5d pop %rbp 102 | 40057e: bf 48 10 60 00 mov $0x601048,%edi 103 | 400583: ff e0 jmpq *%rax 104 | 400585: 0f 1f 00 nopl (%rax) 105 | 400588: 5d pop %rbp 106 | 400589: c3 retq 107 | 40058a: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1) 108 | 109 | 0000000000400590 <__do_global_dtors_aux>: 110 | 400590: 80 3d b1 0a 20 00 00 cmpb $0x0,0x200ab1(%rip) # 601048 <__TMC_END__> 111 | 400597: 75 11 jne 4005aa <__do_global_dtors_aux+0x1a> 112 | 400599: 55 push %rbp 113 | 40059a: 48 89 e5 mov %rsp,%rbp 114 | 40059d: e8 6e ff ff ff callq 400510 115 | 4005a2: 5d pop %rbp 116 | 4005a3: c6 05 9e 0a 20 00 01 movb $0x1,0x200a9e(%rip) # 601048 <__TMC_END__> 117 | 4005aa: f3 c3 repz retq 118 | 4005ac: 0f 1f 40 00 nopl 0x0(%rax) 119 | 120 | 00000000004005b0 : 121 | 4005b0: bf 20 0e 60 00 mov $0x600e20,%edi 122 | 4005b5: 48 83 3f 00 cmpq $0x0,(%rdi) 123 | 4005b9: 75 05 jne 4005c0 124 | 4005bb: eb 93 jmp 400550 125 | 4005bd: 0f 1f 00 nopl (%rax) 126 | 4005c0: b8 00 00 00 00 mov $0x0,%eax 127 | 4005c5: 48 85 c0 test %rax,%rax 128 | 4005c8: 74 f1 je 4005bb 129 | 4005ca: 55 push %rbp 130 | 4005cb: 48 89 e5 mov %rsp,%rbp 131 | 4005ce: ff d0 callq *%rax 132 | 4005d0: 5d pop %rbp 133 | 4005d1: e9 7a ff ff ff jmpq 400550 134 | 135 | 00000000004005d6 : 136 | 4005d6: 55 push %rbp 137 | 4005d7: 48 89 e5 mov %rsp,%rbp 138 | 4005da: bf e8 06 40 00 mov $0x4006e8,%edi 139 | 4005df: e8 ac fe ff ff callq 400490 140 | 4005e4: 90 nop 141 | 4005e5: 5d pop %rbp 142 | 4005e6: c3 retq 143 | 144 | 00000000004005e7 : 145 | 4005e7: 55 push %rbp 146 | 4005e8: 48 89 e5 mov %rsp,%rbp 147 | 4005eb: 48 83 ec 20 sub $0x20,%rsp 148 | 4005ef: 64 48 8b 04 25 28 00 mov %fs:0x28,%rax 149 | 4005f6: 00 00 150 | 4005f8: 48 89 45 f8 mov %rax,-0x8(%rbp) 151 | 4005fc: 31 c0 xor %eax,%eax 152 | 4005fe: 48 8d 45 e0 lea -0x20(%rbp),%rax 153 | 400602: 48 89 c7 mov %rax,%rdi 154 | 400605: b8 00 00 00 00 mov $0x0,%eax 155 | 40060a: e8 b1 fe ff ff callq 4004c0 156 | 40060f: 48 8d 45 e0 lea -0x20(%rbp),%rax 157 | 400613: 48 89 c7 mov %rax,%rdi 158 | 400616: e8 75 fe ff ff callq 400490 159 | 40061b: 90 nop 160 | 40061c: 48 8b 45 f8 mov -0x8(%rbp),%rax 161 | 400620: 64 48 33 04 25 28 00 xor %fs:0x28,%rax 162 | 400627: 00 00 163 | 400629: 74 05 je 400630 164 | 40062b: e8 70 fe ff ff callq 4004a0 <__stack_chk_fail@plt> 165 | 400630: c9 leaveq 166 | 400631: c3 retq 167 | 168 | 0000000000400632
: 169 | 400632: 55 push %rbp 170 | 400633: 48 89 e5 mov %rsp,%rbp 171 | 400636: 48 83 ec 10 sub $0x10,%rsp 172 | 40063a: 89 7d fc mov %edi,-0x4(%rbp) 173 | 40063d: 48 89 75 f0 mov %rsi,-0x10(%rbp) 174 | 400641: b8 00 00 00 00 mov $0x0,%eax 175 | 400646: e8 9c ff ff ff callq 4005e7 176 | 40064b: b8 00 00 00 00 mov $0x0,%eax 177 | 400650: c9 leaveq 178 | 400651: c3 retq 179 | 400652: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1) 180 | 400659: 00 00 00 181 | 40065c: 0f 1f 40 00 nopl 0x0(%rax) 182 | 183 | 0000000000400660 <__libc_csu_init>: 184 | 400660: 41 57 push %r15 185 | 400662: 41 56 push %r14 186 | 400664: 41 89 ff mov %edi,%r15d 187 | 400667: 41 55 push %r13 188 | 400669: 41 54 push %r12 189 | 40066b: 4c 8d 25 9e 07 20 00 lea 0x20079e(%rip),%r12 # 600e10 <__frame_dummy_init_array_entry> 190 | 400672: 55 push %rbp 191 | 400673: 48 8d 2d 9e 07 20 00 lea 0x20079e(%rip),%rbp # 600e18 <__init_array_end> 192 | 40067a: 53 push %rbx 193 | 40067b: 49 89 f6 mov %rsi,%r14 194 | 40067e: 49 89 d5 mov %rdx,%r13 195 | 400681: 4c 29 e5 sub %r12,%rbp 196 | 400684: 48 83 ec 08 sub $0x8,%rsp 197 | 400688: 48 c1 fd 03 sar $0x3,%rbp 198 | 40068c: e8 cf fd ff ff callq 400460 <_init> 199 | 400691: 48 85 ed test %rbp,%rbp 200 | 400694: 74 20 je 4006b6 <__libc_csu_init+0x56> 201 | 400696: 31 db xor %ebx,%ebx 202 | 400698: 0f 1f 84 00 00 00 00 nopl 0x0(%rax,%rax,1) 203 | 40069f: 00 204 | 4006a0: 4c 89 ea mov %r13,%rdx 205 | 4006a3: 4c 89 f6 mov %r14,%rsi 206 | 4006a6: 44 89 ff mov %r15d,%edi 207 | 4006a9: 41 ff 14 dc callq *(%r12,%rbx,8) 208 | 4006ad: 48 83 c3 01 add $0x1,%rbx 209 | 4006b1: 48 39 eb cmp %rbp,%rbx 210 | 4006b4: 75 ea jne 4006a0 <__libc_csu_init+0x40> 211 | 4006b6: 48 83 c4 08 add $0x8,%rsp 212 | 4006ba: 5b pop %rbx 213 | 4006bb: 5d pop %rbp 214 | 4006bc: 41 5c pop %r12 215 | 4006be: 41 5d pop %r13 216 | 4006c0: 41 5e pop %r14 217 | 4006c2: 41 5f pop %r15 218 | 4006c4: c3 retq 219 | 4006c5: 90 nop 220 | 4006c6: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1) 221 | 4006cd: 00 00 00 222 | 223 | 00000000004006d0 <__libc_csu_fini>: 224 | 4006d0: f3 c3 repz retq 225 | 226 | Disassembly of section .fini: 227 | 228 | 00000000004006d4 <_fini>: 229 | 4006d4: 48 83 ec 08 sub $0x8,%rsp 230 | 4006d8: 48 83 c4 08 add $0x8,%rsp 231 | 4006dc: c3 retq 232 | -------------------------------------------------------------------------------- /test/stack_example_llvm.s: -------------------------------------------------------------------------------- 1 | 2 | stack_example_llvm: 文件格式 elf64-x86-64 3 | 4 | 5 | Disassembly of section .init: 6 | 7 | 0000000000400460 <_init>: 8 | 400460: 48 83 ec 08 sub $0x8,%rsp 9 | 400464: 48 8b 05 8d 0b 20 00 mov 0x200b8d(%rip),%rax # 600ff8 <_DYNAMIC+0x1d0> 10 | 40046b: 48 85 c0 test %rax,%rax 11 | 40046e: 74 05 je 400475 <_init+0x15> 12 | 400470: e8 5b 00 00 00 callq 4004d0 13 | 400475: 48 83 c4 08 add $0x8,%rsp 14 | 400479: c3 retq 15 | 16 | Disassembly of section .plt: 17 | 18 | 0000000000400480 : 19 | 400480: ff 35 82 0b 20 00 pushq 0x200b82(%rip) # 601008 <_GLOBAL_OFFSET_TABLE_+0x8> 20 | 400486: ff 25 84 0b 20 00 jmpq *0x200b84(%rip) # 601010 <_GLOBAL_OFFSET_TABLE_+0x10> 21 | 40048c: 0f 1f 40 00 nopl 0x0(%rax) 22 | 23 | 0000000000400490 : 24 | 400490: ff 25 82 0b 20 00 jmpq *0x200b82(%rip) # 601018 <_GLOBAL_OFFSET_TABLE_+0x18> 25 | 400496: 68 00 00 00 00 pushq $0x0 26 | 40049b: e9 e0 ff ff ff jmpq 400480 <_init+0x20> 27 | 28 | 00000000004004a0 <__stack_chk_fail@plt>: 29 | 4004a0: ff 25 7a 0b 20 00 jmpq *0x200b7a(%rip) # 601020 <_GLOBAL_OFFSET_TABLE_+0x20> 30 | 4004a6: 68 01 00 00 00 pushq $0x1 31 | 4004ab: e9 d0 ff ff ff jmpq 400480 <_init+0x20> 32 | 33 | 00000000004004b0 <__libc_start_main@plt>: 34 | 4004b0: ff 25 72 0b 20 00 jmpq *0x200b72(%rip) # 601028 <_GLOBAL_OFFSET_TABLE_+0x28> 35 | 4004b6: 68 02 00 00 00 pushq $0x2 36 | 4004bb: e9 c0 ff ff ff jmpq 400480 <_init+0x20> 37 | 38 | 00000000004004c0 : 39 | 4004c0: ff 25 6a 0b 20 00 jmpq *0x200b6a(%rip) # 601030 <_GLOBAL_OFFSET_TABLE_+0x30> 40 | 4004c6: 68 03 00 00 00 pushq $0x3 41 | 4004cb: e9 b0 ff ff ff jmpq 400480 <_init+0x20> 42 | 43 | Disassembly of section .plt.got: 44 | 45 | 00000000004004d0 <.plt.got>: 46 | 4004d0: ff 25 22 0b 20 00 jmpq *0x200b22(%rip) # 600ff8 <_DYNAMIC+0x1d0> 47 | 4004d6: 66 90 xchg %ax,%ax 48 | 49 | Disassembly of section .text: 50 | 51 | 00000000004004e0 <_start>: 52 | 4004e0: 31 ed xor %ebp,%ebp 53 | 4004e2: 49 89 d1 mov %rdx,%r9 54 | 4004e5: 5e pop %rsi 55 | 4004e6: 48 89 e2 mov %rsp,%rdx 56 | 4004e9: 48 83 e4 f0 and $0xfffffffffffffff0,%rsp 57 | 4004ed: 50 push %rax 58 | 4004ee: 54 push %rsp 59 | 4004ef: 49 c7 c0 10 07 40 00 mov $0x400710,%r8 60 | 4004f6: 48 c7 c1 a0 06 40 00 mov $0x4006a0,%rcx 61 | 4004fd: 48 c7 c7 70 06 40 00 mov $0x400670,%rdi 62 | 400504: e8 a7 ff ff ff callq 4004b0 <__libc_start_main@plt> 63 | 400509: f4 hlt 64 | 40050a: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1) 65 | 66 | 0000000000400510 : 67 | 400510: b8 4f 10 60 00 mov $0x60104f,%eax 68 | 400515: 55 push %rbp 69 | 400516: 48 2d 48 10 60 00 sub $0x601048,%rax 70 | 40051c: 48 83 f8 0e cmp $0xe,%rax 71 | 400520: 48 89 e5 mov %rsp,%rbp 72 | 400523: 76 1b jbe 400540 73 | 400525: b8 00 00 00 00 mov $0x0,%eax 74 | 40052a: 48 85 c0 test %rax,%rax 75 | 40052d: 74 11 je 400540 76 | 40052f: 5d pop %rbp 77 | 400530: bf 48 10 60 00 mov $0x601048,%edi 78 | 400535: ff e0 jmpq *%rax 79 | 400537: 66 0f 1f 84 00 00 00 nopw 0x0(%rax,%rax,1) 80 | 40053e: 00 00 81 | 400540: 5d pop %rbp 82 | 400541: c3 retq 83 | 400542: 0f 1f 40 00 nopl 0x0(%rax) 84 | 400546: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1) 85 | 40054d: 00 00 00 86 | 87 | 0000000000400550 : 88 | 400550: be 48 10 60 00 mov $0x601048,%esi 89 | 400555: 55 push %rbp 90 | 400556: 48 81 ee 48 10 60 00 sub $0x601048,%rsi 91 | 40055d: 48 c1 fe 03 sar $0x3,%rsi 92 | 400561: 48 89 e5 mov %rsp,%rbp 93 | 400564: 48 89 f0 mov %rsi,%rax 94 | 400567: 48 c1 e8 3f shr $0x3f,%rax 95 | 40056b: 48 01 c6 add %rax,%rsi 96 | 40056e: 48 d1 fe sar %rsi 97 | 400571: 74 15 je 400588 98 | 400573: b8 00 00 00 00 mov $0x0,%eax 99 | 400578: 48 85 c0 test %rax,%rax 100 | 40057b: 74 0b je 400588 101 | 40057d: 5d pop %rbp 102 | 40057e: bf 48 10 60 00 mov $0x601048,%edi 103 | 400583: ff e0 jmpq *%rax 104 | 400585: 0f 1f 00 nopl (%rax) 105 | 400588: 5d pop %rbp 106 | 400589: c3 retq 107 | 40058a: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1) 108 | 109 | 0000000000400590 <__do_global_dtors_aux>: 110 | 400590: 80 3d b1 0a 20 00 00 cmpb $0x0,0x200ab1(%rip) # 601048 <__TMC_END__> 111 | 400597: 75 11 jne 4005aa <__do_global_dtors_aux+0x1a> 112 | 400599: 55 push %rbp 113 | 40059a: 48 89 e5 mov %rsp,%rbp 114 | 40059d: e8 6e ff ff ff callq 400510 115 | 4005a2: 5d pop %rbp 116 | 4005a3: c6 05 9e 0a 20 00 01 movb $0x1,0x200a9e(%rip) # 601048 <__TMC_END__> 117 | 4005aa: f3 c3 repz retq 118 | 4005ac: 0f 1f 40 00 nopl 0x0(%rax) 119 | 120 | 00000000004005b0 : 121 | 4005b0: bf 20 0e 60 00 mov $0x600e20,%edi 122 | 4005b5: 48 83 3f 00 cmpq $0x0,(%rdi) 123 | 4005b9: 75 05 jne 4005c0 124 | 4005bb: eb 93 jmp 400550 125 | 4005bd: 0f 1f 00 nopl (%rax) 126 | 4005c0: b8 00 00 00 00 mov $0x0,%eax 127 | 4005c5: 48 85 c0 test %rax,%rax 128 | 4005c8: 74 f1 je 4005bb 129 | 4005ca: 55 push %rbp 130 | 4005cb: 48 89 e5 mov %rsp,%rbp 131 | 4005ce: ff d0 callq *%rax 132 | 4005d0: 5d pop %rbp 133 | 4005d1: e9 7a ff ff ff jmpq 400550 134 | 4005d6: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1) 135 | 4005dd: 00 00 00 136 | 137 | 00000000004005e0 : 138 | 4005e0: 55 push %rbp 139 | 4005e1: 48 89 e5 mov %rsp,%rbp 140 | 4005e4: 48 83 ec 10 sub $0x10,%rsp 141 | 4005e8: 64 48 8b 04 25 28 00 mov %fs:0x28,%rax 142 | 4005ef: 00 00 143 | 4005f1: 48 89 45 f8 mov %rax,-0x8(%rbp) 144 | 4005f5: bf 24 07 40 00 mov $0x400724,%edi 145 | 4005fa: e8 91 fe ff ff callq 400490 146 | 4005ff: 64 48 8b 04 25 28 00 mov %fs:0x28,%rax 147 | 400606: 00 00 148 | 400608: 48 3b 45 f8 cmp -0x8(%rbp),%rax 149 | 40060c: 75 06 jne 400614 150 | 40060e: 48 83 c4 10 add $0x10,%rsp 151 | 400612: 5d pop %rbp 152 | 400613: c3 retq 153 | 400614: e8 87 fe ff ff callq 4004a0 <__stack_chk_fail@plt> 154 | 400619: 0f 1f 80 00 00 00 00 nopl 0x0(%rax) 155 | 156 | 0000000000400620 : 157 | 400620: 55 push %rbp 158 | 400621: 48 89 e5 mov %rsp,%rbp 159 | 400624: 53 push %rbx 160 | 400625: 48 83 ec 18 sub $0x18,%rsp 161 | 400629: 64 48 8b 04 25 28 00 mov %fs:0x28,%rax 162 | 400630: 00 00 163 | 400632: 48 89 45 f0 mov %rax,-0x10(%rbp) 164 | 400636: 48 8d 5d e4 lea -0x1c(%rbp),%rbx 165 | 40063a: 31 c0 xor %eax,%eax 166 | 40063c: 48 89 df mov %rbx,%rdi 167 | 40063f: e8 7c fe ff ff callq 4004c0 168 | 400644: 48 89 df mov %rbx,%rdi 169 | 400647: e8 44 fe ff ff callq 400490 170 | 40064c: 64 48 8b 04 25 28 00 mov %fs:0x28,%rax 171 | 400653: 00 00 172 | 400655: 48 3b 45 f0 cmp -0x10(%rbp),%rax 173 | 400659: 75 07 jne 400662 174 | 40065b: 48 83 c4 18 add $0x18,%rsp 175 | 40065f: 5b pop %rbx 176 | 400660: 5d pop %rbp 177 | 400661: c3 retq 178 | 400662: e8 39 fe ff ff callq 4004a0 <__stack_chk_fail@plt> 179 | 400667: 66 0f 1f 84 00 00 00 nopw 0x0(%rax,%rax,1) 180 | 40066e: 00 00 181 | 182 | 0000000000400670
: 183 | 400670: 55 push %rbp 184 | 400671: 48 89 e5 mov %rsp,%rbp 185 | 400674: 48 83 ec 10 sub $0x10,%rsp 186 | 400678: c7 45 f8 00 00 00 00 movl $0x0,-0x8(%rbp) 187 | 40067f: 89 7d fc mov %edi,-0x4(%rbp) 188 | 400682: 48 89 75 f0 mov %rsi,-0x10(%rbp) 189 | 400686: e8 95 ff ff ff callq 400620 190 | 40068b: 31 c0 xor %eax,%eax 191 | 40068d: 48 83 c4 10 add $0x10,%rsp 192 | 400691: 5d pop %rbp 193 | 400692: c3 retq 194 | 400693: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1) 195 | 40069a: 00 00 00 196 | 40069d: 0f 1f 00 nopl (%rax) 197 | 198 | 00000000004006a0 <__libc_csu_init>: 199 | 4006a0: 41 57 push %r15 200 | 4006a2: 41 56 push %r14 201 | 4006a4: 41 89 ff mov %edi,%r15d 202 | 4006a7: 41 55 push %r13 203 | 4006a9: 41 54 push %r12 204 | 4006ab: 4c 8d 25 5e 07 20 00 lea 0x20075e(%rip),%r12 # 600e10 <__frame_dummy_init_array_entry> 205 | 4006b2: 55 push %rbp 206 | 4006b3: 48 8d 2d 5e 07 20 00 lea 0x20075e(%rip),%rbp # 600e18 <__init_array_end> 207 | 4006ba: 53 push %rbx 208 | 4006bb: 49 89 f6 mov %rsi,%r14 209 | 4006be: 49 89 d5 mov %rdx,%r13 210 | 4006c1: 4c 29 e5 sub %r12,%rbp 211 | 4006c4: 48 83 ec 08 sub $0x8,%rsp 212 | 4006c8: 48 c1 fd 03 sar $0x3,%rbp 213 | 4006cc: e8 8f fd ff ff callq 400460 <_init> 214 | 4006d1: 48 85 ed test %rbp,%rbp 215 | 4006d4: 74 20 je 4006f6 <__libc_csu_init+0x56> 216 | 4006d6: 31 db xor %ebx,%ebx 217 | 4006d8: 0f 1f 84 00 00 00 00 nopl 0x0(%rax,%rax,1) 218 | 4006df: 00 219 | 4006e0: 4c 89 ea mov %r13,%rdx 220 | 4006e3: 4c 89 f6 mov %r14,%rsi 221 | 4006e6: 44 89 ff mov %r15d,%edi 222 | 4006e9: 41 ff 14 dc callq *(%r12,%rbx,8) 223 | 4006ed: 48 83 c3 01 add $0x1,%rbx 224 | 4006f1: 48 39 eb cmp %rbp,%rbx 225 | 4006f4: 75 ea jne 4006e0 <__libc_csu_init+0x40> 226 | 4006f6: 48 83 c4 08 add $0x8,%rsp 227 | 4006fa: 5b pop %rbx 228 | 4006fb: 5d pop %rbp 229 | 4006fc: 41 5c pop %r12 230 | 4006fe: 41 5d pop %r13 231 | 400700: 41 5e pop %r14 232 | 400702: 41 5f pop %r15 233 | 400704: c3 retq 234 | 400705: 90 nop 235 | 400706: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1) 236 | 40070d: 00 00 00 237 | 238 | 0000000000400710 <__libc_csu_fini>: 239 | 400710: f3 c3 repz retq 240 | 241 | Disassembly of section .fini: 242 | 243 | 0000000000400714 <_fini>: 244 | 400714: 48 83 ec 08 sub $0x8,%rsp 245 | 400718: 48 83 c4 08 add $0x8,%rsp 246 | 40071c: c3 retq 247 | --------------------------------------------------------------------------------