@@ -39,15 +39,11 @@ bool AbstractStringEncryptionPass::runOnModule(Module &M) {
3939 if (c){
4040 ConstantDataSequential *cds = dyn_cast<ConstantDataSequential>(c);
4141 if (cds){
42- if (cds->isString ()){
42+ if (cds->isString () || cds-> isCString () ){
4343 StringGlobalVars.push_back (I);
4444 }else {
45- if (cds->isCString ()){
46- StringGlobalVars.push_back (I);
47- }else {
48- // not a string skip it
49- // errs() << "WARNING : Can't get string value from " << GV->getName() << " SKIP ENCRYPTION!\n";
50- }
45+ // not a string skip it
46+ // errs() << "WARNING : Can't get string value from " << GV->getName() << " SKIP ENCRYPTION!\n";
5147 }
5248 }
5349 }
@@ -101,6 +97,38 @@ std::string AbstractStringEncryptionPass::getGlobalStringValue(GlobalVariable* G
10197}
10298
10399void AbstractStringEncryptionPass::checkStringsCanBeEncrypted (Module &M, std::vector<GlobalVariable*>& StringGlobalVars) {
100+ // @todo do not encrypt const char** not supported too many case too handle for now ...
101+ // just detect const char**
102+ for (Module::global_iterator I = M.global_begin (), E = M.global_end (); I != E; ++I) {
103+ GlobalVariable* GV = I;
104+ if (!GV->hasInitializer ())
105+ continue ;
106+
107+ ConstantArray* array = dyn_cast<ConstantArray>(GV->getInitializer ());
108+ if (array){
109+ for (unsigned int i = 0 ; i < array->getNumOperands (); i++){
110+ ConstantExpr* ce = dyn_cast<ConstantExpr>(array->getOperand (i));
111+ if (ce == 0 )
112+ continue ;
113+
114+ GetElementPtrInst *gepElementFromArray = dyn_cast<GetElementPtrInst>(ce->getAsInstruction ());
115+ if (gepElementFromArray == 0 )
116+ continue ;
117+
118+ if (GlobalVariable* gv = dyn_cast<GlobalVariable>(gepElementFromArray->getPointerOperand ())){
119+ if (dyn_cast<ConstantDataSequential>(gv->getInitializer ())){
120+ std::vector<GlobalVariable*>::iterator it = std::find (StringGlobalVars.begin (), StringGlobalVars.end (), gv);
121+ if (it != StringGlobalVars.end ()){
122+ errs () << " WARNING : " << getGlobalStringValue (gv) << " won't be ecnrypted (char** encryption is not supported!)!\n " ;
123+ StringGlobalVars.erase (it);
124+ }
125+ }
126+ }
127+ }
128+ continue ;
129+ }
130+ }
131+
104132 // do not encrypt string that are directly in return instruction
105133 // example : const char* fun(){ return "clear-text"; }
106134 // this can't be encrypted since we have to do some allocation to decrypt the string ...
@@ -116,7 +144,7 @@ void AbstractStringEncryptionPass::checkStringsCanBeEncrypted(Module &M, std::ve
116144 Value* retval = ret->getReturnValue ();
117145 if (retval == 0 )
118146 continue ;
119-
147+
120148 // check if the return value is a load instruction
121149 LoadInst* loadInst = dyn_cast<LoadInst>(retval);
122150 if (loadInst){
@@ -136,9 +164,9 @@ void AbstractStringEncryptionPass::checkStringsCanBeEncrypted(Module &M, std::ve
136164 // handle load i8* getelementptr inbounds ([X x i8]* @string, i32 0, i64 x), align 1
137165 ConstantDataSequential *cds = dyn_cast<ConstantDataSequential>(GV->getInitializer ());
138166 if (cds){
139- errs () << " WARNING : " << getGlobalStringValue (GV) << " cant't be ecnrypted (const char* directly used in return instruction)!\n " ;
140167 std::vector<GlobalVariable*>::iterator it = std::find (StringGlobalVars.begin (), StringGlobalVars.end (), GV);
141168 if (it != StringGlobalVars.end ()){
169+ errs () << " WARNING : " << getGlobalStringValue (GV) << " cant't be ecnrypted (const char* directly used in return instruction)!\n " ;
142170 StringGlobalVars.erase (it);
143171 }
144172 }else {
@@ -153,9 +181,9 @@ void AbstractStringEncryptionPass::checkStringsCanBeEncrypted(Module &M, std::ve
153181 if (GV){
154182 ConstantDataSequential *cds = dyn_cast<ConstantDataSequential>(GV->getInitializer ());
155183 if (cds){
156- errs () << " WARNING : " << getGlobalStringValue (GV) << " cant't be ecnrypted (const char* directly used in return instruction)!\n " ;
157184 std::vector<GlobalVariable*>::iterator it = std::find (StringGlobalVars.begin (), StringGlobalVars.end (), GV);
158185 if (it != StringGlobalVars.end ()){
186+ errs () << " WARNING : " << getGlobalStringValue (GV) << " cant't be ecnrypted (const char* directly used in return instruction)!\n " ;
159187 StringGlobalVars.erase (it);
160188 }
161189 }
@@ -186,9 +214,9 @@ void AbstractStringEncryptionPass::checkStringsCanBeEncrypted(Module &M, std::ve
186214 if (GV){
187215 ConstantDataSequential *cds = dyn_cast<ConstantDataSequential>(GV->getInitializer ());
188216 if (cds){
189- errs () << " WARNING : " << getGlobalStringValue (GV) << " cant't be ecnrypted (const char* directly used in return instruction)!\n " ;
190217 std::vector<GlobalVariable*>::iterator it = std::find (StringGlobalVars.begin (), StringGlobalVars.end (), GV);
191218 if (it != StringGlobalVars.end ()){
219+ errs () << " WARNING : " << getGlobalStringValue (GV) << " cant't be ecnrypted (const char* directly used in return instruction)!\n " ;
192220 StringGlobalVars.erase (it);
193221 }
194222 }
@@ -210,9 +238,9 @@ void AbstractStringEncryptionPass::checkStringsCanBeEncrypted(Module &M, std::ve
210238 if (GV){
211239 ConstantDataSequential *cds = dyn_cast<ConstantDataSequential>(GV->getInitializer ());
212240 if (cds){
213- errs () << " WARNING : " << getGlobalStringValue (GV) << " cant't be ecnrypted (const char* directly used in return instruction)!\n " ;
214241 std::vector<GlobalVariable*>::iterator it = std::find (StringGlobalVars.begin (), StringGlobalVars.end (), GV);
215242 if (it != StringGlobalVars.end ()){
243+ errs () << " WARNING : " << getGlobalStringValue (GV) << " cant't be ecnrypted (const char* directly used in return instruction)!\n " ;
216244 StringGlobalVars.erase (it);
217245 }
218246 }
@@ -221,47 +249,6 @@ void AbstractStringEncryptionPass::checkStringsCanBeEncrypted(Module &M, std::ve
221249 }
222250 }
223251 }
224-
225- // I don't know how to handle this case :
226- // int main(){
227- // const char *test[] = { "item0", "item1", "item2", "item3", "item4"};
228- // printf("%s\n", test[3]);
229- // return 0;
230- // }
231- // do not encrypt those strings ...
232- // @TODO : find a way to handle this case and remove this code
233- for (Module::iterator I = M.begin (), E = M.end (); I != E; ++I) {
234- for (Function::iterator bb = I->begin (), e = I->end (); bb != e; ++bb) {
235- for (BasicBlock::iterator inst = bb->begin (); inst != bb->end (); ++inst) {
236- if (llvm::MemCpyInst* memcpyInst = dyn_cast<llvm::MemCpyInst>(inst)){
237- if (llvm::ConstantExpr *constExpr = llvm::dyn_cast<llvm::ConstantExpr>(memcpyInst->getArgOperand (1 ))){
238- if (llvm::CastInst* castInst = dyn_cast<llvm::CastInst>(constExpr->getAsInstruction ())){
239- if (GlobalVariable* global = dyn_cast<GlobalVariable>(castInst->getOperand (0 ))) {
240- if (ConstantArray* array = dyn_cast<ConstantArray>(global->getInitializer ())) {
241- for (unsigned int i = 0 ; i < array->getNumOperands (); i++){
242- if (ConstantExpr* ce = dyn_cast<ConstantExpr>(array->getOperand (i))){
243- if (GetElementPtrInst *gep = dyn_cast<GetElementPtrInst>(ce->getAsInstruction ())){
244- if (GlobalVariable* gv = dyn_cast<GlobalVariable>(gep->getPointerOperand ())){
245- if (dyn_cast<ConstantDataSequential>(gv->getInitializer ())){
246- errs () << " WARNING : " << getGlobalStringValue (gv) << " won't be ecnrypted (char** encryption not fully supported!)!\n " ;
247- std::vector<GlobalVariable*>::iterator it = std::find (StringGlobalVars.begin (), StringGlobalVars.end (), gv);
248- if (it != StringGlobalVars.end ()){
249- StringGlobalVars.erase (it);
250- }
251- }
252- }
253- }
254- }
255- }
256- }
257- }
258- }
259- }
260- }
261-
262- }
263- }
264- }
265252}
266253
267254bool AbstractStringEncryptionPass::encryptString (Module &M, std::vector<GlobalVariable*>& StringGlobalVars, std::vector<GlobalVariable*>& StringGlobalVarsToDelete) {
@@ -376,61 +363,8 @@ void AbstractStringEncryptionPass::handleLoad(Module &M, LoadInst* Load) {
376363 // check if loaded pointer is global
377364 Value* ptrOp = Load->getPointerOperand ();
378365 GlobalVariable *GV = dyn_cast<GlobalVariable>(ptrOp);
379- if (GV == 0 ){
380- // handle load i8* getelementptr inbounds ([X x i8]* @string, i32 0, i64 x), align 1
381- ConstantExpr *constExpr = dyn_cast<ConstantExpr>(ptrOp);
382- if (constExpr != 0 ){
383- GetElementPtrInst* gepInst = dyn_cast<GetElementPtrInst>(constExpr->getAsInstruction ());
384- if (gepInst != 0 ) {
385- // check if the string is encrypted
386- StringRef gepOpName = gepInst->getPointerOperand ()->getName ();
387- std::map<std::string, GlobalVariable*>::iterator it = StringMapGlobalVars.find (gepOpName.str ());
388- if (it != StringMapGlobalVars.end ()){
389- // get size of string
390- ConstantDataSequential *cds = dyn_cast<ConstantDataSequential>(it->second ->getInitializer ());
391- uint64_t size = cds->getNumElements ();
392- // generate IR to decrypt string
393- Value* decryptedStr = stringDecryption (M, it->second , size, Load);
394- std::vector<Value*> idxlist;
395- idxlist.push_back (gepInst->getOperand (gepInst->getNumOperands () - 1 ));
396- GetElementPtrInst* newGep = GetElementPtrInst::Create (decryptedStr, ArrayRef<Value*>(idxlist), " " , Load);
397- LoadInst* newload = new LoadInst (newGep, " " , false , 8 , Load);
398- // replace current load with the decryption code
399- Load->replaceAllUsesWith (newload);
400- InstructionToDel.push_back (Load);
401- }else {
402- // handle load i8** getelementptr inbounds ([X x i8*]* @string_array, i32 0, i64 x), align 8
403- if (GlobalVariable* global = dyn_cast<GlobalVariable>(gepInst->getPointerOperand ())) {
404- if (ConstantArray* array = dyn_cast<ConstantArray>(global->getInitializer ())) {
405- Constant* c = array->getAggregateElement (dyn_cast<ConstantInt>(gepInst->getOperand (2 ))->getZExtValue ());
406- ConstantExpr* ce = dyn_cast<ConstantExpr>(c);
407- if (ce){
408- GetElementPtrInst *gepElementFromArray = dyn_cast<GetElementPtrInst>(ce->getAsInstruction ());
409- if (gepElementFromArray){
410- StringRef gepOpName = gepElementFromArray->getPointerOperand ()->getName ();
411- std::map<std::string, GlobalVariable*>::iterator it = StringMapGlobalVars.find (gepOpName.str ());
412- if (it != StringMapGlobalVars.end ()){
413- // get size of string
414- ConstantDataSequential *cds = dyn_cast<ConstantDataSequential>(it->second ->getInitializer ());
415- uint64_t size = cds->getNumElements ();
416- // generate IR to decrypt string
417- Value* decryptedStr = stringDecryption (M, it->second , size, Load);
418- std::vector<Value*> idxlist;
419- idxlist.push_back (gepElementFromArray->getOperand (gepElementFromArray->getNumOperands () - 1 ));
420- GetElementPtrInst* newGep = GetElementPtrInst::Create (decryptedStr, ArrayRef<Value*>(idxlist), " " , Load);
421- // replace current load with the decryption code
422- Load->replaceAllUsesWith (newGep);
423- InstructionToDel.push_back (Load);
424- }
425- }
426- }
427- }
428- }
429- }
430- }
431- }
366+ if (GV == 0 )
432367 return ;
433- }
434368
435369 // check if loaded pointer is constant
436370 Constant* c = GV->getInitializer ();
0 commit comments