Ответ 1
Фиксация Perl Script
Шестнадцатеричное число > 0xffffffff не переносимое "
Это предупреждение от hex
, поскольку оно обнаруживает, возможно, не переносимое значение (что-то > 32 бита).
В самом верху script добавьте следующее:
use bigint qw/hex oct/;
Когда этот инструмент был написан, я подозреваю, что люди были на 32-битных машинах. Вы можете скомпилировать программу, используя 32-разрядную версию с флагом -m32
, но если вы измените perl script, как указано выше, вам это не понадобится.
Обратите внимание, что если вы находитесь на Mac, вы не можете использовать mknod
способ, которым он использовался в script для создания канала; вам нужно использовать mkfifo
без аргументов.
В Linux добавлено исправление bigint
выше. Затем вам нужно запустить обе команды из одного и того же каталога, я сделал это с помощью example2
:
../src/etrace.pl crumble
# Switch to a different terminal
./crumble
и я получаю это на Mac и Linux
\-- main
| \-- Crumble_make_apple_crumble
| | \-- Crumble_buy_stuff
| | | \-- Crumble_buy
| | | \-- Crumble_buy
| | | \-- Crumble_buy
| | | \-- Crumble_buy
| | | \-- Crumble_buy
| | \-- Crumble_prepare_apples
| | | \-- Crumble_skin_and_dice
| | \-- Crumble_mix
| | \-- Crumble_finalize
| | | \-- Crumble_put
| | | \-- Crumble_put
| | \-- Crumble_cook
| | | \-- Crumble_put
| | | \-- Crumble_bake
О динамической библиотеке...
При загрузке динамической библиотеки адрес в объектном файле не является адресом, который будет использоваться при запуске. Что означает etrace, это взять имя функции из указанного вами заголовка. Например, в случае example2
это будет следующее:
#include "crumble.h"
#define PTRACE_REFERENCE_FUNCTION Crumble_buy
Затем вы должны отредактировать make файл, чтобы убедиться, что файл заголовка можно найти:
CFLAGS = -g -finstrument-functions -I.
Обратите внимание на добавление include -I.
. Адрес символа из заголовка (в нашем случае Crumble_buy
) используется для вычисления смещения между объектным файлом и фактическим адресом; это позволяет программе рассчитывать правильный адрес, чтобы найти символ.
Если вы посмотрите на вывод nm
, вы получите примерно следующее:
0000000100000960 T _Crumble_bake
00000001000005b0 T _Crumble_buy
0000000100000640 T _Crumble_buy_stuff
00000001000009f0 T _Crumble_cook
Адреса слева являются относительными, то есть во время выполнения эти адреса фактически изменяются. Программа etrace.pl хранит их в хэше, например:
$VAR1 = {
'4294969696' => '_Crumble_bake',
'4294969424' => '_Crumble_put',
'4294970096' => '_main',
'4294969264' => '_Crumble_mix',
'4294970704' => '_gnu_ptrace_close',
'4294967296' => '__mh_execute_header',
'4294968752' => '_Crumble_buy',
'4294968896' => '_Crumble_buy_stuff',
'4294969952' => '_Crumble_make_apple_crumble',
'4294969184' => '_Crumble_prepare_apples',
'4294971512' => '___GNU_PTRACE_FILE__',
'4294971504' => '_gnu_ptrace.first',
'4294970208' => '_gnu_ptrace',
'4294970656' => '___cyg_profile_func_exit',
'4294970608' => '___cyg_profile_func_enter',
'4294969552' => '_Crumble_finalize',
'4294971508' => '_gnu_ptrace.active',
'4294969840' => '_Crumble_cook',
'4294969088' => '_Crumble_skin_and_dice',
'4294970352' => '_gnu_ptrace_init'
};
Обратите внимание на верхнее подчеркивание, потому что это на Mac, используя clang. Во время выполнения эти адреса неверны, но их относительные смещения. Если вы можете решить, что такое смещение, вы можете настроить адреса, которые вы получаете во время выполнения, чтобы найти фактический символ. Код, который делает следующее:
if ($offsetLine =~ m/^$REFERENCE_OFFSET\s+($SYMBOL_NAME)\s+($HEX_NUMBER)$/) {
# This is a dynamic library; need to calculate the load offset
my $offsetSymbol = "_$1";
my $offsetAddress = hex $2;
my %offsetTable = reverse %SYMBOLTABLE;
print Dumper(\%offsetTable);
$baseAddress = $offsetTable{$offsetSymbol} - $offsetAddress;
#print("offsetSymbol == $offsetSymbol\n");
#print("offsetAddress == $offsetAddress\n");
#print("baseoffsetAddress == $offsetAddress\n");
$offsetLine = <CALL_DATA>;
} else {
# This is static
$baseAddress = 0;
}
Для этого используется строка #define PTRACE_REFERENCE_FUNCTION Crumble_buy
. Код C
в ptrace использует этот MACRO и, если он определен, выводит адрес этой функции как первое. Затем он вычисляет смещение и для всех последующих адресов настраивает их на эту величину, просматривая правильный символ в хеше.