From d751a075fa53830a770bb5cc444ea846de0db48a Mon Sep 17 00:00:00 2001 From: Richard L Ford Date: Sun, 17 Jul 2022 20:06:19 -0400 Subject: [PATCH] Handle Procedure Linkage calls for 32bit x86 from gcc This case is for x86 32 bit compiled with GCC. Its PLT entries are in sections .plt.sec or .plt.got. An entry is of the form: jmp *offset(%ebx) When this code is encountered register %ebx has been loaded with the address of the start of the Global Offset Table (.got) section. This change handles that case. --- .../optimizations/decoder/decoder.cpp | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/bin2llvmir/optimizations/decoder/decoder.cpp b/src/bin2llvmir/optimizations/decoder/decoder.cpp index b3238d733..3137f7766 100644 --- a/src/bin2llvmir/optimizations/decoder/decoder.cpp +++ b/src/bin2llvmir/optimizations/decoder/decoder.cpp @@ -853,6 +853,46 @@ common::Address Decoder::getJumpTarget( } } + if (plt && + ((plt->getName() == ".plt.sec") || (plt->getName() == ".plt.got")) && + _config->getConfig().architecture.isX86_32()) + { + // This case is for x86 32 bit compiled with GCC. Its PLT entries are in + // sections .plt.sec or .plt.got. An entry is of the form: + // + // jmp *offset(%ebx) + // + // When this code is encountered register %ebx has been loaded with the + // address of the start of the Global Offset Table (.got) section. + // + // The above jump produces llvm code that matches the following pattern + // where the global variable is a reference to the ebx register. + + llvm::LoadInst* li1 = nullptr; + llvm::LoadInst* li2 = nullptr; + llvm::ConstantInt* ci = nullptr; + llvm::GlobalVariable* gv = nullptr; + auto pattern = + m_Load( + m_Add( + m_Load(m_GlobalVariable(gv), &li2), + m_ConstantInt(ci)), + &li1); + + if (match(st, pattern) && (gv->getName().str() == "ebx")) { + auto* gotSec = _image->getFileFormat()->getSection(".got"); + if (gotSec) + { + auto gotsecAddr = gotSec->getAddress(); + Address t = gotsecAddr + ci->getZExtValue(); + if (_imports.count(t)) + { + return t; + } + } + } + } + st.simplifyNode(); llvm::ConstantInt* ci = nullptr;