動態1:由函數名稱調用函數

來源:互聯網
上載者:User

前言:本文源於對CSDN論壇中一個問題的解答,現將其整理出來,以協助有相同需求的朋友。

對dll進行過動態載入的朋友應該清楚GetProcAddress這個API,其作用是通過一個函數名稱從dll模組中獲得這個函數的地址,然後將其轉換成相應的函數指標供我們調用。這便是通過函數名稱來調用函數的一個典型例子。下面我們就模擬一下這個函數,主要思路就是建立一張函數映射表。

#include <iostream>
using namespace std;

// 定義函數入口結構
typedef void (*FUN_PTR)(void); 
struct fun_entry
{
    const char* fun_name; // 函數名稱
    FUN_PTR fun_ptr; // 函數指標,實際上這裡的資料類型也可以是整型
};

// 定義了兩個原型不同的函數
void foo1() { cout << "foo1" << endl; }
int foo2(int i) { cout << "foo2:" << i << endl; return 0; }

// 定義函數映射表
fun_entry fun_entry_table[] = 
{
    {"foo1", (FUN_PTR)foo1},
    {"foo2", (FUN_PTR)foo2}
};

// 類比GetProcAddress
FUN_PTR get_proc_address(const char* fun_name)
{
    for(int i=0; i<sizeof(fun_entry_table)/sizeof(fun_entry_table[0]); i++)
    {
        if(strcmp(fun_name, fun_entry_table[i].fun_name) == 0)
            return fun_entry_table[i].fun_ptr;
    }
    return NULL;
}

int main()
{
    typedef void (*foo1_ptr)(void);
    typedef int (*foo2_ptr)(int);
    
    foo1_ptr pfoo1 = (foo1_ptr)get_proc_address("foo1"); // 獲得函數入口地址,並轉換成函數指標
    if( pfoo1 ) pfoo1(); // 通過函數指標調用函數
    foo2_ptr pfoo2 = (foo2_ptr)get_proc_address("foo2");
    if( pfoo2 ) pfoo2( 100 );
    system("pause");
    return 0;
}

是不是很簡單,可GetProcAddress究竟是怎麼實現的呢?這個我目前還不太清楚,不過我們知道dll中有函數符號資訊,可以方便的定位一個函數的入口地址。要是普通的程式的二進位代碼中也有函數名稱,那且不是很爽!但這樣就暴露了程式的內部實現,這可大大方便了駭客,:)。

今天是9.18,勿忘國恥,振興中華!

(freefalcon於2004.09.18)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.