#define + __asm

Тема в разделе "WASM.BEGINNERS", создана пользователем gloomyraven, 13 авг 2009.

  1. GoldFinch

    GoldFinch New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2008
    Сообщения:
    1.775
    gloomyraven
    я для генерации "случайных" чисел использовал
    Код (Text):
    1. #define RANDOM ((134775813 * __LINE__ + 1) & 0xFFFFFFFF)
    это генерирует число RANDOM из номера строки, которое сохраняется внутри строки

    также для последовательных макросов нужны уникальные имена меток
    Код (Text):
    1. #define BASE3(line) base##line
    2. #define BASE2(line) BASE3(line)
    3. #define BASE BASE2(__LINE__)
    генерирует уникальную метку BASE сохраняющую имя внутри строки
    используется как
    Код (Text):
    1. #define LOAD_DELTA_TO_EAX \
    2.     __asm   call BASE \
    3.     __asm   BASE: pop eax \
    4.     __asm   sub eax,offset BASE + RANDOM
    если бы метка не была уникальной, 2 таких макроса внутри функции выдавали бы ошибку "переопределение метки"
     
  2. GoldFinch

    GoldFinch New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2008
    Сообщения:
    1.775
    *само собой, RANDOM и дельта с добавленным RANDOM должны быть в одной строке
    Код (Text):
    1.     LOAD_DELTA_TO_EAX \
    2.     __asm   mov eax,[eax+g_hEngine + RANDOM] \
    тогда в коде у каждого обращения к переменной g_hEngine будет свое смещение, что не позволит забить его в IDA и юзать одно для всех
     
  3. GoldFinch

    GoldFinch New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2008
    Сообщения:
    1.775
    проблема получения полиморфного кода в С++ средствами компилятора в том, что там нет способа хранить состояние в процессе компиляции

    допустим есть несколько вариантов сложения целых чисел
    Код (Text):
    1. template<int v> Int add(Int,Int);
    2.  
    3. template<>
    4. Int add<0>(Int a,Int b)
    5. { ... }
    6.  
    7. template<>
    8. Int add<1>(Int a,Int b)
    9. { ... }
    10.  
    11. template<>
    12. Int add<2>(Int a,Int)
    13. { ... }
    и есть оператор сложения
    Код (Text):
    1. Int operator+ (Int lhs, Int rhs) {return add<X>(lhs,rhs);}
    куда надо подставить вместо X номер варианта
    но хз что для его юзать. например номер строки всегда постоянен.
     
  4. GoldFinch

    GoldFinch New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2008
    Сообщения:
    1.775
    состояние можно было бы хранить в типе, но для этого надо чтобы в С++ был спецификатор типа auto, а он будет только в C++0x
     
  5. gloomyraven

    gloomyraven Руслан

    Публикаций:
    0
    Регистрация:
    16 апр 2006
    Сообщения:
    288
    Адрес:
    Москва
    GoldFinch
    Ну ты моск! Зачёт! Долго бы я додумывался до __LINE__ :)
     
  6. GoldFinch

    GoldFinch New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2008
    Сообщения:
    1.775
    вобщем можно было бы юзать такой код
    Код (Text):
    1. #include <iostream>
    2.  
    3. //------- types ------------------------
    4.  
    5. template<int STATE>
    6. struct Int
    7. {
    8.     Int() : value(0) {}
    9.     Int(int value_) : value(value_) {}
    10.     Int<STATE>& operator=(int rhs) { value=rhs; }
    11.  
    12.     int value;
    13. };
    14.  
    15. #define INT Int<0> //Int< __LINE__%10 > - don't work in MSVC o_O
    16.  
    17. //-------- states change -----------------------
    18.  
    19. template<int A,int B>
    20. struct GetRetState
    21. {static const int value=(A*7+B*3+1)%10; };
    22.  
    23. template<int A,int B>
    24. struct GetVariant
    25. {static const int value=(A*11+B*5+1)%3; };
    26.  
    27. //----------- addittion --------------------
    28.  
    29. template<int VARIANT,int A,int B> struct add;
    30.  
    31. template<int A,int B>  
    32. struct add<0,A,B> {
    33.     typedef Int< GetRetState<A,B>::value > ret_t;
    34.     static ret_t invoke(Int<A> a,Int<B> b)
    35.     {
    36.         std::cout << "variant1 with A="<<A <<" B=" << B << std::endl;
    37.         int r = a.value+b.value;
    38.         return ret_t(r);
    39.     }
    40. };
    41.  
    42. template<int A,int B>  
    43. struct add<1,A,B> {
    44.     typedef Int< GetRetState<A,B>::value > ret_t;
    45.     static ret_t invoke(Int<A> a,Int<B> b)
    46.     {
    47.         std::cout << "variant2 with A="<<A <<" B=" << B << std::endl;
    48.         int r = a.value+b.value;
    49.         return ret_t(r);
    50.     }
    51. };
    52.  
    53. template<int A,int B>  
    54. struct add<2,A,B> {
    55.     typedef Int< GetRetState<A,B>::value > ret_t;
    56.     static ret_t invoke(Int<A> a,Int<B> b)
    57.     {
    58.         std::cout << "variant3 with A="<<A <<" B=" << B << std::endl;
    59.         int r = a.value+b.value;
    60.         return ret_t(r);
    61.     }
    62. };
    63.  
    64. template<int A,int B>
    65. Int< GetRetState<A,B>::value >
    66. operator+ (Int<A> lhs, Int<B> rhs)
    67. {
    68.     return add<GetVariant<A,B>::value, A, B>::invoke(lhs,rhs);
    69. }
    70.  
    71. int main()
    72. {
    73.     INT x;
    74.     INT y;
    75.     INT z;
    76.  
    77.     x+y+(z+x+y+z+((x+y)+(z+x)+(y+z)));
    78.  
    79.     return 0;
    80. }
    если бы можно было передавать состояние присваиванием:
    Код (Text):
    1. auto z=x+y;
    2. auto q=r+z;
    но пока что это невозможно.
     
  7. gloomyraven

    gloomyraven Руслан

    Публикаций:
    0
    Регистрация:
    16 апр 2006
    Сообщения:
    288
    Адрес:
    Москва
    GoldFinch
    Почитал в MSDN про "## preprocessor operator", не догоняю, что значит
    Код (Text):
    1. #define BASE3(line) base##line
    2. #define BASE2(line) BASE3(line)
    3. #define BASE BASE2(__LINE__)
    в связке получения дельты
     
  8. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    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__)
     
  9. gloomyraven

    gloomyraven Руслан

    Публикаций:
    0
    Регистрация:
    16 апр 2006
    Сообщения:
    288
    Адрес:
    Москва
    GoldFinch
    Твой последний пост, это нечто космическое и для землям непонятное :)
    Я думаю можно проще сделать, для начала хучу посмотреть в сторону pre-build эвентов.
    Псевдокод:

    #define decrypt(...) (код функции на асме)

    в pre-build эвенте находим _ассемблерном_ коде, который сделал компилятор этот шаблон и мутируем его
     
  10. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Ну, учите С++ :)
     
  11. gloomyraven

    gloomyraven Руслан

    Публикаций:
    0
    Регистрация:
    16 апр 2006
    Сообщения:
    288
    Адрес:
    Москва
    Great
    Доходчиво и понятно, спасибо
     
  12. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    тьфу, описался, лайн генерит номер строки. но, я думаю, что это уже поняли)