Skip to content
Snippets Groups Projects
SMPStaticAnalyzer.cpp 61.7 KiB
Newer Older
jdh8d's avatar
jdh8d committed
/*
 * SMPStaticAnalyzer.cpp - <see below>.
 *
 * Copyright (c) 2000, 2001, 2010 - University of Virginia 
 *
 * This file is part of the Memory Error Detection System (MEDS) infrastructure.
 * This file may be used and modified for non-commercial purposes as long as 
 * all copyright, permission, and nonwarranty notices are preserved.  
 * Redistribution is prohibited without prior written consent from the University 
 * of Virginia.
 *
 * Please contact the authors for restrictions applying to commercial use.
 *
 * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
 * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 *
 * Author: University of Virginia
 * e-mail: jwd@virginia.com
 * URL   : http://www.cs.virginia.edu/
 *
 * Additional copyrights 2010, 2011, 2012, 2013, 2014, 2015 by Zephyr Software LLC
 * e-mail: {clc,jwd}@zephyr-software.com
 * URL   : http://www.zephyr-software.com/
jdh8d's avatar
jdh8d committed
 */

//
// SMPStaticAnalyzer.cpp
//
// This plugin performs the static analyses needed for the SMP project
//   (Software Memory Protection).
//

#include <set>
jdh8d's avatar
jdh8d committed
#include <interfaces/idapro/all.h>
#if 0 // should all be in interfaces/idapro/all.h
#include <ida.hpp>
#include <idp.hpp>
#include <ua.hpp>
#include <bytes.hpp>
jdh8d's avatar
jdh8d committed
#endif
#include <loader.hpp>  // for plugin_t
#include "interfaces/STARSTypes.h"
#include "interfaces/STARSIDATypes.h"
#include "interfaces/SMPDBInterface.h"
#include "base/SMPStaticAnalyzer.h"
#include "base/SMPDataFlowAnalysis.h"
#include "base/SMPProgram.h"
#include "base/SMPFunction.h"
#include "base/SMPInstr.h"
#include "base/ProfilerInformation.h"
#include "interfaces/abstract/STARSOp.h"
#include "interfaces/abstract/STARSInterface.h"
#include "interfaces/idapro/STARSInterface.h"
#include "interfaces/idapro/STARSProgram.h"
#define SMP_DEBUG_DELAY 0   // for setting an early breakpoint
#define SMP_DELAY_TIME 25.0  // 25 seconds

// Set to 1 for debugging output
#define SMP_DEBUG 1
#define SMP_DEBUG3 0   // verbose
#define SMP_DEBUG_MEM 0 // print memory operands
#define SMP_DEBUG_TYPE0 0 // Output instr info for OptType = 0
#define SMP_DEBUG_CHUNKS 0 // restructuring tail chunks, shared chunks, etc.
#define SMP_DEBUG_DATA_ONLY 0  // Find & fix data addresses in code segments

// Set to 1 when doing a binary search using SMP_DEBUG_COUNT to find
//  which function is causing a problem.
#define SMP_BINARY_DEBUG 0
#define SMP_DEBUG_COUNT 356  // How many funcs to process in problem search
int FuncsProcessed = 0;

#define SMP_FIXUP_IDB 0  // Try to fix the IDA database? NOTE: Needs lots of updating before re-enabling.
clc5q's avatar
clc5q committed
#define SMP_DEBUG_FIXUP_IDB 0  // debugging output for FixupIDB chain
#define SMP_FIND_ORPHANS 1  // find code outside of functions
#define SMP_DEBUG_CODE_ORPHANS 0 // Detect whether we are causing code to be orphaned
#define SMP_IDAP_RUN_DELAY 0  // Delay in IDAP_run() so we can attach debugger to process.
#define STARS_GENERATE_DIF_FILE STARS_SCCP_CONVERT_UNREACHABLE_BLOCKS  // If we optimize, generate DIF file
static SMPProgram *CurrProg = nullptr;
STARS_Interface_t* global_stars_interface = nullptr;
STARS_Program_t *global_STARS_program = nullptr;
// Should we convert the x86 LOCK prefix byte to a no-op to avoid
//  IDA Pro problems with instructions that jump past the LOCK
//  prefix and look like they are jumping into the middle of an
//  instruction?
#define STARS_REMOVE_LOCK_PREFIX 0
// Lock prefix for x86 code; jumping around this prefix conditionally looks like jumping
//  into the middle of an instruction to IDA Pro, causing it to not collect instructions
//  into a procedure. We replace these bytes with no-op opcodes because none of our analyses
//  care about LOCK prefices. We store the addresses where we have done the replacement in a 
//  set in case we ever care.
#define X86_LOCK_PREFIX 0xF0
set<STARS_ea_t> LockPreficesRemoved; // Addresses where x86 LOCK prefix byte was turned into a no-op by STARS_custom_ana() callback.
static unsigned long CustomAnaCallCount = 0;

// Code addresses identified by a disassembler, such as objdump on
//  Linux. These can be used to improve the code vs. data identification
//  of IDA Pro.
// Code addresses as identified by IDA Pro, to be compared to DisasmLocs.

// List of functions that need to be reanalyzed after all the code fixup
//  and code discovery is complete. Kept as a list of addresses; any address
//  within the function is good enough to designate it.
list<STARS_ea_t> FuncReanalyzeList;

// A code region that has been converted from data but has code addresses that
//  need to be reanalyzed. This is usually because a former data address is
//  now a jump to a code target that is still a data address. We have to wait
//  until the target has become code before IDA will accept the jump as valid.
class FixupRegion {
public:
	FixupRegion(SMP_bounds_t);
	inline STARS_ea_t GetStart(void) const { return CodeRegion.startEA; };
	inline STARS_ea_t GetEnd(void) const { return CodeRegion.endEA; };
	inline void SetStart(STARS_ea_t addr) { CodeRegion.startEA = addr; };
	list<STARS_ea_t> FixupInstrs; // easier to expose than to encapsulate
private:
	SMP_bounds_t CodeRegion;
};

FixupRegion::FixupRegion(SMP_bounds_t Range) {
	this->CodeRegion = Range;
	return;
}

// List of code regions that were not completely analysed because of jump to
//  data considerations.
list<FixupRegion> CodeReanalyzeList;
// Map library function names to their system call type.
map<string, ZST_SysCallType> ZST_FuncTypeMap;

// Map system call types to their Zephyr Security Toolkit security policy.
map<ZST_SysCallType, ZST_Policy> ZST_TypePolicyMap;

// Set of whitelisted file locations.
set<string> ZST_FileLocWhitelist;

// Set of whitelisted network locations.
set<string> ZST_NetworkLocWhitelist;

// Set of blacklisted file locations.
set<string> ZST_FileLocBlacklist;

// Set of blacklisted network locations.
set<string> ZST_NetworkLocBlacklist;

// Set of system call names whose returned values should be trusted to have only benign numeric errors.
set<string> ZST_SystemCallNumericWhitelist;
clc5q's avatar
clc5q committed
#if (IDA_SDK_VERSION < 700)
void idaapi IDAP_run(int);
clc5q's avatar
clc5q committed
#else
bool idaapi IDAP_run(std::size_t);
clc5q's avatar
clc5q committed
#endif
void IDAP_term(void);

// Functions for diagnosing and/or fixing problems in the IDA database.
void FixupIDB(void);  // Driver for all other fixing functions.
void FindDataInCode(void);
void AuditTailChunkOwnership(void);
jdh8d's avatar
jdh8d committed
void FindOrphanedCode(STARS_Segment_t *, FILE *, FILE *);
void Debug_FindOrphanedCode(STARS_Segment_t *, bool);
void FindLinksFromOrphanedCode(STARS_Segment_t *);
void AuditCodeTargets(void);
void SpecialDebugOutput(void);
void RemoveIDACodeAddr(STARS_ea_t);
static unsigned long DebugCounter = 0;

// Turn LOCK prefix into no-op when detected. Each is one byte in length.
bool STARS_custom_ana(STARS_ea_t CurrentAddr) {
	// static_assert(sizeof(STARS_ea_t) == sizeof(uintptr_t), "Sizeof mismatch between STARS_ea_t and uintptr_t");
Loading
Loading full blame...