mirror of
https://github.com/lifting-bits/mcsema
synced 2026-06-08 15:31:09 +00:00
8a9856ada3
* In progress. Working on an example of using KLEE on a Maze, but with the maze program being compiled to x86, amd64, and aarch64. * Making lots of progress on getting lifting and runnning an aarch64 maze program on amd64, but using --explicit_args. The key thing I'm working through right now is a jump offset table, but where the offset is a block pc, rather than a table base. Also adding various bits of code here and there to making runnning with klee more directly doable, and working on a debugging facility to track down when the emulated program counter gets out of sync with the original program. * Fixed a subtle @PAGE and @PAGEOFF-related reference bug on AArch64. Partially disabled the special jump offset table handling I had in table.py, as it doesn't (yet) handle the shifted table values. However, I still have the code there, so that it can recognize that a basic block address is used as a possible offset, so that I can remove the block address as a reference, which permits a new heuristic on the C++ side to work. On the C++ side, when there's a jump instruction that isn't associated with a cross-reference flow, I try to auto-augment it with addition switch cases, targeting blocks with no predecessors (as present in the CFG). This seems to work reasonably well. * Improved the scripts and updated the READMEs. * Minor rephrase * Minor rephrase
117 lines
3.4 KiB
C++
117 lines
3.4 KiB
C++
/*
|
|
* Copyright (c) 2017 Trail of Bits, Inc.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include <glog/logging.h>
|
|
|
|
#include <sstream>
|
|
#include <vector>
|
|
|
|
#include <llvm/IR/Constants.h>
|
|
#include <llvm/IR/Function.h>
|
|
#include <llvm/IR/Module.h>
|
|
#include <llvm/IR/Type.h>
|
|
|
|
#include "remill/Arch/Arch.h"
|
|
#include "remill/Arch/Name.h"
|
|
|
|
#include "mcsema/Arch/Arch.h"
|
|
#include "mcsema/BC/Callback.h"
|
|
#include "mcsema/BC/External.h"
|
|
#include "mcsema/BC/Util.h"
|
|
#include "mcsema/CFG/CFG.h"
|
|
|
|
namespace mcsema {
|
|
namespace {
|
|
|
|
// For an external named `external`, return a function with the prototype
|
|
// `uintptr_t external(uintptr_t arg0, uintptr_t arg1, ...);`.
|
|
//
|
|
// TODO(pag,car,artem): Handle floating point types eventually.
|
|
static void DeclareExternal(
|
|
const NativeExternalFunction *cfg_func) {
|
|
|
|
std::vector<llvm::Type *> tys(cfg_func->num_args, gWordType);
|
|
|
|
auto extfun = llvm::Function::Create(
|
|
llvm::FunctionType::get(gWordType, tys, false),
|
|
llvm::GlobalValue::ExternalLinkage,
|
|
cfg_func->name, gModule);
|
|
|
|
if (cfg_func->is_weak) {
|
|
extfun->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
|
|
}
|
|
|
|
extfun->setCallingConv(cfg_func->cc);
|
|
extfun->addFnAttr(llvm::Attribute::NoInline);
|
|
}
|
|
|
|
static llvm::GlobalValue::ThreadLocalMode ThreadLocalMode(
|
|
const NativeObject *cfg_obj) {
|
|
if (cfg_obj->is_thread_local) {
|
|
return llvm::GlobalValue::GeneralDynamicTLSModel;
|
|
} else {
|
|
return llvm::GlobalValue::NotThreadLocal;
|
|
}
|
|
}
|
|
|
|
} // namespace
|
|
|
|
// Declare external functions.
|
|
void DeclareExternals(const NativeModule *cfg_module) {
|
|
for (const auto &entry : cfg_module->name_to_extern_func) {
|
|
auto cfg_func = reinterpret_cast<const NativeExternalFunction *>(
|
|
entry.second->Get());
|
|
|
|
CHECK(cfg_func->is_external)
|
|
<< "Trying to declare function " << cfg_func->name << " as external.";
|
|
|
|
CHECK(cfg_func->name != cfg_func->lifted_name);
|
|
|
|
// The "actual" external function.
|
|
if (!gModule->getFunction(cfg_func->name)) {
|
|
LOG(INFO)
|
|
<< "Adding external function " << cfg_func->name;
|
|
DeclareExternal(cfg_func);
|
|
}
|
|
}
|
|
|
|
// Declare external variables.
|
|
for (const auto &entry : cfg_module->name_to_extern_var) {
|
|
auto cfg_var = reinterpret_cast<const NativeExternalVariable *>(
|
|
entry.second->Get());
|
|
|
|
auto ll_var = gModule->getGlobalVariable(cfg_var->name);
|
|
if (!ll_var) {
|
|
LOG(INFO)
|
|
<< "Adding external variable " << cfg_var->name;
|
|
|
|
auto var_type = llvm::Type::getIntNTy(
|
|
*gContext, static_cast<unsigned>(cfg_var->size * 8));
|
|
|
|
auto linkage = llvm::GlobalValue::ExternalLinkage;
|
|
ll_var = new llvm::GlobalVariable(*gModule, var_type, false,
|
|
linkage, nullptr, cfg_var->name,
|
|
nullptr, ThreadLocalMode(cfg_var));
|
|
}
|
|
|
|
if (!cfg_var->address) {
|
|
cfg_var->address = llvm::ConstantExpr::getPtrToInt(ll_var, gWordType);
|
|
}
|
|
}
|
|
}
|
|
|
|
} // namespace mcsema
|