Заменив число на то же значение (число) из одного символа

«Как я могу прочитать данные (значения переменных) процесса, который создан с помощью ./test?".

Вы можете изучить формат отладки DWARF. Часть 3 ссылки Как работают отладчикиниже кратко обсуждает DWARF. Существуют и другие способы разрешения символов, но почему бы не поступить так, как GDB, и не использовать DWARF? [править: Извлечение функций из исходного кода gdb для использования их в более простых программах — нетривиальная задача]. Исходный код в любом случае доступен, проверьте 'Как загружается GDB Файлы символов" ниже, где ссылки указывают прямо на него.Третий вариант - ручной анализ таблиц символов ELF с вашими собственными функциями.Это уродливее и, вероятно, более сложный путь, но он не полагается на символы отладки, которые предоставляет dwarf.

Что касается точек останова, вы можете установить их с помощью ptrace и trap = memory & 0xffffff00 | 0xccпосле сохранения инструкции по адресу и восстановления инструкции после попадания в ловушку, как описано в Как работают отладчики. Байт 0xcc — это код операции int 3.

Чтобы увидеть, как это делает gdb, вот ссылка для вас: Как GDB загружает файлы символов

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

;hello.asm

section .text
    global _start

_start:
    mov edx,5
    mov ecx,msg
    mov ebx,1
    mov eax,4
    int 0x80

    mov eax,1
    int 0x80

msg:
    db "Hello"

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

#include 
#include 
#include 
#include 

#include 

void run_debugger(pid_t child_pid)
{
    int wait_status;
    unsigned icounter = 0;
    printf("debugger started\n");

    /* Wait for child to stop on its first instruction */
    wait(&wait_status);

    while (WIFSTOPPED(wait_status)) {
        icounter++;
        /* Make the child execute another instruction */
        if (ptrace(PTRACE_SINGLESTEP, child_pid, 0, 0) < 0) {
            perror("ptrace");
            return;
        }

        /* Wait for child to stop on its next instruction */
        wait(&wait_status);
    }

    printf("\nthe child executed %u instructions\n", icounter);
}


void run_target(const char* programname)
{
    printf("target started. will run '%s'\n", programname);

    /* Allow tracing of this process */
    if (ptrace(PTRACE_TRACEME, 0, 0, 0) < 0) {
        perror("ptrace");
        return;
    }

    /* Replace this process's image with the given program */
    execl(programname, programname, NULL);
}

int main(int argc, char** argv)
{
    pid_t child_pid;

    if (argc < 2) {
        fprintf(stderr, "Expected a program name as argument\n");
        return -1;
    }

    child_pid = fork();
    if (child_pid == 0)
        run_target(argv[1]);
    else if (child_pid > 0)
        run_debugger(child_pid);
    else {
        perror("fork");
        return -1;
    }

    return 0;
}

Скомпилировал это как a.out и запустил:

$ ./a.out helloasm
debugger started
target started. will run 'helloasm'
Hello
the child executed 7 instructions

vs.

#include 

int main()
{
        printf("Hello World\n");
        return 0;
}

, что в сумме составляет 141 690 инструкций.

1
25.03.2017, 17:29
2 ответа

В Perl символ может повторяться несколько раз с помощью оператора x:

$ perl -e 'print "#" x 10, "\n"'
##########

Давайте воспользуемся этим.

Вместо разбора выводаfind:

find. -type f -exec file -b {} + | sort | uniq -c | sort -rn |
perl -ne 'chomp; s/\s+(\d+)\s+// && printf("%-3d %-50s: %s\n", $1, $_, "#" x $1)'

Первая часть, вплоть до Perl-скрипта, будет выводить примерно так

  23 ASCII C program text
  12 ASCII text
  10 ELF 64-bit LSB relocatable, x86-64, version 1
   3 ASCII English text
   1 ELF 64-bit LSB shared object, x86-64, version 1

Сценарий Perl удалит завершающую новую строку с chomp, а затем выберет число в $1. Затем он использует printf()для вывода числа, типа файла и столько символов #, сколько указано числом.

Конечный результат будет примерно таким:

23  ASCII C program text                              : #######################
12  ASCII text                                        : ############
10  ELF 64-bit LSB relocatable, x86-64, version 1     : ##########
3   ASCII English text                                : ###
1   ELF 64-bit LSB shared object, x86-64, version 1   : #
0
28.01.2020, 00:58

Чтобы ответить на ваш главный вопрос «как символизировать число N последовательностью из N символов, вот команда оболочки, которая сделает именно это:

n=17          # Number to translate to a sequence
printf "%${n}s" '' | tr ' ' '#'

(альтернативный синтаксис:printf '%*s' "$n" '' | tr ' ' '#'; есть и другие альтернативы, вы поняли)

Он генерирует пустую строку, состоящую из nпробелов (части printf), а затем преобразует каждый пробел в нужный символ (часть tr).

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

count_files \
| while read n type; do 
    printf '%4d %-30s %s\n' "$n" "$type" "$(printf "%${n}s" '' | tr ' ' '#')"
done

... и ты получишь это:

   8 empty                          ########
   6 ASCII text                     ######
   3 Vim swap file, version 7.4     ###
   1 UTF-8 Unicode text             #
0
28.01.2020, 00:58

Теги

Похожие вопросы