地址的奇怪错误

Posted

技术标签:

【中文标题】地址的奇怪错误【英文标题】:Weird bug with addresses 【发布时间】:2020-07-05 20:47:43 【问题描述】:

我有几个问题要解决,请帮忙!

我的第一个问题是 表达式必须是指向完整对象类型的指针,但我已经通过在变量前添加 & 解决了这个问题,我做对了吗? p>

下面的代码片段。


    LPVOID dll;
    PIMAGE_DOS_HEADER dos;
    dll = LoadLibraryA(a[1]);
    dos = (PIMAGE_DOS_HEADER)dll;
    nt = (PIMAGE_NT_HEADERS)(&dll+dos->e_lfanew);


下一个问题是我的程序输出总是不同的,为什么? 我的程序应该显示所有地址和函数名称,代码如下。

#include<stdio.h>
#include<windows.h>
#include<winternl.h>


int main(int i, char* a[]) 
    LPVOID dll, faddr;
    PIMAGE_DOS_HEADER dos;
    PIMAGE_NT_HEADERS nt;
    PIMAGE_EXPORT_DIRECTORY exp;

    PWORD f_addr_list, f_name_list;
    PWORD f_ord_list;
    DWORD rva;
    LPSTR fname;


    if (i != 2) 
        printf("error");
        return 0;
    

    dll = LoadLibraryA(a[1]);
    if (dll == NULL) 
        printf("failed to load");
        return 0;
    

    dos = (PIMAGE_DOS_HEADER)dll;
    nt = (PIMAGE_NT_HEADERS)(dll+dos->e_lfanew);
    exp = (PIMAGE_EXPORT_DIRECTORY)(&dll + nt->OptionalHeader.DataDirectory[0].VirtualAddress);

    f_addr_list = (PDWORD)(&dll + exp->AddressOfFunctions);
    f_name_list = (PDWORD)(&dll + exp->AddressOfNames);
    f_ord_list = (PWORD)(&dll + exp->AddressOfNameOrdinals);
    
    printf("Total function names: %ld\nTotal Function: %ld\n", exp->NumberOfNames, exp->NumberOfFunctions);
    printf("Address\t\t\t\t\Function Name\n");
    printf("-------\t\t\t\t\t----------\n");

    for (i = 0; i < exp->NumberOfNames; i++)
    
        fname = (LPSTR)dll + f_name_list[i];
        rva = f_ord_list[i];
        faddr = &dll + f_addr_list[rva];
        printf("%p\t\t\t\t%s\n", faddr, fname);


    

    FreeLibrary(dll);
    return 0;


示例输出:

C:\Users\user\Project2\Debug>Project2.exe user32.dll
Total function names: 2
Total Function: 11914128
Address                         Function Name
-------                                 ----------

C:\Users\user\Project2\Debug>Project2.exe user32.dll
Total function names: 2
Total Function: 11914128
Address                         Function Name
-------                                 ----------

C:\Users\user\Project2\Debug>Project2.exe user32.dll
Total function names: 22826784
Total Function: 2
Address                         Function Name
-------                                 ----------

那里有什么问题?

【问题讨论】:

&amp;dll+dos-&gt;e_lfanew 导致未定义的行为。一般来说,“尝试直到错误消失”并不是用 C 编程的好方法 另外请不要双标;根据您使用的编译器类型选择 C ​​或 C++ 【参考方案1】:

在 WIN 操作系统下,模块句柄是库的基址,就像加载到内存中一样。

在地址前添加&amp; 不能解决问题,而是创建一个更大的地址,添加一个导致内存冲突的间接(现在您正在使用变量@ 987654322@作为模块基地址)。

您不能对 void 指针进行数学运算,因为 void 没有阻止正确位移计算的大小。将基本指针设为BYTE 指针,而不是提供基本大小为 1。

您尝试做的工作代码是:

#include<stdio.h>
#include<windows.h>
#include<winternl.h>

int main(int i, char *a[])

    LPVOID faddr;
    BYTE *dll;
    PIMAGE_DOS_HEADER dos;
    PIMAGE_NT_HEADERS nt;
    PIMAGE_EXPORT_DIRECTORY exp;

    PDWORD f_addr_list, f_name_list;
    PWORD f_ord_list;
    DWORD rva;
    LPSTR fname;

    if (i != 2)
    
        printf("error\n");
        return 0;
    

    dll = (BYTE *)LoadLibraryA(a[1]);
    if (dll == NULL)
    
        printf("failed to load\n");
        return 0;
    

    dos = (PIMAGE_DOS_HEADER)dll;
    nt  = (PIMAGE_NT_HEADERS) (dll + dos->e_lfanew);
    exp = (PIMAGE_EXPORT_DIRECTORY) (dll + nt->OptionalHeader.DataDirectory[0].VirtualAddress);

    f_addr_list = (PDWORD) (dll + exp->AddressOfFunctions);
    f_name_list = (PDWORD) (dll + exp->AddressOfNames);
    f_ord_list  = (PWORD) (dll + exp->AddressOfNameOrdinals);

    printf("Total function names: %ld\nTotal Function: %ld\n", exp->NumberOfNames, exp->NumberOfFunctions);
    printf("Address\t\t\t\tFunction Name\n");
    printf("-------\t\t\t\t\t----------\n");

    for (i = 0; i < exp->NumberOfNames; i++)
    
        fname = (LPSTR)(dll + f_name_list[i]);
        rva   = f_ord_list[i];
        faddr = dll + f_addr_list[rva];
        printf("%p\t\t\t\t%s\n", faddr, fname);
    

    FreeLibrary((LPVOID)dll);
    return 0;


【讨论】:

以上是关于地址的奇怪错误的主要内容,如果未能解决你的问题,请参考以下文章

CreateProcess 和奇怪的 nslookup 错误

得到奇怪的线程1:EXC_BAD_ACCESS(代码= 1,地址= 0x9)swift中的崩溃错误

Linux升级openssl时遇到的奇怪错误

使用valgrind时出现奇怪的错误?也许是一个错误?

CGContext 的奇怪错误

MySQL 语法错误?奇怪的错误