Zhang Qiuyu
2004-Oct-12 06:52 UTC
[LLVMdev] Re: Hide visible string in variable (Chris Lattner)
Hi, Thanks so much at first.> Here are some observations: > > > for C level, > > > > char a[]="global string test"; > > for(i=0;i<strlen(a);i++){ > > a[i]= a[i]^RANDMON; > > } > > If you compile this C code, "global string test" will occur in the program > binary, so you have not obfuscated anything. You can construct exactly > what you have above in LLVM (just write it as C, compile it to LLVM and > you'll see what you need to generate), but I don't think this is what you > want. What you really want is: > > char a[]="GLOBAL STRING TEST"; > > and when the program starts up (perhaps in main), you want to insert this: > > for (i=0...) > A[i] = tolower(a[i]); > > Note that you can use whatever function you wanted, obviously uppercasing > the string isn't much obfuscation. > > To do this on LLVM, you have to do these things: > > 1. Read the string data as a constant (It's an instance of ConstantArray, > which you get form the Globalvaraible with getInitializer() as you are > doing.Following your suggestion, I got some progress. Thanks again. But I am still stuck in some problems. Constant *Cstr = GV->getInitializer(); After that, I tried to use a. for(unsigned i=0;i<Cstr->getNumOperands();++i){ Cstr->getOperand(i); } b. for(User::op_iterator I=Cstr->op_begin(),E=Cstr->op_end(); I!=E;++I){ std::cerr<<*I; } From either a or b, I could get each element of Global Variable. Supposedly, I will use my arithmetic like XOR etc to encode/hide the string. But I cannot use XOR, I mean I tried (*I)^0x33, it doesn't work. I tried op_xor, but I don't know how to use it. For C level, it is really staightforward. But here, I don't know how to do it. It should be easy way to do it. But I spent several hours on it. For simplifing prolem, I also tried to do the way like a[i]=a[i]+1; but I failed. Shy.> 2. Construct a new ConstantArray with all of the elements of the original > string, but modified according to the function you want (exclusive or > is a reasonable start).As you said, how could construct a new ConstantArray? Is it like Constant *pC = new Constant(SBtype); // Constant(const Type *Ty) for ConstantArray, replaceUsesOfWithOnConstant(Value *From, Value *To, bool DisableChecking = false); this API replaceUsesOfWithOnConstant seems to be able to do what I want, but how could create/construct a new Value with my owner value? for 3,4,5, those should work well. I would really appreciated if you can give me a very simple example to show me how to do it.> 3. Change the initializer of the global variable to the new constant with > setInitializer(). > 4. Clear the "constant" flag on the string, because the program will be > dynamically hacking on the string: GV->setConstant(false); > 5. Insert the for loop that translates the string when main runs. > > For #5, write the for loop you want, compile it with llvmgcc, then figure > out how to generate it at compile time. Alternatively, you could put the > 'decryption' routine in a library and just insert a call to the library. > > -Chris >
Chris Lattner
2004-Oct-12 16:55 UTC
[LLVMdev] Re: Hide visible string in variable (Chris Lattner)
On Mon, 11 Oct 2004, Zhang Qiuyu wrote:> Following your suggestion, I got some progress. Thanks again. But I am still stuck in some problems. > > Constant *Cstr = GV->getInitializer(); > > After that, I tried to use > a. > for(unsigned i=0;i<Cstr->getNumOperands();++i){ > Cstr->getOperand(i); > } > > b. for(User::op_iterator I=Cstr->op_begin(),E=Cstr->op_end(); I!=E;++I){ > > std::cerr<<*I; > }These both work, and are equivalent.> From either a or b, I could get each element of Global Variable. Supposedly, I will use my arithmetic like XOR etc to encode/hide the string. But I cannot use XOR, I mean I tried (*I)^0x33, it doesn't work. I tried op_xor, but I don't know how to use it. For C level, it is really staightforward. But here, I don't know how to do it. It should be easy way to do it. But I spent several hours on it. For simplifing prolem, I also tried to do the way like > a[i]=a[i]+1; > but I failed. Shy.The problem is that the operands are 'Constant*'s, not C integers. Take a look at the definitions in the include/llvm/Constants.h file. In particular, you should probably be doing something like this (warning, untested code): if (ConstantArray *CA = dyn_cast<ConstantArray>(GV->getInitializer())) if (CA->getType()->getElementType()->isInteger()) { std::vector<Constant*> NewElements; Constant *Magic = ConstantInt::get(CA->getType()->getElementType(), 123); for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i) NewElements.push_back(ConstantExpr::getXor(CA->getOperand(i), Magic)); CA->setInitializer(ConstantArray::get(CA->getType(), NewElements)); } Please look through all of Constants.h to familiarize yourself with how these things work, and in particular, try to figure out what each part of the above code does, and why it is there.> > 2. Construct a new ConstantArray with all of the elements of the original > > string, but modified according to the function you want (exclusive or > > is a reasonable start). > > As you said, how could construct a new ConstantArray? Is it like > Constant *pC = new Constant(SBtype); // Constant(const Type *Ty) > > for ConstantArray, replaceUsesOfWithOnConstant(Value *From, Value *To, > bool DisableChecking = false); this > API replaceUsesOfWithOnConstant seems to be able to do what I want, but how could create/construct a new Value with my owner value?A good way to figure out stuff like this is to look for other transformations that already exist in LLVM and see how they do it. In particular, you use Constant*::get(...) to create constants. One invariant that LLVM provides is that all structurally identical constants have the same address: this means that if you get the same constant twice, the same Constant* will be returned. Constant's are also immutable. I strongly suggest looking for other examples of LLVM transformations if you can't figure out how to do something. In particular, lib/Transforms/Scalar is a rich source of a bunch of intraprocedural passes and lib/Transforms/IPO is a good source for things that hack on global variables and functions. Good luck, -Chris> for 3,4,5, those should work well. > > I would really appreciated if you can give me a very simple example to show me how to do it. > > > 3. Change the initializer of the global variable to the new constant with > > setInitializer(). > > 4. Clear the "constant" flag on the string, because the program will be > > dynamically hacking on the string: GV->setConstant(false); > > 5. Insert the for loop that translates the string when main runs. > > > > For #5, write the for loop you want, compile it with llvmgcc, then figure > > out how to generate it at compile time. Alternatively, you could put the > > 'decryption' routine in a library and just insert a call to the library. > > > > -Chris > > > > > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://mail.cs.uiuc.edu/mailman/listinfo/llvmdev >-Chris -- http://llvm.org/ http://nondot.org/sabre/
Reasonably Related Threads
- [LLVMdev] Question about Global Variable
- [LLVMdev] Re:question about Insert callInst to call a function in library
- [LLVMdev] Question about insert call func with pionter parameter
- [LLVMdev] RE: Question about Global Variable
- [LLVMdev] Re: Hide visible string in variable