简体   繁体   English

从 dll 调用 function 指针不起作用

[英]Calling function from dll with pointer not working

I made a test program and made a function that just prints some text, and I am trying to call it from a DLL by reversing it using IDA/Ghidra and getting a pointer to it.我制作了一个测试程序并制作了一个仅打印一些文本的 function,我试图通过使用 IDA/Ghidra 反转它并获取指向它的指针来从 DLL 调用它。

What it looks like in Ghidra它在 Ghidra 中的样子

I thought IDA was giving the wrong address so I checked with Ghidra and I got the same address...我以为 IDA 提供了错误的地址,所以我与 Ghidra 核对了一下,我得到了相同的地址......

Here is my code to call the function from my DLL这是我从 DLL 调用 function 的代码

#include <iostream>

void coolRoutine() {
    printf("starting...\n");
    void(*ofunct)() = (void(__cdecl *)())(0x00401000);
    printf("got funct!\n");
    ofunct();
    printf("done!\n");
}

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        coolRoutine();
        break;
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

The program prints "starting..." and "got funct."程序打印“开始...”和“得到功能”。 but does not call the original function.但不调用原始函数。

I have tried looking at several posts and I can't figure out what I am doing wrong as someone else did something similar and it worked for them.我已经尝试查看几个帖子,但我无法弄清楚我做错了什么,因为其他人做了类似的事情并且对他们有用。

Update: as someone suggested, I have tried adding the base address to the function pointer however I have ended up with the same result.更新:正如有人建议的那样,我尝试将基地址添加到 function 指针,但是我得到了相同的结果。

Here is what I tried:这是我尝试过的:

void coolRoutine() {
    printf("starting...\n");
    uintptr_t baseAddress = (uintptr_t)GetModuleHandle(0);
    std::cout << "Base Address: " << baseAddress << std::endl;
    void(*ofunct)() = (void(__cdecl *)())(baseAddress + 0x00401000);
    printf("got funct!\n");
    ofunct();
    printf("done!\n");
}

It is getting the base address correctly (or atleast I think it is, since it isn't null), but it isn't executing ofunct and print "done.".它正确地获取了基地址(或者至少我认为是,因为它不为空),但它没有执行 ofunct 并打印“完成”。

This is due to ASLR .这是由于ASLR The base address of the application changes every time it is restarted, and the disassembly in Ghidra shows what the address of it would have been without ASLR.应用程序的基地址在每次重新启动时都会发生变化,而 Ghidra 中的反汇编显示如果没有 ASLR,它的地址会是什么。

The default base address of an application pre-ASLR was 0x00400000, so we would have to do 0x00401000 - 0x00400000 to get our relative address to the base address which is 0x1000.应用程序 pre-ASLR 的默认基地址是 0x00400000,因此我们必须执行 0x00401000 - 0x00400000 才能获得与基地址 0x1000 的相对地址。

Now, we want to add 0x1000 to base address to get our function pointer.现在,我们要将 0x1000 添加到基地址以获取 function 指针。

This can be achieved using这可以使用

//Get the base address of the application
uintptr_t baseAddress = (uintptr_t)GetModuleHandle(0);
//Add the offset of the function relative to the base
uintptr_t functAddress = baseAddress + 0x1000;
//typecast it to the correct function signature
void(*funct)() = (void(__cdecl *)())(functAddress);
//call it
funct();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM