ROSE  0.11.145.0
I386Linux/Architecture.h
1 #ifndef ROSE_BinaryAnalysis_Concolic_I386Linux_Architecture_H
2 #define ROSE_BinaryAnalysis_Concolic_I386Linux_Architecture_H
3 #include <featureTests.h>
4 #ifdef ROSE_ENABLE_CONCOLIC_TESTING
5 
6 #include <Rose/BinaryAnalysis/Concolic/Architecture.h>
7 #include <Rose/BinaryAnalysis/Concolic/ExecutionEvent.h>
8 #include <Rose/BinaryAnalysis/Concolic/SharedMemory.h>
9 #include <Rose/BinaryAnalysis/Concolic/SystemCall.h>
10 #include <Rose/Yaml.h>
11 
12 #include <boost/filesystem.hpp>
13 #include <Sawyer/Callbacks.h>
14 
15 namespace Rose {
16 namespace BinaryAnalysis {
17 namespace Concolic {
18 namespace I386Linux {
19 
21 // Linux Intel 80386 and compatible hardware architecture.
23 
25 class Architecture: public Concolic::Architecture {
26  using Super = Concolic::Architecture;
27 
28 public:
30  using Ptr = ArchitecturePtr;
31 
32 private:
33  bool markingArgvAsInput_ = true;
34  bool markingEnvpAsInput_ = false;
35 
36 protected:
37  Architecture(const std::string&); // for instantiating a factory
38  Architecture(const DatabasePtr&, TestCaseId);
39 public:
40  ~Architecture();
41 
42 public:
44  static Ptr factory();
45 
51  static Ptr instance(const DatabasePtr&, TestCaseId, const Yaml::Node &config);
52  static Ptr instance(const DatabasePtr&, const TestCasePtr&, const Yaml::Node &config);
55 public:
56  // Same as super class, but casts result to a Linux debugger.
57  Debugger::LinuxPtr debugger() const;
58 
60  RegisterDescriptor systemCallReturnRegister();
61 
62 public:
63  // These are documented in the base class.
64  virtual bool matchFactory(const Yaml::Node&) const override;
65  virtual Super::Ptr instanceFromFactory(const DatabasePtr&, TestCaseId, const Yaml::Node &config) const override;
66  virtual Partitioner2::PartitionerPtr partition(const Partitioner2::EnginePtr&, const std::string &specimen) override;
67  virtual void configureSystemCalls() override;
68  virtual void configureSharedMemory(const Yaml::Node &config) override;
69  virtual void load(const boost::filesystem::path&) override;
70  virtual ByteOrder::Endianness memoryByteOrder() override;
71  virtual std::vector<ExecutionEventPtr> createMemoryRestoreEvents() override;
72  virtual std::vector<ExecutionEventPtr> createMemoryHashEvents() override;
73  virtual std::vector<ExecutionEventPtr> createMemoryAdjustEvents(const MemoryMap::Ptr&, rose_addr_t insnVa) override;
74  virtual bool playEvent(const ExecutionEventPtr&) override;
75  virtual void mapMemory(const AddressInterval&, unsigned permissions) override;
76  virtual void unmapMemory(const AddressInterval&) override;
77  virtual void createInputVariables(const Partitioner2::PartitionerConstPtr&, const Emulation::RiscOperatorsPtr&,
78  const SmtSolver::Ptr &solver) override;
79  virtual void systemCall(const Partitioner2::PartitionerConstPtr&,
81  virtual void advanceExecution(const InstructionSemantics::BaseSemantics::RiscOperatorsPtr&) override;
83  makeDispatcher(const InstructionSemantics::BaseSemantics::RiscOperatorsPtr&) override;
84 
85 private:
86  // Maps a scratch page for internal use and updates scratchVa_ with the address of the page.
87  void mapScratchPage();
88 
89  // Copy (share) some data from the dst map to the src map at where. Generate map and write events that will map the memory
90  // and initialize it when played back.
91  std::vector<ExecutionEventPtr> copyMemory(const MemoryMap::Ptr &src, const MemoryMap::Ptr &dst, const AddressInterval &where,
92  rose_addr_t insnVa);
93 
94  // List of process memory segments that are not special.
95  std::vector<MemoryMap::ProcessMapRecord> disposableMemory();
96 
97  // Unmap nearly all memory. The scratch page is not unmapped, nor is the VDSO or VVAR.
98  void unmapAllMemory();
99 
100  // When stopped at the beginning of a system call, return the system call function number. See <sys/unistd_32.h> for the
101  // mapping function system call number to the Linux kernel function that handles it.
102  uint64_t systemCallFunctionNumber(const Partitioner2::PartitionerConstPtr&,
104 
105  // Returns the system call argument.
107  systemCallArgument(const Partitioner2::PartitionerConstPtr&,
109 
110  // Returns the system call return value.
112  systemCallReturnValue(const Partitioner2::PartitionerConstPtr&,
114 
115  // Modify the symbolic system call return value.
117  systemCallReturnValue(const Partitioner2::PartitionerConstPtr&,
120 
121 };
122 
124 // Linux i386 specific system call operations.
126 
130 class SyscallBase: public SyscallCallback {
131  ExecutionEventPtr latestReturnEvent_; // event for most recent system call return
132  ExecutionEventPtr penultimateReturnEvent_; // event for next most recent system call return
133 
134 public:
135  SyscallBase();
136  virtual ~SyscallBase();
137 
143  void hello(const std::string &name, const SyscallContext&) const;
144 
150  virtual void playback(SyscallContext&) = 0;
151 
169  virtual void handlePreSyscall(SyscallContext&) {}
170  virtual void handlePostSyscall(SyscallContext&) = 0;
187  ExecutionEventPtr latestReturnEvent() const;
188  ExecutionEventPtr penultimateReturnEvent() const;
195  void showRecentReturnValues(std::ostream&, const SyscallContext&) const;
196 
202  SymbolicExpressionPtr penultimateSymbolicReturn() const;
203 
204 public:
205  // Subclasses need not provide a function operator.
206  virtual bool operator()(bool /*handled*/, SyscallContext&) override final;
207 };
208 
214 class SyscallUnimplemented: public SyscallBase {
215 protected:
216  SyscallUnimplemented();
217 public:
218  ~SyscallUnimplemented();
219 
220 public:
222  static Ptr instance();
223 
224  void playback(SyscallContext&) override;
225  void handlePostSyscall(SyscallContext&) override;
226 };
227 
232 class SyscallReturnsInput: public SyscallBase {
233 protected:
234  SyscallReturnsInput();
235 public:
236  ~SyscallReturnsInput();
237 
238 public:
240  static Ptr instance();
241 
242  void playback(SyscallContext&) override;
243  void handlePostSyscall(SyscallContext&) override;
244 };
245 
247 class SyscallTerminates: public SyscallBase {
248 protected:
249  SyscallTerminates();
250 public:
251  ~SyscallTerminates();
252 
253 public:
255  static Ptr instance();
256 
257  void playback(SyscallContext&) override;
258  void handlePostSyscall(SyscallContext&) override;
259 };
260 
264 class SyscallReturn: public SyscallBase {
265 protected:
266  SyscallReturn();
267 public:
268  ~SyscallReturn();
269 
270 protected:
277  virtual std::pair<SymbolicExpressionPtr, Sawyer::Optional<uint64_t>> makeReturnConstraint(SyscallContext&) = 0;
278 
279 public:
280  void handlePostSyscall(SyscallContext&) override final;
281 };
282 
288 class SyscallConstant: public SyscallReturn {
289 protected:
290  SyscallConstant();
291 public:
292  ~SyscallConstant();
293 
294 public:
296  static Ptr instance();
297 
298  void playback(SyscallContext&) override;
299  std::pair<SymbolicExpressionPtr, Sawyer::Optional<uint64_t>> makeReturnConstraint(SyscallContext&) override;
300 };
301 
305 class SyscallNondecreasing: public SyscallReturn {
306 protected:
307  SyscallNondecreasing();
308 public:
309  ~SyscallNondecreasing();
310 
311 public:
313  static Ptr instance();
314 
315  void playback(SyscallContext&) override;
316  std::pair<SymbolicExpressionPtr, Sawyer::Optional<uint64_t>> makeReturnConstraint(SyscallContext&) override;
317 };
318 
320 class SyscallAccess: public SyscallBase {
321 protected:
322  SyscallAccess();
323 public:
324  ~SyscallAccess();
325 
326 public:
328  static Ptr instance();
329 
330  void playback(SyscallContext&) override;
331  void handlePostSyscall(SyscallContext&) override;
332 };
333 
335 class SyscallBrk: public SyscallBase {
336 protected:
337  SyscallBrk();
338 public:
339  ~SyscallBrk();
340 
341 public:
343  static Ptr instance();
344 
345  void playback(SyscallContext&) override;
346  void handlePostSyscall(SyscallContext&) override;
347 };
348 
350 class SyscallMmap2: public SyscallBase {
351 protected:
352  SyscallMmap2();
353 public:
354  ~SyscallMmap2();
355 
356 public:
358  static Ptr instance();
359 
360  void playback(SyscallContext&) override;
361  void handlePostSyscall(SyscallContext&) override;
362 };
363 
365 class SyscallOpenat: public SyscallBase {
366 protected:
367  SyscallOpenat();
368 public:
369  ~SyscallOpenat();
370 
371 public:
373  static Ptr instance();
374 
375  void playback(SyscallContext&) override;
376  void handlePostSyscall(SyscallContext&) override;
377 };
378 
379 } // namespace
380 } // namespace
381 } // namespace
382 } // namespace
383 
384 #endif
385 #endif
SmtSolverPtr Ptr
Reference counting pointer for SMT solvers.
Definition: SmtSolver.h:45
boost::shared_ptr< RiscOperators > RiscOperatorsPtr
Shared-ownership pointer to a RISC operators object.
Main namespace for the ROSE library.
boost::shared_ptr< Dispatcher > DispatcherPtr
Shared-ownership pointer to a semantics instruction dispatcher.
MemoryMapPtr Ptr
Reference counting pointer.
Definition: MemoryMap.h:115
Sawyer::SharedPointer< Partitioner > PartitionerPtr
Shared-ownership pointer for Partitioner.
ROSE_DLL_API void load(SgProject *project, std::list< std::string > const &filepaths)
Load ASTs that have been saved to files.
Sawyer::SharedPointer< const Partitioner > PartitionerConstPtr
Shared-ownership pointer for Partitioner.
const char * Architecture(int64_t)
Convert Rose::BinaryAnalysis::Disassembler::Mips::Decoder::Architecture enum constant to a string...
Sawyer::SharedPointer< Engine > EnginePtr
Shared-ownership pointer for Engine.
Sawyer::SharedPointer< SValue > SValuePtr
Shared-ownership pointer to a semantic value in any domain.
Range of values delimited by endpoints.
Definition: Interval.h:33
Sawyer::SharedPointer< Node > Ptr
Reference counting pointer.