首页
社区
课程
招聘
[旧帖] [求助]win32 DLL多个副本 0.00雪花
发表于: 2013-3-6 10:32 1406

[旧帖] [求助]win32 DLL多个副本 0.00雪花

2013-3-6 10:32
1406
事情是这样的:我在一个程序中通过#pragma comment(lib,"a.lib")指令动态连接a.dll,然后在程序运行的时候,我又通过LoadLibary("a.dll"),通过这两种方式或得到的同一个函数地址(假设Add()函数)是不同的,真心不知道为什么。也就是说:这个a.dll被映射到应用程序中两次。表示疑惑不解。
     但是我在通过两种方式获取LoadLibrary本身地址,地址是一致的。也就是kernel.dll仅仅被加载了一次。求解。

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (5)
雪    币: 3
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
typedef HMODULE        (WINAPI *Type_LoadLibraryW)(__in LPCTSTR lpLibFileName);
                Type_LoadLibraryW DetourLoadLibraryW=NULL;
                DetourLoadLibraryW =(Type_LoadLibraryW)GetProcAddress(hKernel,"LoadLibraryW");
                Type_LoadLibraryW original=LoadLibraryW;

结果:
                DetourLoadLibraryW        0x7707ef42       
                original                                        0x7707ef42
2013-3-6 10:39
0
雪    币: 293
活跃值: (287)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
3
不可能的,你LoadLibrary的地址跟加载器加载的地址都一样了,怎么可能得到的地址不一样呢?
;;;;;;; a.DLL
        .386
        .model flat,stdcall
        option casemap:none

include windows.inc
include user32.inc
include kernel32.inc
includelib user32.lib
includelib kernel32.lib

        .code
DllEntry        proc a:DWORD,reason:DWORD,cdd:DWORD
        mov eax,1
        ret
DllEntry  endp

iAdd proc a:DWORD,b:DWORD
        mov eax,a
        add eax,b
        ret
iAdd endp

end DllEntry

;;;;;;;;;;;;;;;;;;;;;;;call.asm
        .386
        .model flat,stdcall
        option casemap:none

include windows.inc
include user32.inc
include kernel32.inc
include Strings.mac
includelib user32.lib
includelib kernel32.lib
includelib a.lib

iAdd PROTO a:DWORD,b:DWORD

        .code
testfunadd proc hmodle:DWORD
        lea eax,[iAdd+2] ; 跳过 jmp 指令 FF25 得到保存iAdd的地址
        mov eax,[eax] ;导入表中的地址
        mov eax,[eax] ;获取iAdd地址
        push eax
        invoke GetProcAddress, hmodle, $CTA0("iAdd")
        pop ebx
        .if eax != ebx
                invoke MessageBoxA, NULL, $CTA0("iAdd 函数地址不一致"), $CTA0("error"), NULL
        .elseif
                invoke MessageBoxA, NULL, $CTA0("iAdd 函数地址是一致滴"), $CTA0("right"), NULL
        .endif
        ret
testfunadd endp
               
start:
        invoke GetModuleHandleA, $CTA0("a.dll")
        push eax
        invoke LoadLibraryA, $CTA0("a.dll")
        mov ebx,[esp]
        .if eax != ebx
                invoke MessageBoxA, NULL, $CTA0("基址不同"), $CTA0("error"), NULL
        .endif
        pop eax
        invoke testfunadd, eax
        invoke ExitProcess,NULL
end start

取出来地址相同的好吧
2013-3-6 11:16
0
雪    币: 496
活跃值: (286)
能力值: ( LV13,RANK:400 )
在线值:
发帖
回帖
粉丝
4
同学,要打好基础。

首先#pragma comment(lib,"a.dll")这个是肯定编译不过的
因为这种写法只是告诉编译器要使用静态库,你写的是a.dll,如果a.dll不再你的默认库路径下,编译器会提示打不开a.dll,就算你把a.dll放在了你的默认库路径下,编译到后面也会提示你无法解析的符号。

另外,你说的方法是可行的,先静态连接一个库,然后再去显示加载那个DLL,编译出来目标程序后a.exe,当你运行a.exe的时候,Windows会先去找a.exe的倒入表,发现你静态链接了那个a.dll就会把a.dll加载进来,然后你又显示的加载了那个DLL,但是LoadLibrary并不会再把a.dll加载进来,因为已经被加载过了,所以直接返回已经存在的模块句柄,你所说的获取同一个函数的地址不同,是不可能的。

好好打基础。
2013-3-6 19:59
0
雪    币: 3
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
哦,知道了 你说的非常对,一定会努力打基础的。
2013-3-7 09:59
0
雪    币: 3
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
太厉害的纯汇编写的,非常感谢你。我现在还在测试,不知道究竟在什么时候会发生那种情况。
2013-3-7 10:06
0
游客
登录 | 注册 方可回帖
返回
//