Как получить абсолютный адрес функции?

Написал функцию которая распечатывает дамп памяти. Сама функция вроде работает правильно. Не правильно только когда в качестве стартового адреса подсовываешь имя функции. Вроде и имя массива, и имя функции являются константными указателями, то есть это адреса памяти. Только когда подсовываешь имя массива — все работает как надо. А когда имя функции — дампит, но с другого адреса. Я посмотрел по дизассемблированному коду, там используется offset:

    dump(&dump, 100);
00E34E01 A1 60 A3 E3 00   mov         eax,dword ptr [__imp_std::cout (0E3A360h)] 
00E34E06 50               push        eax  
00E34E07 6A 64            push        64h  
00E34E09 68 D6 11 E3 00   push        offset dump (0E311D6h) 
00E34E0E E8 C3 C3 FF FF   call        dump (0E311D6h) 
00E34E13 83 C4 0C         add         esp,0Ch 

и дампит она у меня с адреса по значению оффсета: 00E311D6h, что правильно, если смотреть в дизассемблер. А реально функция dump начинается с адреса 00E31550h. Конкретные адреса от запуска к запуску изменяются но смысл остается.

Объясните тупому хомяку как в функцию передать абсолютный адрес другой функции без применения шаманства в виде ассемблерного кода. Я уже себе весь мозг порушил. Причем когда в отладчике студии наводишь мышь на &dump, она показывает правильный адрес 00E31550h. Пробовал сделать даже через указатель на функцию. Теже яйца только сбоку. В указатель записывается оффсет и по этому оффсету прекрасно вызывается функция. Вопщем HELP!

#include <iostream>
#include <iomanip>

using namespace std;

void dump(const void *mem, int len, ostream& os = cout) {
    const unsigned char *byte = reinterpret_cast<const unsigned char *>(mem);
    if (len < 0) {
        len = -len;
        byte -= len;
    }
    unsigned int lines = len / 16;
    if (len % 16)
        lines++;
    os << endl << setfill('0') << uppercase;
    for (unsigned int i = 0; i < lines; i++) {
        os << hex << setw(8) << reinterpret_cast<const void *>(byte) << "h ";

        for (unsigned int b = 0; b < 16; b++) {
            if (i*16 + b < (unsigned)len) {
                os << setw(2) << static_cast<unsigned int>(byte[b]) << ' ';
            }
            else {
                os << "   ";
            }
            if ((b+1) % 8 == 0)
                os << ' ';
        }

        for (unsigned int b = 0; b < 16; b++) {
            if (i*16 + b < (unsigned)len) {
                if (byte[b] >= ' ')
                    os << byte[b];
                else
                    os << '.';
            }
            else {
                os << "   ";
            }
            if ((b+1) % 8 == 0)
                os << ' ';
        }

        os << endl;
        byte += 16;
    }

}

char area1[] = "qwerty:QWERTY";
unsigned int area2[2][3] = { {1, 2, 3}, {40, 50, 60} };
char *area3[3] = { "poiu", "lkjhg", "mnbv" };

int main() {

    char *str1 = "asdfghjkl";
    char *str2 = "zxcvbnm";

    dump(area1, 30);
    dump(area2, 30);
    dump(area3, 30);
    dump(area3[2], 30);
    dump(str2, -16);
    dump(reinterpret_cast<unsigned char *>(str2) - 16, 32);
    dump(&str2, 16);
    dump(&dump, 100);  // <- здесь работает неправильно

    system("pause");
    return 0;
}

Visual Studio 2008, win7.

Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.

Ответить

Вы можете использовать разметку markdown для оформления комментариев и постов. Используйте функцию предпросмотра для проверки корректности разметки.

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

Либо производите оформление кода вручную, следующим образом:

``` #include <iostream> using namespace std; int main() { // ... } ```

Предпросмотр сообщения

Ваше сообщение пусто.