Размер программы в байтах

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

Отслеживать
задан 9 фев 2016 в 8:24
504 2 2 серебряных знака 15 15 бронзовых знаков
что имеется ввиду под размером функции?
9 фев 2016 в 8:25

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

9 фев 2016 в 8:26
вам стоит развернуть свой вопрос
9 фев 2016 в 8:35
9 фев 2016 в 8:46

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

9 фев 2016 в 9:09

2 ответа 2

Сортировка: Сброс на вариант по умолчанию

Функция в С/С++ не обязана быть непрерывной последовательностью инструкций машинного кода с четко выраженным началом и концом. Если несколько функций содержат одинаковый завершающий блок кода («эпилог»), оптимизирующий компилятор может включить его в бинарник только в одной функции, а в других заменить его на инструкцию перехода в первую. В таком случае понятие «размер функции» становится неоднозначным. Кроме того, попытка перенести машинный код из одного процесса в другой «как есть» скорее всего закончится неудачей, ведь инструкции часто оперируют относительными адресами. Более правильным решением было бы реализовать инжектируемый блок кода полностью в виде ассемблерной вставки, как например здесь.

Почему размер байта 8 бит. Машина Тьюринга. Принцип выполнения программы

Тем не менее, API для получения размера функции (как справочной информации) существуют. Например, так это можно сделать в Windows с помощью dbghelp:

Читайте также:
Компьютерная графика какие программы

#include #include #include #include «DbgHelp.h» #pragma comment(lib, «Dbghelp.lib») struct Function < const char* name; unsigned int size; bool success; >; BOOL CALLBACK EnumSymProc(PSYMBOL_INFO pSymInfo, ULONG SymbolSize, PVOID context) < Function* pfstruct = (Function*)context; if (strcmp(pSymInfo->Name, pfstruct->name) == 0) < pfstruct->size = SymbolSize; pfstruct->success = true; return FALSE; //закончить поиск > return TRUE; //продолжить поиск > // Находит размер функции fname и помещает в переменную resultvar // Требует наличия отладочных символов (PDB-файла) в каталоге с программой bool GetFunctionSize(const char* fname, unsigned int bool ret; Function fstruct; fstruct.name = fname; fstruct.size = 0; fstruct.success = false; HANDLE hProcess = GetCurrentProcess(); //текущий процесс char Mask[] = «*!»; //искать среди всех модулей BOOL status; status = SymInitialize(hProcess, NULL, TRUE); //загрузка символов if (status == FALSE) < printf(«SymInitialize failed. Error code: %dn», GetLastError()); return false; >//поиск символов if (SymEnumSymbols(hProcess, 0, Mask, fstruct)) < if (fstruct.success != false) < resultvar = fstruct.size; //возвращаем размер ret = true; >else < printf(«Symbol [%s] not foundn», fname); ret = false; >> else < printf(«SymEnumSymbols failed. Error code: %dn», GetLastError()); ret = false; >SymCleanup(hProcess); return ret; > //********************************** void Func() < printf(«Hello, World!n»); >int main(int argc, char **argv) < uintptr_t p = (uintptr_t)&Func; printf(«Func address: 0x%xn», (UINT)p); unsigned int size = 0; if (GetFunctionSize(«Func», size) != false) < printf(«Func size: %u bytes», size); >getchar(); return 0; >

При использовании Visual Studio 2017+ для корректной работы данного кода необходимо собирать проект с параметром /DEBUG:FULL (см. /DEBUG).

Просто о битах, байтах и о том, как хранится информация #2

Источник: ru.stackoverflow.com

8.1. Структура оперативной памяти для программ на Turbo Pascal

Рассмотрим общую схему использования оперативной памяти программами на Turbo Pascal.

На персональном компьютере адреса задаются совокупностью двух шестнадцатеричных слов, которые называются сегментом и смещением. Сегмент – это участок памяти, имеющий длину 64 Кбайт (65536 байт) и начинающийся с физического адреса, кратного 16 (0, 16, 32, 48 и т.д.). Смещение указывает, сколько байт от начала сегмента необходимо пропустить, чтобы обратиться к нужному адресу.

Читайте также:
Что такое g90 в программе

Параграфом называется непрерывный фрагмент памяти, объемом в 16 байт. Сегмент адресует с точностью до

параграфа, смещение с точностью до байта. Поэтому, абсолютный адрес образуется следующим образом: сегмент*16 + смещение.

В начале любой программы, выполняемой в среде DOS, операционная система формирует префикс сегмента программы (PSP). PSP занимает 256 байт памяти и его адрес хранится в переменной PrefixSeg модуля System. PSP содержит характеристики программы, используемые MS DOS при загрузке программы в оперативную память, например, размер программы, параметры вызова.

За PSP следует кодовый сегмент головной программы, ее exe-файл.

Далее расположены кодовые сегменты модулей в порядке, обратном их следованию в операторе uses. Последний кодовый сегмент занимает библиотека времени выполнения (модуль System). Размер кодового сегмента не может превышать 64 Кбайт, количество кодовых сегментов ограничено имеющейся оперативной памятью.

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

Размер сегмента данных составляет 64 Кбайт. Сегмент данных адресуется посредством регистра DS (Data Segment). Регистр DS никогда не изменяется во время выполнения программы. Содержимое этого регистра может быть получено с помощью стандартной функции Dseg модуля System.

Сегмент стека используется для управления локальными переменными подпрограмм. Сегмент стека

адресуется специальным регистром SS (Stack Segment), значение которого не изменяется во время выполнения программы. Другой регистр процессора SP(Stack Pointer) всегда показывает адрес свободной области сегмента стека. Значение этого регистра меняется в процессе вызова подпрограмм и выхода из них. Значения регистров SS и SP можно просмотреть, используя соответственно стандартные функции Sseg и Sptr. Для просмотра содержимого всех регистров процессора можно воспользоваться командой Register пункта Debug. Для просмотра содержимого стека

Читайте также:
Самая дешевая программа для сдачи отчетности через интернет

Верхняя граница памяти DOS

Источник: studfile.net

Программирование C — Как получить размер файла?

clang_slide

Как оказалось, узнать размер файла в языке C — совсем нетривиальная задача. В процессе её решения как минимум вы обязательно столкнетесь с переполнением целочисленного типа данных. В данной статье я приведу 4 способа получения размера файла с использованием функций из стандартной библиотеки C, функций из библиотеки POSIX и функций из библиотек Windows.
Способ 1: решение «в лоб» (скомпилируется везде, но работает очень долго)
Мы просто откроем файл в бинарном режиме и в цикле считаем из него байт за байтом.

#include // для int64_t
#include // для правильного вывода int64_t в printf
int64_t getFileSize ( const char * file_name ) <
int64_t _file_size = 0 ;
FILE * fd = fopen ( file_name , «rb» ) ;
if ( fd == NULL ) <
_file_size = — 1 ;
while ( getc ( fd ) != EOF )
_file_size ++ ;
fclose ( fd ) ;
return _file_size ;
#define FILE_PATH «some_file.txt»
int64_t file_size = getFileSize ( FILE_PATH ) ;
printf ( «File size: %» PRId64 «n» , file_size ) ;

Очевидным недостатком способа является скорость работы. Если у нас файл будет на много гигабайт, то только размер файла будет считаться относительно долго (это сколько байт то надо считать?), а надо же еще остальную программу выполнять.
Достоинство такого способа — работать должен на любой платформе. Ну и конечно можно ускорить процесс за счет считывания бОльшего количества байт.

Способ 2: с использованием функций fseek и ftell (ограничен для объемных файлов и работает не всегда верно)

Рейтинг
( Пока оценок нет )
Загрузка ...
EFT-Soft.ru