длинный переход (глобальные метки)
От: Karpov  
Дата: 31.03.02 07:30
Оценка:
Задача сводиться к следующему,

необходимо получить список ссылок на метки

Исправлена подсветка синтаксиса. -- ПК.

LPVOID aLabel[] = { jmp_label1, jmp_label2};


из различный функций

void fun1()
{
...
asm {jmp_label1:}
...
}

void fun2()
{
...
asm {jmp_label2:}
...
}


реализация с ниже преведенным подходом не подходит

typedef (* PFN_fun)();
PFN_fun aLabel[] = { fun1, fun2};
Re: длинный переход (глобальные метки)
От: adontz Грузия http://adontz.wordpress.com/
Дата: 31.03.02 08:19
Оценка:
Здравствуйте Karpov, Вы писали:

Удалено избыточное цитирование. -- ПК.

K>необходимо получить список ссылок на метки


K>LPVOID aLabel[] = { jmp_label1, jmp_label2};


K>из различный функций


K>...

K>asm {jmp_label1:}
K>...
K>asm {jmp_label2:}
K>...

Так делать категорически нельзя
Стек запорешь в результате Access Violation со всеми вытекающими на твою голову проблемами

Покажи всю задачу !!! А то, так, мало понятно, что надо сделать.
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[2]: длинный переход (глобальные метки)
От: Аноним  
Дата: 31.03.02 08:32
Оценка:
A>Так делать категорически нельзя
A>Стек запорешь в результате Access Violation со всеми вытекающими на твою голову проблемами

A>Покажи всю задачу !!! А то, так, мало понятно, что надо сделать.


Задача как стояла получить список всех глобальных меток так и осталась. Всю задачу раскрывать нет смысла, она ни каким образом не повлияет на предлагаемые решения.

Большая просьба писать только по теме и не высказывать мне ваши опасения. Если бы они мне понадобились, я попросил бы их у Вас.
Re[3]: длинный переход (глобальные метки)
От: adontz Грузия http://adontz.wordpress.com/
Дата: 31.03.02 09:53
Оценка:
Здравствуйте Аноним, Вы писали:

A>>Так делать категорически нельзя

A>>Стек запорешь в результате Access Violation со всеми вытекающими на твою голову проблемами

A>>Покажи всю задачу !!! А то, так, мало понятно, что надо сделать.


А>Задача как стояла получить список всех глобальных меток так и осталась. Всю задачу раскрывать нет смысла, она ни каким образом не повлияет на предлагаемые решения.


Вопрос задан не корректно.
Метка это адресс, фактически целое число unsigned int и оно неможет быть глобальным или локальным. Это не переменная в процедуре место под которую выделятся в стеке.
Уточни что ты подразумеваешь под глобальнойй меткой

А>Большая просьба писать только по теме и не высказывать мне ваши опасения. Если бы они мне понадобились, я попросил бы их у Вас.

No comments
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[4]: длинный переход (глобальные метки)
От: whiteForest  
Дата: 31.03.02 10:08
Оценка: -1
Здравствуйте adontz, Вы писали:

A>Вопрос задан не корректно.

A>Метка это адресс, фактически целое число unsigned int и оно неможет быть глобальным или локальным. Это не переменная в процедуре место под которую выделятся в стеке.
A>Уточни что ты подразумеваешь под глобальнойй меткой

Исправлена подсветка синтаксиса. -- ПК.

void fun()
{
...
__asm jmp_test2:;
...
}

void main()
{
__asm 
{

jmp_test:;
     mov eax, offset jmp_test; получаемый смещение, другими словами метку
     mov eax, offset jmp_test2; // а вот здесь не получиться. не из-за того, что этой метки нет, а из-за того что компилятор позволяет оперировать метками текущего тела функции. Так вот... Вопрос... Как получить jmp_test2 из main.
}
}


Если ответ Вам не известен, просьба не отвечать.
Re[5]: длинный переход (глобальные метки)
От: adontz Грузия http://adontz.wordpress.com/
Дата: 31.03.02 11:42
Оценка:
Здравствуйте whiteForest, Вы писали:

F>Здравствуйте adontz, Вы писали:


VC++ очень правильно делает. Это в народе называется защита от дурака

объясняю подробно

есть некая функкция
void a(int x,float y) // возвращаемый тип значения не имеет
 {
  // some local variables here
  char z;
  // code

  __asm
   {

   label1:

   }

 }


её стековый кадр для stdcall напрмер

1 byte  // char  z
4 bytes // int   x
6 bytes // float y
4 bytes // адресс откуда вызвали a()


есть другая процедура
void b(char p)
 {
  // some local variables here
  long q;
  // code
  __asm
   {
    
    label2:
   
   }
 }


её стековый кадр

4 bytes // long q
1 byte  // char p
4 bytes // адрес откуда вызвали b()


Если перепрыгнуть с адреса label1 на label2, то поле работы процедуры будет очищено из стека 5 байт и процедура возвратит управления по адресу не тому откуда её вызывали а старшие 4 байта локальной переменной y типа float

Такие пререходы нарушают принцыпы структурного программирования на которых базируются C и C++ и не разрешены ни стандартом, ни компилятором, ни элементарной логикой
Такое позволяют только автономные ассемблеры tasm masm wasm
F>Если ответ Вам не известен, просьба не отвечать.

На вашем месте я бы
1) Ознакомлся с азами архитектуры Intel x86 процессоров прежде чем писать на ассемблере
2) Прочёл пару книг по структурному программированию и его преимуществам
3) защёл на сюда так как вы пока новичок на этом форуме и вам наверное не понятно что здесь люди привыкли уважать друг друга и писать сообщения в вежливой форме !!!
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[6]: длинный переход (глобальные метки)
От: whiteForest  
Дата: 31.03.02 12:05
Оценка:
A>Такие пререходы нарушают принцыпы структурного программирования на которых базируются C и C++ и не разрешены ни стандартом, ни компилятором, ни элементарной логикой
A>Такое позволяют только автономные ассемблеры tasm masm wasm

Ну может хватит меня лечить. И про стек хватит, знаю я все. И не надо мне советовать что читать.

Мне нужно решение (ключик или pragma какая нибудь), которое позволет сделать это.
А данная задача нужна не с целью написания программы основанной на переходе между функциями, мне нужен список со смещением меток. Для чего, это уже мое дело. да и долго объяснять.
Re[7]: длинный переход (глобальные метки)
От: adontz Грузия http://adontz.wordpress.com/
Дата: 31.03.02 12:38
Оценка:
Здравствуйте whiteForest, Вы писали:

A>>Такие пререходы нарушают принцыпы структурного программирования на которых базируются C и C++ и не разрешены ни стандартом, ни компилятором, ни элементарной логикой

A>>Такое позволяют только автономные ассемблеры tasm masm wasm

F>Ну может хватит меня лечить. И про стек хватит, знаю я все. И не надо мне советовать что читать.


F>Мне нужно решение (ключик или pragma какая нибудь), которое позволет сделать это.

F>А данная задача нужна не с целью написания программы основанной на переходе между функциями, мне нужен список со смещением меток. Для чего, это уже мое дело. да и долго объяснять.

tasm masm wasm

На VC build-in assembler (да и по-моему на любом другом встроенном ассемблере) это не выйдет

Напиши на чистом asm раз уж ты всё знаешь. На самом деле не так уж и сложно !!!

Да и почему метки не могут быть началами функций в конце концов? Удобнее было бы создать массив ссылок на функции. Это единственное что можно сделать на VC.

PS Если ты хочешь оптимизировать переход по условию где условие это число из диапазона то пиши switch-ем компилятор оптимизирут в релизе как раз в массив ссылок и переход по элементу
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[8]: длинный переход (глобальные метки)
От: whiteForest  
Дата: 31.03.02 12:57
Оценка:
Здравствуйте adontz, Вы писали:

A>Напиши на чистом asm раз уж ты всё знаешь. На самом деле не так уж и сложно !!!


A>Да и почему метки не могут быть началами функций в конце концов? Удобнее было бы создать массив ссылок на функции. Это единственное что можно сделать на VC.


Выдержки из переписки 1:

Задача сводиться к следующему,
...
реализация с ниже преведенным подходом не подходит

typedef (* PFN_fun)();
PFN_fun aLabel[] = { fun1, fun2};

Кстати, а зачем мне левые метки... Мне нужны именно конкретные... Причем тут прога на asm? Если бы реализация нужна была бы на асме, я вообще ничего бы не спрашивал.

A>PS Если ты хочешь оптимизировать переход по условию где условие это число из A>диапазона то пиши switch-ем компилятор оптимизирут в релизе как раз в массив A>ссылок и переход по элементу


Выдержки из переписки 2:
задача нужна не с целью написания программы основанной на переходе между функциями, мне нужен список со смещением меток
Re[9]: длинный переход (глобальные метки)
От: adontz Грузия http://adontz.wordpress.com/
Дата: 31.03.02 13:11
Оценка:
Здравствуйте whiteForest, Вы писали:

НЕЛЬЗЯ НА VC ТАКОЕ СДЕЛАТЬ !!!
НЕЛЬЗЯ И ВСЁ !!!

Кто-нибудь докажет что я неправ — буду на него год беслатно работать !
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[10]: длинный переход (глобальные метки)
От: whiteForest  
Дата: 31.03.02 13:25
Оценка:
Здравствуйте adontz, Вы писали:

A>Здравствуйте whiteForest, Вы писали:


A>НЕЛЬЗЯ НА VC ТАКОЕ СДЕЛАТЬ !!!

A>НЕЛЬЗЯ И ВСЁ !!!

Ну с этого и надо было начинать. А то сделай так, почитай это, перепеши на этом и еще кучу нравоучений.

A>Кто-нибудь докажет что я неправ — буду на него год беслатно работать !


Сделать я все-же постараюсь. А на счет года бесплатной пахоты я подумаю. А не будешь работать, забалаболим. До скорого, сотрудничек.
Re[9]: длинный переход (глобальные метки)
От: IT Россия linq2db.com
Дата: 31.03.02 16:37
Оценка:
Здравствуйте whiteForest, Вы писали:

Чё то у вас тут уже не диалог, а канкретна пацанские разборки пошли

Роман, хоть и несколько эмоцианально, но прав, на C++ такого сделать нельзя. Можно ещё поразбираться с setjmp/longjmp, но как минимум ты должен пройтись по тому месту куда хочешь потом сигануть.

F>задача нужна не с целью написания программы основанной на переходе между функциями, мне нужен список со смещением меток


Более конкретная информация дала бы больше пищи для размышления и возможно нашёлся бы нормальный вариант реализации. Сейчас это всё пока больше смахивает на неправильное проектирование задачи.
Если нам не помогут, то мы тоже никого не пощадим.
Re[11]: длинный переход (глобальные метки)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 31.03.02 16:52
Оценка:
Здравствуйте whiteForest, Вы писали:

Исправлена подсветка синтаксиса. -- ПК.

Как верно сказал adontz, в лоб решения не видно.

Но можно сделать криво:
1.
void fun1
{
 __asm
 {
   jmp q;
   DB "Label1"
   q:
    bla-bla-bla
 }
}


Потом найти в коде слово Label1
void main()
{
  find ("Label1", &fun1, &main);
}


2.
int arr[100];
int arr_i = 0;

void fun1()
{
  __asm
  {
    mov arr[arr_i++], $;
    bla-bla-bla
  }
}


Повызывать все функции, они сами заполнят массив

void main()
{
  fun1();
  for (int i = 0; i < arr_i; ++i)
  {
    std::cout << arr[i] << "\n";
  }
}


3. Разобрать символьную информацию, который пихает компилятор для debugger-а.
В частности информацию о том, для какой линии C-кода, какой адрес соответствует.

Причем эту информацию можно получить и для Release-версии.

Компиляем Release с добавлением Debug-информации.
Разбираем Debug-информацию и на ее основание патчим exe-шник, заполняя какой-нибудь массив.
С помощью Strip-а убераем Debug-информацию.

3 путь мне кажется самым перспективным, т.к. исходную программу можно не менять.
Будет проблема с макросами, т.к. внутри макроса номер строки один, но и это можно победить, прогнав сначала код отдельно через препроцессор, а только потом компилировать.
Re[12]: длинный переход (глобальные метки)
От: whiteForest  
Дата: 31.03.02 18:15
Оценка: -1
Здравствуйте DarkGray, Вы писали:

DG>Здравствуйте whiteForest, Вы писали:


DG>Как верно сказал adontz, в лоб решения не видно.


DG>Но можно сделать криво:

DG>1.
DG>void fun1
DG>{
DG> __asm
DG> {
DG> jmp q;
DG> DB "Label1"
DG> q:
DG> bla-bla-bla
DG> }
DG>}


Ну вот и первое толковое решение... правда уже имея это решение я и полез на форум. Метку для поиска лучше поставить в начале функции. следом за меткой сразу будет нужное нам смещение (так-то побыстрее будет). Вот только без вызовов не обойтись. ну думаю, что нибудь еще придумаем.

Итак пол приза достается DarkGray за сообразительность.

Ждем интересных решений.
Re[13]: длинный переход (глобальные метки)
От: IT Россия linq2db.com
Дата: 31.03.02 19:05
Оценка: 24 (3)
Здравствуйте whiteForest, Вы писали:

F>Ну вот и первое толковое решение...

F>Итак пол приза достается DarkGray за сообразительность.

За такие решения надо не призы раздавать, а пороть нещадно
А за подобные постановки задачи отлучать от компьютера на месяц как минимум
Если нам не помогут, то мы тоже никого не пощадим.
Re[13]: длинный переход (глобальные метки)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 31.03.02 19:30
Оценка:
Здравствуйте whiteForest, Вы писали:

Удалено избыточное цитирование. -- ПК.

DG>>Но можно сделать криво:

DG>>1. <...>

F>Ну вот и первое толковое решение...


А чем тебе не нравится третье решение?
Это решение я привел, только потому что оно стандартное и часто встречается в различных библиотеках. Особенно при защите кода.
Re[14]: длинный переход (глобальные метки)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 31.03.02 19:31
Оценка:
Здравствуйте IT, Вы писали:

F>>Ну вот и первое толковое решение...

F>>Итак пол приза достается DarkGray за сообразительность.

IT>За такие решения надо не призы раздавать, а пороть нещадно


Что самое интересное, такое решение часто встречается в коммерческих библиотеках. Особенно в библиотеках по защите кода от вскрытия.
Re[15]: длинный переход (глобальные метки)
От: IT Россия linq2db.com
Дата: 31.03.02 19:41
Оценка:
Здравствуйте DarkGray, Вы писали:

IT>>За такие решения надо не призы раздавать, а пороть нещадно


DG>Что самое интересное, такое решение часто встречается в коммерческих библиотеках. Особенно в библиотеках по защите кода от вскрытия.


Вот откуда ноги растут, понятно. С этого надо было и начинать. В этой области число извратов превышает все мыслимые пределы. А может проще посчитать контрольную сумму всего приложения или отдельных функций, это можно сделать без асма, на одном C?
Если нам не помогут, то мы тоже никого не пощадим.
Re[16]: длинный переход (глобальные метки)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 31.03.02 19:53
Оценка:
Здравствуйте IT, Вы писали:

IT>Вот откуда ноги растут, понятно. С этого надо было и начинать. В этой области число извратов превышает все мыслимые пределы. А может проще посчитать контрольную сумму всего приложения или отдельных функций, это можно сделать без асма, на одном C?


Посчитать контрольную сумму на C можно, вот только нельзя точно узнать где функция кончилась, так как linker не гарантирует, что функции будут в том же порядке, что и при написанни.

Но чаще контрольной суммы не хватает и тогда впихивают динамическое(при достижении данного участка кода) кодирование/разкодирование частей программы. И вот тогда возникает проблема как внешнему кодировщику указать какие части проги надо закодить изначально.
Re[16]: длинный переход (глобальные метки)
От: adontz Грузия http://adontz.wordpress.com/
Дата: 31.03.02 19:57
Оценка:
Здравствуйте IT, Вы писали:

IT>Вот откуда ноги растут, понятно. С этого надо было и начинать. В этой области число извратов превышает все мыслимые пределы. А может проще посчитать контрольную сумму всего приложения или отдельных функций, это можно сделать без асма, на одном C?


Что Игорь тебя тоже досали ?
A journey of a thousand miles must begin with a single step © Lau Tsu
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.