“而对于DLL,函数储存在一个独立的动态链接库文件中。在创建Windows程序时,链接过程并不把DLL文件链接到程序上。直到程序运行并调用一个DLLs中的函数时,该程序才要求这个函数的地址。此时Windows才在DLL中寻找被调用函数,并把它的地址传送给调用程序。一般情况下,如果一个应用程序使用了动态链接库,Win32系统保证内存中只有DLL的一份复制品,这是通过内存映射实现的。DLL首先被调入Win32系统的全局堆栈,然后映射到调用这个DLL的进程的地址空间。在Win32系统中,每个进程拥有自己的32位线性地址空间。如果一个DLL被多个进程调用,每个进程都会被分配一份该DLL的映像。”既然是被调入Win32系统的全局堆栈,那么我就想知道,dll的代码区、数据区都拷贝到内存中了吗?
如果这个dll处于网络中的一个位置,映射到调用这个DLL的进程的地址空间时,会不会包含dll的详细地址?IP+端口号+路径……欢迎发表意见!
十分感谢阅读!

解决方案 »

  1.   

    dll叫啥来着?动态链接库?动态是啥意思?
    dll里面是啥?一堆函数?
      

  2.   

    “dll处于网络中的一个位置..." , 能举个例子么 , 你这个有点前卫呀, 难道是个网络系统?我的理解虽然是远程调用, 那也是在本地呀, 要不要操作系统干吗?  DLL都能远程运行,还分什么window,linux系统咯?如果你说编译过后和系统无关和硬件无关, 那么这个也应该是参数的问题, 如果已经给DLL植入了参数, 到哪里他的内存空间里头都有那个数据。
      

  3.   

    应该是和内存管理机制有关。
    每个进程只能访问自己的虚拟地址空间,通过进程私有的页目、页表来将虚拟地址和物理地址对应。
    所以DLL被调入Win32系统的全局堆栈后,引用它的不同进程的页表就可以指向它所在的同一个物理地址。
    在执行时,通过切换进程环境,dll 没有变动物理地址,函数指针在不同的进程内却可以表现为不同的虚拟地址。
    至于写 dll 专有的数据区,会自动复制一份,然后将页表指向复制后的物理地址。
      

  4.   

    网络调用指 MTS/COM+ 之类?
    这应该是代理模式,实现具体功能的 dll 只在服务器上加载,本地加载的 dll 在调用者和服务器直接进行代理,它内部的确有服务器的信息。
      

  5.   

    我是来学习的,DLL COM DCOM (防删除)
      

  6.   

    网络应用一般都是利用额外的dataspace传递信息.
      

  7.   

    DLL只能是在本地的,也就是说必需把对方映射为本地文件系统的一个分区,WinPE加载器不用考虑这个问题。
    只有进程外组件(ActiveX exe),才可以离开主EXE单独在远程主机中存活,他们之前的联系一般采用TCP或管道(管道似呼也是用TCP?135端口?)。
      

  8.   

    想试这个东西很简单,比方说,在局域网中有A、B两台电脑,假设B有一个可执行的EXE需要调用的DLL放在B本地目录,并且已经注册,B共享这个目录,A拷贝这个目录,不要注册它的DLL,A打开B共享目录并点击运行可执行的EXE,然后再点击运行本地的可执行的EXE,这时A电脑调用的Dll就是源于B。我们将B电脑关机,不重新注册本地Dll下,会系统报错。根据系统日志查看Dll的注册信息。这么长,不知道看糊涂了没有~~
      

  9.   

        动态链接库DLL的代码并不是某个应用程序的组成部份,而是在运行时链接到应用程序中。与动态链接不同,静态链接方式是在链接期间把库(静态链接库)中的代码链接到可执行文件中,也就是说,在可执行文件中含有库函数的代码。
        动态链接分为两阶段,即链接过程和装过程。
        当应用程序调用动态链接库中的某个函数时,链接程序并不拷贝被调用函数的代码,而只是从引入库中拷贝一些指示信息,指出被调用函数属于哪个动态链接库(.dll文件)。因此,在应用程序的可执行文件中,存放的不是被调用的函数的代码,而是DLL中该函数的内存地址。程序运行后,当需要调用该函数时,进入装入过程,把应用程序与DLL库一起装入内存,由Windows读入DLL中的函数并运行程序。
        可以看出,动态链接是在应用程序被装入到内存时进行的。这样,当多个应用程序调用库中的同一个函数时,不会在内存中有该函数的多个拷贝,而是只有一份拷贝,每个应用程序的可执行文件中装入的只是该函数的内存地址,程序运行时再把应用程序代码与被调用函数代码动态链接起来,从而可以节省内存资源。同时,由于DLL与应用程序分开,即使更新DLL,也不用修改已编译好的可执行文件。
    ----节选自清华大学出版社《Visual basic 6.0 Win32 API 程序设计》(刘炳文 李凤华著)第1章 1.1.2 动态链接库
      

  10.   

    其实我觉得把,你的A调用了B的DLL, DLL本身肯定是被完整地加载到A的内存, A的内存空间将对B的DLL所有函数入口分配内存地址, 在执行DLL目标函数的时候直接访问A的这个入口地址, 而不是B的内存地址, 你也不可能访问到(常规技术下我觉得是这样的).   这个过程里头, 是根本不需要 B机器的任何信息的.  但在实际系统设计的时候肯定为了考虑全局安全因素\系统效率\及独占模式等, B的在线主机信息应该是被记录下来的...放哪里还真不知道 .... 你说的B断线过后A会出错啥的, 这个恰恰类似于,本地程序的保护模式, 一个本地保护程序被执行了, 你是删除不掉这个程序的,  如果你用了系统低层高权限强制将物理信息修改, 系统的保护模式就会给出警告出错!!!这个过程确实间接反映了, 内存的保护模式和磁盘文件时有关联的, 不论他在任何地方....当然网络和本地的区别就是数据交互的方式不同了....原理应该差不了哪里去.  成熟的保护模式, 应该非常复杂, 那些小黑字们就喜欢钻这些空巴 , 对系统谙熟技术高超,他可以做异步注册, 其实就是告诉系统我是合法的, 并没有破坏你的保护, 但实际却是已经突破了保护限制了...这个应该就是攻进暴露漏洞了...
      

  11.   

    我觉得,regsvr32.exe的注册原理值得研究~~
      

  12.   

    我觉得问题可能出自Windows的注册机制。我们也不知道它怎么搞的,貌似也没有公开吧?
      

  13.   

    其实为了简单,我 7 楼只说了物理内存。
    exe 进程通过映射调用 dll 函数时,系统保证该函数存在与某个物理页面中。
    但是,每个进程有2G的虚拟空间(常规设置),物理内存总是不够用的,所以系统会用到磁盘上的交换文件,将某些虚拟内存的页面临时存放在磁盘上。
    而对“已加载”的 dll,理想情况当然是一直驻留在物理内存中,但真要腾出物理内存时,并不需要将该页写入交换文件,下次调用时再从磁盘上的 dll 文件中载入就行了。所以系统会将该 dll 文件锁定。
    14 楼所讲的 B 关机后 A 就出错,应该就是 A 系统认为该 dll 失去了锁定,再也不能按照上面的调度方式重新从磁盘载入了,所以报错。
      

  14.   

    先搞清楚是动态链接库dll还是activeX/com Dll,
    前者无需注册所以即使在共享目录只要有权限就能使用,
    后者需要注册,本地没注册不能使用,注册了也是使用本地的activex dll
      

  15.   

    反正都是在一个特定的“space”里头, 并且经过了各种系统层的保护, 不断校验这些数据链的合法性你可以认为你要的信息都在他是一个 文件分配表, 也可以是个特定的文件头里头, 因为你的那些信息都是很重要的概要信息!但系统设计角度,合理的想法肯定是每个文件头的入口, 同样也是被一个系统“表”收集了, 系统访问内存文件先从这些表入手。  你就找这个表就可以了。 找到这个表, 再看看系统对这些在干什么? 每个时钟周期内系统在校验什么。  至少这2个方面要搞清楚才能在根本上把握!这个方面最好还是能参阅一下微软的系统设计, 看看调度文件的整个过程是怎么样的, 涉及到哪些东西, 这样就很容易从一个大局面来把握, 如果对系统设计熟悉, 在这个层次上回头看这些就容易多了, 现在想还不如去看看。
      

  16.   

    LS的几位都说的不错,果断决定看 COM本质论
    LX 还有要讲的吗?
    没有的话结贴了~~~