RT
举个最简单的例子:type
  TForm1 = class(TForm)
  private
    { Private declarations }
  public
    procedure bb;
    { Public declarations }
  end;procedure TForm1.bb;
begin
  showmessage('bb123');
end;
比如就这个简单的单form程序,是别人写的我看不到源代码,但知道这个函数就是一个procedure且不带参数。现在我想编一个程序调用这个函数bb。
通过查资料,我想通过dll注入,然后得到TForm1实例,实例是得到了,但是frm:=TForm(FindControl(form1的句柄));-->(FindControl是根据网上自定义的,非Controls中的)后, frm中无bb函数,我想可能是frm:=TForm(...)这里不应该用TForm,而应该用frm对应的TForm1类,但是DLL中无此类,自己在DLL中定义一个一模一样的类的话,frm.bb执行的是DLL中bb的代码 而非 EXE中bb的代码。 搞不定了, 又想到用内存,但有不会,不知道可不可行。求高手指教!!!暂先给100分,不够再加。ps:还有我想到,如果那个exe不是delphi写的的话,我的思路就=nil了啊.....

解决方案 »

  1.   

    如果都是delphi写的,就还好办一点。
    但要确保一点:被调用的函数要符合window函数调用的约定。
    满足上面一点后,可以采用loadlibrary函数,将exe载入....方法如调用dll
      

  2.   


    Tbb = procedure of object;
    var
      bb: Tbb;begin
      @bb = bb函数的地址;
      bb;
    end;
      

  3.   


    Are you kidding me?! How can I get the 'bb函数的地址'??
      

  4.   

    我用exe导出函数,有报内存错误,代码:
    exe1:exports
      aa;type
      procedure aa;export;stdcall;procedure aa;export;stdcall;
    begin
      showmessage('aa');
    end;
    调用的exe:type
      TKKK=procedure of object;procedure TForm1.Button1Click(Sender: TObject);
    var
      lib:   THandle;
      kkk:TKKK;
    begin
      lib   :=   LoadLibrary('Project1.exe');
      if   lib   =   0   then
        ShowMessage('Cannot   load   the   module')
      else
      begin
        @kkk   :=   GetProcAddress(lib,   'aa');
        if   @kkk   =   nil   then
          ShowMessage('Cannot   GetProcAddress')
        else
        begin
          kkk;
        end;
        FreeLibrary(lib);
      end;
    end;报内存错误: Access violation at address 7c92f0e2 in modul 'ntdll.dll'.Read of address 00464000.在网上查了下,发现delphi exe导出函数是会产生一些内存错误的。(我用的是D6,不知道是否有影响)PS:就算这个OK了,但是按照我的要求中,如果手里的别人的exe不提供导出函数我怎么办???
      

  5.   

    貌似不好搞吧!
    如果程序是别人的,你根本无法知道别人的类结构,所以各个成员函数所在的位置索引你无法知道
    位置索引不能知道的话,那么你使用LoadLibrary获得了程序的句柄,也不能计算出函数的位置。
      

  6.   

    除非你把DLL植入到别人的进程,然后在该进程空间当中调用,否则无法跨进程调用。
      

  7.   


    我上面(顶楼) 有讲到,我进去了,也得到了Form1的实例了, 下面就 不会了。
      

  8.   


    是不是类似这句话?:‘目标进程的模块基地址就是EXE基地址,一般是0x00400000,
    但DLL的模块加载基地址就不是这个了,默认是0x10000000,而实际上可能因为这个地址
    已经被占用(有其他DLL被加载到这个地址)而进行重定位’怎么转换?能不能讲解下,或给个例子??
      

  9.   

    每个进程都有自己的逻辑基地址,如果你是跨进程的话,可能你的本意是由A调用B进程的0x00abcdef,结果却调用的是A进程自己的0x00abcdef.
      

  10.   


    还是不太明白,有几个问题:
    1、怎么知道B进程的函数(例如 函数bb),是在进程B的某个地址(如0x00abcdef)?
    2、我DLL插入的话,调用逻辑地址0x00abcdef的话,应该调用的就是B进程的了吧?
    3、可不可以用进程基地址+逻辑地址的方式来调用B进程的0x00abcdef?How?PS:我对内存方面的事可以说是一窍不通,希望你不要觉得烦啊。
      

  11.   

    建议可以看看Windows操作系统原理(潘爱民写的那本Window2000~Windiws2003的挺不错的)
      

  12.   


    是这个吗?                  '深入解析Windows操作系统' 潘爱民 翻译的
    能不能先给我讲讲啊,毕竟像我看这本书的话也不是短时间没可以完成的
      

  13.   


    网上找了好久  '深入解析Windows操作系统'找不到中文版的下载,僵哥能推荐另一本 或 给个下载地址吗?
      

  14.   

    前面給出的解決方法的前提是:都是delphi寫的,且exe有公布出函數,且非對象方法或類方法。基于這些條件,如無法滿足,做這些努力,是徒勞的。
    解釋一下,為什么loadlibrary加載exe后,調用函數會出錯?其實你打開exe應該可以發現(加載后),有兩個exe的鏡像地址,前面一個并不是真正的!至于如何解決...
      

  15.   


    '两个exe的镜像地址',这个什么意思?LoadLibrary返回2个??
      

  16.   

    這個exe的保護機制在起作用。
    load進來后,返回的是第一個鏡像地址
      

  17.   


    可以这样调用吗?:(假设 Y进程 知道下面 tt函数的 偏移地址)
    X进程 中的函数:procedure tt;
    begin
        showmessage('tt');
    end;Y进程:TKK:procedure of object;TForm1.Button1Click(Sender: TObject);
    var kk:TKK;
    begin
        @kk:=pointer(X进程的基地址+X进程中tt函数的偏移地址);
        kk;
    end;
      

  18.   

    远程注入。。网上代码一堆,注入个dll就搞定鸟
      

  19.   

    你先找到 地址就好办了
    然后注入  然后 如下调用procedure TFrm_DllForm.exec_proc_ptgj(flag: integer;
      param: array of string);
    var
      d: Dword;
    begin
      d := Off_Const_ptgj;
      asm      mov    eax, dword ptr [$926FD4]
          mov    eax, dword ptr [eax+$1C]
          mov    esi, dword ptr [eax+$20]
          mov    eax,2
          mov    EDX,$FFFFFFF0
          mov    ecx,  esicall  d  end;
      {
    004930F8    6A FF           PUSH -1
    004930FA    6A 00           PUSH 0
    004930FC    6A 00           PUSH 0
    004930FE    6A 00           PUSH 0
    00493100    8BCE            MOV ECX,ESI
    00493102    E8 C96AFBFF     CALL elementc.00449BD0
    00493107    5F              POP EDI
    00493108    B0 01           MOV AL,1
    0049310A    5E              POP ESI  }
      setexec_result(['普通攻击:call ' + inttostr16(Off_Const_ptgj)]);
    end;
      

  20.   

    如果是delphi写的,对一个对象的具体类不清楚的,可以用RTTI来找到他的public函数。
      

  21.   

    就是函数地址怎么找?我不会。有人说用ida反汇编,我搞了下,不太会用,没找到函数地址。注入和调用我会。
    这个我先学习下。
      

  22.   

    你应该申明一个与被调用类一样的类结构,然后再用这个类的结构去套目前地址,这样才能访问。记得在李维的深入VCL 里有好多这样的例子,你可以参考一下。