gloomyraven я для генерации "случайных" чисел использовал Код (Text): #define RANDOM ((134775813 * __LINE__ + 1) & 0xFFFFFFFF) это генерирует число RANDOM из номера строки, которое сохраняется внутри строки также для последовательных макросов нужны уникальные имена меток Код (Text): #define BASE3(line) base##line #define BASE2(line) BASE3(line) #define BASE BASE2(__LINE__) генерирует уникальную метку BASE сохраняющую имя внутри строки используется как Код (Text): #define LOAD_DELTA_TO_EAX \ __asm call BASE \ __asm BASE: pop eax \ __asm sub eax,offset BASE + RANDOM если бы метка не была уникальной, 2 таких макроса внутри функции выдавали бы ошибку "переопределение метки"
*само собой, RANDOM и дельта с добавленным RANDOM должны быть в одной строке Код (Text): LOAD_DELTA_TO_EAX \ __asm mov eax,[eax+g_hEngine + RANDOM] \ тогда в коде у каждого обращения к переменной g_hEngine будет свое смещение, что не позволит забить его в IDA и юзать одно для всех
проблема получения полиморфного кода в С++ средствами компилятора в том, что там нет способа хранить состояние в процессе компиляции допустим есть несколько вариантов сложения целых чисел Код (Text): template<int v> Int add(Int,Int); template<> Int add<0>(Int a,Int b) { ... } template<> Int add<1>(Int a,Int b) { ... } template<> Int add<2>(Int a,Int) { ... } и есть оператор сложения Код (Text): Int operator+ (Int lhs, Int rhs) {return add<X>(lhs,rhs);} куда надо подставить вместо X номер варианта но хз что для его юзать. например номер строки всегда постоянен.
состояние можно было бы хранить в типе, но для этого надо чтобы в С++ был спецификатор типа auto, а он будет только в C++0x
вобщем можно было бы юзать такой код Код (Text): #include <iostream> //------- types ------------------------ template<int STATE> struct Int { Int() : value(0) {} Int(int value_) : value(value_) {} Int<STATE>& operator=(int rhs) { value=rhs; } int value; }; #define INT Int<0> //Int< __LINE__%10 > - don't work in MSVC o_O //-------- states change ----------------------- template<int A,int B> struct GetRetState {static const int value=(A*7+B*3+1)%10; }; template<int A,int B> struct GetVariant {static const int value=(A*11+B*5+1)%3; }; //----------- addittion -------------------- template<int VARIANT,int A,int B> struct add; template<int A,int B> struct add<0,A,B> { typedef Int< GetRetState<A,B>::value > ret_t; static ret_t invoke(Int<A> a,Int<B> b) { std::cout << "variant1 with A="<<A <<" B=" << B << std::endl; int r = a.value+b.value; return ret_t(r); } }; template<int A,int B> struct add<1,A,B> { typedef Int< GetRetState<A,B>::value > ret_t; static ret_t invoke(Int<A> a,Int<B> b) { std::cout << "variant2 with A="<<A <<" B=" << B << std::endl; int r = a.value+b.value; return ret_t(r); } }; template<int A,int B> struct add<2,A,B> { typedef Int< GetRetState<A,B>::value > ret_t; static ret_t invoke(Int<A> a,Int<B> b) { std::cout << "variant3 with A="<<A <<" B=" << B << std::endl; int r = a.value+b.value; return ret_t(r); } }; template<int A,int B> Int< GetRetState<A,B>::value > operator+ (Int<A> lhs, Int<B> rhs) { return add<GetVariant<A,B>::value, A, B>::invoke(lhs,rhs); } int main() { INT x; INT y; INT z; x+y+(z+x+y+z+((x+y)+(z+x)+(y+z))); return 0; } если бы можно было передавать состояние присваиванием: Код (Text): auto z=x+y; auto q=r+z; но пока что это невозможно.
GoldFinch Почитал в MSDN про "## preprocessor operator", не догоняю, что значит Код (Text): #define BASE3(line) base##line #define BASE2(line) BASE3(line) #define BASE BASE2(__LINE__) в связке получения дельты
gloomyraven __LINE__ генерит имя метки. ## связывает две лексемы внутри подстановки макроса но #define BASE base##__LINE__ не сработало бы, потому что замены не произойдет внутри строки и вышло бы base__LINE__ #define base1(line) base##line #define BASE base1(__LINE__) тоже не сработало бы, потому что препроцессор при первой подстановке подставил бы саму строку __LINE__ и вышло бы base__LINE__, вместо фактического номера строчки. тока при двойной замене макросов подставится значение #define base1(line) base##line #define base2(line) base1(line) #define BASE base2(__LINE__)
GoldFinch Твой последний пост, это нечто космическое и для землям непонятное Я думаю можно проще сделать, для начала хучу посмотреть в сторону pre-build эвентов. Псевдокод: #define decrypt(...) (код функции на асме) в pre-build эвенте находим _ассемблерном_ коде, который сделал компилятор этот шаблон и мутируем его