C - 从外部进程调用函数而不导出函数

Posted

技术标签:

【中文标题】C - 从外部进程调用函数而不导出函数【英文标题】:C - Calling functions from external process without exported functions 【发布时间】:2010-08-01 03:17:36 【问题描述】:

我试图弄清楚如何在不导出函数的情况下调用它。

好的,所以我有一个 exe 文件,其中定义了“add”,这个 exe 是一个 win32 控制台应用程序并加载一个 DLL。该 DLL 还旨在使用 exe 文件中的添加功能(没有导出)

这是我的主要 win32 控制台应用程序文件:

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

#pragma auto_inline ( off )

int add ( int a, int b )

    printf( "Adding some ints\n" );
    return a + b;


int main ( )

    HMODULE module = NULL;

    if ( (module = LoadLibrary( L"hook.dll" )) == NULL )
    
        printf( "Could not load library: %ld\n", GetLastError() );
        return 0;
    

    add( 3, 5 );

    FreeLibrary( module );

    return 0;

这里是 hook.dll 的代码:

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

static int (*add) ( int a, int b ) = ( int (*)( int a, int b ) ) 0x401000;

int Detoured_add ( int a, int b )

    return add( a, b );


BOOL WINAPI DllMain ( HINSTANCE hDll, DWORD reason, LPVOID reserved )

    if ( reason == DLL_PROCESS_ATTACH )
    
        DetourTransactionBegin();
        DetourAttach( (PVOID*) &add, Detoured_add );
        DetourTransactionCommit();

    
    else if ( reason == DLL_PROCESS_DETACH )
    
        DetourTransactionBegin();
        DetourDetach( (PVOID*) &add, Detoured_add );
        DetourTransactionCommit();
    

    return TRUE;

我反汇编了我的win32控制台应用程序,找到了add函数的地址

.text:00401000 ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
.text:00401000
.text:00401000
.text:00401000 sub_401000      proc near               ; CODE XREF: sub_401020:loc_40104Bp
.text:00401000                 push    offset aAddingSomeInts ; "Adding some ints\n"
.text:00401005                 call    ds:printf
.text:0040100B                 add     esp, 4
.text:0040100E                 mov     eax, 8
.text:00401013                 retn
.text:00401013 sub_401000      endp

问题是当我调用 LoadLibrary 时,它返回 998,我认为这是错误代码访问冲突。我想这是有道理的,因为该内存区域可能受到保护。

有什么建议吗?

(另外我用的反汇编器是Ida Pro免费版,detours库是微软提供的。)

【问题讨论】:

我对Detours了解不多,不确定能不能这样用。但是你确定 add() 的地址在运行时实际上是 0x401000 吗?模块不能重定位吗? 对了,地址我也不太清楚,因为我是新手。 我将继续努力并报告我的发现。 你给自己带来了很多麻烦和悲伤。从实际的角度来看,您有两个选择:要么导出函数,要么让您的可执行文件传递一个指向需要调用的函数的指针。 【参考方案1】:

模块在加载时会重新定位。您应该找到已加载模块的基地址并自己重新定位该地址。此外,您可以使用 [DebugHelp][1] 库通过符号名称而不是硬编码来检索函数地址。

【讨论】:

+1 我想可以使用DebugHelp。不过,您必须使用调试信息编译模块。 我发现将反汇编得到的原始十六进制码值作为函数指针放入可以工作,但不适用于 win32 控制台应用程序。 Windows DEP 阻止它。所以 int (add)( int a, int b ) = ( int ()(int,int) ) 0x2329381; // 一些值 如果它只是来自主可执行文件,这似乎工作正常,但是如果它来自主可执行文件使用的外部模块,我认为这将工作:HMODULE handle = GetModuleHandleA("another.dll"); int (add)( int a, int b ) = ( int ()(int,int) )( (DWORD)handle + (DWORD)0x2329381 );

以上是关于C - 从外部进程调用函数而不导出函数的主要内容,如果未能解决你的问题,请参考以下文章

windows中dll的"导出函数"是啥?"导入函数"又是啥?和普通的C语言函数有啥区别?

为啥有的dll里没有导出函数?

c++调用dll导出函数

未导出成员函数时,从 C# 调用 C++ 本机/非托管成员函数

如何从另一个模块调用导出的内核模块函数?

调用另一个进程加载的 DLL 中的函数