Функции net


Взаимодействие с JavaScript

В этой и последующих статьях рассматриваются способы взаимодействия JavaScript и ASP.NET: создание сложных сценариев, построение интерактивных серверных элементов управления ASP.NET, асинхронное взаимодействие с сервером с помощью Ajax и т.д. Если вы не знакомы с основами JavaScript, рекомендую обратится к разделу «Учебник JavaScript» на нашем сайте.

Создание JavaScript-процессора страницы

Сколько раз вам приходилось щелкать на веб-странице и затем наблюдать за загрузкой сайта в строке состояния вашего браузера? Возможно, разорвано соединение с Интернетом? Или произошла какая-то ошибка подключения к базовой системе? Или же просто система работает столь медленно? Часто эти проблемы усложняют признание новых веб-решений, особенно при замене более быстро реагирующего и предоставляющего большие возможности клиентского приложения (такого как Windows-приложение).

В этой ситуации самый легкий способ убеждения пользователей своего приложения в его работоспособности — предоставление им сообщений о ходе выполнения, которые ставят их в известность о том, что в настоящий момент система обрабатывает их запрос.

Одним из распространенных способов предоставления сообщения о состоянии является применение JavaScript для создания стандартного процессора страницы. Когда пользователь переходит к странице, обработка которой занимает много времени, процессор страницы отображается немедленно и выводит стандартное сообщение (возможно, с прокруткой текста). В это же время запрошенная страница загружается в фоновом режиме. Как только результаты становятся доступными, сообщение процессора страницы заменяется запрошенной страницей.

Проблему задержки обработки невозможно решить, добавляя код JavaScript в целевую страницу, поскольку этот код не будет запущен до завершения обработки страницы и возврата визуализированной HTML-разметки пользователю. Однако универсальный процессор страницы, который обрабатывает запросы к любой отнимающей много времени страницы, можно создать на своем сайте.

Чтобы создать процессор страницы, понадобится отреагировать на JS-события onload и onunload. Ниже приведена страница (по имени PageProcessor.aspx), в которой демонстрируется этот подход. Она отображает индикатор загрузки страницы (большую коллекцию индикаторов можно загрузить на сайте www.ajaxload.info). Элемент связан с двумя функциями, которые вскоре будут рассмотрены.

Чтобы использовать процессор страницы, нужно запросить эту страницу и передать в аргументе строки запроса требуемую страницу. Например, для загрузки в фоновом режиме страницы Default.aspx понадобилось бы использовать следующий URL-адрес:

Процессор страницы нуждается в очень небольшом объеме серверного кода. Фактически, все его действия сводятся к извлечению первоначально запрошенной страницы из строки запроса и ее сохранению в защищенной переменной класса страницы. (Это полезно, поскольку затем эту переменную можно предоставить коду JavaScript с использованием выражения привязки данных ASP.NET, как будет показано чуть позже.) Полный серверный код станицы PageProcessor.aspx имеет следующий вид:

Остальная часть работы выполняется клиентским кодом JavaScript. При первой загрузке процессора страницы генерируется событие onload, которое вызывает функцию BeginPageLoad() клиентской стороны. Функция BeginPageLoad() сохраняет текущее окно открытым и начинает извлечение страницы, запрошенной пользователем. Для этого применяется метод window.setInterval(), устанавливающий таймер, который периодически вызывает специальную функцию UpdateProgressMeter().

Код JavaScript-функции BeginPageLoad() выглядит следующим образом:

Первый оператор кода указывает на страницу по ее новому URL-адресу. Обратите внимание, что страница, которую требуется загрузить, не является жестко закодированной в коде JavaScript. Вместо этого она устанавливается с помощью выражения привязки данных . Когда страница визуализируется на сервере, ASP.NET автоматически вставляет значение переменной PageToLoad на свое место.

Последний оператор кода запускает таймер, используя функцию window.setInterval(). Каждые 500 миллисекунд этот таймер срабатывает, и указанная строка кода выполняется. Эта строка кода вызывает JavaScript-функцию по имени UpdateProgressMeter() и продолжает отслеживать текущий счетчик цикла.

Функция UpdateProgressMeter() просто периодически изменяет сообщение о состоянии, придавая ему сходство с анимированным индикатором выполнения. Сообщения о состоянии циклически повторяется, периодами от 0 до 5. Код JavaScript, который решает эту задачу, имеет следующий вид:

И, наконец, когда страница полностью загружена, генерируется клиентское событие onunload. В приведенном примере событие onunload связано с функцией EndPageLoad(). Эта функция останавливает таймер, очищает сообщение о ходе выполнения и устанавливает временное сообщение передачи, которое исчезает, как только новая страница визуализируется в браузере. Ниже приведен код:

На протяжении всего процесса никакие обратные отправки не выполняются, Конечным результатом является сообщение о ходе выполнения, которое остается на экране до тех пор. пока целевая страница будет полностью обработана и загружена:

Чтобы протестировать процессор страницы, нужно просто воспользоваться целевой страницей, которая занимает много времени при выполнении на сервере (из-за объема работ, выполняемых кодом) или при загрузке на клиенте (из-за размеров страницы). Медленную страницу можно имитировать, помещая в целевую страницу код задержки, подобный следующему:

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

Как видите, совсем небольшой объем клиентского кода JavaScript позволяет информировать пользователя о том, что страница обрабатывается. А это, в свою очередь, улучшает субъективное представление пользователя о производительности.

Визуализация блоков сценария

В рассмотренном ранее примере использовался статический блок «; Page.ClientScript.RegisterClientScriptBlock(this.GetType(), «Confirm», script); form1.Attributes.Add(«onsubmit», «return ConfirmSubmit();»); >

Чтобы упростить определение функции JavaScript в нескольких строках, в начале должен быть помещен символ @, в результате все символы будут обрабатываться как строковые литералы, что позволяет использовать несколько строк.

Результат показан на рисунке ниже:

В этом примере применение метода RegisterCllentScriptBlock() не дает никаких реальных преимуществ. Однако методы ClientScriptManager становятся важны при разработке специального элемента управления, который использует JavaScript. Позже будет рассмотрен элемент управления, в котором с помощью метода RegisterStartupScript() отображается всплывающее окно.

Толковый справочник по функциям?

К вам 2 вопроса)
1) Где можно взять толковый справочник по функциям vb.net?
Можно на английском главное чтоб функции были разбиты по категориям, типа строковый, работа с массивами, файловые и тд? MSDN не предлагать, там чёрт ногу сломит так у них всё организованно) К тому же интернет не всегда есть.


2) Переделываю свою библиотеку классов.
Насколько корректно в классах vb.net использовать такой вид кода?

08.09.2013, 13:12

Книги по VB (справочник по функциям с примерами)
Скажите есть вобще более интерестные книги по Визуалу . Я имею ввиду ввиде справочника по функциям.

Где взять справочник по API-функциям?
Мож у кого завалялся справочник по API функциям для ., поделитесь пожалуйста. Заранее всем спасибо.

Где найти толковый справочник по JavaScript?
Где найти толковый справочник по JavaScript такой, чтобы четко были перечислены все методы и.

Справочник по функциям
Добрый день всем! Подскажите, пожалуйста, справочник по функциям для JS (да и по языку в целом.

Справочник по функциям C/C++
Есть вообще справочник по всем функциям C/C++

08.09.2013, 15:43 2

Не знаю что может быть лучше чем документация как от разработчиков ОС, так и от разработчиков языка. Да и других справочников по моему нет.

08.09.2013, 15:55 [ТС] 3 09.09.2013, 01:35 4

Long в vb6 — это int32. Непосредственный аналог для VB.NET — Integer. Но на самом деле всё не совсем так. Часто Long использовался для передачи указателелей, а при компиляции под x64 указатель 64-битный, а не 32. Размер типа IntPtr на x32 — 32 бита, поэтому там от него точно ничего плохого не будет, а на x64 — 64 бита. Есть предположение, что на x64 значения всё равно выравниваются по 8 байт, что означет, что любое использование int64 вместо int32 при передаче по значению не приведёт к проблемам. Передача по ссылке вероятно подразумевает запись в соответствующее местно, но в стек независимо от типа будет помещаться указатель. Однако, я не знаю, так ли это. В общем, лучше смотреть по смыслу значения и соответствующим образом подставлять Integer/IntPtr.

Насколько я представляю, в большинстве WinApi-функций используется IntPtr.

Функции net

Приведем пример синтаксиса, используемого для описания функций:

Пример #1 Псевдокод для демонстрации использования функций

Внутри функции можно использовать любой корректный PHP-код, в том числе другие функции и даже объявления классов.

Имена функций следуют тем же правилам, что и другие метки в PHP. Корректное имя функции начинается с буквы или знака подчеркивания, за которым следует любое количество букв, цифр или знаков подчеркивания. В качестве регулярного выражения оно может быть выражено так: ^[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*$ .

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

В случае, когда функция определяется в зависимости от какого-либо условия, например, как это показано в двух приведенных ниже примерах, обработка описания функции должна предшествовать ее вызову.

Пример #2 Функции, зависящие от условий

/* Мы не можем вызвать функцию foo() в этом месте,
поскольку она еще не определена, но мы можем
обратиться к bar() */

if ( $makefoo ) <
function foo ()
<
echo «Я не существую до тех пор, пока выполнение программы меня не достигнет.\n» ;
>
>

/* Теперь мы благополучно можем вызывать foo(),
поскольку $makefoo была интерпретирована как true */

if ( $makefoo ) foo ();

function bar ()
<
echo «Я существую сразу с начала старта программы.\n» ;
>

Пример #3 Вложенные функции

Илон Маск рекомендует:  Что такое код msql_list_fields


function foo ()
<
function bar ()
<
echo «Я не существую пока не будет вызвана foo().\n» ;
>
>

/* Мы пока не можем обратиться к bar(),
поскольку она еще не определена. */

/* Теперь мы можем вызвать функцию bar(),
обработка foo() сделала ее доступной. */

Все функции и классы PHP имеют глобальную область видимости — они могут быть вызваны вне функции, даже если были определены внутри и наоборот.

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

Замечание: Имена функций регистронезависимы, тем не менее, более предпочтительно вызывать функции так, как они были объявлены.

Функции PHP поддерживают как списки аргументов переменной длины, так и значения аргументов по умолчанию. Смотрите также описания функций func_num_args() , func_get_arg() и func_get_args() для более детальной информации.

Можно вызывать функции PHP рекурсивно.

Пример #4 Рекурсивные функции

Замечание: Рекурсивный вызов методов/процедур с глубиной более 100-200 уровней рекурсии может вызвать переполнение стека и привести к аварийному завершению скрипта. В частности, бесконечная рекурсия будет считаться программной ошибкой.

Образовательный блог — всё для учебы

Неуправляемый экспорт
Среда CLR позволяет предоставить статические методы DotNet неуправлямому коду Win32.

Для среды DotNet всякий кода Win32 называется неуправляемым, хотя неочевидно, что там будут указатели. Иногда это называют неуправляемым экспортом Unmanaged Export. Неуправляемый экспорт реализован с помощью механизма Invert Pain Work. По сути приложение Win32 способно импортировать эти функции также как и другие функции из обычных dll. Тем не менее не все языки могут это делать. В Delphi всё ограничивается экспортом глобальных функций, которые реализованы фактически как статические методы.

Примечание: глобальные функции объявлены в Interface, а не в Implementation.

Net Remote
Протокол обмена бинарными сообщеньями предоставляемой средой DotNet это по существу замена COM, DCOM. Т.е. Net Remote – это другое название DCOM только для среды DotNet.

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

Так называемые домены приложения APP Domain является основой инфраструктуры дистанционного доступа и для межпроцессорного взаимодействия. По сути, они выполняют функции те же, что и Win32, но декларируется, что уровень разделения, уровень защиты и т.п. гораздо выше, чем у Win32. в одном процессе можно создать несколько доменов приложения с одним уровнем изоляции без дополнительных затрат на межпроцессорные обращения. Технология DotNet Remote позволяет обращаться объектам одного домена к объектам другого домена (аналог – апартаменты) независимо от нахождения (в каком домене находится и в каком процессе выполняется).

Объекты дистанционного доступа
Объекты, предполагающие обращение к разным доменам, называются объектами дистанционного доступа. Среда DotNet предоставляет 2 типа таких объектов:
• маршалинга по ссылки Marshal by References
• маршалинга по значению Marshal by Value

Формально существует третий связанный с контекстом, но он сложный и его мало кто использует.

Объекты маршалинга по ссылки
Экземпляры объектов этого типа можно рассматривать как коллекцию методов, доступных для вызова удаленных клиентов. Создаются они на сервере, параметры должны быть, как правило, простыми типами, в крайнем случаи объектным типом.

Маршалинг по значению
После сериализации (от serial – последовательный ) в транспортный формат экземпляры объектов этого типа способны пересекать границы доменов. Для того, чтобы использовать такой способ, надо использовать атрибут

Сериализация – процесс преобразования классов в поток байтов, который можно хранить, передавать и т.п. с одного компьютера на другой.

Активизация объектов
Существует 2 способа создания экземпляров объектов дистанционного доступа:
• активизация сервера;
• активизация клиента.

Активизация сервера
Объекты сервера, называемые общеизвестными (т.к. они регистрируются в среда дистанционного доступа DotNet). При одноэлементной активации Singleton Activation подразумевается создание только одного экземпляра, который будет доступен в любой момент времени. Если ссылку запросят 2 клиента, то оба получат одну и ту же ссылку, но обращение будет последовательным. Под реактивизации с одиночным обращение Single Call Instantiation получается более масштабируемый способ активации.

Активизация клиента
Объект активизации клиента индивидуальный для каждого клиента. Каждый клиент имеет свою собственную ссылку, которая может оставаться активной между обращениями к методам. Хотя клиентская активация предоставляет некоторые преимущества и проще в применении (исторически появилась раньше, пример: клиент базы данных), но масштабируемость этого способа хуже, необходимо больше ресурсов на сервере.

Примечание: Для активации клиента надо заранее знать сколько примерно будет подключений к серверу (чтобы выбрать сервер с нужным объёмом ресурсов), а теперь от этого ушли с помощью серверной активации (надо только реализовать пул объектов).

Резервирование
Нет счетчика ссылок, есть дистанционный объект. Возникают проблемы его продолжительности жизни. Проблемы управления продолжительностью жизни дистанционного объекта осуществляются на основе резервирования. Каждый домен обладает своим собственным диспетчером резервирования, который отслеживает все обращения к объекту. Если объект некоторое время не востребован, то мы его отдаем сборщику мусора. Это проще, чем DCOM, где используется счетчик ссылок по сети, которым сложно управлять.


Proxy Server
Естественно, что клиенты связываются с дистанционным объектом с помощью Proxy Server или просто Proxy, которая так же как и ранее является объектами расположенными в адресном пространстве клиента и которая также как и ранее выступает в роли заместителя и заглушки. В DotNet существует 2 типа Proxy Server:
• Сквозной Transparent
• Реальный Real

Для обращению к сквозному надо написать Activate.GetObject

Каналы
Канал дистанционного доступа Remote Channel неодходим для передачи сообщений между доменами приложений.

Можно использовать 2 типа каналов:
• TCP/IP, если возможна высокая скорость передачи;
• HTTP для Интернета.

Оба канала применяются независимо от формата обмена сообщениями. Т.е. можно использовать как формат caap (по умолчанию), так и бинарный(эффективный).

Разработка приложений по технологии Net Remote, т.е. дистанционного доступа, в Delphi относительно проста, по сути, она похожа на разработку OLE сервера. Регистрация проходит проще библиотека типов чего-то там не приводиться.

Тригонометрические функции .net framework

Есть статический класс Math. Есть в нем тригонометрические функции. Возьмем Cos и Acos. Наверное, я забыл тригонометрию, потому что ожидаю что эта строка Console.WriteLine(Math.Acos(Math.Cos(ang))); выведет мне значение ang, а она выводит непонятные вещи. Объясните почему?

3 ответа 3

Вероятно, вы забыли, что тригонометрические функции в C# принимают угол не в градусах, а в радианах. Сначала вам надо аргумент функции Cos сконвертировать в радианы:

Как включить функцию .Net Framework 3.5 в Windows 8.

Иногда в Windows 8 может появится сообщение «приложение на вашем компьютере нуждается в следующих компонентах Windows» «.Net Framework 3.5 (включая 3.0 и 2.0)». Это сообщение появляется при попытке установить приложение, которое требует .Net 3.5 но оно не может найти эту .Net версию на вашем компьютере.Это происходит потому, что .Net 3.5 не устанавливается автоматически вместе с Windows 8; только усовершенствованная функция .Net 4.5 автоматически устанавливается вместе с Windows 8. Чтобы избавиться от этой проблемы вы должны включить эту функцию.Есть два пути, чтобы включить эту функцию,во-первых,когда вы находитесь в режиме онлайн,скачать и установить её,а второй путь находится в автономном режиме, используя команды DISM в командной строке.

Включить функцию .Net 3.5 онлайн.

Откройте Панель Управления и щелкните на «Программы и компоненты».

В окне Программы и компоненты щелкните на «Включить функции Windows или выключить».

В появившемся диалоговом окне,перейдите на «.Net Framework 3.5» и нажмите кнопку OK. и следуйте инструкциям.

Функция будет установлена и, наконец, будет отображаться в этом окне,далее просто нажмите кнопку Закрыть.

Включить функцию .Net 3.5 в автономном режиме.

Откройте окно командной строки с помощью «Run as Administrator» и измените «C:\» dirctory.

И введите следующую команду и нажмите Enter:

Здесь «F» — это загрузочный носитель; это может быть компакт-диск, загрузочная флешка и др.

Подождите несколько минут;компонент .Net 3.5 Windows будет установлен.

Перехватываем .NET: Теория и практика перехвата вызовов .NET-функций

Содержание статьи

. в проге обнаружился баг. Первое обращение к базе отваливалось по таймауту, но следующие шли нормально. Выяснилось, что индусы наколбасили метод в 75000 строк, и подключение к бд отваливалось за то время, пока шла jit-компиляция метода. По-моему, метод в 75к строк на С# скорее призовет дьявола, чем заработает.

Помню, несколько лет назад мы с друзьями язвили по поводу того, что скоро мобильные телефоны уже не будут отставать от компьютеров по мощности микропроцессора. И вот, пожалуйста — в том месте, где я работаю, 20% компов УЖЕ уступают по мощности современному GalaxyS.

Аналогичная ситуация складывается и с разработкой программного обеспечения — пару лет назад. Прогрессивное человечество было уверено, что перехват вызова .NET функций — удел извращенцев. И я бы с ними согласился.


О перехватах API-функций написано море книг и статей, снята куча видеоуроков. Если раньше эта тема казалась уделом гурупрограммистов, то теперь написать код, который будет перехватывать системные вызовы, не составит проблемы даже для новичка — там и на самом деле нет ничего сложного. Разумеется, только если речь идет о стандартном WinAPI-интерфейсе. Идея перехвата вызовов функций в .NET поначалу вызывала лишь улыбки программистов. Улыбали и попытки написания вирусов под .NET Framework.

Времена изменились, и вместе с ними изменились требования, которые потенциальный заказчик ставит для разработчика. Теперь перехват вызовов в .NET-прогах — не такая уж никчемная и безумная задача, как казалось раньше. И теперь после прочтения этой статьи ты легко сможешь взять под контроль свои .NETприложения!

Собираем мозаику

Теперь можно со всей смелостью утверждать, что ответ Майкрософта вездесущей Java удался — разработчик на .NET на сегодняшний день так же востребован, как и Java-программист. С внедрением .NET Framework принципиально поменялась схема «язык программирования — ОС». Если раньше речь шла об адаптации одного языка для разных платформ, то сейчас — об адаптации разных языков для одной платформы. Давай вкратце вспомним, что такое .NET, и что нам нужно знать, если мы хотим научиться основам перехвата в его среде. Дело в том, что в нашем случае мало будет просто знать язык программирования среды .NET, нужно еще иметь четкое представление о том, как он работает.

Илон Маск рекомендует:  Что такое код doubles (floats)

Платформа .NET содержит общеязыковую среду выполнения (Common Language Runtime — CLR). Общеязыковая среда выполнения CLR поддерживает управляемое выполнение, которое характеризуется рядом преимуществ. Совместно с общей системой типов, общеязыковая среда выполнения CLR поддерживает возможность взаимодействия языков платформы .NET. Кроме того, платформа .NET предоставляет большую полнофункциональную библиотеку классов .NET Framework. Ну и конечно же, метаданные (Metadata) — это информация о сборках, модулях и типах, составляющих программы в .NET.

Компилятор генерирует метаданные, а CLR и наши программы их используют. Когда загружаются сборка и связанные с ней модули и типы, метаданные подгружаются вместе с ними.

Metadata

На метаданных, как на одной из самых важных и принципиальных тем, мы сейчас и остановимся.
Итак, в них хранятся все классы, типы, константы и строки, используемые .NET-приложением. Metadata, в свою очередь, делится на несколько отдельных куч (heaps) или потоков. В Microsoft .NET предусмотрены пять куч: #US, #Strings, #Blob #GUID и #

  • #US-куча хранит все строки, которые программист «заготовил» в своем коде. К примеру, если программа выводит на экран строку функцией Print(«hello»), то hello будет храниться в #US-куче.
  • #Strings-куча хранит в себе такие вещи, как имена методов и имена файлов.
  • #Blob-куча содержит в себе бинарные данные, на которые ссылается сборка, такие как, например, сигнатура методов.
  • #

-куча содержит набор таблиц, которые определяют важное содержимое .NET-сборки. Например, там содержатся таблицы AssemblyRef, MethodRef, MethodDef, и таблицы Param. Таблица AssemblyRef включает набор внешних сборок, от которых зависит сама сборка.

Таблица MethodRef включает в себя лист внешних методов, которые используются сборкой. Таблица MethodDef содержит все методы, которые определены в сборке.

Param, в свою очередь, содержит все параметры, которые используются методами, определенными в таблице MethodDef. «К чему эта скукота?», — спросишь ты. Спокойно! Сверни ковер нетерпения и положи его в сундук ожидания, ведь без понимания того, «как же эта хрень работает», смысл статьи до тебя может и не дойти :).

Поговорим поподробнее о таблице MethodDef. Для перехвата методов .NET-приложений это крайне нужная вещь. Каждая запись в таблице методов содержит RVA (relative virtual address) метода, флаги метода, имя метода, смещение в куче #Blob на сигнатуру метода и индекс в таблице Param, которая содержит первый параметр, передаваемый функции. RVA метода указывает на тело метода (который содержит IL-код) в секции .TEXT.

Сигнатура метода определяет порядок передачи параметров (calling convention), какой тип будет на возврате из метода и т.д. Чтобы ты смог понять тему на уровне Дао, на сайте rsdn.ru выложены аж целых три статьи на тему метаданных в .NET, которые рекомендуются к обязательному изучению (http://www.rsdn.ru/article/dotnet/refl.xml, …/phmetadata.xml, и …/dne.xml).

Как далеко можно зайти в лес?

До его середины — дальше лес уже кончается. Спешу обрадовать: половину леса мы уже прошли и постепенно продвигаемся к нашей главной цели — научиться перехватывать .NET-вызовы.

Рассмотрим вопрос исполнения .NET-приложений чисто практически:

  • Mscoree.dll (исполнительный движок среды .NET)
  • Mscorwks.dll (where most of the stuff happens)
  • Mscorjit.dll (та самая JIT)
  • Mscorsn.dll (обрабатывает верификацию «строгих» имен)
  • Mscorlib.dll (Base Class Library — библиотека базовых классов)
  • Fushion.dll (assembly binding)

Любое .NET-приложение на точке входа имеет всего одну инструкцию. Эта инструкция реализует джамп на функцию _CorExeMain, которая располагается в таблице импорта. _CorExeMain, в свою очередь, ссылается на mscoree.dll, которая и начинает процесс загрузки и исполнения .NET-приложения.

Mscoree.dll вызывает _CorExeMain из mscorwks.dll. Mscorwks.dll — это довольно большая библиотека, которая контролирует и обрабатывает процесс загрузки. Она загружает библиотеки базовых классов (BCL) и только затем вызывает точку входа Main() твоего .NET-приложения. Так как Main() в этом моменте все еще не декомпилировано, код Main() будет переброшен обратно в mscorwks.dll для компиляции. Mscorwks.dll вызовет JITFunction, которая загрузит среду JIT из mscorjit.dll.

Как только сгенерированный IL-код будет скомпилирован в native-код, контроль будет передан обратно в Main(), которая и начнет непосредственное исполнение.

Перехват? Легко!

Ну, наконец-то! Поговорим непосредственно о перехвате вызовов в .NET. Мы привыкли воспринимать перехват классически, то есть таким образом, когда с целью его реализации или пишутся прокси-обертки, или же функция просто сплайсится. В случае с .NET все происходит по-другому.

Первое, что надо уяснить для осуществления перехвата — это то, что методы, которые мы хотим перехватить, хранятся в конце секции .TEXT. Это сделано, потому что секция .TEXT .NET’овской сборки довольно компактна — там недостаточно места для хранения всех перехваченных функций.


Кто-то может спросить, почему нельзя просто изменить стандартным общеизвестными способом (инструкции «CALL» и «JUMP» RVA-метода) на перехватываемый код, а затем просто перехватить код всех оригинальных функций? Причина проста — инструкции «CALL» и «JUMP» в MSIL-коде используют токены (сигнатуры) методов, а не смещения на них. Таким образом, если я хочу получить ссылку на код, который нужно перехватить, это нужно будет сделать путем поиска токена метода. Итак, для решения нашей задачи перехвата нам нужно будет раздвинуть секцию .TEXT кода.

Представляется, что единственный способ вызвать оригинальный код — создать другой метод. Есть две причины, по которым такой подход трудно, но все же осуществим. Во-первых, это требует включения новой записи в таблицу методов. И во-вторых, в таблице методов дополнительного места для этого просто нет.

Второе — нам нужно найти RVA метода в таблице MethodDef и перезаписать его так, чтобы он указывал на место расположения нового перехваченного метода. Для совершения этой операции нужно увеличить размер секции .TEXT для того, чтобы она смогла вместить все это хозяйство. При этом должны быть учтены и виртуальный, и raw-размер секции. Виртуальный размер — это актуальный, действительный размер секции, rawразмер — это размер, округленный до выравнивания секции.

Виртуальные адреса и размеры нужны для того, чтобы знать, как исполняемый файл загружается в память. Если, к примеру, секция .TEXT имеет виртуальный адрес 0x1000, то по этому смещению в памяти запущенного процесса мы и найдем эту самую секцию .TEXT, которая туда была спроецирована. Вместе с тем, raw-адрес секции может быть 0x200, а это значит, что секция .TEXT в самом файле расположена по смещению 0x200.

Те секции, которые идут за .TEXT (секции данных и релоки), тоже нужно будет выровнять, потому что расширение секции .TEXT «наедет» на начало следующей секции, в результате чего файл просто не запустится. В конце всего этого действа обновляются PE-заголовки. Все, теперь наш перехваченный код вшит прямо в сборку, а другие методы остались нетронутыми.

Колбасим код

Как ты, наверное, уже догадался, один из основных моментов, который позволит нам взять под контроль .NET-программулину, заключается в получении указателя на заголовок CLIHeader, который, в свою очередь, содержит такое поле, как Metadata. Оно-то нам и нужно:

Получим указатель на Cliheader C#

FileReader Input = new FileReader(AssemblyPath);
byte[] Buffer = Input.Read();
[skip. ]
ImageBase = Marshal.AllocHGlobal(Buffer.Length * 2);
HeaderOffset = *((UInt32 *)(ImageBase + 60));
PE = (PEHeader *)(ImageBase + HeaderOffset);
HeaderOffset += (UInt32)sizeof(PEHeader);
StandardHeader = (PEStandardHeader *)(ImageBase + HeaderOffset);
RVA *CLIHeaderRVA = (RVA *)((byte *) StandardHeader + 208);
SectionOffset = GetSectionOffset(CLIHeaderRVA-> Address);
CLI = (CLIHeader *)(ImageBase + CLIHeaderRVA->Address — SectionOffset);
MetaDataHeader = (MetaDataHeader *)(ImageBase + CLI->MetaData.Address — SectionOffset);
metadata = new MetaData(Function, ImageBase, (Int32)CLI->MetaData.Address, MetaDataHeader, CLI->MetaData.Size);

Далее будет ненамного сложнее, особенно для тех, кто знаком со способом внедрения в PE-файлы путем расширения его секций.

Нам нужно будет записать в конец секции .TEXT перехваченные функции и пересчитать все необходимые поля, связанные с секцией, чтобы дать ей возможность нормально выполниться, после чего обновить необходимые PE-заголовки:

VirtualSize = TextSectionHeader->VirtualSize + HookSize;
RawDataSize = VirtualSize;
if ((RawDataSize % FileAlignment) != 0)
RawDataSize += (FileAlignment (RawDataSize % FileAlignment));
StandardHeader->CodeSize = RawDataSize;
HookAddress = TextSectionHeader->VirtualAddress + TextSectionHeader->VirtualSize;
TextSectionHeader->VirtualSize = VirtualSize;
TextSectionHeader->RawDataSize = RawDataSize;
[skip. ]
StandardHeader->DataBase = DataSectionHeader->
VirtualAddress;
StandardHeader->ImageSize = SectionHeader->
VirtualAddress + SectionHeader->VirtualSize;
if ((StandardHeader->ImageSize % SectionAlignment) != 0)
StandardHeader->ImageSize += (SectionAlignment (StandardHeader->ImageSize % SectionAlignment));

Вот и все. К сожалению, те 75 тысяч строк кода, которые мне хотелось бы выложить на страницы журнала, в него просто не влезут. Шутка :). Полностью рабочий код ты, как и всегда, сможешь найти на диске.

Заключение

Так уж получилось, что большая часть статьи — это описание принципов действия .NET’овской среды, о которых ты наверняка наслышан. Но, как говорится, RTFM — и будет тебе счастье. Для того, чтобы полностью овладеть этой техникой и прослыть шаманом, тебе придется хорошенько потрудиться. Но это не страшно, ведь перехват .NET-приложений в твоем исполнении того стоит.

Тема: Функции NetStats

Показано с 1 по 4 из 4

Опции темы
Поиск по теме
Отображение
  • Линейный вид
  • Комбинированный вид
  • Древовидный вид


Функции NetStats

Листал я на досуге функции на wiki и наткнулся на раздел NetStats Functions https://wiki.sa-mp.com/wiki/Category:NetStats_Functions
Посмотрел на них, я понял, что можно реализовать маломальскую защиту от ддоса либо же просто получать статистику сервера, вот собственно описание:

GetNetworkStats(retstr[], retstr_size)
Получает сетевую статистику сервера и сохраняет её в строку
retstr[] Строка, в которую сохраняется статистика
retstr_size Длина строки
!Заметка: На оф. сайте используют длину 400+1 символ.

GetPlayerNetworkStats(playerid, retstr[], retstr_size)
то же самое как и в функции выше, только для отдельного игрока.

Илон Маск рекомендует:  Ошибки IE7

NetStats_BytesReceived(playerid)
Получает количество данных (в байтах), полученных от игрока.

NetStats_BytesSent(playerid)
Получает количество данных (в байтах), посланных игроку.

NetStats_GetConnectedTime(playerid)
Получает количество времени (в миллисекундах) проведенного игроком на сервере (удобно использовать для подсчета времени, вместо использования переменных).

NetStats_GetIpPort(playerid, ip_port[], ip_port_len)
Возвращает ип и порт игрока
playerid Ид игрока, у которого получаем порт и ип.
ip_port[] Строка, куда записываем данные.
ip_port_len Длина строки (рекомендуется 22).

NetStats_MessagesReceived(playerid)
Возвращает количество сообщений, полученные сервером от игрока.

NetStats_MessagesRecvPerSecond(playerid)
Возвращает количество сообщений, отправленных игроком в последнюю секунду.

NetStats_MessagesSent(playerid)
Возвращает количество сообщений, отправленных сервером игроку.

NetStats_PacketLossPercent(playerid)
Получает процент потери пакетов игроком.
!Замечание: если больше 1%, то это уже сигнализирует о неполадках.

Урок 33. Процедуры и функции

Урок из серии «Программирование на Visual Basic.NET для школьников»

В предыдущем уроке рассказывалось о работе с текстовыми файлами.

В этом уроке поговорим о подпрограммах. При разработке сложного алгоритма целесообразно выделить в нем последовательности действий, которые многократно повторяются, оформить как вспомогательные алгоритмы и, по мере необходимости, вызывать их из основного алгоритма.

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

В этом уроке вы узнаете: какие преимущества дает использование подпрограмм, чем отличаются процедуры и функции, как они описываются и как вызываются.

Процедуры и функции предоставляют следующие преимущества:

  • Устраняют повторяющиеся строки. Вы можете один раз определить процедуру или функцию и вызывать ее там, где это необходимо.
  • Делают программы более читаемыми. Программу, разбитую на несколько частей, воспринимать легче, чем программу, сделанную в виде одного большого фрагмента.
  • Упрощают разработку программы. Программы, разделенные на логические единицы, легче разрабатывать, писать и отлаживать.
  • Могут повторно использоваться в других проектах и решениях.
  • Расширяют возможности языка программирования. Если для решения ваших задач в языке программирования нет готовых, встроенных в язык программирования процедур и функций, можно написать свои процедуры и функции.

Основные отличия функции от процедуры:

1. Функция имеет тип (аналогично переменной) и может возвращать значение через имя функции. Ее можно использовать качестве операнда в выражениях. Процедура возвращает результаты через параметры, ее нельзя использовать в выражениях.

2. Вызов функции осуществляется посредством указания ее имени в каком либо операторе языка программирования. Процедура вызывается с помощью отдельного оператора.

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

Подпрограмма типа Sub

При описании процедуры, как и при описании функции, ей дается уникальное название – имя процедуры и устанавливается список параметров. Параметры разделяются между собой запятой и содержат описание типов.


Общий вид описания процедуры:

  • название_процедуры — имя создаваемой вами процедуры Sub;
  • параметры — необязательный список формальных параметров, используемых в процедуре Sub;
  • операторы_процедуры — блок операторов, который выполняет работу процедуры.

Вызов процедуры типа Sub
Чтобы вызвать в программе процедуру, нужно указать имя этой процедуры, а затем список фактических параметров, требуемых для этой процедуры.

Общий вид вызова процедуры:

Если в процедуру не передается ни одного аргумента, то требуется наличие пустых круглых скобок.

Передача параметров

При описании процедуры после имени в круглых скобках указывается список параметров с указанием их типов. Эти параметры называются формальными. Они определяют место подстановки фактических параметров.

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

Параметры можно передавать по значению и по ссылке.

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

Языки программирования позволяют передавать в процедуру как значение переменной (передача по значению), так и ее адрес в оперативной памяти (передача по ссылке).

При передаче по значению в процедуру передается только копия переменной, т.е. процедура не получает доступ к переменной в памяти и не может изменить ее значение. Для передачи параметров по значению в описании процедуры перед параметром в списке параметров указывают ключевое слово ByVal (от англ. by value – по значению).

При передаче переменной по ссылке процедуре передается ссылка на ее адрес в оперативной памяти, таким образом, процедура получает доступ к переменной в памяти и может ее изменить. Чтобы передавать переменную по ссылке, необходимо в описании процедуры перед соответствующим параметром в списке добавить ключевое слово ByRef (от англ. by reference – по ссылке).

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

Проект «Передача по ссылке и по значению»

Задание.Создать проект, в котором описывается процедура, один параметр которой передается по ссылке, а другой – по значению. Значения параметров внутри процедуры изменяются. В вызывающей процедуре переменным присваиваются начальные значения, производится вызов процедуры с указанием переменных в качестве фактических параметров. После выполнения процедуры значения переменных выводятся на надписи.

  1. Разместить на форме:
    • текстовые поля TextBox1 и TextBox2 для вывода начальных значений переменных;
    • надписи Label1 и Label2 для вывода конечного значения переменных;
    • кнопку button1 для создания процедуры-обработчика события;
    • четыре надписи для вывода поясняющих текстов.

В программном коде процедуры первый параметр X передается по ссылке, а второй параметр Y передается по значению.

Создадим программный код проекта, в котором:

  • объявим переменные;
  • создадим процедуру, умножающую значение переменных, передаваемых по ссылке и по значению, на коэффициент 5;
  • создадим обработчик, реализующих присваивание переменным начальных значений, вызов первой процедуры и осуществляющий вывод ключевых значений переменных на надписи.
  • Объявить переменные и создать код вызываемой процедуры:

    Подпрограмма типа Function

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

    Наиболее широко используются встроенные функции: математические, преобразования типов данных, обработки строк, даты и времени и др.

    Программист может создавать свои функции.


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

    Общий вид описания функции:

    • название_функции — имя создаваемой вами функции.
    • As тип — пара ключевых слов, которые определяют тип возвращаемого функцией значения.
    • параметры — необязательный список параметров, используемых в данной функции.
    • операторы_функции — это блок операторов, который выполняет работу функции.
    • Return — новый оператор Visual Basic .NET. Он позволяет указать, когда нужно выйти из функции, чтобы возвратить значение в вызывающую программу, и каково это возвращаемое значение.В качестве альтернативы можно использовать синтаксис Visual Basic 6 и возвращать значение в вызывающий код, присвоив значение имени функции.

    Вызов подпрограммы типа Function

    Для вызова функцию в программе, необходимо поместить в оператор программы имя этой функции и все требуемые для нее аргументы (фактические параметры).

    Пример вызова функции в операторе присваивания:

    Проект «Функция»

    Задание. Создать проект, в котором определяется функция (например, умножения двух чисел F = x*y), выводится на надпись значение функции.

    1. Разместить на форме:
      • для вывода значений аргументов два текстовых поля TextBox1 и TextBox20;
      • для вывода значений функции надпись label1;
      • для создания обработчика события кнопку Button1.

    Создать код вызываемой функции:

    В этом уроке было показано применение процедур и функций для реализации вспомогательных алгоритмов. В следующем уроке поговорим о массивах

    Функции .NET разобраны

    При разборке функций .NET я замечаю, что все они начинаются с шаблона similair. Что делает этот исходный код?

    Этот код появляется перед фактическим кодом для функции, которую должна выполнять функция. Это какая-то проверка счетчика параметров?

    [Изменить] Так это правильное описание?

    Этот пролог состоит из двух частей.

    Настройка стекового кадра

    Здесь хранится текущий регистр EBP в стеке, а затем присваивается значение счетчика стека (ESP) для EBP.

    Если есть локальные переменные, которые хранятся в стеке (т.е. недостаточно места в доступных регистрах), то ESP будет перемещаться по их размеру для создания стекового кадра текущей функции.

    И в конце функции вы увидите, что эти операции отменены, поэтому восстанавливается стоп-кадр предыдущей функции.

    EBP всегда должен указывать на начало стекового кадра текущей функции
    ESP до конца (который имеет более низкий адрес на x86, потому что стек растет вниз).

    Это часть общих соглашений вызова и требуется для разворачивания стека при вызове исключения. Это не является специфичным для сети и используется большинством вызовов на окнах /x 86.

    После настройки стекового фрейма его общий для хранения некоторых регистров в стеке. Это потому, что вы можете использовать определенные регистры в качестве временных переменных, но для вызывающего соглашения требуется, чтобы ваша функция сохраняла их. Поэтому вам нужно создать резервную копию в стеке. Какие регистры должны быть сохранены и которые могут быть изменены, зависит от используемого вами соглашения о вызовах.

    При обращении к локальным переменным в стеке вы можете использовать [ebp-x] , где ebp указывает на начало стекового кадра, а x — смещение, которое указывает, где в стеке кадр хранится переменная. В качестве альтернативы вы можете использовать [esp+y] со смещением от конца стекового кадра.

    Вызов статического конструктора/инициализатора

    Как danbystrom заметила, что вторая часть, скорее всего, является вызовом статического конструктора/инициализатора. Поскольку статический конструктор не вызывается при запуске программы, но при первом доступе каждый доступ, для которого джиттер не может гарантировать, что статический конструктор уже выполнил, должен проверить, был ли он вызван, а затем вызывает его, если нет.

    Это что-то вроде if (globalVar!=0) Call Function_65CC36CF . Где, скорее всего, глобальный var указывает, запущен ли статический конструктор, а вызов — это вызов статического конструктора.

    Насколько я знаю, ваши комментарии к разборке верны.

    Отметьте эту запись в блоге OldNewThing на стековых кадрах: Как спасти сломанную трассировку стека: Восстановление цепи EBP

  • Понравилась статья? Поделиться с друзьями:
    Кодинг, CSS и SQL