Skip to content

Commit

Permalink
Initial build of ClamBCLogicalCompiler (#37)
Browse files Browse the repository at this point in the history
  • Loading branch information
ragusaa authored Sep 7, 2023
1 parent ef76364 commit 89ab7cb
Show file tree
Hide file tree
Showing 4 changed files with 208 additions and 40 deletions.
1 change: 1 addition & 0 deletions libclambcc/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Copyright (C) 2021 Cisco Systems, Inc. and/or its affiliates. All rights reserved.


add_subdirectory(ClamBCLogicalCompiler)
add_subdirectory(ClamBCRemoveUndefs)
add_subdirectory(ClamBCPreserveABIs)
add_subdirectory(ClamBCAnalyzer)
Expand Down
72 changes: 72 additions & 0 deletions libclambcc/ClamBCLogicalCompiler/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Copyright (C) 2021 Cisco Systems, Inc. and/or its affiliates. All rights reserved.

#
# The clambclogicalcompiler object library
#
add_library(clambclogicalcompiler_obj OBJECT)
target_sources(clambclogicalcompiler_obj
PRIVATE
ClamBCLogicalCompiler.cpp
)

target_include_directories(clambclogicalcompiler_obj
PRIVATE
${CMAKE_BINARY_DIR} # For clambc-version.h (generated file)
. # For Common/clambc.h
.. # For clambc.h #TODO: change all passes to use "Common" and then delete this line.
${LLVM_INCLUDE_DIRS}
)

set_target_properties(clambclogicalcompiler_obj PROPERTIES COMPILE_FLAGS "${WARNCXXFLAGS}")

#
# For testing
#
#target_compile_definitions(clambclogicalcompiler_obj -DLOG_BEFORE_AFTER=1)

#
# The clambclogicalcompiler shared library.
#
add_library( clambclogicalcompiler SHARED )
target_link_libraries( clambclogicalcompiler
PUBLIC
clambclogicalcompiler_obj )
set_target_properties( clambclogicalcompiler PROPERTIES
VERSION ${LIBCLAMBC_VERSION}
SOVERSION ${LIBCLAMBC_SOVERSION} )

target_link_directories(clambclogicalcompiler PRIVATE ${LLVM_LIBRARY_DIRS})
target_link_libraries(clambclogicalcompiler PUBLIC ${LLVM_LIBS})

if(WIN32)
install(TARGETS clambclogicalcompiler DESTINATION .)

# Also install shared library (DLL) dependencies
install(CODE [[
file(GET_RUNTIME_DEPENDENCIES
LIBRARIES
$<TARGET_FILE:clambclogicalcompiler>
RESOLVED_DEPENDENCIES_VAR _r_deps
UNRESOLVED_DEPENDENCIES_VAR _u_deps
DIRECTORIES
${LLVM_LIBRARY_DIRS}
)
foreach(_file ${_r_deps})
string(TOLOWER ${_file} _file_lower)
if(NOT ${_file_lower} MATCHES "c:[\\/]windows[\\/]system32.*")
file(INSTALL
DESTINATION "${CMAKE_INSTALL_PREFIX}"
TYPE SHARED_LIBRARY
FOLLOW_SYMLINK_CHAIN
FILES "${_file}"
)
endif()
endforeach()
#message("UNRESOLVED_DEPENDENCIES_VAR: ${_u_deps}")
]])
else()
install(TARGETS clambclogicalcompiler DESTINATION ${CMAKE_INSTALL_LIBDIR})
endif()



166 changes: 126 additions & 40 deletions libclambcc/ClamBCLogicalCompiler/ClamBCLogicalCompiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,56 +20,59 @@
* MA 02110-1301, USA.
*/

#include "ClamBCModule.h"
#include "Common/ClamBCModule.h"
#include "Common/clambc.h"
#include "Common/bytecode_api.h"
#include "Common/ClamBCDiagnostics.h"
#include "Common/ClamBCCommon.h"
#include "Common/ClamBCUtilities.h"

#include <llvm/Support/DataTypes.h>
#include "../Common/bytecode_api.h"
#include "clambc.h"
#include "ClamBCDiagnostics.h"
#include "ClamBCModule.h"
#include "ClamBCCommon.h"
#include "ClamBCUtilities.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/Analysis/ConstantFolding.h"
#include <llvm/ADT/FoldingSet.h>
#include <llvm/ADT/SmallPtrSet.h>
#include <llvm/ADT/StringSet.h>
#include <llvm/Analysis/ConstantFolding.h>
#include <llvm/IR/DebugInfo.h>
#include "llvm/Analysis/ValueTracking.h"
#include <llvm/Analysis/ValueTracking.h>
#include <llvm/IR/DerivedTypes.h>
#include <llvm/IR/IntrinsicInst.h>
#include <llvm/IR/Module.h>
#include <llvm/Pass.h>
//#include <llvm/IR/PassManager.h>
#include <llvm/IR/LegacyPassManager.h>
#include <llvm/IR/CallSite.h>
#include <llvm/IR/PassManager.h>
#include <llvm/Passes/PassBuilder.h>
#include <llvm/Passes/PassPlugin.h>
#include <llvm/IR/ConstantRange.h>
#include "llvm/Support/Debug.h"
#include <llvm/Support/Debug.h>
#include <llvm/IR/InstIterator.h>
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/raw_ostream.h"
#include <llvm/Support/FormattedStream.h>
#include <llvm/Support/raw_ostream.h>
#include <llvm/Support/Process.h>
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Transforms/IPO.h"
#include <llvm/Transforms/Scalar.h>
#include <llvm/Transforms/Utils/Local.h>
#include <llvm/Transforms/IPO.h>
#include <llvm/IR/Type.h>
//#include <llvm/IR/DataLayout.h>
#include <llvm/Transforms/Utils.h>
#include <llvm/LinkAllPasses.h>


#define DEBUG_TYPE "lsigcompiler"

using namespace llvm;

namespace
namespace ClamBCLogicalCompiler
{

class ClamBCLogicalCompiler : public ModulePass
class ClamBCLogicalCompiler : public PassInfoMixin<ClamBCLogicalCompiler>
{
public:
#if 0
static char ID;
#endif
ClamBCLogicalCompiler()
: ModulePass(ID) {}
/* : ModulePass(ID) */ {}

virtual bool runOnModule(Module &M);
//virtual bool runOnModule(Module &M);
virtual PreservedAnalyses run(Module & m, ModuleAnalysisManager & MAM);
virtual void getAnalysisUsage(AnalysisUsage &AU) const
{
AU.setPreservesCFG();
Expand All @@ -90,9 +93,9 @@ class ClamBCLogicalCompiler : public ModulePass
bool compileVirusNames(Module &M, unsigned kind);
};

char ClamBCLogicalCompiler::ID = 0;
RegisterPass<ClamBCLogicalCompiler> X("clambc-lcompiler",
"ClamAV Logical Compiler");



enum LogicalKind {
LOG_SUBSIGNATURE,
LOG_AND,
Expand Down Expand Up @@ -1631,6 +1634,7 @@ bool ClamBCLogicalCompiler::compileVirusNames(Module &M, unsigned kind)
bool Valid = true;

for (auto I : F->users()) {
#if 0
Value *pv = nullptr;
pv = llvm::cast<Value>(I);
CallSite CS(pv);
Expand All @@ -1644,14 +1648,48 @@ bool ClamBCLogicalCompiler::compileVirusNames(Module &M, unsigned kind)
continue;
}
assert(CS.arg_size() == 2 && "setvirusname has 2 args");
#else
CallInst * pCallInst = llvm::cast<CallInst>(I);
if (nullptr == pCallInst){
assert (0 && "NOT sure how this is possible");
continue;
}

if (F != pCallInst->getCalledFunction()){

llvm::errs() << "<" << __FUNCTION__ << "::" << __LINE__ << ">NOT SURE HOW THIS IS POSSIBLE<END>\n";

/*Not sure how this is possible, either*/
printDiagnostic("setvirusname can only be directly called",
pCallInst);
Valid = false;
continue;
}
#endif

if (2 != pCallInst->arg_size()){
printDiagnostic("setvirusname has 2 args", pCallInst);
Valid = false;
continue;
}

std::string param;
llvm::StringRef sr;
#if 0
Value *V = CS.getArgument(0);
#else
#endif
Value * V = llvm::cast<Value>(pCallInst->arg_begin());
if (nullptr == V){
printDiagnostic("Invalid argument passed to setvirusname", pCallInst);
Valid = false;
continue;
}
bool result = getConstantStringInfo(V, sr);
param = sr.str();
if (!result) {
printDiagnostic("Argument of foundVirus() must be a constant string",
CS.getInstruction());
pCallInst);
Valid = false;
continue;
}
Expand All @@ -1662,23 +1700,32 @@ bool ClamBCLogicalCompiler::compileVirusNames(Module &M, unsigned kind)
if (!p.empty() && !virusNamesSet.count(p)) {
printDiagnostic(Twine("foundVirus called with an undeclared virusname: ",
p),
CS.getInstruction());
pCallInst);
Valid = false;
continue;
}
// Add prefix
std::string fullname = p.empty() ? virusNamePrefix : virusNamePrefix + "." + p.str();
IRBuilder<> builder(CS.getInstruction()->getParent());
IRBuilder<> builder(pCallInst->getParent());
Value *C = builder.CreateGlobalStringPtr(fullname.c_str());

IntegerType *I32Ty = Type::getInt32Ty(M.getContext());
#if 0
CS.setArgument(0, C);
CS.setArgument(1, ConstantInt::get(I32Ty, fullname.size()));
#else
pCallInst->setArgOperand(0, C);
pCallInst->setArgOperand(1, ConstantInt::get(I32Ty, fullname.size()));
#endif
}
return Valid;
}

#if 0
bool ClamBCLogicalCompiler::runOnModule(Module &M)
#else
PreservedAnalyses ClamBCLogicalCompiler::run(Module & M, ModuleAnalysisManager & MAM)
#endif
{
bool Valid = true;
LogicalSignature = "";
Expand All @@ -1705,14 +1752,21 @@ bool ClamBCLogicalCompiler::runOnModule(Module &M)
GVKind->setConstant(true);
}
if (!compileVirusNames(M, kind)) {
if (!kind || kind == BC_STARTUP)
return true;
if (!kind || kind == BC_STARTUP) {
// return true;
return PreservedAnalyses::all();
}
Valid = false;
}

if (F) {
#if 0
LoopInfo &li = getAnalysis<LoopInfoWrapperPass>(*F).getLoopInfo();
if (functionHasLoop(F, li)) {
#else
FunctionAnalysisManager &fam = MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
LoopInfo * li = &fam.getResult<LoopAnalysis>(*F);
#endif
if (functionHasLoop(F, *li)) {
printDiagnostic("Logical signature: loop/recursion not supported", F);
Valid = false;
}
Expand Down Expand Up @@ -1842,13 +1896,45 @@ bool ClamBCLogicalCompiler::runOnModule(Module &M)
// diagnostic already printed
exit(42);
}
return true;
return PreservedAnalyses::none();
}

} // namespace
const PassInfo *const ClamBCLogicalCompilerID = &X;

llvm::ModulePass *createClamBCLogicalCompiler()
#if 0
const PassInfo *const ClamBCLogicalCompilerID = &X; llvm::ModulePass *createClamBCLogicalCompiler()
{
return new ClamBCLogicalCompiler();
}
#endif


#if 0
char ClamBCLogicalCompiler::ID = 0;
RegisterPass<ClamBCLogicalCompiler> X("clambc-lcompiler",
"ClamAV Logical Compiler");
#else

// This part is the new way of registering your pass
extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK
llvmGetPassPluginInfo() {
return {
LLVM_PLUGIN_API_VERSION, "ClamBCLogicalCompiler", "v0.1",
[](PassBuilder &PB) {
PB.registerPipelineParsingCallback(
[](StringRef Name, ModulePassManager &FPM,
ArrayRef<PassBuilder::PipelineElement>) {
if(Name == "clambc-lcompiler"){
FPM.addPass(ClamBCLogicalCompiler());
return true;
}
return false;
}
);
}
};
}
#endif


} // namespace


9 changes: 9 additions & 0 deletions libclambcc/ClamBCRemoveUndefs/ClamBCRemoveUndefs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,15 @@
#include <llvm/Passes/PassPlugin.h>
#include <llvm/Support/raw_ostream.h>

#include <llvm/Pass.h>
#include <llvm/IR/Module.h>
#include <llvm/IR/Module.h>
#include <llvm/IR/Instructions.h>
#include <llvm/Support/raw_ostream.h>
#include <llvm/IR/PassManager.h>
#include <llvm/Passes/PassBuilder.h>
#include <llvm/Passes/PassPlugin.h>
#include <llvm/Support/raw_ostream.h>
#include <llvm/IR/Dominators.h>

#include <llvm/Transforms/IPO/PassManagerBuilder.h>
Expand Down

0 comments on commit 89ab7cb

Please sign in to comment.