Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/157.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 带有地址的奇怪bug_C++_C_Windows - Fatal编程技术网

C++ 带有地址的奇怪bug

C++ 带有地址的奇怪bug,c++,c,windows,C++,C,Windows,我有几个问题要解决,请帮忙 我的第一个问题是表达式必须是指向完整对象类型的指针,但我通过在变量前添加&解决了这个问题,我做得对吗 下面的代码片段 LPVOID dll; PIMAGE_DOS_HEADER dos; dll = LoadLibraryA(a[1]); dos = (PIMAGE_DOS_HEADER)dll; nt = (PIMAGE_NT_HEADERS)(&dll+dos->e_lfanew); #include&

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

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

下面的代码片段


    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;

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


    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;

}

有什么问题吗?

在WIN OS下,模块句柄是加载到内存中的库的基址

在地址之前添加
并不能解决问题,但会创建一个更大的问题,添加一个导致内存冲突的间接寻址(现在使用变量
dll
的地址作为模块基地址)

不能对空指针进行数学计算,因为
void
没有阻止正确位移计算的大小。将基指针设为
字节
指针,而将基指针的大小设为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;

}
#包括
#包括
#包括
int main(int i,char*a[]
{
LPVOID-faddr;
字节*dll;
PIMAGE_DOS_HEADER DOS;
PIMAGE\u NT\u头;
PIMAGE_导出_目录exp;
PDWORD地址列表、名称列表;
PWORD f_ord_清单;
德沃德rva;
LPSTR-fname;
如果(i!=2)
{
printf(“错误\n”);
返回0;
}
dll=(字节*)加载库a(a[1]);
如果(dll==NULL)
{
printf(“加载失败\n”);
返回0;
}
dos=(PIMAGE\U dos\U头)dll;
nt=(PIMAGE\u nt\u头)(dll+dos->e\u lfanew);
exp=(PIMAGE\u EXPORT\u目录)(dll+nt->OptionalHeader.DataDirectory[0].VirtualAddress);
f_addr_list=(PDWORD)(dll+exp->addressofffunctions);
f_name_list=(PDWORD)(dll+exp->AddressOfNames);
f_ord_list=(PWORD)(dll+exp->AddressOfNameOrdinals);
printf(“总函数名:%ld\n总函数:%ld\n”,exp->NumberOfNames,exp->NumberOfFunctions);
printf(“地址\t\t\t\t函数名\n”);
printf(“----\t\t\t\t\t----\n”);
对于(i=0;iNumberOfNames;i++)
{
fname=(LPSTR)(dll+f_name_list[i]);
rva=f_ord_list[i];
faddr=dll+f_地址列表[rva];
printf(“%p\t\t\t\t%s\n”,faddr,fname);
}
FreeLibrary((LPVOID)dll);
返回0;
}

&dll+dos->e\u lfanew
导致未定义的行为。一般来说,“尝试直到错误消失”不是一个好方法,在CAlso程序请不要双重标签;根据你使用的编译器选择C或C++