1 // Copyright (c) 2006, Google Inc.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 //     * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 //     * Redistributions in binary form must reproduce the above
11 // copyright notice, this list of conditions and the following disclaimer
12 // in the documentation and/or other materials provided with the
13 // distribution.
14 //     * Neither the name of Google Inc. nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 
30 // macho_id.h: Functions to gather identifying information from a macho file
31 //
32 // Author: Dan Waylonis
33 
34 #ifndef COMMON_MAC_MACHO_ID_H__
35 #define COMMON_MAC_MACHO_ID_H__
36 
37 #include <limits.h>
38 #include <mach/machine.h>
39 #include <mach-o/loader.h>
40 
41 #include "common/mac/macho_walker.h"
42 #include "common/md5.h"
43 
44 namespace MacFileUtilities {
45 
46 class MachoID {
47  public:
48   MachoID(const char *path);
49   MachoID(const char *path, void *memory, size_t size);
50   ~MachoID();
51 
52   // For the given |cpu_type| and |cpu_subtype|, return a UUID from the LC_UUID
53   // command.
54   // Return false if there isn't a LC_UUID command.
55   bool UUIDCommand(cpu_type_t cpu_type,
56                    cpu_subtype_t cpu_subtype,
57                    unsigned char identifier[16]);
58 
59   // For the given |cpu_type| and |cpu_subtype|, return a UUID from the
60   // LC_ID_DYLIB command.
61   // Return false if there isn't a LC_ID_DYLIB command.
62   bool IDCommand(cpu_type_t cpu_type,
63                  cpu_subtype_t cpu_subtype,
64                  unsigned char identifier[16]);
65 
66   // For the given |cpu_type| and |cpu_subtype|, return the Adler32 CRC for the
67   // mach-o data segment(s).
68   // Return 0 on error (e.g., if the file is not a mach-o file)
69   uint32_t Adler32(cpu_type_t cpu_type,
70                    cpu_subtype_t cpu_subtype);
71 
72   // For the given |cpu_type|, and |cpu_subtype| return the MD5 for the mach-o
73   // data segment(s).
74   // Return true on success, false otherwise
75   bool MD5(cpu_type_t cpu_type,
76            cpu_subtype_t cpu_subtype,
77            unsigned char identifier[16]);
78 
79  private:
80   // Signature of class member function to be called with data read from file
81   typedef void (MachoID::*UpdateFunction)(unsigned char *bytes, size_t size);
82 
83   // Update the CRC value by examining |size| |bytes| and applying the algorithm
84   // to each byte.
85   void UpdateCRC(unsigned char *bytes, size_t size);
86 
87   // Update the MD5 value by examining |size| |bytes| and applying the algorithm
88   // to each byte.
89   void UpdateMD5(unsigned char *bytes, size_t size);
90 
91   // Bottleneck for update routines
92   void Update(MachoWalker *walker, off_t offset, size_t size);
93 
94   // Factory for the MachoWalker
95   bool WalkHeader(cpu_type_t cpu_type, cpu_subtype_t cpu_subtype,
96                   MachoWalker::LoadCommandCallback callback, void *context);
97 
98   // The callback from the MachoWalker for CRC and MD5
99   static bool WalkerCB(MachoWalker *walker, load_command *cmd, off_t offset,
100                        bool swap, void *context);
101 
102   // The callback from the MachoWalker for LC_UUID
103   static bool UUIDWalkerCB(MachoWalker *walker, load_command *cmd, off_t offset,
104                            bool swap, void *context);
105 
106   // The callback from the MachoWalker for LC_ID_DYLIB
107   static bool IDWalkerCB(MachoWalker *walker, load_command *cmd, off_t offset,
108                          bool swap, void *context);
109 
110   // File path
111   char path_[PATH_MAX];
112 
113   // Memory region to read from
114   void *memory_;
115 
116   // Size of the memory region
117   size_t memory_size_;
118 
119   // The current crc value
120   uint32_t crc_;
121 
122   // The MD5 context
123   google_breakpad::MD5Context md5_context_;
124 
125   // The current update to call from the Update callback
126   UpdateFunction update_function_;
127 };
128 
129 }  // namespace MacFileUtilities
130 
131 #endif  // COMMON_MAC_MACHO_ID_H__
132