00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "torc/Generic.hpp"
00020 #include "torc/Common.hpp"
00021 #include "torc/externals/md5/md5.h"
00022 #include <iostream>
00023 #include <fstream>
00024 #include <sstream>
00025 #include <iomanip>
00026 #include <boost/filesystem.hpp>
00027 #include <boost/regex.hpp>
00028 #include <boost/cstdint.hpp>
00029 #include <boost/lexical_cast.hpp>
00030
00031 using namespace torc::generic;
00032
00033 boost::uint32_t mIdentifierCount = 0;
00034
00035
00036 std::string md5(const char* inMessage);
00037 std::string obfuscate(const std::string& inIdentifier);
00038 void obfuscate(RootSharedPtr rootPtr, std::fstream& log);
00039
00040
00041 std::string md5(const char* inMessage) {
00042
00043 md5_state_t md5_state;
00044 md5_byte_t digest[16];
00045 md5_init(&md5_state);
00046
00047 md5_append(&md5_state, (md5_byte_t*) inMessage, strlen(inMessage));
00048 md5_finish(&md5_state, digest);
00049
00050 std::ostringstream md5oss;
00051 md5oss << 'i';
00052 for(boost::uint16_t i = 0; i < sizeof(digest); i++) md5oss << std::hex << std::setw(2)
00053 << std::setfill('0') << (boost::uint16_t) (digest[i] & 0xff) << std::dec;
00054 return md5oss.str();
00055 }
00056
00057
00058 std::string obfuscate(const std::string& inIdentifier) {
00059
00060
00061 std::string message = boost::lexical_cast<std::string>(mIdentifierCount++);
00062
00063 std::string hash = md5(message.c_str());
00064
00065 return hash;
00066 }
00067
00068 void obfuscate(RootSharedPtr rootPtr, std::fstream& log) {
00069
00070
00071 mIdentifierCount = 0;
00072
00073
00074 typedef std::map<std::string, bool> StringToBoolMap;
00075 StringToBoolMap protectedCells;
00076 StringToBoolMap protectedLibraries;
00077
00078
00079 typedef std::vector<DesignSharedPtr> DesignSharedPtrVector;
00080 DesignSharedPtrVector designs;
00081 rootPtr->getDesigns(designs);
00082 DesignSharedPtrVector::iterator dp = designs.begin();
00083 DesignSharedPtrVector::iterator de = designs.end();
00084 while(dp < de) {
00085
00086
00087 DesignSharedPtr& designPtr = *dp++;
00088 std::string designName = designPtr->getName();
00089 std::string cellRefName = designPtr->getCellRefName();
00090 std::string libraryRefName = designPtr->getLibraryRefName();
00091 std::cout << " Protecting design \"" << designName << "\" (cell \"" << cellRefName
00092 << "\", library \"" << libraryRefName << "\")" << std::endl;
00093 protectedCells[libraryRefName + ":" + cellRefName] = true;
00094 protectedLibraries[libraryRefName] = true;
00095
00096 }
00097
00098
00099 boost::regex regexVendorLibraries("^(VhdlGenLib|virtex|virtexr|unilib)$",
00100 boost::regex_constants::icase);
00101
00102
00103 typedef std::vector<LibrarySharedPtr> LibrarySharedPtrVector;
00104 LibrarySharedPtrVector libraries;
00105 rootPtr->getLibraries(libraries);
00106 LibrarySharedPtrVector::iterator lp = libraries.begin();
00107 LibrarySharedPtrVector::iterator le = libraries.end();
00108 while(lp < le) {
00109
00110
00111 LibrarySharedPtr& libraryPtr = *lp++;
00112 std::string libraryName = libraryPtr->getName();
00113
00114
00115
00116 if(boost::regex_search(libraryName, regexVendorLibraries)) continue;
00117
00118
00119 typedef std::vector<CellSharedPtr> CellSharedPtrVector;
00120 CellSharedPtrVector cells;
00121 libraryPtr->getCells(cells);
00122 CellSharedPtrVector::iterator cp = cells.begin();
00123 CellSharedPtrVector::iterator ce = cells.end();
00124 while(cp < ce) {
00125
00126 CellSharedPtr& cellPtr = *cp++;
00127 std::string cellName = cellPtr->getName();
00128
00129 typedef std::vector<ViewSharedPtr> ViewSharedPtrVector;
00130 ViewSharedPtrVector views;
00131 cellPtr->getViews(views);
00132 ViewSharedPtrVector::iterator vp = views.begin();
00133 ViewSharedPtrVector::iterator ve = views.end();
00134 while(vp < ve) {
00135
00136 ViewSharedPtr& viewPtr = *vp++;
00137 std::string viewName = viewPtr->getName();
00138 if(viewName == "syn_black_box") {
00139 protectedLibraries[libraryName] = true;
00140 protectedCells[libraryName + ":" + cellName] = true;
00141 }
00142 }
00143 }
00144
00145
00146 bool libraryIsProtected = protectedLibraries.count(libraryName) > 0;
00147 if(!libraryIsProtected) {
00148 std::string obfuscatedLibraryName
00149 = libraryIsProtected ? libraryName : obfuscate(libraryName);
00150 libraryPtr->setName(obfuscatedLibraryName);
00151 libraryPtr->setOriginalName("");
00152 log << "library " << libraryName << "=> " << obfuscatedLibraryName << std::endl;
00153 }
00154
00155
00156
00157
00158
00159
00160
00161 cp = cells.begin();
00162 ce = cells.end();
00163 while(cp < ce) {
00164
00165
00166 CellSharedPtr& cellPtr = *cp++;
00167 std::string cellName = cellPtr->getName();
00168
00169
00170
00171 bool cellIsProtected = protectedCells.count(libraryName + ":" + cellName) > 0;
00172 if(cellIsProtected == false) {
00173 std::string obfuscatedCellName = obfuscate(cellName);
00174 cellPtr->setName(obfuscatedCellName);
00175 cellPtr->setOriginalName("");
00176 log << "cell " << cellName << " => " << obfuscatedCellName << std::endl;
00177 } else {
00178 log << "cell " << cellName << " => " << cellName << std::endl;
00179 }
00180
00181
00182 typedef std::vector<ViewSharedPtr> ViewSharedPtrVector;
00183 ViewSharedPtrVector views;
00184 cellPtr->getViews(views);
00185 ViewSharedPtrVector::iterator vp = views.begin();
00186 ViewSharedPtrVector::iterator ve = views.end();
00187 while(vp < ve) {
00188
00189
00190 ViewSharedPtr& viewPtr = *vp++;
00191 std::string viewName = viewPtr->getName();
00192
00193
00194
00195 if(cellIsProtected == false) {
00196 std::string obfuscatedViewName = obfuscate(viewName);
00197 viewPtr->setName(obfuscatedViewName);
00198 viewPtr->setOriginalName("");
00199 log << " view " << viewName << " => " << obfuscatedViewName << std::endl;
00200 } else {
00201 log << " view " << viewName << " => " << viewName << std::endl;
00202 }
00203
00204
00205 typedef std::vector<PortSharedPtr> PortSharedPtrVector;
00206 PortSharedPtrVector ports;
00207 viewPtr->getPorts(ports);
00208 PortSharedPtrVector::iterator pp = ports.begin();
00209 PortSharedPtrVector::iterator pe = ports.end();
00210 while(pp < pe) {
00211
00212
00213 PortSharedPtr& portPtr = *pp++;
00214 std::string portName = portPtr->getName();
00215
00216
00217
00218 if(cellIsProtected == false) {
00219 std::string obfuscatedPortName = obfuscate(portName);
00220 portPtr->setName(obfuscatedPortName);
00221 std::string originalName = portPtr->getOriginalName();
00222
00223 boost::smatch what;
00224 boost::regex re(".*([\\(\\[].+[\\)\\]])");
00225 if(boost::regex_match(originalName, what, re, boost::match_default)) {
00226 std::string newName = obfuscatedPortName
00227 + std::string(what[1].first, what[1].second);
00228
00229
00230 originalName = newName;
00231 }
00232 portPtr->setOriginalName(originalName);
00233 log << " port " << portName << " => " << obfuscatedPortName
00234 << std::endl;
00235 } else {
00236 log << " port " << portName << " => " << portName << std::endl;
00237 }
00238
00239 }
00240
00241
00242 typedef std::vector<InstanceSharedPtr> InstanceSharedPtrVector;
00243 InstanceSharedPtrVector instances;
00244 viewPtr->getInstances(instances);
00245 InstanceSharedPtrVector::iterator ip = instances.begin();
00246 InstanceSharedPtrVector::iterator ie = instances.end();
00247 while(ip < ie) {
00248
00249
00250 InstanceSharedPtr& instancePtr = *ip++;
00251 std::string instanceName = instancePtr->getName();
00252
00253
00254
00255
00256 std::string obfuscatedInstanceName = obfuscate(instanceName);
00257 instancePtr->setName(obfuscatedInstanceName);
00258 instancePtr->setOriginalName("");
00259 log << " instance " << instanceName << " => " << obfuscatedInstanceName
00260 << std::endl;
00261
00262 }
00263
00264
00265 typedef std::vector<NetSharedPtr> NetSharedPtrVector;
00266 NetSharedPtrVector nets;
00267 viewPtr->getNets(nets);
00268 NetSharedPtrVector::iterator np = nets.begin();
00269 NetSharedPtrVector::iterator ne = nets.end();
00270 while(np < ne) {
00271
00272
00273 NetSharedPtr& netPtr = *np++;
00274 std::string netName = netPtr->getName();
00275
00276
00277
00278 std::string obfuscatedNetName = obfuscate(netName);
00279 netPtr->setName(obfuscatedNetName);
00280 netPtr->setOriginalName("");
00281 log << " net " << netName << " => " << obfuscatedNetName << std::endl;
00282
00283
00284 typedef std::vector<PortSharedPtr> PortSharedPtrVector;
00285 PortSharedPtrVector ports;
00286 netPtr->getConnectedPorts(ports, false);
00287 PortSharedPtrVector::iterator pp = ports.begin();
00288 PortSharedPtrVector::iterator pe = ports.end();
00289 while(pp < pe) {
00290
00291 PortSharedPtr& portPtr = *pp++;
00292 std::string portName = portPtr->getName();
00293 std::string parentPortName;
00294 CompositionType compositionType = portPtr->getCompositionType();
00295 switch(compositionType) {
00296 case eCompositionTypeScalar:
00297 parentPortName = portPtr->getName();
00298 if(parentPortName == portName) break;
00299 portPtr->setName(parentPortName);
00300
00301
00302
00303 break;
00304 case eCompositionTypeVectorBit: {
00305 const PortSharedPtr& vectorPtr = portPtr->getParentCollection();
00306 parentPortName = vectorPtr->getName();
00307 if(parentPortName == portName) break;
00308 vectorPtr->setName(parentPortName);
00309
00310
00311
00312 } break;
00313 default:
00314 std::cerr << "ERROR: Unsupported composition type "
00315 << compositionType << " in " << __FILE__ << " line "
00316 << __LINE__ << std::endl;
00317 break;
00318 }
00319
00320 }
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363 }
00364 }
00365
00366 }
00367
00368 }
00369 }
00370
00371 int main(int argc, char** argv) {
00372
00373
00374 for(int i = 1; i < argc; i++) {
00375
00376 boost::filesystem::path sourcePath = argv[i];
00377 boost::filesystem::path targetPath = sourcePath;
00378 targetPath = targetPath.replace_extension().string()
00379 + ".mod" + boost::filesystem::extension(sourcePath);
00380 boost::filesystem::path logPath = sourcePath;
00381 logPath = logPath.replace_extension().string() + ".obfuscation_log";
00382
00383 try {
00384
00385 std::cout << "Reading source: " << sourcePath.string() << " ... ";
00386 std::cout.flush();
00387 boost::shared_ptr<ObjectFactory> factoryPtr(new ObjectFactory());
00388 boost::shared_ptr<Root> rootPtr;
00389 factoryPtr->create(rootPtr);
00390 boost::shared_ptr<Linker> linkerPtr(new Linker(rootPtr));
00391 ParserOptions options;
00392 EdifParser parser;
00393 try {
00394 parser.parse(sourcePath.string(), rootPtr, linkerPtr, factoryPtr, options);
00395 std::cout << "done." << std::endl;
00396 } catch(Error& e) {
00397 std::cerr << std::endl;
00398 std::cerr << MessageTable::instance()->getMessage(e.getErrorMessageId())
00399 << std::endl;
00400 const std::vector<Error::StackFrameInfo> &stack = e.getStackTrace();
00401 for(std::vector<Error::StackFrameInfo>::const_iterator it = stack.begin();
00402 it != stack.end(); it++) {
00403 std::cerr << " " << (*it).getFunction() << "() [" << (*it).getFile() << ":"
00404 << (*it).getLine() << "]" << std::endl;
00405 }
00406 }
00407
00408 std::fstream logStream(logPath.string().c_str(), std::ios_base::out);
00409
00410 obfuscate(rootPtr, logStream);
00411
00412 std::cout << "Writing target: " << targetPath.string() << " ... ";
00413 std::cout.flush();
00414 std::fstream targetStream(targetPath.string().c_str(), std::ios_base::out);
00415 Decompiler decompiler(rootPtr, targetStream);
00416 decompiler();
00417 std::cout << "done." << std::endl;
00418 }
00419
00420 catch(...) {
00421 std::cerr << "ERROR: Failed to obfuscate " << sourcePath.string() << std::endl;
00422 }
00423 }
00424
00425 return 0;
00426 }