Как получить сигнатуры методов из файла банки?

Я часто использую внедрение кода в качестве метода имитации для автоматического тестирования кода на языке Си. Если вы находитесь в такой ситуации - если вы используете GDB просто потому, что вас не интересуют родительские процессы, а не потому, что вы хотите интерактивно выбирать интересующие процессы - тогда вы все равно можете используйте LD_PRELOAD для достижения вашего решения. Ваш внедренный код просто должен определить, находится ли он в родительском или дочернем процессах. Есть несколько способов сделать это, но в Linux, поскольку ваш дочерний процесс exec(), проще всего, вероятно, взглянуть на активный исполняемый образ.

Я создал два исполняемых файла, один с именем a, а другой b. Исполняемый файл a печатает результат вызова rand() дважды, затем fork() с и exec() с b дважды. Исполняемый файл b выводит результат вызова rand() один раз. Я использую LD_PRELOAD, чтобы добавить результат компиляции следующего кода в исполняемые файлы:

// -*- compile-command: "gcc -D_GNU_SOURCE=1 -Wall -std=gnu99 -O2 -pipe -fPIC -shared -o inject.so inject.c"; -*-
#include <sys/types.h>
#include <unistd.h>
#include <limits.h>
#include <stdio.h>
#include <dlfcn.h>

#define constructor __attribute__((__constructor__))

typedef int (*rand_t)(void);

typedef enum {
    UNKNOWN,
    PARENT,
    CHILD
} state_t;

state_t state = UNKNOWN;
rand_t rand__ = NULL;

state_t
determine_state(void)
{
    pid_t pid = getpid();
    char linkpath[PATH_MAX] = { 0, };
    char exepath[PATH_MAX] = { 0, };
    ssize_t exesz = 0;

    snprintf(linkpath, PATH_MAX, "/proc/%d/exe", pid);
    exesz = readlink(linkpath, exepath, PATH_MAX);
    if (exesz < 0)
        return UNKNOWN;

    switch (exepath[exesz - 1]) {
    case 'a':
        return PARENT;
    case 'b':
        return CHILD;
    }

    return UNKNOWN;
}

int
rand(void)
{
    if (state == CHILD)
        return 47;
    return rand__();
}

constructor static void
inject_init(void) 
{
    rand__ = dlsym(RTLD_NEXT, "rand");
    state = determine_state();
}

Результат выполнения a с и без внедрения:

$ ./a
a: 644034683
a: 2011954203
b: 375870504
b: 1222326746
$ LD_PRELOAD=$PWD/inject.so ./a
a: 1023059566
a: 986551064
b: 47
b: 47

I ' Позже я опубликую решение, ориентированное на gdb.

45
задан MCS 10 June 2009 в 15:33
поделиться

4 ответа

jar tf выведет для вас список содержимого. javap позволит вам увидеть более подробную информацию о классах (см. Руководство по инструментам).

Например, если у вас есть класс с именем mypkg.HelloWorld в банке myjar.jar , затем запустите его как

javap -classpath myjar.jar mypkg.HelloWorld

Однако вы уверены, что хотите использовать эти неопубликованные API? Обычно это действительно плохая идея.

57
ответ дан 26 November 2019 в 21:20
поделиться

Как сказал Скотт, вы можете использовать Eclipse, чтобы получить то, что ищете.

Я бы рекомендовал получить плагин JadClipse , который будет декомпилировать .class файлы "на лету" и показывают реальный код Java при просмотре классов в среде IDE.

5
ответ дан 26 November 2019 в 21:20
поделиться

Если вы используете eclipse, вы можете просто добавить его в путь к классам проекта и исследовать его с помощью древовидного представления и / или помощника по содержанию.

Я предполагаю, что другие IDE могут делать аналогичные .

С точки зрения командной строки, вы можете отключить его (jar xf foo.jar) и использовать javap для всех файлов.

4
ответ дан 26 November 2019 в 21:20
поделиться
​​
  • Eclipse отлично работал бы

  • A Декомпилятор Java преобразовал бы классы обратно в некое подобие исходного кода, который вы могли бы изучить, чтобы узнать о классах, методах, их подписи и, возможно, даже некоторое представление о допустимых значениях для некоторых аргументов (например, не передавайте значение null для этого аргумента, иначе вы немедленно вызовете исключение NullPointerException). Но засучите рукава, чтобы открыть банку и запустить декомпилятор для всех файлов классов. По сути, это то, что Eclipse делает для справочного текста с недокументированными классами.

  • Наконец, конечно, «настоящий программист» прочитал бы байт-код напрямую без необходимости в декомпилятор.

2
ответ дан 26 November 2019 в 21:20
поделиться
Другие вопросы по тегам:

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